diff options
author | Zheyu Ma <zheyuma97@gmail.com> | 2022-08-24 16:16:54 +0800 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2022-08-24 11:41:53 +0200 |
commit | 6ab55ec0a938c7f943a4edba3d6514f775983887 (patch) | |
tree | 6250c2625787c84cf7fb230fedd604590cf3d19c /sound/core | |
parent | 2e6481a3f3ee6234ce577454e1d88aca55f51d47 (diff) | |
download | linux-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.c | 6 |
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; |