Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

USB: core: Limit the length of unkillable synchronous timeouts

The usb_control_msg(), usb_bulk_msg(), and usb_interrupt_msg() APIs in
usbcore allow unlimited timeout durations. And since they use
uninterruptible waits, this leaves open the possibility of hanging a
task for an indefinitely long time, with no way to kill it short of
unplugging the target device.

To prevent this sort of problem, enforce a maximum limit on the length
of these unkillable timeouts. The limit chosen here, somewhat
arbitrarily, is 60 seconds. On many systems (although not all) this
is short enough to avoid triggering the kernel's hung-task detector.

In addition, clear up the ambiguity of negative timeout values by
treating them the same as 0, i.e., using the maximum allowed timeout.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/linux-usb/3acfe838-6334-4f6d-be7c-4bb01704b33d@rowland.harvard.edu/
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
CC: stable@vger.kernel.org
Link: https://patch.msgid.link/15fc9773-a007-47b0-a703-df89a8cf83dd@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alan Stern and committed by
Greg Kroah-Hartman
1015c27a 7784caa4

+16 -14
+13 -14
drivers/usb/core/message.c
··· 45 45 * Starts urb and waits for completion or timeout. 46 46 * Whether or not the wait is killable depends on the flag passed in. 47 47 * For example, compare usb_bulk_msg() and usb_bulk_msg_killable(). 48 + * 49 + * For non-killable waits, we enforce a maximum limit on the timeout value. 48 50 */ 49 51 static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length, 50 52 bool killable) ··· 63 61 if (unlikely(retval)) 64 62 goto out; 65 63 66 - expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; 64 + if (!killable && (timeout <= 0 || timeout > USB_MAX_SYNCHRONOUS_TIMEOUT)) 65 + timeout = USB_MAX_SYNCHRONOUS_TIMEOUT; 66 + expire = (timeout > 0) ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; 67 67 if (killable) 68 68 rc = wait_for_completion_killable_timeout(&ctx.done, expire); 69 69 else ··· 131 127 * @index: USB message index value 132 128 * @data: pointer to the data to send 133 129 * @size: length in bytes of the data to send 134 - * @timeout: time in msecs to wait for the message to complete before timing 135 - * out (if 0 the wait is forever) 130 + * @timeout: time in msecs to wait for the message to complete before timing out 136 131 * 137 132 * Context: task context, might sleep. 138 133 * ··· 186 183 * @index: USB message index value 187 184 * @driver_data: pointer to the data to send 188 185 * @size: length in bytes of the data to send 189 - * @timeout: time in msecs to wait for the message to complete before timing 190 - * out (if 0 the wait is forever) 186 + * @timeout: time in msecs to wait for the message to complete before timing out 191 187 * @memflags: the flags for memory allocation for buffers 192 188 * 193 189 * Context: !in_interrupt () ··· 244 242 * @index: USB message index value 245 243 * @driver_data: pointer to the data to be filled in by the message 246 244 * @size: length in bytes of the data to be received 247 - * @timeout: time in msecs to wait for the message to complete before timing 248 - * out (if 0 the wait is forever) 245 + * @timeout: time in msecs to wait for the message to complete before timing out 249 246 * @memflags: the flags for memory allocation for buffers 250 247 * 251 248 * Context: !in_interrupt () ··· 315 314 * @len: length in bytes of the data to send 316 315 * @actual_length: pointer to a location to put the actual length transferred 317 316 * in bytes 318 - * @timeout: time in msecs to wait for the message to complete before 319 - * timing out (if 0 the wait is forever) 317 + * @timeout: time in msecs to wait for the message to complete before timing out 320 318 * 321 319 * Context: task context, might sleep. 322 320 * ··· 347 347 * @len: length in bytes of the data to send 348 348 * @actual_length: pointer to a location to put the actual length transferred 349 349 * in bytes 350 - * @timeout: time in msecs to wait for the message to complete before 351 - * timing out (if 0 the wait is forever) 350 + * @timeout: time in msecs to wait for the message to complete before timing out 352 351 * 353 352 * Context: task context, might sleep. 354 353 * ··· 407 408 * @actual_length: pointer to a location to put the actual length transferred 408 409 * in bytes 409 410 * @timeout: time in msecs to wait for the message to complete before 410 - * timing out (if 0 the wait is forever) 411 + * timing out (if <= 0, the wait is as long as possible) 411 412 * 412 413 * Context: task context, might sleep. 413 414 * 414 - * This function is just like usb_blk_msg() except that it waits in a 415 - * killable state. 415 + * This function is just like usb_blk_msg(), except that it waits in a 416 + * killable state and there is no limit on the timeout length. 416 417 * 417 418 * Return: 418 419 * If successful, 0. Otherwise a negative error number. The number of actual
+3
include/linux/usb.h
··· 1862 1862 * SYNCHRONOUS CALL SUPPORT * 1863 1863 *-------------------------------------------------------------------*/ 1864 1864 1865 + /* Maximum value allowed for timeout in synchronous routines below */ 1866 + #define USB_MAX_SYNCHRONOUS_TIMEOUT 60000 /* ms */ 1867 + 1865 1868 extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, 1866 1869 __u8 request, __u8 requesttype, __u16 value, __u16 index, 1867 1870 void *data, __u16 size, int timeout);