diff options
Diffstat (limited to 'mm/mremap.c')
-rw-r--r-- | mm/mremap.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/mm/mremap.c b/mm/mremap.c index 3f23715d3c69..7395564daa6c 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -384,6 +384,19 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr, | |||
384 | if (!vma || vma->vm_start > addr) | 384 | if (!vma || vma->vm_start > addr) |
385 | return ERR_PTR(-EFAULT); | 385 | return ERR_PTR(-EFAULT); |
386 | 386 | ||
387 | /* | ||
388 | * !old_len is a special case where an attempt is made to 'duplicate' | ||
389 | * a mapping. This makes no sense for private mappings as it will | ||
390 | * instead create a fresh/new mapping unrelated to the original. This | ||
391 | * is contrary to the basic idea of mremap which creates new mappings | ||
392 | * based on the original. There are no known use cases for this | ||
393 | * behavior. As a result, fail such attempts. | ||
394 | */ | ||
395 | if (!old_len && !(vma->vm_flags & (VM_SHARED | VM_MAYSHARE))) { | ||
396 | pr_warn_once("%s (%d): attempted to duplicate a private mapping with mremap. This is not supported.\n", current->comm, current->pid); | ||
397 | return ERR_PTR(-EINVAL); | ||
398 | } | ||
399 | |||
387 | if (is_vm_hugetlb_page(vma)) | 400 | if (is_vm_hugetlb_page(vma)) |
388 | return ERR_PTR(-EINVAL); | 401 | return ERR_PTR(-EINVAL); |
389 | 402 | ||