Thomas Zimmermann 6f1b5e
From aaf7dbe07385e0b8deb7237eca2a79926bbc7091 Mon Sep 17 00:00:00 2001
Thomas Zimmermann 6f1b5e
From: Pavel Skripkin <paskripkin@gmail.com>
Thomas Zimmermann 6f1b5e
Date: Tue, 22 Mar 2022 23:04:38 +0300
Thomas Zimmermann 6f1b5e
Subject: video: fbdev: udlfb: properly check endpoint type
Thomas Zimmermann 6f1b5e
Git-commit: aaf7dbe07385e0b8deb7237eca2a79926bbc7091
Thomas Zimmermann 6f1b5e
Patch-mainline: v5.18-rc5
Thomas Zimmermann 6f1b5e
References: bsc#1152489
Thomas Zimmermann 6f1b5e
Thomas Zimmermann 6f1b5e
syzbot reported warning in usb_submit_urb, which is caused by wrong
Thomas Zimmermann 6f1b5e
endpoint type.
Thomas Zimmermann 6f1b5e
Thomas Zimmermann 6f1b5e
This driver uses out bulk endpoint for communication, so
Thomas Zimmermann 6f1b5e
let's check if this endpoint is present and bail out early if not.
Thomas Zimmermann 6f1b5e
Thomas Zimmermann 6f1b5e
Fail log:
Thomas Zimmermann 6f1b5e
Thomas Zimmermann 6f1b5e
usb 1-1: BOGUS urb xfer, pipe 3 != type 1
Thomas Zimmermann 6f1b5e
WARNING: CPU: 0 PID: 4822 at drivers/usb/core/urb.c:493 usb_submit_urb+0xd27/0x1540 drivers/usb/core/urb.c:493
Thomas Zimmermann 6f1b5e
Modules linked in:
Thomas Zimmermann 6f1b5e
CPU: 0 PID: 4822 Comm: kworker/0:3 Tainted: G        W         5.13.0-syzkaller #0
Thomas Zimmermann 6f1b5e
...
Thomas Zimmermann 6f1b5e
Workqueue: usb_hub_wq hub_event
Thomas Zimmermann 6f1b5e
RIP: 0010:usb_submit_urb+0xd27/0x1540 drivers/usb/core/urb.c:493
Thomas Zimmermann 6f1b5e
...
Thomas Zimmermann 6f1b5e
Call Trace:
Thomas Zimmermann 6f1b5e
 dlfb_submit_urb+0x89/0x160 drivers/video/fbdev/udlfb.c:1969
Thomas Zimmermann 6f1b5e
 dlfb_set_video_mode+0x21f0/0x2950 drivers/video/fbdev/udlfb.c:315
Thomas Zimmermann 6f1b5e
 dlfb_ops_set_par+0x2a3/0x840 drivers/video/fbdev/udlfb.c:1110
Thomas Zimmermann 6f1b5e
 dlfb_usb_probe.cold+0x113e/0x1f4a drivers/video/fbdev/udlfb.c:1732
Thomas Zimmermann 6f1b5e
 usb_probe_interface+0x315/0x7f0 drivers/usb/core/driver.c:396
Thomas Zimmermann 6f1b5e
Thomas Zimmermann 6f1b5e
Fixes: 88e58b1a42f8 ("Staging: add udlfb driver")
Thomas Zimmermann 6f1b5e
Reported-and-tested-by: syzbot+53ce4a4246d0fe0fee34@syzkaller.appspotmail.com
Thomas Zimmermann 6f1b5e
Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
Thomas Zimmermann 6f1b5e
Signed-off-by: Helge Deller <deller@gmx.de>
Thomas Zimmermann 6f1b5e
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Thomas Zimmermann 6f1b5e
---
Thomas Zimmermann 6f1b5e
 drivers/video/fbdev/udlfb.c | 14 ++++++++++++--
Thomas Zimmermann 6f1b5e
 1 file changed, 12 insertions(+), 2 deletions(-)
Thomas Zimmermann 6f1b5e
Thomas Zimmermann 6f1b5e
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
Thomas Zimmermann 6f1b5e
index b6ec0b8e2b725..d280733f283b1 100644
Thomas Zimmermann 6f1b5e
--- a/drivers/video/fbdev/udlfb.c
Thomas Zimmermann 6f1b5e
+++ b/drivers/video/fbdev/udlfb.c
Thomas Zimmermann 6f1b5e
@@ -1650,8 +1650,9 @@ static int dlfb_usb_probe(struct usb_interface *intf,
Thomas Zimmermann 6f1b5e
 	const struct device_attribute *attr;
Thomas Zimmermann 6f1b5e
 	struct dlfb_data *dlfb;
Thomas Zimmermann 6f1b5e
 	struct fb_info *info;
Thomas Zimmermann 6f1b5e
-	int retval = -ENOMEM;
Thomas Zimmermann 6f1b5e
+	int retval;
Thomas Zimmermann 6f1b5e
 	struct usb_device *usbdev = interface_to_usbdev(intf);
Thomas Zimmermann 6f1b5e
+	struct usb_endpoint_descriptor *out;
Thomas Zimmermann 6f1b5e
 
Thomas Zimmermann 6f1b5e
 	/* usb initialization */
Thomas Zimmermann 6f1b5e
 	dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL);
Thomas Zimmermann 6f1b5e
@@ -1665,6 +1666,12 @@ static int dlfb_usb_probe(struct usb_interface *intf,
Thomas Zimmermann 6f1b5e
 	dlfb->udev = usb_get_dev(usbdev);
Thomas Zimmermann 6f1b5e
 	usb_set_intfdata(intf, dlfb);
Thomas Zimmermann 6f1b5e
 
Thomas Zimmermann 6f1b5e
+	retval = usb_find_common_endpoints(intf->cur_altsetting, NULL, &out, NULL, NULL);
Thomas Zimmermann 6f1b5e
+	if (retval) {
Thomas Zimmermann 6f1b5e
+		dev_err(&intf->dev, "Device should have at lease 1 bulk endpoint!\n");
Thomas Zimmermann 6f1b5e
+		goto error;
Thomas Zimmermann 6f1b5e
+	}
Thomas Zimmermann 6f1b5e
+
Thomas Zimmermann 6f1b5e
 	dev_dbg(&intf->dev, "console enable=%d\n", console);
Thomas Zimmermann 6f1b5e
 	dev_dbg(&intf->dev, "fb_defio enable=%d\n", fb_defio);
Thomas Zimmermann 6f1b5e
 	dev_dbg(&intf->dev, "shadow enable=%d\n", shadow);
Thomas Zimmermann 6f1b5e
@@ -1674,6 +1681,7 @@ static int dlfb_usb_probe(struct usb_interface *intf,
Thomas Zimmermann 6f1b5e
 	if (!dlfb_parse_vendor_descriptor(dlfb, intf)) {
Thomas Zimmermann 6f1b5e
 		dev_err(&intf->dev,
Thomas Zimmermann 6f1b5e
 			"firmware not recognized, incompatible device?\n");
Thomas Zimmermann 6f1b5e
+		retval = -ENODEV;
Thomas Zimmermann 6f1b5e
 		goto error;
Thomas Zimmermann 6f1b5e
 	}
Thomas Zimmermann 6f1b5e
 
Thomas Zimmermann 6f1b5e
@@ -1687,8 +1695,10 @@ static int dlfb_usb_probe(struct usb_interface *intf,
Thomas Zimmermann 6f1b5e
 
Thomas Zimmermann 6f1b5e
 	/* allocates framebuffer driver structure, not framebuffer memory */
Thomas Zimmermann 6f1b5e
 	info = framebuffer_alloc(0, &dlfb->udev->dev);
Thomas Zimmermann 6f1b5e
-	if (!info)
Thomas Zimmermann 6f1b5e
+	if (!info) {
Thomas Zimmermann 6f1b5e
+		retval = -ENOMEM;
Thomas Zimmermann 6f1b5e
 		goto error;
Thomas Zimmermann 6f1b5e
+	}
Thomas Zimmermann 6f1b5e
 
Thomas Zimmermann 6f1b5e
 	dlfb->info = info;
Thomas Zimmermann 6f1b5e
 	info->par = dlfb;
Thomas Zimmermann 6f1b5e
-- 
Thomas Zimmermann 6f1b5e
2.36.0
Thomas Zimmermann 6f1b5e