]> git.pld-linux.org Git - packages/kernel.git/blame - exec-shield-nx-2.6.7-A0
- ported from linux-2.4.25-atmdd.patch
[packages/kernel.git] / exec-shield-nx-2.6.7-A0
CommitLineData
3d208c1f
AM
1--- linux/drivers/char/drm/ffb_drv.c.orig
2+++ linux/drivers/char/drm/ffb_drv.c
3@@ -285,19 +285,19 @@ static unsigned long ffb_get_unmapped_ar
4 unsigned long addr = -ENOMEM;
5
6 if (!map)
7- return get_unmapped_area(NULL, hint, len, pgoff, flags);
8+ return get_unmapped_area(NULL, hint, len, pgoff, flags, 0);
9
10 if (map->type == _DRM_FRAME_BUFFER ||
11 map->type == _DRM_REGISTERS) {
12 #ifdef HAVE_ARCH_FB_UNMAPPED_AREA
13 addr = get_fb_unmapped_area(filp, hint, len, pgoff, flags);
14 #else
15- addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
16+ addr = get_unmapped_area(NULL, hint, len, pgoff, flags, 0);
17 #endif
18 } else if (map->type == _DRM_SHM && SHMLBA > PAGE_SIZE) {
19 unsigned long slack = SHMLBA - PAGE_SIZE;
20
21- addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags);
22+ addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags, 0);
23 if (!(addr & ~PAGE_MASK)) {
24 unsigned long kvirt = (unsigned long) map->handle;
25
26@@ -313,7 +313,7 @@ static unsigned long ffb_get_unmapped_ar
27 }
28 }
29 } else {
30- addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
31+ addr = get_unmapped_area(NULL, hint, len, pgoff, flags, 0);
32 }
33
34 return addr;
35--- linux/arch/sparc64/kernel/sys_sparc.c.orig
36+++ linux/arch/sparc64/kernel/sys_sparc.c
37@@ -127,7 +127,7 @@ unsigned long get_fb_unmapped_area(struc
38
39 if (flags & MAP_FIXED) {
40 /* Ok, don't mess with it. */
41- return get_unmapped_area(NULL, addr, len, pgoff, flags);
42+ return get_unmapped_area(NULL, addr, len, pgoff, flags, 0);
43 }
44 flags &= ~MAP_SHARED;
45
46@@ -140,7 +140,7 @@ unsigned long get_fb_unmapped_area(struc
47 align_goal = (64UL * 1024);
48
49 do {
50- addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
51+ addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags, 0);
52 if (!(addr & ~PAGE_MASK)) {
53 addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
54 break;
55@@ -158,7 +158,7 @@ unsigned long get_fb_unmapped_area(struc
56 * be obtained.
57 */
58 if (addr & ~PAGE_MASK)
59- addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
60+ addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags, 0);
61
62 return addr;
63 }
64@@ -402,7 +402,7 @@ asmlinkage unsigned long sys64_mremap(un
65 /* MREMAP_FIXED checked above. */
66 new_addr = get_unmapped_area(file, addr, new_len,
67 vma ? vma->vm_pgoff : 0,
68- map_flags);
69+ map_flags, vma->vm_flags & VM_EXEC);
70 ret = new_addr;
71 if (new_addr & ~PAGE_MASK)
72 goto out_sem;
73--- linux/arch/sparc64/kernel/sys_sparc32.c.orig
74+++ linux/arch/sparc64/kernel/sys_sparc32.c
75@@ -1750,7 +1750,7 @@ asmlinkage unsigned long sys32_mremap(un
76 /* MREMAP_FIXED checked above. */
77 new_addr = get_unmapped_area(file, addr, new_len,
78 vma ? vma->vm_pgoff : 0,
79- map_flags);
80+ map_flags, vma->vm_flags & VM_EXEC);
81 ret = new_addr;
82 if (new_addr & ~PAGE_MASK)
83 goto out_sem;
84--- linux/arch/i386/kernel/cpu/proc.c.orig
85+++ linux/arch/i386/kernel/cpu/proc.c
86@@ -27,7 +27,7 @@ static int show_cpuinfo(struct seq_file
87 /* AMD-defined */
88 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
89 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
90- NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL,
91+ NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
92 NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
93
94 /* Transmeta-defined */
95--- linux/arch/i386/kernel/asm-offsets.c.orig
96+++ linux/arch/i386/kernel/asm-offsets.c
97@@ -52,6 +52,7 @@ void foo(void)
98 OFFSET(TI_preempt_count, thread_info, preempt_count);
99 OFFSET(TI_addr_limit, thread_info, addr_limit);
100 OFFSET(TI_restart_block, thread_info, restart_block);
101+ OFFSET(TI_sysenter_return, thread_info, sysenter_return);
102 BLANK();
103
104 OFFSET(EXEC_DOMAIN_handler, exec_domain, handler);
105--- linux/arch/i386/kernel/entry.S.orig
106+++ linux/arch/i386/kernel/entry.S
107@@ -238,8 +238,12 @@ sysenter_past_esp:
108 pushl %ebp
109 pushfl
110 pushl $(__USER_CS)
111- pushl $SYSENTER_RETURN
112-
113+ /*
114+ * Push current_thread_info()->sysenter_return to the stack.
115+ * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
116+ * pushed above, and the word being pushed now:
117+ */
118+ pushl (TI_sysenter_return-THREAD_SIZE+4*4)(%esp)
119 /*
120 * Load the potential sixth argument from user stack.
121 * Careful about security.
122--- linux/arch/i386/kernel/head.S.orig
123+++ linux/arch/i386/kernel/head.S
124@@ -153,6 +153,32 @@ ENTRY(startup_32_smp)
125 orl %edx,%eax
126 movl %eax,%cr4
127
128+ btl $5, %eax # check if PAE is enabled
129+ jnc 6f
130+
131+ /* Check if extended functions are implemented */
132+ movl $0x80000000, %eax
133+ cpuid
134+ cmpl $0x80000000, %eax
135+ jbe 6f
136+ mov $0x80000001, %eax
137+ cpuid
138+ /* Execute Disable bit supported? */
139+ btl $20, %edx
140+ jnc 6f
141+
142+ /* Setup EFER (Extended Feature Enable Register) */
143+ movl $0xc0000080, %ecx
144+ rdmsr
145+
146+ btsl $11, %eax
147+ /* Make changes effective */
148+ wrmsr
149+
150+6:
151+ /* cpuid clobbered ebx, set it up again: */
152+ xorl %ebx,%ebx
153+ incl %ebx
154 3:
155 #endif /* CONFIG_SMP */
156
157--- linux/arch/i386/kernel/module.c.orig
158+++ linux/arch/i386/kernel/module.c
159@@ -32,7 +32,7 @@ void *module_alloc(unsigned long size)
160 {
161 if (size == 0)
162 return NULL;
163- return vmalloc(size);
164+ return vmalloc_exec(size);
165 }
166
167
168--- linux/arch/i386/kernel/process.c.orig
169+++ linux/arch/i386/kernel/process.c
170@@ -36,6 +36,8 @@
171 #include <linux/module.h>
172 #include <linux/kallsyms.h>
173 #include <linux/ptrace.h>
174+#include <linux/mman.h>
175+#include <linux/random.h>
176
177 #include <asm/uaccess.h>
178 #include <asm/pgtable.h>
179@@ -512,6 +514,8 @@ struct task_struct fastcall * __switch_t
180 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
181
182 __unlazy_fpu(prev_p);
183+ if (next_p->mm)
184+ load_user_cs_desc(cpu, next_p->mm);
185
186 /*
187 * Reload esp0, LDT and the page table pointer:
188@@ -776,3 +780,303 @@ asmlinkage int sys_get_thread_area(struc
189 return 0;
190 }
191
192+/*
193+ * Get a random word:
194+ */
195+static inline unsigned int get_random_int(void)
196+{
197+ unsigned int val = 0;
198+
199+ if (!exec_shield_randomize)
200+ return 0;
201+
202+#ifdef CONFIG_X86_HAS_TSC
203+ rdtscl(val);
204+#endif
205+ val += current->pid + jiffies + (int)&val;
206+
207+ /*
208+ * Use IP's RNG. It suits our purpose perfectly: it re-keys itself
209+ * every second, from the entropy pool (and thus creates a limited
210+ * drain on it), and uses halfMD4Transform within the second. We
211+ * also spice it with the TSC (if available), jiffies, PID and the
212+ * stack address:
213+ */
214+ return secure_ip_id(val);
215+}
216+
217+unsigned long arch_align_stack(unsigned long sp)
218+{
219+ if (current->mm && !(current->mm->def_flags & VM_EXEC))
220+ sp -= ((get_random_int() % 65536) << 4);
221+ return sp & ~0xf;
222+}
223+
224+#if SHLIB_BASE >= 0x01000000
225+# error SHLIB_BASE must be under 16MB!
226+#endif
227+
228+static unsigned long
229+arch_get_unmapped_nonexecutable_area(struct mm_struct *mm, unsigned long addr, unsigned long len)
230+{
231+ struct vm_area_struct *vma, *prev_vma;
232+ unsigned long stack_limit;
233+ int first_time = 1;
234+
235+ if (!mm->mmap_top) {
236+ printk("hm, %s:%d, !mmap_top.\n", current->comm, current->pid);
237+ mm->mmap_top = mmap_top();
238+ }
239+ stack_limit = mm->mmap_top;
240+
241+ /* requested length too big for entire address space */
242+ if (len > TASK_SIZE)
243+ return -ENOMEM;
244+
245+ /* dont allow allocations above current stack limit */
246+ if (mm->non_executable_cache > stack_limit)
247+ mm->non_executable_cache = stack_limit;
248+
249+ /* requesting a specific address */
250+ if (addr) {
251+ addr = PAGE_ALIGN(addr);
252+ vma = find_vma(mm, addr);
253+ if (TASK_SIZE - len >= addr &&
254+ (!vma || addr + len <= vma->vm_start))
255+ return addr;
256+ }
257+
258+ /* make sure it can fit in the remaining address space */
259+ if (mm->non_executable_cache < len)
260+ return -ENOMEM;
261+
262+ /* either no address requested or cant fit in requested address hole */
263+try_again:
264+ addr = (mm->non_executable_cache - len)&PAGE_MASK;
265+ do {
266+ if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
267+ return -ENOMEM;
268+
269+ /* new region fits between prev_vma->vm_end and vma->vm_start, use it */
270+ if (addr+len <= vma->vm_start && (!prev_vma || (addr >= prev_vma->vm_end))) {
271+ /* remember the address as a hint for next time */
272+ mm->non_executable_cache = addr;
273+ return addr;
274+
275+ /* pull non_executable_cache down to the first hole */
276+ } else if (mm->non_executable_cache == vma->vm_end)
277+ mm->non_executable_cache = vma->vm_start;
278+
279+ /* try just below the current vma->vm_start */
280+ addr = vma->vm_start-len;
281+ } while (len <= vma->vm_start);
282+ /* if hint left us with no space for the requested mapping try again */
283+ if (first_time) {
284+ first_time = 0;
285+ mm->non_executable_cache = stack_limit;
286+ goto try_again;
287+ }
288+ return -ENOMEM;
289+}
290+
291+static unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len)
292+{
293+ unsigned long range = end - len - start;
294+ if (end <= start + len)
295+ return 0;
296+ return PAGE_ALIGN(get_random_int() % range + start);
297+}
298+
299+static inline unsigned long
300+stock_arch_get_unmapped_area(struct file *filp, unsigned long addr,
301+ unsigned long len, unsigned long pgoff, unsigned long flags)
302+{
303+ struct mm_struct *mm = current->mm;
304+ struct vm_area_struct *vma;
305+ unsigned long start_addr;
306+
307+ if (len > TASK_SIZE)
308+ return -ENOMEM;
309+
310+ if (addr) {
311+ addr = PAGE_ALIGN(addr);
312+ vma = find_vma(mm, addr);
313+ if (TASK_SIZE - len >= addr &&
314+ (!vma || addr + len <= vma->vm_start))
315+ return addr;
316+ }
317+ start_addr = addr = mm->free_area_cache;
318+
319+full_search:
320+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
321+ /* At this point: (!vma || addr < vma->vm_end). */
322+ if (TASK_SIZE - len < addr) {
323+ /*
324+ * Start a new search - just in case we missed
325+ * some holes.
326+ */
327+ if (start_addr != TASK_UNMAPPED_BASE) {
328+ start_addr = addr = TASK_UNMAPPED_BASE;
329+ goto full_search;
330+ }
331+ return -ENOMEM;
332+ }
333+ if (!vma || addr + len <= vma->vm_start) {
334+ /*
335+ * Remember the place where we stopped the search:
336+ */
337+ mm->free_area_cache = addr + len;
338+ return addr;
339+ }
340+ addr = vma->vm_end;
341+ }
342+}
343+
344+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0,
345+ unsigned long len0, unsigned long pgoff, unsigned long flags,
346+ unsigned long prot)
347+{
348+ unsigned long addr = addr0, len = len0;
349+ struct mm_struct *mm = current->mm;
350+ struct vm_area_struct *vma;
351+ int ascii_shield = 0;
352+ unsigned long tmp;
353+
354+ /*
355+ * Fall back to the old layout:
356+ */
357+ if (current->mm->def_flags & VM_EXEC)
358+ return stock_arch_get_unmapped_area(filp, addr0, len0, pgoff, flags);
359+ if (len > TASK_SIZE)
360+ return -ENOMEM;
361+
362+ if (!addr && (prot & PROT_EXEC) && !(flags & MAP_FIXED))
363+ addr = randomize_range(SHLIB_BASE, 0x01000000, len);
364+
365+ if (addr) {
366+ addr = PAGE_ALIGN(addr);
367+ vma = find_vma(mm, addr);
368+ if (TASK_SIZE - len >= addr &&
369+ (!vma || addr + len <= vma->vm_start)) {
370+ return addr;
371+ }
372+ }
373+
374+ if (prot & PROT_EXEC) {
375+ ascii_shield = 1;
376+ addr = SHLIB_BASE;
377+ } else {
378+ /* this can fail if the stack was unlimited */
379+ if ((tmp = arch_get_unmapped_nonexecutable_area(mm, addr, len)) != -ENOMEM)
380+ return tmp;
381+search_upper:
382+ addr = PAGE_ALIGN(arch_align_stack(TASK_UNMAPPED_BASE));
383+ }
384+
385+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
386+ /* At this point: (!vma || addr < vma->vm_end). */
387+ if (TASK_SIZE - len < addr) {
388+ return -ENOMEM;
389+ }
390+ if (!vma || addr + len <= vma->vm_start) {
391+ /*
392+ * Must not let a PROT_EXEC mapping get into the
393+ * brk area:
394+ */
395+ if (ascii_shield && (addr + len > mm->brk)) {
396+ ascii_shield = 0;
397+ goto search_upper;
398+ }
399+ /*
400+ * Up until the brk area we randomize addresses
401+ * as much as possible:
402+ */
403+ if (ascii_shield && (addr >= 0x01000000)) {
404+ tmp = randomize_range(0x01000000, mm->brk, len);
405+ vma = find_vma(mm, tmp);
406+ if (TASK_SIZE - len >= tmp &&
407+ (!vma || tmp + len <= vma->vm_start))
408+ return tmp;
409+ }
410+ /*
411+ * Ok, randomization didnt work out - return
412+ * the result of the linear search:
413+ */
414+ return addr;
415+ }
416+ addr = vma->vm_end;
417+ }
418+}
419+
420+void arch_add_exec_range(struct mm_struct *mm, unsigned long limit)
421+{
422+ if (limit > mm->context.exec_limit) {
423+ mm->context.exec_limit = limit;
424+ set_user_cs(&mm->context.user_cs, limit);
425+ if (mm == current->mm)
426+ load_user_cs_desc(smp_processor_id(), mm);
427+ }
428+}
429+
430+void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end)
431+{
432+ struct vm_area_struct *vma;
433+ unsigned long limit = 0;
434+
435+ if (old_end == mm->context.exec_limit) {
436+ for (vma = mm->mmap; vma; vma = vma->vm_next)
437+ if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
438+ limit = vma->vm_end;
439+
440+ mm->context.exec_limit = limit;
441+ set_user_cs(&mm->context.user_cs, limit);
442+ if (mm == current->mm)
443+ load_user_cs_desc(smp_processor_id(), mm);
444+ }
445+}
446+
447+void arch_flush_exec_range(struct mm_struct *mm)
448+{
449+ mm->context.exec_limit = 0;
450+ set_user_cs(&mm->context.user_cs, 0);
451+}
452+
453+/*
454+ * Generate random brk address between 128MB and 196MB. (if the layout
455+ * allows it.)
456+ */
457+void randomize_brk(unsigned long old_brk)
458+{
459+ unsigned long new_brk, range_start, range_end;
460+
461+ range_start = 0x08000000;
462+ if (current->mm->brk >= range_start)
463+ range_start = current->mm->brk;
464+ range_end = range_start + 0x02000000;
465+ new_brk = randomize_range(range_start, range_end, 0);
466+ if (new_brk)
467+ current->mm->brk = new_brk;
468+}
469+
470+/*
471+ * Top of mmap area (just below the process stack).
472+ * leave an at least ~128 MB hole. Randomize it.
473+ */
474+#define MIN_GAP (128*1024*1024)
475+#define MAX_GAP (TASK_SIZE/6*5)
476+
477+unsigned long mmap_top(void)
478+{
479+ unsigned long gap = 0;
480+
481+ gap = current->rlim[RLIMIT_STACK].rlim_cur;
482+ if (gap < MIN_GAP)
483+ gap = MIN_GAP;
484+ else if (gap > MAX_GAP)
485+ gap = MAX_GAP;
486+
487+ gap = arch_align_stack(gap) & PAGE_MASK;
488+
489+ return TASK_SIZE - gap;
490+}
491+
492--- linux/arch/i386/kernel/signal.c.orig
493+++ linux/arch/i386/kernel/signal.c
494@@ -333,7 +333,7 @@ get_sigframe(struct k_sigaction *ka, str
495
496 /* These symbols are defined with the addresses in the vsyscall page.
497 See vsyscall-sigreturn.S. */
498-extern void __kernel_sigreturn, __kernel_rt_sigreturn;
499+extern char __kernel_sigreturn, __kernel_rt_sigreturn, SYSENTER_RETURN;
500
501 static void setup_frame(int sig, struct k_sigaction *ka,
502 sigset_t *set, struct pt_regs * regs)
503@@ -367,7 +367,7 @@ static void setup_frame(int sig, struct
504 if (err)
505 goto give_sigsegv;
506
507- restorer = &__kernel_sigreturn;
508+ restorer = current->mm->context.vdso + (long)&__kernel_sigreturn;
509 if (ka->sa.sa_flags & SA_RESTORER)
510 restorer = ka->sa.sa_restorer;
511
512@@ -450,9 +450,10 @@ static void setup_rt_frame(int sig, stru
513 goto give_sigsegv;
514
515 /* Set up to return from userspace. */
516- restorer = &__kernel_rt_sigreturn;
517+ restorer = current->mm->context.vdso + (long)&__kernel_rt_sigreturn;
518 if (ka->sa.sa_flags & SA_RESTORER)
519 restorer = ka->sa.sa_restorer;
520+
521 err |= __put_user(restorer, &frame->pretcode);
522
523 /*
524--- linux/arch/i386/kernel/sysenter.c.orig
525+++ linux/arch/i386/kernel/sysenter.c
526@@ -13,6 +13,7 @@
527 #include <linux/gfp.h>
528 #include <linux/string.h>
529 #include <linux/elf.h>
530+#include <linux/mman.h>
531
532 #include <asm/cpufeature.h>
533 #include <asm/msr.h>
534@@ -41,11 +42,14 @@ void enable_sep_cpu(void *info)
535 extern const char vsyscall_int80_start, vsyscall_int80_end;
536 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
537
538+struct page *sysenter_page;
539+
540 static int __init sysenter_setup(void)
541 {
542 unsigned long page = get_zeroed_page(GFP_ATOMIC);
543
544- __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY);
545+ __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_KERNEL_RO);
546+ sysenter_page = virt_to_page(page);
547
548 if (!boot_cpu_has(X86_FEATURE_SEP)) {
549 memcpy((void *) page,
550@@ -59,7 +63,51 @@ static int __init sysenter_setup(void)
551 &vsyscall_sysenter_end - &vsyscall_sysenter_start);
552
553 on_each_cpu(enable_sep_cpu, NULL, 1, 1);
554+
555 return 0;
556 }
557
558 __initcall(sysenter_setup);
559+
560+extern void SYSENTER_RETURN_OFFSET;
561+
562+unsigned int vdso_enabled = 1;
563+
564+void map_vsyscall(void)
565+{
566+ struct thread_info *ti = current_thread_info();
567+ struct vm_area_struct *vma;
568+ unsigned long addr;
569+
570+ if (unlikely(!vdso_enabled)) {
571+ current->mm->context.vdso = NULL;
572+ return;
573+ }
574+
575+ /*
576+ * Map the vDSO (it will be randomized):
577+ */
578+ down_write(&current->mm->mmap_sem);
579+ addr = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, 0);
580+ current->mm->context.vdso = (void *)addr;
581+ ti->sysenter_return = (void *)addr + (long)&SYSENTER_RETURN_OFFSET;
582+ if (addr != -1) {
583+ vma = find_vma(current->mm, addr);
584+ if (vma) {
585+ pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
586+ get_page(sysenter_page);
587+ install_page(current->mm, vma, addr,
588+ sysenter_page, vma->vm_page_prot);
589+
590+ }
591+ }
592+ up_write(&current->mm->mmap_sem);
593+}
594+
595+static int __init vdso_setup(char *str)
596+{
597+ vdso_enabled = simple_strtoul(str, NULL, 0);
598+ return 1;
599+}
600+__setup("vdso=", vdso_setup);
601+
602--- linux/arch/i386/kernel/traps.c.orig
603+++ linux/arch/i386/kernel/traps.c
604@@ -428,6 +428,10 @@ DO_ERROR(11, SIGBUS, "segment not prese
605 DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
606 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2())
607
608+/*
609+ * the original non-exec stack patch was written by
610+ * Solar Designer <solar at openwall.com>. Thanks!
611+ */
612 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
613 {
614 if (regs->eflags & X86_EFLAGS_IF)
615@@ -439,6 +443,46 @@ asmlinkage void do_general_protection(st
616 if (!(regs->xcs & 3))
617 goto gp_in_kernel;
618
619+ /*
620+ * lazy-check for CS validity on exec-shield binaries:
621+ */
622+ if (current->mm) {
623+ int cpu = smp_processor_id();
624+ struct desc_struct *desc1, *desc2;
625+ struct vm_area_struct *vma;
626+ unsigned long limit = 0;
627+
628+ spin_lock(&current->mm->page_table_lock);
629+ for (vma = current->mm->mmap; vma; vma = vma->vm_next)
630+ if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
631+ limit = vma->vm_end;
632+ spin_unlock(&current->mm->page_table_lock);
633+
634+ current->mm->context.exec_limit = limit;
635+ set_user_cs(&current->mm->context.user_cs, limit);
636+
637+ desc1 = &current->mm->context.user_cs;
638+ desc2 = cpu_gdt_table[cpu] + GDT_ENTRY_DEFAULT_USER_CS;
639+
640+ /*
641+ * The CS was not in sync - reload it and retry the
642+ * instruction. If the instruction still faults then
643+ * we wont hit this branch next time around.
644+ */
645+ if (desc1->a != desc2->a || desc1->b != desc2->b) {
646+ if (print_fatal_signals >= 2) {
647+ printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
648+ printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
649+ }
650+ load_user_cs_desc(cpu, current->mm);
651+ return;
652+ }
653+ }
654+ if (print_fatal_signals) {
655+ printk("#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
656+ printk(" exec_limit: %08lx, user_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b);
657+ }
658+
659 current->thread.error_code = error_code;
660 current->thread.trap_no = 13;
661 force_sig(SIGSEGV, current);
662--- linux/arch/i386/kernel/vsyscall-sysenter.S.orig
663+++ linux/arch/i386/kernel/vsyscall-sysenter.S
664@@ -24,11 +24,11 @@ __kernel_vsyscall:
665 /* 7: align return point with nop's to make disassembly easier */
666 .space 7,0x90
667
668- /* 14: System call restart point is here! (SYSENTER_RETURN - 2) */
669+ /* 14: System call restart point is here! (SYSENTER_RETURN_OFFSET-2) */
670 jmp .Lenter_kernel
671 /* 16: System call normal return point is here! */
672- .globl SYSENTER_RETURN /* Symbol used by entry.S. */
673-SYSENTER_RETURN:
674+ .globl SYSENTER_RETURN_OFFSET /* Symbol used by sysenter.c */
675+SYSENTER_RETURN_OFFSET:
676 pop %ebp
677 .Lpop_ebp:
678 pop %edx
679--- linux/arch/i386/kernel/vsyscall.lds.orig
680+++ linux/arch/i386/kernel/vsyscall.lds
681@@ -1,15 +1,12 @@
682 /*
683 * Linker script for vsyscall DSO. The vsyscall page is an ELF shared
684- * object prelinked to its virtual address, and with only one read-only
685- * segment (that fits in one page). This script controls its layout.
686+ * object with only one read-only segment (that fits in one page).
687+ * This script controls its layout.
688 */
689
690-/* This must match <asm/fixmap.h>. */
691-VSYSCALL_BASE = 0xffffe000;
692-
693 SECTIONS
694 {
695- . = VSYSCALL_BASE + SIZEOF_HEADERS;
696+ . = SIZEOF_HEADERS;
697
698 .hash : { *(.hash) } :text
699 .dynsym : { *(.dynsym) }
700@@ -22,7 +19,7 @@ SECTIONS
701 For the layouts to match, we need to skip more than enough
702 space for the dynamic symbol table et al. If this amount
703 is insufficient, ld -shared will barf. Just increase it here. */
704- . = VSYSCALL_BASE + 0x400;
705+ . = 0x400;
706
707 .text : { *(.text) } :text =0x90909090
708
709--- linux/arch/i386/mm/fault.c.orig
710+++ linux/arch/i386/mm/fault.c
711@@ -405,6 +405,21 @@ no_context:
712
713 bust_spinlocks(1);
714
715+#ifdef CONFIG_X86_PAE
716+ {
717+ pgd_t *pgd;
718+ pmd_t *pmd;
719+
720+
721+
722+ pgd = init_mm.pgd + pgd_index(address);
723+ if (pgd_present(*pgd)) {
724+ pmd = pmd_offset(pgd, address);
725+ if (pmd_val(*pmd) & _PAGE_NX)
726+ printk(KERN_CRIT "kernel tried to access NX-protected page - exploit attempt? (uid: %d)\n", current->uid);
727+ }
728+ }
729+#endif
730 if (address < PAGE_SIZE)
731 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
732 else
733--- linux/arch/i386/mm/init.c.orig
734+++ linux/arch/i386/mm/init.c
735@@ -122,6 +122,13 @@ static void __init page_table_range_init
736 }
737 }
738
739+static inline int is_kernel_text(unsigned long addr)
740+{
741+ if (addr >= (unsigned long)_stext && addr <= (unsigned long)__init_end)
742+ return 1;
743+ return 0;
744+}
745+
746 /*
747 * This maps the physical memory to kernel virtual address space, a total
748 * of max_low_pfn pages, by creating page tables starting from address
749@@ -144,18 +151,29 @@ static void __init kernel_physical_mappi
750 if (pfn >= max_low_pfn)
751 continue;
752 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
753+ unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
754+
755 /* Map with big pages if possible, otherwise create normal page tables. */
756 if (cpu_has_pse) {
757- set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
758+ unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
759+
760+ if (is_kernel_text(address) || is_kernel_text(address2))
761+ set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
762+ else
763+ set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
764 pfn += PTRS_PER_PTE;
765 } else {
766 pte = one_page_table_init(pmd);
767
768- for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++)
769- set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
770+ for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
771+ if (is_kernel_text(address))
772+ set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
773+ else
774+ set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
775+ }
776 }
777 }
778- }
779+ }
780 }
781
782 static inline int page_kills_ppro(unsigned long pagenr)
783@@ -272,7 +290,8 @@ extern void set_highmem_pages_init(int);
784 #define set_highmem_pages_init(bad_ppro) do { } while (0)
785 #endif /* CONFIG_HIGHMEM */
786
787-unsigned long __PAGE_KERNEL = _PAGE_KERNEL;
788+unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
789+unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
790
791 #ifndef CONFIG_DISCONTIGMEM
792 #define remap_numa_kva() do {} while (0)
793@@ -301,6 +320,7 @@ static void __init pagetable_init (void)
794 if (cpu_has_pge) {
795 set_in_cr4(X86_CR4_PGE);
796 __PAGE_KERNEL |= _PAGE_GLOBAL;
797+ __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL;
798 }
799
800 kernel_physical_mapping_init(pgd_base);
801@@ -391,6 +411,53 @@ void __init zone_sizes_init(void)
802 extern void zone_sizes_init(void);
803 #endif /* !CONFIG_DISCONTIGMEM */
804
805+static int disable_nx __initdata = 0;
806+u64 __supported_pte_mask = ~_PAGE_NX;
807+int use_nx = 0;
808+
809+/*
810+ * noexec = on|off
811+ *
812+ * Control non executable mappings.
813+ *
814+ * on Enable
815+ * off Disable (disables exec-shield too)
816+ */
817+static int __init noexec_setup(char *str)
818+{
819+ if (!strncmp(str, "on",2) && cpu_has_nx) {
820+ __supported_pte_mask |= _PAGE_NX;
821+ disable_nx = 0;
822+ } else if (!strncmp(str,"off",3)) {
823+ disable_nx = 1;
824+ __supported_pte_mask &= ~_PAGE_NX;
825+ exec_shield = 0;
826+ }
827+ return 1;
828+}
829+
830+__setup("noexec=", noexec_setup);
831+
832+#ifdef CONFIG_X86_PAE
833+
834+static void __init set_nx(void)
835+{
836+ unsigned int v[4], l, h;
837+
838+ if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
839+ cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
840+ if ((v[3] & (1 << 20)) && !disable_nx) {
841+ rdmsr(MSR_EFER, l, h);
842+ l |= EFER_NX;
843+ wrmsr(MSR_EFER, l, h);
844+ use_nx = 1;
845+ __supported_pte_mask |= _PAGE_NX;
846+ }
847+ }
848+}
849+
850+#endif
851+
852 /*
853 * paging_init() sets up the page tables - note that the first 8MB are
854 * already mapped by head.S.
855@@ -400,6 +467,14 @@ extern void zone_sizes_init(void);
856 */
857 void __init paging_init(void)
858 {
859+#ifdef CONFIG_X86_PAE
860+ set_nx();
861+ if (use_nx)
862+ printk("NX (Execute Disable) protection: active\n");
863+ else if (exec_shield)
864+ printk("Using x86 segment limits to approximate NX (Execute Disable) protection\n");
865+#endif
866+
867 pagetable_init();
868
869 load_cr3(swapper_pg_dir);
870--- linux/arch/sparc/kernel/sys_sparc.c.orig
871+++ linux/arch/sparc/kernel/sys_sparc.c
872@@ -332,7 +332,7 @@ asmlinkage unsigned long sparc_mremap(un
873
874 new_addr = get_unmapped_area(file, addr, new_len,
875 vma ? vma->vm_pgoff : 0,
876- map_flags);
877+ map_flags, vma->vm_flags & VM_EXEC);
878 ret = new_addr;
879 if (new_addr & ~PAGE_MASK)
880 goto out_sem;
881--- linux/arch/ia64/kernel/perfmon.c.orig
882+++ linux/arch/ia64/kernel/perfmon.c
883@@ -600,7 +600,7 @@ pfm_do_munmap(struct mm_struct *mm, unsi
884 static inline unsigned long
885 pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)
886 {
887- return get_unmapped_area(file, addr, len, pgoff, flags);
888+ return get_unmapped_area(file, addr, len, pgoff, flags, 0);
889 }
890
891
892--- linux/arch/ia64/ia32/binfmt_elf32.c.orig
893+++ linux/arch/ia64/ia32/binfmt_elf32.c
894@@ -215,7 +215,7 @@ elf32_set_personality (void)
895 }
896
897 static unsigned long
898-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
899+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
900 {
901 unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
902
903--- linux/arch/x86_64/kernel/module.c.orig
904+++ linux/arch/x86_64/kernel/module.c
905@@ -121,7 +121,7 @@ void *module_alloc(unsigned long size)
906 goto fail;
907 }
908
909- if (map_vm_area(area, PAGE_KERNEL_EXECUTABLE, &pages))
910+ if (map_vm_area(area, PAGE_KERNEL_EXEC, &pages))
911 goto fail;
912
913 memset(addr, 0, size);
914--- linux/arch/x86_64/mm/pageattr.c.orig
915+++ linux/arch/x86_64/mm/pageattr.c
916@@ -180,7 +180,7 @@ int change_page_attr(struct page *page,
917 unsigned long addr2;
918 addr2 = __START_KERNEL_map + page_to_phys(page);
919 err = __change_page_attr(addr2, page, prot,
920- PAGE_KERNEL_EXECUTABLE);
921+ PAGE_KERNEL_EXEC);
922 }
923 }
924 up_write(&init_mm.mmap_sem);
925--- linux/arch/x86_64/ia32/ia32_binfmt.c.orig
926+++ linux/arch/x86_64/ia32/ia32_binfmt.c
927@@ -382,7 +382,7 @@ int setup_arg_pages(struct linux_binprm
928 }
929
930 static unsigned long
931-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
932+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
933 {
934 unsigned long map_addr;
935 struct task_struct *me = current;
936--- linux/include/asm-x86_64/pgalloc.h.orig
937+++ linux/include/asm-x86_64/pgalloc.h
938@@ -7,6 +7,11 @@
939 #include <linux/threads.h>
940 #include <linux/mm.h>
941
942+#define arch_add_exec_range(mm, limit) do { ; } while (0)
943+#define arch_flush_exec_range(mm) do { ; } while (0)
944+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
945+
946+
947 #define pmd_populate_kernel(mm, pmd, pte) \
948 set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
949 #define pgd_populate(mm, pgd, pmd) \
950--- linux/include/asm-x86_64/pgtable.h.orig
951+++ linux/include/asm-x86_64/pgtable.h
952@@ -172,7 +172,7 @@ static inline void set_pml4(pml4_t *dst,
953 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
954 #define __PAGE_KERNEL \
955 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
956-#define __PAGE_KERNEL_EXECUTABLE \
957+#define __PAGE_KERNEL_EXEC \
958 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
959 #define __PAGE_KERNEL_NOCACHE \
960 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX)
961@@ -188,7 +188,7 @@ static inline void set_pml4(pml4_t *dst,
962 #define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL)
963
964 #define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
965-#define PAGE_KERNEL_EXECUTABLE MAKE_GLOBAL(__PAGE_KERNEL_EXECUTABLE)
966+#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
967 #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
968 #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
969 #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
970--- linux/include/linux/mm.h.orig
971+++ linux/include/linux/mm.h
972@@ -630,7 +630,7 @@ extern struct vm_area_struct *copy_vma(s
973 unsigned long addr, unsigned long len, pgoff_t pgoff);
974 extern void exit_mmap(struct mm_struct *);
975
976-extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
977+extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
978
979 extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
980 unsigned long len, unsigned long prot,
981--- linux/include/linux/resource.h.orig
982+++ linux/include/linux/resource.h
983@@ -52,8 +52,11 @@ struct rlimit {
984 /*
985 * Limit the stack by to some sane default: root can always
986 * increase this limit if needed.. 8MB seems reasonable.
987+ *
988+ * (2MB more to cover randomization effects.)
989 */
990-#define _STK_LIM (8*1024*1024)
991+#define _STK_LIM (10*1024*1024)
992+#define EXEC_STACK_BIAS (2*1024*1024)
993
994 /*
995 * Due to binary compatibility, the actual resource numbers
996--- linux/include/linux/sched.h.orig
997+++ linux/include/linux/sched.h
998@@ -31,6 +31,9 @@
999 #include <linux/percpu.h>
1000
1001 struct exec_domain;
1002+extern int exec_shield;
1003+extern int exec_shield_randomize;
1004+extern int print_fatal_signals;
1005
1006 /*
1007 * cloning flags:
1008@@ -194,6 +197,8 @@ struct mm_struct {
1009 struct rb_root mm_rb;
1010 struct vm_area_struct * mmap_cache; /* last find_vma result */
1011 unsigned long free_area_cache; /* first hole */
1012+ unsigned long non_executable_cache; /* last hole top */
1013+ unsigned long mmap_top; /* top of mmap area */
1014 pgd_t * pgd;
1015 atomic_t mm_users; /* How many users with user space? */
1016 atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
1017--- linux/include/linux/vmalloc.h.orig
1018+++ linux/include/linux/vmalloc.h
1019@@ -23,6 +23,7 @@ struct vm_struct {
1020 * Highlevel APIs for driver use
1021 */
1022 extern void *vmalloc(unsigned long size);
1023+extern void *vmalloc_exec(unsigned long size);
1024 extern void *vmalloc_32(unsigned long size);
1025 extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot);
1026 extern void vfree(void *addr);
1027--- linux/include/asm-ppc64/pgalloc.h.orig
1028+++ linux/include/asm-ppc64/pgalloc.h
1029@@ -10,6 +10,11 @@
1030
1031 extern kmem_cache_t *zero_cache;
1032
1033+/* Dummy functions since we don't support execshield on ppc */
1034+#define arch_add_exec_range(mm, limit) do { ; } while (0)
1035+#define arch_flush_exec_range(mm) do { ; } while (0)
1036+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
1037+
1038 /*
1039 * This program is free software; you can redistribute it and/or
1040 * modify it under the terms of the GNU General Public License
1041--- linux/include/asm-ia64/pgalloc.h.orig
1042+++ linux/include/asm-ia64/pgalloc.h
1043@@ -23,6 +23,10 @@
1044 #include <asm/mmu_context.h>
1045 #include <asm/processor.h>
1046
1047+#define arch_add_exec_range(mm, limit) do { ; } while (0)
1048+#define arch_flush_exec_range(mm) do { ; } while (0)
1049+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
1050+
1051 /*
1052 * Very stupidly, we used to get new pgd's and pmd's, init their contents
1053 * to point to the NULL versions of the next level page table, later on
1054--- linux/include/asm-ppc/pgalloc.h.orig
1055+++ linux/include/asm-ppc/pgalloc.h
1056@@ -40,5 +40,10 @@ extern void pte_free(struct page *pte);
1057
1058 #define check_pgt_cache() do { } while (0)
1059
1060+#define arch_add_exec_range(mm, limit) do { ; } while (0)
1061+#define arch_flush_exec_range(mm) do { ; } while (0)
1062+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
1063+
1064+
1065 #endif /* _PPC_PGALLOC_H */
1066 #endif /* __KERNEL__ */
1067--- linux/include/asm-sparc/pgalloc.h.orig
1068+++ linux/include/asm-sparc/pgalloc.h
1069@@ -66,4 +66,8 @@ BTFIXUPDEF_CALL(void, pte_free, struct p
1070 #define pte_free(pte) BTFIXUP_CALL(pte_free)(pte)
1071 #define __pte_free_tlb(tlb, pte) pte_free(pte)
1072
1073+#define arch_add_exec_range(mm, limit) do { ; } while (0)
1074+#define arch_flush_exec_range(mm) do { ; } while (0)
1075+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
1076+
1077 #endif /* _SPARC_PGALLOC_H */
1078--- linux/include/asm-s390/pgalloc.h.orig
1079+++ linux/include/asm-s390/pgalloc.h
1080@@ -19,6 +19,10 @@
1081 #include <linux/gfp.h>
1082 #include <linux/mm.h>
1083
1084+#define arch_add_exec_range(mm, limit) do { ; } while (0)
1085+#define arch_flush_exec_range(mm) do { ; } while (0)
1086+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
1087+
1088 #define check_pgt_cache() do {} while (0)
1089
1090 extern void diag10(unsigned long addr);
1091--- linux/include/asm-i386/desc.h.orig
1092+++ linux/include/asm-i386/desc.h
1093@@ -123,6 +123,20 @@ static inline void load_LDT(mm_context_t
1094 put_cpu();
1095 }
1096
1097+static inline void set_user_cs(struct desc_struct *desc, unsigned long limit)
1098+{
1099+ limit = (limit - 1) / PAGE_SIZE;
1100+ desc->a = limit & 0xffff;
1101+ desc->b = (limit & 0xf0000) | 0x00c0fb00;
1102+}
1103+
1104+#define load_user_cs_desc(cpu, mm) \
1105+ cpu_gdt_table[(cpu)][GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs
1106+
1107+extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit);
1108+extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit);
1109+extern void arch_flush_exec_range(struct mm_struct *mm);
1110+
1111 #endif /* !__ASSEMBLY__ */
1112
1113 #endif
1114--- linux/include/asm-i386/cpufeature.h.orig
1115+++ linux/include/asm-i386/cpufeature.h
1116@@ -47,6 +47,7 @@
1117 /* Don't duplicate feature flags which are redundant with Intel! */
1118 #define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */
1119 #define X86_FEATURE_MP (1*32+19) /* MP Capable. */
1120+#define X86_FEATURE_NX (1*32+20) /* Execute Disable */
1121 #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */
1122 #define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */
1123 #define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */
1124@@ -100,6 +101,7 @@
1125 #define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM)
1126 #define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
1127 #define cpu_has_mp boot_cpu_has(X86_FEATURE_MP)
1128+#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX)
1129 #define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR)
1130 #define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR)
1131 #define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR)
1132--- linux/include/asm-i386/elf.h.orig
1133+++ linux/include/asm-i386/elf.h
1134@@ -9,6 +9,7 @@
1135 #include <asm/user.h>
1136 #include <asm/processor.h>
1137 #include <asm/system.h> /* for savesegment */
1138+#include <asm/desc.h>
1139
1140 #include <linux/utsname.h>
1141
1142@@ -117,7 +118,8 @@ typedef struct user_fxsr_struct elf_fpxr
1143 #define AT_SYSINFO_EHDR 33
1144
1145 #ifdef __KERNEL__
1146-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
1147+/* child inherits the personality of the parent */
1148+#define SET_PERSONALITY(ex, ibcs2) do { } while (0)
1149
1150 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
1151 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
1152@@ -127,15 +129,22 @@ extern int dump_task_extended_fpu (struc
1153 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
1154 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
1155
1156-#define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
1157-#define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
1158-#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
1159 extern void __kernel_vsyscall;
1160+#define VSYSCALL_BASE ((unsigned long)current->mm->context.vdso)
1161+#define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
1162+#define VSYSCALL_OFFSET ((unsigned long) &__kernel_vsyscall)
1163+#define VSYSCALL_ENTRY (VSYSCALL_BASE + VSYSCALL_OFFSET)
1164
1165-#define ARCH_DLINFO \
1166-do { \
1167- NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \
1168- NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \
1169+/* kernel-internal fixmap address: */
1170+#define __VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
1171+#define __VSYSCALL_EHDR ((const struct elfhdr *) __VSYSCALL_BASE)
1172+
1173+#define ARCH_DLINFO \
1174+do { \
1175+ if (VSYSCALL_BASE) { \
1176+ NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \
1177+ NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \
1178+ } \
1179 } while (0)
1180
1181 /*
1182@@ -146,15 +155,15 @@ do { \
1183 * Dumping its extra ELF program headers includes all the other information
1184 * a debugger needs to easily find how the vsyscall DSO was being used.
1185 */
1186-#define ELF_CORE_EXTRA_PHDRS (VSYSCALL_EHDR->e_phnum)
1187+#define ELF_CORE_EXTRA_PHDRS (__VSYSCALL_EHDR->e_phnum)
1188 #define ELF_CORE_WRITE_EXTRA_PHDRS \
1189 do { \
1190 const struct elf_phdr *const vsyscall_phdrs = \
1191- (const struct elf_phdr *) (VSYSCALL_BASE \
1192- + VSYSCALL_EHDR->e_phoff); \
1193+ (const struct elf_phdr *) (__VSYSCALL_BASE \
1194+ + __VSYSCALL_EHDR->e_phoff); \
1195 int i; \
1196 Elf32_Off ofs = 0; \
1197- for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \
1198+ for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) { \
1199 struct elf_phdr phdr = vsyscall_phdrs[i]; \
1200 if (phdr.p_type == PT_LOAD) { \
1201 BUG_ON(ofs != 0); \
1202@@ -172,10 +181,10 @@ do { \
1203 #define ELF_CORE_WRITE_EXTRA_DATA \
1204 do { \
1205 const struct elf_phdr *const vsyscall_phdrs = \
1206- (const struct elf_phdr *) (VSYSCALL_BASE \
1207- + VSYSCALL_EHDR->e_phoff); \
1208+ (const struct elf_phdr *) (__VSYSCALL_BASE \
1209+ + __VSYSCALL_EHDR->e_phoff); \
1210 int i; \
1211- for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \
1212+ for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) { \
1213 if (vsyscall_phdrs[i].p_type == PT_LOAD) \
1214 DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \
1215 PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \
1216@@ -184,4 +193,10 @@ do { \
1217
1218 #endif
1219
1220+#define __HAVE_ARCH_RANDOMIZE_BRK
1221+extern void randomize_brk(unsigned long old_brk);
1222+
1223+#define __HAVE_ARCH_VSYSCALL
1224+extern void map_vsyscall(void);
1225+
1226 #endif
1227--- linux/include/asm-i386/mmu.h.orig
1228+++ linux/include/asm-i386/mmu.h
1229@@ -7,11 +7,17 @@
1230 * we put the segment information here.
1231 *
1232 * cpu_vm_mask is used to optimize ldt flushing.
1233+ *
1234+ * exec_limit is used to track the range PROT_EXEC
1235+ * mappings span.
1236 */
1237 typedef struct {
1238 int size;
1239 struct semaphore sem;
1240 void *ldt;
1241+ struct desc_struct user_cs;
1242+ unsigned long exec_limit;
1243+ void *vdso;
1244 } mm_context_t;
1245
1246 #endif
1247--- linux/include/asm-i386/msr.h.orig
1248+++ linux/include/asm-i386/msr.h
1249@@ -217,6 +217,15 @@ static inline void wrmsrl (unsigned long
1250 #define MSR_K7_FID_VID_CTL 0xC0010041
1251 #define MSR_K7_FID_VID_STATUS 0xC0010042
1252
1253+/* extended feature register */
1254+#define MSR_EFER 0xc0000080
1255+
1256+/* EFER bits: */
1257+
1258+/* Execute Disable enable */
1259+#define _EFER_NX 11
1260+#define EFER_NX (1<<_EFER_NX)
1261+
1262 /* Centaur-Hauls/IDT defined MSRs. */
1263 #define MSR_IDT_FCR1 0x107
1264 #define MSR_IDT_FCR2 0x108
1265--- linux/include/asm-i386/page.h.orig
1266+++ linux/include/asm-i386/page.h
1267@@ -40,15 +40,18 @@
1268 * These are used to make use of C type-checking..
1269 */
1270 #ifdef CONFIG_X86_PAE
1271+extern unsigned long long __supported_pte_mask;
1272 typedef struct { unsigned long pte_low, pte_high; } pte_t;
1273 typedef struct { unsigned long long pmd; } pmd_t;
1274 typedef struct { unsigned long long pgd; } pgd_t;
1275+typedef struct { unsigned long long pgprot; } pgprot_t;
1276 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
1277 #define HPAGE_SHIFT 21
1278 #else
1279 typedef struct { unsigned long pte_low; } pte_t;
1280 typedef struct { unsigned long pmd; } pmd_t;
1281 typedef struct { unsigned long pgd; } pgd_t;
1282+typedef struct { unsigned long pgprot; } pgprot_t;
1283 #define boot_pte_t pte_t /* or would you rather have a typedef */
1284 #define pte_val(x) ((x).pte_low)
1285 #define HPAGE_SHIFT 22
1286@@ -61,7 +64,6 @@ typedef struct { unsigned long pgd; } pg
1287 #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
1288 #endif
1289
1290-typedef struct { unsigned long pgprot; } pgprot_t;
1291
1292 #define pmd_val(x) ((x).pmd)
1293 #define pgd_val(x) ((x).pgd)
1294@@ -136,7 +138,7 @@ static __inline__ int get_order(unsigned
1295
1296 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
1297
1298-#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
1299+#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \
1300 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1301
1302 #endif /* __KERNEL__ */
1303--- linux/include/asm-i386/pgalloc.h.orig
1304+++ linux/include/asm-i386/pgalloc.h
1305@@ -4,6 +4,7 @@
1306 #include <linux/config.h>
1307 #include <asm/processor.h>
1308 #include <asm/fixmap.h>
1309+#include <asm/desc.h>
1310 #include <linux/threads.h>
1311 #include <linux/mm.h> /* for struct page */
1312
1313@@ -52,4 +53,6 @@ static inline void pte_free(struct page
1314
1315 #define check_pgt_cache() do { } while (0)
1316
1317+#define HAVE_ARCH_UNMAPPED_AREA 1
1318+
1319 #endif /* _I386_PGALLOC_H */
1320--- linux/include/asm-i386/pgtable-3level.h.orig
1321+++ linux/include/asm-i386/pgtable-3level.h
1322@@ -101,18 +101,24 @@ static inline unsigned long pte_pfn(pte_
1323 (pte.pte_high << (32 - PAGE_SHIFT));
1324 }
1325
1326+extern unsigned long long __supported_pte_mask;
1327+
1328 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
1329 {
1330 pte_t pte;
1331
1332- pte.pte_high = page_nr >> (32 - PAGE_SHIFT);
1333- pte.pte_low = (page_nr << PAGE_SHIFT) | pgprot_val(pgprot);
1334+ pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \
1335+ (pgprot_val(pgprot) >> 32);
1336+ pte.pte_high &= (__supported_pte_mask >> 32);
1337+ pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \
1338+ __supported_pte_mask;
1339 return pte;
1340 }
1341
1342 static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
1343 {
1344- return __pmd(((unsigned long long)page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
1345+ return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | \
1346+ pgprot_val(pgprot)) & __supported_pte_mask);
1347 }
1348
1349 /*
1350--- linux/include/asm-i386/pgtable.h.orig
1351+++ linux/include/asm-i386/pgtable.h
1352@@ -110,6 +110,7 @@ void paging_init(void);
1353 #define _PAGE_BIT_UNUSED1 9 /* available for programmer */
1354 #define _PAGE_BIT_UNUSED2 10
1355 #define _PAGE_BIT_UNUSED3 11
1356+#define _PAGE_BIT_NX 63
1357
1358 #define _PAGE_PRESENT 0x001
1359 #define _PAGE_RW 0x002
1360@@ -126,28 +127,51 @@ void paging_init(void);
1361
1362 #define _PAGE_FILE 0x040 /* set:pagecache unset:swap */
1363 #define _PAGE_PROTNONE 0x080 /* If not present */
1364+#ifdef CONFIG_X86_PAE
1365+#define _PAGE_NX (1ULL<<_PAGE_BIT_NX)
1366+#else
1367+#define _PAGE_NX 0
1368+#endif
1369
1370 #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
1371 #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
1372 #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
1373
1374-#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
1375-#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
1376-#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
1377-#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
1378+#define PAGE_NONE \
1379+ __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
1380+#define PAGE_SHARED \
1381+ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
1382+
1383+#define PAGE_SHARED_EXEC \
1384+ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
1385+#define PAGE_COPY_NOEXEC \
1386+ __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
1387+#define PAGE_COPY_EXEC \
1388+ __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
1389+#define PAGE_COPY \
1390+ PAGE_COPY_NOEXEC
1391+#define PAGE_READONLY \
1392+ __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
1393+#define PAGE_READONLY_EXEC \
1394+ __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
1395
1396 #define _PAGE_KERNEL \
1397+ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
1398+#define _PAGE_KERNEL_EXEC \
1399 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
1400
1401-extern unsigned long __PAGE_KERNEL;
1402-#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW)
1403-#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD)
1404-#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
1405+extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
1406+#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW)
1407+#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD)
1408+#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
1409+#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
1410
1411 #define PAGE_KERNEL __pgprot(__PAGE_KERNEL)
1412 #define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO)
1413+#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC)
1414 #define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE)
1415 #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE)
1416+#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC)
1417
1418 /*
1419 * The i386 can't do page protection for execute, and considers that
1420@@ -158,19 +182,19 @@ extern unsigned long __PAGE_KERNEL;
1421 #define __P001 PAGE_READONLY
1422 #define __P010 PAGE_COPY
1423 #define __P011 PAGE_COPY
1424-#define __P100 PAGE_READONLY
1425-#define __P101 PAGE_READONLY
1426-#define __P110 PAGE_COPY
1427-#define __P111 PAGE_COPY
1428+#define __P100 PAGE_READONLY_EXEC
1429+#define __P101 PAGE_READONLY_EXEC
1430+#define __P110 PAGE_COPY_EXEC
1431+#define __P111 PAGE_COPY_EXEC
1432
1433 #define __S000 PAGE_NONE
1434 #define __S001 PAGE_READONLY
1435 #define __S010 PAGE_SHARED
1436 #define __S011 PAGE_SHARED
1437-#define __S100 PAGE_READONLY
1438-#define __S101 PAGE_READONLY
1439-#define __S110 PAGE_SHARED
1440-#define __S111 PAGE_SHARED
1441+#define __S100 PAGE_READONLY_EXEC
1442+#define __S101 PAGE_READONLY_EXEC
1443+#define __S110 PAGE_SHARED_EXEC
1444+#define __S111 PAGE_SHARED_EXEC
1445
1446 /*
1447 * Define this if things work differently on an i386 and an i486:
1448@@ -256,6 +280,15 @@ static inline pte_t pte_modify(pte_t pte
1449 {
1450 pte.pte_low &= _PAGE_CHG_MASK;
1451 pte.pte_low |= pgprot_val(newprot);
1452+#ifdef CONFIG_X86_PAE
1453+ /*
1454+ * Chop off the NX bit (if present), and add the NX portion of
1455+ * the newprot (if present):
1456+ */
1457+ pte.pte_high &= -1 ^ (1 << (_PAGE_BIT_NX - 32));
1458+ pte.pte_high |= (pgprot_val(newprot) >> 32) & \
1459+ (__supported_pte_mask >> 32);
1460+#endif
1461 return pte;
1462 }
1463
1464--- linux/include/asm-i386/processor.h.orig
1465+++ linux/include/asm-i386/processor.h
1466@@ -294,7 +294,15 @@ extern unsigned int mca_pentium_flag;
1467 /* This decides where the kernel will search for a free chunk of vm
1468 * space during mmap's.
1469 */
1470-#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
1471+#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE/3)
1472+
1473+#define SHLIB_BASE 0x00111000
1474+
1475+#define __HAVE_ARCH_ALIGN_STACK
1476+extern unsigned long arch_align_stack(unsigned long sp);
1477+
1478+#define __HAVE_ARCH_MMAP_TOP
1479+extern unsigned long mmap_top(void);
1480
1481 /*
1482 * Size of io_bitmap, covering ports 0 to 0x3ff.
1483@@ -456,6 +464,8 @@ static inline void load_esp0(struct tss_
1484 }
1485 }
1486
1487+extern int use_nx;
1488+
1489 #define start_thread(regs, new_eip, new_esp) do { \
1490 __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \
1491 set_fs(USER_DS); \
1492@@ -465,6 +475,7 @@ static inline void load_esp0(struct tss_
1493 regs->xcs = __USER_CS; \
1494 regs->eip = new_eip; \
1495 regs->esp = new_esp; \
1496+ load_user_cs_desc(smp_processor_id(), current->mm); \
1497 } while (0)
1498
1499 /* Forward declaration, a strange C thing */
1500--- linux/include/asm-i386/thread_info.h.orig
1501+++ linux/include/asm-i386/thread_info.h
1502@@ -37,6 +37,7 @@ struct thread_info {
1503 0-0xBFFFFFFF for user-thead
1504 0-0xFFFFFFFF for kernel-thread
1505 */
1506+ void *sysenter_return;
1507 struct restart_block restart_block;
1508
1509 unsigned long previous_esp; /* ESP of the previous stack in case
1510--- linux/include/asm-sparc64/pgalloc.h.orig
1511+++ linux/include/asm-sparc64/pgalloc.h
1512@@ -236,4 +236,8 @@ static __inline__ void free_pte_slow(pte
1513 #define pgd_free(pgd) free_pgd_fast(pgd)
1514 #define pgd_alloc(mm) get_pgd_fast()
1515
1516+#define arch_add_exec_range(mm, limit) do { ; } while (0)
1517+#define arch_flush_exec_range(mm) do { ; } while (0)
1518+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
1519+
1520 #endif /* _SPARC64_PGALLOC_H */
1521--- linux/fs/proc/array.c.orig
1522+++ linux/fs/proc/array.c
1523@@ -324,7 +324,10 @@ int proc_pid_stat(struct task_struct *ta
1524 up_read(&mm->mmap_sem);
1525 }
1526
1527- wchan = get_wchan(task);
1528+ wchan = 0;
1529+ if (current->uid == task->uid || current->euid == task->uid ||
1530+ capable(CAP_SYS_NICE))
1531+ wchan = get_wchan(task);
1532
1533 sigemptyset(&sigign);
1534 sigemptyset(&sigcatch);
1535--- linux/fs/proc/base.c.orig
1536+++ linux/fs/proc/base.c
1537@@ -111,7 +111,7 @@ static struct pid_entry tgid_base_stuff[
1538 E(PROC_TGID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
1539 E(PROC_TGID_STAT, "stat", S_IFREG|S_IRUGO),
1540 E(PROC_TGID_STATM, "statm", S_IFREG|S_IRUGO),
1541- E(PROC_TGID_MAPS, "maps", S_IFREG|S_IRUGO),
1542+ E(PROC_TGID_MAPS, "maps", S_IFREG|S_IRUSR),
1543 E(PROC_TGID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
1544 E(PROC_TGID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
1545 E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
1546@@ -133,7 +133,7 @@ static struct pid_entry tid_base_stuff[]
1547 E(PROC_TID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
1548 E(PROC_TID_STAT, "stat", S_IFREG|S_IRUGO),
1549 E(PROC_TID_STATM, "statm", S_IFREG|S_IRUGO),
1550- E(PROC_TID_MAPS, "maps", S_IFREG|S_IRUGO),
1551+ E(PROC_TID_MAPS, "maps", S_IFREG|S_IRUSR),
1552 E(PROC_TID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
1553 E(PROC_TID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
1554 E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO),
1555--- linux/fs/proc/task_mmu.c.orig
1556+++ linux/fs/proc/task_mmu.c
1557@@ -34,12 +34,23 @@ char *task_mem(struct mm_struct *mm, cha
1558 "VmData:\t%8lu kB\n"
1559 "VmStk:\t%8lu kB\n"
1560 "VmExe:\t%8lu kB\n"
1561- "VmLib:\t%8lu kB\n",
1562+ "VmLib:\t%8lu kB\n"
1563+ "StaBrk:\t%08lx kB\n"
1564+ "Brk:\t%08lx kB\n"
1565+ "StaStk:\t%08lx kB\n"
1566+#if __i386__
1567+ "ExecLim:\t%08lx\n"
1568+#endif
1569+ ,
1570 mm->total_vm << (PAGE_SHIFT-10),
1571 mm->locked_vm << (PAGE_SHIFT-10),
1572 mm->rss << (PAGE_SHIFT-10),
1573 data - stack, stack,
1574- exec - lib, lib);
1575+ exec - lib, lib, mm->start_brk, mm->brk, mm->start_stack
1576+#if __i386__
1577+ , mm->context.exec_limit
1578+#endif
1579+ );
1580 up_read(&mm->mmap_sem);
1581 return buffer;
1582 }
1583--- linux/fs/binfmt_aout.c.orig
1584+++ linux/fs/binfmt_aout.c
1585@@ -308,7 +308,8 @@ static int load_aout_binary(struct linux
1586 current->mm->brk = ex.a_bss +
1587 (current->mm->start_brk = N_BSSADDR(ex));
1588 current->mm->free_area_cache = TASK_UNMAPPED_BASE;
1589-
1590+ /* unlimited stack is larger than TASK_SIZE */
1591+ current->mm->non_executable_cache = current->mm->mmap_top;
1592 current->mm->rss = 0;
1593 current->mm->mmap = NULL;
1594 compute_creds(bprm);
1595--- linux/fs/binfmt_elf.c.orig
1596+++ linux/fs/binfmt_elf.c
1597@@ -45,7 +45,7 @@
1598
1599 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
1600 static int load_elf_library(struct file*);
1601-static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
1602+static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long);
1603 extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
1604
1605 #ifndef elf_addr_t
1606@@ -155,20 +155,8 @@ create_elf_tables(struct linux_binprm *b
1607 if (k_platform) {
1608 size_t len = strlen(k_platform) + 1;
1609
1610-#ifdef CONFIG_X86_HT
1611- /*
1612- * In some cases (e.g. Hyper-Threading), we want to avoid L1
1613- * evictions by the processes running on the same package. One
1614- * thing we can do is to shuffle the initial stack for them.
1615- *
1616- * The conditionals here are unneeded, but kept in to make the
1617- * code behaviour the same as pre change unless we have
1618- * hyperthreaded processors. This should be cleaned up
1619- * before 2.6
1620- */
1621-
1622- if (smp_num_siblings > 1)
1623- STACK_ALLOC(p, ((current->pid % 64) << 7));
1624+#ifdef __HAVE_ARCH_ALIGN_STACK
1625+ p = (unsigned long)arch_align_stack((unsigned long)p);
1626 #endif
1627 u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
1628 __copy_to_user(u_platform, k_platform, len);
1629@@ -272,20 +260,59 @@ create_elf_tables(struct linux_binprm *b
1630 #ifndef elf_map
1631
1632 static unsigned long elf_map(struct file *filep, unsigned long addr,
1633- struct elf_phdr *eppnt, int prot, int type)
1634+ struct elf_phdr *eppnt, int prot, int type,
1635+ unsigned long total_size)
1636 {
1637 unsigned long map_addr;
1638+ unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
1639+ unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
1640+
1641+ addr = ELF_PAGESTART(addr);
1642+ size = ELF_PAGEALIGN(size);
1643
1644 down_write(&current->mm->mmap_sem);
1645- map_addr = do_mmap(filep, ELF_PAGESTART(addr),
1646- eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
1647- eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
1648+
1649+ /*
1650+ * total_size is the size of the ELF (interpreter) image.
1651+ * The _first_ mmap needs to know the full size, otherwise
1652+ * randomization might put this image into an overlapping
1653+ * position with the ELF binary image. (since size < total_size)
1654+ * So we first map the 'big' image - and unmap the remainder at
1655+ * the end. (which unmap is needed for ELF images with holes.)
1656+ */
1657+ if (total_size) {
1658+ total_size = ELF_PAGEALIGN(total_size);
1659+ map_addr = do_mmap(filep, addr, total_size, prot, type, off);
1660+ if (!BAD_ADDR(map_addr))
1661+ do_munmap(current->mm, map_addr+size, total_size-size);
1662+ } else
1663+ map_addr = do_mmap(filep, addr, size, prot, type, off);
1664+
1665 up_write(&current->mm->mmap_sem);
1666- return(map_addr);
1667+
1668+ return map_addr;
1669 }
1670
1671 #endif /* !elf_map */
1672
1673+static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr)
1674+{
1675+ int i, first_idx = -1, last_idx = -1;
1676+
1677+ for (i = 0; i < nr; i++)
1678+ if (cmds[i].p_type == PT_LOAD) {
1679+ last_idx = i;
1680+ if (first_idx == -1)
1681+ first_idx = i;
1682+ }
1683+
1684+ if (first_idx == -1)
1685+ return 0;
1686+
1687+ return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz -
1688+ ELF_PAGESTART(cmds[first_idx].p_vaddr);
1689+}
1690+
1691 /* This is much more generalized than the library routine read function,
1692 so we keep this separate. Technically the library read function
1693 is only provided so that we can read a.out libraries that have
1694@@ -293,7 +320,8 @@ static unsigned long elf_map(struct file
1695
1696 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
1697 struct file * interpreter,
1698- unsigned long *interp_load_addr)
1699+ unsigned long *interp_load_addr,
1700+ unsigned long no_base)
1701 {
1702 struct elf_phdr *elf_phdata;
1703 struct elf_phdr *eppnt;
1704@@ -301,6 +329,7 @@ static unsigned long load_elf_interp(str
1705 int load_addr_set = 0;
1706 unsigned long last_bss = 0, elf_bss = 0;
1707 unsigned long error = ~0UL;
1708+ unsigned long total_size;
1709 int retval, i, size;
1710
1711 /* First of all, some simple consistency checks */
1712@@ -335,6 +364,10 @@ static unsigned long load_elf_interp(str
1713 if (retval < 0)
1714 goto out_close;
1715
1716+ total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
1717+ if (!total_size)
1718+ goto out_close;
1719+
1720 eppnt = elf_phdata;
1721 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
1722 if (eppnt->p_type == PT_LOAD) {
1723@@ -349,8 +382,11 @@ static unsigned long load_elf_interp(str
1724 vaddr = eppnt->p_vaddr;
1725 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
1726 elf_type |= MAP_FIXED;
1727+ else if (no_base && interp_elf_ex->e_type == ET_DYN)
1728+ load_addr = -vaddr;
1729
1730- map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
1731+ map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type, total_size);
1732+ total_size = 0;
1733 error = map_addr;
1734 if (BAD_ADDR(map_addr))
1735 goto out_close;
1736@@ -490,6 +526,7 @@ static int load_elf_binary(struct linux_
1737 char passed_fileno[6];
1738 struct files_struct *files;
1739 int executable_stack = EXSTACK_DEFAULT;
1740+ unsigned long def_flags = 0;
1741
1742 /* Get the exec-header */
1743 elf_ex = *((struct elfhdr *) bprm->buf);
1744@@ -621,7 +658,18 @@ static int load_elf_binary(struct linux_
1745 executable_stack = EXSTACK_ENABLE_X;
1746 else
1747 executable_stack = EXSTACK_DISABLE_X;
1748+ break;
1749 }
1750+ if (i == elf_ex.e_phnum)
1751+ def_flags |= VM_EXEC | VM_MAYEXEC;
1752+
1753+ if (current->personality == PER_LINUX)
1754+ switch (exec_shield) {
1755+ case 2:
1756+ executable_stack = EXSTACK_DISABLE_X;
1757+ def_flags &= ~(VM_EXEC | VM_MAYEXEC);
1758+ break;
1759+ }
1760
1761 /* Some simple consistency checks for the interpreter */
1762 if (elf_interpreter) {
1763@@ -676,6 +724,15 @@ static int load_elf_binary(struct linux_
1764 if (retval)
1765 goto out_free_dentry;
1766
1767+#ifdef __i386__
1768+ /*
1769+ * Turn off the CS limit completely if exec-shield disabled or
1770+ * NX active:
1771+ */
1772+ if (!exec_shield || use_nx)
1773+ arch_add_exec_range(current->mm, -1);
1774+#endif
1775+
1776 /* Discard our unneeded old files struct */
1777 if (files) {
1778 steal_locks(files);
1779@@ -688,7 +745,11 @@ static int load_elf_binary(struct linux_
1780 current->mm->end_data = 0;
1781 current->mm->end_code = 0;
1782 current->mm->mmap = NULL;
1783+#ifdef __HAVE_ARCH_MMAP_TOP
1784+ current->mm->mmap_top = mmap_top();
1785+#endif
1786 current->flags &= ~PF_FORKNOEXEC;
1787+ current->mm->def_flags = def_flags;
1788
1789 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
1790 may depend on the personality. */
1791@@ -698,6 +759,7 @@ static int load_elf_binary(struct linux_
1792 change some of these later */
1793 current->mm->rss = 0;
1794 current->mm->free_area_cache = TASK_UNMAPPED_BASE;
1795+ current->mm->non_executable_cache = current->mm->mmap_top;
1796 retval = setup_arg_pages(bprm, executable_stack);
1797 if (retval < 0) {
1798 send_sig(SIGKILL, current, 0);
1799@@ -706,10 +768,10 @@ static int load_elf_binary(struct linux_
1800
1801 current->mm->start_stack = bprm->p;
1802
1803+
1804 /* Now we do a little grungy work by mmaping the ELF image into
1805- the correct location in memory. At this point, we assume that
1806- the image should be loaded at fixed address, not at a variable
1807- address. */
1808+ the correct location in memory.
1809+ */
1810
1811 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
1812 int elf_prot = 0, elf_flags;
1813@@ -746,16 +808,16 @@ static int load_elf_binary(struct linux_
1814 elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
1815
1816 vaddr = elf_ppnt->p_vaddr;
1817- if (elf_ex.e_type == ET_EXEC || load_addr_set) {
1818+ if (elf_ex.e_type == ET_EXEC || load_addr_set)
1819 elf_flags |= MAP_FIXED;
1820- } else if (elf_ex.e_type == ET_DYN) {
1821- /* Try and get dynamic programs out of the way of the default mmap
1822- base, as well as whatever program they might try to exec. This
1823- is because the brk will follow the loader, and is not movable. */
1824+ else if (elf_ex.e_type == ET_DYN)
1825+#ifdef __i386__
1826+ load_bias = 0;
1827+#else
1828 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
1829- }
1830+#endif
1831
1832- error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
1833+ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags, 0);
1834 if (BAD_ADDR(error))
1835 continue;
1836
1837@@ -826,7 +888,8 @@ static int load_elf_binary(struct linux_
1838 else
1839 elf_entry = load_elf_interp(&interp_elf_ex,
1840 interpreter,
1841- &interp_load_addr);
1842+ &interp_load_addr,
1843+ load_bias);
1844 if (BAD_ADDR(elf_entry)) {
1845 printk(KERN_ERR "Unable to load interpreter\n");
1846 send_sig(SIGSEGV, current, 0);
1847@@ -849,6 +912,14 @@ static int load_elf_binary(struct linux_
1848
1849 set_binfmt(&elf_format);
1850
1851+ /*
1852+ * Map the vsyscall trampoline. This address is then passed via
1853+ * AT_SYSINFO.
1854+ */
1855+#ifdef __HAVE_ARCH_VSYSCALL
1856+ map_vsyscall();
1857+#endif
1858+
1859 compute_creds(bprm);
1860 current->flags &= ~PF_FORKNOEXEC;
1861 create_elf_tables(bprm, &elf_ex, (interpreter_type == INTERPRETER_AOUT),
1862@@ -862,6 +933,10 @@ static int load_elf_binary(struct linux_
1863 current->mm->end_data = end_data;
1864 current->mm->start_stack = bprm->p;
1865
1866+#ifdef __HAVE_ARCH_RANDOMIZE_BRK
1867+ if (!(current->mm->def_flags & VM_EXEC))
1868+ randomize_brk(elf_brk);
1869+#endif
1870 if (current->personality & MMAP_PAGE_ZERO) {
1871 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
1872 and some applications "depend" upon this behavior.
1873--- linux/fs/exec.c.orig
1874+++ linux/fs/exec.c
1875@@ -389,7 +389,12 @@ int setup_arg_pages(struct linux_binprm
1876 while (i < MAX_ARG_PAGES)
1877 bprm->page[i++] = NULL;
1878 #else
1879+#ifdef __HAVE_ARCH_ALIGN_STACK
1880+ stack_base = arch_align_stack(STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE);
1881+ stack_base = PAGE_ALIGN(stack_base);
1882+#else
1883 stack_base = STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE;
1884+#endif
1885 mm->arg_start = bprm->p + stack_base;
1886 arg_size = STACK_TOP - (PAGE_MASK & (unsigned long) mm->arg_start);
1887 #endif
1888@@ -430,6 +435,7 @@ int setup_arg_pages(struct linux_binprm
1889 mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
1890 else
1891 mpnt->vm_flags = VM_STACK_FLAGS;
1892+ mpnt->vm_flags |= mm->def_flags;
1893 mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
1894 insert_vm_struct(mm, mpnt);
1895 mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
1896@@ -886,8 +892,13 @@ int prepare_binprm(struct linux_binprm *
1897
1898 if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
1899 /* Set-uid? */
1900- if (mode & S_ISUID)
1901+ if (mode & S_ISUID) {
1902 bprm->e_uid = inode->i_uid;
1903+#ifdef __i386__
1904+ /* reset personality */
1905+ current->personality = PER_LINUX;
1906+#endif
1907+ }
1908
1909 /* Set-gid? */
1910 /*
1911@@ -895,8 +906,13 @@ int prepare_binprm(struct linux_binprm *
1912 * is a candidate for mandatory locking, not a setgid
1913 * executable.
1914 */
1915- if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
1916+ if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
1917 bprm->e_gid = inode->i_gid;
1918+#ifdef __i386__
1919+ /* reset personality */
1920+ current->personality = PER_LINUX;
1921+#endif
1922+ }
1923 }
1924
1925 /* fill in binprm security blob */
1926--- linux/kernel/fork.c.orig
1927+++ linux/kernel/fork.c
1928@@ -417,6 +417,9 @@ static struct mm_struct * mm_init(struct
1929
1930 if (likely(!mm_alloc_pgd(mm))) {
1931 mm->def_flags = 0;
1932+#ifdef __HAVE_ARCH_MMAP_TOP
1933+ mm->mmap_top = mmap_top();
1934+#endif
1935 return mm;
1936 }
1937 free_mm(mm);
1938--- linux/kernel/signal.c.orig
1939+++ linux/kernel/signal.c
1940@@ -1552,6 +1552,34 @@ do_notify_parent_cldstop(struct task_str
1941 spin_unlock_irqrestore(&sighand->siglock, flags);
1942 }
1943
1944+int print_fatal_signals = 0;
1945+
1946+static void print_fatal_signal(struct pt_regs *regs, int signr)
1947+{
1948+ int i;
1949+ unsigned char insn;
1950+ printk("%s/%d: potentially unexpected fatal signal %d.\n",
1951+ current->comm, current->pid, signr);
1952+
1953+#ifdef __i386__
1954+ printk("code at %08lx: ", regs->eip);
1955+ for (i = 0; i < 16; i++) {
1956+ __get_user(insn, (unsigned char *)(regs->eip + i));
1957+ printk("%02x ", insn);
1958+ }
1959+#endif
1960+ printk("\n");
1961+ show_regs(regs);
1962+}
1963+
1964+static int __init setup_print_fatal_signals(char *str)
1965+{
1966+ get_option (&str, &print_fatal_signals);
1967+
1968+ return 1;
1969+}
1970+
1971+__setup("print-fatal-signals=", setup_print_fatal_signals);
1972
1973 #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
1974
1975@@ -1743,6 +1771,11 @@ relock:
1976 if (!signr)
1977 break; /* will return 0 */
1978
1979+ if ((signr == SIGSEGV) && print_fatal_signals) {
1980+ spin_unlock_irq(&current->sighand->siglock);
1981+ print_fatal_signal(regs, signr);
1982+ spin_lock_irq(&current->sighand->siglock);
1983+ }
1984 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
1985 ptrace_signal_deliver(regs, cookie);
1986
1987@@ -1847,6 +1880,8 @@ relock:
1988 * Anything else is fatal, maybe with a core dump.
1989 */
1990 current->flags |= PF_SIGNALED;
1991+ if (print_fatal_signals)
1992+ print_fatal_signal(regs, signr);
1993 if (sig_kernel_coredump(signr) &&
1994 do_coredump((long)signr, signr, regs)) {
1995 /*
1996--- linux/kernel/sysctl.c.orig
1997+++ linux/kernel/sysctl.c
1998@@ -63,6 +63,29 @@ extern int min_free_kbytes;
1999 extern int printk_ratelimit_jiffies;
2000 extern int printk_ratelimit_burst;
2001
2002+extern unsigned int vdso_enabled;
2003+
2004+int exec_shield = 2;
2005+int exec_shield_randomize = 1;
2006+
2007+static int __init setup_exec_shield(char *str)
2008+{
2009+ get_option (&str, &exec_shield);
2010+
2011+ return 1;
2012+}
2013+
2014+__setup("exec-shield=", setup_exec_shield);
2015+
2016+static int __init setup_exec_shield_randomize(char *str)
2017+{
2018+ get_option (&str, &exec_shield_randomize);
2019+
2020+ return 1;
2021+}
2022+
2023+__setup("exec-shield-randomize=", setup_exec_shield_randomize);
2024+
2025 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
2026 static int maxolduid = 65535;
2027 static int minolduid;
2028@@ -266,6 +289,40 @@ static ctl_table kern_table[] = {
2029 .proc_handler = &proc_dointvec,
2030 },
2031 {
2032+ .ctl_name = KERN_PANIC,
2033+ .procname = "exec-shield",
2034+ .data = &exec_shield,
2035+ .maxlen = sizeof(int),
2036+ .mode = 0644,
2037+ .proc_handler = &proc_dointvec,
2038+ },
2039+ {
2040+ .ctl_name = KERN_PANIC,
2041+ .procname = "exec-shield-randomize",
2042+ .data = &exec_shield_randomize,
2043+ .maxlen = sizeof(int),
2044+ .mode = 0644,
2045+ .proc_handler = &proc_dointvec,
2046+ },
2047+ {
2048+ .ctl_name = KERN_PANIC,
2049+ .procname = "print-fatal-signals",
2050+ .data = &print_fatal_signals,
2051+ .maxlen = sizeof(int),
2052+ .mode = 0644,
2053+ .proc_handler = &proc_dointvec,
2054+ },
2055+#if __i386__
2056+ {
2057+ .ctl_name = KERN_PANIC,
2058+ .procname = "vdso",
2059+ .data = &vdso_enabled,
2060+ .maxlen = sizeof(int),
2061+ .mode = 0644,
2062+ .proc_handler = &proc_dointvec,
2063+ },
2064+#endif
2065+ {
2066 .ctl_name = KERN_CORE_USES_PID,
2067 .procname = "core_uses_pid",
2068 .data = &core_uses_pid,
2069--- linux/mm/fremap.c.orig
2070+++ linux/mm/fremap.c
2071@@ -61,12 +61,6 @@ int install_page(struct mm_struct *mm, s
2072 pmd_t *pmd;
2073 pte_t pte_val;
2074
2075- /*
2076- * We use page_add_file_rmap below: if install_page is
2077- * ever extended to anonymous pages, this will warn us.
2078- */
2079- BUG_ON(!page_mapping(page));
2080-
2081 pgd = pgd_offset(mm, addr);
2082 spin_lock(&mm->page_table_lock);
2083
2084--- linux/mm/mmap.c.orig
2085+++ linux/mm/mmap.c
2086@@ -244,6 +244,8 @@ static inline void
2087 __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
2088 struct vm_area_struct *prev, struct rb_node *rb_parent)
2089 {
2090+ if (vma->vm_flags & VM_EXEC)
2091+ arch_add_exec_range(mm, vma->vm_end);
2092 if (prev) {
2093 vma->vm_next = prev->vm_next;
2094 prev->vm_next = vma;
2095@@ -348,6 +350,8 @@ __vma_unlink(struct mm_struct *mm, struc
2096 rb_erase(&vma->vm_rb, &mm->mm_rb);
2097 if (mm->mmap_cache == vma)
2098 mm->mmap_cache = prev;
2099+ if (vma->vm_flags & VM_EXEC)
2100+ arch_remove_exec_range(mm, vma->vm_end);
2101 }
2102
2103 /*
2104@@ -646,6 +650,8 @@ struct vm_area_struct *vma_merge(struct
2105 } else /* cases 2, 5, 7 */
2106 vma_adjust(prev, prev->vm_start,
2107 end, prev->vm_pgoff, NULL);
2108+ if (prev->vm_flags & VM_EXEC)
2109+ arch_add_exec_range(mm, prev->vm_end);
2110 return prev;
2111 }
2112
2113@@ -782,7 +788,7 @@ unsigned long do_mmap_pgoff(struct file
2114 /* Obtain the address to map to. we verify (or select) it and ensure
2115 * that it represents a valid section of the address space.
2116 */
2117- addr = get_unmapped_area(file, addr, len, pgoff, flags);
2118+ addr = get_unmapped_area(file, addr, len, pgoff, flags, prot & PROT_EXEC);
2119 if (addr & ~PAGE_MASK)
2120 return addr;
2121
2122@@ -1016,7 +1022,7 @@ EXPORT_SYMBOL(do_mmap_pgoff);
2123 #ifndef HAVE_ARCH_UNMAPPED_AREA
2124 static inline unsigned long
2125 arch_get_unmapped_area(struct file *filp, unsigned long addr,
2126- unsigned long len, unsigned long pgoff, unsigned long flags)
2127+ unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)
2128 {
2129 struct mm_struct *mm = current->mm;
2130 struct vm_area_struct *vma;
2131@@ -1061,12 +1067,12 @@ full_search:
2132 #else
2133 extern unsigned long
2134 arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
2135- unsigned long, unsigned long);
2136+ unsigned long, unsigned long, unsigned long);
2137 #endif
2138
2139 unsigned long
2140 get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
2141- unsigned long pgoff, unsigned long flags)
2142+ unsigned long pgoff, unsigned long flags, unsigned long exec)
2143 {
2144 if (flags & MAP_FIXED) {
2145 unsigned long ret;
2146@@ -1098,7 +1104,7 @@ get_unmapped_area(struct file *file, uns
2147 return file->f_op->get_unmapped_area(file, addr, len,
2148 pgoff, flags);
2149
2150- return arch_get_unmapped_area(file, addr, len, pgoff, flags);
2151+ return arch_get_unmapped_area(file, addr, len, pgoff, flags, exec);
2152 }
2153
2154 EXPORT_SYMBOL(get_unmapped_area);
2155@@ -1176,6 +1182,14 @@ out:
2156 return prev ? prev->vm_next : vma;
2157 }
2158
2159+
2160+static int over_stack_limit(unsigned long sz)
2161+{
2162+ if (sz < EXEC_STACK_BIAS)
2163+ return 0;
2164+ return (sz - EXEC_STACK_BIAS) > current->rlim[RLIMIT_STACK].rlim_cur;
2165+}
2166+
2167 #ifdef CONFIG_STACK_GROWSUP
2168 /*
2169 * vma is the first one with address > vma->vm_end. Have to extend vma.
2170@@ -1210,7 +1224,7 @@ int expand_stack(struct vm_area_struct *
2171 return -ENOMEM;
2172 }
2173
2174- if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur ||
2175+ if (over_stack_limit(address - vma->vm_start) ||
2176 ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
2177 current->rlim[RLIMIT_AS].rlim_cur) {
2178 anon_vma_unlock(vma);
2179@@ -1271,7 +1285,7 @@ int expand_stack(struct vm_area_struct *
2180 return -ENOMEM;
2181 }
2182
2183- if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
2184+ if (over_stack_limit(vma->vm_end - address) ||
2185 ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
2186 current->rlim[RLIMIT_AS].rlim_cur) {
2187 anon_vma_unlock(vma);
2188@@ -1384,6 +1398,7 @@ no_mmaps:
2189 static void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area)
2190 {
2191 size_t len = area->vm_end - area->vm_start;
2192+ unsigned long old_end = area->vm_end;
2193
2194 area->vm_mm->total_vm -= len >> PAGE_SHIFT;
2195 if (area->vm_flags & VM_LOCKED)
2196@@ -1394,8 +1409,14 @@ static void unmap_vma(struct mm_struct *
2197 if (area->vm_start >= TASK_UNMAPPED_BASE &&
2198 area->vm_start < area->vm_mm->free_area_cache)
2199 area->vm_mm->free_area_cache = area->vm_start;
2200-
2201+ /*
2202+ * Is this a new hole at the highest possible address?
2203+ */
2204+ if (area->vm_start > area->vm_mm->non_executable_cache)
2205+ area->vm_mm->non_executable_cache = area->vm_start;
2206 remove_vm_struct(area);
2207+ if (unlikely(area->vm_flags & VM_EXEC))
2208+ arch_remove_exec_range(mm, old_end);
2209 }
2210
2211 /*
2212@@ -1505,10 +1526,14 @@ int split_vma(struct mm_struct * mm, str
2213 if (new->vm_ops && new->vm_ops->open)
2214 new->vm_ops->open(new);
2215
2216- if (new_below)
2217+ if (new_below) {
2218+ unsigned long old_end = vma->vm_end;
2219+
2220 vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
2221 ((addr - new->vm_start) >> PAGE_SHIFT), new);
2222- else
2223+ if (vma->vm_flags & VM_EXEC)
2224+ arch_remove_exec_range(mm, old_end);
2225+ } else
2226 vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
2227
2228 return 0;
2229@@ -1716,6 +1741,7 @@ void exit_mmap(struct mm_struct *mm)
2230 mm->rss = 0;
2231 mm->total_vm = 0;
2232 mm->locked_vm = 0;
2233+ arch_flush_exec_range(mm);
2234
2235 spin_unlock(&mm->page_table_lock);
2236
2237--- linux/mm/mprotect.c.orig
2238+++ linux/mm/mprotect.c
2239@@ -20,6 +20,7 @@
2240
2241 #include <asm/uaccess.h>
2242 #include <asm/pgtable.h>
2243+#include <asm/pgalloc.h>
2244 #include <asm/cacheflush.h>
2245 #include <asm/tlbflush.h>
2246
2247@@ -112,8 +113,9 @@ mprotect_fixup(struct vm_area_struct *vm
2248 unsigned long start, unsigned long end, unsigned int newflags)
2249 {
2250 struct mm_struct * mm = vma->vm_mm;
2251- unsigned long charged = 0;
2252+ unsigned long charged = 0, old_end = vma->vm_end;
2253 pgprot_t newprot;
2254+ unsigned int oldflags;
2255 pgoff_t pgoff;
2256 int error;
2257
2258@@ -174,8 +176,11 @@ success:
2259 * vm_flags and vm_page_prot are protected by the mmap_sem
2260 * held in write mode.
2261 */
2262+ oldflags = vma->vm_flags;
2263 vma->vm_flags = newflags;
2264 vma->vm_page_prot = newprot;
2265+ if (oldflags & VM_EXEC)
2266+ arch_remove_exec_range(current->mm, old_end);
2267 change_protection(vma, start, end, newprot);
2268 return 0;
2269
2270--- linux/mm/mremap.c.orig
2271+++ linux/mm/mremap.c
2272@@ -380,7 +380,8 @@ unsigned long do_mremap(unsigned long ad
2273 map_flags |= MAP_SHARED;
2274
2275 new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
2276- vma->vm_pgoff, map_flags);
2277+ vma->vm_pgoff, map_flags,
2278+ vma->vm_flags & VM_EXEC);
2279 ret = new_addr;
2280 if (new_addr & ~PAGE_MASK)
2281 goto out;
2282--- linux/mm/vmalloc.c.orig
2283+++ linux/mm/vmalloc.c
2284@@ -455,6 +455,28 @@ void *vmalloc(unsigned long size)
2285 EXPORT_SYMBOL(vmalloc);
2286
2287 /**
2288+ * vmalloc_exec - allocate virtually contiguous, executable memory
2289+ *
2290+ * @size: allocation size
2291+ *
2292+ * Kernel-internal function to allocate enough pages to cover @size
2293+ * the page level allocator and map them into contiguous and
2294+ * executable kernel virtual space.
2295+ *
2296+ * For tight cotrol over page level allocator and protection flags
2297+ * use __vmalloc() instead.
2298+ */
2299+
2300+#ifndef PAGE_KERNEL_EXEC
2301+# define PAGE_KERNEL_EXEC PAGE_KERNEL
2302+#endif
2303+
2304+void *vmalloc_exec(unsigned long size)
2305+{
2306+ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
2307+}
2308+
2309+/**
2310 * vmalloc_32 - allocate virtually contiguous memory (32bit addressable)
2311 *
2312 * @size: allocation size
This page took 0.333957 seconds and 4 git commands to generate.