summaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorZheyu Ma <zheyuma97@gmail.com>2022-08-24 16:16:54 +0800
committerTakashi Iwai <tiwai@suse.de>2022-08-24 11:41:53 +0200
commit6ab55ec0a938c7f943a4edba3d6514f775983887 (patch)
tree6250c2625787c84cf7fb230fedd604590cf3d19c /sound/core
parent2e6481a3f3ee6234ce577454e1d88aca55f51d47 (diff)
downloadlinux-6ab55ec0a938c7f943a4edba3d6514f775983887.tar.gz
linux-6ab55ec0a938c7f943a4edba3d6514f775983887.tar.bz2
linux-6ab55ec0a938c7f943a4edba3d6514f775983887.zip
ALSA: control: Fix an out-of-bounds bug in get_ctl_id_hash()
Since the user can control the arguments provided to the kernel by the ioctl() system call, an out-of-bounds bug occurs when the 'id->name' provided by the user does not end with '\0'. The following log can reveal it: [ 10.002313] BUG: KASAN: stack-out-of-bounds in snd_ctl_find_id+0x36c/0x3a0 [ 10.002895] Read of size 1 at addr ffff888109f5fe28 by task snd/439 [ 10.004934] Call Trace: [ 10.007140] snd_ctl_find_id+0x36c/0x3a0 [ 10.007489] snd_ctl_ioctl+0x6cf/0x10e0 Fix this by checking the bound of 'id->name' in the loop. Fixes: c27e1efb61c5 ("ALSA: control: Use xarray for faster lookups") Signed-off-by: Zheyu Ma <zheyuma97@gmail.com> Link: https://lore.kernel.org/r/20220824081654.3767739-1-zheyuma97@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/control.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index f3e893715369..e8fc4c511e5f 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -385,14 +385,14 @@ static bool elem_id_matches(const struct snd_kcontrol *kctl,
#define MULTIPLIER 37
static unsigned long get_ctl_id_hash(const struct snd_ctl_elem_id *id)
{
+ int i;
unsigned long h;
- const unsigned char *p;
h = id->iface;
h = MULTIPLIER * h + id->device;
h = MULTIPLIER * h + id->subdevice;
- for (p = id->name; *p; p++)
- h = MULTIPLIER * h + *p;
+ for (i = 0; id->name[i] && i < SNDRV_CTL_ELEM_ID_NAME_MAXLEN; i++)
+ h = MULTIPLIER * h + id->name[i];
h = MULTIPLIER * h + id->index;
h &= LONG_MAX;
return h;