Skip to content

Commit

Permalink
ALSA: ctl: fill identical information to return value when adding use…
Browse files Browse the repository at this point in the history
…rspace elements

currently some members related identical information are not fiiled
in returned parameter of SNDRV_CTL_IOCTL_ELEM_ADD. This is not better
for userspace application.

This commit copies information to returned value. When failing to copy
into userspace, the added elements are going to be removed. Then, no
applications can lock these elements between adding and removing because
these are already locked.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Sakamoto authored and Takashi Iwai committed Apr 11, 2015
1 parent c378c3b commit cab2ed7
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion sound/core/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
unsigned int access;
long private_size;
struct user_element *ue;
unsigned int offset;
int err;

if (!*info->id.name)
Expand Down Expand Up @@ -1316,6 +1317,15 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
err = snd_ctl_add(card, kctl);
if (err < 0)
return err;
offset = snd_ctl_get_ioff(kctl, &info->id);
snd_ctl_build_ioff(&info->id, kctl, offset);
/*
* Here we cannot fill any field for the number of elements added by
* this operation because there're no specific fields. The usage of
* 'owner' field for this purpose may cause any bugs to userspace
* applications because the field originally means PID of a process
* which locks the element.
*/

down_write(&card->controls_rwsem);
card->user_ctl_count++;
Expand All @@ -1328,9 +1338,19 @@ static int snd_ctl_elem_add_user(struct snd_ctl_file *file,
struct snd_ctl_elem_info __user *_info, int replace)
{
struct snd_ctl_elem_info info;
int err;

if (copy_from_user(&info, _info, sizeof(info)))
return -EFAULT;
return snd_ctl_elem_add(file, &info, replace);
err = snd_ctl_elem_add(file, &info, replace);
if (err < 0)
return err;
if (copy_to_user(_info, &info, sizeof(info))) {
snd_ctl_remove_user_ctl(file, &info.id);
return -EFAULT;
}

return 0;
}

static int snd_ctl_elem_remove(struct snd_ctl_file *file,
Expand Down

0 comments on commit cab2ed7

Please sign in to comment.