diff options
author | Oliver Neukum <oneukum@suse.com> | 2019-08-08 05:28:54 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-08-08 06:43:18 -0400 |
commit | 2ca359f4f8b954b3a9d15a89f22a8b7283e7669f (patch) | |
tree | 417c4dfe45505f34e8ab6ad4a80f76baeefd08ce | |
parent | c43f28dfdc4654e738aa6d3fd08a105b2bee758d (diff) |
Revert "USB: rio500: simplify locking"
This reverts commit d710734b06770814de2bfa2819420fb5df7f3a81.
This simplification causes a deadlock.
Reported-by: syzbot+7bbcbe9c9ff0cd49592a@syzkaller.appspotmail.com
Fixes: d710734b0677 ("USB: rio500: simplify locking")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Oliver Neukum <oneukum@suse.com>
Link: https://lore.kernel.org/r/20190808092854.23519-1-oneukum@suse.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/misc/rio500.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 27e9c78a791e..a32d61a79ab8 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -51,6 +51,7 @@ struct rio_usb_data { | |||
51 | char *obuf, *ibuf; /* transfer buffers */ | 51 | char *obuf, *ibuf; /* transfer buffers */ |
52 | char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ | 52 | char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ |
53 | wait_queue_head_t wait_q; /* for timeouts */ | 53 | wait_queue_head_t wait_q; /* for timeouts */ |
54 | struct mutex lock; /* general race avoidance */ | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | static DEFINE_MUTEX(rio500_mutex); | 57 | static DEFINE_MUTEX(rio500_mutex); |
@@ -62,8 +63,10 @@ static int open_rio(struct inode *inode, struct file *file) | |||
62 | 63 | ||
63 | /* against disconnect() */ | 64 | /* against disconnect() */ |
64 | mutex_lock(&rio500_mutex); | 65 | mutex_lock(&rio500_mutex); |
66 | mutex_lock(&(rio->lock)); | ||
65 | 67 | ||
66 | if (rio->isopen || !rio->present) { | 68 | if (rio->isopen || !rio->present) { |
69 | mutex_unlock(&(rio->lock)); | ||
67 | mutex_unlock(&rio500_mutex); | 70 | mutex_unlock(&rio500_mutex); |
68 | return -EBUSY; | 71 | return -EBUSY; |
69 | } | 72 | } |
@@ -71,6 +74,7 @@ static int open_rio(struct inode *inode, struct file *file) | |||
71 | 74 | ||
72 | init_waitqueue_head(&rio->wait_q); | 75 | init_waitqueue_head(&rio->wait_q); |
73 | 76 | ||
77 | mutex_unlock(&(rio->lock)); | ||
74 | 78 | ||
75 | dev_info(&rio->rio_dev->dev, "Rio opened.\n"); | 79 | dev_info(&rio->rio_dev->dev, "Rio opened.\n"); |
76 | mutex_unlock(&rio500_mutex); | 80 | mutex_unlock(&rio500_mutex); |
@@ -84,6 +88,7 @@ static int close_rio(struct inode *inode, struct file *file) | |||
84 | 88 | ||
85 | /* against disconnect() */ | 89 | /* against disconnect() */ |
86 | mutex_lock(&rio500_mutex); | 90 | mutex_lock(&rio500_mutex); |
91 | mutex_lock(&(rio->lock)); | ||
87 | 92 | ||
88 | rio->isopen = 0; | 93 | rio->isopen = 0; |
89 | if (!rio->present) { | 94 | if (!rio->present) { |
@@ -95,6 +100,7 @@ static int close_rio(struct inode *inode, struct file *file) | |||
95 | } else { | 100 | } else { |
96 | dev_info(&rio->rio_dev->dev, "Rio closed.\n"); | 101 | dev_info(&rio->rio_dev->dev, "Rio closed.\n"); |
97 | } | 102 | } |
103 | mutex_unlock(&(rio->lock)); | ||
98 | mutex_unlock(&rio500_mutex); | 104 | mutex_unlock(&rio500_mutex); |
99 | return 0; | 105 | return 0; |
100 | } | 106 | } |
@@ -109,7 +115,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) | |||
109 | int retries; | 115 | int retries; |
110 | int retval=0; | 116 | int retval=0; |
111 | 117 | ||
112 | mutex_lock(&rio500_mutex); | 118 | mutex_lock(&(rio->lock)); |
113 | /* Sanity check to make sure rio is connected, powered, etc */ | 119 | /* Sanity check to make sure rio is connected, powered, etc */ |
114 | if (rio->present == 0 || rio->rio_dev == NULL) { | 120 | if (rio->present == 0 || rio->rio_dev == NULL) { |
115 | retval = -ENODEV; | 121 | retval = -ENODEV; |
@@ -253,7 +259,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) | |||
253 | 259 | ||
254 | 260 | ||
255 | err_out: | 261 | err_out: |
256 | mutex_unlock(&rio500_mutex); | 262 | mutex_unlock(&(rio->lock)); |
257 | return retval; | 263 | return retval; |
258 | } | 264 | } |
259 | 265 | ||
@@ -273,12 +279,12 @@ write_rio(struct file *file, const char __user *buffer, | |||
273 | int errn = 0; | 279 | int errn = 0; |
274 | int intr; | 280 | int intr; |
275 | 281 | ||
276 | intr = mutex_lock_interruptible(&rio500_mutex); | 282 | intr = mutex_lock_interruptible(&(rio->lock)); |
277 | if (intr) | 283 | if (intr) |
278 | return -EINTR; | 284 | return -EINTR; |
279 | /* Sanity check to make sure rio is connected, powered, etc */ | 285 | /* Sanity check to make sure rio is connected, powered, etc */ |
280 | if (rio->present == 0 || rio->rio_dev == NULL) { | 286 | if (rio->present == 0 || rio->rio_dev == NULL) { |
281 | mutex_unlock(&rio500_mutex); | 287 | mutex_unlock(&(rio->lock)); |
282 | return -ENODEV; | 288 | return -ENODEV; |
283 | } | 289 | } |
284 | 290 | ||
@@ -301,7 +307,7 @@ write_rio(struct file *file, const char __user *buffer, | |||
301 | goto error; | 307 | goto error; |
302 | } | 308 | } |
303 | if (signal_pending(current)) { | 309 | if (signal_pending(current)) { |
304 | mutex_unlock(&rio500_mutex); | 310 | mutex_unlock(&(rio->lock)); |
305 | return bytes_written ? bytes_written : -EINTR; | 311 | return bytes_written ? bytes_written : -EINTR; |
306 | } | 312 | } |
307 | 313 | ||
@@ -339,12 +345,12 @@ write_rio(struct file *file, const char __user *buffer, | |||
339 | buffer += copy_size; | 345 | buffer += copy_size; |
340 | } while (count > 0); | 346 | } while (count > 0); |
341 | 347 | ||
342 | mutex_unlock(&rio500_mutex); | 348 | mutex_unlock(&(rio->lock)); |
343 | 349 | ||
344 | return bytes_written ? bytes_written : -EIO; | 350 | return bytes_written ? bytes_written : -EIO; |
345 | 351 | ||
346 | error: | 352 | error: |
347 | mutex_unlock(&rio500_mutex); | 353 | mutex_unlock(&(rio->lock)); |
348 | return errn; | 354 | return errn; |
349 | } | 355 | } |
350 | 356 | ||
@@ -361,12 +367,12 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
361 | char *ibuf; | 367 | char *ibuf; |
362 | int intr; | 368 | int intr; |
363 | 369 | ||
364 | intr = mutex_lock_interruptible(&rio500_mutex); | 370 | intr = mutex_lock_interruptible(&(rio->lock)); |
365 | if (intr) | 371 | if (intr) |
366 | return -EINTR; | 372 | return -EINTR; |
367 | /* Sanity check to make sure rio is connected, powered, etc */ | 373 | /* Sanity check to make sure rio is connected, powered, etc */ |
368 | if (rio->present == 0 || rio->rio_dev == NULL) { | 374 | if (rio->present == 0 || rio->rio_dev == NULL) { |
369 | mutex_unlock(&rio500_mutex); | 375 | mutex_unlock(&(rio->lock)); |
370 | return -ENODEV; | 376 | return -ENODEV; |
371 | } | 377 | } |
372 | 378 | ||
@@ -377,11 +383,11 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
377 | 383 | ||
378 | while (count > 0) { | 384 | while (count > 0) { |
379 | if (signal_pending(current)) { | 385 | if (signal_pending(current)) { |
380 | mutex_unlock(&rio500_mutex); | 386 | mutex_unlock(&(rio->lock)); |
381 | return read_count ? read_count : -EINTR; | 387 | return read_count ? read_count : -EINTR; |
382 | } | 388 | } |
383 | if (!rio->rio_dev) { | 389 | if (!rio->rio_dev) { |
384 | mutex_unlock(&rio500_mutex); | 390 | mutex_unlock(&(rio->lock)); |
385 | return -ENODEV; | 391 | return -ENODEV; |
386 | } | 392 | } |
387 | this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; | 393 | this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; |
@@ -399,7 +405,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
399 | count = this_read = partial; | 405 | count = this_read = partial; |
400 | } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ | 406 | } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ |
401 | if (!maxretry--) { | 407 | if (!maxretry--) { |
402 | mutex_unlock(&rio500_mutex); | 408 | mutex_unlock(&(rio->lock)); |
403 | dev_err(&rio->rio_dev->dev, | 409 | dev_err(&rio->rio_dev->dev, |
404 | "read_rio: maxretry timeout\n"); | 410 | "read_rio: maxretry timeout\n"); |
405 | return -ETIME; | 411 | return -ETIME; |
@@ -409,19 +415,19 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
409 | finish_wait(&rio->wait_q, &wait); | 415 | finish_wait(&rio->wait_q, &wait); |
410 | continue; | 416 | continue; |
411 | } else if (result != -EREMOTEIO) { | 417 | } else if (result != -EREMOTEIO) { |
412 | mutex_unlock(&rio500_mutex); | 418 | mutex_unlock(&(rio->lock)); |
413 | dev_err(&rio->rio_dev->dev, | 419 | dev_err(&rio->rio_dev->dev, |
414 | "Read Whoops - result:%d partial:%u this_read:%u\n", | 420 | "Read Whoops - result:%d partial:%u this_read:%u\n", |
415 | result, partial, this_read); | 421 | result, partial, this_read); |
416 | return -EIO; | 422 | return -EIO; |
417 | } else { | 423 | } else { |
418 | mutex_unlock(&rio500_mutex); | 424 | mutex_unlock(&(rio->lock)); |
419 | return (0); | 425 | return (0); |
420 | } | 426 | } |
421 | 427 | ||
422 | if (this_read) { | 428 | if (this_read) { |
423 | if (copy_to_user(buffer, ibuf, this_read)) { | 429 | if (copy_to_user(buffer, ibuf, this_read)) { |
424 | mutex_unlock(&rio500_mutex); | 430 | mutex_unlock(&(rio->lock)); |
425 | return -EFAULT; | 431 | return -EFAULT; |
426 | } | 432 | } |
427 | count -= this_read; | 433 | count -= this_read; |
@@ -429,7 +435,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
429 | buffer += this_read; | 435 | buffer += this_read; |
430 | } | 436 | } |
431 | } | 437 | } |
432 | mutex_unlock(&rio500_mutex); | 438 | mutex_unlock(&(rio->lock)); |
433 | return read_count; | 439 | return read_count; |
434 | } | 440 | } |
435 | 441 | ||
@@ -494,6 +500,8 @@ static int probe_rio(struct usb_interface *intf, | |||
494 | } | 500 | } |
495 | dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf); | 501 | dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf); |
496 | 502 | ||
503 | mutex_init(&(rio->lock)); | ||
504 | |||
497 | usb_set_intfdata (intf, rio); | 505 | usb_set_intfdata (intf, rio); |
498 | rio->present = 1; | 506 | rio->present = 1; |
499 | bail_out: | 507 | bail_out: |
@@ -511,10 +519,12 @@ static void disconnect_rio(struct usb_interface *intf) | |||
511 | if (rio) { | 519 | if (rio) { |
512 | usb_deregister_dev(intf, &usb_rio_class); | 520 | usb_deregister_dev(intf, &usb_rio_class); |
513 | 521 | ||
522 | mutex_lock(&(rio->lock)); | ||
514 | if (rio->isopen) { | 523 | if (rio->isopen) { |
515 | rio->isopen = 0; | 524 | rio->isopen = 0; |
516 | /* better let it finish - the release will do whats needed */ | 525 | /* better let it finish - the release will do whats needed */ |
517 | rio->rio_dev = NULL; | 526 | rio->rio_dev = NULL; |
527 | mutex_unlock(&(rio->lock)); | ||
518 | mutex_unlock(&rio500_mutex); | 528 | mutex_unlock(&rio500_mutex); |
519 | return; | 529 | return; |
520 | } | 530 | } |
@@ -524,6 +534,7 @@ static void disconnect_rio(struct usb_interface *intf) | |||
524 | dev_info(&intf->dev, "USB Rio disconnected.\n"); | 534 | dev_info(&intf->dev, "USB Rio disconnected.\n"); |
525 | 535 | ||
526 | rio->present = 0; | 536 | rio->present = 0; |
537 | mutex_unlock(&(rio->lock)); | ||
527 | } | 538 | } |
528 | mutex_unlock(&rio500_mutex); | 539 | mutex_unlock(&rio500_mutex); |
529 | } | 540 | } |