* [PATCH] usb: core: fix NULL dereference in usb_ifnum_to_if() during device removal
@ 2025-11-13 11:44 Jie Deng
2025-11-13 13:28 ` Greg KH
2025-11-13 14:50 ` Alan Stern
0 siblings, 2 replies; 5+ messages in thread
From: Jie Deng @ 2025-11-13 11:44 UTC (permalink / raw)
To: gregkh
Cc: mathias.nyman, sakari.ailus, stern, linux-usb, linux-kernel, Jie Deng
During USB device hot-unplug, in the time window between when
usb_disconnect() calls usb_disable_device() to set
dev->actconfig->interface[i] to NULL but before dev->actconfig
is set to NULL.At this point, outside the kernel, usb_ifnum_to_if()
is called through usb_set_interface(), and usb_ifnum_to_if() continues
to access interface[i]->altsetting[i], triggering a null pointer.
kernel log:
[ 9518.779148][ 1] [ T4650] pc : usb_ifnum_to_if+0x34/0x50
[ 9518.784360][ 1] [ T4650] lr : usb_hcd_alloc_bandwidth+0x260/0x348
[ 9518.790439][ 1] [ T4650] sp : ffffffa25a6c79d0
[ 9518.794868][ 1] [ T4650] x29: ffffffa25a6c79d0 x28: 0000000040045613
[ 9518.801294][ 1] [ T4650] x27: 0000000000000000 x26: 0000000000000000
[ 9518.807720][ 1] [ T4650] x25: ffffffa2e1597408 x24: ffffffa2e1597408
[ 9518.814146][ 1] [ T4650] x23: ffffffa2e15974f8 x22: 0000000000000000
[ 9518.820572][ 1] [ T4650] x21: ffffffa2e9acc000 x20: ffffffa2e6712000
[ 9518.826998][ 1] [ T4650] x19: ffffffa2e6a8a800 x18: 0000000000000000
[ 9518.833423][ 1] [ T4650] x17: 0000007fbb91b4b0 x16: ffffffc01016a170
[ 9518.839849][ 1] [ T4650] x15: 0000000000000000 x14: 0845c02202702800
[ 9518.846275][ 1] [ T4650] x13: 0000000000000001 x12: 0000000000000000
[ 9518.852700][ 1] [ T4650] x11: 0000000000000400 x10: ffffffff89e5d720
[ 9518.859126][ 1] [ T4650] x9 : 0000000000000000 x8 : 0000000000000000
[ 9518.865551][ 1] [ T4650] x7 : ffffffa2fff1e440 x6 : ffffffa28175c900
[ 9518.871977][ 1] [ T4650] x5 : 0000000000000060 x4 : ffffffa2e9bc54b0
[ 9518.878403][ 1] [ T4650] x3 : ffffffa2e9bc54a0 x2 : ffffffa2e9bc54a0
[ 9518.884828][ 1] [ T4650] x1 : 0000000000000001 x0 : 0000000000000000
[ 9518.891254][ 1] [ T4650] Call trace:
[ 9518.894817][ 1] [ T4650] usb_ifnum_to_if+0x34/0x50
[ 9518.899681][ 1] [ T4650] usb_set_interface+0x108/0x3c8
[ 9518.904898][ 1] [ T4650] uvc_video_stop_streaming+0x3c/0x90 [uvcvideo]
[ 9518.911500][ 1] [ T4650] uvc_stop_streaming+0x24/0x90 [uvcvideo]
[ 9518.917583][ 1] [ T4650] __vb2_queue_cancel+0x44/0x458 [videobuf2_common]
[ 9518.924444][ 1] [ T4650] vb2_core_streamoff+0x20/0xb8 [videobuf2_common]
[ 9518.931221][ 1] [ T4650] vb2_streamoff+0x18/0x60 [videobuf2_v4l2]
[ 9518.937390][ 1] [ T4650] uvc_queue_streamoff+0x30/0x50 [uvcvideo]
[ 9518.943557][ 1] [ T4650] uvc_ioctl_streamoff+0x40/0x68 [uvcvideo]
[ 9518.949724][ 1] [ T4650] v4l_streamoff+0x20/0x28
[ 9518.954415][ 1] [ T4650] __video_do_ioctl+0x17c/0x3e0
[ 9518.959540][ 1] [ T4650] video_usercopy+0x1d8/0x558
[ 9518.964490][ 1] [ T4650] video_ioctl2+0x14/0x1c
[ 9518.969094][ 1] [ T4650] v4l2_ioctl+0x3c/0x58
[ 9518.973526][ 1] [ T4650] do_vfs_ioctl+0x374/0x7b0
[ 9518.978304][ 1] [ T4650] ksys_ioctl+0x78/0xa8
[ 9518.982734][ 1] [ T4650] sys_ioctl+0xc/0x18
[ 9518.986991][ 1] [ T4650] __sys_trace_return+0x0/0x4
[ 9518.991943][ 1] [ T4650] Code: eb04005f 54000100 f9400040 91002042 (f9400003)
[ 9518.999153][ 1] [ T4650] ---[ end trace f7c7d3236806d9a4 ]---
To resolve this issue, a null pointer check for config->interface[i]
can be added in the usb_ifnum_to_if() function.
Signed-off-by: Jie Deng <dengjie03@kylinos.cn>
---
drivers/usb/core/usb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index e740f7852bcd..85dcda06a838 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -355,7 +355,7 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev,
if (!config)
return NULL;
for (i = 0; i < config->desc.bNumInterfaces; i++)
- if (config->interface[i]->altsetting[0]
+ if (config->interface[i] && config->interface[i]->altsetting[0]
.desc.bInterfaceNumber == ifnum)
return config->interface[i];
--
2.25.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] usb: core: fix NULL dereference in usb_ifnum_to_if() during device removal
2025-11-13 11:44 [PATCH] usb: core: fix NULL dereference in usb_ifnum_to_if() during device removal Jie Deng
@ 2025-11-13 13:28 ` Greg KH
2025-11-17 8:50 ` Jie Deng
2025-11-13 14:50 ` Alan Stern
1 sibling, 1 reply; 5+ messages in thread
From: Greg KH @ 2025-11-13 13:28 UTC (permalink / raw)
To: Jie Deng; +Cc: mathias.nyman, sakari.ailus, stern, linux-usb, linux-kernel
On Thu, Nov 13, 2025 at 07:44:11PM +0800, Jie Deng wrote:
> During USB device hot-unplug, in the time window between when
> usb_disconnect() calls usb_disable_device() to set
> dev->actconfig->interface[i] to NULL but before dev->actconfig
> is set to NULL.At this point, outside the kernel, usb_ifnum_to_if()
> is called through usb_set_interface(), and usb_ifnum_to_if() continues
> to access interface[i]->altsetting[i], triggering a null pointer.
I do not understand, sorry. What do you mean by "outside the kernel"?
> kernel log:
> [ 9518.779148][ 1] [ T4650] pc : usb_ifnum_to_if+0x34/0x50
> [ 9518.784360][ 1] [ T4650] lr : usb_hcd_alloc_bandwidth+0x260/0x348
What is the [TXXX] stuff?
> [ 9518.790439][ 1] [ T4650] sp : ffffffa25a6c79d0
> [ 9518.794868][ 1] [ T4650] x29: ffffffa25a6c79d0 x28: 0000000040045613
> [ 9518.801294][ 1] [ T4650] x27: 0000000000000000 x26: 0000000000000000
> [ 9518.807720][ 1] [ T4650] x25: ffffffa2e1597408 x24: ffffffa2e1597408
> [ 9518.814146][ 1] [ T4650] x23: ffffffa2e15974f8 x22: 0000000000000000
> [ 9518.820572][ 1] [ T4650] x21: ffffffa2e9acc000 x20: ffffffa2e6712000
> [ 9518.826998][ 1] [ T4650] x19: ffffffa2e6a8a800 x18: 0000000000000000
> [ 9518.833423][ 1] [ T4650] x17: 0000007fbb91b4b0 x16: ffffffc01016a170
> [ 9518.839849][ 1] [ T4650] x15: 0000000000000000 x14: 0845c02202702800
> [ 9518.846275][ 1] [ T4650] x13: 0000000000000001 x12: 0000000000000000
> [ 9518.852700][ 1] [ T4650] x11: 0000000000000400 x10: ffffffff89e5d720
> [ 9518.859126][ 1] [ T4650] x9 : 0000000000000000 x8 : 0000000000000000
> [ 9518.865551][ 1] [ T4650] x7 : ffffffa2fff1e440 x6 : ffffffa28175c900
> [ 9518.871977][ 1] [ T4650] x5 : 0000000000000060 x4 : ffffffa2e9bc54b0
> [ 9518.878403][ 1] [ T4650] x3 : ffffffa2e9bc54a0 x2 : ffffffa2e9bc54a0
> [ 9518.884828][ 1] [ T4650] x1 : 0000000000000001 x0 : 0000000000000000
> [ 9518.891254][ 1] [ T4650] Call trace:
> [ 9518.894817][ 1] [ T4650] usb_ifnum_to_if+0x34/0x50
> [ 9518.899681][ 1] [ T4650] usb_set_interface+0x108/0x3c8
> [ 9518.904898][ 1] [ T4650] uvc_video_stop_streaming+0x3c/0x90 [uvcvideo]
> [ 9518.911500][ 1] [ T4650] uvc_stop_streaming+0x24/0x90 [uvcvideo]
> [ 9518.917583][ 1] [ T4650] __vb2_queue_cancel+0x44/0x458 [videobuf2_common]
> [ 9518.924444][ 1] [ T4650] vb2_core_streamoff+0x20/0xb8 [videobuf2_common]
> [ 9518.931221][ 1] [ T4650] vb2_streamoff+0x18/0x60 [videobuf2_v4l2]
> [ 9518.937390][ 1] [ T4650] uvc_queue_streamoff+0x30/0x50 [uvcvideo]
> [ 9518.943557][ 1] [ T4650] uvc_ioctl_streamoff+0x40/0x68 [uvcvideo]
> [ 9518.949724][ 1] [ T4650] v4l_streamoff+0x20/0x28
> [ 9518.954415][ 1] [ T4650] __video_do_ioctl+0x17c/0x3e0
> [ 9518.959540][ 1] [ T4650] video_usercopy+0x1d8/0x558
> [ 9518.964490][ 1] [ T4650] video_ioctl2+0x14/0x1c
> [ 9518.969094][ 1] [ T4650] v4l2_ioctl+0x3c/0x58
> [ 9518.973526][ 1] [ T4650] do_vfs_ioctl+0x374/0x7b0
> [ 9518.978304][ 1] [ T4650] ksys_ioctl+0x78/0xa8
> [ 9518.982734][ 1] [ T4650] sys_ioctl+0xc/0x18
> [ 9518.986991][ 1] [ T4650] __sys_trace_return+0x0/0x4
> [ 9518.991943][ 1] [ T4650] Code: eb04005f 54000100 f9400040 91002042 (f9400003)
> [ 9518.999153][ 1] [ T4650] ---[ end trace f7c7d3236806d9a4 ]---
>
> To resolve this issue, a null pointer check for config->interface[i]
> can be added in the usb_ifnum_to_if() function.
>
> Signed-off-by: Jie Deng <dengjie03@kylinos.cn>
> ---
> drivers/usb/core/usb.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> index e740f7852bcd..85dcda06a838 100644
> --- a/drivers/usb/core/usb.c
> +++ b/drivers/usb/core/usb.c
> @@ -355,7 +355,7 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev,
> if (!config)
> return NULL;
> for (i = 0; i < config->desc.bNumInterfaces; i++)
> - if (config->interface[i]->altsetting[0]
> + if (config->interface[i] && config->interface[i]->altsetting[0]
Are you sure this is not just papering over a race? What prevents this
from changing right after you check it?
And what is causing this to happen now? What commit broke this to
require this change?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] usb: core: fix NULL dereference in usb_ifnum_to_if() during device removal
2025-11-13 11:44 [PATCH] usb: core: fix NULL dereference in usb_ifnum_to_if() during device removal Jie Deng
2025-11-13 13:28 ` Greg KH
@ 2025-11-13 14:50 ` Alan Stern
2025-11-17 5:33 ` Jie Deng
1 sibling, 1 reply; 5+ messages in thread
From: Alan Stern @ 2025-11-13 14:50 UTC (permalink / raw)
To: Jie Deng; +Cc: gregkh, mathias.nyman, sakari.ailus, linux-usb, linux-kernel
On Thu, Nov 13, 2025 at 07:44:11PM +0800, Jie Deng wrote:
> During USB device hot-unplug, in the time window between when
> usb_disconnect() calls usb_disable_device() to set
> dev->actconfig->interface[i] to NULL but before dev->actconfig
> is set to NULL.At this point, outside the kernel, usb_ifnum_to_if()
> is called through usb_set_interface(), and usb_ifnum_to_if() continues
> to access interface[i]->altsetting[i], triggering a null pointer.
> [ 9518.891254][ 1] [ T4650] Call trace:
> [ 9518.894817][ 1] [ T4650] usb_ifnum_to_if+0x34/0x50
> [ 9518.899681][ 1] [ T4650] usb_set_interface+0x108/0x3c8
> [ 9518.904898][ 1] [ T4650] uvc_video_stop_streaming+0x3c/0x90 [uvcvideo]
> [ 9518.911500][ 1] [ T4650] uvc_stop_streaming+0x24/0x90 [uvcvideo]
> [ 9518.917583][ 1] [ T4650] __vb2_queue_cancel+0x44/0x458 [videobuf2_common]
> [ 9518.924444][ 1] [ T4650] vb2_core_streamoff+0x20/0xb8 [videobuf2_common]
> [ 9518.931221][ 1] [ T4650] vb2_streamoff+0x18/0x60 [videobuf2_v4l2]
> [ 9518.937390][ 1] [ T4650] uvc_queue_streamoff+0x30/0x50 [uvcvideo]
> [ 9518.943557][ 1] [ T4650] uvc_ioctl_streamoff+0x40/0x68 [uvcvideo]
> [ 9518.949724][ 1] [ T4650] v4l_streamoff+0x20/0x28
> [ 9518.954415][ 1] [ T4650] __video_do_ioctl+0x17c/0x3e0
> [ 9518.959540][ 1] [ T4650] video_usercopy+0x1d8/0x558
> [ 9518.964490][ 1] [ T4650] video_ioctl2+0x14/0x1c
> [ 9518.969094][ 1] [ T4650] v4l2_ioctl+0x3c/0x58
> [ 9518.973526][ 1] [ T4650] do_vfs_ioctl+0x374/0x7b0
> [ 9518.978304][ 1] [ T4650] ksys_ioctl+0x78/0xa8
> [ 9518.982734][ 1] [ T4650] sys_ioctl+0xc/0x18
> [ 9518.986991][ 1] [ T4650] __sys_trace_return+0x0/0x4
> [ 9518.991943][ 1] [ T4650] Code: eb04005f 54000100 f9400040 91002042 (f9400003)
> [ 9518.999153][ 1] [ T4650] ---[ end trace f7c7d3236806d9a4 ]---
This looks like a bug in the uvc driver. usb_disable_device() unbinds
ther interface's driver before it sets dev->actconfig->interface[i] to
NULL, and the uvc driver shouldn't call usb_set_interface() after it has
been unbound.
> To resolve this issue, a null pointer check for config->interface[i]
> can be added in the usb_ifnum_to_if() function.
That won't fix the real bug. You need to change the uvc driver.
Alan Stern
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] usb: core: fix NULL dereference in usb_ifnum_to_if() during device removal
2025-11-13 14:50 ` Alan Stern
@ 2025-11-17 5:33 ` Jie Deng
0 siblings, 0 replies; 5+ messages in thread
From: Jie Deng @ 2025-11-17 5:33 UTC (permalink / raw)
To: Alan Stern; +Cc: gregkh, mathias.nyman, sakari.ailus, linux-usb, linux-kernel
在 2025/11/13 22:50, Alan Stern 写道:
> On Thu, Nov 13, 2025 at 07:44:11PM +0800, Jie Deng wrote:
>> During USB device hot-unplug, in the time window between when
>> usb_disconnect() calls usb_disable_device() to set
>> dev->actconfig->interface[i] to NULL but before dev->actconfig
>> is set to NULL.At this point, outside the kernel, usb_ifnum_to_if()
>> is called through usb_set_interface(), and usb_ifnum_to_if() continues
>> to access interface[i]->altsetting[i], triggering a null pointer.
>> [ 9518.891254][ 1] [ T4650] Call trace:
>> [ 9518.894817][ 1] [ T4650] usb_ifnum_to_if+0x34/0x50
>> [ 9518.899681][ 1] [ T4650] usb_set_interface+0x108/0x3c8
>> [ 9518.904898][ 1] [ T4650] uvc_video_stop_streaming+0x3c/0x90 [uvcvideo]
>> [ 9518.911500][ 1] [ T4650] uvc_stop_streaming+0x24/0x90 [uvcvideo]
>> [ 9518.917583][ 1] [ T4650] __vb2_queue_cancel+0x44/0x458 [videobuf2_common]
>> [ 9518.924444][ 1] [ T4650] vb2_core_streamoff+0x20/0xb8 [videobuf2_common]
>> [ 9518.931221][ 1] [ T4650] vb2_streamoff+0x18/0x60 [videobuf2_v4l2]
>> [ 9518.937390][ 1] [ T4650] uvc_queue_streamoff+0x30/0x50 [uvcvideo]
>> [ 9518.943557][ 1] [ T4650] uvc_ioctl_streamoff+0x40/0x68 [uvcvideo]
>> [ 9518.949724][ 1] [ T4650] v4l_streamoff+0x20/0x28
>> [ 9518.954415][ 1] [ T4650] __video_do_ioctl+0x17c/0x3e0
>> [ 9518.959540][ 1] [ T4650] video_usercopy+0x1d8/0x558
>> [ 9518.964490][ 1] [ T4650] video_ioctl2+0x14/0x1c
>> [ 9518.969094][ 1] [ T4650] v4l2_ioctl+0x3c/0x58
>> [ 9518.973526][ 1] [ T4650] do_vfs_ioctl+0x374/0x7b0
>> [ 9518.978304][ 1] [ T4650] ksys_ioctl+0x78/0xa8
>> [ 9518.982734][ 1] [ T4650] sys_ioctl+0xc/0x18
>> [ 9518.986991][ 1] [ T4650] __sys_trace_return+0x0/0x4
>> [ 9518.991943][ 1] [ T4650] Code: eb04005f 54000100 f9400040 91002042 (f9400003)
>> [ 9518.999153][ 1] [ T4650] ---[ end trace f7c7d3236806d9a4 ]---
> This looks like a bug in the uvc driver. usb_disable_device() unbinds
> ther interface's driver before it sets dev->actconfig->interface[i] to
> NULL, and the uvc driver shouldn't call usb_set_interface() after it has
> been unbound.
Thank you for your correction.
>
>> To resolve this issue, a null pointer check for config->interface[i]
>> can be added in the usb_ifnum_to_if() function.
> That won't fix the real bug. You need to change the uvc driver.
I will fix this issue from the uvc driver and submit a patch.
>
> Alan Stern
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] usb: core: fix NULL dereference in usb_ifnum_to_if() during device removal
2025-11-13 13:28 ` Greg KH
@ 2025-11-17 8:50 ` Jie Deng
0 siblings, 0 replies; 5+ messages in thread
From: Jie Deng @ 2025-11-17 8:50 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, linux-usb, mathias.nyman, sakari.ailus, stern
Sorry for replying late.
I'm not sure why, but I didn't receive your email in my mailbox.
>> is set to NULL.At this point, outside the kernel, usb_ifnum_to_if()
>> is called through usb_set_interface(), and usb_ifnum_to_if() continues
>> to access interface[i]->altsetting[i], triggering a null pointer.
>
>I do not understand, sorry. What do you mean by "outside the kernel"?
Sorry, I wasn't accurate in my expression. What I want to express is
the system application program.
>
>> kernel log:
>> [ 9518.779148][ 1] [ T4650] pc : usb_ifnum_to_if+0x34/0x50
>> [ 9518.784360][ 1] [ T4650] lr : usb_hcd_alloc_bandwidth+0x260/0x348
>
>What is the [TXXX] stuff?
Superfluous information. I will delete it later.
>> --- a/drivers/usb/core/usb.c
>> +++ b/drivers/usb/core/usb.c
>> @@ -355,7 +355,7 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev,
>> if (!config)
>> return NULL;
>> for (i = 0; i < config->desc.bNumInterfaces; i++)
>> - if (config->interface[i]->altsetting[0]
>> + if (config->interface[i] && config->interface[i]->altsetting[0]
>
>Are you sure this is not just papering over a race? What prevents this
>from changing right after you check it?
>
>And what is causing this to happen now? What commit broke this to
>require this change?
As you said, such a repair method cannot eliminate race behavior.
Next, I will attempt to eliminate this competitive factor from the
uvc driver side.
Thanks,
Jie Deng
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-11-17 8:51 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-13 11:44 [PATCH] usb: core: fix NULL dereference in usb_ifnum_to_if() during device removal Jie Deng
2025-11-13 13:28 ` Greg KH
2025-11-17 8:50 ` Jie Deng
2025-11-13 14:50 ` Alan Stern
2025-11-17 5:33 ` Jie Deng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®