From patchwork Tue Jul 11 17:38:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Stern X-Patchwork-Id: 703166 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7E34C0015E for ; Tue, 11 Jul 2023 17:38:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231277AbjGKRiJ (ORCPT ); Tue, 11 Jul 2023 13:38:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44460 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230495AbjGKRiI (ORCPT ); Tue, 11 Jul 2023 13:38:08 -0400 Received: from netrider.rowland.org (netrider.rowland.org [192.131.102.5]) by lindbergh.monkeyblade.net (Postfix) with SMTP id AD4BBE49 for ; Tue, 11 Jul 2023 10:38:01 -0700 (PDT) Received: (qmail 1366713 invoked by uid 1000); 11 Jul 2023 13:38:00 -0400 Date: Tue, 11 Jul 2023 13:38:00 -0400 From: Alan Stern To: "David S. Miller" Cc: Oliver Neukum , netdev@vger.kernel.org, USB mailing list Subject: [PATCH] net: usbnet: Fix WARNING in usbnet_start_xmit/usb_submit_urb Message-ID: <38ff51d4-2734-4dd7-8638-ae2fc8572c0d@rowland.harvard.edu> References: <000000000000a56e9105d0cec021@google.com> <000000000000e298cd05fecc07d4@google.com> <0f685f2f-06df-4cf2-9387-34f5e3c8b7b7@rowland.harvard.edu> <7330e6c0-eb73-499e-8699-dc1754d90cad@rowland.harvard.edu> <413fb529-477c-7ac9-881e-550b4613d38c@suse.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <413fb529-477c-7ac9-881e-550b4613d38c@suse.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The syzbot fuzzer identified a problem in the usbnet driver: usb 1-1: BOGUS urb xfer, pipe 3 != type 1 WARNING: CPU: 0 PID: 754 at drivers/usb/core/urb.c:504 usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504 Modules linked in: CPU: 0 PID: 754 Comm: kworker/0:2 Not tainted 6.4.0-rc7-syzkaller-00014-g692b7dc87ca6 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023 Workqueue: mld mld_ifc_work RIP: 0010:usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504 Code: 7c 24 18 e8 2c b4 5b fb 48 8b 7c 24 18 e8 42 07 f0 fe 41 89 d8 44 89 e1 4c 89 ea 48 89 c6 48 c7 c7 a0 c9 fc 8a e8 5a 6f 23 fb <0f> 0b e9 58 f8 ff ff e8 fe b3 5b fb 48 81 c5 c0 05 00 00 e9 84 f7 RSP: 0018:ffffc9000463f568 EFLAGS: 00010086 RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000 RDX: ffff88801eb28000 RSI: ffffffff814c03b7 RDI: 0000000000000001 RBP: ffff8881443b7190 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000003 R13: ffff88802a77cb18 R14: 0000000000000003 R15: ffff888018262500 FS: 0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000556a99c15a18 CR3: 0000000028c71000 CR4: 0000000000350ef0 Call Trace: usbnet_start_xmit+0xfe5/0x2190 drivers/net/usb/usbnet.c:1453 __netdev_start_xmit include/linux/netdevice.h:4918 [inline] netdev_start_xmit include/linux/netdevice.h:4932 [inline] xmit_one net/core/dev.c:3578 [inline] dev_hard_start_xmit+0x187/0x700 net/core/dev.c:3594 ... This bug is caused by the fact that usbnet trusts the bulk endpoint addresses its probe routine receives in the driver_info structure, and it does not check to see that these endpoints actually exist and have the expected type and directions. The fix is simply to add such a check. Reported-and-tested-by: syzbot+63ee658b9a100ffadbe2@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-usb/000000000000a56e9105d0cec021@google.com/ Signed-off-by: Alan Stern CC: Oliver Neukum --- drivers/net/usb/usbnet.c | 5 +++++ 1 file changed, 5 insertions(+) Index: usb-devel/drivers/net/usb/usbnet.c =================================================================== --- usb-devel.orig/drivers/net/usb/usbnet.c +++ usb-devel/drivers/net/usb/usbnet.c @@ -1775,6 +1775,9 @@ usbnet_probe (struct usb_interface *udev } else if (!info->in || !info->out) status = usbnet_get_endpoints (dev, udev); else { + u8 ep_addrs[3] = { + info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0}; + dev->in = usb_rcvbulkpipe (xdev, info->in); dev->out = usb_sndbulkpipe (xdev, info->out); if (!(info->flags & FLAG_NO_SETINT)) @@ -1784,6 +1787,8 @@ usbnet_probe (struct usb_interface *udev else status = 0; + if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs)) + status = -EINVAL; } if (status >= 0 && dev->status) status = init_status (dev, udev);