diff options
author | John Sheu <sheu@google.com> | 2013-02-11 20:50:24 -0500 |
---|---|---|
committer | Sumit Semwal <sumit.semwal@linaro.org> | 2013-02-27 04:44:02 -0500 |
commit | 495c10cc1c0c359871d5bef32dd173252fc17995 (patch) | |
tree | 5cc942ec2c74496dd3774dffff5cdde67cd75ae0 /drivers/base | |
parent | f00b4dad9d9eb001a04cf72e8351a2a1b9e99322 (diff) |
CHROMIUM: dma-buf: restore args on failure of dma_buf_mmap
Callers to dma_buf_mmap expect to fput() the vma struct's vm_file
themselves on failure. Not restoring the struct's data on failure
causes a double-decrement of the vm_file's refcount.
Signed-off-by: John Sheu <sheu@google.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/dma-buf.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 394523807a6d..2a7cb0df176b 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c | |||
@@ -447,6 +447,9 @@ EXPORT_SYMBOL_GPL(dma_buf_kunmap); | |||
447 | int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, | 447 | int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, |
448 | unsigned long pgoff) | 448 | unsigned long pgoff) |
449 | { | 449 | { |
450 | struct file *oldfile; | ||
451 | int ret; | ||
452 | |||
450 | if (WARN_ON(!dmabuf || !vma)) | 453 | if (WARN_ON(!dmabuf || !vma)) |
451 | return -EINVAL; | 454 | return -EINVAL; |
452 | 455 | ||
@@ -460,14 +463,22 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, | |||
460 | return -EINVAL; | 463 | return -EINVAL; |
461 | 464 | ||
462 | /* readjust the vma */ | 465 | /* readjust the vma */ |
463 | if (vma->vm_file) | 466 | get_file(dmabuf->file); |
464 | fput(vma->vm_file); | 467 | oldfile = vma->vm_file; |
465 | 468 | vma->vm_file = dmabuf->file; | |
466 | vma->vm_file = get_file(dmabuf->file); | ||
467 | |||
468 | vma->vm_pgoff = pgoff; | 469 | vma->vm_pgoff = pgoff; |
469 | 470 | ||
470 | return dmabuf->ops->mmap(dmabuf, vma); | 471 | ret = dmabuf->ops->mmap(dmabuf, vma); |
472 | if (ret) { | ||
473 | /* restore old parameters on failure */ | ||
474 | vma->vm_file = oldfile; | ||
475 | fput(dmabuf->file); | ||
476 | } else { | ||
477 | if (oldfile) | ||
478 | fput(oldfile); | ||
479 | } | ||
480 | return ret; | ||
481 | |||
471 | } | 482 | } |
472 | EXPORT_SYMBOL_GPL(dma_buf_mmap); | 483 | EXPORT_SYMBOL_GPL(dma_buf_mmap); |
473 | 484 | ||