Author: hawk Date: Sat Jan 27 14:07:59 2007 GMT Module: SOURCES Tag: hawk-LINUX_2_6 ---- Log message: - copy of grsecurity-2.1.10-2.6.19.2-200701222307.patch, not adjusted for vserver patched kernel yet
---- Files affected: SOURCES: grsecurity-vs-2.1.10-2.6.19.2-200701222307.patch (NONE -> 1.1.2.1) (NEW) ---- Diffs: ================================================================ Index: SOURCES/grsecurity-vs-2.1.10-2.6.19.2-200701222307.patch diff -u /dev/null SOURCES/grsecurity-vs-2.1.10-2.6.19.2-200701222307.patch:1.1.2.1 --- /dev/null Sat Jan 27 15:07:59 2007 +++ SOURCES/grsecurity-vs-2.1.10-2.6.19.2-200701222307.patch Sat Jan 27 15:07:54 2007 @@ -0,0 +1,29305 @@ +diff -urNP linux-2.6.19.2/arch/alpha/kernel/module.c linux-2.6.19.2/arch/alpha/kernel/module.c +--- linux-2.6.19.2/arch/alpha/kernel/module.c 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/alpha/kernel/module.c 2007-01-20 17:29:54.000000000 -0500 +@@ -177,7 +177,7 @@ + + /* The small sections were sorted to the end of the segment. + The following should definitely cover them. */ +- gp = (u64)me->module_core + me->core_size - 0x8000; ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000; + got = sechdrs[me->arch.gotsecindex].sh_addr; + + for (i = 0; i < n; i++) { +diff -urNP linux-2.6.19.2/arch/alpha/kernel/osf_sys.c linux-2.6.19.2/arch/alpha/kernel/osf_sys.c +--- linux-2.6.19.2/arch/alpha/kernel/osf_sys.c 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/alpha/kernel/osf_sys.c 2007-01-20 17:29:54.000000000 -0500 +@@ -1277,6 +1277,10 @@ + merely specific addresses, but regions of memory -- perhaps + this feature should be incorporated into all ports? */ + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) ++#endif ++ + if (addr) { + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); + if (addr != (unsigned long) -ENOMEM) +@@ -1284,8 +1288,8 @@ + } + + /* Next, try allocating at TASK_UNMAPPED_BASE. */ +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE), +- len, limit); ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit); ++ + if (addr != (unsigned long) -ENOMEM) + return addr; + +diff -urNP linux-2.6.19.2/arch/alpha/kernel/ptrace.c linux-2.6.19.2/arch/alpha/kernel/ptrace.c +--- linux-2.6.19.2/arch/alpha/kernel/ptrace.c 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/alpha/kernel/ptrace.c 2007-01-20 17:29:54.000000000 -0500 +@@ -15,6 +15,7 @@ + #include <linux/slab.h> + #include <linux/security.h> + #include <linux/signal.h> ++#include <linux/grsecurity.h> + + #include <asm/uaccess.h> + #include <asm/pgtable.h> +@@ -283,6 +284,9 @@ + goto out_notsk; + } + ++ if (gr_handle_ptrace(child, request)) ++ goto out; ++ + if (request == PTRACE_ATTACH) { + ret = ptrace_attach(child); + goto out; +diff -urNP linux-2.6.19.2/arch/alpha/mm/fault.c linux-2.6.19.2/arch/alpha/mm/fault.c +--- linux-2.6.19.2/arch/alpha/mm/fault.c 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/alpha/mm/fault.c 2007-01-20 17:29:54.000000000 -0500 +@@ -24,6 +24,7 @@ + #include <linux/smp_lock.h> + #include <linux/interrupt.h> + #include <linux/module.h> ++#include <linux/binfmts.h> + + #include <asm/system.h> + #include <asm/uaccess.h> +@@ -55,6 +56,124 @@ + __reload_thread(pcb); + } + ++#ifdef CONFIG_PAX_PAGEEXEC ++/* ++ * PaX: decide what to do with offenders (regs->pc = fault address) ++ * ++ * returns 1 when task should be killed ++ * 2 when patched PLT trampoline was detected ++ * 3 when unpatched PLT trampoline was detected ++ */ ++static int pax_handle_fetch_fault(struct pt_regs *regs) ++{ ++ ++#ifdef CONFIG_PAX_EMUPLT ++ int err; ++ ++ do { /* PaX: patched PLT emulation #1 */ ++ unsigned int ldah, ldq, jmp; ++ ++ err = get_user(ldah, (unsigned int *)regs->pc); ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4)); ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8)); ++ ++ if (err) ++ break; ++ ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U && ++ (ldq & 0xFFFF0000U) == 0xA77B0000U && ++ jmp == 0x6BFB0000U) ++ { ++ unsigned long r27, addr; ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL; ++ ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); ++ err = get_user(r27, (unsigned long*)addr); ++ if (err) ++ break; ++ ++ regs->r27 = r27; ++ regs->pc = r27; ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: patched PLT emulation #2 */ ++ unsigned int ldah, lda, br; ++ ++ err = get_user(ldah, (unsigned int *)regs->pc); ++ err |= get_user(lda, (unsigned int *)(regs->pc+4)); ++ err |= get_user(br, (unsigned int *)(regs->pc+8)); ++ ++ if (err) ++ break; ++ ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U && ++ (lda & 0xFFFF0000U) == 0xA77B0000U && ++ (br & 0xFFE00000U) == 0xC3E00000U) ++ { ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL; ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL; ++ ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: unpatched PLT emulation */ ++ unsigned int br; ++ ++ err = get_user(br, (unsigned int *)regs->pc); ++ ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) { ++ unsigned int br2, ldq, nop, jmp; ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver; ++ ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); ++ err = get_user(br2, (unsigned int *)addr); ++ err |= get_user(ldq, (unsigned int *)(addr+4)); ++ err |= get_user(nop, (unsigned int *)(addr+8)); ++ err |= get_user(jmp, (unsigned int *)(addr+12)); ++ err |= get_user(resolver, (unsigned long *)(addr+16)); ++ ++ if (err) ++ break; ++ ++ if (br2 == 0xC3600000U && ++ ldq == 0xA77B000CU && ++ nop == 0x47FF041FU && ++ jmp == 0x6B7B0000U) ++ { ++ regs->r28 = regs->pc+4; ++ regs->r27 = addr+16; ++ regs->pc = resolver; ++ return 3; ++ } ++ } ++ } while (0); ++#endif ++ ++ return 1; ++} ++ ++void pax_report_insns(void *pc, void *sp) ++{ ++ unsigned long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 5; i++) { ++ unsigned int c; ++ if (get_user(c, (unsigned int*)pc+i)) ++ printk("???????? "); ++ else ++ printk("%08x ", c); ++ } ++ printk("\n"); ++} ++#endif + + /* + * This routine handles page faults. It determines the address, +@@ -132,8 +251,29 @@ + good_area: + si_code = SEGV_ACCERR; + if (cause < 0) { +- if (!(vma->vm_flags & VM_EXEC)) ++ if (!(vma->vm_flags & VM_EXEC)) { ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc) ++ goto bad_area; ++ ++ up_read(&mm->mmap_sem); ++ switch(pax_handle_fetch_fault(regs)) { ++ ++#ifdef CONFIG_PAX_EMUPLT ++ case 2: ++ case 3: ++ return; ++#endif ++ ++ } ++ pax_report_fault(regs, (void*)regs->pc, (void*)rdusp()); ++ do_exit(SIGKILL); ++#else + goto bad_area; ++#endif ++ ++ } + } else if (!cause) { + /* Allow reads even for write-only mappings */ + if (!(vma->vm_flags & (VM_READ | VM_WRITE))) +diff -urNP linux-2.6.19.2/arch/arm/mm/mmap.c linux-2.6.19.2/arch/arm/mm/mmap.c +--- linux-2.6.19.2/arch/arm/mm/mmap.c 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/arm/mm/mmap.c 2007-01-20 17:29:54.000000000 -0500 +@@ -61,6 +61,10 @@ + if (len > TASK_SIZE) + return -ENOMEM; + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) ++#endif ++ + if (addr) { + if (do_align) + addr = COLOUR_ALIGN(addr, pgoff); +@@ -75,7 +79,7 @@ + if (len > mm->cached_hole_size) { + start_addr = addr = mm->free_area_cache; + } else { +- start_addr = addr = TASK_UNMAPPED_BASE; ++ start_addr = addr = mm->mmap_base; + mm->cached_hole_size = 0; + } + +@@ -92,8 +96,8 @@ + * Start a new search - just in case we missed + * some holes. + */ +- if (start_addr != TASK_UNMAPPED_BASE) { +- start_addr = addr = TASK_UNMAPPED_BASE; ++ if (start_addr != mm->mmap_base) { ++ start_addr = addr = mm->mmap_base; + mm->cached_hole_size = 0; + goto full_search; + } +diff -urNP linux-2.6.19.2/arch/i386/boot/compressed/head.S linux-2.6.19.2/arch/i386/boot/compressed/head.S +--- linux-2.6.19.2/arch/i386/boot/compressed/head.S 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/i386/boot/compressed/head.S 2007-01-20 17:29:54.000000000 -0500 +@@ -39,11 +39,13 @@ + movl %eax,%gs + + lss stack_start,%esp ++ movl 0x000000,%ecx + xorl %eax,%eax + 1: incl %eax # check that A20 really IS enabled + movl %eax,0x000000 # loop forever if it isn't + cmpl %eax,0x100000 + je 1b ++ movl %ecx,0x000000 + + /* + * Initialize eflags. Some BIOS's leave bits like NT set. This would +diff -urNP linux-2.6.19.2/arch/i386/Kconfig linux-2.6.19.2/arch/i386/Kconfig +--- linux-2.6.19.2/arch/i386/Kconfig 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/i386/Kconfig 2007-01-20 17:29:54.000000000 -0500 +@@ -803,7 +803,7 @@ + + config COMPAT_VDSO + bool "Compat VDSO support" +- default y ++ default n + depends on !PARAVIRT + help + Map the VDSO to the predictable old-style address too. +@@ -999,7 +999,7 @@ + choice + prompt "PCI access mode" + depends on PCI && !X86_VISWS +- default PCI_GOANY ++ default PCI_GODIRECT + ---help--- + On PCI systems, the BIOS can be used to detect the PCI devices and + determine their configuration. However, some old PCI motherboards +@@ -1031,7 +1031,7 @@ + + config PCI_BIOS + bool +- depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) ++ depends on !X86_VISWS && PCI && PCI_GOBIOS + default y + + config PCI_DIRECT +diff -urNP linux-2.6.19.2/arch/i386/Kconfig.cpu linux-2.6.19.2/arch/i386/Kconfig.cpu +--- linux-2.6.19.2/arch/i386/Kconfig.cpu 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/i386/Kconfig.cpu 2007-01-20 17:29:54.000000000 -0500 +@@ -252,7 +252,7 @@ + + config X86_F00F_BUG + bool +- depends on M586MMX || M586TSC || M586 || M486 || M386 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC + default y + + config X86_WP_WORKS_OK +@@ -282,7 +282,7 @@ + + config X86_ALIGNMENT_16 + bool +- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 ++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 + default y + + config X86_GOOD_APIC +diff -urNP linux-2.6.19.2/arch/i386/Kconfig.debug linux-2.6.19.2/arch/i386/Kconfig.debug +--- linux-2.6.19.2/arch/i386/Kconfig.debug 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/i386/Kconfig.debug 2007-01-20 17:29:54.000000000 -0500 +@@ -48,7 +48,7 @@ + + config DEBUG_RODATA + bool "Write protect kernel read-only data structures" +- depends on DEBUG_KERNEL ++ depends on DEBUG_KERNEL && !PAX_KERNEXEC + help + Mark the kernel read-only data as write-protected in the pagetables, + in order to catch accidental (and incorrect) writes to such const +diff -urNP linux-2.6.19.2/arch/i386/kernel/alternative.c linux-2.6.19.2/arch/i386/kernel/alternative.c +--- linux-2.6.19.2/arch/i386/kernel/alternative.c 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/i386/kernel/alternative.c 2007-01-20 17:29:54.000000000 -0500 +@@ -3,6 +3,7 @@ + #include <linux/list.h> + #include <asm/alternative.h> + #include <asm/sections.h> ++#include <asm/desc.h> + + static int no_replacement = 0; + static int smp_alt_once = 0; +@@ -142,6 +143,12 @@ + u8 *instr; + int diff, i, k; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); + for (a = start; a < end; a++) { + BUG_ON(a->replacementlen > a->instrlen); +@@ -156,16 +163,21 @@ + __FUNCTION__, a->instr, instr); + } + #endif +- memcpy(instr, a->replacement, a->replacementlen); ++ memcpy(instr + __KERNEL_TEXT_OFFSET, a->replacement, a->replacementlen); + diff = a->instrlen - a->replacementlen; + /* Pad the rest with nops */ + for (i = a->replacementlen; diff > 0; diff -= k, i += k) { + k = diff; + if (k > ASM_NOP_MAX) + k = ASM_NOP_MAX; +- memcpy(a->instr + i, noptable[k], k); ++ memcpy(a->instr + i + __KERNEL_TEXT_OFFSET, noptable[k], k); + } + } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + #ifdef CONFIG_SMP +@@ -174,50 +186,96 @@ + { + struct alt_instr *a; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end); + for (a = start; a < end; a++) { + memcpy(a->replacement + a->replacementlen, +- a->instr, ++ a->instr + __KERNEL_TEXT_OFFSET, + a->instrlen); + } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end) + { + struct alt_instr *a; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + for (a = start; a < end; a++) { +- memcpy(a->instr, ++ memcpy(a->instr + __KERNEL_TEXT_OFFSET, + a->replacement + a->replacementlen, + a->instrlen); + } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) + { +- u8 **ptr; ++ u8 *ptr; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; + +- for (ptr = start; ptr < end; ptr++) { +- if (*ptr < text) ++ pax_open_kernel(cr0); ++#endif ++ ++ for (; start < end; start++) { ++ ptr = *start + __KERNEL_TEXT_OFFSET; ++ if (ptr < text) + continue; +- if (*ptr > text_end) ++ if (ptr > text_end) + continue; +- **ptr = 0xf0; /* lock prefix */ ++ *ptr = 0xf0; /* lock prefix */ + }; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) + { + unsigned char **noptable = find_nop_table(); +- u8 **ptr; ++ u8 *ptr; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif + +- for (ptr = start; ptr < end; ptr++) { +- if (*ptr < text) ++ for (; start < end; start++) { ++ ptr = *start + __KERNEL_TEXT_OFFSET; ++ if (ptr < text) + continue; +- if (*ptr > text_end) ++ if (ptr > text_end) + continue; +- **ptr = noptable[1][0]; ++ *ptr = noptable[1][0]; + }; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + struct smp_alt_module { +diff -urNP linux-2.6.19.2/arch/i386/kernel/apic.c linux-2.6.19.2/arch/i386/kernel/apic.c +--- linux-2.6.19.2/arch/i386/kernel/apic.c 2006-11-29 16:57:37.000000000 -0500 ++++ linux-2.6.19.2/arch/i386/kernel/apic.c 2007-01-20 17:29:54.000000000 -0500 +@@ -1197,7 +1197,7 @@ + { + profile_tick(CPU_PROFILING); + #ifdef CONFIG_SMP +- update_process_times(user_mode_vm(get_irq_regs())); ++ update_process_times(user_mode(get_irq_regs())); + #endif + + /* +diff -urNP linux-2.6.19.2/arch/i386/kernel/apm.c linux-2.6.19.2/arch/i386/kernel/apm.c +--- linux-2.6.19.2/arch/i386/kernel/apm.c 2007-01-12 11:32:03.000000000 -0500 ++++ linux-2.6.19.2/arch/i386/kernel/apm.c 2007-01-20 17:29:54.000000000 -0500 +@@ -235,7 +235,7 @@ + #include "io_ports.h" + + extern unsigned long get_cmos_time(void); +-extern void machine_real_restart(unsigned char *, int); ++extern void machine_real_restart(const unsigned char *, unsigned int); + + #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) + extern int (*console_blank_hook)(int); +@@ -608,9 +608,18 @@ + struct desc_struct save_desc_40; + struct desc_struct *gdt; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + cpus = apm_save_cpus(); + + cpu = get_cpu(); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + gdt = get_cpu_gdt_table(cpu); + save_desc_40 = gdt[0x40 / 8]; + gdt[0x40 / 8] = bad_bios_desc; +@@ -621,6 +630,11 @@ + APM_DO_RESTORE_SEGS; + apm_irq_restore(flags); + gdt[0x40 / 8] = save_desc_40; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + put_cpu(); + apm_restore_cpus(cpus); + +@@ -651,9 +665,18 @@ + struct desc_struct save_desc_40; + struct desc_struct *gdt; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + cpus = apm_save_cpus(); + + cpu = get_cpu(); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + gdt = get_cpu_gdt_table(cpu); + save_desc_40 = gdt[0x40 / 8]; + gdt[0x40 / 8] = bad_bios_desc; +@@ -664,6 +687,11 @@ + APM_DO_RESTORE_SEGS; + apm_irq_restore(flags); + gdt[0x40 / 8] = save_desc_40; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + put_cpu(); + apm_restore_cpus(cpus); + return error; +@@ -931,7 +959,7 @@ + + static void apm_power_off(void) + { +- unsigned char po_bios_call[] = { ++ const unsigned char po_bios_call[] = { + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */ + 0x8e, 0xd0, /* movw ax,ss */ + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */ <<Diff was trimmed, longer than 597 lines>> _______________________________________________ pld-cvs-commit mailing list pld-cvs-commit@lists.pld-linux.org http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit