[alsa-devel] [PATCH 07/24] ALSA: ctl: add a helper function to allocate for ELEM_LIST request
Takashi Sakamoto
o-takashi at sakamocchi.jp
Sat Nov 25 10:19:49 CET 2017
When investigating compatibility layer, several functions for native ABI
are called by the layer. A 'snd_ctl_elem_list()' is such a function,
while it cannot receive a second argument for data on kernel space. This
will bring a future inconvenience in integration of the layer.
This commit adds a helper function to allocate memory object on kernel
space for the argument.
Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
sound/core/control.c | 41 ++++++++++++++++++++++++++++-------------
sound/core/control_compat.c | 2 +-
2 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/sound/core/control.c b/sound/core/control.c
index 8baee922a400..ad4d27c681c4 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -745,22 +745,19 @@ static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
}
static int snd_ctl_elem_list(struct snd_ctl_file *ctl_file,
- struct snd_ctl_elem_list __user *_list)
+ struct snd_ctl_elem_list *list)
{
- struct snd_ctl_elem_list list;
struct snd_kcontrol *kctl;
struct snd_ctl_elem_id id;
unsigned int offset, space, jidx;
int err = 0;
- if (copy_from_user(&list, _list, sizeof(list)))
- return -EFAULT;
- offset = list.offset;
- space = list.space;
+ offset = list->offset;
+ space = list->space;
down_read(&ctl_file->card->controls_rwsem);
- list.count = ctl_file->card->controls_count;
- list.used = 0;
+ list->count = ctl_file->card->controls_count;
+ list->used = 0;
if (space > 0) {
list_for_each_entry(kctl, &ctl_file->card->controls, list) {
if (offset >= kctl->count) {
@@ -769,12 +766,12 @@ static int snd_ctl_elem_list(struct snd_ctl_file *ctl_file,
}
for (jidx = offset; jidx < kctl->count; jidx++) {
snd_ctl_build_ioff(&id, kctl, jidx);
- if (copy_to_user(list.pids + list.used, &id,
+ if (copy_to_user(list->pids + list->used, &id,
sizeof(id))) {
err = -EFAULT;
goto out;
}
- list.used++;
+ list->used++;
if (!--space)
goto out;
}
@@ -783,8 +780,26 @@ static int snd_ctl_elem_list(struct snd_ctl_file *ctl_file,
}
out:
up_read(&ctl_file->card->controls_rwsem);
- if (!err && copy_to_user(_list, &list, sizeof(list)))
- err = -EFAULT;
+ return err;
+}
+
+static int snd_ctl_elem_list_user(struct snd_ctl_file *ctl_file,
+ void __user *arg)
+{
+ struct snd_ctl_elem_list *list;
+ int err;
+
+ list = memdup_user(arg, sizeof(*list));
+ if (IS_ERR(list))
+ return PTR_ERR(list);
+
+ err = snd_ctl_elem_list(ctl_file, list);
+ if (err >= 0) {
+ if (copy_to_user(arg, list, sizeof(*list)))
+ err = -EFAULT;
+ }
+
+ kfree(list);
return err;
}
@@ -1552,7 +1567,7 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
case SNDRV_CTL_IOCTL_CARD_INFO:
return snd_ctl_card_info(card, ctl, cmd, argp);
case SNDRV_CTL_IOCTL_ELEM_LIST:
- return snd_ctl_elem_list(ctl, argp);
+ return snd_ctl_elem_list_user(ctl, argp);
case SNDRV_CTL_IOCTL_ELEM_INFO:
return snd_ctl_elem_info_user(ctl, argp);
case SNDRV_CTL_IOCTL_ELEM_READ:
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 3594bd41750e..8a4c58c0cf3b 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -422,7 +422,7 @@ static int snd_ctl_elem_list_compat(struct snd_ctl_file *ctl_file,
if (get_user(ptr, &data32->pids) ||
put_user(compat_ptr(ptr), &data->pids))
return -EFAULT;
- err = snd_ctl_elem_list(ctl_file, data);
+ err = snd_ctl_elem_list_user(ctl_file, data);
if (err < 0)
return err;
/* copy the result */
--
2.14.1
More information about the Alsa-devel
mailing list