@@ -58,6 +58,9 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
#define WDM_MAX 16
+/* flush() is uninterruptible, but we cannot wait forever */
+#define WDM_FLUSH_TIMEOUT (30 * HZ)
+
/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */
#define WDM_DEFAULT_BUFSIZE 256
@@ -589,7 +592,7 @@ static int wdm_flush(struct file *file, fl_owner_t id)
struct wdm_device *desc = file->private_data;
int rv;
- wait_event(desc->wait,
+ rv = wait_event_timeout(desc->wait,
/*
* needs both flags. We cannot do with one
* because resetting it would cause a race
@@ -597,11 +600,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),
+ WDM_FLUSH_TIMEOUT);
/* cannot dereference desc->intf if WDM_DISCONNECTING */
if (test_bit(WDM_DISCONNECTING, &desc->flags))
return -ENODEV;
+ if (!rv)
+ return -EIO;
rv = desc->werr;
if (rv < 0)
dev_err(&desc->intf->dev, "Error in flush path: %d\n",
@@ -659,6 +665,14 @@ static int wdm_open(struct inode *inode, struct file *file)
goto out;
}
+ /*
+ * in case flush() had timed out
+ */
+ usb_kill_urb(desc->command);
+ spin_lock_irq(&desc->iuspin);
+ desc->werr = 0;
+ spin_unlock_irq(&desc->iuspin);
+
/* using write lock to protect desc->count */
mutex_lock(&desc->wlock);
if (!desc->count++) {
Malicious or defective hardware may cease communication while flush() is running. In last consequence we need a timeout, as hardware that remains silent must be ignored. The 30 seconds are coming out of thin air. Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: Oliver Neukum <oneukum@suse.com> --- drivers/usb/class/cdc-wdm.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)