FAILED: patch "[PATCH] ALSA: usbusx2y: fix in04_last array size mismatch with" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 861111a14740e12c36d363e9830f8daa734279c9
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091636-ultimatum-procurer-683f@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 861111a14740e12c36d363e9830f8daa734279c9 Mon Sep 17 00:00:00 2001
From: Tristan Madani <[email protected]>
Date: Fri, 4 Sep 2026 20:58:25 +0000
Subject: [PATCH] ALSA: usbusx2y: fix in04_last array size mismatch with
in04_buf
The in04_last array in struct usx2ydev is declared as char[24], but in04_buf is allocated as sizeof(struct us428_ctls) which is 21 bytes. In i_usx2y_in04_int(), when ctl_snapshot_last == -2 (initialization path):
memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last));
This copies 24 bytes from a 21-byte slab allocation, reading 3 bytes past the end of the source object.
Introduce a USX2Y_IN04_SIZE constant defined as sizeof(struct us428_ctls) and use it consistently for the in04_last array, the in04_buf allocation, the URB transfer length, and the comparison loop, replacing the bare 24 and 21 literals throughout.
sound/usb/usx2y/usbusx2y.c +3 -3
@@ -196,7 +196,7 @@ static void i_usx2y_in04_int(struct urb *urb)memcpy (usx2y->in04_last, usx2y->in04_buf,sizeof (usx2y->in04_last)); us428ctls->ctl_snapshot_last =-1 ; }else { -for (i =0 ; i <21 ; i++) { +for (i =0 ; i <USX2Y_IN04_SIZE ; i++) {if (usx2y->in04_last[i] != ((char *)usx2y->in04_buf)[i]) {if (diff <0 ) diff = i;
@@ -305,7 +305,7 @@ int usx2y_in04_init(struct usx2ydev *usx2y) goto error; } - usx2y->in04_buf =kmalloc (21 ,GFP_KERNEL ); + usx2y->in04_buf =kmalloc (USX2Y_IN04_SIZE ,GFP_KERNEL );if (!usx2y->in04_buf) { err = -ENOMEM ; goto error;
@@ -313,7 +313,7 @@ int usx2y_in04_init(struct usx2ydev *usx2y)init_waitqueue_head (&usx2y->in04_wait_queue);usb_fill_int_urb (usx2y->in04_urb, usx2y->dev,usb_rcvintpipe (usx2y->dev,0x4 ), - usx2y->in04_buf,21 , + usx2y->in04_buf,USX2Y_IN04_SIZE , i_usx2y_in04_int, usx2y,10 );if (usb_urb_ep_type_check (usx2y->in04_urb)) {
sound/usb/usx2y/usbusx2y.h +3 -1
@@ -5,6 +5,8 @@#include "../midi.h" #include "usbus428ctldefs.h" +#define USX2Y_IN04_SIZE sizeof(struct us428_ctls) +#define NRURBS 2/* Default value used for nr of packs per urb.
@@ -55,7 +57,7 @@ struct usx2ydev {int stride;struct urb *in04_urb;void *in04_buf; -char in04_last[24 ]; +char in04_last[USX2Y_IN04_SIZE ];unsigned int in04_int_calls;struct snd_usx2y_urb_seq *us04;wait_queue_head_t in04_wait_queue;
Sasha Levin
maintainerPATCH 1/2 ALSA: usx2y: Fix potential memory leaks
From: Takashi Iwai <[email protected]>
[ Upstream commit 02d382af1c4e321acbea1c25b97ee13f52b9ac7d ]
Theoretically the initialization functions in usx2y drivers may be called multiple times as the driver gets initialized via hwpdep ioctl. Meanwhile, those functions including memory allocations don't check whether they are called twice, and they forget the old resources, which would lead to memory leaks.
This patch adds the sanity checks about the doubly initializations to give kernel WARNING, and returns an error in such a case. Also, each allocation assures to release the resources at its error path properly.
Stable-dep-of: 861111a14740 ("ALSA: usbusx2y: fix in04_last array size mismatch with in04_buf")
--- sound/usb/usx2y/usbusx2y.c | 39 ++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-)
sound/usb/usx2y/usbusx2y.c +33 -6
@@ -150,6 +150,7 @@ MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");static int snd_usx2y_card_used[SNDRV_CARDS ];static void snd_usx2y_card_private_free (struct snd_card *card); +static void usx2y_unlinkseq (struct snd_usx2y_async_seq *s);#ifdef USX2Y_NRPACKS_VARIABLE int nrpacks =USX2Y_NRPACKS ;/* number of packets per urb */
@@ -258,6 +259,9 @@ int usx2y_async_seq04_init(struct usx2ydev *usx2y) {int err =0 , i; +if (WARN_ON (usx2y->as04.buffer)) +return -EBUSY ; + usx2y->as04.buffer =kmalloc_array (URBS_ASYNC_SEQ ,URB_DATA_LEN_ASYNC_SEQ ,GFP_KERNEL );if (!usx2y->as04.buffer) {
@@ -278,27 +282,47 @@ int usx2y_async_seq04_init(struct usx2ydev *usx2y)break ; } } +if (err) +usx2y_unlinkseq (&usx2y->as04);return err; }int usx2y_in04_init (struct usx2ydev *usx2y) { +int err; + +if (WARN_ON (usx2y->in04_urb)) +return -EBUSY ; + usx2y->in04_urb =usb_alloc_urb (0 ,GFP_KERNEL ); -if (!usx2y->in04_urb) -return -ENOMEM ; +if (!usx2y->in04_urb) { + err = -ENOMEM ; + goto error; + } usx2y->in04_buf =kmalloc (21 ,GFP_KERNEL ); -if (!usx2y->in04_buf) -return -ENOMEM ; +if (!usx2y->in04_buf) { + err = -ENOMEM ; + goto error; + }init_waitqueue_head (&usx2y->in04_wait_queue);usb_fill_int_urb (usx2y->in04_urb, usx2y->dev,usb_rcvintpipe (usx2y->dev,0x4 ), usx2y->in04_buf,21 , i_usx2y_in04_int, usx2y,10 ); -if (usb_urb_ep_type_check (usx2y->in04_urb)) -return -EINVAL ; +if (usb_urb_ep_type_check (usx2y->in04_urb)) { + err = -EINVAL ; + goto error; + }return usb_submit_urb (usx2y->in04_urb,GFP_KERNEL ); + + error: +kfree (usx2y->in04_buf); +usb_free_urb (usx2y->in04_urb); + usx2y->in04_buf =NULL ; + usx2y->in04_urb =NULL ; +return err; }static void usx2y_unlinkseq (struct snd_usx2y_async_seq *s)
@@ -306,11 +330,14 @@ static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s)int i;for (i =0 ; i <URBS_ASYNC_SEQ ; ++i) { +if (!s->urb[i]) +continue ;usb_kill_urb (s->urb[i]);usb_free_urb (s->urb[i]); s->urb[i] =NULL ; }kfree (s->buffer); + s->buffer =NULL ; }static const struct usb_device_id snd_usx2y_usb_id_table[] = {
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 ALSA: usbusx2y: fix in04_last array size mismatch with in04_buf
From: Tristan Madani <[email protected]>
[ Upstream commit 861111a14740e12c36d363e9830f8daa734279c9 ]
The in04_last array in struct usx2ydev is declared as char[24], but in04_buf is allocated as sizeof(struct us428_ctls) which is 21 bytes. In i_usx2y_in04_int(), when ctl_snapshot_last == -2 (initialization path):
memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last));
This copies 24 bytes from a 21-byte slab allocation, reading 3 bytes past the end of the source object.
Introduce a USX2Y_IN04_SIZE constant defined as sizeof(struct us428_ctls) and use it consistently for the in04_last array, the in04_buf allocation, the URB transfer length, and the comparison loop, replacing the bare 24 and 21 literals throughout.
--- sound/usb/usx2y/usbusx2y.c | 6 +++--- sound/usb/usx2y/usbusx2y.h | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-)
sound/usb/usx2y/usbusx2y.c +3 -3
@@ -198,7 +198,7 @@ static void i_usx2y_in04_int(struct urb *urb)memcpy (usx2y->in04_last, usx2y->in04_buf,sizeof (usx2y->in04_last)); us428ctls->ctl_snapshot_last =-1 ; }else { -for (i =0 ; i <21 ; i++) { +for (i =0 ; i <USX2Y_IN04_SIZE ; i++) {if (usx2y->in04_last[i] != ((char *)usx2y->in04_buf)[i]) {if (diff <0 ) diff = i;
@@ -300,7 +300,7 @@ int usx2y_in04_init(struct usx2ydev *usx2y) goto error; } - usx2y->in04_buf =kmalloc (21 ,GFP_KERNEL ); + usx2y->in04_buf =kmalloc (USX2Y_IN04_SIZE ,GFP_KERNEL );if (!usx2y->in04_buf) { err = -ENOMEM ; goto error;
@@ -308,7 +308,7 @@ int usx2y_in04_init(struct usx2ydev *usx2y)init_waitqueue_head (&usx2y->in04_wait_queue);usb_fill_int_urb (usx2y->in04_urb, usx2y->dev,usb_rcvintpipe (usx2y->dev,0x4 ), - usx2y->in04_buf,21 , + usx2y->in04_buf,USX2Y_IN04_SIZE , i_usx2y_in04_int, usx2y,10 );if (usb_urb_ep_type_check (usx2y->in04_urb)) {
sound/usb/usx2y/usbusx2y.h +3 -1
@@ -5,6 +5,8 @@#include "../midi.h" #include "usbus428ctldefs.h" +#define USX2Y_IN04_SIZE sizeof(struct us428_ctls) +#define NRURBS 2/* Default value used for nr of packs per urb.
@@ -55,7 +57,7 @@ struct usx2ydev {int stride;struct urb *in04_urb;void *in04_buf; -char in04_last[24 ]; +char in04_last[USX2Y_IN04_SIZE ];unsigned int in04_int_calls;struct snd_usx2y_urb_seq *us04;wait_queue_head_t in04_wait_queue;
Signature · 1 line
2.53.0