SOURCES (LINUX_2_6): grsecurity-2.1.8-2.6.14.6-200601121820.patch ...
cieciwa
cieciwa at pld-linux.org
Thu Jan 26 12:58:31 CET 2006
Author: cieciwa Date: Thu Jan 26 11:58:30 2006 GMT
Module: SOURCES Tag: LINUX_2_6
---- Log message:
- grsec.
---- Files affected:
SOURCES:
grsecurity-2.1.8-2.6.14.6-200601121820.patch (NONE -> 1.1.4.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/grsecurity-2.1.8-2.6.14.6-200601121820.patch
diff -u /dev/null SOURCES/grsecurity-2.1.8-2.6.14.6-200601121820.patch:1.1.4.1
--- /dev/null Thu Jan 26 12:58:30 2006
+++ SOURCES/grsecurity-2.1.8-2.6.14.6-200601121820.patch Thu Jan 26 12:58:25 2006
@@ -0,0 +1,24386 @@
+diff -urNp linux-2.6.14.6/Makefile linux-2.6.14.6/Makefile
+--- linux-2.6.14.6/Makefile 2006-01-08 19:46:31.000000000 -0500
++++ linux-2.6.14.6/Makefile 2006-01-09 00:40:48.000000000 -0500
+@@ -582,7 +582,7 @@ export MODLIB
+
+
+ ifeq ($(KBUILD_EXTMOD),)
+-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
+
+ vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
+ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
+diff -urNp linux-2.6.14.6/arch/alpha/kernel/module.c linux-2.6.14.6/arch/alpha/kernel/module.c
+--- linux-2.6.14.6/arch/alpha/kernel/module.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/alpha/kernel/module.c 2006-01-09 00:40:49.000000000 -0500
+@@ -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 -urNp linux-2.6.14.6/arch/alpha/kernel/osf_sys.c linux-2.6.14.6/arch/alpha/kernel/osf_sys.c
+--- linux-2.6.14.6/arch/alpha/kernel/osf_sys.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/alpha/kernel/osf_sys.c 2006-01-09 00:40:49.000000000 -0500
+@@ -1274,6 +1274,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)
+@@ -1281,8 +1285,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 -urNp linux-2.6.14.6/arch/alpha/kernel/ptrace.c linux-2.6.14.6/arch/alpha/kernel/ptrace.c
+--- linux-2.6.14.6/arch/alpha/kernel/ptrace.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/alpha/kernel/ptrace.c 2006-01-09 00:40:49.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>
+@@ -290,6 +291,9 @@ do_sys_ptrace(long request, long pid, lo
+ if (!child)
+ 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.14.6/arch/alpha/mm/fault.c linux-2.6.14.6/arch/alpha/mm/fault.c
+--- linux-2.6.14.6/arch/alpha/mm/fault.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/alpha/mm/fault.c 2006-01-09 00:40:49.000000000 -0500
+@@ -25,6 +25,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>
+@@ -56,6 +57,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,
+@@ -133,8 +252,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 -urNp linux-2.6.14.6/arch/arm/mm/mmap.c linux-2.6.14.6/arch/arm/mm/mmap.c
+--- linux-2.6.14.6/arch/arm/mm/mmap.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/arm/mm/mmap.c 2006-01-09 00:40:49.000000000 -0500
+@@ -62,6 +62,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);
+@@ -76,7 +80,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;
+ }
+
+@@ -93,8 +97,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 -urNp linux-2.6.14.6/arch/i386/Kconfig.cpu linux-2.6.14.6/arch/i386/Kconfig.cpu
+--- linux-2.6.14.6/arch/i386/Kconfig.cpu 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/Kconfig.cpu 2006-01-09 00:40:49.000000000 -0500
+@@ -397,7 +397,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
+@@ -422,7 +422,7 @@ config X86_POPAD_OK
+
+ 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.14.6/arch/i386/Kconfig linux-2.6.14.6/arch/i386/Kconfig
+--- linux-2.6.14.6/arch/i386/Kconfig 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/Kconfig 2006-01-09 00:40:49.000000000 -0500
+@@ -1196,7 +1196,7 @@ endchoice
+
+ 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.14.6/arch/i386/boot/compressed/head.S linux-2.6.14.6/arch/i386/boot/compressed/head.S
+--- linux-2.6.14.6/arch/i386/boot/compressed/head.S 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/boot/compressed/head.S 2006-01-09 00:40:49.000000000 -0500
+@@ -39,11 +39,13 @@ startup_32:
+ 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.14.6/arch/i386/kernel/acpi/sleep.c linux-2.6.14.6/arch/i386/kernel/acpi/sleep.c
+--- linux-2.6.14.6/arch/i386/kernel/acpi/sleep.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/kernel/acpi/sleep.c 2006-01-09 00:40:49.000000000 -0500
+@@ -10,6 +10,7 @@
+ #include <linux/dmi.h>
+ #include <asm/smp.h>
+ #include <asm/tlbflush.h>
++#include <asm/desc.h>
+
+ /* address in low memory of the wakeup routine. */
+ unsigned long acpi_wakeup_address = 0;
+diff -urNp linux-2.6.14.6/arch/i386/kernel/apic.c linux-2.6.14.6/arch/i386/kernel/apic.c
+--- linux-2.6.14.6/arch/i386/kernel/apic.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/kernel/apic.c 2006-01-09 01:02:55.000000000 -0500
+@@ -1150,7 +1150,7 @@ inline void smp_local_timer_interrupt(st
+ }
+
+ #ifdef CONFIG_SMP
+- update_process_times(user_mode_vm(regs));
++ update_process_times(user_mode(regs));
+ #endif
+ }
+
+diff -urNp linux-2.6.14.6/arch/i386/kernel/apm.c linux-2.6.14.6/arch/i386/kernel/apm.c
+--- linux-2.6.14.6/arch/i386/kernel/apm.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/kernel/apm.c 2006-01-09 00:40:49.000000000 -0500
+@@ -598,19 +598,39 @@ static u8 apm_bios_call(u32 func, u32 eb
+ int cpu;
+ struct desc_struct save_desc_40;
+
++#ifdef CONFIG_PAX_KERNEXEC
++ unsigned long cr0;
++#endif
++
+ cpus = apm_save_cpus();
+-
+ cpu = get_cpu();
+- save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
+- per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
+
++#ifdef CONFIG_PAX_KERNEXEC
++ pax_open_kernel(flags, cr0);
++#endif
++
++ save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
++ cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
++
++#ifndef CONFIG_PAX_KERNEXEC
+ local_save_flags(flags);
+ APM_DO_CLI;
++#endif
++
+ APM_DO_SAVE_SEGS;
+ apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
+ APM_DO_RESTORE_SEGS;
++
++#ifndef CONFIG_PAX_KERNEXEC
+ local_irq_restore(flags);
+- per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = save_desc_40;
++#endif
++
++ cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
++
++#ifdef CONFIG_PAX_KERNEXEC
++ pax_close_kernel(flags, cr0);
++#endif
++
+ put_cpu();
+ apm_restore_cpus(cpus);
+
+@@ -640,20 +660,39 @@ static u8 apm_bios_call_simple(u32 func,
+ int cpu;
+ struct desc_struct save_desc_40;
+
++#ifdef CONFIG_PAX_KERNEXEC
++ unsigned long cr0;
++#endif
+
+ cpus = apm_save_cpus();
+-
+ cpu = get_cpu();
+- save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
+- per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
+
++#ifdef CONFIG_PAX_KERNEXEC
++ pax_open_kernel(flags, cr0);
++#endif
++
++ save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
++ cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
++
++#ifndef CONFIG_PAX_KERNEXEC
+ local_save_flags(flags);
+ APM_DO_CLI;
++#endif
++
+ APM_DO_SAVE_SEGS;
+ error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
+ APM_DO_RESTORE_SEGS;
++
++#ifndef CONFIG_PAX_KERNEXEC
+ local_irq_restore(flags);
+- __get_cpu_var(cpu_gdt_table)[0x40 / 8] = save_desc_40;
++#endif
++
++ cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
++
++#ifdef CONFIG_PAX_KERNEXEC
++ pax_close_kernel(flags, cr0);
++#endif
++
+ put_cpu();
+ apm_restore_cpus(cpus);
+ return error;
+@@ -2295,35 +2334,35 @@ static int __init apm_init(void)
+ apm_bios_entry.segment = APM_CS;
+
+ for (i = 0; i < NR_CPUS; i++) {
+- set_base(per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
++ set_base(cpu_gdt_table[i][APM_CS >> 3],
+ __va((unsigned long)apm_info.bios.cseg << 4));
+- set_base(per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
++ set_base(cpu_gdt_table[i][APM_CS_16 >> 3],
+ __va((unsigned long)apm_info.bios.cseg_16 << 4));
+- set_base(per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
++ set_base(cpu_gdt_table[i][APM_DS >> 3],
+ __va((unsigned long)apm_info.bios.dseg << 4));
+ #ifndef APM_RELAX_SEGMENTS
+ if (apm_info.bios.version == 0x100) {
+ #endif
+ /* For ASUS motherboard, Award BIOS rev 110 (and others?) */
+- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 - 1);
++ _set_limit((char *)&cpu_gdt_table[i][APM_CS >> 3], 64 * 1024 - 1);
+ /* For some unknown machine. */
+- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3], 64 * 1024 - 1);
++ _set_limit((char *)&cpu_gdt_table[i][APM_CS_16 >> 3], 64 * 1024 - 1);
+ /* For the DEC Hinote Ultra CT475 (and others?) */
+- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3], 64 * 1024 - 1);
++ _set_limit((char *)&cpu_gdt_table[i][APM_DS >> 3], 64 * 1024 - 1);
+ #ifndef APM_RELAX_SEGMENTS
+ } else {
+- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
++ _set_limit((char *)&cpu_gdt_table[i][APM_CS >> 3],
+ (apm_info.bios.cseg_len - 1) & 0xffff);
+- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
++ _set_limit((char *)&cpu_gdt_table[i][APM_CS_16 >> 3],
+ (apm_info.bios.cseg_16_len - 1) & 0xffff);
+- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
++ _set_limit((char *)&cpu_gdt_table[i][APM_DS >> 3],
+ (apm_info.bios.dseg_len - 1) & 0xffff);
+ /* workaround for broken BIOSes */
+ if (apm_info.bios.cseg_len <= apm_info.bios.offset)
+- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 -1);
++ _set_limit((char *)&cpu_gdt_table[i][APM_CS >> 3], 64 * 1024 -1);
+ if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
+ /* for the BIOS that assumes granularity = 1 */
+- per_cpu(cpu_gdt_table, i)[APM_DS >> 3].b |= 0x800000;
++ cpu_gdt_table[i][APM_DS >> 3].b |= 0x800000;
+ printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
+ }
+ }
+diff -urNp linux-2.6.14.6/arch/i386/kernel/cpu/common.c linux-2.6.14.6/arch/i386/kernel/cpu/common.c
+--- linux-2.6.14.6/arch/i386/kernel/cpu/common.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/kernel/cpu/common.c 2006-01-09 00:40:49.000000000 -0500
+@@ -18,8 +18,7 @@
+
+ #include "cpu.h"
+
+-DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
+-EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
++EXPORT_SYMBOL_GPL(cpu_gdt_table);
+
+ DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
+ EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
+@@ -376,6 +375,10 @@ void __devinit identify_cpu(struct cpuin
+ if (this_cpu->c_init)
+ this_cpu->c_init(c);
+
++#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_NOVSYSCALL)
++ clear_bit(X86_FEATURE_SEP, c->x86_capability);
++#endif
++
+ /* Disable the PN if appropriate */
+ squash_the_stupid_serial_number(c);
+
+@@ -571,7 +574,7 @@ void __init early_cpu_init(void)
+ void __devinit cpu_init(void)
+ {
+ int cpu = smp_processor_id();
+- struct tss_struct * t = &per_cpu(init_tss, cpu);
++ struct tss_struct * t = init_tss + cpu;
+ struct thread_struct *thread = ¤t->thread;
+ __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
+
+@@ -594,24 +597,22 @@ void __devinit cpu_init(void)
+ * Initialize the per-CPU GDT with the boot GDT,
+ * and set up the GDT descriptor:
+ */
+- memcpy(&per_cpu(cpu_gdt_table, cpu), cpu_gdt_table,
+- GDT_SIZE);
++ if (cpu)
++ memcpy(cpu_gdt_table[cpu], cpu_gdt_table[0], GDT_SIZE);
+
+ /* Set up GDT entry for 16bit stack */
+- *(__u64 *)&(per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_ESPFIX_SS]) |=
++ *(__u64 *)&(cpu_gdt_table[cpu][GDT_ENTRY_ESPFIX_SS]) |=
+ ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) |
+ ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
+ (CPU_16BIT_STACK_SIZE - 1);
+
+ cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
+- cpu_gdt_descr[cpu].address =
+- (unsigned long)&per_cpu(cpu_gdt_table, cpu);
++ cpu_gdt_descr[cpu].address = (unsigned long)cpu_gdt_table[cpu];
+
+ /*
+ * Set up the per-thread TLS descriptor cache:
+ */
+- memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu),
+- GDT_ENTRY_TLS_ENTRIES * 8);
++ memcpy(thread->tls_array, cpu_gdt_table[cpu], GDT_ENTRY_TLS_ENTRIES * 8);
+
+ load_gdt(&cpu_gdt_descr[cpu]);
+ load_idt(&idt_descr);
+@@ -633,7 +634,7 @@ void __devinit cpu_init(void)
+ load_esp0(t, thread);
+ set_tss_desc(cpu,t);
+ load_TR_desc();
+- load_LDT(&init_mm.context);
++ _load_LDT(&init_mm.context);
+
+ /* Set up doublefault TSS pointer in the GDT */
+ __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
+diff -urNp linux-2.6.14.6/arch/i386/kernel/cpu/mtrr/if.c linux-2.6.14.6/arch/i386/kernel/cpu/mtrr/if.c
+--- linux-2.6.14.6/arch/i386/kernel/cpu/mtrr/if.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/kernel/cpu/mtrr/if.c 2006-01-09 00:40:49.000000000 -0500
+@@ -105,7 +105,7 @@ mtrr_write(struct file *file, const char
+ if (!len)
+ return -EINVAL;
+ memset(line, 0, LINE_SIZE);
+- if (len > LINE_SIZE)
++ if (!len || len > LINE_SIZE)
+ len = LINE_SIZE;
+ if (copy_from_user(line, buf, len - 1))
+ return -EFAULT;
+diff -urNp linux-2.6.14.6/arch/i386/kernel/doublefault.c linux-2.6.14.6/arch/i386/kernel/doublefault.c
+--- linux-2.6.14.6/arch/i386/kernel/doublefault.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/kernel/doublefault.c 2006-01-09 00:40:49.000000000 -0500
+@@ -11,7 +11,7 @@
+
+ #define DOUBLEFAULT_STACKSIZE (1024)
+ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
+-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
+
+ #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
+
+diff -urNp linux-2.6.14.6/arch/i386/kernel/efi.c linux-2.6.14.6/arch/i386/kernel/efi.c
+--- linux-2.6.14.6/arch/i386/kernel/efi.c 2005-12-26 19:26:33.000000000 -0500
++++ linux-2.6.14.6/arch/i386/kernel/efi.c 2006-01-09 00:40:49.000000000 -0500
+@@ -64,78 +64,59 @@ extern void * boot_ioremap(unsigned long
+
+ static unsigned long efi_rt_eflags;
+ static DEFINE_SPINLOCK(efi_rt_lock);
+-static pgd_t efi_bak_pg_dir_pointer[2];
++static pgd_t __initdata efi_bak_pg_dir_pointer[4];
+
+-static void efi_call_phys_prelog(void)
++static void __init efi_call_phys_prelog(void)
+ {
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list