Re: INFO: task hung in wdm_flush

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



#syz test: https://github.com/google/kasan.git e96407b4

>From d3d9edf17e33889e0fc4238f3d03a2dce7af30e1 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@xxxxxxxx>
Date: Tue, 19 Nov 2019 14:09:41 +0100
Subject: [PATCH] cdc-wdm: add timeout in wdm_flush()

wdm_flush() will wait forever for IO to end. If a device
happens to crash exactly at that time and becomes unresponsive or
turns rogue and malicious exactly at that time, we get unkillable
tasks. The solition is to add a sensible timeout.

Signed-off-by: Oliver Neukum <oneukum@xxxxxxxx>
---
 drivers/usb/class/cdc-wdm.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index f9f7c8a5e091..17de5c88a325 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -587,8 +587,9 @@ static ssize_t wdm_read
 static int wdm_flush(struct file *file, fl_owner_t id)
 {
 	struct wdm_device *desc = file->private_data;
+	int timeout;
 
-	wait_event(desc->wait,
+	timeout = wait_event_timeout(desc->wait,
 			/*
 			 * needs both flags. We cannot do with one
 			 * because resetting it would cause a race
@@ -596,7 +597,14 @@ static int wdm_flush(struct file *file, fl_owner_t id)
 			 * a disconnect
 			 */
 			!test_bit(WDM_IN_USE, &desc->flags) ||
-			test_bit(WDM_DISCONNECTING, &desc->flags));
+			test_bit(WDM_DISCONNECTING, &desc->flags),
+			/* pulled out of thin air */
+			30 * HZ);
+
+	if (!timeout) {
+		usb_kill_urb(desc->command);
+		return -EIO;
+	}
 
 	/* cannot dereference desc->intf if WDM_DISCONNECTING */
 	if (test_bit(WDM_DISCONNECTING, &desc->flags))
-- 
2.16.4




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux