SOURCES (LINUX_2_6_11): grsecurity-2.1.6-2.6.11.12-200506141713.pa...

pluto pluto at pld-linux.org
Sun Jun 26 13:53:19 CEST 2005


Author: pluto                        Date: Sun Jun 26 11:53:19 2005 GMT
Module: SOURCES                       Tag: LINUX_2_6_11
---- Log message:
- new version (reworked).

---- Files affected:
SOURCES:
   grsecurity-2.1.6-2.6.11.12-200506141713.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/grsecurity-2.1.6-2.6.11.12-200506141713.patch
diff -u /dev/null SOURCES/grsecurity-2.1.6-2.6.11.12-200506141713.patch:1.1.2.1
--- /dev/null	Sun Jun 26 13:53:19 2005
+++ SOURCES/grsecurity-2.1.6-2.6.11.12-200506141713.patch	Sun Jun 26 13:53:14 2005
@@ -0,0 +1,23451 @@
+diff -urNp linux-2.6.11.12/Makefile linux-2.6.11.12/Makefile
+--- linux-2.6.11.12/Makefile	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/Makefile	2005-06-14 10:54:08.000000000 -0400
+@@ -561,7 +561,7 @@ export MODLIB
+ 
+ 
+ ifeq ($(KBUILD_EXTMOD),)
+-core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/
++core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ grsecurity/
+ 
+ vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
+ 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
+diff -urNp linux-2.6.11.12/arch/alpha/kernel/osf_sys.c linux-2.6.11.12/arch/alpha/kernel/osf_sys.c
+--- linux-2.6.11.12/arch/alpha/kernel/osf_sys.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/alpha/kernel/osf_sys.c	2005-06-14 10:54:08.000000000 -0400
+@@ -179,6 +179,11 @@ osf_mmap(unsigned long addr, unsigned lo
+ 	struct file *file = NULL;
+ 	unsigned long ret = -EBADF;
+ 
++#ifdef CONFIG_PAX_RANDEXEC
++	if (flags & MAP_MIRROR)
++		return -EINVAL;
++#endif
++
+ #if 0
+ 	if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
+ 		printk("%s: unimplemented OSF mmap flags %04lx\n", 
+@@ -1288,6 +1293,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->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 +1304,16 @@ 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 = TASK_UNMAPPED_BASE;
++
++#ifdef CONFIG_PAX_RANDMMAP
++	if (current->mm->flags & MF_PAX_RANDMMAP)
++		addr += current->mm->delta_mmap;
++#endif
++
++	addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
++
+ 	if (addr != (unsigned long) -ENOMEM)
+ 		return addr;
+ 
+diff -urNp linux-2.6.11.12/arch/alpha/kernel/ptrace.c linux-2.6.11.12/arch/alpha/kernel/ptrace.c
+--- linux-2.6.11.12/arch/alpha/kernel/ptrace.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/alpha/kernel/ptrace.c	2005-06-14 10:54:08.000000000 -0400
+@@ -14,6 +14,7 @@
+ #include <linux/user.h>
+ #include <linux/slab.h>
+ #include <linux/security.h>
++#include <linux/grsecurity.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -289,6 +290,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.11.12/arch/alpha/mm/fault.c linux-2.6.11.12/arch/alpha/mm/fault.c
+--- linux-2.6.11.12/arch/alpha/mm/fault.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/alpha/mm/fault.c	2005-06-14 10:54:08.000000000 -0400
+@@ -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,142 @@ __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
++ *         4 when legitimate ET_EXEC was detected
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++
++#ifdef CONFIG_PAX_EMUPLT
++	int err;
++#endif
++
++#ifdef CONFIG_PAX_RANDEXEC
++	if (current->mm->flags & MF_PAX_RANDEXEC) {
++		if (regs->pc >= current->mm->start_code &&
++		    regs->pc < current->mm->end_code)
++		{
++			if (regs->r26 == regs->pc)
++				return 1;
++
++			regs->pc += current->mm->delta_exec;
++			return 4;
++		}
++	}
++#endif
++
++#ifdef CONFIG_PAX_EMUPLT
++	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("<invalid address>.");
++			break;
++		}
++		printk("%08x ", c);
++	}
++	printk("\n");
++}
++#endif
+ 
+ /*
+  * This routine handles page faults.  It determines the address,
+@@ -125,7 +262,7 @@ do_page_fault(unsigned long address, uns
+ 		goto good_area;
+ 	if (!(vma->vm_flags & VM_GROWSDOWN))
+ 		goto bad_area;
+-	if (expand_stack(vma, address))
++	if (expand_stack(current, vma, address))
+ 		goto bad_area;
+ 
+ 	/* Ok, we have a good vm_area for this memory access, so
+@@ -133,8 +270,34 @@ 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->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
++
++#ifdef CONFIG_PAX_RANDEXEC
++			case 4:
++				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.11.12/arch/arm/mm/fault.c linux-2.6.11.12/arch/arm/mm/fault.c
+--- linux-2.6.11.12/arch/arm/mm/fault.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/arm/mm/fault.c	2005-06-14 10:54:08.000000000 -0400
+@@ -208,7 +208,7 @@ survive:
+ 	goto survive;
+ 
+ check_stack:
+-	if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
++	if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(tsk, vma, addr))
+ 		goto good_area;
+ out:
+ 	return fault;
+diff -urNp linux-2.6.11.12/arch/arm/mm/mmap.c linux-2.6.11.12/arch/arm/mm/mmap.c
+--- linux-2.6.11.12/arch/arm/mm/mmap.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/arm/mm/mmap.c	2005-06-14 10:54:08.000000000 -0400
+@@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
+ 	if (len > TASK_SIZE)
+ 		return -ENOMEM;
+ 
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(mm->flags & MF_PAX_RANDMMAP) || !filp)
++#endif
++
+ 	if (addr) {
+ 		if (do_align)
+ 			addr = COLOUR_ALIGN(addr, pgoff);
+@@ -88,8 +92,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;
+ 				goto full_search;
+ 			}
+ 			return -ENOMEM;
+diff -urNp linux-2.6.11.12/arch/arm26/mm/fault.c linux-2.6.11.12/arch/arm26/mm/fault.c
+--- linux-2.6.11.12/arch/arm26/mm/fault.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/arm26/mm/fault.c	2005-06-14 10:54:08.000000000 -0400
+@@ -197,7 +197,7 @@ survive:
+ 	goto survive;
+ 
+ check_stack:
+-	if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
++	if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(tsk, vma, addr))
+ 		goto good_area;
+ out:
+ 	return fault;
+diff -urNp linux-2.6.11.12/arch/cris/mm/fault.c linux-2.6.11.12/arch/cris/mm/fault.c
+--- linux-2.6.11.12/arch/cris/mm/fault.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/cris/mm/fault.c	2005-06-14 10:54:08.000000000 -0400
+@@ -207,7 +207,7 @@ do_page_fault(unsigned long address, str
+ 		if (address + PAGE_SIZE < rdusp())
+ 			goto bad_area;
+ 	}
+-	if (expand_stack(vma, address))
++	if (expand_stack(tsk, vma, address))
+ 		goto bad_area;
+ 
+ 	/*
+diff -urNp linux-2.6.11.12/arch/i386/Kconfig linux-2.6.11.12/arch/i386/Kconfig
+--- linux-2.6.11.12/arch/i386/Kconfig	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/i386/Kconfig	2005-06-14 10:54:08.000000000 -0400
+@@ -409,7 +409,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
++	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
+ 	default y
+ 
+ config X86_GOOD_APIC
+diff -urNp linux-2.6.11.12/arch/i386/kernel/apm.c linux-2.6.11.12/arch/i386/kernel/apm.c
+--- linux-2.6.11.12/arch/i386/kernel/apm.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/i386/kernel/apm.c	2005-06-14 10:54:08.000000000 -0400
+@@ -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		cr3;
++#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, cr3);
++#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, cr3);
++#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		cr3;
++#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, cr3);
++#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, cr3);
++#endif
++
+ 	put_cpu();
+ 	apm_restore_cpus(cpus);
+ 	return error;
+@@ -2294,35 +2333,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.11.12/arch/i386/kernel/cpu/common.c linux-2.6.11.12/arch/i386/kernel/cpu/common.c
+--- linux-2.6.11.12/arch/i386/kernel/cpu/common.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/i386/kernel/cpu/common.c	2005-06-14 10:54:08.000000000 -0400
+@@ -3,7 +3,6 @@
+ #include <linux/delay.h>
+ #include <linux/smp.h>
+ #include <linux/module.h>
+-#include <linux/percpu.h>
+ #include <asm/semaphore.h>
+ #include <asm/processor.h>
+ #include <asm/i387.h>
+@@ -18,8 +17,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);
+ 
+ static int cachesize_override __initdata = -1;
+ static int disable_x86_fxsr __initdata = 0;
+@@ -369,6 +367,10 @@ void __init identify_cpu(struct cpuinfo_
+ 	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);
+ 
+@@ -555,7 +557,7 @@ void __init early_cpu_init(void)
+ void __init 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 = &current->thread;
+ 
+ 	if (cpu_test_and_set(cpu, cpu_initialized)) {
+@@ -582,8 +584,8 @@
+ 	 * 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 *)&(cpu_gdt_table[cpu][GDT_ENTRY_ESPFIX_SS]) |=
+@@ -593,13 +595,13 @@
+ 
+ 	cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
+ 	cpu_gdt_descr[cpu].address =
+-	    (unsigned long)&per_cpu(cpu_gdt_table, cpu);
++	    (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);
+ 
+ 	__asm__ __volatile__("lgdt %0" : : "m" (cpu_gdt_descr[cpu]));
+ 	__asm__ __volatile__("lidt %0" : : "m" (idt_descr));
+@@ -609,7 +610,7 @@ void __init 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.11.12/arch/i386/kernel/cpu/mtrr/if.c linux-2.6.11.12/arch/i386/kernel/cpu/mtrr/if.c
+--- linux-2.6.11.12/arch/i386/kernel/cpu/mtrr/if.c	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/i386/kernel/cpu/mtrr/if.c	2005-06-14 10:54:08.000000000 -0400
+@@ -102,7 +102,7 @@ mtrr_write(struct file *file, const char
+ 	if (!capable(CAP_SYS_ADMIN))
+ 		return -EPERM;
+ 	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.11.12/arch/i386/kernel/entry.S linux-2.6.11.12/arch/i386/kernel/entry.S
+--- linux-2.6.11.12/arch/i386/kernel/entry.S	2005-06-11 22:45:37.000000000 -0400
++++ linux-2.6.11.12/arch/i386/kernel/entry.S	2005-06-14 10:54:08.000000000 -0400
+@@ -229,6 +229,15 @@ sysenter_past_esp:
+ 	movl TI_flags(%ebp), %ecx
+ 	testw $_TIF_ALLWORK_MASK, %cx
+ 	jne syscall_exit_work
++
++#ifdef CONFIG_PAX_RANDKSTACK
++	pushl %eax
++	call pax_randomize_kstack
++	popl %eax
++#endif
<<Diff was trimmed, longer than 597 lines>>



More information about the pld-cvs-commit mailing list