This is a note to let you know that I've just added the patch titled ALSA: pcm: Move rwsem lock inside snd_ctl_elem_read to prevent UAF to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: alsa-pcm-move-rwsem-lock-inside-snd_ctl_elem_read-to-prevent-uaf.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 56b88b50565cd8b946a2d00b0c83927b7ebb055e Mon Sep 17 00:00:00 2001 From: Clement Lecigne <clecigne@xxxxxxxxxx> Date: Fri, 13 Jan 2023 13:07:45 +0100 Subject: ALSA: pcm: Move rwsem lock inside snd_ctl_elem_read to prevent UAF From: Clement Lecigne <clecigne@xxxxxxxxxx> commit 56b88b50565cd8b946a2d00b0c83927b7ebb055e upstream. Takes rwsem lock inside snd_ctl_elem_read instead of snd_ctl_elem_read_user like it was done for write in commit 1fa4445f9adf1 ("ALSA: control - introduce snd_ctl_notify_one() helper"). Doing this way we are also fixing the following locking issue happening in the compat path which can be easily triggered and turned into an use-after-free. 64-bits: snd_ctl_ioctl snd_ctl_elem_read_user [takes controls_rwsem] snd_ctl_elem_read [lock properly held, all good] [drops controls_rwsem] 32-bits: snd_ctl_ioctl_compat snd_ctl_elem_write_read_compat ctl_elem_write_read snd_ctl_elem_read [missing lock, not good] CVE-2023-0266 was assigned for this issue. Cc: stable@xxxxxxxxxx # 5.13+ Signed-off-by: Clement Lecigne <clecigne@xxxxxxxxxx> Reviewed-by: Jaroslav Kysela <perex@xxxxxxxx> Link: https://lore.kernel.org/r/20230113120745.25464-1-tiwai@xxxxxxx Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- sound/core/control.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1067,14 +1067,19 @@ static int snd_ctl_elem_read(struct snd_ const u32 pattern = 0xdeadbeef; int ret; + down_read(&card->controls_rwsem); kctl = snd_ctl_find_id(card, &control->id); - if (kctl == NULL) - return -ENOENT; + if (kctl == NULL) { + ret = -ENOENT; + goto unlock; + } index_offset = snd_ctl_get_ioff(kctl, &control->id); vd = &kctl->vd[index_offset]; - if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL) - return -EPERM; + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL) { + ret = -EPERM; + goto unlock; + } snd_ctl_build_ioff(&control->id, kctl, index_offset); @@ -1084,7 +1089,7 @@ static int snd_ctl_elem_read(struct snd_ info.id = control->id; ret = __snd_ctl_elem_info(card, kctl, &info, NULL); if (ret < 0) - return ret; + goto unlock; #endif if (!snd_ctl_skip_validation(&info)) @@ -1094,7 +1099,7 @@ static int snd_ctl_elem_read(struct snd_ ret = kctl->get(kctl, control); snd_power_unref(card); if (ret < 0) - return ret; + goto unlock; if (!snd_ctl_skip_validation(&info) && sanity_check_elem_value(card, control, &info, pattern) < 0) { dev_err(card->dev, @@ -1102,8 +1107,11 @@ static int snd_ctl_elem_read(struct snd_ control->id.iface, control->id.device, control->id.subdevice, control->id.name, control->id.index); - return -EINVAL; + ret = -EINVAL; + goto unlock; } +unlock: + up_read(&card->controls_rwsem); return ret; } @@ -1117,9 +1125,7 @@ static int snd_ctl_elem_read_user(struct if (IS_ERR(control)) return PTR_ERR(control); - down_read(&card->controls_rwsem); result = snd_ctl_elem_read(card, control); - up_read(&card->controls_rwsem); if (result < 0) goto error; Patches currently in stable-queue which might be from clecigne@xxxxxxxxxx are queue-5.15/alsa-pcm-move-rwsem-lock-inside-snd_ctl_elem_read-to-prevent-uaf.patch