Author: zbyniu                       Date: Sat Sep  8 18:52:54 2007 GMT
Module: SOURCES                       Tag: LINUX_2_6
---- Log message:
- raw http://www.grsecurity.net/~paxguy1/pax-linux-2.6.22.6-test26.patch

---- Files affected:
SOURCES:
   kernel-pax.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/kernel-pax.patch
diff -u /dev/null SOURCES/kernel-pax.patch:1.1.2.1
--- /dev/null   Sat Sep  8 20:52:54 2007
+++ SOURCES/kernel-pax.patch    Sat Sep  8 20:52:49 2007
@@ -0,0 +1,20949 @@
+diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/Documentation/dontdiff linux-2.6.22.6-pax/Documentation/dontdiff
+--- linux-2.6.22.6/Documentation/dontdiff      2007-07-09 01:32:17.000000000 
+0200
++++ linux-2.6.22.6-pax/Documentation/dontdiff  2007-07-10 02:05:11.000000000 
+0200
+@@ -177,10 +177,13 @@ version.h*
+ vmlinux
+ vmlinux-*
+ vmlinux.aout
++vmlinux.bin.all
+ vmlinux.lds
++vmlinux.relocs
+ vsyscall.lds
+ wanxlfw.inc
+ uImage
+ unifdef
++utsrelease.h
+ zImage*
+ zconf.hash.c
+diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/Makefile 
linux-2.6.22.6-pax/Makefile
+--- linux-2.6.22.6/Makefile    2007-08-31 14:33:33.000000000 +0200
++++ linux-2.6.22.6-pax/Makefile        2007-08-31 14:37:51.000000000 +0200
+@@ -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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/alpha/kernel/module.c 
linux-2.6.22.6-pax/arch/alpha/kernel/module.c
+--- linux-2.6.22.6/arch/alpha/kernel/module.c  2007-07-09 01:32:17.000000000 
+0200
++++ linux-2.6.22.6-pax/arch/alpha/kernel/module.c      2007-07-10 
02:05:11.000000000 +0200
+@@ -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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/alpha/kernel/osf_sys.c 
linux-2.6.22.6-pax/arch/alpha/kernel/osf_sys.c
+--- linux-2.6.22.6/arch/alpha/kernel/osf_sys.c 2007-07-09 01:32:17.000000000 
+0200
++++ linux-2.6.22.6-pax/arch/alpha/kernel/osf_sys.c     2007-07-10 
02:05:11.000000000 +0200
+@@ -1288,6 +1288,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)
+@@ -1295,8 +1299,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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/alpha/mm/fault.c linux-2.6.22.6-pax/arch/alpha/mm/fault.c
+--- linux-2.6.22.6/arch/alpha/mm/fault.c       2007-07-09 01:32:17.000000000 
+0200
++++ linux-2.6.22.6-pax/arch/alpha/mm/fault.c   2007-07-29 21:45:49.000000000 
+0200
+@@ -23,6 +23,7 @@
+ #include <linux/smp.h>
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
++#include <linux/binfmts.h>
+ 
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+@@ -54,6 +55,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,
+@@ -131,8 +250,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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/arm/mm/mmap.c linux-2.6.22.6-pax/arch/arm/mm/mmap.c
+--- linux-2.6.22.6/arch/arm/mm/mmap.c  2007-07-09 01:32:17.000000000 +0200
++++ linux-2.6.22.6-pax/arch/arm/mm/mmap.c      2007-07-29 21:45:49.000000000 
+0200
+@@ -60,6 +60,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);
+@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
+                       return addr;
+       }
+       if (len > mm->cached_hole_size) {
+-              start_addr = addr = mm->free_area_cache;
++              start_addr = addr = mm->free_area_cache;
+       } else {
+-              start_addr = addr = TASK_UNMAPPED_BASE;
+-              mm->cached_hole_size = 0;
++              start_addr = addr = mm->mmap_base;
++              mm->cached_hole_size = 0;
+       }
+ 
+ full_search:
+@@ -91,8 +95,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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/avr32/mm/fault.c linux-2.6.22.6-pax/arch/avr32/mm/fault.c
+--- linux-2.6.22.6/arch/avr32/mm/fault.c       2007-07-09 01:32:17.000000000 
+0200
++++ linux-2.6.22.6-pax/arch/avr32/mm/fault.c   2007-07-29 21:45:49.000000000 
+0200
+@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
+ 
+ int exception_trace = 1;
+ 
++#ifdef CONFIG_PAX_PAGEEXEC
++void pax_report_insns(void *pc, void *sp)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 20; i++) {
++              unsigned char c;
++              if (get_user(c, (unsigned char *)pc+i))
++                      printk("???????? ");
++              else
++                      printk("%02x ", c);
++      }
++      printk("\n");
++}
++#endif
++
+ /*
+  * This routine handles page faults. It determines the address and the
+  * problem, and then passes it off to one of the appropriate routines.
+@@ -158,6 +175,16 @@ bad_area:
+       up_read(&mm->mmap_sem);
+ 
+       if (user_mode(regs)) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++              if (mm->pax_flags & MF_PAX_PAGEEXEC) {
++                      if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
++                              pax_report_fault(regs, (void *)regs->pc, (void 
*)regs->sp);
++                              do_exit(SIGKILL);
++                      }
++              }
++#endif
++
+               if (exception_trace && printk_ratelimit())
+                       printk("%s%s[%d]: segfault at %08lx pc %08lx "
+                              "sp %08lx ecr %lu\n",
+diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/i386/Kconfig linux-2.6.22.6-pax/arch/i386/Kconfig
+--- linux-2.6.22.6/arch/i386/Kconfig   2007-07-09 01:32:17.000000000 +0200
++++ linux-2.6.22.6-pax/arch/i386/Kconfig       2007-07-10 02:05:11.000000000 
+0200
+@@ -586,7 +586,7 @@ config PAGE_OFFSET
+       hex
+       default 0xB0000000 if VMSPLIT_3G_OPT
+       default 0x80000000 if VMSPLIT_2G
+-      default 0x78000000 if VMSPLIT_2G_OPT
++      default 0x70000000 if VMSPLIT_2G_OPT
+       default 0x40000000 if VMSPLIT_1G
+       default 0xC0000000
+ 
+@@ -815,7 +815,7 @@ config CRASH_DUMP
+ 
+ config PHYSICAL_START
+       hex "Physical address where the kernel is loaded" if (EMBEDDED || 
CRASH_DUMP)
+-      default "0x100000"
++      default "0x200000"
+       help
+         This gives the physical address where the kernel is loaded.
+ 
+@@ -900,7 +900,7 @@ config HOTPLUG_CPU
+ 
+ config COMPAT_VDSO
+       bool "Compat VDSO support"
+-      default y
++      default n
+       help
+         Map the VDSO to the predictable old-style address too.
+       ---help---
+@@ -1076,7 +1076,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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/i386/Kconfig.cpu linux-2.6.22.6-pax/arch/i386/Kconfig.cpu
+--- linux-2.6.22.6/arch/i386/Kconfig.cpu       2007-07-09 01:32:17.000000000 
+0200
++++ linux-2.6.22.6-pax/arch/i386/Kconfig.cpu   2007-07-10 02:05:11.000000000 
+0200
+@@ -274,7 +274,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
+@@ -304,7 +304,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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/i386/Kconfig.debug 
linux-2.6.22.6-pax/arch/i386/Kconfig.debug
+--- linux-2.6.22.6/arch/i386/Kconfig.debug     2007-07-09 01:32:17.000000000 
+0200
++++ linux-2.6.22.6-pax/arch/i386/Kconfig.debug 2007-07-10 02:05:11.000000000 
+0200
+@@ -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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/i386/boot/setup.S linux-2.6.22.6-pax/arch/i386/boot/setup.S
+--- linux-2.6.22.6/arch/i386/boot/setup.S      2007-07-09 01:32:17.000000000 
+0200
++++ linux-2.6.22.6-pax/arch/i386/boot/setup.S  2007-07-10 02:05:11.000000000 
+0200
+@@ -893,11 +893,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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/i386/boot/video.S linux-2.6.22.6-pax/arch/i386/boot/video.S
+--- linux-2.6.22.6/arch/i386/boot/video.S      2007-07-09 01:32:17.000000000 
+0200
++++ linux-2.6.22.6-pax/arch/i386/boot/video.S  2007-08-19 17:23:53.000000000 
+0200
+@@ -96,6 +96,7 @@
+ #define PARAM_LFB_PAGES               0x32
+ #define PARAM_VESA_ATTRIB     0x34
+ #define PARAM_CAPABILITIES    0x36
++#define PARAM_VESAPM_SIZE     0x3a
+ 
+ /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
+ #ifdef CONFIG_VIDEO_RETAIN
+@@ -280,6 +281,7 @@ dac_done:
+ 
+       movw    %es, %fs:(PARAM_VESAPM_SEG)
+       movw    %di, %fs:(PARAM_VESAPM_OFF)
++      movw    %cx, %fs:(PARAM_VESAPM_SIZE)
+ no_pm:        ret
+ 
+ # The video mode menu
+diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/i386/kernel/acpi/boot.c 
linux-2.6.22.6-pax/arch/i386/kernel/acpi/boot.c
+--- linux-2.6.22.6/arch/i386/kernel/acpi/boot.c        2007-07-09 
01:32:17.000000000 +0200
++++ linux-2.6.22.6-pax/arch/i386/kernel/acpi/boot.c    2007-07-10 
02:05:11.000000000 +0200
+@@ -1095,7 +1095,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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/i386/kernel/acpi/sleep.c 
linux-2.6.22.6-pax/arch/i386/kernel/acpi/sleep.c
+--- linux-2.6.22.6/arch/i386/kernel/acpi/sleep.c       2007-07-09 
01:32:17.000000000 +0200
++++ linux-2.6.22.6-pax/arch/i386/kernel/acpi/sleep.c   2007-07-10 
02:05:11.000000000 +0200
+@@ -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.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/i386/kernel/acpi/wakeup.S 
linux-2.6.22.6-pax/arch/i386/kernel/acpi/wakeup.S
+--- linux-2.6.22.6/arch/i386/kernel/acpi/wakeup.S      2007-07-09 
01:32:17.000000000 +0200
++++ linux-2.6.22.6-pax/arch/i386/kernel/acpi/wakeup.S  2007-07-10 
02:05:11.000000000 +0200
+@@ -2,6 +2,7 @@
+ #include <linux/linkage.h>
+ #include <asm/segment.h>
+ #include <asm/page.h>
++#include <asm/msr-index.h>
+ 
+ #
+ # wakeup_code runs in real mode, and at unknown address (determined at 
run-time).
+@@ -64,7 +65,7 @@ wakeup_code:
+       # restore efer setting
+       movl    real_save_efer_edx - wakeup_code, %edx
+       movl    real_save_efer_eax - wakeup_code, %eax
+-      mov     $0xc0000080, %ecx
++      mov     $MSR_EFER, %ecx
+       wrmsr
+ 4:
+       # make sure %cr4 is set correctly (features, etc)
+@@ -205,13 +206,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
+@@ -243,7 +242,7 @@ ENTRY(acpi_copy_wakeup_routine)
+       # save efer setting
+       pushl   %eax
+       movl    %eax, %ebx
+-      mov     $0xc0000080, %ecx
++      mov     $MSR_EFER, %ecx
+       rdmsr
+       movl    %edx, real_save_efer_edx - wakeup_start (%ebx)
+       movl    %eax, real_save_efer_eax - wakeup_start (%ebx)
+diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff 
linux-2.6.22.6/arch/i386/kernel/alternative.c 
linux-2.6.22.6-pax/arch/i386/kernel/alternative.c
+--- linux-2.6.22.6/arch/i386/kernel/alternative.c      2007-07-09 
01:32:17.000000000 +0200
++++ linux-2.6.22.6-pax/arch/i386/kernel/alternative.c  2007-08-11 
22:49:55.000000000 +0200
+@@ -4,6 +4,7 @@
+ #include <linux/list.h>
+ #include <asm/alternative.h>
+ #include <asm/sections.h>
++#include <asm/desc.h>
+ 
+ static int noreplace_smp     = 0;
+ static int smp_alt_once      = 0;
+@@ -165,12 +166,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) 
{
+@@ -183,6 +190,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
+@@ -191,29 +203,53 @@ static void alternatives_smp_lock(u8 **s
+ {
+       u8 **ptr;
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++      unsigned long cr0;
++
++      pax_open_kernel(cr0);
++#endif
++
+       for (ptr = start; ptr < end; ptr++) {
+               if (*ptr < text)
+                       continue;
+               if (*ptr > text_end)
+                       continue;
+-              **ptr = 0xf0; /* lock prefix */
+-      };
++              *(*ptr + __KERNEL_TEXT_OFFSET) = 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;
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++      unsigned long cr0;
++#endif
++
+       if (noreplace_smp)
+               return;
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++      pax_open_kernel(cr0);
++#endif
++
+       for (ptr = start; ptr < end; ptr++) {
+               if (*ptr < text)
+                       continue;
+               if (*ptr > text_end)
+                       continue;
+-              nop_out(*ptr, 1);
+-      };
++              nop_out(*ptr + __KERNEL_TEXT_OFFSET, 1);
++      }
++
++#ifdef CONFIG_PAX_KERNEXEC
++      pax_close_kernel(cr0);
++#endif
++
<<Diff was trimmed, longer than 597 lines>>
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to