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 694a8625ab0..39a68ddf38b 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1279,8 +1279,9 @@ munmap_back:
1279 vma->vm_pgoff = pgoff; 1279 vma->vm_pgoff = pgoff;
1280 INIT_LIST_HEAD(&vma->anon_vma_chain); 1280 INIT_LIST_HEAD(&vma->anon_vma_chain);
1281 1281
1282 error = -EINVAL; /* when rejecting VM_GROWSDOWN|VM_GROWSUP */
1283
1282 if (file) { 1284 if (file) {
1283 error = -EINVAL;
1284 if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP)) 1285 if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
1285 goto free_vma; 1286 goto free_vma;
1286 if (vm_flags & VM_DENYWRITE) { 1287 if (vm_flags & VM_DENYWRITE) {
@@ -1306,6 +1307,8 @@ munmap_back:
1306 pgoff = vma->vm_pgoff; 1307 pgoff = vma->vm_pgoff;
1307 vm_flags = vma->vm_flags; 1308 vm_flags = vma->vm_flags;
1308 } else if (vm_flags & VM_SHARED) { 1309 } else if (vm_flags & VM_SHARED) {
1310 if (unlikely(vm_flags & (VM_GROWSDOWN|VM_GROWSUP)))
1311 goto free_vma;
1309 error = shmem_zero_setup(vma); 1312 error = shmem_zero_setup(vma);
1310 if (error) 1313 if (error)
1311 goto free_vma; 1314 goto free_vma;
@@ -1618,7 +1621,6 @@ EXPORT_SYMBOL(find_vma);
1618 1621
1619/* 1622/*
1620 * Same as find_vma, but also return a pointer to the previous VMA in *pprev. 1623 * Same as find_vma, but also return a pointer to the previous VMA in *pprev.
1621 * Note: pprev is set to NULL when return value is NULL.
1622 */ 1624 */
1623struct vm_area_struct * 1625struct vm_area_struct *
1624find_vma_prev(struct mm_struct *mm, unsigned long addr, 1626find_vma_prev(struct mm_struct *mm, unsigned long addr,
@@ -1627,7 +1629,16 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr,
1627 struct vm_area_struct *vma; 1629 struct vm_area_struct *vma;
1628 1630
1629 vma = find_vma(mm, addr); 1631 vma = find_vma(mm, addr);
1630 *pprev = vma ? vma->vm_prev : NULL; 1632 if (vma) {
1633 *pprev = vma->vm_prev;
1634 } else {
1635 struct rb_node *rb_node = mm->mm_rb.rb_node;
1636 *pprev = NULL;
1637 while (rb_node) {
1638 *pprev = rb_entry(rb_node, struct vm_area_struct, vm_rb);
1639 rb_node = rb_node->rb_right;
1640 }
1641 }
1631 return vma; 1642 return vma;
1632} 1643}
1633 1644