Message ID | 20230324171812.221086-3-theflamefire89@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | ALSA: control: Fix locking around snd_ctl_elem_read/write | expand |
Hi, Thanks for your patch! > -----Original Message----- > From: cip-dev@lists.cip-project.org <cip-dev@lists.cip-project.org> On > Behalf Of Alexander Grund > Sent: Saturday, March 25, 2023 2:18 AM > To: cip-dev@lists.cip-project.org > Cc: uli+cip@fpond.eu > Subject: [cip-dev] [PATCH 4.4 2/3] ALSA: control: Fix memory corruption risk in > snd_ctl_elem_read > > From: Richard Fitzgerald <rf@opensource.cirrus.com> > > commit 5a23699a39abc5328921a81b89383d088f6ba9cc upstream. > > The patch "ALSA: control: code refactoring for ELEM_READ/ELEM_WRITE > operations" introduced a potential for kernel memory corruption due to an > incorrect if statement allowing non-readable controls to fall through and call > the get function. For TLV controls a driver can omit > SNDRV_CTL_ELEM_ACCESS_READ to ensure that only the TLV get function > can be called. Instead the normal get() can be invoked unexpectedly and as the > driver expects that this will only be called for controls <= 512 bytes, potentially > try to copy >512 bytes into the 512 byte return array, so corrupting kernel > memory. > > The problem is an attempt to refactor the snd_ctl_elem_read function to invert > the logic so that it conditionally aborted if the control is unreadable instead of > conditionally executing. But the if statement wasn't inverted correctly. > > The correct inversion of > > if (a && !b) > > is > if (!a || b) > > Fixes: becf9e5d553c2 ("ALSA: control: code refactoring for > ELEM_READ/ELEM_WRITE operations") > Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> > Cc: <stable@vger.kernel.org> > Signed-off-by: Takashi Iwai <tiwai@suse.de> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > Space here is not required. > Signed-off-by: Alexander Grund <theflamefire89@gmail.com> > --- > sound/core/control.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/sound/core/control.c b/sound/core/control.c index > a042a30d6a728..3ca81e85a1492 100644 > --- a/sound/core/control.c > +++ b/sound/core/control.c > @@ -884,7 +884,7 @@ static int snd_ctl_elem_read(struct snd_card *card, > > 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) > + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get > == NULL) > return -EPERM; > > snd_ctl_build_ioff(&control->id, kctl, index_offset); > -- > 2.40.0 Best regards, Nobuhiro
> > Space here is not required. I agree. Can this be just ignored when applying this or do I need to resend the patch?
diff --git a/sound/core/control.c b/sound/core/control.c index a042a30d6a728..3ca81e85a1492 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -884,7 +884,7 @@ static int snd_ctl_elem_read(struct snd_card *card, 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) + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL) return -EPERM; snd_ctl_build_ioff(&control->id, kctl, index_offset);