SOURCES (LINUX_2_6_20): pax-linux-2.6.20.patch (NEW) - http://www....
mguevara
mguevara at pld-linux.org
Wed Feb 28 00:53:46 CET 2007
Author: mguevara Date: Tue Feb 27 23:53:46 2007 GMT
Module: SOURCES Tag: LINUX_2_6_20
---- Log message:
- http://www.grsecurity.net/~paxguy1/pax-linux-2.6.20.1-test5.patch
---- Files affected:
SOURCES:
pax-linux-2.6.20.patch (NONE -> 1.1.2.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/pax-linux-2.6.20.patch
diff -u /dev/null SOURCES/pax-linux-2.6.20.patch:1.1.2.1
--- /dev/null Wed Feb 28 00:53:46 2007
+++ SOURCES/pax-linux-2.6.20.patch Wed Feb 28 00:53:41 2007
@@ -0,0 +1,18702 @@
+diff -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/Documentation/dontdiff linux-2.6.20.1-pax/Documentation/dontdiff
+--- linux-2.6.20.1/Documentation/dontdiff 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/Documentation/dontdiff 2007-02-10 01:32:42.000000000 +0100
+@@ -55,7 +55,7 @@ aic7*seq.h*
+ aicasm
+ aicdb.h*
+ asm
+-asm-offsets.*
++asm-offsets.h
+ asm_offsets.*
+ autoconf.h*
+ bbootsect
+@@ -127,6 +127,7 @@ pss_boot.h
+ raid6altivec*.c
+ raid6int*.c
+ raid6tables.c
++relocs
+ setup
+ sim710_d.h*
+ sm_tbl*
+@@ -139,8 +140,11 @@ utsrelease.h*
+ version.h*
+ vmlinux
+ vmlinux-*
++vmlinux.bin.all
+ vmlinux.lds
++vmlinux.relocs
+ vsyscall.lds
+ wanxlfw.inc
+ uImage
++utsrelease.h
+ zImage
+diff -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/Makefile linux-2.6.20.1-pax/Makefile
+--- linux-2.6.20.1/Makefile 2007-02-20 12:36:46.000000000 +0100
++++ linux-2.6.20.1-pax/Makefile 2007-02-20 12:36:39.000000000 +0100
+@@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \
+
+ CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
+
+-CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
++CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
+ -fno-strict-aliasing -fno-common
+ AFLAGS := -D__ASSEMBLY__
+
+diff -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/alpha/kernel/module.c linux-2.6.20.1-pax/arch/alpha/kernel/module.c
+--- linux-2.6.20.1/arch/alpha/kernel/module.c 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/alpha/kernel/module.c 2007-02-05 00:56:17.000000000 +0100
+@@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
+
+ /* 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 -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/alpha/kernel/osf_sys.c linux-2.6.20.1-pax/arch/alpha/kernel/osf_sys.c
+--- linux-2.6.20.1/arch/alpha/kernel/osf_sys.c 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/alpha/kernel/osf_sys.c 2007-02-05 00:56:17.000000000 +0100
+@@ -1277,6 +1277,10 @@ arch_get_unmapped_area(struct file *filp
+ 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 @@ arch_get_unmapped_area(struct file *filp
+ }
+
+ /* 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 -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/alpha/mm/fault.c linux-2.6.20.1-pax/arch/alpha/mm/fault.c
+--- linux-2.6.20.1/arch/alpha/mm/fault.c 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/alpha/mm/fault.c 2007-02-05 00:56:17.000000000 +0100
+@@ -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 @@ __load_new_mm_context(struct mm_struct *
+ __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 @@ do_page_fault(unsigned long address, uns
+ 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 -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/arm/mm/mmap.c linux-2.6.20.1-pax/arch/arm/mm/mmap.c
+--- linux-2.6.20.1/arch/arm/mm/mmap.c 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/arm/mm/mmap.c 2007-02-05 00:56:17.000000000 +0100
+@@ -61,6 +61,10 @@ arch_get_unmapped_area(struct file *filp
+ 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 @@ arch_get_unmapped_area(struct file *filp
+ 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 @@ full_search:
+ * 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 -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/Kconfig linux-2.6.20.1-pax/arch/i386/Kconfig
+--- linux-2.6.20.1/arch/i386/Kconfig 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/i386/Kconfig 2007-02-05 00:56:17.000000000 +0100
+@@ -864,7 +864,7 @@ config HOTPLUG_CPU
+
+ 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.
+@@ -1060,7 +1060,7 @@ config PCI
+ 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
+diff -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/Kconfig.cpu linux-2.6.20.1-pax/arch/i386/Kconfig.cpu
+--- linux-2.6.20.1/arch/i386/Kconfig.cpu 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/i386/Kconfig.cpu 2007-02-05 00:56:18.000000000 +0100
+@@ -267,7 +267,7 @@ config X86_PPRO_FENCE
+
+ 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
+@@ -297,7 +297,7 @@ config X86_CMPXCHG64
+
+ 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 -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/Kconfig.debug linux-2.6.20.1-pax/arch/i386/Kconfig.debug
+--- linux-2.6.20.1/arch/i386/Kconfig.debug 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/i386/Kconfig.debug 2007-02-05 00:56:18.000000000 +0100
+@@ -48,7 +48,7 @@ config DEBUG_PAGEALLOC
+
+ 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 -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/boot/setup.S linux-2.6.20.1-pax/arch/i386/boot/setup.S
+--- linux-2.6.20.1/arch/i386/boot/setup.S 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/i386/boot/setup.S 2007-02-05 00:56:18.000000000 +0100
+@@ -869,11 +869,13 @@ startup_32:
+ movl %eax, %gs
+ movl %eax, %ss
+
++ movl 0x00000000, %ecx
+ xorl %eax, %eax
+ 1: incl %eax # check that A20 really IS enabled
+ movl %eax, 0x00000000 # loop forever if it isn't
+ cmpl %eax, 0x00100000
+ je 1b
++ movl %ecx, 0x00000000
+
+ # Jump to the 32bit entry point
+ jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
+diff -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/kernel/acpi/boot.c linux-2.6.20.1-pax/arch/i386/kernel/acpi/boot.c
+--- linux-2.6.20.1/arch/i386/kernel/acpi/boot.c 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/i386/kernel/acpi/boot.c 2007-02-15 01:43:45.000000000 +0100
+@@ -1152,7 +1152,7 @@ static struct dmi_system_id __initdata a
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
+ },
+ },
+- {}
++ { NULL, NULL, {{0, NULL}}, NULL}
+ };
+
+ #endif /* __i386__ */
+diff -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/kernel/acpi/sleep.c linux-2.6.20.1-pax/arch/i386/kernel/acpi/sleep.c
+--- linux-2.6.20.1/arch/i386/kernel/acpi/sleep.c 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/i386/kernel/acpi/sleep.c 2007-02-15 01:44:30.000000000 +0100
+@@ -94,7 +94,7 @@ static __initdata struct dmi_system_id a
+ DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
+ },
+ },
+- {}
++ { NULL, NULL, {{0, NULL}}, NULL}
+ };
+
+ static int __init acpisleep_dmi_init(void)
+diff -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/kernel/acpi/wakeup.S linux-2.6.20.1-pax/arch/i386/kernel/acpi/wakeup.S
+--- linux-2.6.20.1/arch/i386/kernel/acpi/wakeup.S 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/i386/kernel/acpi/wakeup.S 2007-02-18 18:31:31.000000000 +0100
+@@ -205,13 +205,11 @@ wakeup_pmode_return:
+ # and restore the stack ... but you need gdt for this to work
+ movl saved_context_esp, %esp
+
+- movl %cs:saved_magic, %eax
+- cmpl $0x12345678, %eax
++ cmpl $0x12345678, saved_magic
+ jne bogus_magic
+
+ # jump to place where we left off
+- movl saved_eip,%eax
+- jmp *%eax
++ jmp *(saved_eip)
+
+ bogus_magic:
+ movw $0x0e00 + 'B', 0xb8018
+diff -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/kernel/alternative.c linux-2.6.20.1-pax/arch/i386/kernel/alternative.c
+--- linux-2.6.20.1/arch/i386/kernel/alternative.c 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/i386/kernel/alternative.c 2007-02-18 20:20:56.000000000 +0100
+@@ -4,6 +4,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;
+@@ -156,12 +157,18 @@ void apply_alternatives(struct alt_instr
+ u8 *instr;
+ int diff;
+
++#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);
+ if (!boot_cpu_has(a->cpuid))
+ continue;
+- instr = a->instr;
++ instr = a->instr + __KERNEL_TEXT_OFFSET;
+ #ifdef CONFIG_X86_64
+ /* vsyscall code is not mapped yet. resolve it manually. */
+ if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) {
+@@ -174,6 +181,11 @@ void apply_alternatives(struct alt_instr
+ diff = a->instrlen - a->replacementlen;
+ nop_out(instr + a->replacementlen, diff);
+ }
++
++#ifdef CONFIG_PAX_KERNEXEC
++ pax_close_kernel(cr0);
++#endif
++
+ }
+
+ #ifdef CONFIG_SMP
+@@ -182,49 +194,95 @@ static void alternatives_smp_save(struct
+ {
+ 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)
+ {
+- 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;
+- nop_out(*ptr, 1);
++ nop_out(ptr, 1);
+ };
++
++#ifdef CONFIG_PAX_KERNEXEC
++ pax_close_kernel(cr0);
++#endif
++
+ }
+
+ struct smp_alt_module {
+@@ -356,8 +414,9 @@ void apply_paravirt(struct paravirt_patc
+
+ for (p = start; p < end; p++) {
+ unsigned int used;
++ u8 *instr = p->instr + __KERNEL_TEXT_OFFSET;
+
+- used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr,
++ used = paravirt_ops.patch(p->instrtype, p->clobbers, instr,
+ p->len);
+ #ifdef CONFIG_DEBUG_PARAVIRT
+ {
+@@ -365,15 +424,14 @@ void apply_paravirt(struct paravirt_patc
+ /* Deliberately clobber regs using "not %reg" to find bugs. */
+ for (i = 0; i < 3; i++) {
+ if (p->len - used >= 2 && (p->clobbers & (1 << i))) {
+- memcpy(p->instr + used, "\xf7\xd0", 2);
+- p->instr[used+1] |= i;
+- used += 2;
++ instr[used++] = 0xf7;
++ instr[used++] = 0xd0 | i;
+ }
+ }
+ }
+ #endif
+ /* Pad the rest with nops */
+- nop_out(p->instr + used, p->len - used);
++ nop_out(instr + used, p->len - used);
+ }
+
+ /* Sync to be conservative, in case we patched following instructions */
+diff -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/kernel/apic.c linux-2.6.20.1-pax/arch/i386/kernel/apic.c
+--- linux-2.6.20.1/arch/i386/kernel/apic.c 2007-02-04 19:44:54.000000000 +0100
++++ linux-2.6.20.1-pax/arch/i386/kernel/apic.c 2007-02-05 00:56:18.000000000 +0100
+@@ -1211,7 +1211,7 @@ inline void smp_local_timer_interrupt(vo
+ {
+ 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 -NurpX linux-2.6.20.1-pax/Documentation/dontdiff -x 'netfilter*' linux-2.6.20.1/arch/i386/kernel/apm.c linux-2.6.20.1-pax/arch/i386/kernel/apm.c
+--- linux-2.6.20.1/arch/i386/kernel/apm.c 2007-02-04 19:44:54.000000000 +0100
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list