control: use reference-counted pid

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>
This commit is contained in:
Clemens Ladisch 2009-11-02 09:35:44 +01:00 committed by Takashi Iwai
parent 31cef7076e
commit 25d27eded1
4 changed files with 8 additions and 5 deletions

View file

@ -86,10 +86,12 @@ struct snd_kctl_event {
#define snd_kctl_event(n) list_entry(n, struct snd_kctl_event, list) #define snd_kctl_event(n) list_entry(n, struct snd_kctl_event, list)
struct pid;
struct snd_ctl_file { struct snd_ctl_file {
struct list_head list; /* list of all control files */ struct list_head list; /* list of all control files */
struct snd_card *card; struct snd_card *card;
pid_t pid; struct pid *pid;
int prefer_pcm_subdevice; int prefer_pcm_subdevice;
int prefer_rawmidi_subdevice; int prefer_rawmidi_subdevice;
wait_queue_head_t change_sleep; wait_queue_head_t change_sleep;

View file

@ -75,7 +75,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
ctl->card = card; ctl->card = card;
ctl->prefer_pcm_subdevice = -1; ctl->prefer_pcm_subdevice = -1;
ctl->prefer_rawmidi_subdevice = -1; ctl->prefer_rawmidi_subdevice = -1;
ctl->pid = current->pid; ctl->pid = get_pid(task_pid(current));
file->private_data = ctl; file->private_data = ctl;
write_lock_irqsave(&card->ctl_files_rwlock, flags); write_lock_irqsave(&card->ctl_files_rwlock, flags);
list_add_tail(&ctl->list, &card->ctl_files); 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; control->vd[idx].owner = NULL;
up_write(&card->controls_rwsem); up_write(&card->controls_rwsem);
snd_ctl_empty_read_queue(ctl); snd_ctl_empty_read_queue(ctl);
put_pid(ctl->pid);
kfree(ctl); kfree(ctl);
module_put(card->module); module_put(card->module);
snd_card_file_remove(card, file); 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; info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
if (vd->owner == ctl) if (vd->owner == ctl)
info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER; info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
info->owner = vd->owner->pid; info->owner = pid_vnr(vd->owner->pid);
} else { } else {
info->owner = -1; info->owner = -1;
} }

View file

@ -809,7 +809,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
card = pcm->card; card = pcm->card;
read_lock(&card->ctl_files_rwlock); read_lock(&card->ctl_files_rwlock);
list_for_each_entry(kctl, &card->ctl_files, list) { 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; prefer_subdevice = kctl->prefer_pcm_subdevice;
if (prefer_subdevice != -1) if (prefer_subdevice != -1)
break; break;

View file

@ -415,7 +415,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
subdevice = -1; subdevice = -1;
read_lock(&card->ctl_files_rwlock); read_lock(&card->ctl_files_rwlock);
list_for_each_entry(kctl, &card->ctl_files, list) { 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; subdevice = kctl->prefer_rawmidi_subdevice;
if (subdevice != -1) if (subdevice != -1)
break; break;