[PATCH v2] usbip: usbip_host: fix null pointer dereference in

Jeffin Philip <[email protected]>
Newsgroups org.kernel.vger.stable,org.kernel.vger.linux-kernel,org.kernel.vger.linux-usb
Message-ID <[email protected]>
rebind_store calls do_rebind which dereferences udev without
checking if it is NULL. If busid is registered using match_busid
but the device is never bound to the driver or it is never present
in the first place, it triggers a null pointer dereference when we
attempt to rebind the device. Fix this by checking explicitly for
udev first and returning -ENODEV if udev is NULL. Add usb_get_dev
in addition to the null check to get a reference to udev to prevent
udev from becoming NULL after the check. Drop the reference after
using it in do_rebind().

Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=af76b01c9a0f0ab60fb0
Fixes: 4bfb141bc013 ("usbip: usbip_host: fix to hold parent lock for device_attach() calls")
Cc: [email protected]
Signed-off-by: Jeffin Philip <[email protected]>
---
Changes in v2:
 - Addressed concerns raised by the maintainer in v1 discussion
   - Added usb_get_dev() to get a reference to udev preventing
     it from becoming null after the null check. Drop the reference
     after using it in do_rebind()
---
 drivers/usb/usbip/stub_main.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c
index 79110a69d697..c911626427dc 100644
--- a/drivers/usb/usbip/stub_main.c
+++ b/drivers/usb/usbip/stub_main.c
@@ -256,12 +256,21 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf,
 	if (!bid)
 		return -ENODEV;
 
+	if (!bid->udev) {
+		put_busid_priv(bid);
+		return -ENODEV;
+	}
+
+	/* get a reference to udev to prevent it from becoming NULL */
+	usb_get_dev(bid->udev);
 	/* mark the device for deletion so probe ignores it during rescan */
 	bid->status = STUB_BUSID_OTHER;
 	/* release the busid lock */
 	put_busid_priv(bid);
 
 	ret = do_rebind((char *) buf, bid);
+	/* we finished using udev and don't need the reference anymore, drop it */
+	usb_put_dev(bid->udev);
 	if (ret < 0)
 		return ret;
 
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.