diff options
| author | Dan Carpenter <dan.carpenter@oracle.com> | 2016-02-02 04:48:09 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-02-08 00:26:57 -0500 |
| commit | 5fae054c2b5a7c10475d2e425dfea0c567c1c5dd (patch) | |
| tree | dda71124754c5cf778acd00a8bc51c1556e7b636 /drivers/platform/goldfish | |
| parent | d40a09464401265e2894061cca388fb86e05b4be (diff) | |
goldfish: locking bugs in goldfish_pipe_read_write()
We recently messed up the error handling here. We can return with the
pipe->lock held or sometimes we unlock twice by mistake.
Fixes: 2f3be88237a3 ('goldfish_pipe: Pin pages to memory while copying and other cleanups')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/platform/goldfish')
| -rw-r--r-- | drivers/platform/goldfish/goldfish_pipe.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c index e3fab9a1d9f7..839df4aace76 100644 --- a/drivers/platform/goldfish/goldfish_pipe.c +++ b/drivers/platform/goldfish/goldfish_pipe.c | |||
| @@ -313,7 +313,7 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer, | |||
| 313 | !is_write, 0, &page, NULL); | 313 | !is_write, 0, &page, NULL); |
| 314 | up_read(¤t->mm->mmap_sem); | 314 | up_read(¤t->mm->mmap_sem); |
| 315 | if (ret < 0) | 315 | if (ret < 0) |
| 316 | return ret; | 316 | break; |
| 317 | 317 | ||
| 318 | if (dev->version) { | 318 | if (dev->version) { |
| 319 | /* Device version 1 or newer (qemu-android) expects the | 319 | /* Device version 1 or newer (qemu-android) expects the |
| @@ -400,22 +400,16 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer, | |||
| 400 | while (test_bit(wakeBit, &pipe->flags)) { | 400 | while (test_bit(wakeBit, &pipe->flags)) { |
| 401 | if (wait_event_interruptible( | 401 | if (wait_event_interruptible( |
| 402 | pipe->wake_queue, | 402 | pipe->wake_queue, |
| 403 | !test_bit(wakeBit, &pipe->flags))) { | 403 | !test_bit(wakeBit, &pipe->flags))) |
| 404 | ret = -ERESTARTSYS; | 404 | return -ERESTARTSYS; |
| 405 | break; | 405 | |
| 406 | } | 406 | if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) |
| 407 | 407 | return -EIO; | |
| 408 | if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) { | ||
| 409 | ret = -EIO; | ||
| 410 | break; | ||
| 411 | } | ||
| 412 | } | 408 | } |
| 413 | 409 | ||
| 414 | /* Try to re-acquire the lock */ | 410 | /* Try to re-acquire the lock */ |
| 415 | if (mutex_lock_interruptible(&pipe->lock)) { | 411 | if (mutex_lock_interruptible(&pipe->lock)) |
| 416 | ret = -ERESTARTSYS; | 412 | return -ERESTARTSYS; |
| 417 | break; | ||
| 418 | } | ||
| 419 | } | 413 | } |
| 420 | mutex_unlock(&pipe->lock); | 414 | mutex_unlock(&pipe->lock); |
| 421 | 415 | ||
