aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index a7bf6a31c9f6..b17a39f31a5e 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -30,6 +30,7 @@
30#include <linux/perf_event.h> 30#include <linux/perf_event.h>
31#include <linux/audit.h> 31#include <linux/audit.h>
32#include <linux/khugepaged.h> 32#include <linux/khugepaged.h>
33#include <linux/uprobes.h>
33 34
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
35#include <asm/cacheflush.h> 36#include <asm/cacheflush.h>
@@ -217,6 +218,7 @@ void unlink_file_vma(struct vm_area_struct *vma)
217 mutex_lock(&mapping->i_mmap_mutex); 218 mutex_lock(&mapping->i_mmap_mutex);
218 __remove_shared_vm_struct(vma, file, mapping); 219 __remove_shared_vm_struct(vma, file, mapping);
219 mutex_unlock(&mapping->i_mmap_mutex); 220 mutex_unlock(&mapping->i_mmap_mutex);
221 uprobe_munmap(vma);
220 } 222 }
221} 223}
222 224
@@ -544,8 +546,14 @@ again: remove_next = 1 + (end > next->vm_end);
544 546
545 if (file) { 547 if (file) {
546 mapping = file->f_mapping; 548 mapping = file->f_mapping;
547 if (!(vma->vm_flags & VM_NONLINEAR)) 549 if (!(vma->vm_flags & VM_NONLINEAR)) {
548 root = &mapping->i_mmap; 550 root = &mapping->i_mmap;
551 uprobe_munmap(vma);
552
553 if (adjust_next)
554 uprobe_munmap(next);
555 }
556
549 mutex_lock(&mapping->i_mmap_mutex); 557 mutex_lock(&mapping->i_mmap_mutex);
550 if (insert) { 558 if (insert) {
551 /* 559 /*
@@ -615,8 +623,16 @@ again: remove_next = 1 + (end > next->vm_end);
615 if (mapping) 623 if (mapping)
616 mutex_unlock(&mapping->i_mmap_mutex); 624 mutex_unlock(&mapping->i_mmap_mutex);
617 625
626 if (root) {
627 uprobe_mmap(vma);
628
629 if (adjust_next)
630 uprobe_mmap(next);
631 }
632
618 if (remove_next) { 633 if (remove_next) {
619 if (file) { 634 if (file) {
635 uprobe_munmap(next);
620 fput(file); 636 fput(file);
621 if (next->vm_flags & VM_EXECUTABLE) 637 if (next->vm_flags & VM_EXECUTABLE)
622 removed_exe_file_vma(mm); 638 removed_exe_file_vma(mm);
@@ -636,6 +652,8 @@ again: remove_next = 1 + (end > next->vm_end);
636 goto again; 652 goto again;
637 } 653 }
638 } 654 }
655 if (insert && file)
656 uprobe_mmap(insert);
639 657
640 validate_mm(mm); 658 validate_mm(mm);
641 659
@@ -1344,6 +1362,11 @@ out:
1344 mm->locked_vm += (len >> PAGE_SHIFT); 1362 mm->locked_vm += (len >> PAGE_SHIFT);
1345 } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK)) 1363 } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
1346 make_pages_present(addr, addr + len); 1364 make_pages_present(addr, addr + len);
1365
1366 if (file && uprobe_mmap(vma))
1367 /* matching probes but cannot insert */
1368 goto unmap_and_free_vma;
1369
1347 return addr; 1370 return addr;
1348 1371
1349unmap_and_free_vma: 1372unmap_and_free_vma:
@@ -2311,6 +2334,10 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
2311 if ((vma->vm_flags & VM_ACCOUNT) && 2334 if ((vma->vm_flags & VM_ACCOUNT) &&
2312 security_vm_enough_memory_mm(mm, vma_pages(vma))) 2335 security_vm_enough_memory_mm(mm, vma_pages(vma)))
2313 return -ENOMEM; 2336 return -ENOMEM;
2337
2338 if (vma->vm_file && uprobe_mmap(vma))
2339 return -EINVAL;
2340
2314 vma_link(mm, vma, prev, rb_link, rb_parent); 2341 vma_link(mm, vma, prev, rb_link, rb_parent);
2315 return 0; 2342 return 0;
2316} 2343}
@@ -2380,6 +2407,10 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
2380 new_vma->vm_pgoff = pgoff; 2407 new_vma->vm_pgoff = pgoff;
2381 if (new_vma->vm_file) { 2408 if (new_vma->vm_file) {
2382 get_file(new_vma->vm_file); 2409 get_file(new_vma->vm_file);
2410
2411 if (uprobe_mmap(new_vma))
2412 goto out_free_mempol;
2413
2383 if (vma->vm_flags & VM_EXECUTABLE) 2414 if (vma->vm_flags & VM_EXECUTABLE)
2384 added_exe_file_vma(mm); 2415 added_exe_file_vma(mm);
2385 } 2416 }