aboutsummaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-07-14 00:50:02 -0700
committerJohn Rigby <john.rigby@linaro.org>2011-07-25 14:39:23 -0600
commit6e817e280ee7a4ba0d7af10feb56315ccd0a9303 (patch)
tree8aed199b78607d05f7a7e2f9a2ee1f424d90689a /mm
parent5cbdb681c915d4b85f049cb56f86824949d0ed3e (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.c25
-rw-r--r--mm/mprotect.c10
-rw-r--r--mm/util.c8
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)