Skip to content

Commit 98c6a7a

Browse files
Ying Luvijay-suman
authored andcommitted
usbnet:fix NPE during rx_complete
commit 51de3600093429e3b712e5f091d767babc5dd6df upstream. Missing usbnet_going_away Check in Critical Path. The usb_submit_urb function lacks a usbnet_going_away validation, whereas __usbnet_queue_skb includes this check. This inconsistency creates a race condition where: A URB request may succeed, but the corresponding SKB data fails to be queued. Subsequent processes: (e.g., rx_complete → defer_bh → __skb_unlink(skb, list)) attempt to access skb->next, triggering a NULL pointer dereference (Kernel Panic). Fixes: 04e9068 ("usbnet: fix cyclical race on disconnect with work queue") Cc: [email protected] Signed-off-by: Ying Lu <[email protected]> Link: https://patch.msgid.link/4c9ef2efaa07eb7f9a5042b74348a67e5a3a7aea.1743584159.git.luying1@xiaomi.com Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> (cherry picked from commit 95789c2f94fd29dce8759f9766baa333f749287c) FOF: 0525 Signed-off-by: Vijayendra Suman <[email protected]>
1 parent e35d78e commit 98c6a7a

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

drivers/net/usb/usbnet.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,8 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
522522
netif_device_present (dev->net) &&
523523
test_bit(EVENT_DEV_OPEN, &dev->flags) &&
524524
!test_bit (EVENT_RX_HALT, &dev->flags) &&
525-
!test_bit (EVENT_DEV_ASLEEP, &dev->flags)) {
525+
!test_bit (EVENT_DEV_ASLEEP, &dev->flags) &&
526+
!usbnet_going_away(dev)) {
526527
switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) {
527528
case -EPIPE:
528529
usbnet_defer_kevent (dev, EVENT_RX_HALT);
@@ -543,8 +544,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
543544
tasklet_schedule (&dev->bh);
544545
break;
545546
case 0:
546-
if (!usbnet_going_away(dev))
547-
__usbnet_queue_skb(&dev->rxq, skb, rx_start);
547+
__usbnet_queue_skb(&dev->rxq, skb, rx_start);
548548
}
549549
} else {
550550
netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");

0 commit comments

Comments
 (0)