lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230427133350.31064-2-oneukum@suse.com>
Date:   Thu, 27 Apr 2023 15:33:43 +0200
From:   Oliver Neukum <oneukum@...e.com>
To:     wim@...ux-watchdog.org, linux@...ck-us.net,
        linux-watchdog@...r.kernel.org, linux-kernel@...r.kernel.org
Cc:     Oliver Neukum <oneukum@...e.com>
Subject: [PATCH 1/8] pwcd_usb: fix error handling in probe

If you support only one device, you need to roll back
back your counter in all cases if probe() fails.
That cannot be left to usb_pcwd_delete() because
that must be called conditionally.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Oliver Neukum <oneukum@...e.com>
---
 drivers/watchdog/pcwd_usb.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index 8202f0a6b093..3a22291d633b 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -606,7 +606,7 @@ static int usb_pcwd_probe(struct usb_interface *interface,
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_pcwd_private *usb_pcwd = NULL;
 	int pipe;
-	int retval = -ENOMEM;
+	int retval = -ENODEV;
 	int got_fw_rev;
 	unsigned char fw_rev_major, fw_rev_minor;
 	char fw_ver_str[20];
@@ -615,7 +615,7 @@ static int usb_pcwd_probe(struct usb_interface *interface,
 	cards_found++;
 	if (cards_found > 1) {
 		pr_err("This driver only supports 1 device\n");
-		return -ENODEV;
+		goto error_count;
 	}
 
 	/* get the active interface descriptor */
@@ -624,11 +624,12 @@ static int usb_pcwd_probe(struct usb_interface *interface,
 	/* check out that we have a HID device */
 	if (!(iface_desc->desc.bInterfaceClass == USB_CLASS_HID)) {
 		pr_err("The device isn't a Human Interface Device\n");
-		return -ENODEV;
+		goto error_count;
 	}
 
 	if (iface_desc->desc.bNumEndpoints < 1)
-		return -ENODEV;
+		goto error_count;
+	
 
 	/* check out the endpoint: it has to be Interrupt & IN */
 	endpoint = &iface_desc->endpoint[0].desc;
@@ -636,16 +637,17 @@ static int usb_pcwd_probe(struct usb_interface *interface,
 	if (!usb_endpoint_is_int_in(endpoint)) {
 		/* we didn't find a Interrupt endpoint with direction IN */
 		pr_err("Couldn't find an INTR & IN endpoint\n");
-		return -ENODEV;
+		goto error_count;
 	}
 
 	/* get a handle to the interrupt data pipe */
 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
 
 	/* allocate memory for our device and initialize it */
+	retval = -ENOMEM;
 	usb_pcwd = kzalloc(sizeof(struct usb_pcwd_private), GFP_KERNEL);
 	if (usb_pcwd == NULL)
-		goto error;
+		goto error_count;
 
 	usb_pcwd_device = usb_pcwd;
 
@@ -661,13 +663,13 @@ static int usb_pcwd_probe(struct usb_interface *interface,
 					GFP_KERNEL, &usb_pcwd->intr_dma);
 	if (!usb_pcwd->intr_buffer) {
 		pr_err("Out of memory\n");
-		goto error;
+		goto error_delete;
 	}
 
 	/* allocate the urb's */
 	usb_pcwd->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!usb_pcwd->intr_urb)
-		goto error;
+		goto error_delete;
 
 	/* initialise the intr urb's */
 	usb_fill_int_urb(usb_pcwd->intr_urb, udev, pipe,
@@ -680,7 +682,7 @@ static int usb_pcwd_probe(struct usb_interface *interface,
 	if (usb_submit_urb(usb_pcwd->intr_urb, GFP_KERNEL)) {
 		pr_err("Problem registering interrupt URB\n");
 		retval = -EIO; /* failure */
-		goto error;
+		goto error_delete;
 	}
 
 	/* The device exists and can be communicated with */
@@ -723,7 +725,7 @@ static int usb_pcwd_probe(struct usb_interface *interface,
 	retval = register_reboot_notifier(&usb_pcwd_notifier);
 	if (retval != 0) {
 		pr_err("cannot register reboot notifier (err=%d)\n", retval);
-		goto error;
+		goto error_delete;
 	}
 
 	retval = misc_register(&usb_pcwd_temperature_miscdev);
@@ -752,10 +754,12 @@ static int usb_pcwd_probe(struct usb_interface *interface,
 	misc_deregister(&usb_pcwd_temperature_miscdev);
 err_out_unregister_reboot:
 	unregister_reboot_notifier(&usb_pcwd_notifier);
-error:
+error_delete:
 	if (usb_pcwd)
 		usb_pcwd_delete(usb_pcwd);
 	usb_pcwd_device = NULL;
+error_count:
+	cards_found--;
 	return retval;
 }
 
-- 
2.40.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ