In current implementation, for I/O request of ELEM_INFO, kernel stack is used to copy 'struct snd_ctl_elem_info' data. However, the size of this structure is a bit big and usage of kernel stack is not preferable.
This commit allocates a memory object on kernel space, instead.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/core/control.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/sound/core/control.c b/sound/core/control.c index 8d158a49467d..4cb950e310bf 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -875,20 +875,23 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl, return result; }
-static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl, - struct snd_ctl_elem_info __user *_info) +static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl, void __user *arg) { - struct snd_ctl_elem_info info; - int result; + struct snd_ctl_elem_info *info; + int err;
- if (copy_from_user(&info, _info, sizeof(info))) - return -EFAULT; - result = snd_ctl_elem_info(ctl, &info); - if (result < 0) - return result; - if (copy_to_user(_info, &info, sizeof(info))) - return -EFAULT; - return result; + info = memdup_user(arg, sizeof(*info)); + if (IS_ERR(info)) + return PTR_ERR(info); + + err = snd_ctl_elem_info(ctl, info); + if (err >= 0) { + if (copy_to_user(arg, info, sizeof(*info))) + return -EFAULT; + } + + kfree(info); + return err; }
static int snd_ctl_elem_read(struct snd_card *card,