diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-07-14 00:50:02 -0700 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2011-07-25 14:39:23 -0600 |
commit | 6e817e280ee7a4ba0d7af10feb56315ccd0a9303 (patch) | |
tree | 8aed199b78607d05f7a7e2f9a2ee1f424d90689a /mm | |
parent | 5cbdb681c915d4b85f049cb56f86824949d0ed3e (diff) |
UBUNTU: ubuntu: nx-emu - i386: NX emulation
This is old code with some cruft, all originally by Ingo Molnar with
much later rebasing by Fedora folks and at least one arcane fix by
Roland McGrath a few years ago. No longer uses exec-shield sysctl,
merged with disable_nx. Kees Cook fixed boottime NX reporting for various
corner cases.
Signed-off-by: Kees Cook <kees.cook@canonical.com>
Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/mmap.c | 25 | ||||
-rw-r--r-- | mm/mprotect.c | 10 | ||||
-rw-r--r-- | mm/util.c | 8 |
3 files changed, 40 insertions, 3 deletions
diff --git a/mm/mmap.c b/mm/mmap.c index d49736ff8a8..a4ccc637c06 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -46,6 +46,18 @@ #define arch_rebalance_pgtables(addr, len) (addr) #endif +/* No sane architecture will #define these to anything else */ +#ifndef arch_add_exec_range +#define arch_add_exec_range(mm, limit) do { ; } while (0) +#endif +#ifndef arch_flush_exec_range +#define arch_flush_exec_range(mm) do { ; } while (0) +#endif +#ifndef arch_remove_exec_range +#define arch_remove_exec_range(mm, limit) do { ; } while (0) +#endif + + static void unmap_region(struct mm_struct *mm, struct vm_area_struct *vma, struct vm_area_struct *prev, unsigned long start, unsigned long end); @@ -486,6 +498,8 @@ __vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma, rb_erase(&vma->vm_rb, &mm->mm_rb); if (mm->mmap_cache == vma) mm->mmap_cache = prev; + if (vma->vm_flags & VM_EXEC) + arch_remove_exec_range(mm, vma->vm_end); } /* @@ -802,6 +816,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, } else /* cases 2, 5, 7 */ err = vma_adjust(prev, prev->vm_start, end, prev->vm_pgoff, NULL); + if (prev->vm_flags & VM_EXEC) + arch_add_exec_range(mm, prev->vm_end); if (err) return NULL; khugepaged_enter_vma_merge(prev); @@ -1980,10 +1996,14 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, if (new->vm_ops && new->vm_ops->open) new->vm_ops->open(new); - if (new_below) + if (new_below) { + unsigned long old_end = vma->vm_end; + err = vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff + ((addr - new->vm_start) >> PAGE_SHIFT), new); - else + if (vma->vm_flags & VM_EXEC) + arch_remove_exec_range(mm, old_end); + } else err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); /* Success. */ @@ -2271,6 +2291,7 @@ void exit_mmap(struct mm_struct *mm) free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0); tlb_finish_mmu(&tlb, 0, end); + arch_flush_exec_range(mm); /* * Walk the list again, actually closing and freeing it, diff --git a/mm/mprotect.c b/mm/mprotect.c index 5a688a2756b..128d996c984 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -25,9 +25,14 @@ #include <linux/perf_event.h> #include <asm/uaccess.h> #include <asm/pgtable.h> +#include <asm/pgalloc.h> #include <asm/cacheflush.h> #include <asm/tlbflush.h> +#ifndef arch_remove_exec_range +#define arch_remove_exec_range(mm, limit) do { ; } while (0) +#endif + #ifndef pgprot_modify static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) { @@ -148,7 +153,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, struct mm_struct *mm = vma->vm_mm; unsigned long oldflags = vma->vm_flags; long nrpages = (end - start) >> PAGE_SHIFT; - unsigned long charged = 0; + unsigned long charged = 0, old_end = vma->vm_end; pgoff_t pgoff; int error; int dirty_accountable = 0; @@ -213,6 +218,9 @@ success: dirty_accountable = 1; } + if (oldflags & VM_EXEC) + arch_remove_exec_range(current->mm, old_end); + mmu_notifier_invalidate_range_start(mm, start, end); if (is_vm_hugetlb_page(vma)) hugetlb_change_protection(vma, start, end, vma->vm_page_prot); diff --git a/mm/util.c b/mm/util.c index 88ea1bd661c..c4db4127176 100644 --- a/mm/util.c +++ b/mm/util.c @@ -11,6 +11,11 @@ #define CREATE_TRACE_POINTS #include <trace/events/kmem.h> +/* No sane architecture will #define these to anything else */ +#ifndef arch_add_exec_range +#define arch_add_exec_range(mm, limit) do { ; } while (0) +#endif + /** * kstrdup - allocate space for and copy an existing string * @s: the string to duplicate @@ -237,6 +242,9 @@ void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, vma->vm_next = next; if (next) next->vm_prev = vma; + + if (vma->vm_flags & VM_EXEC) + arch_add_exec_range(mm, vma->vm_end); } #if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT) |