control: use reference-counted pid
Clemens Ladisch [Mon, 2 Nov 2009 08:35:44 +0000 (09:35 +0100)]
Instead of storing the PID number, take a reference to the task's pid
structure.  This protects against duplicates due to PID overflows, and
using pid_vnr() ensures that the PID returned by snd_ctl_elem_info() is
correct as seen from the current namespace.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

include/sound/control.h
sound/core/control.c
sound/core/pcm.c
sound/core/rawmidi.c

index 3517745..112374d 100644 (file)
@@ -86,10 +86,12 @@ struct snd_kctl_event {
 
 #define snd_kctl_event(n) list_entry(n, struct snd_kctl_event, list)
 
+struct pid;
+
 struct snd_ctl_file {
        struct list_head list;          /* list of all control files */
        struct snd_card *card;
-       pid_t pid;
+       struct pid *pid;
        int prefer_pcm_subdevice;
        int prefer_rawmidi_subdevice;
        wait_queue_head_t change_sleep;
index 814d2cf..73dc10a 100644 (file)
@@ -75,7 +75,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
        ctl->card = card;
        ctl->prefer_pcm_subdevice = -1;
        ctl->prefer_rawmidi_subdevice = -1;
-       ctl->pid = current->pid;
+       ctl->pid = get_pid(task_pid(current));
        file->private_data = ctl;
        write_lock_irqsave(&card->ctl_files_rwlock, flags);
        list_add_tail(&ctl->list, &card->ctl_files);
@@ -125,6 +125,7 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
                                control->vd[idx].owner = NULL;
        up_write(&card->controls_rwsem);
        snd_ctl_empty_read_queue(ctl);
+       put_pid(ctl->pid);
        kfree(ctl);
        module_put(card->module);
        snd_card_file_remove(card, file);
@@ -672,7 +673,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
                        info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
                        if (vd->owner == ctl)
                                info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
-                       info->owner = vd->owner->pid;
+                       info->owner = pid_vnr(vd->owner->pid);
                } else {
                        info->owner = -1;
                }
index c69c60b..8e2c783 100644 (file)
@@ -809,7 +809,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
        card = pcm->card;
        read_lock(&card->ctl_files_rwlock);
        list_for_each_entry(kctl, &card->ctl_files, list) {
-               if (kctl->pid == current->pid) {
+               if (kctl->pid == task_pid(current)) {
                        prefer_subdevice = kctl->prefer_pcm_subdevice;
                        if (prefer_subdevice != -1)
                                break;
index c0adc14..8a81bda 100644 (file)
@@ -415,7 +415,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
                subdevice = -1;
                read_lock(&card->ctl_files_rwlock);
                list_for_each_entry(kctl, &card->ctl_files, list) {
-                       if (kctl->pid == current->pid) {
+                       if (kctl->pid == task_pid(current)) {
                                subdevice = kctl->prefer_rawmidi_subdevice;
                                if (subdevice != -1)
                                        break;