Skip to content

Commit 309d08d

Browse files
Liu Zixiantorvalds
Liu Zixian
authored andcommitted
mm/mmap.c: fix mmap return value when vma is merged after call_mmap()
On success, mmap should return the begin address of newly mapped area, but patch "mm: mmap: merge vma after call_mmap() if possible" set vm_start of newly merged vma to return value addr. Users of mmap will get wrong address if vma is merged after call_mmap(). We fix this by moving the assignment to addr before merging vma. We have a driver which changes vm_flags, and this bug is found by our testcases. Fixes: d70cec8 ("mm: mmap: merge vma after call_mmap() if possible") Signed-off-by: Liu Zixian <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: David Hildenbrand <[email protected]> Cc: Miaohe Lin <[email protected]> Cc: Hongxiang Lou <[email protected]> Cc: Hu Shiyuan <[email protected]> Cc: Matthew Wilcox <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Linus Torvalds <[email protected]>
1 parent 7a5bde3 commit 309d08d

File tree

1 file changed

+12
-14
lines changed

1 file changed

+12
-14
lines changed

mm/mmap.c

+12-14
Original file line numberDiff line numberDiff line change
@@ -1808,6 +1808,17 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
18081808
if (error)
18091809
goto unmap_and_free_vma;
18101810

1811+
/* Can addr have changed??
1812+
*
1813+
* Answer: Yes, several device drivers can do it in their
1814+
* f_op->mmap method. -DaveM
1815+
* Bug: If addr is changed, prev, rb_link, rb_parent should
1816+
* be updated for vma_link()
1817+
*/
1818+
WARN_ON_ONCE(addr != vma->vm_start);
1819+
1820+
addr = vma->vm_start;
1821+
18111822
/* If vm_flags changed after call_mmap(), we should try merge vma again
18121823
* as we may succeed this time.
18131824
*/
@@ -1822,25 +1833,12 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
18221833
fput(vma->vm_file);
18231834
vm_area_free(vma);
18241835
vma = merge;
1825-
/* Update vm_flags and possible addr to pick up the change. We don't
1826-
* warn here if addr changed as the vma is not linked by vma_link().
1827-
*/
1828-
addr = vma->vm_start;
1836+
/* Update vm_flags to pick up the change. */
18291837
vm_flags = vma->vm_flags;
18301838
goto unmap_writable;
18311839
}
18321840
}
18331841

1834-
/* Can addr have changed??
1835-
*
1836-
* Answer: Yes, several device drivers can do it in their
1837-
* f_op->mmap method. -DaveM
1838-
* Bug: If addr is changed, prev, rb_link, rb_parent should
1839-
* be updated for vma_link()
1840-
*/
1841-
WARN_ON_ONCE(addr != vma->vm_start);
1842-
1843-
addr = vma->vm_start;
18441842
vm_flags = vma->vm_flags;
18451843
} else if (vm_flags & VM_SHARED) {
18461844
error = shmem_zero_setup(vma);

0 commit comments

Comments
 (0)