summaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorAlan Young <consult.awy@gmail.com>2021-12-02 15:06:07 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-12-14 10:18:05 +0100
commitfd753901ca921877cf585dc315dd5b36f672a404 (patch)
treecaa311e8803b1e509375cf830fc5a7ce5ea9658a /sound/core
parent505039dd0fe6493565e27b55700e46f43f20580d (diff)
downloadlinux-stable-fd753901ca921877cf585dc315dd5b36f672a404.tar.gz
linux-stable-fd753901ca921877cf585dc315dd5b36f672a404.tar.bz2
linux-stable-fd753901ca921877cf585dc315dd5b36f672a404.zip
ALSA: ctl: Fix copy of updated id with element read/write
commit b6409dd6bdc03aa178bbff0d80db2a30d29b63ac upstream. When control_compat.c:copy_ctl_value_to_user() is used, by ctl_elem_read_user() & ctl_elem_write_user(), it must also copy back the snd_ctl_elem_id value that may have been updated (filled in) by the call to snd_ctl_elem_read/snd_ctl_elem_write(). This matches the functionality provided by snd_ctl_elem_read_user() and snd_ctl_elem_write_user(), via snd_ctl_build_ioff(). Without this, and without making additional calls to snd_ctl_info() which are unnecessary when using the non-compat calls, a userspace application will not know the numid value for the element and consequently will not be able to use the poll/read interface on the control file to determine which elements have updates. Signed-off-by: Alan Young <consult.awy@gmail.com> Cc: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20211202150607.543389-1-consult.awy@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/control_compat.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 507fd5210c1c..3fc216644e0e 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -279,6 +279,7 @@ static int copy_ctl_value_to_user(void __user *userdata,
struct snd_ctl_elem_value *data,
int type, int count)
{
+ struct snd_ctl_elem_value32 __user *data32 = userdata;
int i, size;
if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
@@ -295,6 +296,8 @@ static int copy_ctl_value_to_user(void __user *userdata,
if (copy_to_user(valuep, data->value.bytes.data, size))
return -EFAULT;
}
+ if (copy_to_user(&data32->id, &data->id, sizeof(data32->id)))
+ return -EFAULT;
return 0;
}