usb: usbtmc: Fix erroneous get_stb ioctl error returns
authorDave Penkler <dpenkler@gmail.com>
Fri, 2 May 2025 07:09:39 +0000 (09:09 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 May 2025 07:28:54 +0000 (09:28 +0200)
wait_event_interruptible_timeout returns a long
The return was being assigned to an int causing an integer overflow when
the remaining jiffies > INT_MAX resulting in random error returns.

Use a long return value and convert to int ioctl return only on error.

When the return value of wait_event_interruptible_timeout was <= INT_MAX
the number of remaining jiffies was returned which has no meaning for the
user. Return 0 on success.

Reported-by: Michael Katzmann <vk2bea@gmail.com>
Fixes: dbf3e7f654c0 ("Implement an ioctl to support the USMTMC-USB488 READ_STATUS_BYTE operation.")
Cc: stable@vger.kernel.org
Signed-off-by: Dave Penkler <dpenkler@gmail.com>
Link: https://lore.kernel.org/r/20250502070941.31819-2-dpenkler@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/class/usbtmc.c

index 634c3bcbb413e48e4221549351b524e7a86535d3..e91f11c1ab5fde837240068100b93db75697900c 100644 (file)
@@ -482,6 +482,7 @@ static int usbtmc_get_stb(struct usbtmc_file_data *file_data, __u8 *stb)
        u8 *buffer;
        u8 tag;
        int rv;
+       long wait_rv;
 
        dev_dbg(dev, "Enter ioctl_read_stb iin_ep_present: %d\n",
                data->iin_ep_present);
@@ -511,16 +512,17 @@ static int usbtmc_get_stb(struct usbtmc_file_data *file_data, __u8 *stb)
        }
 
        if (data->iin_ep_present) {
-               rv = wait_event_interruptible_timeout(
+               wait_rv = wait_event_interruptible_timeout(
                        data->waitq,
                        atomic_read(&data->iin_data_valid) != 0,
                        file_data->timeout);
-               if (rv < 0) {
-                       dev_dbg(dev, "wait interrupted %d\n", rv);
+               if (wait_rv < 0) {
+                       dev_dbg(dev, "wait interrupted %ld\n", wait_rv);
+                       rv = wait_rv;
                        goto exit;
                }
 
-               if (rv == 0) {
+               if (wait_rv == 0) {
                        dev_dbg(dev, "wait timed out\n");
                        rv = -ETIMEDOUT;
                        goto exit;
@@ -539,6 +541,8 @@ static int usbtmc_get_stb(struct usbtmc_file_data *file_data, __u8 *stb)
 
        dev_dbg(dev, "stb:0x%02x received %d\n", (unsigned int)*stb, rv);
 
+       rv = 0;
+
  exit:
        /* bump interrupt bTag */
        data->iin_bTag += 1;