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;
7 - return get_unmapped_area(NULL, hint, len, pgoff, flags);
8 + return get_unmapped_area(NULL, hint, len, pgoff, flags, 0);
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);
15 - addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
16 + addr = get_unmapped_area(NULL, hint, len, pgoff, flags, 0);
18 } else if (map->type == _DRM_SHM && SHMLBA > PAGE_SIZE) {
19 unsigned long slack = SHMLBA - PAGE_SIZE;
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;
26 @@ -313,7 +313,7 @@ static unsigned long ffb_get_unmapped_ar
30 - addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
31 + addr = get_unmapped_area(NULL, hint, len, pgoff, flags, 0);
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
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);
46 @@ -140,7 +140,7 @@ unsigned long get_fb_unmapped_area(struc
47 align_goal = (64UL * 1024);
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);
55 @@ -158,7 +158,7 @@ unsigned long get_fb_unmapped_area(struc
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);
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,
69 + map_flags, vma->vm_flags & VM_EXEC);
71 if (new_addr & ~PAGE_MASK)
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,
80 + map_flags, vma->vm_flags & VM_EXEC);
82 if (new_addr & ~PAGE_MASK)
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
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",
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);
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:
111 - pushl $SYSENTER_RETURN
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:
118 + pushl (TI_sysenter_return-THREAD_SIZE+4*4)(%esp)
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)
128 + btl $5, %eax # check if PAE is enabled
131 + /* Check if extended functions are implemented */
132 + movl $0x80000000, %eax
134 + cmpl $0x80000000, %eax
136 + mov $0x80000001, %eax
138 + /* Execute Disable bit supported? */
142 + /* Setup EFER (Extended Feature Enable Register) */
143 + movl $0xc0000080, %ecx
147 + /* Make changes effective */
151 + /* cpuid clobbered ebx, set it up again: */
155 #endif /* CONFIG_SMP */
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)
163 - return vmalloc(size);
164 + return vmalloc_exec(size);
168 --- linux/arch/i386/kernel/process.c.orig
169 +++ linux/arch/i386/kernel/process.c
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>
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 */
182 __unlazy_fpu(prev_p);
184 + load_user_cs_desc(cpu, next_p->mm);
187 * Reload esp0, LDT and the page table pointer:
188 @@ -776,3 +780,303 @@ asmlinkage int sys_get_thread_area(struc
193 + * Get a random word:
195 +static inline unsigned int get_random_int(void)
197 + unsigned int val = 0;
199 + if (!exec_shield_randomize)
202 +#ifdef CONFIG_X86_HAS_TSC
205 + val += current->pid + jiffies + (int)&val;
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
214 + return secure_ip_id(val);
217 +unsigned long arch_align_stack(unsigned long sp)
219 + if (current->mm && !(current->mm->def_flags & VM_EXEC))
220 + sp -= ((get_random_int() % 65536) << 4);
224 +#if SHLIB_BASE >= 0x01000000
225 +# error SHLIB_BASE must be under 16MB!
228 +static unsigned long
229 +arch_get_unmapped_nonexecutable_area(struct mm_struct *mm, unsigned long addr, unsigned long len)
231 + struct vm_area_struct *vma, *prev_vma;
232 + unsigned long stack_limit;
233 + int first_time = 1;
235 + if (!mm->mmap_top) {
236 + printk("hm, %s:%d, !mmap_top.\n", current->comm, current->pid);
237 + mm->mmap_top = mmap_top();
239 + stack_limit = mm->mmap_top;
241 + /* requested length too big for entire address space */
242 + if (len > TASK_SIZE)
245 + /* dont allow allocations above current stack limit */
246 + if (mm->non_executable_cache > stack_limit)
247 + mm->non_executable_cache = stack_limit;
249 + /* requesting a specific address */
251 + addr = PAGE_ALIGN(addr);
252 + vma = find_vma(mm, addr);
253 + if (TASK_SIZE - len >= addr &&
254 + (!vma || addr + len <= vma->vm_start))
258 + /* make sure it can fit in the remaining address space */
259 + if (mm->non_executable_cache < len)
262 + /* either no address requested or cant fit in requested address hole */
264 + addr = (mm->non_executable_cache - len)&PAGE_MASK;
266 + if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
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;
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;
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 */
285 + mm->non_executable_cache = stack_limit;
291 +static unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len)
293 + unsigned long range = end - len - start;
294 + if (end <= start + len)
296 + return PAGE_ALIGN(get_random_int() % range + start);
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)
303 + struct mm_struct *mm = current->mm;
304 + struct vm_area_struct *vma;
305 + unsigned long start_addr;
307 + if (len > TASK_SIZE)
311 + addr = PAGE_ALIGN(addr);
312 + vma = find_vma(mm, addr);
313 + if (TASK_SIZE - len >= addr &&
314 + (!vma || addr + len <= vma->vm_start))
317 + start_addr = addr = mm->free_area_cache;
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) {
324 + * Start a new search - just in case we missed
327 + if (start_addr != TASK_UNMAPPED_BASE) {
328 + start_addr = addr = TASK_UNMAPPED_BASE;
333 + if (!vma || addr + len <= vma->vm_start) {
335 + * Remember the place where we stopped the search:
337 + mm->free_area_cache = addr + len;
340 + addr = vma->vm_end;
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)
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;
355 + * Fall back to the old layout:
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)
362 + if (!addr && (prot & PROT_EXEC) && !(flags & MAP_FIXED))
363 + addr = randomize_range(SHLIB_BASE, 0x01000000, len);
366 + addr = PAGE_ALIGN(addr);
367 + vma = find_vma(mm, addr);
368 + if (TASK_SIZE - len >= addr &&
369 + (!vma || addr + len <= vma->vm_start)) {
374 + if (prot & PROT_EXEC) {
378 + /* this can fail if the stack was unlimited */
379 + if ((tmp = arch_get_unmapped_nonexecutable_area(mm, addr, len)) != -ENOMEM)
382 + addr = PAGE_ALIGN(arch_align_stack(TASK_UNMAPPED_BASE));
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) {
390 + if (!vma || addr + len <= vma->vm_start) {
392 + * Must not let a PROT_EXEC mapping get into the
395 + if (ascii_shield && (addr + len > mm->brk)) {
400 + * Up until the brk area we randomize addresses
401 + * as much as possible:
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))
411 + * Ok, randomization didnt work out - return
412 + * the result of the linear search:
416 + addr = vma->vm_end;
420 +void arch_add_exec_range(struct mm_struct *mm, unsigned long limit)
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);
430 +void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end)
432 + struct vm_area_struct *vma;
433 + unsigned long limit = 0;
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;
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);
447 +void arch_flush_exec_range(struct mm_struct *mm)
449 + mm->context.exec_limit = 0;
450 + set_user_cs(&mm->context.user_cs, 0);
454 + * Generate random brk address between 128MB and 196MB. (if the layout
457 +void randomize_brk(unsigned long old_brk)
459 + unsigned long new_brk, range_start, range_end;
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);
467 + current->mm->brk = new_brk;
471 + * Top of mmap area (just below the process stack).
472 + * leave an at least ~128 MB hole. Randomize it.
474 +#define MIN_GAP (128*1024*1024)
475 +#define MAX_GAP (TASK_SIZE/6*5)
477 +unsigned long mmap_top(void)
479 + unsigned long gap = 0;
481 + gap = current->rlim[RLIMIT_STACK].rlim_cur;
484 + else if (gap > MAX_GAP)
487 + gap = arch_align_stack(gap) & PAGE_MASK;
489 + return TASK_SIZE - gap;
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
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;
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
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;
512 @@ -450,9 +450,10 @@ static void setup_rt_frame(int sig, stru
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;
521 err |= __put_user(restorer, &frame->pretcode);
524 --- linux/arch/i386/kernel/sysenter.c.orig
525 +++ linux/arch/i386/kernel/sysenter.c
527 #include <linux/gfp.h>
528 #include <linux/string.h>
529 #include <linux/elf.h>
530 +#include <linux/mman.h>
532 #include <asm/cpufeature.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;
538 +struct page *sysenter_page;
540 static int __init sysenter_setup(void)
542 unsigned long page = get_zeroed_page(GFP_ATOMIC);
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);
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);
553 on_each_cpu(enable_sep_cpu, NULL, 1, 1);
558 __initcall(sysenter_setup);
560 +extern void SYSENTER_RETURN_OFFSET;
562 +unsigned int vdso_enabled = 1;
564 +void map_vsyscall(void)
566 + struct thread_info *ti = current_thread_info();
567 + struct vm_area_struct *vma;
568 + unsigned long addr;
570 + if (unlikely(!vdso_enabled)) {
571 + current->mm->context.vdso = NULL;
576 + * Map the vDSO (it will be randomized):
578 + down_write(¤t->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;
583 + vma = find_vma(current->mm, addr);
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);
592 + up_write(¤t->mm->mmap_sem);
595 +static int __init vdso_setup(char *str)
597 + vdso_enabled = simple_strtoul(str, NULL, 0);
600 +__setup("vdso=", vdso_setup);
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())
609 + * the original non-exec stack patch was written by
610 + * Solar Designer <solar at openwall.com>. Thanks!
612 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
614 if (regs->eflags & X86_EFLAGS_IF)
615 @@ -439,6 +443,46 @@ asmlinkage void do_general_protection(st
616 if (!(regs->xcs & 3))
620 + * lazy-check for CS validity on exec-shield binaries:
623 + int cpu = smp_processor_id();
624 + struct desc_struct *desc1, *desc2;
625 + struct vm_area_struct *vma;
626 + unsigned long limit = 0;
628 + spin_lock(¤t->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(¤t->mm->page_table_lock);
634 + current->mm->context.exec_limit = limit;
635 + set_user_cs(¤t->mm->context.user_cs, limit);
637 + desc1 = ¤t->mm->context.user_cs;
638 + desc2 = cpu_gdt_table[cpu] + GDT_ENTRY_DEFAULT_USER_CS;
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.
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);
650 + load_user_cs_desc(cpu, current->mm);
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);
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 */
668 - /* 14: System call restart point is here! (SYSENTER_RETURN - 2) */
669 + /* 14: System call restart point is here! (SYSENTER_RETURN_OFFSET-2) */
671 /* 16: System call normal return point is here! */
672 - .globl SYSENTER_RETURN /* Symbol used by entry.S. */
674 + .globl SYSENTER_RETURN_OFFSET /* Symbol used by sysenter.c */
675 +SYSENTER_RETURN_OFFSET:
679 --- linux/arch/i386/kernel/vsyscall.lds.orig
680 +++ linux/arch/i386/kernel/vsyscall.lds
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.
690 -/* This must match <asm/fixmap.h>. */
691 -VSYSCALL_BASE = 0xffffe000;
695 - . = VSYSCALL_BASE + SIZEOF_HEADERS;
696 + . = SIZEOF_HEADERS;
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;
707 .text : { *(.text) } :text =0x90909090
709 --- linux/arch/i386/mm/fault.c.orig
710 +++ linux/arch/i386/mm/fault.c
711 @@ -405,6 +405,21 @@ no_context:
715 +#ifdef CONFIG_X86_PAE
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);
730 if (address < PAGE_SIZE)
731 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
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
739 +static inline int is_kernel_text(unsigned long addr)
741 + if (addr >= (unsigned long)_stext && addr <= (unsigned long)__init_end)
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)
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;
755 /* Map with big pages if possible, otherwise create normal page tables. */
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;
760 + if (is_kernel_text(address) || is_kernel_text(address2))
761 + set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
763 + set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
766 pte = one_page_table_init(pmd);
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));
774 + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
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 */
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;
791 #ifndef CONFIG_DISCONTIGMEM
792 #define remap_numa_kva() do {} while (0)
793 @@ -301,6 +320,7 @@ static void __init pagetable_init (void)
795 set_in_cr4(X86_CR4_PGE);
796 __PAGE_KERNEL |= _PAGE_GLOBAL;
797 + __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL;
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 */
805 +static int disable_nx __initdata = 0;
806 +u64 __supported_pte_mask = ~_PAGE_NX;
812 + * Control non executable mappings.
815 + * off Disable (disables exec-shield too)
817 +static int __init noexec_setup(char *str)
819 + if (!strncmp(str, "on",2) && cpu_has_nx) {
820 + __supported_pte_mask |= _PAGE_NX;
822 + } else if (!strncmp(str,"off",3)) {
824 + __supported_pte_mask &= ~_PAGE_NX;
830 +__setup("noexec=", noexec_setup);
832 +#ifdef CONFIG_X86_PAE
834 +static void __init set_nx(void)
836 + unsigned int v[4], l, h;
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);
843 + wrmsr(MSR_EFER, l, h);
845 + __supported_pte_mask |= _PAGE_NX;
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);
857 void __init paging_init(void)
859 +#ifdef CONFIG_X86_PAE
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");
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
874 new_addr = get_unmapped_area(file, addr, new_len,
875 vma ? vma->vm_pgoff : 0,
877 + map_flags, vma->vm_flags & VM_EXEC);
879 if (new_addr & ~PAGE_MASK)
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)
887 - return get_unmapped_area(file, addr, len, pgoff, flags);
888 + return get_unmapped_area(file, addr, len, pgoff, flags, 0);
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)
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)
901 unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
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)
909 - if (map_vm_area(area, PAGE_KERNEL_EXECUTABLE, &pages))
910 + if (map_vm_area(area, PAGE_KERNEL_EXEC, &pages))
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,
918 addr2 = __START_KERNEL_map + page_to_phys(page);
919 err = __change_page_attr(addr2, page, prot,
920 - PAGE_KERNEL_EXECUTABLE);
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
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)
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
939 #include <linux/threads.h>
940 #include <linux/mm.h>
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)
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)
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 *);
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);
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 {
985 * Limit the stack by to some sane default: root can always
986 * increase this limit if needed.. 8MB seems reasonable.
988 + * (2MB more to cover randomization effects.)
990 -#define _STK_LIM (8*1024*1024)
991 +#define _STK_LIM (10*1024*1024)
992 +#define EXEC_STACK_BIAS (2*1024*1024)
995 * Due to binary compatibility, the actual resource numbers
996 --- linux/include/linux/sched.h.orig
997 +++ linux/include/linux/sched.h
999 #include <linux/percpu.h>
1002 +extern int exec_shield;
1003 +extern int exec_shield_randomize;
1004 +extern int print_fatal_signals;
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 */
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
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
1031 extern kmem_cache_t *zero_cache;
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)
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
1044 #include <asm/mmu_context.h>
1045 #include <asm/processor.h>
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)
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);
1058 #define check_pgt_cache() do { } while (0)
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)
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)
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)
1077 #endif /* _SPARC_PGALLOC_H */
1078 --- linux/include/asm-s390/pgalloc.h.orig
1079 +++ linux/include/asm-s390/pgalloc.h
1081 #include <linux/gfp.h>
1082 #include <linux/mm.h>
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)
1088 #define check_pgt_cache() do {} while (0)
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
1097 +static inline void set_user_cs(struct desc_struct *desc, unsigned long limit)
1099 + limit = (limit - 1) / PAGE_SIZE;
1100 + desc->a = limit & 0xffff;
1101 + desc->b = (limit & 0xf0000) | 0x00c0fb00;
1104 +#define load_user_cs_desc(cpu, mm) \
1105 + cpu_gdt_table[(cpu)][GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs
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);
1111 #endif /* !__ASSEMBLY__ */
1114 --- linux/include/asm-i386/cpufeature.h.orig
1115 +++ linux/include/asm-i386/cpufeature.h
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 */
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
1135 #include <asm/user.h>
1136 #include <asm/processor.h>
1137 #include <asm/system.h> /* for savesegment */
1138 +#include <asm/desc.h>
1140 #include <linux/utsname.h>
1142 @@ -117,7 +118,8 @@ typedef struct user_fxsr_struct elf_fpxr
1143 #define AT_SYSINFO_EHDR 33
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)
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)
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)
1165 -#define ARCH_DLINFO \
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)
1173 +#define ARCH_DLINFO \
1175 + if (VSYSCALL_BASE) { \
1176 + NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \
1177 + NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \
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.
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 \
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); \
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) { \
1202 @@ -172,10 +181,10 @@ do { \
1203 #define ELF_CORE_WRITE_EXTRA_DATA \
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); \
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 { \
1220 +#define __HAVE_ARCH_RANDOMIZE_BRK
1221 +extern void randomize_brk(unsigned long old_brk);
1223 +#define __HAVE_ARCH_VSYSCALL
1224 +extern void map_vsyscall(void);
1227 --- linux/include/asm-i386/mmu.h.orig
1228 +++ linux/include/asm-i386/mmu.h
1230 * we put the segment information here.
1232 * cpu_vm_mask is used to optimize ldt flushing.
1234 + * exec_limit is used to track the range PROT_EXEC
1239 struct semaphore sem;
1241 + struct desc_struct user_cs;
1242 + unsigned long exec_limit;
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
1253 +/* extended feature register */
1254 +#define MSR_EFER 0xc0000080
1258 +/* Execute Disable enable */
1259 +#define _EFER_NX 11
1260 +#define EFER_NX (1<<_EFER_NX)
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
1268 * These are used to make use of C type-checking..
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
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)
1290 -typedef struct { unsigned long pgprot; } pgprot_t;
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
1296 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
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)
1302 #endif /* __KERNEL__ */
1303 --- linux/include/asm-i386/pgalloc.h.orig
1304 +++ linux/include/asm-i386/pgalloc.h
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 */
1313 @@ -52,4 +53,6 @@ static inline void pte_free(struct page
1315 #define check_pgt_cache() do { } while (0)
1317 +#define HAVE_ARCH_UNMAPPED_AREA 1
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));
1326 +extern unsigned long long __supported_pte_mask;
1328 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
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;
1342 static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
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);
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
1358 #define _PAGE_PRESENT 0x001
1359 #define _PAGE_RW 0x002
1360 @@ -126,28 +127,51 @@ void paging_init(void);
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)
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)
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)
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 \
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)
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)
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)
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)
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
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
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
1450 pte.pte_low &= _PAGE_CHG_MASK;
1451 pte.pte_low |= pgprot_val(newprot);
1452 +#ifdef CONFIG_X86_PAE
1454 + * Chop off the NX bit (if present), and add the NX portion of
1455 + * the newprot (if present):
1457 + pte.pte_high &= -1 ^ (1 << (_PAGE_BIT_NX - 32));
1458 + pte.pte_high |= (pgprot_val(newprot) >> 32) & \
1459 + (__supported_pte_mask >> 32);
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.
1470 -#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
1471 +#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE/3)
1473 +#define SHLIB_BASE 0x00111000
1475 +#define __HAVE_ARCH_ALIGN_STACK
1476 +extern unsigned long arch_align_stack(unsigned long sp);
1478 +#define __HAVE_ARCH_MMAP_TOP
1479 +extern unsigned long mmap_top(void);
1482 * Size of io_bitmap, covering ports 0 to 0x3ff.
1483 @@ -456,6 +464,8 @@ static inline void load_esp0(struct tss_
1489 #define start_thread(regs, new_eip, new_esp) do { \
1490 __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \
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); \
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
1506 + void *sysenter_return;
1507 struct restart_block restart_block;
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()
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)
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);
1527 - wchan = get_wchan(task);
1529 + if (current->uid == task->uid || current->euid == task->uid ||
1530 + capable(CAP_SYS_NICE))
1531 + wchan = get_wchan(task);
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"
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"
1567 + "ExecLim:\t%08lx\n"
1570 mm->total_vm << (PAGE_SHIFT-10),
1571 mm->locked_vm << (PAGE_SHIFT-10),
1572 mm->rss << (PAGE_SHIFT-10),
1573 data - stack, stack,
1575 + exec - lib, lib, mm->start_brk, mm->brk, mm->start_stack
1577 + , mm->context.exec_limit
1580 up_read(&mm->mmap_sem);
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;
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
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 *);
1606 @@ -155,20 +155,8 @@ create_elf_tables(struct linux_binprm *b
1608 size_t len = strlen(k_platform) + 1;
1610 -#ifdef CONFIG_X86_HT
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.
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
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);
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
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)
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);
1641 + addr = ELF_PAGESTART(addr);
1642 + size = ELF_PAGEALIGN(size);
1644 down_write(¤t->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));
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.)
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);
1663 + map_addr = do_mmap(filep, addr, size, prot, type, off);
1665 up_write(¤t->mm->mmap_sem);
1671 #endif /* !elf_map */
1673 +static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr)
1675 + int i, first_idx = -1, last_idx = -1;
1677 + for (i = 0; i < nr; i++)
1678 + if (cmds[i].p_type == PT_LOAD) {
1680 + if (first_idx == -1)
1684 + if (first_idx == -1)
1687 + return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz -
1688 + ELF_PAGESTART(cmds[first_idx].p_vaddr);
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
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)
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;
1711 /* First of all, some simple consistency checks */
1712 @@ -335,6 +364,10 @@ static unsigned long load_elf_interp(str
1716 + total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
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;
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);
1734 if (BAD_ADDR(map_addr))
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;
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;
1747 executable_stack = EXSTACK_DISABLE_X;
1750 + if (i == elf_ex.e_phnum)
1751 + def_flags |= VM_EXEC | VM_MAYEXEC;
1753 + if (current->personality == PER_LINUX)
1754 + switch (exec_shield) {
1756 + executable_stack = EXSTACK_DISABLE_X;
1757 + def_flags &= ~(VM_EXEC | VM_MAYEXEC);
1761 /* Some simple consistency checks for the interpreter */
1762 if (elf_interpreter) {
1763 @@ -676,6 +724,15 @@ static int load_elf_binary(struct linux_
1765 goto out_free_dentry;
1769 + * Turn off the CS limit completely if exec-shield disabled or
1772 + if (!exec_shield || use_nx)
1773 + arch_add_exec_range(current->mm, -1);
1776 /* Discard our unneeded old files struct */
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();
1786 current->flags &= ~PF_FORKNOEXEC;
1787 + current->mm->def_flags = def_flags;
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);
1798 send_sig(SIGKILL, current, 0);
1799 @@ -706,10 +768,10 @@ static int load_elf_binary(struct linux_
1801 current->mm->start_stack = bprm->p;
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
1808 + the correct location in memory.
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;
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)
1828 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
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))
1837 @@ -826,7 +888,8 @@ static int load_elf_binary(struct linux_
1839 elf_entry = load_elf_interp(&interp_elf_ex,
1841 - &interp_load_addr);
1842 + &interp_load_addr,
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_
1849 set_binfmt(&elf_format);
1852 + * Map the vsyscall trampoline. This address is then passed via
1855 +#ifdef __HAVE_ARCH_VSYSCALL
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;
1866 +#ifdef __HAVE_ARCH_RANDOMIZE_BRK
1867 + if (!(current->mm->def_flags & VM_EXEC))
1868 + randomize_brk(elf_brk);
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
1875 @@ -389,7 +389,12 @@ int setup_arg_pages(struct linux_binprm
1876 while (i < MAX_ARG_PAGES)
1877 bprm->page[i++] = NULL;
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);
1883 stack_base = STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE;
1885 mm->arg_start = bprm->p + stack_base;
1886 arg_size = STACK_TOP - (PAGE_MASK & (unsigned long) mm->arg_start);
1888 @@ -430,6 +435,7 @@ int setup_arg_pages(struct linux_binprm
1889 mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
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 *
1898 if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
1900 - if (mode & S_ISUID)
1901 + if (mode & S_ISUID) {
1902 bprm->e_uid = inode->i_uid;
1904 + /* reset personality */
1905 + current->personality = PER_LINUX;
1911 @@ -895,8 +906,13 @@ int prepare_binprm(struct linux_binprm *
1912 * is a candidate for mandatory locking, not a setgid
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;
1919 + /* reset personality */
1920 + current->personality = PER_LINUX;
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
1930 if (likely(!mm_alloc_pgd(mm))) {
1932 +#ifdef __HAVE_ARCH_MMAP_TOP
1933 + mm->mmap_top = mmap_top();
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);
1944 +int print_fatal_signals = 0;
1946 +static void print_fatal_signal(struct pt_regs *regs, int signr)
1949 + unsigned char insn;
1950 + printk("%s/%d: potentially unexpected fatal signal %d.\n",
1951 + current->comm, current->pid, signr);
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);
1964 +static int __init setup_print_fatal_signals(char *str)
1966 + get_option (&str, &print_fatal_signals);
1971 +__setup("print-fatal-signals=", setup_print_fatal_signals);
1973 #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
1975 @@ -1743,6 +1771,11 @@ relock:
1977 break; /* will return 0 */
1979 + if ((signr == SIGSEGV) && print_fatal_signals) {
1980 + spin_unlock_irq(¤t->sighand->siglock);
1981 + print_fatal_signal(regs, signr);
1982 + spin_lock_irq(¤t->sighand->siglock);
1984 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
1985 ptrace_signal_deliver(regs, cookie);
1987 @@ -1847,6 +1880,8 @@ relock:
1988 * Anything else is fatal, maybe with a core dump.
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)) {
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;
2002 +extern unsigned int vdso_enabled;
2004 +int exec_shield = 2;
2005 +int exec_shield_randomize = 1;
2007 +static int __init setup_exec_shield(char *str)
2009 + get_option (&str, &exec_shield);
2014 +__setup("exec-shield=", setup_exec_shield);
2016 +static int __init setup_exec_shield_randomize(char *str)
2018 + get_option (&str, &exec_shield_randomize);
2023 +__setup("exec-shield-randomize=", setup_exec_shield_randomize);
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,
2032 + .ctl_name = KERN_PANIC,
2033 + .procname = "exec-shield",
2034 + .data = &exec_shield,
2035 + .maxlen = sizeof(int),
2037 + .proc_handler = &proc_dointvec,
2040 + .ctl_name = KERN_PANIC,
2041 + .procname = "exec-shield-randomize",
2042 + .data = &exec_shield_randomize,
2043 + .maxlen = sizeof(int),
2045 + .proc_handler = &proc_dointvec,
2048 + .ctl_name = KERN_PANIC,
2049 + .procname = "print-fatal-signals",
2050 + .data = &print_fatal_signals,
2051 + .maxlen = sizeof(int),
2053 + .proc_handler = &proc_dointvec,
2057 + .ctl_name = KERN_PANIC,
2058 + .procname = "vdso",
2059 + .data = &vdso_enabled,
2060 + .maxlen = sizeof(int),
2062 + .proc_handler = &proc_dointvec,
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
2076 - * We use page_add_file_rmap below: if install_page is
2077 - * ever extended to anonymous pages, this will warn us.
2079 - BUG_ON(!page_mapping(page));
2081 pgd = pgd_offset(mm, addr);
2082 spin_lock(&mm->page_table_lock);
2084 --- linux/mm/mmap.c.orig
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)
2090 + if (vma->vm_flags & VM_EXEC)
2091 + arch_add_exec_range(mm, vma->vm_end);
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);
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);
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.
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)
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)
2129 struct mm_struct *mm = current->mm;
2130 struct vm_area_struct *vma;
2131 @@ -1061,12 +1067,12 @@ full_search:
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);
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)
2144 if (flags & MAP_FIXED) {
2146 @@ -1098,7 +1104,7 @@ get_unmapped_area(struct file *file, uns
2147 return file->f_op->get_unmapped_area(file, addr, len,
2150 - return arch_get_unmapped_area(file, addr, len, pgoff, flags);
2151 + return arch_get_unmapped_area(file, addr, len, pgoff, flags, exec);
2154 EXPORT_SYMBOL(get_unmapped_area);
2155 @@ -1176,6 +1182,14 @@ out:
2156 return prev ? prev->vm_next : vma;
2160 +static int over_stack_limit(unsigned long sz)
2162 + if (sz < EXEC_STACK_BIAS)
2164 + return (sz - EXEC_STACK_BIAS) > current->rlim[RLIMIT_STACK].rlim_cur;
2167 #ifdef CONFIG_STACK_GROWSUP
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 *
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 *
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)
2191 size_t len = area->vm_end - area->vm_start;
2192 + unsigned long old_end = area->vm_end;
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;
2202 + * Is this a new hole at the highest possible address?
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);
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);
2218 + unsigned long old_end = vma->vm_end;
2220 vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
2221 ((addr - new->vm_start) >> PAGE_SHIFT), new);
2223 + if (vma->vm_flags & VM_EXEC)
2224 + arch_remove_exec_range(mm, old_end);
2226 vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
2229 @@ -1716,6 +1741,7 @@ void exit_mmap(struct mm_struct *mm)
2233 + arch_flush_exec_range(mm);
2235 spin_unlock(&mm->page_table_lock);
2237 --- linux/mm/mprotect.c.orig
2238 +++ linux/mm/mprotect.c
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>
2247 @@ -112,8 +113,9 @@ mprotect_fixup(struct vm_area_struct *vm
2248 unsigned long start, unsigned long end, unsigned int newflags)
2250 struct mm_struct * mm = vma->vm_mm;
2251 - unsigned long charged = 0;
2252 + unsigned long charged = 0, old_end = vma->vm_end;
2254 + unsigned int oldflags;
2258 @@ -174,8 +176,11 @@ success:
2259 * vm_flags and vm_page_prot are protected by the mmap_sem
2260 * held in write mode.
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);
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;
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);
2280 if (new_addr & ~PAGE_MASK)
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);
2288 + * vmalloc_exec - allocate virtually contiguous, executable memory
2290 + * @size: allocation size
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.
2296 + * For tight cotrol over page level allocator and protection flags
2297 + * use __vmalloc() instead.
2300 +#ifndef PAGE_KERNEL_EXEC
2301 +# define PAGE_KERNEL_EXEC PAGE_KERNEL
2304 +void *vmalloc_exec(unsigned long size)
2306 + return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
2310 * vmalloc_32 - allocate virtually contiguous memory (32bit addressable)
2312 * @size: allocation size