aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 3f758c7f4c81..da15a79b1441 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1266,8 +1266,9 @@ munmap_back:
1266 vma->vm_pgoff = pgoff; 1266 vma->vm_pgoff = pgoff;
1267 INIT_LIST_HEAD(&vma->anon_vma_chain); 1267 INIT_LIST_HEAD(&vma->anon_vma_chain);
1268 1268
1269 error = -EINVAL; /* when rejecting VM_GROWSDOWN|VM_GROWSUP */
1270
1269 if (file) { 1271 if (file) {
1270 error = -EINVAL;
1271 if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP)) 1272 if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
1272 goto free_vma; 1273 goto free_vma;
1273 if (vm_flags & VM_DENYWRITE) { 1274 if (vm_flags & VM_DENYWRITE) {
@@ -1293,6 +1294,8 @@ munmap_back:
1293 pgoff = vma->vm_pgoff; 1294 pgoff = vma->vm_pgoff;
1294 vm_flags = vma->vm_flags; 1295 vm_flags = vma->vm_flags;
1295 } else if (vm_flags & VM_SHARED) { 1296 } else if (vm_flags & VM_SHARED) {
1297 if (unlikely(vm_flags & (VM_GROWSDOWN|VM_GROWSUP)))
1298 goto free_vma;
1296 error = shmem_zero_setup(vma); 1299 error = shmem_zero_setup(vma);
1297 if (error) 1300 if (error)
1298 goto free_vma; 1301 goto free_vma;
@@ -1605,7 +1608,6 @@ EXPORT_SYMBOL(find_vma);
1605 1608
1606/* 1609/*
1607 * Same as find_vma, but also return a pointer to the previous VMA in *pprev. 1610 * Same as find_vma, but also return a pointer to the previous VMA in *pprev.
1608 * Note: pprev is set to NULL when return value is NULL.
1609 */ 1611 */
1610struct vm_area_struct * 1612struct vm_area_struct *
1611find_vma_prev(struct mm_struct *mm, unsigned long addr, 1613find_vma_prev(struct mm_struct *mm, unsigned long addr,
@@ -1614,7 +1616,16 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr,
1614 struct vm_area_struct *vma; 1616 struct vm_area_struct *vma;
1615 1617
1616 vma = find_vma(mm, addr); 1618 vma = find_vma(mm, addr);
1617 *pprev = vma ? vma->vm_prev : NULL; 1619 if (vma) {
1620 *pprev = vma->vm_prev;
1621 } else {
1622 struct rb_node *rb_node = mm->mm_rb.rb_node;
1623 *pprev = NULL;
1624 while (rb_node) {
1625 *pprev = rb_entry(rb_node, struct vm_area_struct, vm_rb);
1626 rb_node = rb_node->rb_right;
1627 }
1628 }
1618 return vma; 1629 return vma;
1619} 1630}
1620 1631