10 diff -urNp linux-2.6.27.10/arch/alpha/include/asm/elf.h linux-2.6.27.10/arch/alpha/include/asm/elf.h
11 --- linux-2.6.27.10/arch/alpha/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
12 +++ linux-2.6.27.10/arch/alpha/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
13 @@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
15 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
17 +#ifdef CONFIG_PAX_ASLR
18 +#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
20 +#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
21 +#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
24 /* $0 is set by ld.so to a pointer to a function which might be
25 registered using atexit. This provides a mean for the dynamic
26 linker to call DT_FINI functions for shared libraries that have
27 diff -urNp linux-2.6.27.10/arch/alpha/include/asm/kmap_types.h linux-2.6.27.10/arch/alpha/include/asm/kmap_types.h
28 --- linux-2.6.27.10/arch/alpha/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
29 +++ linux-2.6.27.10/arch/alpha/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
30 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
40 diff -urNp linux-2.6.27.10/arch/alpha/include/asm/pgtable.h linux-2.6.27.10/arch/alpha/include/asm/pgtable.h
41 --- linux-2.6.27.10/arch/alpha/include/asm/pgtable.h 2008-11-07 12:55:34.000000000 -0500
42 +++ linux-2.6.27.10/arch/alpha/include/asm/pgtable.h 2008-11-18 03:39:50.000000000 -0500
43 @@ -101,6 +101,17 @@ struct vm_area_struct;
44 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
45 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
46 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
48 +#ifdef CONFIG_PAX_PAGEEXEC
49 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
50 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
51 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
53 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
54 +# define PAGE_COPY_NOEXEC PAGE_COPY
55 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
58 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
60 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
61 diff -urNp linux-2.6.27.10/arch/alpha/kernel/module.c linux-2.6.27.10/arch/alpha/kernel/module.c
62 --- linux-2.6.27.10/arch/alpha/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
63 +++ linux-2.6.27.10/arch/alpha/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
64 @@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
66 /* The small sections were sorted to the end of the segment.
67 The following should definitely cover them. */
68 - gp = (u64)me->module_core + me->core_size - 0x8000;
69 + gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
70 got = sechdrs[me->arch.gotsecindex].sh_addr;
72 for (i = 0; i < n; i++) {
73 diff -urNp linux-2.6.27.10/arch/alpha/kernel/osf_sys.c linux-2.6.27.10/arch/alpha/kernel/osf_sys.c
74 --- linux-2.6.27.10/arch/alpha/kernel/osf_sys.c 2008-11-07 12:55:34.000000000 -0500
75 +++ linux-2.6.27.10/arch/alpha/kernel/osf_sys.c 2008-11-18 03:38:43.000000000 -0500
76 @@ -1232,6 +1232,10 @@ arch_get_unmapped_area(struct file *filp
77 merely specific addresses, but regions of memory -- perhaps
78 this feature should be incorporated into all ports? */
80 +#ifdef CONFIG_PAX_RANDMMAP
81 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
85 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
86 if (addr != (unsigned long) -ENOMEM)
87 @@ -1239,8 +1243,8 @@ arch_get_unmapped_area(struct file *filp
90 /* Next, try allocating at TASK_UNMAPPED_BASE. */
91 - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
93 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
95 if (addr != (unsigned long) -ENOMEM)
98 diff -urNp linux-2.6.27.10/arch/alpha/kernel/ptrace.c linux-2.6.27.10/arch/alpha/kernel/ptrace.c
99 --- linux-2.6.27.10/arch/alpha/kernel/ptrace.c 2008-11-07 12:55:34.000000000 -0500
100 +++ linux-2.6.27.10/arch/alpha/kernel/ptrace.c 2008-11-18 03:38:43.000000000 -0500
102 #include <linux/security.h>
103 #include <linux/signal.h>
104 #include <linux/vs_base.h>
105 +#include <linux/grsecurity.h>
107 #include <asm/uaccess.h>
108 #include <asm/pgtable.h>
109 @@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
113 + if (gr_handle_ptrace(child, request))
117 /* When I and D space are separate, these will need to be fixed. */
118 case PTRACE_PEEKTEXT: /* read word at location addr. */
119 diff -urNp linux-2.6.27.10/arch/alpha/mm/fault.c linux-2.6.27.10/arch/alpha/mm/fault.c
120 --- linux-2.6.27.10/arch/alpha/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
121 +++ linux-2.6.27.10/arch/alpha/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
122 @@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
123 __reload_thread(pcb);
126 +#ifdef CONFIG_PAX_PAGEEXEC
128 + * PaX: decide what to do with offenders (regs->pc = fault address)
130 + * returns 1 when task should be killed
131 + * 2 when patched PLT trampoline was detected
132 + * 3 when unpatched PLT trampoline was detected
134 +static int pax_handle_fetch_fault(struct pt_regs *regs)
137 +#ifdef CONFIG_PAX_EMUPLT
140 + do { /* PaX: patched PLT emulation #1 */
141 + unsigned int ldah, ldq, jmp;
143 + err = get_user(ldah, (unsigned int *)regs->pc);
144 + err |= get_user(ldq, (unsigned int *)(regs->pc+4));
145 + err |= get_user(jmp, (unsigned int *)(regs->pc+8));
150 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
151 + (ldq & 0xFFFF0000U) == 0xA77B0000U &&
152 + jmp == 0x6BFB0000U)
154 + unsigned long r27, addr;
155 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
156 + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
158 + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
159 + err = get_user(r27, (unsigned long *)addr);
169 + do { /* PaX: patched PLT emulation #2 */
170 + unsigned int ldah, lda, br;
172 + err = get_user(ldah, (unsigned int *)regs->pc);
173 + err |= get_user(lda, (unsigned int *)(regs->pc+4));
174 + err |= get_user(br, (unsigned int *)(regs->pc+8));
179 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
180 + (lda & 0xFFFF0000U) == 0xA77B0000U &&
181 + (br & 0xFFE00000U) == 0xC3E00000U)
183 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
184 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
185 + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
187 + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
188 + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
193 + do { /* PaX: unpatched PLT emulation */
196 + err = get_user(br, (unsigned int *)regs->pc);
198 + if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
199 + unsigned int br2, ldq, nop, jmp;
200 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
202 + addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
203 + err = get_user(br2, (unsigned int *)addr);
204 + err |= get_user(ldq, (unsigned int *)(addr+4));
205 + err |= get_user(nop, (unsigned int *)(addr+8));
206 + err |= get_user(jmp, (unsigned int *)(addr+12));
207 + err |= get_user(resolver, (unsigned long *)(addr+16));
212 + if (br2 == 0xC3600000U &&
213 + ldq == 0xA77B000CU &&
214 + nop == 0x47FF041FU &&
215 + jmp == 0x6B7B0000U)
217 + regs->r28 = regs->pc+4;
218 + regs->r27 = addr+16;
219 + regs->pc = resolver;
229 +void pax_report_insns(void *pc, void *sp)
233 + printk(KERN_ERR "PAX: bytes at PC: ");
234 + for (i = 0; i < 5; i++) {
236 + if (get_user(c, (unsigned int *)pc+i))
237 + printk(KERN_CONT "???????? ");
239 + printk(KERN_CONT "%08x ", c);
246 * This routine handles page faults. It determines the address,
247 @@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
249 si_code = SEGV_ACCERR;
251 - if (!(vma->vm_flags & VM_EXEC))
252 + if (!(vma->vm_flags & VM_EXEC)) {
254 +#ifdef CONFIG_PAX_PAGEEXEC
255 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
258 + up_read(&mm->mmap_sem);
259 + switch (pax_handle_fetch_fault(regs)) {
261 +#ifdef CONFIG_PAX_EMUPLT
268 + pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
269 + do_group_exit(SIGKILL);
276 /* Allow reads even for write-only mappings */
277 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
278 diff -urNp linux-2.6.27.10/arch/arm/include/asm/elf.h linux-2.6.27.10/arch/arm/include/asm/elf.h
279 --- linux-2.6.27.10/arch/arm/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
280 +++ linux-2.6.27.10/arch/arm/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
281 @@ -87,7 +87,14 @@ extern char elf_platform[];
282 the loader. We need to make sure that it is out of the way of the program
283 that it will "exec", and that there is sufficient room for the brk. */
285 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
286 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
288 +#ifdef CONFIG_PAX_ASLR
289 +#define PAX_ELF_ET_DYN_BASE 0x00008000UL
291 +#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
292 +#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
295 /* When the program starts, a1 contains a pointer to a function to be
296 registered with atexit, as per the SVR4 ABI. A value of 0 means we
297 diff -urNp linux-2.6.27.10/arch/arm/include/asm/kmap_types.h linux-2.6.27.10/arch/arm/include/asm/kmap_types.h
298 --- linux-2.6.27.10/arch/arm/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
299 +++ linux-2.6.27.10/arch/arm/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
300 @@ -18,6 +18,7 @@ enum km_type {
308 diff -urNp linux-2.6.27.10/arch/arm/mm/mmap.c linux-2.6.27.10/arch/arm/mm/mmap.c
309 --- linux-2.6.27.10/arch/arm/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
310 +++ linux-2.6.27.10/arch/arm/mm/mmap.c 2008-11-18 03:38:43.000000000 -0500
311 @@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
315 +#ifdef CONFIG_PAX_RANDMMAP
316 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
321 addr = COLOUR_ALIGN(addr, pgoff);
322 @@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
325 if (len > mm->cached_hole_size) {
326 - start_addr = addr = mm->free_area_cache;
327 + start_addr = addr = mm->free_area_cache;
329 - start_addr = addr = TASK_UNMAPPED_BASE;
330 - mm->cached_hole_size = 0;
331 + start_addr = addr = mm->mmap_base;
332 + mm->cached_hole_size = 0;
336 @@ -91,8 +95,8 @@ full_search:
337 * Start a new search - just in case we missed
340 - if (start_addr != TASK_UNMAPPED_BASE) {
341 - start_addr = addr = TASK_UNMAPPED_BASE;
342 + if (start_addr != mm->mmap_base) {
343 + start_addr = addr = mm->mmap_base;
344 mm->cached_hole_size = 0;
347 diff -urNp linux-2.6.27.10/arch/avr32/include/asm/elf.h linux-2.6.27.10/arch/avr32/include/asm/elf.h
348 --- linux-2.6.27.10/arch/avr32/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
349 +++ linux-2.6.27.10/arch/avr32/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
350 @@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
351 the loader. We need to make sure that it is out of the way of the program
352 that it will "exec", and that there is sufficient room for the brk. */
354 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
355 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
357 +#ifdef CONFIG_PAX_ASLR
358 +#define PAX_ELF_ET_DYN_BASE 0x00001000UL
360 +#define PAX_DELTA_MMAP_LEN 15
361 +#define PAX_DELTA_STACK_LEN 15
364 /* This yields a mask that user programs can use to figure out what
365 instruction set this CPU supports. This could be done in user space,
366 diff -urNp linux-2.6.27.10/arch/avr32/include/asm/kmap_types.h linux-2.6.27.10/arch/avr32/include/asm/kmap_types.h
367 --- linux-2.6.27.10/arch/avr32/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
368 +++ linux-2.6.27.10/arch/avr32/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
369 @@ -22,7 +22,8 @@ D(10) KM_IRQ0,
379 diff -urNp linux-2.6.27.10/arch/avr32/mm/fault.c linux-2.6.27.10/arch/avr32/mm/fault.c
380 --- linux-2.6.27.10/arch/avr32/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
381 +++ linux-2.6.27.10/arch/avr32/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
382 @@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
384 int exception_trace = 1;
386 +#ifdef CONFIG_PAX_PAGEEXEC
387 +void pax_report_insns(void *pc, void *sp)
391 + printk(KERN_ERR "PAX: bytes at PC: ");
392 + for (i = 0; i < 20; i++) {
394 + if (get_user(c, (unsigned char *)pc+i))
395 + printk(KERN_CONT "???????? ");
397 + printk(KERN_CONT "%02x ", c);
404 * This routine handles page faults. It determines the address and the
405 * problem, and then passes it off to one of the appropriate routines.
406 @@ -157,6 +174,16 @@ bad_area:
407 up_read(&mm->mmap_sem);
409 if (user_mode(regs)) {
411 +#ifdef CONFIG_PAX_PAGEEXEC
412 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
413 + if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
414 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
415 + do_group_exit(SIGKILL);
420 if (exception_trace && printk_ratelimit())
421 printk("%s%s[%d]: segfault at %08lx pc %08lx "
422 "sp %08lx ecr %lu\n",
423 diff -urNp linux-2.6.27.10/arch/blackfin/include/asm/kmap_types.h linux-2.6.27.10/arch/blackfin/include/asm/kmap_types.h
424 --- linux-2.6.27.10/arch/blackfin/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
425 +++ linux-2.6.27.10/arch/blackfin/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
426 @@ -15,6 +15,7 @@ enum km_type {
434 diff -urNp linux-2.6.27.10/arch/h8300/include/asm/kmap_types.h linux-2.6.27.10/arch/h8300/include/asm/kmap_types.h
435 --- linux-2.6.27.10/arch/h8300/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
436 +++ linux-2.6.27.10/arch/h8300/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
437 @@ -15,6 +15,7 @@ enum km_type {
445 diff -urNp linux-2.6.27.10/arch/ia64/ia32/binfmt_elf32.c linux-2.6.27.10/arch/ia64/ia32/binfmt_elf32.c
446 --- linux-2.6.27.10/arch/ia64/ia32/binfmt_elf32.c 2008-11-07 12:55:34.000000000 -0500
447 +++ linux-2.6.27.10/arch/ia64/ia32/binfmt_elf32.c 2008-11-18 03:38:43.000000000 -0500
448 @@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
450 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
452 +#ifdef CONFIG_PAX_ASLR
453 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
455 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
456 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
459 /* Ugly but avoids duplication */
460 #include "../../../fs/binfmt_elf.c"
462 diff -urNp linux-2.6.27.10/arch/ia64/ia32/ia32priv.h linux-2.6.27.10/arch/ia64/ia32/ia32priv.h
463 --- linux-2.6.27.10/arch/ia64/ia32/ia32priv.h 2008-11-07 12:55:34.000000000 -0500
464 +++ linux-2.6.27.10/arch/ia64/ia32/ia32priv.h 2008-11-18 03:38:43.000000000 -0500
465 @@ -296,7 +296,14 @@ typedef struct compat_siginfo {
466 #define ELF_DATA ELFDATA2LSB
467 #define ELF_ARCH EM_386
469 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
470 +#ifdef CONFIG_PAX_RANDUSTACK
471 +#define __IA32_DELTA_STACK (current->mm->delta_stack)
473 +#define __IA32_DELTA_STACK 0UL
476 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
478 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
479 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
481 diff -urNp linux-2.6.27.10/arch/ia64/include/asm/elf.h linux-2.6.27.10/arch/ia64/include/asm/elf.h
482 --- linux-2.6.27.10/arch/ia64/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
483 +++ linux-2.6.27.10/arch/ia64/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
486 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
488 +#ifdef CONFIG_PAX_ASLR
489 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
491 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
492 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
495 #define PT_IA_64_UNWIND 0x70000001
497 /* IA-64 relocations: */
498 diff -urNp linux-2.6.27.10/arch/ia64/include/asm/kmap_types.h linux-2.6.27.10/arch/ia64/include/asm/kmap_types.h
499 --- linux-2.6.27.10/arch/ia64/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
500 +++ linux-2.6.27.10/arch/ia64/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
501 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
511 diff -urNp linux-2.6.27.10/arch/ia64/include/asm/pgtable.h linux-2.6.27.10/arch/ia64/include/asm/pgtable.h
512 --- linux-2.6.27.10/arch/ia64/include/asm/pgtable.h 2008-11-07 12:55:34.000000000 -0500
513 +++ linux-2.6.27.10/arch/ia64/include/asm/pgtable.h 2008-11-18 03:39:50.000000000 -0500
515 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
516 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
517 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
519 +#ifdef CONFIG_PAX_PAGEEXEC
520 +# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
521 +# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
522 +# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
524 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
525 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
526 +# define PAGE_COPY_NOEXEC PAGE_COPY
529 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
530 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
531 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
532 diff -urNp linux-2.6.27.10/arch/ia64/kernel/module.c linux-2.6.27.10/arch/ia64/kernel/module.c
533 --- linux-2.6.27.10/arch/ia64/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
534 +++ linux-2.6.27.10/arch/ia64/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
535 @@ -312,8 +312,7 @@ module_alloc (unsigned long size)
537 module_free (struct module *mod, void *module_region)
539 - if (mod && mod->arch.init_unw_table &&
540 - module_region == mod->module_init) {
541 + if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
542 unw_remove_unwind_table(mod->arch.init_unw_table);
543 mod->arch.init_unw_table = NULL;
545 @@ -491,15 +490,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
549 +in_init_rx (const struct module *mod, uint64_t addr)
551 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
555 +in_init_rw (const struct module *mod, uint64_t addr)
557 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
561 in_init (const struct module *mod, uint64_t addr)
563 - return addr - (uint64_t) mod->module_init < mod->init_size;
564 + return in_init_rx(mod, addr) || in_init_rw(mod, addr);
568 +in_core_rx (const struct module *mod, uint64_t addr)
570 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
574 +in_core_rw (const struct module *mod, uint64_t addr)
576 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
580 in_core (const struct module *mod, uint64_t addr)
582 - return addr - (uint64_t) mod->module_core < mod->core_size;
583 + return in_core_rx(mod, addr) || in_core_rw(mod, addr);
587 @@ -683,7 +706,14 @@ do_reloc (struct module *mod, uint8_t r_
591 - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
592 + if (in_init_rx(mod, val))
593 + val -= (uint64_t) mod->module_init_rx;
594 + else if (in_init_rw(mod, val))
595 + val -= (uint64_t) mod->module_init_rw;
596 + else if (in_core_rx(mod, val))
597 + val -= (uint64_t) mod->module_core_rx;
598 + else if (in_core_rw(mod, val))
599 + val -= (uint64_t) mod->module_core_rw;
603 @@ -817,15 +847,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
604 * addresses have been selected...
607 - if (mod->core_size > MAX_LTOFF)
608 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
610 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
611 * at the end of the module.
613 - gp = mod->core_size - MAX_LTOFF / 2;
614 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
616 - gp = mod->core_size / 2;
617 - gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
618 + gp = (mod->core_size_rx + mod->core_size_rw) / 2;
619 + gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
621 DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
623 diff -urNp linux-2.6.27.10/arch/ia64/kernel/sys_ia64.c linux-2.6.27.10/arch/ia64/kernel/sys_ia64.c
624 --- linux-2.6.27.10/arch/ia64/kernel/sys_ia64.c 2008-11-07 12:55:34.000000000 -0500
625 +++ linux-2.6.27.10/arch/ia64/kernel/sys_ia64.c 2008-11-18 03:38:43.000000000 -0500
626 @@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
627 if (REGION_NUMBER(addr) == RGN_HPAGE)
631 +#ifdef CONFIG_PAX_RANDMMAP
632 + if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
633 + addr = mm->free_area_cache;
638 addr = mm->free_area_cache;
640 @@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
641 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
642 /* At this point: (!vma || addr < vma->vm_end). */
643 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
644 - if (start_addr != TASK_UNMAPPED_BASE) {
645 + if (start_addr != mm->mmap_base) {
646 /* Start a new search --- just in case we missed some holes. */
647 - addr = TASK_UNMAPPED_BASE;
648 + addr = mm->mmap_base;
652 diff -urNp linux-2.6.27.10/arch/ia64/mm/fault.c linux-2.6.27.10/arch/ia64/mm/fault.c
653 --- linux-2.6.27.10/arch/ia64/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
654 +++ linux-2.6.27.10/arch/ia64/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
655 @@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
656 return pte_present(pte);
659 +#ifdef CONFIG_PAX_PAGEEXEC
660 +void pax_report_insns(void *pc, void *sp)
664 + printk(KERN_ERR "PAX: bytes at PC: ");
665 + for (i = 0; i < 8; i++) {
667 + if (get_user(c, (unsigned int *)pc+i))
668 + printk(KERN_CONT "???????? ");
670 + printk(KERN_CONT "%08x ", c);
677 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
679 @@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
680 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
681 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
683 - if ((vma->vm_flags & mask) != mask)
684 + if ((vma->vm_flags & mask) != mask) {
686 +#ifdef CONFIG_PAX_PAGEEXEC
687 + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
688 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
691 + up_read(&mm->mmap_sem);
692 + pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
693 + do_group_exit(SIGKILL);
703 * If for any reason at all we couldn't handle the fault, make
704 diff -urNp linux-2.6.27.10/arch/ia64/mm/init.c linux-2.6.27.10/arch/ia64/mm/init.c
705 --- linux-2.6.27.10/arch/ia64/mm/init.c 2008-11-07 12:55:34.000000000 -0500
706 +++ linux-2.6.27.10/arch/ia64/mm/init.c 2008-11-18 03:38:43.000000000 -0500
707 @@ -122,6 +122,19 @@ ia64_init_addr_space (void)
708 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
709 vma->vm_end = vma->vm_start + PAGE_SIZE;
710 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
712 +#ifdef CONFIG_PAX_PAGEEXEC
713 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
714 + vma->vm_flags &= ~VM_EXEC;
716 +#ifdef CONFIG_PAX_MPROTECT
717 + if (current->mm->pax_flags & MF_PAX_MPROTECT)
718 + vma->vm_flags &= ~VM_MAYEXEC;
724 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
725 down_write(¤t->mm->mmap_sem);
726 if (insert_vm_struct(current->mm, vma)) {
727 diff -urNp linux-2.6.27.10/arch/m68knommu/include/asm/kmap_types.h linux-2.6.27.10/arch/m68knommu/include/asm/kmap_types.h
728 --- linux-2.6.27.10/arch/m68knommu/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
729 +++ linux-2.6.27.10/arch/m68knommu/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
730 @@ -15,6 +15,7 @@ enum km_type {
738 diff -urNp linux-2.6.27.10/arch/mips/kernel/binfmt_elfn32.c linux-2.6.27.10/arch/mips/kernel/binfmt_elfn32.c
739 --- linux-2.6.27.10/arch/mips/kernel/binfmt_elfn32.c 2008-11-07 12:55:34.000000000 -0500
740 +++ linux-2.6.27.10/arch/mips/kernel/binfmt_elfn32.c 2008-11-18 03:38:43.000000000 -0500
741 @@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
742 #undef ELF_ET_DYN_BASE
743 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
745 +#ifdef CONFIG_PAX_ASLR
746 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
748 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
749 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
752 #include <asm/processor.h>
753 #include <linux/module.h>
754 #include <linux/elfcore.h>
755 diff -urNp linux-2.6.27.10/arch/mips/kernel/binfmt_elfo32.c linux-2.6.27.10/arch/mips/kernel/binfmt_elfo32.c
756 --- linux-2.6.27.10/arch/mips/kernel/binfmt_elfo32.c 2008-11-07 12:55:34.000000000 -0500
757 +++ linux-2.6.27.10/arch/mips/kernel/binfmt_elfo32.c 2008-11-18 03:38:43.000000000 -0500
758 @@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
759 #undef ELF_ET_DYN_BASE
760 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
762 +#ifdef CONFIG_PAX_ASLR
763 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
765 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
766 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
769 #include <asm/processor.h>
770 #include <linux/module.h>
771 #include <linux/elfcore.h>
772 diff -urNp linux-2.6.27.10/arch/mips/kernel/process.c linux-2.6.27.10/arch/mips/kernel/process.c
773 --- linux-2.6.27.10/arch/mips/kernel/process.c 2008-11-07 12:55:34.000000000 -0500
774 +++ linux-2.6.27.10/arch/mips/kernel/process.c 2008-11-18 03:38:43.000000000 -0500
775 @@ -458,15 +458,3 @@ unsigned long get_wchan(struct task_stru
781 - * Don't forget that the stack pointer must be aligned on a 8 bytes
782 - * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
784 -unsigned long arch_align_stack(unsigned long sp)
786 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
787 - sp -= get_random_int() & ~PAGE_MASK;
789 - return sp & ALMASK;
791 diff -urNp linux-2.6.27.10/arch/mips/kernel/syscall.c linux-2.6.27.10/arch/mips/kernel/syscall.c
792 --- linux-2.6.27.10/arch/mips/kernel/syscall.c 2008-11-07 12:55:34.000000000 -0500
793 +++ linux-2.6.27.10/arch/mips/kernel/syscall.c 2008-11-18 03:38:43.000000000 -0500
794 @@ -100,6 +100,11 @@ unsigned long arch_get_unmapped_area(str
796 if (filp || (flags & MAP_SHARED))
799 +#ifdef CONFIG_PAX_RANDMMAP
800 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
805 addr = COLOUR_ALIGN(addr, pgoff);
806 @@ -110,7 +115,7 @@ unsigned long arch_get_unmapped_area(str
807 (!vmm || addr + len <= vmm->vm_start))
810 - addr = TASK_UNMAPPED_BASE;
811 + addr = current->mm->mmap_base;
813 addr = COLOUR_ALIGN(addr, pgoff);
815 diff -urNp linux-2.6.27.10/arch/mips/mm/fault.c linux-2.6.27.10/arch/mips/mm/fault.c
816 --- linux-2.6.27.10/arch/mips/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
817 +++ linux-2.6.27.10/arch/mips/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
819 #include <asm/ptrace.h>
820 #include <asm/highmem.h> /* For VMALLOC_END */
822 +#ifdef CONFIG_PAX_PAGEEXEC
823 +void pax_report_insns(void *pc)
827 + printk(KERN_ERR "PAX: bytes at PC: ");
828 + for (i = 0; i < 5; i++) {
830 + if (get_user(c, (unsigned int *)pc+i))
831 + printk(KERN_CONT "???????? ");
833 + printk(KERN_CONT "%08x ", c);
840 * This routine handles page faults. It determines the address,
841 * and the problem, and then passes it off to one of the appropriate
842 diff -urNp linux-2.6.27.10/arch/parisc/kernel/module.c linux-2.6.27.10/arch/parisc/kernel/module.c
843 --- linux-2.6.27.10/arch/parisc/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
844 +++ linux-2.6.27.10/arch/parisc/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
847 /* three functions to determine where in the module core
848 * or init pieces the location is */
849 +static inline int in_init_rx(struct module *me, void *loc)
851 + return (loc >= me->module_init_rx &&
852 + loc < (me->module_init_rx + me->init_size_rx));
855 +static inline int in_init_rw(struct module *me, void *loc)
857 + return (loc >= me->module_init_rw &&
858 + loc < (me->module_init_rw + me->init_size_rw));
861 static inline int in_init(struct module *me, void *loc)
863 - return (loc >= me->module_init &&
864 - loc <= (me->module_init + me->init_size));
865 + return in_init_rx(me, loc) || in_init_rw(me, loc);
868 +static inline int in_core_rx(struct module *me, void *loc)
870 + return (loc >= me->module_core_rx &&
871 + loc < (me->module_core_rx + me->core_size_rx));
874 +static inline int in_core_rw(struct module *me, void *loc)
876 + return (loc >= me->module_core_rw &&
877 + loc < (me->module_core_rw + me->core_size_rw));
880 static inline int in_core(struct module *me, void *loc)
882 - return (loc >= me->module_core &&
883 - loc <= (me->module_core + me->core_size));
884 + return in_core_rx(me, loc) || in_core_rw(me, loc);
887 static inline int in_local(struct module *me, void *loc)
888 @@ -298,21 +320,21 @@ int module_frob_arch_sections(CONST Elf_
891 /* align things a bit */
892 - me->core_size = ALIGN(me->core_size, 16);
893 - me->arch.got_offset = me->core_size;
894 - me->core_size += gots * sizeof(struct got_entry);
896 - me->core_size = ALIGN(me->core_size, 16);
897 - me->arch.fdesc_offset = me->core_size;
898 - me->core_size += fdescs * sizeof(Elf_Fdesc);
900 - me->core_size = ALIGN(me->core_size, 16);
901 - me->arch.stub_offset = me->core_size;
902 - me->core_size += stubs * sizeof(struct stub_entry);
904 - me->init_size = ALIGN(me->init_size, 16);
905 - me->arch.init_stub_offset = me->init_size;
906 - me->init_size += init_stubs * sizeof(struct stub_entry);
907 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
908 + me->arch.got_offset = me->core_size_rw;
909 + me->core_size_rw += gots * sizeof(struct got_entry);
911 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
912 + me->arch.fdesc_offset = me->core_size_rw;
913 + me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
915 + me->core_size_rx = ALIGN(me->core_size_rx, 16);
916 + me->arch.stub_offset = me->core_size_rx;
917 + me->core_size_rx += stubs * sizeof(struct stub_entry);
919 + me->init_size_rx = ALIGN(me->init_size_rx, 16);
920 + me->arch.init_stub_offset = me->init_size_rx;
921 + me->init_size_rx += init_stubs * sizeof(struct stub_entry);
923 me->arch.got_max = gots;
924 me->arch.fdesc_max = fdescs;
925 @@ -332,7 +354,7 @@ static Elf64_Word get_got(struct module
929 - got = me->module_core + me->arch.got_offset;
930 + got = me->module_core_rw + me->arch.got_offset;
931 for (i = 0; got[i].addr; i++)
932 if (got[i].addr == value)
934 @@ -350,7 +372,7 @@ static Elf64_Word get_got(struct module
936 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
938 - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
939 + Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
942 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
943 @@ -368,7 +390,7 @@ static Elf_Addr get_fdesc(struct module
947 - fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
948 + fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
949 return (Elf_Addr)fdesc;
951 #endif /* CONFIG_64BIT */
952 @@ -388,12 +410,12 @@ static Elf_Addr get_stub(struct module *
954 i = me->arch.init_stub_count++;
955 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
956 - stub = me->module_init + me->arch.init_stub_offset +
957 + stub = me->module_init_rx + me->arch.init_stub_offset +
958 i * sizeof(struct stub_entry);
960 i = me->arch.stub_count++;
961 BUG_ON(me->arch.stub_count > me->arch.stub_max);
962 - stub = me->module_core + me->arch.stub_offset +
963 + stub = me->module_core_rx + me->arch.stub_offset +
964 i * sizeof(struct stub_entry);
967 @@ -761,7 +783,7 @@ register_unwind_table(struct module *me,
969 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
970 end = table + sechdrs[me->arch.unwind_section].sh_size;
971 - gp = (Elf_Addr)me->module_core + me->arch.got_offset;
972 + gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
974 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
975 me->arch.unwind_section, table, end, gp);
976 diff -urNp linux-2.6.27.10/arch/parisc/kernel/sys_parisc.c linux-2.6.27.10/arch/parisc/kernel/sys_parisc.c
977 --- linux-2.6.27.10/arch/parisc/kernel/sys_parisc.c 2008-11-07 12:55:34.000000000 -0500
978 +++ linux-2.6.27.10/arch/parisc/kernel/sys_parisc.c 2008-11-18 03:38:43.000000000 -0500
979 @@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
980 if (flags & MAP_FIXED)
983 - addr = TASK_UNMAPPED_BASE;
984 + addr = current->mm->mmap_base;
987 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
988 diff -urNp linux-2.6.27.10/arch/parisc/kernel/traps.c linux-2.6.27.10/arch/parisc/kernel/traps.c
989 --- linux-2.6.27.10/arch/parisc/kernel/traps.c 2008-12-10 22:35:36.000000000 -0500
990 +++ linux-2.6.27.10/arch/parisc/kernel/traps.c 2008-12-10 22:35:46.000000000 -0500
991 @@ -731,9 +731,7 @@ void handle_interruption(int code, struc
993 down_read(¤t->mm->mmap_sem);
994 vma = find_vma(current->mm,regs->iaoq[0]);
995 - if (vma && (regs->iaoq[0] >= vma->vm_start)
996 - && (vma->vm_flags & VM_EXEC)) {
998 + if (vma && (regs->iaoq[0] >= vma->vm_start)) {
999 fault_address = regs->iaoq[0];
1000 fault_space = regs->iasq[0];
1002 diff -urNp linux-2.6.27.10/arch/parisc/mm/fault.c linux-2.6.27.10/arch/parisc/mm/fault.c
1003 --- linux-2.6.27.10/arch/parisc/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
1004 +++ linux-2.6.27.10/arch/parisc/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
1006 #include <linux/sched.h>
1007 #include <linux/interrupt.h>
1008 #include <linux/module.h>
1009 +#include <linux/unistd.h>
1011 #include <asm/uaccess.h>
1012 #include <asm/traps.h>
1013 @@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
1014 static unsigned long
1015 parisc_acctyp(unsigned long code, unsigned int inst)
1017 - if (code == 6 || code == 16)
1018 + if (code == 6 || code == 7 || code == 16)
1021 switch (inst & 0xf0000000) {
1022 @@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
1026 +#ifdef CONFIG_PAX_PAGEEXEC
1028 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
1030 + * returns 1 when task should be killed
1031 + * 2 when rt_sigreturn trampoline was detected
1032 + * 3 when unpatched PLT trampoline was detected
1034 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1037 +#ifdef CONFIG_PAX_EMUPLT
1040 + do { /* PaX: unpatched PLT emulation */
1041 + unsigned int bl, depwi;
1043 + err = get_user(bl, (unsigned int *)instruction_pointer(regs));
1044 + err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
1049 + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
1050 + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
1052 + err = get_user(ldw, (unsigned int *)addr);
1053 + err |= get_user(bv, (unsigned int *)(addr+4));
1054 + err |= get_user(ldw2, (unsigned int *)(addr+8));
1059 + if (ldw == 0x0E801096U &&
1060 + bv == 0xEAC0C000U &&
1061 + ldw2 == 0x0E881095U)
1063 + unsigned int resolver, map;
1065 + err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
1066 + err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
1070 + regs->gr[20] = instruction_pointer(regs)+8;
1071 + regs->gr[21] = map;
1072 + regs->gr[22] = resolver;
1073 + regs->iaoq[0] = resolver | 3UL;
1074 + regs->iaoq[1] = regs->iaoq[0] + 4;
1081 +#ifdef CONFIG_PAX_EMUTRAMP
1083 +#ifndef CONFIG_PAX_EMUSIGRT
1084 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
1088 + do { /* PaX: rt_sigreturn emulation */
1089 + unsigned int ldi1, ldi2, bel, nop;
1091 + err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
1092 + err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
1093 + err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
1094 + err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
1099 + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
1100 + ldi2 == 0x3414015AU &&
1101 + bel == 0xE4008200U &&
1102 + nop == 0x08000240U)
1104 + regs->gr[25] = (ldi1 & 2) >> 1;
1105 + regs->gr[20] = __NR_rt_sigreturn;
1106 + regs->gr[31] = regs->iaoq[1] + 16;
1107 + regs->sr[0] = regs->iasq[1];
1108 + regs->iaoq[0] = 0x100UL;
1109 + regs->iaoq[1] = regs->iaoq[0] + 4;
1110 + regs->iasq[0] = regs->sr[2];
1111 + regs->iasq[1] = regs->sr[2];
1120 +void pax_report_insns(void *pc, void *sp)
1124 + printk(KERN_ERR "PAX: bytes at PC: ");
1125 + for (i = 0; i < 5; i++) {
1127 + if (get_user(c, (unsigned int *)pc+i))
1128 + printk(KERN_CONT "???????? ");
1130 + printk(KERN_CONT "%08x ", c);
1136 void do_page_fault(struct pt_regs *regs, unsigned long code,
1137 unsigned long address)
1139 @@ -165,8 +276,33 @@ good_area:
1141 acc_type = parisc_acctyp(code,regs->iir);
1143 - if ((vma->vm_flags & acc_type) != acc_type)
1144 + if ((vma->vm_flags & acc_type) != acc_type) {
1146 +#ifdef CONFIG_PAX_PAGEEXEC
1147 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
1148 + (address & ~3UL) == instruction_pointer(regs))
1150 + up_read(&mm->mmap_sem);
1151 + switch (pax_handle_fetch_fault(regs)) {
1153 +#ifdef CONFIG_PAX_EMUPLT
1158 +#ifdef CONFIG_PAX_EMUTRAMP
1164 + pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1165 + do_group_exit(SIGKILL);
1173 * If for any reason at all we couldn't handle the fault, make
1174 diff -urNp linux-2.6.27.10/arch/powerpc/include/asm/elf.h linux-2.6.27.10/arch/powerpc/include/asm/elf.h
1175 --- linux-2.6.27.10/arch/powerpc/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
1176 +++ linux-2.6.27.10/arch/powerpc/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
1177 @@ -180,6 +180,18 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
1179 #define ELF_ET_DYN_BASE (0x20000000)
1181 +#ifdef CONFIG_PAX_ASLR
1182 +#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
1184 +#ifdef __powerpc64__
1185 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1186 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1188 +#define PAX_DELTA_MMAP_LEN 15
1189 +#define PAX_DELTA_STACK_LEN 15
1194 * Our registers are always unsigned longs, whether we're a 32 bit
1195 * process or 64 bit, on either a 64 bit or 32 bit kernel.
1196 diff -urNp linux-2.6.27.10/arch/powerpc/include/asm/kmap_types.h linux-2.6.27.10/arch/powerpc/include/asm/kmap_types.h
1197 --- linux-2.6.27.10/arch/powerpc/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
1198 +++ linux-2.6.27.10/arch/powerpc/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
1199 @@ -26,6 +26,7 @@ enum km_type {
1207 diff -urNp linux-2.6.27.10/arch/powerpc/include/asm/page_64.h linux-2.6.27.10/arch/powerpc/include/asm/page_64.h
1208 --- linux-2.6.27.10/arch/powerpc/include/asm/page_64.h 2008-11-07 12:55:34.000000000 -0500
1209 +++ linux-2.6.27.10/arch/powerpc/include/asm/page_64.h 2008-11-18 03:39:50.000000000 -0500
1210 @@ -170,15 +170,18 @@ do { \
1211 * stack by default, so in the absense of a PT_GNU_STACK program header
1212 * we turn execute permission off.
1214 -#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1215 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1216 +#define VM_STACK_DEFAULT_FLAGS32 \
1217 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1218 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1220 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1221 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1223 +#ifndef CONFIG_PAX_PAGEEXEC
1224 #define VM_STACK_DEFAULT_FLAGS \
1225 (test_thread_flag(TIF_32BIT) ? \
1226 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
1229 #include <asm-generic/page.h>
1231 diff -urNp linux-2.6.27.10/arch/powerpc/include/asm/page.h linux-2.6.27.10/arch/powerpc/include/asm/page.h
1232 --- linux-2.6.27.10/arch/powerpc/include/asm/page.h 2008-11-07 12:55:34.000000000 -0500
1233 +++ linux-2.6.27.10/arch/powerpc/include/asm/page.h 2008-11-18 03:39:50.000000000 -0500
1234 @@ -100,8 +100,9 @@ extern phys_addr_t kernstart_addr;
1235 * and needs to be executable. This means the whole heap ends
1236 * up being executable.
1238 -#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1239 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1240 +#define VM_DATA_DEFAULT_FLAGS32 \
1241 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1242 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1244 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1245 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1246 diff -urNp linux-2.6.27.10/arch/powerpc/kernel/module_32.c linux-2.6.27.10/arch/powerpc/kernel/module_32.c
1247 --- linux-2.6.27.10/arch/powerpc/kernel/module_32.c 2008-11-07 12:55:34.000000000 -0500
1248 +++ linux-2.6.27.10/arch/powerpc/kernel/module_32.c 2008-11-18 03:38:43.000000000 -0500
1249 @@ -158,7 +158,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1250 me->arch.core_plt_section = i;
1252 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1253 - printk("Module doesn't contain .plt or .init.plt sections.\n");
1254 + printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1258 @@ -199,11 +199,16 @@ static uint32_t do_plt_call(void *locati
1260 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1261 /* Init, or core PLT? */
1262 - if (location >= mod->module_core
1263 - && location < mod->module_core + mod->core_size)
1264 + if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1265 + (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1266 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1268 + else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1269 + (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1270 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1272 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1276 /* Find this entry, or if that fails, the next avail. entry */
1277 while (entry->jump[0]) {
1278 diff -urNp linux-2.6.27.10/arch/powerpc/kernel/signal_32.c linux-2.6.27.10/arch/powerpc/kernel/signal_32.c
1279 --- linux-2.6.27.10/arch/powerpc/kernel/signal_32.c 2008-11-07 12:55:34.000000000 -0500
1280 +++ linux-2.6.27.10/arch/powerpc/kernel/signal_32.c 2008-11-18 03:38:43.000000000 -0500
1281 @@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig
1282 /* Save user registers on the stack */
1283 frame = &rt_sf->uc.uc_mcontext;
1285 - if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1286 + if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1287 if (save_user_regs(regs, frame, 0, 1))
1289 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1290 diff -urNp linux-2.6.27.10/arch/powerpc/kernel/signal_64.c linux-2.6.27.10/arch/powerpc/kernel/signal_64.c
1291 --- linux-2.6.27.10/arch/powerpc/kernel/signal_64.c 2008-11-07 12:55:34.000000000 -0500
1292 +++ linux-2.6.27.10/arch/powerpc/kernel/signal_64.c 2008-11-18 03:38:43.000000000 -0500
1293 @@ -434,7 +434,7 @@ int handle_rt_signal64(int signr, struct
1294 current->thread.fpscr.val = 0;
1296 /* Set up to return from userspace. */
1297 - if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1298 + if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1299 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1301 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1302 diff -urNp linux-2.6.27.10/arch/powerpc/kernel/vdso.c linux-2.6.27.10/arch/powerpc/kernel/vdso.c
1303 --- linux-2.6.27.10/arch/powerpc/kernel/vdso.c 2008-11-07 12:55:34.000000000 -0500
1304 +++ linux-2.6.27.10/arch/powerpc/kernel/vdso.c 2008-11-18 03:38:43.000000000 -0500
1305 @@ -212,7 +212,7 @@ int arch_setup_additional_pages(struct l
1306 vdso_base = VDSO32_MBASE;
1309 - current->mm->context.vdso_base = 0;
1310 + current->mm->context.vdso_base = ~0UL;
1312 /* vDSO has a problem and was disabled, just don't "enable" it for the
1314 @@ -229,7 +229,7 @@ int arch_setup_additional_pages(struct l
1316 down_write(&mm->mmap_sem);
1317 vdso_base = get_unmapped_area(NULL, vdso_base,
1318 - vdso_pages << PAGE_SHIFT, 0, 0);
1319 + vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1320 if (IS_ERR_VALUE(vdso_base)) {
1323 diff -urNp linux-2.6.27.10/arch/powerpc/mm/fault.c linux-2.6.27.10/arch/powerpc/mm/fault.c
1324 --- linux-2.6.27.10/arch/powerpc/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
1325 +++ linux-2.6.27.10/arch/powerpc/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
1327 #include <linux/module.h>
1328 #include <linux/kprobes.h>
1329 #include <linux/kdebug.h>
1330 +#include <linux/slab.h>
1331 +#include <linux/pagemap.h>
1332 +#include <linux/compiler.h>
1333 +#include <linux/unistd.h>
1335 #include <asm/page.h>
1336 #include <asm/pgtable.h>
1337 @@ -62,6 +66,363 @@ static inline int notify_page_fault(stru
1341 +#ifdef CONFIG_PAX_EMUSIGRT
1342 +void pax_syscall_close(struct vm_area_struct *vma)
1344 + vma->vm_mm->call_syscall = 0UL;
1347 +static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1349 + unsigned int *kaddr;
1351 + vmf->page = alloc_page(GFP_HIGHUSER);
1353 + return VM_FAULT_OOM;
1355 + kaddr = kmap(vmf->page);
1356 + memset(kaddr, 0, PAGE_SIZE);
1357 + kaddr[0] = 0x44000002U; /* sc */
1358 + __flush_dcache_icache(kaddr);
1359 + kunmap(vmf->page);
1360 + return VM_FAULT_MAJOR;
1363 +static struct vm_operations_struct pax_vm_ops = {
1364 + .close = pax_syscall_close,
1365 + .fault = pax_syscall_fault
1368 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1372 + vma->vm_mm = current->mm;
1373 + vma->vm_start = addr;
1374 + vma->vm_end = addr + PAGE_SIZE;
1375 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1376 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1377 + vma->vm_ops = &pax_vm_ops;
1379 + ret = insert_vm_struct(current->mm, vma);
1383 + ++current->mm->total_vm;
1388 +#ifdef CONFIG_PAX_PAGEEXEC
1390 + * PaX: decide what to do with offenders (regs->nip = fault address)
1392 + * returns 1 when task should be killed
1393 + * 2 when patched GOT trampoline was detected
1394 + * 3 when patched PLT trampoline was detected
1395 + * 4 when unpatched PLT trampoline was detected
1396 + * 5 when sigreturn trampoline was detected
1397 + * 6 when rt_sigreturn trampoline was detected
1399 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1402 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1406 +#ifdef CONFIG_PAX_EMUPLT
1407 + do { /* PaX: patched GOT emulation */
1408 + unsigned int blrl;
1410 + err = get_user(blrl, (unsigned int *)regs->nip);
1412 + if (!err && blrl == 0x4E800021U) {
1413 + unsigned long temp = regs->nip;
1415 + regs->nip = regs->link & 0xFFFFFFFCUL;
1416 + regs->link = temp + 4UL;
1421 + do { /* PaX: patched PLT emulation #1 */
1424 + err = get_user(b, (unsigned int *)regs->nip);
1426 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
1427 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1432 + do { /* PaX: unpatched PLT emulation #1 */
1433 + unsigned int li, b;
1435 + err = get_user(li, (unsigned int *)regs->nip);
1436 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1438 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1439 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1440 + unsigned long addr = b | 0xFC000000UL;
1442 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1443 + err = get_user(rlwinm, (unsigned int *)addr);
1444 + err |= get_user(add, (unsigned int *)(addr+4));
1445 + err |= get_user(li2, (unsigned int *)(addr+8));
1446 + err |= get_user(addis2, (unsigned int *)(addr+12));
1447 + err |= get_user(mtctr, (unsigned int *)(addr+16));
1448 + err |= get_user(li3, (unsigned int *)(addr+20));
1449 + err |= get_user(addis3, (unsigned int *)(addr+24));
1450 + err |= get_user(bctr, (unsigned int *)(addr+28));
1455 + if (rlwinm == 0x556C083CU &&
1456 + add == 0x7D6C5A14U &&
1457 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1458 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1459 + mtctr == 0x7D8903A6U &&
1460 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1461 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1462 + bctr == 0x4E800420U)
1464 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1465 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1466 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1467 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1468 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1469 + regs->nip = regs->ctr;
1476 + do { /* PaX: unpatched PLT emulation #2 */
1477 + unsigned int lis, lwzu, b, bctr;
1479 + err = get_user(lis, (unsigned int *)regs->nip);
1480 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1481 + err |= get_user(b, (unsigned int *)(regs->nip+8));
1482 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1487 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
1488 + (lwzu & 0xU) == 0xU &&
1489 + (b & 0xFC000003U) == 0x48000000U &&
1490 + bctr == 0x4E800420U)
1492 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1493 + unsigned long addr = b | 0xFC000000UL;
1495 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1496 + err = get_user(addis, (unsigned int *)addr);
1497 + err |= get_user(addi, (unsigned int *)(addr+4));
1498 + err |= get_user(rlwinm, (unsigned int *)(addr+8));
1499 + err |= get_user(add, (unsigned int *)(addr+12));
1500 + err |= get_user(li2, (unsigned int *)(addr+16));
1501 + err |= get_user(addis2, (unsigned int *)(addr+20));
1502 + err |= get_user(mtctr, (unsigned int *)(addr+24));
1503 + err |= get_user(li3, (unsigned int *)(addr+28));
1504 + err |= get_user(addis3, (unsigned int *)(addr+32));
1505 + err |= get_user(bctr, (unsigned int *)(addr+36));
1510 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1511 + (addi & 0xFFFF0000U) == 0x396B0000U &&
1512 + rlwinm == 0x556C083CU &&
1513 + add == 0x7D6C5A14U &&
1514 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1515 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1516 + mtctr == 0x7D8903A6U &&
1517 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1518 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1519 + bctr == 0x4E800420U)
1521 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1522 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1523 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1524 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1525 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1526 + regs->nip = regs->ctr;
1533 + do { /* PaX: unpatched PLT emulation #3 */
1534 + unsigned int li, b;
1536 + err = get_user(li, (unsigned int *)regs->nip);
1537 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1539 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1540 + unsigned int addis, lwz, mtctr, bctr;
1541 + unsigned long addr = b | 0xFC000000UL;
1543 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1544 + err = get_user(addis, (unsigned int *)addr);
1545 + err |= get_user(lwz, (unsigned int *)(addr+4));
1546 + err |= get_user(mtctr, (unsigned int *)(addr+8));
1547 + err |= get_user(bctr, (unsigned int *)(addr+12));
1552 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1553 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
1554 + mtctr == 0x7D6903A6U &&
1555 + bctr == 0x4E800420U)
1559 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1560 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1562 + err = get_user(r11, (unsigned int *)addr);
1566 + regs->gpr[PT_R11] = r11;
1575 +#ifdef CONFIG_PAX_EMUSIGRT
1576 + do { /* PaX: sigreturn emulation */
1577 + unsigned int li, sc;
1579 + err = get_user(li, (unsigned int *)regs->nip);
1580 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1582 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1583 + struct vm_area_struct *vma;
1584 + unsigned long call_syscall;
1586 + down_read(¤t->mm->mmap_sem);
1587 + call_syscall = current->mm->call_syscall;
1588 + up_read(¤t->mm->mmap_sem);
1589 + if (likely(call_syscall))
1592 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1594 + down_write(¤t->mm->mmap_sem);
1595 + if (current->mm->call_syscall) {
1596 + call_syscall = current->mm->call_syscall;
1597 + up_write(¤t->mm->mmap_sem);
1599 + kmem_cache_free(vm_area_cachep, vma);
1603 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1604 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1605 + up_write(¤t->mm->mmap_sem);
1607 + kmem_cache_free(vm_area_cachep, vma);
1611 + if (pax_insert_vma(vma, call_syscall)) {
1612 + up_write(¤t->mm->mmap_sem);
1613 + kmem_cache_free(vm_area_cachep, vma);
1617 + current->mm->call_syscall = call_syscall;
1618 + up_write(¤t->mm->mmap_sem);
1621 + regs->gpr[PT_R0] = __NR_sigreturn;
1622 + regs->nip = call_syscall;
1627 + do { /* PaX: rt_sigreturn emulation */
1628 + unsigned int li, sc;
1630 + err = get_user(li, (unsigned int *)regs->nip);
1631 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1633 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1634 + struct vm_area_struct *vma;
1635 + unsigned int call_syscall;
1637 + down_read(¤t->mm->mmap_sem);
1638 + call_syscall = current->mm->call_syscall;
1639 + up_read(¤t->mm->mmap_sem);
1640 + if (likely(call_syscall))
1643 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1645 + down_write(¤t->mm->mmap_sem);
1646 + if (current->mm->call_syscall) {
1647 + call_syscall = current->mm->call_syscall;
1648 + up_write(¤t->mm->mmap_sem);
1650 + kmem_cache_free(vm_area_cachep, vma);
1654 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1655 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1656 + up_write(¤t->mm->mmap_sem);
1658 + kmem_cache_free(vm_area_cachep, vma);
1662 + if (pax_insert_vma(vma, call_syscall)) {
1663 + up_write(¤t->mm->mmap_sem);
1664 + kmem_cache_free(vm_area_cachep, vma);
1668 + current->mm->call_syscall = call_syscall;
1669 + up_write(¤t->mm->mmap_sem);
1672 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
1673 + regs->nip = call_syscall;
1682 +void pax_report_insns(void *pc, void *sp)
1686 + printk(KERN_ERR "PAX: bytes at PC: ");
1687 + for (i = 0; i < 5; i++) {
1689 + if (get_user(c, (unsigned int *)pc+i))
1690 + printk(KERN_CONT "???????? ");
1692 + printk(KERN_CONT "%08x ", c);
1699 * Check whether the instruction at regs->nip is a store using
1700 * an update addressing form which will update r1.
1701 @@ -132,7 +493,7 @@ int __kprobes do_page_fault(struct pt_re
1702 * indicate errors in DSISR but can validly be set in SRR1.
1705 - error_code &= 0x48200000;
1706 + error_code &= 0x58200000;
1708 is_write = error_code & DSISR_ISSTORE;
1710 @@ -331,6 +692,37 @@ bad_area:
1711 bad_area_nosemaphore:
1712 /* User mode accesses cause a SIGSEGV */
1713 if (user_mode(regs)) {
1715 +#ifdef CONFIG_PAX_PAGEEXEC
1716 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1717 +#ifdef CONFIG_PPC64
1718 + if (is_exec && (error_code & DSISR_PROTFAULT)) {
1720 + if (is_exec && regs->nip == address) {
1722 + switch (pax_handle_fetch_fault(regs)) {
1724 +#ifdef CONFIG_PAX_EMUPLT
1731 +#ifdef CONFIG_PAX_EMUSIGRT
1739 + pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
1740 + do_group_exit(SIGKILL);
1745 _exception(SIGSEGV, regs, code, address);
1748 diff -urNp linux-2.6.27.10/arch/powerpc/mm/mmap.c linux-2.6.27.10/arch/powerpc/mm/mmap.c
1749 --- linux-2.6.27.10/arch/powerpc/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
1750 +++ linux-2.6.27.10/arch/powerpc/mm/mmap.c 2008-11-18 03:38:43.000000000 -0500
1751 @@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1753 if (mmap_is_legacy()) {
1754 mm->mmap_base = TASK_UNMAPPED_BASE;
1756 +#ifdef CONFIG_PAX_RANDMMAP
1757 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1758 + mm->mmap_base += mm->delta_mmap;
1761 mm->get_unmapped_area = arch_get_unmapped_area;
1762 mm->unmap_area = arch_unmap_area;
1764 mm->mmap_base = mmap_base();
1766 +#ifdef CONFIG_PAX_RANDMMAP
1767 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1768 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1771 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1772 mm->unmap_area = arch_unmap_area_topdown;
1774 diff -urNp linux-2.6.27.10/arch/s390/include/asm/kmap_types.h linux-2.6.27.10/arch/s390/include/asm/kmap_types.h
1775 --- linux-2.6.27.10/arch/s390/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
1776 +++ linux-2.6.27.10/arch/s390/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
1777 @@ -16,6 +16,7 @@ enum km_type {
1785 diff -urNp linux-2.6.27.10/arch/s390/kernel/module.c linux-2.6.27.10/arch/s390/kernel/module.c
1786 --- linux-2.6.27.10/arch/s390/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
1787 +++ linux-2.6.27.10/arch/s390/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
1788 @@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
1790 /* Increase core size by size of got & plt and set start
1791 offsets for got and plt. */
1792 - me->core_size = ALIGN(me->core_size, 4);
1793 - me->arch.got_offset = me->core_size;
1794 - me->core_size += me->arch.got_size;
1795 - me->arch.plt_offset = me->core_size;
1796 - me->core_size += me->arch.plt_size;
1797 + me->core_size_rw = ALIGN(me->core_size_rw, 4);
1798 + me->arch.got_offset = me->core_size_rw;
1799 + me->core_size_rw += me->arch.got_size;
1800 + me->arch.plt_offset = me->core_size_rx;
1801 + me->core_size_rx += me->arch.plt_size;
1805 @@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1806 if (info->got_initialized == 0) {
1809 - gotent = me->module_core + me->arch.got_offset +
1810 + gotent = me->module_core_rw + me->arch.got_offset +
1813 info->got_initialized = 1;
1814 @@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1815 else if (r_type == R_390_GOTENT ||
1816 r_type == R_390_GOTPLTENT)
1817 *(unsigned int *) loc =
1818 - (val + (Elf_Addr) me->module_core - loc) >> 1;
1819 + (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
1820 else if (r_type == R_390_GOT64 ||
1821 r_type == R_390_GOTPLT64)
1822 *(unsigned long *) loc = val;
1823 @@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1824 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
1825 if (info->plt_initialized == 0) {
1827 - ip = me->module_core + me->arch.plt_offset +
1828 + ip = me->module_core_rx + me->arch.plt_offset +
1830 #ifndef CONFIG_64BIT
1831 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
1832 @@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1833 val = me->arch.plt_offset - me->arch.got_offset +
1834 info->plt_offset + rela->r_addend;
1836 - val = (Elf_Addr) me->module_core +
1837 + val = (Elf_Addr) me->module_core_rx +
1838 me->arch.plt_offset + info->plt_offset +
1839 rela->r_addend - loc;
1840 if (r_type == R_390_PLT16DBL)
1841 @@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1842 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
1843 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
1844 val = val + rela->r_addend -
1845 - ((Elf_Addr) me->module_core + me->arch.got_offset);
1846 + ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
1847 if (r_type == R_390_GOTOFF16)
1848 *(unsigned short *) loc = val;
1849 else if (r_type == R_390_GOTOFF32)
1850 @@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1852 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
1853 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
1854 - val = (Elf_Addr) me->module_core + me->arch.got_offset +
1855 + val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
1856 rela->r_addend - loc;
1857 if (r_type == R_390_GOTPC)
1858 *(unsigned int *) loc = val;
1859 diff -urNp linux-2.6.27.10/arch/sh/include/asm/kmap_types.h linux-2.6.27.10/arch/sh/include/asm/kmap_types.h
1860 --- linux-2.6.27.10/arch/sh/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
1861 +++ linux-2.6.27.10/arch/sh/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
1862 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
1867 +D(13) KM_CLEARPAGE,
1872 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/elf_32.h linux-2.6.27.10/arch/sparc/include/asm/elf_32.h
1873 --- linux-2.6.27.10/arch/sparc/include/asm/elf_32.h 2008-11-07 12:55:34.000000000 -0500
1874 +++ linux-2.6.27.10/arch/sparc/include/asm/elf_32.h 2008-11-18 03:39:50.000000000 -0500
1875 @@ -119,6 +119,13 @@ typedef struct {
1877 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
1879 +#ifdef CONFIG_PAX_ASLR
1880 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
1882 +#define PAX_DELTA_MMAP_LEN 16
1883 +#define PAX_DELTA_STACK_LEN 16
1886 /* This yields a mask that user programs can use to figure out what
1887 instruction set this cpu supports. This can NOT be done in userspace
1889 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/elf_64.h linux-2.6.27.10/arch/sparc/include/asm/elf_64.h
1890 --- linux-2.6.27.10/arch/sparc/include/asm/elf_64.h 2008-11-07 12:55:34.000000000 -0500
1891 +++ linux-2.6.27.10/arch/sparc/include/asm/elf_64.h 2008-11-18 03:39:50.000000000 -0500
1892 @@ -163,6 +163,12 @@ typedef struct {
1893 #define ELF_ET_DYN_BASE 0x0000010000000000UL
1894 #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
1896 +#ifdef CONFIG_PAX_ASLR
1897 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
1899 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
1900 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
1903 /* This yields a mask that user programs can use to figure out what
1904 instruction set this cpu supports. */
1905 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/kmap_types.h linux-2.6.27.10/arch/sparc/include/asm/kmap_types.h
1906 --- linux-2.6.27.10/arch/sparc/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
1907 +++ linux-2.6.27.10/arch/sparc/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
1908 @@ -19,6 +19,7 @@ enum km_type {
1916 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/pgtable_32.h linux-2.6.27.10/arch/sparc/include/asm/pgtable_32.h
1917 --- linux-2.6.27.10/arch/sparc/include/asm/pgtable_32.h 2008-11-07 12:55:34.000000000 -0500
1918 +++ linux-2.6.27.10/arch/sparc/include/asm/pgtable_32.h 2008-11-18 03:39:50.000000000 -0500
1919 @@ -47,6 +47,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
1920 BTFIXUPDEF_INT(page_none)
1921 BTFIXUPDEF_INT(page_copy)
1922 BTFIXUPDEF_INT(page_readonly)
1924 +#ifdef CONFIG_PAX_PAGEEXEC
1925 +BTFIXUPDEF_INT(page_shared_noexec)
1926 +BTFIXUPDEF_INT(page_copy_noexec)
1927 +BTFIXUPDEF_INT(page_readonly_noexec)
1930 BTFIXUPDEF_INT(page_kernel)
1932 #define PMD_SHIFT SUN4C_PMD_SHIFT
1933 @@ -68,6 +75,16 @@ extern pgprot_t PAGE_SHARED;
1934 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
1935 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
1937 +#ifdef CONFIG_PAX_PAGEEXEC
1938 +extern pgprot_t PAGE_SHARED_NOEXEC;
1939 +# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
1940 +# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
1942 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
1943 +# define PAGE_COPY_NOEXEC PAGE_COPY
1944 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
1947 extern unsigned long page_kernel;
1950 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.27.10/arch/sparc/include/asm/pgtsrmmu.h
1951 --- linux-2.6.27.10/arch/sparc/include/asm/pgtsrmmu.h 2008-11-07 12:55:34.000000000 -0500
1952 +++ linux-2.6.27.10/arch/sparc/include/asm/pgtsrmmu.h 2008-11-18 03:39:50.000000000 -0500
1953 @@ -115,6 +115,13 @@
1954 SRMMU_EXEC | SRMMU_REF)
1955 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
1956 SRMMU_EXEC | SRMMU_REF)
1958 +#ifdef CONFIG_PAX_PAGEEXEC
1959 +#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
1960 +#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
1961 +#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
1964 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
1965 SRMMU_DIRTY | SRMMU_REF)
1967 diff -urNp linux-2.6.27.10/arch/sparc/kernel/sys_sparc.c linux-2.6.27.10/arch/sparc/kernel/sys_sparc.c
1968 --- linux-2.6.27.10/arch/sparc/kernel/sys_sparc.c 2008-11-07 12:55:34.000000000 -0500
1969 +++ linux-2.6.27.10/arch/sparc/kernel/sys_sparc.c 2008-11-18 03:38:43.000000000 -0500
1970 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
1971 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
1974 - addr = TASK_UNMAPPED_BASE;
1975 + addr = current->mm->mmap_base;
1977 if (flags & MAP_SHARED)
1978 addr = COLOUR_ALIGN(addr);
1979 diff -urNp linux-2.6.27.10/arch/sparc/Makefile linux-2.6.27.10/arch/sparc/Makefile
1980 --- linux-2.6.27.10/arch/sparc/Makefile 2008-11-07 12:55:34.000000000 -0500
1981 +++ linux-2.6.27.10/arch/sparc/Makefile 2008-11-18 03:38:43.000000000 -0500
1982 @@ -37,7 +37,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
1983 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
1984 INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
1986 -CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
1987 +CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
1988 CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
1989 DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
1990 NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
1991 diff -urNp linux-2.6.27.10/arch/sparc/mm/fault.c linux-2.6.27.10/arch/sparc/mm/fault.c
1992 --- linux-2.6.27.10/arch/sparc/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
1993 +++ linux-2.6.27.10/arch/sparc/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
1995 #include <linux/interrupt.h>
1996 #include <linux/module.h>
1997 #include <linux/kdebug.h>
1998 +#include <linux/slab.h>
1999 +#include <linux/pagemap.h>
2000 +#include <linux/compiler.h>
2002 #include <asm/system.h>
2003 #include <asm/page.h>
2004 @@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
2005 return safe_compute_effective_address(regs, insn);
2008 +#ifdef CONFIG_PAX_PAGEEXEC
2009 +void pax_emuplt_close(struct vm_area_struct *vma)
2011 + vma->vm_mm->call_dl_resolve = 0UL;
2014 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2016 + unsigned int *kaddr;
2018 + vmf->page = alloc_page(GFP_HIGHUSER);
2020 + return VM_FAULT_OOM;
2022 + kaddr = kmap(vmf->page);
2023 + memset(kaddr, 0, PAGE_SIZE);
2024 + kaddr[0] = 0x9DE3BFA8U; /* save */
2025 + flush_dcache_page(vmf->page);
2026 + kunmap(vmf->page);
2027 + return VM_FAULT_MAJOR;
2030 +static struct vm_operations_struct pax_vm_ops = {
2031 + .close = pax_emuplt_close,
2032 + .fault = pax_emuplt_fault
2035 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2039 + vma->vm_mm = current->mm;
2040 + vma->vm_start = addr;
2041 + vma->vm_end = addr + PAGE_SIZE;
2042 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2043 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2044 + vma->vm_ops = &pax_vm_ops;
2046 + ret = insert_vm_struct(current->mm, vma);
2050 + ++current->mm->total_vm;
2055 + * PaX: decide what to do with offenders (regs->pc = fault address)
2057 + * returns 1 when task should be killed
2058 + * 2 when patched PLT trampoline was detected
2059 + * 3 when unpatched PLT trampoline was detected
2061 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2064 +#ifdef CONFIG_PAX_EMUPLT
2067 + do { /* PaX: patched PLT emulation #1 */
2068 + unsigned int sethi1, sethi2, jmpl;
2070 + err = get_user(sethi1, (unsigned int *)regs->pc);
2071 + err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
2072 + err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
2077 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2078 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2079 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2081 + unsigned int addr;
2083 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2084 + addr = regs->u_regs[UREG_G1];
2085 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2087 + regs->npc = addr+4;
2092 + { /* PaX: patched PLT emulation #2 */
2095 + err = get_user(ba, (unsigned int *)regs->pc);
2097 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2098 + unsigned int addr;
2100 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2102 + regs->npc = addr+4;
2107 + do { /* PaX: patched PLT emulation #3 */
2108 + unsigned int sethi, jmpl, nop;
2110 + err = get_user(sethi, (unsigned int *)regs->pc);
2111 + err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
2112 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
2117 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2118 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2119 + nop == 0x01000000U)
2121 + unsigned int addr;
2123 + addr = (sethi & 0x003FFFFFU) << 10;
2124 + regs->u_regs[UREG_G1] = addr;
2125 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2127 + regs->npc = addr+4;
2132 + do { /* PaX: unpatched PLT emulation step 1 */
2133 + unsigned int sethi, ba, nop;
2135 + err = get_user(sethi, (unsigned int *)regs->pc);
2136 + err |= get_user(ba, (unsigned int *)(regs->pc+4));
2137 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
2142 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2143 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2144 + nop == 0x01000000U)
2146 + unsigned int addr, save, call;
2148 + if ((ba & 0xFFC00000U) == 0x30800000U)
2149 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2151 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2153 + err = get_user(save, (unsigned int *)addr);
2154 + err |= get_user(call, (unsigned int *)(addr+4));
2155 + err |= get_user(nop, (unsigned int *)(addr+8));
2159 + if (save == 0x9DE3BFA8U &&
2160 + (call & 0xC0000000U) == 0x40000000U &&
2161 + nop == 0x01000000U)
2163 + struct vm_area_struct *vma;
2164 + unsigned long call_dl_resolve;
2166 + down_read(¤t->mm->mmap_sem);
2167 + call_dl_resolve = current->mm->call_dl_resolve;
2168 + up_read(¤t->mm->mmap_sem);
2169 + if (likely(call_dl_resolve))
2172 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2174 + down_write(¤t->mm->mmap_sem);
2175 + if (current->mm->call_dl_resolve) {
2176 + call_dl_resolve = current->mm->call_dl_resolve;
2177 + up_write(¤t->mm->mmap_sem);
2179 + kmem_cache_free(vm_area_cachep, vma);
2183 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2184 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2185 + up_write(¤t->mm->mmap_sem);
2187 + kmem_cache_free(vm_area_cachep, vma);
2191 + if (pax_insert_vma(vma, call_dl_resolve)) {
2192 + up_write(¤t->mm->mmap_sem);
2193 + kmem_cache_free(vm_area_cachep, vma);
2197 + current->mm->call_dl_resolve = call_dl_resolve;
2198 + up_write(¤t->mm->mmap_sem);
2201 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2202 + regs->pc = call_dl_resolve;
2203 + regs->npc = addr+4;
2209 + do { /* PaX: unpatched PLT emulation step 2 */
2210 + unsigned int save, call, nop;
2212 + err = get_user(save, (unsigned int *)(regs->pc-4));
2213 + err |= get_user(call, (unsigned int *)regs->pc);
2214 + err |= get_user(nop, (unsigned int *)(regs->pc+4));
2218 + if (save == 0x9DE3BFA8U &&
2219 + (call & 0xC0000000U) == 0x40000000U &&
2220 + nop == 0x01000000U)
2222 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2224 + regs->u_regs[UREG_RETPC] = regs->pc;
2225 + regs->pc = dl_resolve;
2226 + regs->npc = dl_resolve+4;
2235 +void pax_report_insns(void *pc, void *sp)
2239 + printk(KERN_ERR "PAX: bytes at PC: ");
2240 + for (i = 0; i < 5; i++) {
2242 + if (get_user(c, (unsigned int *)pc+i))
2243 + printk(KERN_CONT "???????? ");
2245 + printk(KERN_CONT "%08x ", c);
2251 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2252 unsigned long address)
2254 @@ -231,6 +477,24 @@ good_area:
2255 if(!(vma->vm_flags & VM_WRITE))
2259 +#ifdef CONFIG_PAX_PAGEEXEC
2260 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
2261 + up_read(&mm->mmap_sem);
2262 + switch (pax_handle_fetch_fault(regs)) {
2264 +#ifdef CONFIG_PAX_EMUPLT
2271 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2272 + do_group_exit(SIGKILL);
2276 /* Allow reads even for write-only mappings */
2277 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2279 diff -urNp linux-2.6.27.10/arch/sparc/mm/init.c linux-2.6.27.10/arch/sparc/mm/init.c
2280 --- linux-2.6.27.10/arch/sparc/mm/init.c 2008-11-07 12:55:34.000000000 -0500
2281 +++ linux-2.6.27.10/arch/sparc/mm/init.c 2008-11-18 03:38:43.000000000 -0500
2282 @@ -312,6 +312,9 @@ extern void device_scan(void);
2283 pgprot_t PAGE_SHARED __read_mostly;
2284 EXPORT_SYMBOL(PAGE_SHARED);
2286 +pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
2287 +EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
2289 void __init paging_init(void)
2291 switch(sparc_cpu_model) {
2292 @@ -337,17 +340,17 @@ void __init paging_init(void)
2294 /* Initialize the protection map with non-constant, MMU dependent values. */
2295 protection_map[0] = PAGE_NONE;
2296 - protection_map[1] = PAGE_READONLY;
2297 - protection_map[2] = PAGE_COPY;
2298 - protection_map[3] = PAGE_COPY;
2299 + protection_map[1] = PAGE_READONLY_NOEXEC;
2300 + protection_map[2] = PAGE_COPY_NOEXEC;
2301 + protection_map[3] = PAGE_COPY_NOEXEC;
2302 protection_map[4] = PAGE_READONLY;
2303 protection_map[5] = PAGE_READONLY;
2304 protection_map[6] = PAGE_COPY;
2305 protection_map[7] = PAGE_COPY;
2306 protection_map[8] = PAGE_NONE;
2307 - protection_map[9] = PAGE_READONLY;
2308 - protection_map[10] = PAGE_SHARED;
2309 - protection_map[11] = PAGE_SHARED;
2310 + protection_map[9] = PAGE_READONLY_NOEXEC;
2311 + protection_map[10] = PAGE_SHARED_NOEXEC;
2312 + protection_map[11] = PAGE_SHARED_NOEXEC;
2313 protection_map[12] = PAGE_READONLY;
2314 protection_map[13] = PAGE_READONLY;
2315 protection_map[14] = PAGE_SHARED;
2316 diff -urNp linux-2.6.27.10/arch/sparc/mm/srmmu.c linux-2.6.27.10/arch/sparc/mm/srmmu.c
2317 --- linux-2.6.27.10/arch/sparc/mm/srmmu.c 2008-11-07 12:55:34.000000000 -0500
2318 +++ linux-2.6.27.10/arch/sparc/mm/srmmu.c 2008-11-18 03:38:43.000000000 -0500
2319 @@ -2163,6 +2163,13 @@ void __init ld_mmu_srmmu(void)
2320 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
2321 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
2322 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
2324 +#ifdef CONFIG_PAX_PAGEEXEC
2325 + PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2326 + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2327 + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2330 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2331 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2333 diff -urNp linux-2.6.27.10/arch/sparc64/kernel/Makefile linux-2.6.27.10/arch/sparc64/kernel/Makefile
2334 --- linux-2.6.27.10/arch/sparc64/kernel/Makefile 2008-11-07 12:55:34.000000000 -0500
2335 +++ linux-2.6.27.10/arch/sparc64/kernel/Makefile 2008-11-18 03:38:43.000000000 -0500
2339 EXTRA_AFLAGS := -ansi
2340 -EXTRA_CFLAGS := -Werror
2341 +#EXTRA_CFLAGS := -Werror
2343 extra-y := head.o init_task.o vmlinux.lds
2345 diff -urNp linux-2.6.27.10/arch/sparc64/kernel/sys_sparc.c linux-2.6.27.10/arch/sparc64/kernel/sys_sparc.c
2346 --- linux-2.6.27.10/arch/sparc64/kernel/sys_sparc.c 2008-11-07 12:55:34.000000000 -0500
2347 +++ linux-2.6.27.10/arch/sparc64/kernel/sys_sparc.c 2008-11-18 03:38:43.000000000 -0500
2348 @@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
2349 /* We do not accept a shared mapping if it would violate
2350 * cache aliasing constraints.
2352 - if ((flags & MAP_SHARED) &&
2353 + if ((filp || (flags & MAP_SHARED)) &&
2354 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2357 @@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
2358 if (filp || (flags & MAP_SHARED))
2361 +#ifdef CONFIG_PAX_RANDMMAP
2362 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2367 addr = COLOUR_ALIGN(addr, pgoff);
2368 @@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
2371 if (len > mm->cached_hole_size) {
2372 - start_addr = addr = mm->free_area_cache;
2373 + start_addr = addr = mm->free_area_cache;
2375 - start_addr = addr = TASK_UNMAPPED_BASE;
2376 + start_addr = addr = mm->mmap_base;
2377 mm->cached_hole_size = 0;
2380 @@ -174,8 +178,8 @@ full_search:
2381 vma = find_vma(mm, VA_EXCLUDE_END);
2383 if (unlikely(task_size < addr)) {
2384 - if (start_addr != TASK_UNMAPPED_BASE) {
2385 - start_addr = addr = TASK_UNMAPPED_BASE;
2386 + if (start_addr != mm->mmap_base) {
2387 + start_addr = addr = mm->mmap_base;
2388 mm->cached_hole_size = 0;
2391 @@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
2392 /* We do not accept a shared mapping if it would violate
2393 * cache aliasing constraints.
2395 - if ((flags & MAP_SHARED) &&
2396 + if ((filp || (flags & MAP_SHARED)) &&
2397 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2400 @@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
2401 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2402 sysctl_legacy_va_layout) {
2403 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2405 +#ifdef CONFIG_PAX_RANDMMAP
2406 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2407 + mm->mmap_base += mm->delta_mmap;
2410 mm->get_unmapped_area = arch_get_unmapped_area;
2411 mm->unmap_area = arch_unmap_area;
2413 @@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
2414 gap = (task_size / 6 * 5);
2416 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2418 +#ifdef CONFIG_PAX_RANDMMAP
2419 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2420 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2423 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2424 mm->unmap_area = arch_unmap_area_topdown;
2426 diff -urNp linux-2.6.27.10/arch/sparc64/mm/fault.c linux-2.6.27.10/arch/sparc64/mm/fault.c
2427 --- linux-2.6.27.10/arch/sparc64/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
2428 +++ linux-2.6.27.10/arch/sparc64/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
2430 #include <linux/interrupt.h>
2431 #include <linux/kprobes.h>
2432 #include <linux/kdebug.h>
2433 +#include <linux/slab.h>
2434 +#include <linux/pagemap.h>
2435 +#include <linux/compiler.h>
2437 #include <asm/page.h>
2438 #include <asm/pgtable.h>
2439 @@ -261,6 +264,367 @@ cannot_handle:
2440 unhandled_fault (address, current, regs);
2443 +#ifdef CONFIG_PAX_PAGEEXEC
2444 +#ifdef CONFIG_PAX_EMUPLT
2445 +static void pax_emuplt_close(struct vm_area_struct *vma)
2447 + vma->vm_mm->call_dl_resolve = 0UL;
2450 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2452 + unsigned int *kaddr;
2454 + vmf->page = alloc_page(GFP_HIGHUSER);
2456 + return VM_FAULT_OOM;
2458 + kaddr = kmap(vmf->page);
2459 + memset(kaddr, 0, PAGE_SIZE);
2460 + kaddr[0] = 0x9DE3BFA8U; /* save */
2461 + flush_dcache_page(vmf->page);
2462 + kunmap(vmf->page);
2463 + return VM_FAULT_MAJOR;
2466 +static struct vm_operations_struct pax_vm_ops = {
2467 + .close = pax_emuplt_close,
2468 + .fault = pax_emuplt_fault
2471 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2475 + vma->vm_mm = current->mm;
2476 + vma->vm_start = addr;
2477 + vma->vm_end = addr + PAGE_SIZE;
2478 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2479 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2480 + vma->vm_ops = &pax_vm_ops;
2482 + ret = insert_vm_struct(current->mm, vma);
2486 + ++current->mm->total_vm;
2492 + * PaX: decide what to do with offenders (regs->tpc = fault address)
2494 + * returns 1 when task should be killed
2495 + * 2 when patched PLT trampoline was detected
2496 + * 3 when unpatched PLT trampoline was detected
2498 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2501 +#ifdef CONFIG_PAX_EMUPLT
2504 + do { /* PaX: patched PLT emulation #1 */
2505 + unsigned int sethi1, sethi2, jmpl;
2507 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2508 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2509 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
2514 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2515 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2516 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2518 + unsigned long addr;
2520 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2521 + addr = regs->u_regs[UREG_G1];
2522 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2524 + regs->tnpc = addr+4;
2529 + { /* PaX: patched PLT emulation #2 */
2532 + err = get_user(ba, (unsigned int *)regs->tpc);
2534 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2535 + unsigned long addr;
2537 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2539 + regs->tnpc = addr+4;
2544 + do { /* PaX: patched PLT emulation #3 */
2545 + unsigned int sethi, jmpl, nop;
2547 + err = get_user(sethi, (unsigned int *)regs->tpc);
2548 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
2549 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2554 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2555 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2556 + nop == 0x01000000U)
2558 + unsigned long addr;
2560 + addr = (sethi & 0x003FFFFFU) << 10;
2561 + regs->u_regs[UREG_G1] = addr;
2562 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2564 + regs->tnpc = addr+4;
2569 + do { /* PaX: patched PLT emulation #4 */
2570 + unsigned int mov1, call, mov2;
2572 + err = get_user(mov1, (unsigned int *)regs->tpc);
2573 + err |= get_user(call, (unsigned int *)(regs->tpc+4));
2574 + err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
2579 + if (mov1 == 0x8210000FU &&
2580 + (call & 0xC0000000U) == 0x40000000U &&
2581 + mov2 == 0x9E100001U)
2583 + unsigned long addr;
2585 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2586 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2588 + regs->tnpc = addr+4;
2593 + do { /* PaX: patched PLT emulation #5 */
2594 + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
2596 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2597 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2598 + err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2599 + err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2600 + err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2601 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2602 + err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2607 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2608 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2609 + (or1 & 0xFFFFE000U) == 0x82106000U &&
2610 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
2611 + sllx == 0x83287020 &&
2612 + jmpl == 0x81C04005U &&
2613 + nop == 0x01000000U)
2615 + unsigned long addr;
2617 + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2618 + regs->u_regs[UREG_G1] <<= 32;
2619 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2620 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2622 + regs->tnpc = addr+4;
2627 + do { /* PaX: patched PLT emulation #6 */
2628 + unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
2630 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2631 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2632 + err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2633 + err |= get_user(or, (unsigned int *)(regs->tpc+12));
2634 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2635 + err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2640 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2641 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2642 + sllx == 0x83287020 &&
2643 + (or & 0xFFFFE000U) == 0x8A116000U &&
2644 + jmpl == 0x81C04005U &&
2645 + nop == 0x01000000U)
2647 + unsigned long addr;
2649 + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2650 + regs->u_regs[UREG_G1] <<= 32;
2651 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2652 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2654 + regs->tnpc = addr+4;
2659 + do { /* PaX: patched PLT emulation #7 */
2660 + unsigned int sethi, ba, nop;
2662 + err = get_user(sethi, (unsigned int *)regs->tpc);
2663 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2664 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2669 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2670 + (ba & 0xFFF00000U) == 0x30600000U &&
2671 + nop == 0x01000000U)
2673 + unsigned long addr;
2675 + addr = (sethi & 0x003FFFFFU) << 10;
2676 + regs->u_regs[UREG_G1] = addr;
2677 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2679 + regs->tnpc = addr+4;
2684 + do { /* PaX: unpatched PLT emulation step 1 */
2685 + unsigned int sethi, ba, nop;
2687 + err = get_user(sethi, (unsigned int *)regs->tpc);
2688 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2689 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2694 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2695 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2696 + nop == 0x01000000U)
2698 + unsigned long addr;
2699 + unsigned int save, call;
2701 + if ((ba & 0xFFC00000U) == 0x30800000U)
2702 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2704 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2706 + err = get_user(save, (unsigned int *)addr);
2707 + err |= get_user(call, (unsigned int *)(addr+4));
2708 + err |= get_user(nop, (unsigned int *)(addr+8));
2712 + if (save == 0x9DE3BFA8U &&
2713 + (call & 0xC0000000U) == 0x40000000U &&
2714 + nop == 0x01000000U)
2716 + struct vm_area_struct *vma;
2717 + unsigned long call_dl_resolve;
2719 + down_read(¤t->mm->mmap_sem);
2720 + call_dl_resolve = current->mm->call_dl_resolve;
2721 + up_read(¤t->mm->mmap_sem);
2722 + if (likely(call_dl_resolve))
2725 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2727 + down_write(¤t->mm->mmap_sem);
2728 + if (current->mm->call_dl_resolve) {
2729 + call_dl_resolve = current->mm->call_dl_resolve;
2730 + up_write(¤t->mm->mmap_sem);
2732 + kmem_cache_free(vm_area_cachep, vma);
2736 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2737 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2738 + up_write(¤t->mm->mmap_sem);
2740 + kmem_cache_free(vm_area_cachep, vma);
2744 + if (pax_insert_vma(vma, call_dl_resolve)) {
2745 + up_write(¤t->mm->mmap_sem);
2746 + kmem_cache_free(vm_area_cachep, vma);
2750 + current->mm->call_dl_resolve = call_dl_resolve;
2751 + up_write(¤t->mm->mmap_sem);
2754 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2755 + regs->tpc = call_dl_resolve;
2756 + regs->tnpc = addr+4;
2762 + do { /* PaX: unpatched PLT emulation step 2 */
2763 + unsigned int save, call, nop;
2765 + err = get_user(save, (unsigned int *)(regs->tpc-4));
2766 + err |= get_user(call, (unsigned int *)regs->tpc);
2767 + err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2771 + if (save == 0x9DE3BFA8U &&
2772 + (call & 0xC0000000U) == 0x40000000U &&
2773 + nop == 0x01000000U)
2775 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2777 + regs->u_regs[UREG_RETPC] = regs->tpc;
2778 + regs->tpc = dl_resolve;
2779 + regs->tnpc = dl_resolve+4;
2788 +void pax_report_insns(void *pc, void *sp)
2792 + printk(KERN_ERR "PAX: bytes at PC: ");
2793 + for (i = 0; i < 5; i++) {
2795 + if (get_user(c, (unsigned int *)pc+i))
2796 + printk(KERN_CONT "???????? ");
2798 + printk(KERN_CONT "%08x ", c);
2804 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2806 struct mm_struct *mm = current->mm;
2807 @@ -302,8 +666,10 @@ asmlinkage void __kprobes do_sparc64_fau
2810 if (test_thread_flag(TIF_32BIT)) {
2811 - if (!(regs->tstate & TSTATE_PRIV))
2812 + if (!(regs->tstate & TSTATE_PRIV)) {
2813 regs->tpc &= 0xffffffff;
2814 + regs->tnpc &= 0xffffffff;
2816 address &= 0xffffffff;
2819 @@ -320,6 +686,29 @@ asmlinkage void __kprobes do_sparc64_fau
2823 +#ifdef CONFIG_PAX_PAGEEXEC
2824 + /* PaX: detect ITLB misses on non-exec pages */
2825 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2826 + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2828 + if (address != regs->tpc)
2831 + up_read(&mm->mmap_sem);
2832 + switch (pax_handle_fetch_fault(regs)) {
2834 +#ifdef CONFIG_PAX_EMUPLT
2841 + pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
2842 + do_group_exit(SIGKILL);
2846 /* Pure DTLB misses do not tell us whether the fault causing
2847 * load/store/atomic was a write or not, it only says that there
2848 * was no match. So in such a case we (carefully) read the
2849 diff -urNp linux-2.6.27.10/arch/sparc64/mm/Makefile linux-2.6.27.10/arch/sparc64/mm/Makefile
2850 --- linux-2.6.27.10/arch/sparc64/mm/Makefile 2008-11-07 12:55:34.000000000 -0500
2851 +++ linux-2.6.27.10/arch/sparc64/mm/Makefile 2008-11-18 03:38:43.000000000 -0500
2855 EXTRA_AFLAGS := -ansi
2856 -EXTRA_CFLAGS := -Werror
2857 +#EXTRA_CFLAGS := -Werror
2859 obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
2861 diff -urNp linux-2.6.27.10/arch/um/sys-i386/syscalls.c linux-2.6.27.10/arch/um/sys-i386/syscalls.c
2862 --- linux-2.6.27.10/arch/um/sys-i386/syscalls.c 2008-11-07 12:55:34.000000000 -0500
2863 +++ linux-2.6.27.10/arch/um/sys-i386/syscalls.c 2008-11-18 03:38:43.000000000 -0500
2865 #include "asm/uaccess.h"
2866 #include "asm/unistd.h"
2868 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
2870 + unsigned long pax_task_size = TASK_SIZE;
2872 +#ifdef CONFIG_PAX_SEGMEXEC
2873 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2874 + pax_task_size = SEGMEXEC_TASK_SIZE;
2877 + if (len > pax_task_size || addr > pax_task_size - len)
2884 * Perform the select(nd, in, out, ex, tv) and mmap() system
2885 * calls. Linux/i386 didn't use to be able to handle more than
2886 diff -urNp linux-2.6.27.10/arch/x86/boot/bitops.h linux-2.6.27.10/arch/x86/boot/bitops.h
2887 --- linux-2.6.27.10/arch/x86/boot/bitops.h 2008-11-07 12:55:34.000000000 -0500
2888 +++ linux-2.6.27.10/arch/x86/boot/bitops.h 2008-11-18 03:38:44.000000000 -0500
2889 @@ -26,7 +26,7 @@ static inline int variable_test_bit(int
2891 const u32 *p = (const u32 *)addr;
2893 - asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2894 + asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2898 @@ -37,7 +37,7 @@ static inline int variable_test_bit(int
2900 static inline void set_bit(int nr, void *addr)
2902 - asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2903 + asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2906 #endif /* BOOT_BITOPS_H */
2907 diff -urNp linux-2.6.27.10/arch/x86/boot/boot.h linux-2.6.27.10/arch/x86/boot/boot.h
2908 --- linux-2.6.27.10/arch/x86/boot/boot.h 2008-11-07 12:55:34.000000000 -0500
2909 +++ linux-2.6.27.10/arch/x86/boot/boot.h 2008-11-18 03:38:44.000000000 -0500
2910 @@ -80,7 +80,7 @@ static inline void io_delay(void)
2911 static inline u16 ds(void)
2914 - asm("movw %%ds,%0" : "=rm" (seg));
2915 + asm volatile("movw %%ds,%0" : "=rm" (seg));
2919 @@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t
2920 static inline int memcmp(const void *s1, const void *s2, size_t len)
2923 - asm("repe; cmpsb; setnz %0"
2924 + asm volatile("repe; cmpsb; setnz %0"
2925 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
2928 diff -urNp linux-2.6.27.10/arch/x86/boot/compressed/head_32.S linux-2.6.27.10/arch/x86/boot/compressed/head_32.S
2929 --- linux-2.6.27.10/arch/x86/boot/compressed/head_32.S 2008-11-07 12:55:34.000000000 -0500
2930 +++ linux-2.6.27.10/arch/x86/boot/compressed/head_32.S 2008-11-18 03:38:44.000000000 -0500
2931 @@ -70,7 +70,7 @@ startup_32:
2932 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
2933 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
2935 - movl $LOAD_PHYSICAL_ADDR, %ebx
2936 + movl $____LOAD_PHYSICAL_ADDR, %ebx
2939 /* Replace the compressed data size with the uncompressed size */
2940 @@ -105,7 +105,7 @@ startup_32:
2941 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
2942 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
2944 - movl $LOAD_PHYSICAL_ADDR, %ebp
2945 + movl $____LOAD_PHYSICAL_ADDR, %ebp
2949 @@ -159,16 +159,15 @@ relocated:
2950 * and where it was actually loaded.
2953 - subl $LOAD_PHYSICAL_ADDR, %ebx
2954 + subl $____LOAD_PHYSICAL_ADDR, %ebx
2955 jz 2f /* Nothing to be done if loaded at compiled addr. */
2957 * Process relocations.
2961 - movl 0(%edi), %ecx
2966 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
2969 diff -urNp linux-2.6.27.10/arch/x86/boot/compressed/misc.c linux-2.6.27.10/arch/x86/boot/compressed/misc.c
2970 --- linux-2.6.27.10/arch/x86/boot/compressed/misc.c 2008-11-07 12:55:34.000000000 -0500
2971 +++ linux-2.6.27.10/arch/x86/boot/compressed/misc.c 2008-11-18 03:38:44.000000000 -0500
2972 @@ -371,7 +371,7 @@ static void parse_elf(void *output)
2974 #ifdef CONFIG_RELOCATABLE
2976 - dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
2977 + dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
2979 dest = (void *)(phdr->p_paddr);
2981 @@ -423,7 +423,7 @@ asmlinkage void decompress_kernel(void *
2982 if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
2983 error("Destination address too large");
2984 #ifndef CONFIG_RELOCATABLE
2985 - if ((u32)output != LOAD_PHYSICAL_ADDR)
2986 + if ((u32)output != ____LOAD_PHYSICAL_ADDR)
2987 error("Wrong destination address");
2990 diff -urNp linux-2.6.27.10/arch/x86/boot/compressed/relocs.c linux-2.6.27.10/arch/x86/boot/compressed/relocs.c
2991 --- linux-2.6.27.10/arch/x86/boot/compressed/relocs.c 2008-11-07 12:55:34.000000000 -0500
2992 +++ linux-2.6.27.10/arch/x86/boot/compressed/relocs.c 2008-11-18 03:38:44.000000000 -0500
2997 +#include "../../../../include/linux/autoconf.h"
2999 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3000 static Elf32_Ehdr ehdr;
3001 +static Elf32_Phdr *phdr;
3002 static unsigned long reloc_count, reloc_idx;
3003 static unsigned long *relocs;
3005 @@ -245,6 +248,36 @@ static void read_ehdr(FILE *fp)
3009 +static void read_phdrs(FILE *fp)
3013 + phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
3015 + die("Unable to allocate %d program headers\n",
3018 + if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3019 + die("Seek to %d failed: %s\n",
3020 + ehdr.e_phoff, strerror(errno));
3022 + if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3023 + die("Cannot read ELF program headers: %s\n",
3026 + for(i = 0; i < ehdr.e_phnum; i++) {
3027 + phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
3028 + phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
3029 + phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
3030 + phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
3031 + phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
3032 + phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
3033 + phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
3034 + phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
3039 static void read_shdrs(FILE *fp)
3042 @@ -341,6 +374,8 @@ static void read_symtabs(FILE *fp)
3043 static void read_relocs(FILE *fp)
3048 for (i = 0; i < ehdr.e_shnum; i++) {
3049 struct section *sec = &secs[i];
3050 if (sec->shdr.sh_type != SHT_REL) {
3051 @@ -360,9 +395,18 @@ static void read_relocs(FILE *fp)
3052 die("Cannot read symbol table: %s\n",
3056 + for (j = 0; j < ehdr.e_phnum; j++) {
3057 + if (phdr[j].p_type != PT_LOAD )
3059 + if (secs[secs[i].shdr.sh_info].shdr.sh_offset < phdr[j].p_offset || secs[secs[i].shdr.sh_info].shdr.sh_offset > phdr[j].p_offset + phdr[j].p_filesz)
3061 + base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3064 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
3065 Elf32_Rel *rel = &sec->reltab[j];
3066 - rel->r_offset = elf32_to_cpu(rel->r_offset);
3067 + rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
3068 rel->r_info = elf32_to_cpu(rel->r_info);
3071 @@ -504,6 +548,23 @@ static void walk_relocs(void (*visit)(El
3072 if (sym->st_shndx == SHN_ABS) {
3075 + /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
3076 + if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
3078 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3079 + /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3080 + if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
3082 + if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
3084 + if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3085 + if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3086 + strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3089 + if (!strcmp(sec_name(sym->st_shndx), ".text"))
3092 if (r_type == R_386_PC32) {
3093 /* PC relative relocations don't need to be adjusted */
3095 @@ -631,6 +692,7 @@ int main(int argc, char **argv)
3096 fname, strerror(errno));
3103 diff -urNp linux-2.6.27.10/arch/x86/boot/cpucheck.c linux-2.6.27.10/arch/x86/boot/cpucheck.c
3104 --- linux-2.6.27.10/arch/x86/boot/cpucheck.c 2008-11-07 12:55:34.000000000 -0500
3105 +++ linux-2.6.27.10/arch/x86/boot/cpucheck.c 2008-11-18 03:38:44.000000000 -0500
3106 @@ -74,7 +74,7 @@ static int has_fpu(void)
3107 u16 fcw = -1, fsw = -1;
3110 - asm("movl %%cr0,%0" : "=r" (cr0));
3111 + asm volatile("movl %%cr0,%0" : "=r" (cr0));
3112 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3113 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3114 asm volatile("movl %0,%%cr0" : : "r" (cr0));
3115 @@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
3120 + asm volatile("pushfl ; "
3124 @@ -115,7 +115,7 @@ static void get_flags(void)
3125 set_bit(X86_FEATURE_FPU, cpu.flags);
3127 if (has_eflag(X86_EFLAGS_ID)) {
3129 + asm volatile("cpuid"
3130 : "=a" (max_intel_level),
3131 "=b" (cpu_vendor[0]),
3132 "=d" (cpu_vendor[1]),
3133 @@ -124,7 +124,7 @@ static void get_flags(void)
3135 if (max_intel_level >= 0x00000001 &&
3136 max_intel_level <= 0x0000ffff) {
3138 + asm volatile("cpuid"
3140 "=c" (cpu.flags[4]),
3142 @@ -136,7 +136,7 @@ static void get_flags(void)
3143 cpu.model += ((tfms >> 16) & 0xf) << 4;
3147 + asm volatile("cpuid"
3148 : "=a" (max_amd_level)
3150 : "ebx", "ecx", "edx");
3151 @@ -144,7 +144,7 @@ static void get_flags(void)
3152 if (max_amd_level >= 0x80000001 &&
3153 max_amd_level <= 0x8000ffff) {
3154 u32 eax = 0x80000001;
3156 + asm volatile("cpuid"
3158 "=c" (cpu.flags[6]),
3160 @@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3161 u32 ecx = MSR_K7_HWCR;
3164 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3165 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3167 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3168 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3170 get_flags(); /* Make sure it really did something */
3171 err = check_flags();
3172 @@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3173 u32 ecx = MSR_VIA_FCR;
3176 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3177 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3178 eax |= (1<<1)|(1<<7);
3179 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3180 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3182 set_bit(X86_FEATURE_CX8, cpu.flags);
3183 err = check_flags();
3184 @@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
3188 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3189 - asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3191 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3192 + asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3193 + asm volatile("cpuid"
3194 : "+a" (level), "=d" (cpu.flags[0])
3196 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3197 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3199 err = check_flags();
3201 diff -urNp linux-2.6.27.10/arch/x86/boot/edd.c linux-2.6.27.10/arch/x86/boot/edd.c
3202 --- linux-2.6.27.10/arch/x86/boot/edd.c 2008-11-07 12:55:34.000000000 -0500
3203 +++ linux-2.6.27.10/arch/x86/boot/edd.c 2008-11-18 03:38:44.000000000 -0500
3204 @@ -76,7 +76,7 @@ static int get_edd_info(u8 devno, struct
3208 - asm("pushfl; stc; int $0x13; setc %%al; popfl"
3209 + asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
3210 : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3213 @@ -95,7 +95,7 @@ static int get_edd_info(u8 devno, struct
3214 ei->params.length = sizeof(ei->params);
3217 - asm("pushfl; int $0x13; popfl"
3218 + asm volatile("pushfl; int $0x13; popfl"
3219 : "+a" (ax), "+d" (dx), "=m" (ei->params)
3221 : "ebx", "ecx", "edi");
3222 @@ -106,7 +106,7 @@ static int get_edd_info(u8 devno, struct
3226 - asm("pushw %%es; "
3227 + asm volatile("pushw %%es; "
3229 "pushfl; stc; int $0x13; setc %%al; popfl; "
3231 diff -urNp linux-2.6.27.10/arch/x86/boot/main.c linux-2.6.27.10/arch/x86/boot/main.c
3232 --- linux-2.6.27.10/arch/x86/boot/main.c 2008-11-07 12:55:34.000000000 -0500
3233 +++ linux-2.6.27.10/arch/x86/boot/main.c 2008-11-18 03:38:44.000000000 -0500
3234 @@ -78,7 +78,7 @@ static void query_ist(void)
3239 + asm volatile("int $0x15"
3240 : "=a" (boot_params.ist_info.signature),
3241 "=b" (boot_params.ist_info.command),
3242 "=c" (boot_params.ist_info.event),
3243 diff -urNp linux-2.6.27.10/arch/x86/boot/mca.c linux-2.6.27.10/arch/x86/boot/mca.c
3244 --- linux-2.6.27.10/arch/x86/boot/mca.c 2008-11-07 12:55:34.000000000 -0500
3245 +++ linux-2.6.27.10/arch/x86/boot/mca.c 2008-11-18 03:38:44.000000000 -0500
3246 @@ -19,7 +19,7 @@ int query_mca(void)
3250 - asm("pushw %%es ; "
3251 + asm volatile("pushw %%es ; "
3255 diff -urNp linux-2.6.27.10/arch/x86/boot/memory.c linux-2.6.27.10/arch/x86/boot/memory.c
3256 --- linux-2.6.27.10/arch/x86/boot/memory.c 2008-11-07 12:55:34.000000000 -0500
3257 +++ linux-2.6.27.10/arch/x86/boot/memory.c 2008-11-18 03:38:44.000000000 -0500
3258 @@ -30,7 +30,7 @@ static int detect_memory_e820(void)
3259 /* Important: %edx is clobbered by some BIOSes,
3260 so it must be either used for the error output
3261 or explicitly marked clobbered. */
3262 - asm("int $0x15; setc %0"
3263 + asm volatile("int $0x15; setc %0"
3264 : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
3266 : "D" (desc), "d" (SMAP), "a" (0xe820));
3267 @@ -65,7 +65,7 @@ static int detect_memory_e801(void)
3271 - asm("stc; int $0x15; setc %0"
3272 + asm volatile("stc; int $0x15; setc %0"
3273 : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3276 @@ -95,7 +95,7 @@ static int detect_memory_88(void)
3280 - asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3281 + asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3283 boot_params.screen_info.ext_mem_k = ax;
3285 diff -urNp linux-2.6.27.10/arch/x86/boot/video.c linux-2.6.27.10/arch/x86/boot/video.c
3286 --- linux-2.6.27.10/arch/x86/boot/video.c 2008-11-07 12:55:34.000000000 -0500
3287 +++ linux-2.6.27.10/arch/x86/boot/video.c 2008-11-18 03:38:44.000000000 -0500
3288 @@ -23,7 +23,7 @@ static void store_cursor_position(void)
3293 + asm volatile(INT10
3294 : "=d" (curpos), "+a" (ax), "+b" (bx)
3295 : : "ecx", "esi", "edi");
3297 @@ -38,7 +38,7 @@ static void store_video_mode(void)
3298 /* N.B.: the saving of the video page here is a bit silly,
3299 since we pretty much assume page 0 everywhere. */
3302 + asm volatile(INT10
3303 : "+a" (ax), "=b" (page)
3304 : : "ecx", "edx", "esi", "edi");
3306 diff -urNp linux-2.6.27.10/arch/x86/boot/video-vesa.c linux-2.6.27.10/arch/x86/boot/video-vesa.c
3307 --- linux-2.6.27.10/arch/x86/boot/video-vesa.c 2008-11-07 12:55:34.000000000 -0500
3308 +++ linux-2.6.27.10/arch/x86/boot/video-vesa.c 2008-11-18 03:38:44.000000000 -0500
3309 @@ -41,7 +41,7 @@ static int vesa_probe(void)
3312 di = (size_t)&vginfo;
3314 + asm volatile(INT10
3315 : "+a" (ax), "+D" (di), "=m" (vginfo)
3316 : : "ebx", "ecx", "edx", "esi");
3318 @@ -68,7 +68,7 @@ static int vesa_probe(void)
3321 di = (size_t)&vminfo;
3323 + asm volatile(INT10
3324 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3325 : : "ebx", "edx", "esi");
3327 @@ -123,7 +123,7 @@ static int vesa_set_mode(struct mode_inf
3330 di = (size_t)&vminfo;
3332 + asm volatile(INT10
3333 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3334 : : "ebx", "edx", "esi");
3336 @@ -203,19 +203,20 @@ static void vesa_dac_set_8bits(void)
3337 /* Save the VESA protected mode info */
3338 static void vesa_store_pm_info(void)
3340 - u16 ax, bx, di, es;
3341 + u16 ax, bx, cx, di, es;
3345 - asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3346 - : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3347 - : : "ecx", "esi");
3349 + asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3350 + : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3356 boot_params.screen_info.vesapm_seg = es;
3357 boot_params.screen_info.vesapm_off = di;
3358 + boot_params.screen_info.vesapm_size = cx;
3362 @@ -269,7 +270,7 @@ void vesa_store_edid(void)
3363 /* Note: The VBE DDC spec is different from the main VESA spec;
3364 we genuinely have to assume all registers are destroyed here. */
3366 - asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3367 + asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3368 : "+a" (ax), "+b" (bx)
3369 : "c" (cx), "D" (di)
3371 @@ -285,7 +286,7 @@ void vesa_store_edid(void)
3372 cx = 0; /* Controller 0 */
3373 dx = 0; /* EDID block number */
3374 di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
3376 + asm volatile(INT10
3377 : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
3378 : "c" (cx), "D" (di)
3380 diff -urNp linux-2.6.27.10/arch/x86/boot/video-vga.c linux-2.6.27.10/arch/x86/boot/video-vga.c
3381 --- linux-2.6.27.10/arch/x86/boot/video-vga.c 2008-11-07 12:55:34.000000000 -0500
3382 +++ linux-2.6.27.10/arch/x86/boot/video-vga.c 2008-11-18 03:38:44.000000000 -0500
3383 @@ -225,7 +225,7 @@ static int vga_probe(void)
3388 + asm volatile(INT10
3390 : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
3391 : "ecx", "edx", "esi", "edi");
3392 @@ -237,7 +237,7 @@ static int vga_probe(void)
3393 /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
3394 if ((u8)ega_bx != 0x10) {
3397 + asm volatile(INT10
3400 : "ebx", "ecx", "edx", "esi", "edi");
3401 diff -urNp linux-2.6.27.10/arch/x86/boot/voyager.c linux-2.6.27.10/arch/x86/boot/voyager.c
3402 --- linux-2.6.27.10/arch/x86/boot/voyager.c 2008-11-07 12:55:34.000000000 -0500
3403 +++ linux-2.6.27.10/arch/x86/boot/voyager.c 2008-11-18 03:38:44.000000000 -0500
3404 @@ -23,7 +23,7 @@ int query_voyager(void)
3406 data_ptr[0] = 0xff; /* Flag on config not found(?) */
3408 - asm("pushw %%es ; "
3409 + asm volatile("pushw %%es ; "
3413 diff -urNp linux-2.6.27.10/arch/x86/ia32/ia32_signal.c linux-2.6.27.10/arch/x86/ia32/ia32_signal.c
3414 --- linux-2.6.27.10/arch/x86/ia32/ia32_signal.c 2008-11-07 12:55:34.000000000 -0500
3415 +++ linux-2.6.27.10/arch/x86/ia32/ia32_signal.c 2008-11-18 03:38:44.000000000 -0500
3416 @@ -535,6 +535,7 @@ int ia32_setup_rt_frame(int sig, struct
3417 __NR_ia32_rt_sigreturn,
3423 frame = get_sigframe(ka, regs, sizeof(*frame));
3424 diff -urNp linux-2.6.27.10/arch/x86/Kconfig linux-2.6.27.10/arch/x86/Kconfig
3425 --- linux-2.6.27.10/arch/x86/Kconfig 2008-11-17 20:03:30.000000000 -0500
3426 +++ linux-2.6.27.10/arch/x86/Kconfig 2008-11-18 03:38:44.000000000 -0500
3427 @@ -912,7 +912,7 @@ config PAGE_OFFSET
3429 default 0xB0000000 if VMSPLIT_3G_OPT
3430 default 0x80000000 if VMSPLIT_2G
3431 - default 0x78000000 if VMSPLIT_2G_OPT
3432 + default 0x70000000 if VMSPLIT_2G_OPT
3433 default 0x40000000 if VMSPLIT_1G
3436 @@ -1293,8 +1293,7 @@ config KEXEC_JUMP
3437 config PHYSICAL_START
3438 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
3439 default "0x1000000" if X86_NUMAQ
3440 - default "0x200000" if X86_64
3441 - default "0x100000"
3442 + default "0x200000"
3444 This gives the physical address where the kernel is loaded.
3446 @@ -1386,9 +1385,9 @@ config HOTPLUG_CPU
3452 prompt "Compat VDSO support"
3453 - depends on X86_32 || IA32_EMULATION
3454 + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
3456 Map the 32-bit VDSO to the predictable old-style address too.
3458 diff -urNp linux-2.6.27.10/arch/x86/Kconfig.cpu linux-2.6.27.10/arch/x86/Kconfig.cpu
3459 --- linux-2.6.27.10/arch/x86/Kconfig.cpu 2008-11-07 12:55:34.000000000 -0500
3460 +++ linux-2.6.27.10/arch/x86/Kconfig.cpu 2008-11-18 03:38:44.000000000 -0500
3461 @@ -340,7 +340,7 @@ config X86_PPRO_FENCE
3465 - depends on M586MMX || M586TSC || M586 || M486 || M386
3466 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
3468 config X86_WP_WORKS_OK
3470 @@ -360,7 +360,7 @@ config X86_POPAD_OK
3472 config X86_ALIGNMENT_16
3474 - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3475 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3477 config X86_INTEL_USERCOPY
3479 @@ -406,7 +406,7 @@ config X86_CMPXCHG64
3483 - depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
3484 + depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
3486 config X86_MINIMUM_CPU_FAMILY
3488 diff -urNp linux-2.6.27.10/arch/x86/Kconfig.debug linux-2.6.27.10/arch/x86/Kconfig.debug
3489 --- linux-2.6.27.10/arch/x86/Kconfig.debug 2008-11-07 12:55:34.000000000 -0500
3490 +++ linux-2.6.27.10/arch/x86/Kconfig.debug 2008-11-18 03:38:44.000000000 -0500
3491 @@ -94,7 +94,7 @@ config X86_PTDUMP
3493 bool "Write protect kernel read-only data structures"
3495 - depends on DEBUG_KERNEL
3496 + depends on DEBUG_KERNEL && BROKEN
3498 Mark the kernel read-only data as write-protected in the pagetables,
3499 in order to catch accidental (and incorrect) writes to such const
3500 diff -urNp linux-2.6.27.10/arch/x86/kernel/acpi/boot.c linux-2.6.27.10/arch/x86/kernel/acpi/boot.c
3501 --- linux-2.6.27.10/arch/x86/kernel/acpi/boot.c 2008-12-10 22:35:36.000000000 -0500
3502 +++ linux-2.6.27.10/arch/x86/kernel/acpi/boot.c 2008-12-10 22:35:46.000000000 -0500
3503 @@ -1640,7 +1640,7 @@ static struct dmi_system_id __initdata a
3504 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
3508 + { NULL, NULL, {{0, NULL}}, NULL}
3512 diff -urNp linux-2.6.27.10/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.27.10/arch/x86/kernel/acpi/realmode/wakeup.S
3513 --- linux-2.6.27.10/arch/x86/kernel/acpi/realmode/wakeup.S 2008-11-07 12:55:34.000000000 -0500
3514 +++ linux-2.6.27.10/arch/x86/kernel/acpi/realmode/wakeup.S 2008-11-18 03:38:44.000000000 -0500
3515 @@ -104,7 +104,7 @@ _start:
3519 - movl $0xc0000080, %ecx
3520 + mov $MSR_EFER, %ecx
3524 diff -urNp linux-2.6.27.10/arch/x86/kernel/acpi/sleep.c linux-2.6.27.10/arch/x86/kernel/acpi/sleep.c
3525 --- linux-2.6.27.10/arch/x86/kernel/acpi/sleep.c 2008-11-07 12:55:34.000000000 -0500
3526 +++ linux-2.6.27.10/arch/x86/kernel/acpi/sleep.c 2008-11-18 11:45:34.000000000 -0500
3527 @@ -37,6 +37,10 @@ int acpi_save_state_mem(void)
3529 struct wakeup_header *header;
3531 +#if defined(CONFIG_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_PAX_KERNEXEC)
3532 + unsigned long cr0;
3535 if (!acpi_realmode) {
3536 printk(KERN_ERR "Could not allocate memory during boot, "
3538 @@ -99,8 +103,18 @@ int acpi_save_state_mem(void)
3539 header->trampoline_segment = setup_trampoline() >> 4;
3541 stack_start.sp = temp_stack + 4096;
3543 +#ifdef CONFIG_PAX_KERNEXEC
3544 + pax_open_kernel(cr0);
3547 early_gdt_descr.address =
3548 (unsigned long)get_cpu_gdt_table(smp_processor_id());
3550 +#ifdef CONFIG_PAX_KERNEXEC
3551 + pax_close_kernel(cr0);
3555 initial_code = (unsigned long)wakeup_long64;
3556 saved_magic = 0x123456789abcdef0;
3557 diff -urNp linux-2.6.27.10/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.27.10/arch/x86/kernel/acpi/wakeup_32.S
3558 --- linux-2.6.27.10/arch/x86/kernel/acpi/wakeup_32.S 2008-11-07 12:55:34.000000000 -0500
3559 +++ linux-2.6.27.10/arch/x86/kernel/acpi/wakeup_32.S 2008-11-18 03:38:44.000000000 -0500
3560 @@ -30,13 +30,11 @@ wakeup_pmode_return:
3561 # and restore the stack ... but you need gdt for this to work
3562 movl saved_context_esp, %esp
3564 - movl %cs:saved_magic, %eax
3565 - cmpl $0x12345678, %eax
3566 + cmpl $0x12345678, saved_magic
3569 # jump to place where we left off
3570 - movl saved_eip, %eax
3576 diff -urNp linux-2.6.27.10/arch/x86/kernel/alternative.c linux-2.6.27.10/arch/x86/kernel/alternative.c
3577 --- linux-2.6.27.10/arch/x86/kernel/alternative.c 2008-11-07 12:55:34.000000000 -0500
3578 +++ linux-2.6.27.10/arch/x86/kernel/alternative.c 2008-11-18 03:38:44.000000000 -0500
3579 @@ -393,7 +393,7 @@ void apply_paravirt(struct paravirt_patc
3581 BUG_ON(p->len > MAX_PATCH_LEN);
3582 /* prep the buffer with the original instructions */
3583 - memcpy(insnbuf, p->instr, p->len);
3584 + memcpy(insnbuf, ktla_ktva(p->instr), p->len);
3585 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
3586 (unsigned long)p->instr, p->len);
3588 @@ -473,11 +473,26 @@ void __init alternative_instructions(voi
3589 * instructions. And on the local CPU you need to be protected again NMI or MCE
3590 * handlers seeing an inconsistent instruction while you patch.
3592 -void *text_poke_early(void *addr, const void *opcode, size_t len)
3593 +void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
3595 unsigned long flags;
3597 +#ifdef CONFIG_PAX_KERNEXEC
3598 + unsigned long cr0;
3601 local_irq_save(flags);
3602 - memcpy(addr, opcode, len);
3604 +#ifdef CONFIG_PAX_KERNEXEC
3605 + pax_open_kernel(cr0);
3608 + memcpy(ktla_ktva(addr), opcode, len);
3610 +#ifdef CONFIG_PAX_KERNEXEC
3611 + pax_close_kernel(cr0);
3614 local_irq_restore(flags);
3616 /* Could also do a CLFLUSH here to speed up CPU recovery; but
3617 @@ -498,33 +513,27 @@ void *text_poke_early(void *addr, const
3619 void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
3621 - unsigned long flags;
3624 + unsigned char *vaddr = ktla_ktva(addr);
3625 struct page *pages[2];
3629 + if (!core_kernel_text((unsigned long)addr)
3631 - if (!core_kernel_text((unsigned long)addr)) {
3632 - pages[0] = vmalloc_to_page(addr);
3633 - pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
3634 +#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
3635 + && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
3639 + pages[0] = vmalloc_to_page(vaddr);
3640 + pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
3642 - pages[0] = virt_to_page(addr);
3643 + pages[0] = virt_to_page(vaddr);
3644 WARN_ON(!PageReserved(pages[0]));
3645 - pages[1] = virt_to_page(addr + PAGE_SIZE);
3646 + pages[1] = virt_to_page(vaddr + PAGE_SIZE);
3651 - vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
3653 - local_irq_save(flags);
3654 - memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
3655 - local_irq_restore(flags);
3658 - /* Could also do a CLFLUSH here to speed up CPU recovery; but
3659 - that causes hangs on some VIA CPUs. */
3660 + text_poke_early(addr, opcode, len);
3661 for (i = 0; i < len; i++)
3662 - BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
3663 + BUG_ON((vaddr)[i] != ((unsigned char *)opcode)[i]);
3666 diff -urNp linux-2.6.27.10/arch/x86/kernel/apm_32.c linux-2.6.27.10/arch/x86/kernel/apm_32.c
3667 --- linux-2.6.27.10/arch/x86/kernel/apm_32.c 2008-11-07 12:55:34.000000000 -0500
3668 +++ linux-2.6.27.10/arch/x86/kernel/apm_32.c 2008-11-18 03:38:44.000000000 -0500
3669 @@ -408,7 +408,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
3670 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
3671 static struct apm_user *user_list;
3672 static DEFINE_SPINLOCK(user_list_lock);
3673 -static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
3674 +static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
3676 static const char driver_version[] = "1.16ac"; /* no spaces */
3678 @@ -603,19 +603,42 @@ static u8 apm_bios_call(u32 func, u32 eb
3679 struct desc_struct save_desc_40;
3680 struct desc_struct *gdt;
3682 +#ifdef CONFIG_PAX_KERNEXEC
3683 + unsigned long cr0;
3686 cpus = apm_save_cpus();
3689 gdt = get_cpu_gdt_table(cpu);
3690 save_desc_40 = gdt[0x40 / 8];
3692 +#ifdef CONFIG_PAX_KERNEXEC
3693 + pax_open_kernel(cr0);
3696 gdt[0x40 / 8] = bad_bios_desc;
3698 +#ifdef CONFIG_PAX_KERNEXEC
3699 + pax_close_kernel(cr0);
3702 apm_irq_save(flags);
3704 apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
3705 APM_DO_RESTORE_SEGS;
3706 apm_irq_restore(flags);
3708 +#ifdef CONFIG_PAX_KERNEXEC
3709 + pax_open_kernel(cr0);
3712 gdt[0x40 / 8] = save_desc_40;
3714 +#ifdef CONFIG_PAX_KERNEXEC
3715 + pax_close_kernel(cr0);
3719 apm_restore_cpus(cpus);
3721 @@ -646,19 +669,42 @@ static u8 apm_bios_call_simple(u32 func,
3722 struct desc_struct save_desc_40;
3723 struct desc_struct *gdt;
3725 +#ifdef CONFIG_PAX_KERNEXEC
3726 + unsigned long cr0;
3729 cpus = apm_save_cpus();
3732 gdt = get_cpu_gdt_table(cpu);
3733 save_desc_40 = gdt[0x40 / 8];
3735 +#ifdef CONFIG_PAX_KERNEXEC
3736 + pax_open_kernel(cr0);
3739 gdt[0x40 / 8] = bad_bios_desc;
3741 +#ifdef CONFIG_PAX_KERNEXEC
3742 + pax_close_kernel(cr0);
3745 apm_irq_save(flags);
3747 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
3748 APM_DO_RESTORE_SEGS;
3749 apm_irq_restore(flags);
3751 +#ifdef CONFIG_PAX_KERNEXEC
3752 + pax_open_kernel(cr0);
3755 gdt[0x40 / 8] = save_desc_40;
3757 +#ifdef CONFIG_PAX_KERNEXEC
3758 + pax_close_kernel(cr0);
3762 apm_restore_cpus(cpus);
3764 @@ -930,7 +976,7 @@ recalc:
3766 static void apm_power_off(void)
3768 - unsigned char po_bios_call[] = {
3769 + const unsigned char po_bios_call[] = {
3770 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
3771 0x8e, 0xd0, /* movw ax,ss */
3772 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
3773 @@ -1877,7 +1923,10 @@ static const struct file_operations apm_
3774 static struct miscdevice apm_device = {
3785 @@ -2198,7 +2247,7 @@ static struct dmi_system_id __initdata a
3786 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
3790 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
3794 @@ -2216,6 +2265,10 @@ static int __init apm_init(void)
3795 struct desc_struct *gdt;
3798 +#ifdef CONFIG_PAX_KERNEXEC
3799 + unsigned long cr0;
3802 dmi_check_system(apm_dmi_table);
3804 if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
3805 @@ -2289,9 +2342,18 @@ static int __init apm_init(void)
3806 * This is for buggy BIOS's that refer to (real mode) segment 0x40
3807 * even though they are called in protected mode.
3810 +#ifdef CONFIG_PAX_KERNEXEC
3811 + pax_open_kernel(cr0);
3814 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
3815 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
3817 +#ifdef CONFIG_PAX_KERNEXEC
3818 + pax_close_kernel(cr0);
3822 * Set up the long jump entry point to the APM BIOS, which is called
3823 * from inline assembly.
3824 @@ -2310,6 +2372,11 @@ static int __init apm_init(void)
3827 gdt = get_cpu_gdt_table(0);
3829 +#ifdef CONFIG_PAX_KERNEXEC
3830 + pax_open_kernel(cr0);
3833 set_base(gdt[APM_CS >> 3],
3834 __va((unsigned long)apm_info.bios.cseg << 4));
3835 set_base(gdt[APM_CS_16 >> 3],
3836 @@ -2317,6 +2384,10 @@ static int __init apm_init(void)
3837 set_base(gdt[APM_DS >> 3],
3838 __va((unsigned long)apm_info.bios.dseg << 4));
3840 +#ifdef CONFIG_PAX_KERNEXEC
3841 + pax_close_kernel(cr0);
3844 proc_create("apm", 0, NULL, &apm_file_ops);
3846 kapmd_task = kthread_create(apm, NULL, "kapmd");
3847 diff -urNp linux-2.6.27.10/arch/x86/kernel/asm-offsets_32.c linux-2.6.27.10/arch/x86/kernel/asm-offsets_32.c
3848 --- linux-2.6.27.10/arch/x86/kernel/asm-offsets_32.c 2008-11-07 12:55:34.000000000 -0500
3849 +++ linux-2.6.27.10/arch/x86/kernel/asm-offsets_32.c 2008-11-18 03:38:44.000000000 -0500
3850 @@ -100,6 +100,7 @@ void foo(void)
3851 DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
3852 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
3853 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
3854 + DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
3856 OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
3858 @@ -113,6 +114,7 @@ void foo(void)
3859 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
3860 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
3861 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
3862 + OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
3866 diff -urNp linux-2.6.27.10/arch/x86/kernel/asm-offsets_64.c linux-2.6.27.10/arch/x86/kernel/asm-offsets_64.c
3867 --- linux-2.6.27.10/arch/x86/kernel/asm-offsets_64.c 2008-11-07 12:55:34.000000000 -0500
3868 +++ linux-2.6.27.10/arch/x86/kernel/asm-offsets_64.c 2008-11-18 03:38:44.000000000 -0500
3869 @@ -122,6 +122,7 @@ int main(void)
3873 + DEFINE(TSS_size, sizeof(struct tss_struct));
3874 DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
3876 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
3877 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/common_64.c linux-2.6.27.10/arch/x86/kernel/cpu/common_64.c
3878 --- linux-2.6.27.10/arch/x86/kernel/cpu/common_64.c 2008-11-07 12:55:34.000000000 -0500
3879 +++ linux-2.6.27.10/arch/x86/kernel/cpu/common_64.c 2008-11-18 03:38:44.000000000 -0500
3884 -/* We need valid kernel segments for data and code in long mode too
3885 - * IRET will check the segment types kkeil 2000/10/28
3886 - * Also sysret mandates a special GDT layout
3888 -/* The TLS descriptors are currently at a different place compared to i386.
3889 - Hopefully nobody expects them at a fixed place (Wine?) */
3890 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
3891 - [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
3892 - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
3893 - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
3894 - [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
3895 - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
3896 - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
3898 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
3900 __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
3902 /* Current gdt points %fs at the "master" per-cpu area: after this,
3903 @@ -457,15 +441,13 @@ cpumask_t cpu_initialized __cpuinitdata
3904 struct x8664_pda **_cpu_pda __read_mostly;
3905 EXPORT_SYMBOL(_cpu_pda);
3907 -struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
3908 +struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
3910 char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
3912 unsigned long __supported_pte_mask __read_mostly = ~0UL;
3913 EXPORT_SYMBOL_GPL(__supported_pte_mask);
3915 -static int do_not_nx __cpuinitdata;
3918 Control non executable mappings for 64bit processes.
3920 @@ -478,9 +460,7 @@ static int __init nonx_setup(char *str)
3922 if (!strncmp(str, "on", 2)) {
3923 __supported_pte_mask |= _PAGE_NX;
3925 } else if (!strncmp(str, "off", 3)) {
3927 __supported_pte_mask &= ~_PAGE_NX;
3930 @@ -576,7 +556,7 @@ void __cpuinit check_efer(void)
3933 rdmsrl(MSR_EFER, efer);
3934 - if (!(efer & EFER_NX) || do_not_nx)
3935 + if (!(efer & EFER_NX))
3936 __supported_pte_mask &= ~_PAGE_NX;
3939 @@ -598,7 +578,7 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
3940 void __cpuinit cpu_init(void)
3942 int cpu = stack_smp_processor_id();
3943 - struct tss_struct *t = &per_cpu(init_tss, cpu);
3944 + struct tss_struct *t = init_tss + cpu;
3945 struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
3947 char *estacks = NULL;
3948 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/common.c linux-2.6.27.10/arch/x86/kernel/cpu/common.c
3949 --- linux-2.6.27.10/arch/x86/kernel/cpu/common.c 2008-11-07 12:55:34.000000000 -0500
3950 +++ linux-2.6.27.10/arch/x86/kernel/cpu/common.c 2008-11-18 03:38:44.000000000 -0500
3952 #include <linux/smp.h>
3953 #include <linux/module.h>
3954 #include <linux/percpu.h>
3955 -#include <linux/bootmem.h>
3956 #include <asm/processor.h>
3957 #include <asm/i387.h>
3958 #include <asm/msr.h>
3963 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
3964 - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
3965 - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
3966 - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
3967 - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
3969 - * Segments used for calling PnP BIOS have byte granularity.
3970 - * They code segments and data segments have fixed 64k limits,
3971 - * the transfer segment sizes are set at run time.
3974 - [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
3976 - [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
3978 - [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
3980 - [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
3982 - [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
3984 - * The APM segments have byte granularity and their bases
3985 - * are set at run time. All have 64k limits.
3988 - [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
3990 - [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
3992 - [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
3994 - [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
3995 - [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
3997 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
3999 __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
4001 static int cachesize_override __cpuinitdata = -1;
4002 @@ -493,6 +456,10 @@ static void __cpuinit identify_cpu(struc
4003 * we do "generic changes."
4006 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4007 + setup_clear_cpu_cap(X86_FEATURE_SEP);
4010 /* If the model name is still unset, do table lookup. */
4011 if (!c->x86_model_id[0]) {
4013 @@ -629,7 +596,7 @@ static __init int setup_disablecpuid(cha
4015 __setup("clearcpuid=", setup_disablecpuid);
4017 -cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
4018 +cpumask_t cpu_initialized = CPU_MASK_NONE;
4020 void __init early_cpu_init(void)
4022 @@ -658,7 +625,7 @@ void switch_to_new_gdt(void)
4024 struct desc_ptr gdt_descr;
4026 - gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
4027 + gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
4028 gdt_descr.size = GDT_SIZE - 1;
4029 load_gdt(&gdt_descr);
4030 asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
4031 @@ -674,7 +641,7 @@ void __cpuinit cpu_init(void)
4033 int cpu = smp_processor_id();
4034 struct task_struct *curr = current;
4035 - struct tss_struct *t = &per_cpu(init_tss, cpu);
4036 + struct tss_struct *t = init_tss + cpu;
4037 struct thread_struct *thread = &curr->thread;
4039 if (cpu_test_and_set(cpu, cpu_initialized)) {
4040 @@ -729,7 +696,7 @@ void __cpuinit cpu_init(void)
4043 #ifdef CONFIG_HOTPLUG_CPU
4044 -void __cpuinit cpu_uninit(void)
4045 +void cpu_uninit(void)
4047 int cpu = raw_smp_processor_id();
4048 cpu_clear(cpu, cpu_initialized);
4049 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
4050 --- linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-11-07 12:55:34.000000000 -0500
4051 +++ linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-11-18 03:38:44.000000000 -0500
4052 @@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
4053 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
4057 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
4061 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
4062 --- linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-11-07 12:55:34.000000000 -0500
4063 +++ linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-11-18 03:38:44.000000000 -0500
4064 @@ -225,7 +225,7 @@ static struct cpu_model models[] =
4065 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
4066 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
4069 + { NULL, NULL, 0, NULL}
4073 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/intel.c linux-2.6.27.10/arch/x86/kernel/cpu/intel.c
4074 --- linux-2.6.27.10/arch/x86/kernel/cpu/intel.c 2008-11-07 12:55:34.000000000 -0500
4075 +++ linux-2.6.27.10/arch/x86/kernel/cpu/intel.c 2008-11-18 03:38:44.000000000 -0500
4076 @@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
4077 * Update the IDT descriptor and reload the IDT so that
4078 * it uses the read-only mapped virtual address.
4080 - idt_descr.address = fix_to_virt(FIX_F00F_IDT);
4081 + idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
4082 load_idt(&idt_descr);
4085 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.27.10/arch/x86/kernel/cpu/mcheck/mce_64.c
4086 --- linux-2.6.27.10/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-11-07 12:55:34.000000000 -0500
4087 +++ linux-2.6.27.10/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-11-18 03:38:44.000000000 -0500
4088 @@ -681,6 +681,7 @@ static struct miscdevice mce_log_device
4092 + {NULL, NULL}, NULL, NULL
4095 static unsigned long old_cr4 __initdata;
4096 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.27.10/arch/x86/kernel/cpu/mtrr/generic.c
4097 --- linux-2.6.27.10/arch/x86/kernel/cpu/mtrr/generic.c 2008-11-07 12:55:34.000000000 -0500
4098 +++ linux-2.6.27.10/arch/x86/kernel/cpu/mtrr/generic.c 2008-11-18 03:38:44.000000000 -0500
4099 @@ -31,11 +31,11 @@ static struct fixed_range_block fixed_ra
4100 { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
4101 { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
4102 { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
4107 static unsigned long smp_changes_mask;
4108 -static struct mtrr_state mtrr_state = {};
4109 +static struct mtrr_state mtrr_state;
4110 static int mtrr_state_set;
4113 diff -urNp linux-2.6.27.10/arch/x86/kernel/crash.c linux-2.6.27.10/arch/x86/kernel/crash.c
4114 --- linux-2.6.27.10/arch/x86/kernel/crash.c 2008-11-07 12:55:34.000000000 -0500
4115 +++ linux-2.6.27.10/arch/x86/kernel/crash.c 2008-11-18 03:38:44.000000000 -0500
4116 @@ -59,7 +59,7 @@ static int crash_nmi_callback(struct not
4117 local_irq_disable();
4119 #ifdef CONFIG_X86_32
4120 - if (!user_mode_vm(regs)) {
4121 + if (!user_mode(regs)) {
4122 crash_fixup_ss_esp(&fixed_regs, regs);
4125 diff -urNp linux-2.6.27.10/arch/x86/kernel/doublefault_32.c linux-2.6.27.10/arch/x86/kernel/doublefault_32.c
4126 --- linux-2.6.27.10/arch/x86/kernel/doublefault_32.c 2008-11-07 12:55:34.000000000 -0500
4127 +++ linux-2.6.27.10/arch/x86/kernel/doublefault_32.c 2008-11-18 03:38:44.000000000 -0500
4130 #define DOUBLEFAULT_STACKSIZE (1024)
4131 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
4132 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
4133 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
4135 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
4137 @@ -21,7 +21,7 @@ static void doublefault_fn(void)
4138 unsigned long gdt, tss;
4140 store_gdt(&gdt_desc);
4141 - gdt = gdt_desc.address;
4142 + gdt = (unsigned long)gdt_desc.address;
4144 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
4146 @@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
4147 /* 0x2 bit is always set */
4148 .flags = X86_EFLAGS_SF | 0x2,
4151 + .es = __KERNEL_DS,
4155 + .ds = __KERNEL_DS,
4156 .fs = __KERNEL_PERCPU,
4158 .__cr3 = __pa(swapper_pg_dir)
4159 diff -urNp linux-2.6.27.10/arch/x86/kernel/efi_32.c linux-2.6.27.10/arch/x86/kernel/efi_32.c
4160 --- linux-2.6.27.10/arch/x86/kernel/efi_32.c 2008-11-07 12:55:34.000000000 -0500
4161 +++ linux-2.6.27.10/arch/x86/kernel/efi_32.c 2008-11-18 03:38:44.000000000 -0500
4165 static unsigned long efi_rt_eflags;
4166 -static pgd_t efi_bak_pg_dir_pointer[2];
4167 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
4169 -void efi_call_phys_prelog(void)
4170 +void __init efi_call_phys_prelog(void)
4172 - unsigned long cr4;
4173 - unsigned long temp;
4174 struct desc_ptr gdt_descr;
4176 local_irq_save(efi_rt_eflags);
4179 - * If I don't have PAE, I should just duplicate two entries in page
4180 - * directory. If I have PAE, I just need to duplicate one entry in
4183 - cr4 = read_cr4_safe();
4185 - if (cr4 & X86_CR4_PAE) {
4186 - efi_bak_pg_dir_pointer[0].pgd =
4187 - swapper_pg_dir[pgd_index(0)].pgd;
4188 - swapper_pg_dir[0].pgd =
4189 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4191 - efi_bak_pg_dir_pointer[0].pgd =
4192 - swapper_pg_dir[pgd_index(0)].pgd;
4193 - efi_bak_pg_dir_pointer[1].pgd =
4194 - swapper_pg_dir[pgd_index(0x400000)].pgd;
4195 - swapper_pg_dir[pgd_index(0)].pgd =
4196 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4197 - temp = PAGE_OFFSET + 0x400000;
4198 - swapper_pg_dir[pgd_index(0x400000)].pgd =
4199 - swapper_pg_dir[pgd_index(temp)].pgd;
4201 + clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
4202 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
4203 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
4206 * After the lock is released, the original page table is restored.
4210 - gdt_descr.address = __pa(get_cpu_gdt_table(0));
4211 + gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
4212 gdt_descr.size = GDT_SIZE - 1;
4213 load_gdt(&gdt_descr);
4216 -void efi_call_phys_epilog(void)
4217 +void __init efi_call_phys_epilog(void)
4219 - unsigned long cr4;
4220 struct desc_ptr gdt_descr;
4222 - gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
4223 + gdt_descr.address = get_cpu_gdt_table(0);
4224 gdt_descr.size = GDT_SIZE - 1;
4225 load_gdt(&gdt_descr);
4227 - cr4 = read_cr4_safe();
4229 - if (cr4 & X86_CR4_PAE) {
4230 - swapper_pg_dir[pgd_index(0)].pgd =
4231 - efi_bak_pg_dir_pointer[0].pgd;
4233 - swapper_pg_dir[pgd_index(0)].pgd =
4234 - efi_bak_pg_dir_pointer[0].pgd;
4235 - swapper_pg_dir[pgd_index(0x400000)].pgd =
4236 - efi_bak_pg_dir_pointer[1].pgd;
4238 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
4241 * After the lock is released, the original page table is restored.
4242 diff -urNp linux-2.6.27.10/arch/x86/kernel/efi_stub_32.S linux-2.6.27.10/arch/x86/kernel/efi_stub_32.S
4243 --- linux-2.6.27.10/arch/x86/kernel/efi_stub_32.S 2008-11-07 12:55:34.000000000 -0500
4244 +++ linux-2.6.27.10/arch/x86/kernel/efi_stub_32.S 2008-11-18 03:38:44.000000000 -0500
4248 #include <linux/linkage.h>
4249 +#include <linux/init.h>
4250 #include <asm/page.h>
4254 * service functions will comply with gcc calling convention, too.
4259 ENTRY(efi_call_phys)
4261 * 0. The function can only be called in Linux kernel. So CS has been
4262 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
4263 * The mapping of lower virtual memory has been created in prelog and
4267 - subl $__PAGE_OFFSET, %edx
4269 + jmp 1f-__PAGE_OFFSET
4273 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
4274 * parameter 2, ..., param n. To make things easy, we save the return
4275 * address of efi_call_phys in a global variable.
4278 - movl %edx, saved_return_addr
4279 - /* get the function pointer into ECX*/
4281 - movl %ecx, efi_rt_function_ptr
4283 - subl $__PAGE_OFFSET, %edx
4285 + popl (saved_return_addr)
4286 + popl (efi_rt_function_ptr)
4289 * 3. Clear PG bit in %CR0.
4290 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
4292 * 5. Call the physical function.
4295 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
4299 * 6. After EFI runtime service returns, control will return to
4300 * following instruction. We'd better readjust stack pointer first.
4301 @@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
4303 orl $0x80000000, %edx
4309 * 8. Now restore the virtual mode from flat mode by
4310 * adding EIP with PAGE_OFFSET.
4314 + jmp 1f+__PAGE_OFFSET
4318 * 9. Balance the stack. And because EAX contain the return value,
4319 * we'd better not clobber it.
4321 - leal efi_rt_function_ptr, %edx
4324 + pushl (efi_rt_function_ptr)
4327 - * 10. Push the saved return address onto the stack and return.
4328 + * 10. Return to the saved return address.
4330 - leal saved_return_addr, %edx
4334 + jmpl *(saved_return_addr)
4341 efi_rt_function_ptr:
4342 diff -urNp linux-2.6.27.10/arch/x86/kernel/entry_32.S linux-2.6.27.10/arch/x86/kernel/entry_32.S
4343 --- linux-2.6.27.10/arch/x86/kernel/entry_32.S 2008-11-07 12:55:34.000000000 -0500
4344 +++ linux-2.6.27.10/arch/x86/kernel/entry_32.S 2008-11-18 03:38:44.000000000 -0500
4346 #define resume_userspace_sig resume_userspace
4350 +#define __SAVE_ALL(_DS) \
4353 CFI_ADJUST_CFA_OFFSET 4;\
4354 @@ -133,12 +133,26 @@
4356 CFI_ADJUST_CFA_OFFSET 4;\
4357 CFI_REL_OFFSET ebx, 0;\
4358 - movl $(__USER_DS), %edx; \
4359 + movl $(_DS), %edx; \
4362 movl $(__KERNEL_PERCPU), %edx; \
4365 +#ifdef CONFIG_PAX_KERNEXEC
4367 + __SAVE_ALL(__KERNEL_DS); \
4368 + GET_CR0_INTO_EDX; \
4369 + movl %edx, %esi; \
4370 + orl $X86_CR0_WP, %edx; \
4371 + xorl %edx, %esi; \
4373 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4374 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
4376 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
4379 #define RESTORE_INT_REGS \
4381 CFI_ADJUST_CFA_OFFSET -4;\
4382 @@ -229,6 +243,11 @@ ENTRY(ret_from_fork)
4383 CFI_ADJUST_CFA_OFFSET 4
4385 CFI_ADJUST_CFA_OFFSET -4
4387 +#ifdef CONFIG_PAX_KERNEXEC
4394 @@ -252,7 +271,17 @@ check_userspace:
4395 movb PT_CS(%esp), %al
4396 andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
4397 cmpl $USER_RPL, %eax
4399 +#ifdef CONFIG_PAX_KERNEXEC
4400 + jae resume_userspace
4407 jb resume_kernel # not returning to v8086 or userspace
4410 ENTRY(resume_userspace)
4412 @@ -314,10 +343,9 @@ sysenter_past_esp:
4413 /*CFI_REL_OFFSET cs, 0*/
4415 * Push current_thread_info()->sysenter_return to the stack.
4416 - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
4417 - * pushed above; +8 corresponds to copy_thread's esp0 setting.
4419 - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
4420 + GET_THREAD_INFO(%ebp)
4421 + pushl TI_sysenter_return(%ebp)
4422 CFI_ADJUST_CFA_OFFSET 4
4423 CFI_REL_OFFSET eip, 0
4425 @@ -330,9 +358,17 @@ sysenter_past_esp:
4426 * Load the potential sixth argument from user stack.
4427 * Careful about security.
4429 + movl PT_OLDESP(%esp),%ebp
4431 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4432 + mov PT_OLDSS(%esp),%ds
4433 +1: movl %ds:(%ebp),%ebp
4435 cmpl $__PAGE_OFFSET-3,%ebp
4440 movl %ebp,PT_EBP(%esp)
4441 .section __ex_table,"a"
4443 @@ -356,12 +392,23 @@ sysenter_do_call:
4444 testw $_TIF_ALLWORK_MASK, %cx
4448 +#ifdef CONFIG_PAX_RANDKSTACK
4450 + CFI_ADJUST_CFA_OFFSET 4
4451 + call pax_randomize_kstack
4453 + CFI_ADJUST_CFA_OFFSET -4
4456 /* if something modifies registers it must also disable sysexit */
4457 movl PT_EIP(%esp), %edx
4458 movl PT_OLDESP(%esp), %ecx
4461 1: mov PT_FS(%esp), %fs
4462 +2: mov PT_DS(%esp), %ds
4463 +3: mov PT_ES(%esp), %es
4464 ENABLE_INTERRUPTS_SYSEXIT
4466 #ifdef CONFIG_AUDITSYSCALL
4467 @@ -404,11 +451,17 @@ sysexit_audit:
4470 .pushsection .fixup,"ax"
4471 -2: movl $0,PT_FS(%esp)
4472 +4: movl $0,PT_FS(%esp)
4474 +5: movl $0,PT_DS(%esp)
4476 +6: movl $0,PT_ES(%esp)
4478 .section __ex_table,"a"
4485 ENDPROC(ia32_sysenter_target)
4487 @@ -438,6 +491,10 @@ syscall_exit:
4488 testw $_TIF_ALLWORK_MASK, %cx # current->work
4489 jne syscall_exit_work
4491 +#ifdef CONFIG_PAX_RANDKSTACK
4492 + call pax_randomize_kstack
4496 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
4497 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
4498 @@ -531,25 +588,19 @@ work_resched:
4500 work_notifysig: # deal with pending signals and
4501 # notify-resume requests
4504 testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
4506 - jne work_notifysig_v86 # returning to kernel-space or
4507 + jz 1f # returning to kernel-space or
4510 - call do_notify_resume
4511 - jmp resume_userspace_sig
4514 -work_notifysig_v86:
4515 pushl %ecx # save ti_flags for do_notify_resume
4516 CFI_ADJUST_CFA_OFFSET 4
4517 call save_v86_state # %eax contains pt_regs pointer
4519 CFI_ADJUST_CFA_OFFSET -4
4526 call do_notify_resume
4527 @@ -595,17 +646,24 @@ syscall_badsys:
4531 -#define FIXUP_ESPFIX_STACK \
4532 - /* since we are on a wrong stack, we cant make it a C code :( */ \
4533 - PER_CPU(gdt_page, %ebx); \
4534 - GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
4535 - addl %esp, %eax; \
4536 - pushl $__KERNEL_DS; \
4537 - CFI_ADJUST_CFA_OFFSET 4; \
4539 - CFI_ADJUST_CFA_OFFSET 4; \
4540 - lss (%esp), %esp; \
4541 +.macro FIXUP_ESPFIX_STACK
4542 + /* since we are on a wrong stack, we cant make it a C code :( */
4544 + movl PER_CPU_VAR(cpu_number), %ebx;
4545 + shll $PAGE_SHIFT_asm, %ebx;
4546 + addl $cpu_gdt_table, %ebx;
4548 + movl $cpu_gdt_table, %ebx;
4550 + GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
4552 + pushl $__KERNEL_DS;
4553 + CFI_ADJUST_CFA_OFFSET 4;
4555 + CFI_ADJUST_CFA_OFFSET 4;
4557 CFI_ADJUST_CFA_OFFSET -8;
4559 #define UNWIND_ESPFIX_STACK \
4561 /* see if on espfix stack */ \
4562 @@ -622,7 +680,7 @@ END(syscall_badsys)
4563 * Build the entry stubs and pointer table with
4564 * some assembler magic.
4566 -.section .rodata,"a"
4567 +.section .rodata,"a",@progbits
4571 @@ -722,12 +780,21 @@ error_code:
4573 CFI_ADJUST_CFA_OFFSET -4
4574 /*CFI_REGISTER es, ecx*/
4576 +#ifdef CONFIG_PAX_KERNEXEC
4579 + orl $X86_CR0_WP, %edx
4584 movl PT_FS(%esp), %edi # get the function address
4585 movl PT_ORIG_EAX(%esp), %edx # get the error code
4586 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
4587 mov %ecx, PT_FS(%esp)
4588 /*CFI_REL_OFFSET fs, ES*/
4589 - movl $(__USER_DS), %ecx
4590 + movl $(__KERNEL_DS), %ecx
4593 movl %esp,%eax # pt_regs pointer
4594 @@ -861,6 +928,13 @@ nmi_stack_correct:
4595 xorl %edx,%edx # zero error code
4596 movl %esp,%eax # pt_regs pointer
4599 +#ifdef CONFIG_PAX_KERNEXEC
4605 jmp restore_nocheck_notrace
4608 @@ -901,6 +975,13 @@ nmi_espfix_stack:
4609 FIXUP_ESPFIX_STACK # %eax == %esp
4610 xorl %edx,%edx # zero error code
4613 +#ifdef CONFIG_PAX_KERNEXEC
4620 lss 12+4(%esp), %esp # back to espfix stack
4621 CFI_ADJUST_CFA_OFFSET -24
4622 @@ -1226,7 +1307,6 @@ END(mcount)
4623 #endif /* CONFIG_DYNAMIC_FTRACE */
4624 #endif /* CONFIG_FTRACE */
4626 -.section .rodata,"a"
4627 #include "syscall_table_32.S"
4629 syscall_table_size=(.-sys_call_table)
4630 diff -urNp linux-2.6.27.10/arch/x86/kernel/entry_64.S linux-2.6.27.10/arch/x86/kernel/entry_64.S
4631 --- linux-2.6.27.10/arch/x86/kernel/entry_64.S 2008-11-07 12:55:34.000000000 -0500
4632 +++ linux-2.6.27.10/arch/x86/kernel/entry_64.S 2008-11-18 03:38:44.000000000 -0500
4633 @@ -930,17 +930,18 @@ END(spurious_interrupt)
4637 - movq %gs:pda_data_offset, %rbp
4638 + imul $TSS_size, %gs:pda_cpunumber, %ebp
4639 + lea init_tss(%rbp), %rbp
4642 movq ORIG_RAX(%rsp),%rsi
4643 movq $-1,ORIG_RAX(%rsp)
4645 - subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4646 + subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4650 - addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4651 + addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4653 DISABLE_INTERRUPTS(CLBR_NONE)
4655 diff -urNp linux-2.6.27.10/arch/x86/kernel/ftrace.c linux-2.6.27.10/arch/x86/kernel/ftrace.c
4656 --- linux-2.6.27.10/arch/x86/kernel/ftrace.c 2008-11-07 12:55:34.000000000 -0500
4657 +++ linux-2.6.27.10/arch/x86/kernel/ftrace.c 2008-12-10 22:28:27.000000000 -0500
4658 @@ -103,9 +103,9 @@ notrace int ftrace_update_ftrace_func(ft
4659 unsigned char old[MCOUNT_INSN_SIZE], *new;
4662 - memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
4663 + memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
4664 new = ftrace_call_replace(ip, (unsigned long)func);
4665 - ret = ftrace_modify_code(ip, old, new);
4666 + ret = ftrace_modify_code(ktla_ktva(ip), old, new);
4670 @@ -120,9 +120,9 @@ notrace int ftrace_mcount_set(unsigned l
4671 * Replace the mcount stub with a pointer to the
4672 * ip recorder function.
4674 - memcpy(old, &mcount_call, MCOUNT_INSN_SIZE);
4675 + memcpy(old, ktla_ktva(mcount_call), MCOUNT_INSN_SIZE);
4676 new = ftrace_call_replace(ip, *addr);
4677 - *addr = ftrace_modify_code(ip, old, new);
4678 + *addr = ftrace_modify_code(ktla_ktva(ip), old, new);
4682 diff -urNp linux-2.6.27.10/arch/x86/kernel/head32.c linux-2.6.27.10/arch/x86/kernel/head32.c
4683 --- linux-2.6.27.10/arch/x86/kernel/head32.c 2008-11-07 12:55:34.000000000 -0500
4684 +++ linux-2.6.27.10/arch/x86/kernel/head32.c 2008-11-18 03:38:44.000000000 -0500
4686 #include <asm/sections.h>
4687 #include <asm/e820.h>
4688 #include <asm/bios_ebda.h>
4689 +#include <asm/boot.h>
4691 void __init i386_start_kernel(void)
4693 - reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
4694 + reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&_end), "TEXT DATA BSS");
4696 #ifdef CONFIG_BLK_DEV_INITRD
4697 /* Reserve INITRD */
4698 diff -urNp linux-2.6.27.10/arch/x86/kernel/head_32.S linux-2.6.27.10/arch/x86/kernel/head_32.S
4699 --- linux-2.6.27.10/arch/x86/kernel/head_32.S 2008-11-07 12:55:34.000000000 -0500
4700 +++ linux-2.6.27.10/arch/x86/kernel/head_32.S 2008-11-18 03:38:44.000000000 -0500
4702 #include <asm/asm-offsets.h>
4703 #include <asm/setup.h>
4704 #include <asm/processor-flags.h>
4705 +#include <asm/msr-index.h>
4707 /* Physical address */
4708 #define pa(X) ((X) - __PAGE_OFFSET)
4709 @@ -64,17 +65,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
4710 LOW_PAGES = LOW_PAGES + 0x1000000
4713 -#if PTRS_PER_PMD > 1
4714 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
4716 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
4718 +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
4719 BOOTBITMAP_SIZE = LOW_PAGES / 8
4722 INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
4725 + * Real beginning of normal "text" segment
4730 +.section .text.startup,"ax",@progbits
4731 + ljmp $(__BOOT_CS),$phys_startup_32
4734 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
4735 * %esi points to the real-mode code as a 32-bit pointer.
4736 * CS and DS must be 4 GB flat segments, but we don't depend on
4737 @@ -82,6 +88,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
4740 .section .text.head,"ax",@progbits
4742 +#ifdef CONFIG_PAX_KERNEXEC
4743 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
4748 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
4749 us to not reload segments */
4750 @@ -99,6 +111,56 @@ ENTRY(startup_32)
4754 + movl $pa(cpu_gdt_table),%edi
4755 + movl $__per_cpu_start,%eax
4756 + movw %ax,__KERNEL_PERCPU + 2(%edi)
4758 + movb %al,__KERNEL_PERCPU + 4(%edi)
4759 + movb %ah,__KERNEL_PERCPU + 7(%edi)
4760 + movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
4761 + subl $__per_cpu_start,%eax
4762 + movw %ax,__KERNEL_PERCPU + 0(%edi)
4764 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4765 + /* check for VMware */
4766 + movl $0x564d5868,%eax
4771 + cmpl $0x564d5868,%ebx
4774 + movl $NR_CPUS,%ecx
4775 + movl $pa(cpu_gdt_table),%edi
4777 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
4778 + addl $PAGE_SIZE_asm,%edi
4783 +#ifdef CONFIG_PAX_KERNEXEC
4784 + movl $pa(boot_gdt),%edi
4785 + movl $KERNEL_TEXT_OFFSET,%eax
4786 + movw %ax,__BOOT_CS + 2(%edi)
4788 + movb %al,__BOOT_CS + 4(%edi)
4789 + movb %ah,__BOOT_CS + 7(%edi)
4792 + movl $NR_CPUS,%ecx
4793 + movl $pa(cpu_gdt_table),%edi
4795 + movw %ax,__KERNEL_CS + 2(%edi)
4797 + movb %al,__KERNEL_CS + 4(%edi)
4798 + movb %ah,__KERNEL_CS + 7(%edi)
4800 + addl $PAGE_SIZE_asm,%edi
4805 * Clear BSS first so that there are no surprises...
4807 @@ -142,9 +204,7 @@ ENTRY(startup_32)
4808 cmpl $num_subarch_entries, %eax
4811 - movl pa(subarch_entries)(,%eax,4), %eax
4812 - subl $__PAGE_OFFSET, %eax
4814 + jmp *pa(subarch_entries)(,%eax,4)
4818 @@ -156,9 +216,9 @@ WEAK(xen_entry)
4822 - .long default_entry /* normal x86/PC */
4823 - .long lguest_entry /* lguest hypervisor */
4824 - .long xen_entry /* Xen hypervisor */
4825 + .long pa(default_entry) /* normal x86/PC */
4826 + .long pa(lguest_entry) /* lguest hypervisor */
4827 + .long pa(xen_entry) /* Xen hypervisor */
4828 num_subarch_entries = (. - subarch_entries) / 4
4830 #endif /* CONFIG_PARAVIRT */
4831 @@ -172,7 +232,7 @@ num_subarch_entries = (. - subarch_entri
4833 * Note that the stack is not yet set up!
4835 -#define PTE_ATTR 0x007 /* PRESENT+RW+USER */
4836 +#define PTE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
4837 #define PDE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
4838 #define PGD_ATTR 0x001 /* PRESENT (no other attributes) */
4840 @@ -224,8 +284,7 @@ default_entry:
4841 movl %eax, pa(max_pfn_mapped)
4843 /* Do early initialization of the fixmap area */
4844 - movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4845 - movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4846 + movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4849 page_pde_offset = (__PAGE_OFFSET >> 20);
4850 @@ -257,8 +316,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
4851 movl %eax, pa(max_pfn_mapped)
4853 /* Do early initialization of the fixmap area */
4854 - movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4855 - movl %eax,pa(swapper_pg_dir+0xffc)
4856 + movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
4860 @@ -322,13 +380,16 @@ ENTRY(startup_32_smp)
4863 /* Setup EFER (Extended Feature Enable Register) */
4864 - movl $0xc0000080, %ecx
4865 + movl $MSR_EFER, %ecx
4869 /* Make changes effective */
4872 + btsl $63-32,pa(__supported_pte_mask+4)
4873 + movl $1,pa(nx_enabled)
4878 @@ -354,9 +415,7 @@ ENTRY(startup_32_smp)
4882 - jz 1f /* Initial CPU cleans BSS */
4885 + jnz checkCPUtype /* Initial CPU cleans BSS */
4886 #endif /* CONFIG_SMP */
4889 @@ -433,12 +492,12 @@ is386: movl $2,%ecx # set MP
4890 ljmp $(__KERNEL_CS),$1f
4891 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
4892 movl %eax,%ss # after changing gdt.
4893 - movl %eax,%fs # gets reset once there's real percpu
4895 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
4899 + movl $(__KERNEL_PERCPU), %eax
4900 + movl %eax,%fs # set this cpu's percpu
4902 xorl %eax,%eax # Clear GS and LDT
4905 @@ -448,12 +507,6 @@ is386: movl $2,%ecx # set MP
4909 - cmpb $0,%cl # the first CPU calls start_kernel
4911 - movl $(__KERNEL_PERCPU), %eax
4912 - movl %eax,%fs # set this cpu's percpu
4913 - movl (stack_start), %esp
4915 #endif /* CONFIG_SMP */
4918 @@ -539,15 +592,15 @@ early_page_fault:
4923 #ifdef CONFIG_PRINTK
4924 + cmpl $2,%ss:early_recursion_flag
4926 + incl %ss:early_recursion_flag
4929 movl $(__KERNEL_DS),%eax
4932 - cmpl $2,early_recursion_flag
4934 - incl early_recursion_flag
4937 pushl %edx /* trapno */
4938 @@ -557,8 +610,8 @@ early_fault:
4948 @@ -566,8 +619,11 @@ hlt_loop:
4949 /* This is the default interrupt "handler" :-) */
4953 #ifdef CONFIG_PRINTK
4954 + cmpl $2,%ss:early_recursion_flag
4956 + incl %ss:early_recursion_flag
4961 @@ -576,9 +632,6 @@ ignore_int:
4962 movl $(__KERNEL_DS),%eax
4965 - cmpl $2,early_recursion_flag
4967 - incl early_recursion_flag
4971 @@ -603,36 +656,41 @@ ignore_int:
4973 .long i386_start_kernel
4977 - * Real beginning of normal "text" segment
4985 -.section ".bss.page_aligned","wa"
4986 - .align PAGE_SIZE_asm
4987 #ifdef CONFIG_X86_PAE
4988 +.section .swapper_pg_pmd,"a",@progbits
4990 .fill 1024*KPMDS,4,0
4992 +.section .swapper_pg_dir,"a",@progbits
4993 ENTRY(swapper_pg_dir)
4999 +.section .empty_zero_page,"a",@progbits
5000 ENTRY(empty_zero_page)
5004 + * The IDT has to be page-aligned to simplify the Pentium
5005 + * F0 0F bug workaround.. We have a special link segment
5008 +.section .idt,"a",@progbits
5013 * This starts the data section.
5017 #ifdef CONFIG_X86_PAE
5018 -.section ".data.page_aligned","wa"
5019 - /* Page-aligned for the benefit of paravirt? */
5020 - .align PAGE_SIZE_asm
5021 +.section .swapper_pg_dir,"a",@progbits
5022 ENTRY(swapper_pg_dir)
5023 .long pa(swapper_pg_pmd+PGD_ATTR),0 /* low identity map */
5025 @@ -655,11 +713,12 @@ ENTRY(swapper_pg_dir)
5029 - .long init_thread_union+THREAD_SIZE
5030 + .long init_thread_union+THREAD_SIZE-8
5035 +.section .rodata,"a",@progbits
5036 early_recursion_flag:
5039 @@ -695,7 +754,7 @@ fault_msg:
5040 .word 0 # 32 bit align gdt_desc.address
5043 - .long boot_gdt - __PAGE_OFFSET
5044 + .long pa(boot_gdt)
5046 .word 0 # 32-bit align idt_desc.address
5048 @@ -706,7 +765,7 @@ idt_descr:
5049 .word 0 # 32 bit align gdt_desc.address
5050 ENTRY(early_gdt_descr)
5051 .word GDT_ENTRIES*8-1
5052 - .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
5053 + .long cpu_gdt_table /* Overwritten for secondary CPUs */
5056 * The boot_gdt must mirror the equivalent in setup.S and is
5057 @@ -715,5 +774,59 @@ ENTRY(early_gdt_descr)
5058 .align L1_CACHE_BYTES
5060 .fill GDT_ENTRY_BOOT_CS,8,0
5061 - .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
5062 - .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
5063 + .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
5064 + .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
5066 + .align PAGE_SIZE_asm
5067 +ENTRY(cpu_gdt_table)
5069 + .quad 0x0000000000000000 /* NULL descriptor */
5070 + .quad 0x0000000000000000 /* 0x0b reserved */
5071 + .quad 0x0000000000000000 /* 0x13 reserved */
5072 + .quad 0x0000000000000000 /* 0x1b reserved */
5073 + .quad 0x0000000000000000 /* 0x20 unused */
5074 + .quad 0x0000000000000000 /* 0x28 unused */
5075 + .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
5076 + .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
5077 + .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
5078 + .quad 0x0000000000000000 /* 0x4b reserved */
5079 + .quad 0x0000000000000000 /* 0x53 reserved */
5080 + .quad 0x0000000000000000 /* 0x5b reserved */
5082 + .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
5083 + .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
5084 + .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
5085 + .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
5087 + .quad 0x0000000000000000 /* 0x80 TSS descriptor */
5088 + .quad 0x0000000000000000 /* 0x88 LDT descriptor */
5091 + * Segments used for calling PnP BIOS have byte granularity.
5092 + * The code segments and data segments have fixed 64k limits,
5093 + * the transfer segment sizes are set at run time.
5095 + .quad 0x00409b000000ffff /* 0x90 32-bit code */
5096 + .quad 0x00009b000000ffff /* 0x98 16-bit code */
5097 + .quad 0x000093000000ffff /* 0xa0 16-bit data */
5098 + .quad 0x0000930000000000 /* 0xa8 16-bit data */
5099 + .quad 0x0000930000000000 /* 0xb0 16-bit data */
5102 + * The APM segments have byte granularity and their bases
5103 + * are set at run time. All have 64k limits.
5105 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
5106 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
5107 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
5109 + .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
5110 + .quad 0x0040930000000000 /* 0xd8 - PERCPU */
5111 + .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
5112 + .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
5113 + .quad 0x0000000000000000 /* 0xf0 - unused */
5114 + .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
5116 + /* Be sure this is zeroed to avoid false validations in Xen */
5117 + .fill PAGE_SIZE_asm - GDT_SIZE,1,0
5119 diff -urNp linux-2.6.27.10/arch/x86/kernel/head64.c linux-2.6.27.10/arch/x86/kernel/head64.c
5120 --- linux-2.6.27.10/arch/x86/kernel/head64.c 2008-11-07 12:55:34.000000000 -0500
5121 +++ linux-2.6.27.10/arch/x86/kernel/head64.c 2008-11-18 03:38:44.000000000 -0500
5122 @@ -93,6 +93,8 @@ void __init x86_64_start_kernel(char * r
5123 /* clear bss before set_intr_gate with early_idt_handler */
5126 + x86_64_init_pda();
5128 /* Make NULL pointers segfault */
5129 zap_identity_mappings();
5131 @@ -110,8 +112,6 @@ void __init x86_64_start_kernel(char * r
5133 early_printk("Kernel alive\n");
5135 - x86_64_init_pda();
5137 early_printk("Kernel really alive\n");
5139 x86_64_start_reservations(real_mode_data);
5140 diff -urNp linux-2.6.27.10/arch/x86/kernel/head_64.S linux-2.6.27.10/arch/x86/kernel/head_64.S
5141 --- linux-2.6.27.10/arch/x86/kernel/head_64.S 2008-11-07 12:55:34.000000000 -0500
5142 +++ linux-2.6.27.10/arch/x86/kernel/head_64.S 2008-11-18 03:38:44.000000000 -0500
5143 @@ -38,6 +38,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
5144 L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
5145 L4_START_KERNEL = pgd_index(__START_KERNEL_map)
5146 L3_START_KERNEL = pud_index(__START_KERNEL_map)
5147 +L4_VMALLOC_START = pgd_index(VMALLOC_START)
5148 +L3_VMALLOC_START = pud_index(VMALLOC_START)
5149 +L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
5150 +L3_VMEMMAP_START = pud_index(VMEMMAP_START)
5154 @@ -85,14 +89,17 @@ startup_64:
5156 addq %rbp, init_level4_pgt + 0(%rip)
5157 addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
5158 + addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
5159 + addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
5160 addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
5162 addq %rbp, level3_ident_pgt + 0(%rip)
5164 - addq %rbp, level3_kernel_pgt + (510*8)(%rip)
5165 - addq %rbp, level3_kernel_pgt + (511*8)(%rip)
5166 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
5167 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
5169 addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
5170 + addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
5172 /* Add an Identity mapping if I am above 1G */
5173 leaq _text(%rip), %rdi
5174 @@ -187,6 +194,10 @@ ENTRY(secondary_startup_64)
5175 btl $20,%edi /* No Execute supported? */
5177 btsl $_EFER_NX, %eax
5178 + leaq init_level4_pgt(%rip), %rdi
5179 + btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
5180 + btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
5181 + btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
5182 1: wrmsr /* Make changes effective */
5185 @@ -257,16 +268,16 @@ ENTRY(secondary_startup_64)
5188 .quad x86_64_start_kernel
5192 .quad init_thread_union+THREAD_SIZE-8
5199 - .section ".init.text","ax"
5201 #ifdef CONFIG_EARLY_PRINTK
5202 .globl early_idt_handlers
5204 @@ -311,18 +322,23 @@ ENTRY(early_idt_handler)
5205 #endif /* EARLY_PRINTK */
5210 #ifdef CONFIG_EARLY_PRINTK
5212 early_recursion_flag:
5216 + .section .rodata,"a",@progbits
5218 .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
5221 -#endif /* CONFIG_EARLY_PRINTK */
5223 +#endif /* CONFIG_EARLY_PRINTK */
5225 + .section .rodata,"a",@progbits
5228 #define NEXT_PAGE(name) \
5229 @@ -347,6 +363,10 @@ NEXT_PAGE(init_level4_pgt)
5230 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5231 .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
5232 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5233 + .org init_level4_pgt + L4_VMALLOC_START*8, 0
5234 + .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
5235 + .org init_level4_pgt + L4_VMEMMAP_START*8, 0
5236 + .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
5237 .org init_level4_pgt + L4_START_KERNEL*8, 0
5238 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
5239 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
5240 @@ -355,6 +375,12 @@ NEXT_PAGE(level3_ident_pgt)
5241 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5244 +NEXT_PAGE(level3_vmalloc_pgt)
5247 +NEXT_PAGE(level3_vmemmap_pgt)
5250 NEXT_PAGE(level3_kernel_pgt)
5251 .fill L3_START_KERNEL,8,0
5252 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
5253 @@ -364,12 +390,16 @@ NEXT_PAGE(level3_kernel_pgt)
5254 NEXT_PAGE(level2_fixmap_pgt)
5256 .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
5257 - /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
5259 + .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
5260 + /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
5263 NEXT_PAGE(level1_fixmap_pgt)
5266 +NEXT_PAGE(level1_vsyscall_pgt)
5269 NEXT_PAGE(level2_ident_pgt)
5270 /* Since I easily can, map the first 1G.
5271 * Don't set NX because code runs from these pages.
5272 @@ -396,19 +426,39 @@ NEXT_PAGE(level2_spare_pgt)
5278 +ENTRY(cpu_gdt_table)
5280 + .quad 0x0000000000000000 /* NULL descriptor */
5281 + .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
5282 + .quad 0x00af9b000000ffff /* __KERNEL_CS */
5283 + .quad 0x00cf93000000ffff /* __KERNEL_DS */
5284 + .quad 0x00cffb000000ffff /* __USER32_CS */
5285 + .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
5286 + .quad 0x00affb000000ffff /* __USER_CS */
5287 + .quad 0x0 /* unused */
5288 + .quad 0,0 /* TSS */
5289 + .quad 0,0 /* LDT */
5290 + .quad 0,0,0 /* three TLS descriptors */
5291 + .quad 0x0000f40000000000 /* node/CPU stored in limit */
5292 + /* asm/segment.h:GDT_ENTRIES must match this */
5294 + /* zero the remaining page */
5295 + .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
5299 .globl early_gdt_descr
5301 .word GDT_ENTRIES*8-1
5302 - .quad per_cpu__gdt_page
5303 + .quad cpu_gdt_table
5306 /* This must match the first entry in level2_kernel_pgt */
5307 .quad 0x0000000000000000
5309 #include "../../x86/xen/xen-head.S"
5312 .section .bss, "aw", @nobits
5313 .align L1_CACHE_BYTES
5315 diff -urNp linux-2.6.27.10/arch/x86/kernel/i386_ksyms_32.c linux-2.6.27.10/arch/x86/kernel/i386_ksyms_32.c
5316 --- linux-2.6.27.10/arch/x86/kernel/i386_ksyms_32.c 2008-11-07 12:55:34.000000000 -0500
5317 +++ linux-2.6.27.10/arch/x86/kernel/i386_ksyms_32.c 2008-11-18 03:38:44.000000000 -0500
5319 EXPORT_SYMBOL(mcount);
5322 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
5324 /* Networking helper routines. */
5325 EXPORT_SYMBOL(csum_partial_copy_generic);
5326 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
5327 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
5329 EXPORT_SYMBOL(__get_user_1);
5330 EXPORT_SYMBOL(__get_user_2);
5331 @@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr);
5333 EXPORT_SYMBOL(csum_partial);
5334 EXPORT_SYMBOL(empty_zero_page);
5336 +#ifdef CONFIG_PAX_KERNEXEC
5337 +EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
5339 diff -urNp linux-2.6.27.10/arch/x86/kernel/init_task.c linux-2.6.27.10/arch/x86/kernel/init_task.c
5340 --- linux-2.6.27.10/arch/x86/kernel/init_task.c 2008-11-07 12:55:34.000000000 -0500
5341 +++ linux-2.6.27.10/arch/x86/kernel/init_task.c 2008-11-18 03:38:44.000000000 -0500
5342 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
5343 * section. Since TSS's are completely CPU-local, we want them
5344 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
5346 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
5348 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
5349 +EXPORT_SYMBOL(init_tss);
5350 diff -urNp linux-2.6.27.10/arch/x86/kernel/ioport.c linux-2.6.27.10/arch/x86/kernel/ioport.c
5351 --- linux-2.6.27.10/arch/x86/kernel/ioport.c 2008-11-07 12:55:34.000000000 -0500
5352 +++ linux-2.6.27.10/arch/x86/kernel/ioport.c 2008-11-18 03:38:44.000000000 -0500
5354 #include <linux/slab.h>
5355 #include <linux/thread_info.h>
5356 #include <linux/syscalls.h>
5357 +#include <linux/grsecurity.h>
5359 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
5360 static void set_bitmap(unsigned long *bitmap, unsigned int base,
5361 @@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
5363 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
5365 +#ifdef CONFIG_GRKERNSEC_IO
5367 + gr_handle_ioperm();
5371 if (turn_on && !capable(CAP_SYS_RAWIO))
5374 @@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
5375 * because the ->io_bitmap_max value must match the bitmap
5378 - tss = &per_cpu(init_tss, get_cpu());
5379 + tss = init_tss + get_cpu();
5381 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5383 @@ -121,8 +128,13 @@ static int do_iopl(unsigned int level, s
5385 /* Trying to gain more privileges? */
5387 +#ifdef CONFIG_GRKERNSEC_IO
5391 if (!capable(CAP_SYS_RAWIO))
5395 regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
5397 diff -urNp linux-2.6.27.10/arch/x86/kernel/irq_32.c linux-2.6.27.10/arch/x86/kernel/irq_32.c
5398 --- linux-2.6.27.10/arch/x86/kernel/irq_32.c 2008-11-07 12:55:34.000000000 -0500
5399 +++ linux-2.6.27.10/arch/x86/kernel/irq_32.c 2008-11-18 03:38:44.000000000 -0500
5400 @@ -116,7 +116,7 @@ execute_on_irq_stack(int overflow, struc
5403 /* build the stack frame on the IRQ stack */
5404 - isp = (u32 *) ((char*)irqctx + sizeof(*irqctx));
5405 + isp = (u32 *) ((char*)irqctx + sizeof(*irqctx) - 8);
5406 irqctx->tinfo.task = curctx->tinfo.task;
5407 irqctx->tinfo.previous_esp = current_stack_pointer;
5409 @@ -197,7 +197,7 @@ asmlinkage void do_softirq(void)
5410 irqctx->tinfo.previous_esp = current_stack_pointer;
5412 /* build the stack frame on the softirq stack */
5413 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5414 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5416 call_on_stack(__do_softirq, isp);
5418 diff -urNp linux-2.6.27.10/arch/x86/kernel/kprobes.c linux-2.6.27.10/arch/x86/kernel/kprobes.c
5419 --- linux-2.6.27.10/arch/x86/kernel/kprobes.c 2008-11-07 12:55:34.000000000 -0500
5420 +++ linux-2.6.27.10/arch/x86/kernel/kprobes.c 2008-11-18 04:48:35.000000000 -0500
5421 @@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
5424 } __attribute__((packed)) * jop;
5425 - jop = (struct __arch_jmp_op *)from;
5427 +#ifdef CONFIG_PAX_KERNEXEC
5428 + unsigned long cr0;
5431 + jop = (struct __arch_jmp_op *)(ktla_ktva(from));
5433 +#ifdef CONFIG_PAX_KERNEXEC
5434 + pax_open_kernel(cr0);
5437 jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
5438 jop->op = RELATIVEJUMP_INSTRUCTION;
5440 +#ifdef CONFIG_PAX_KERNEXEC
5441 + pax_close_kernel(cr0);
5447 @@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
5449 static void __kprobes arch_copy_kprobe(struct kprobe *p)
5451 - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5453 +#ifdef CONFIG_PAX_KERNEXEC
5454 + unsigned long cr0;
5457 +#ifdef CONFIG_PAX_KERNEXEC
5458 + pax_open_kernel(cr0);
5461 + memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5463 +#ifdef CONFIG_PAX_KERNEXEC
5464 + pax_close_kernel(cr0);
5469 - if (can_boost(p->addr))
5470 + if (can_boost(ktla_ktva(p->addr)))
5471 p->ainsn.boostable = 0;
5473 p->ainsn.boostable = -1;
5475 - p->opcode = *p->addr;
5476 + p->opcode = *(ktla_ktva(p->addr));
5479 int __kprobes arch_prepare_kprobe(struct kprobe *p)
5480 @@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
5481 if (p->opcode == BREAKPOINT_INSTRUCTION)
5482 regs->ip = (unsigned long)p->addr;
5484 - regs->ip = (unsigned long)p->ainsn.insn;
5485 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5488 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
5489 @@ -449,7 +477,7 @@ static void __kprobes setup_singlestep(s
5490 if (p->ainsn.boostable == 1 && !p->post_handler) {
5491 /* Boost up -- we can execute copied instructions directly */
5492 reset_current_kprobe();
5493 - regs->ip = (unsigned long)p->ainsn.insn;
5494 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5495 preempt_enable_no_resched();
5498 @@ -519,7 +547,7 @@ static int __kprobes kprobe_handler(stru
5499 struct kprobe_ctlblk *kcb;
5501 addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
5502 - if (*addr != BREAKPOINT_INSTRUCTION) {
5503 + if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
5505 * The breakpoint instruction was removed right
5506 * after we hit it. Another cpu has removed
5507 @@ -770,7 +798,7 @@ static void __kprobes resume_execution(s
5508 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
5510 unsigned long *tos = stack_addr(regs);
5511 - unsigned long copy_ip = (unsigned long)p->ainsn.insn;
5512 + unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
5513 unsigned long orig_ip = (unsigned long)p->addr;
5514 kprobe_opcode_t *insn = p->ainsn.insn;
5516 @@ -953,7 +981,7 @@ int __kprobes kprobe_exceptions_notify(s
5517 struct die_args *args = data;
5518 int ret = NOTIFY_DONE;
5520 - if (args->regs && user_mode_vm(args->regs))
5521 + if (args->regs && user_mode(args->regs))
5525 diff -urNp linux-2.6.27.10/arch/x86/kernel/ldt.c linux-2.6.27.10/arch/x86/kernel/ldt.c
5526 --- linux-2.6.27.10/arch/x86/kernel/ldt.c 2008-11-07 12:55:34.000000000 -0500
5527 +++ linux-2.6.27.10/arch/x86/kernel/ldt.c 2008-11-18 03:38:44.000000000 -0500
5528 @@ -63,13 +63,13 @@ static int alloc_ldt(mm_context_t *pc, i
5533 + load_LDT_nolock(pc);
5534 if (!cpus_equal(current->mm->cpu_vm_mask,
5535 cpumask_of_cpu(smp_processor_id())))
5536 smp_call_function(flush_ldt, current->mm, 1);
5540 + load_LDT_nolock(pc);
5544 @@ -108,6 +108,24 @@ int init_new_context(struct task_struct
5545 retval = copy_ldt(&mm->context, &old_mm->context);
5546 mutex_unlock(&old_mm->context.lock);
5549 + if (tsk == current) {
5550 + mm->context.vdso = ~0UL;
5552 +#ifdef CONFIG_X86_32
5553 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5554 + mm->context.user_cs_base = 0UL;
5555 + mm->context.user_cs_limit = ~0UL;
5557 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5558 + cpus_clear(mm->context.cpu_user_cs_mask);
5569 @@ -221,6 +239,13 @@ static int write_ldt(void __user *ptr, u
5573 +#ifdef CONFIG_PAX_SEGMEXEC
5574 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
5580 fill_ldt(&ldt, &ldt_info);
5583 diff -urNp linux-2.6.27.10/arch/x86/kernel/machine_kexec_32.c linux-2.6.27.10/arch/x86/kernel/machine_kexec_32.c
5584 --- linux-2.6.27.10/arch/x86/kernel/machine_kexec_32.c 2008-11-07 12:55:34.000000000 -0500
5585 +++ linux-2.6.27.10/arch/x86/kernel/machine_kexec_32.c 2008-11-18 03:38:44.000000000 -0500
5586 @@ -34,7 +34,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
5587 static u32 kexec_pte0[1024] PAGE_ALIGNED;
5588 static u32 kexec_pte1[1024] PAGE_ALIGNED;
5590 -static void set_idt(void *newidt, __u16 limit)
5591 +static void set_idt(struct desc_struct *newidt, __u16 limit)
5593 struct desc_ptr curidt;
5595 @@ -46,7 +46,7 @@ static void set_idt(void *newidt, __u16
5599 -static void set_gdt(void *newgdt, __u16 limit)
5600 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
5602 struct desc_ptr curgdt;
5604 @@ -145,7 +145,7 @@ void machine_kexec(struct kimage *image)
5607 control_page = page_address(image->control_code_page);
5608 - memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
5609 + memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
5611 relocate_kernel_ptr = control_page;
5612 page_list[PA_CONTROL_PAGE] = __pa(control_page);
5613 diff -urNp linux-2.6.27.10/arch/x86/kernel/module_32.c linux-2.6.27.10/arch/x86/kernel/module_32.c
5614 --- linux-2.6.27.10/arch/x86/kernel/module_32.c 2008-11-07 12:55:34.000000000 -0500
5615 +++ linux-2.6.27.10/arch/x86/kernel/module_32.c 2008-11-18 03:38:44.000000000 -0500
5617 #include <linux/kernel.h>
5618 #include <linux/bug.h>
5620 +#include <asm/desc.h>
5621 +#include <asm/pgtable.h>
5624 #define DEBUGP printk
5626 @@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
5631 +#ifdef CONFIG_PAX_KERNEXEC
5632 + return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
5634 return vmalloc_exec(size);
5639 +#ifdef CONFIG_PAX_KERNEXEC
5640 +void *module_alloc_exec(unsigned long size)
5642 + struct vm_struct *area;
5647 + area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
5649 + return area->addr;
5653 +EXPORT_SYMBOL(module_alloc_exec);
5656 /* Free memory returned from module_alloc */
5657 void module_free(struct module *mod, void *module_region)
5658 @@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
5662 +#ifdef CONFIG_PAX_KERNEXEC
5663 +void module_free_exec(struct module *mod, void *module_region)
5665 + struct vm_struct **p, *tmp;
5667 + if (!module_region)
5670 + if ((PAGE_SIZE-1) & (unsigned long)module_region) {
5671 + printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
5676 + write_lock(&vmlist_lock);
5677 + for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
5678 + if (tmp->addr == module_region)
5682 + unsigned long cr0;
5684 + pax_open_kernel(cr0);
5685 + memset(tmp->addr, 0xCC, tmp->size);
5686 + pax_close_kernel(cr0);
5691 + write_unlock(&vmlist_lock);
5694 + printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
5701 /* We don't need anything special. */
5702 int module_frob_arch_sections(Elf_Ehdr *hdr,
5704 @@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5706 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
5708 - uint32_t *location;
5709 + uint32_t *plocation, location;
5711 +#ifdef CONFIG_PAX_KERNEXEC
5712 + unsigned long cr0;
5715 DEBUGP("Applying relocate section %u to %u\n", relsec,
5716 sechdrs[relsec].sh_info);
5717 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
5718 /* This is where to make the change */
5719 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
5720 - + rel[i].r_offset;
5721 + plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
5722 + location = (uint32_t)plocation;
5723 + if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
5724 + plocation = ktla_ktva((void *)plocation);
5725 /* This is the symbol it is referring to. Note that all
5726 undefined symbols have been resolved. */
5727 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
5728 @@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5730 switch (ELF32_R_TYPE(rel[i].r_info)) {
5733 +#ifdef CONFIG_PAX_KERNEXEC
5734 + pax_open_kernel(cr0);
5737 /* We add the value into the location given */
5738 - *location += sym->st_value;
5739 + *plocation += sym->st_value;
5741 +#ifdef CONFIG_PAX_KERNEXEC
5742 + pax_close_kernel(cr0);
5748 +#ifdef CONFIG_PAX_KERNEXEC
5749 + pax_open_kernel(cr0);
5752 /* Add the value, subtract its postition */
5753 - *location += sym->st_value - (uint32_t)location;
5754 + *plocation += sym->st_value - location;
5756 +#ifdef CONFIG_PAX_KERNEXEC
5757 + pax_close_kernel(cr0);
5762 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
5763 diff -urNp linux-2.6.27.10/arch/x86/kernel/module_64.c linux-2.6.27.10/arch/x86/kernel/module_64.c
5764 --- linux-2.6.27.10/arch/x86/kernel/module_64.c 2008-11-07 12:55:34.000000000 -0500
5765 +++ linux-2.6.27.10/arch/x86/kernel/module_64.c 2008-11-18 03:38:44.000000000 -0500
5766 @@ -40,7 +40,7 @@ void module_free(struct module *mod, voi
5770 -void *module_alloc(unsigned long size)
5771 +static void *__module_alloc(unsigned long size, pgprot_t prot)
5773 struct vm_struct *area;
5775 @@ -54,8 +54,31 @@ void *module_alloc(unsigned long size)
5779 - return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
5780 + return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
5783 +#ifdef CONFIG_PAX_KERNEXEC
5784 +void *module_alloc(unsigned long size)
5786 + return __module_alloc(size, PAGE_KERNEL);
5789 +void module_free_exec(struct module *mod, void *module_region)
5791 + module_free(mod, module_region);
5794 +void *module_alloc_exec(unsigned long size)
5796 + return __module_alloc(size, PAGE_KERNEL_RX);
5799 +void *module_alloc(unsigned long size)
5801 + return __module_alloc(size, PAGE_KERNEL_EXEC);
5807 /* We don't need anything special. */
5808 @@ -77,7 +100,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
5809 Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
5815 +#ifdef CONFIG_PAX_KERNEXEC
5816 + unsigned long cr0;
5819 DEBUGP("Applying relocate section %u to %u\n", relsec,
5820 sechdrs[relsec].sh_info);
5821 @@ -101,21 +128,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
5826 +#ifdef CONFIG_PAX_KERNEXEC
5827 + pax_open_kernel(cr0);
5832 +#ifdef CONFIG_PAX_KERNEXEC
5833 + pax_close_kernel(cr0);
5839 +#ifdef CONFIG_PAX_KERNEXEC
5840 + pax_open_kernel(cr0);
5845 +#ifdef CONFIG_PAX_KERNEXEC
5846 + pax_close_kernel(cr0);
5849 if (val != *(u32 *)loc)
5854 +#ifdef CONFIG_PAX_KERNEXEC
5855 + pax_open_kernel(cr0);
5860 +#ifdef CONFIG_PAX_KERNEXEC
5861 + pax_close_kernel(cr0);
5864 if ((s64)val != *(s32 *)loc)
5870 +#ifdef CONFIG_PAX_KERNEXEC
5871 + pax_open_kernel(cr0);
5876 +#ifdef CONFIG_PAX_KERNEXEC
5877 + pax_close_kernel(cr0);
5881 if ((s64)val != *(s32 *)loc)
5883 diff -urNp linux-2.6.27.10/arch/x86/kernel/paravirt.c linux-2.6.27.10/arch/x86/kernel/paravirt.c
5884 --- linux-2.6.27.10/arch/x86/kernel/paravirt.c 2008-11-07 12:55:34.000000000 -0500
5885 +++ linux-2.6.27.10/arch/x86/kernel/paravirt.c 2008-11-18 03:38:44.000000000 -0500
5886 @@ -44,7 +44,7 @@ void _paravirt_nop(void)
5890 -static void __init default_banner(void)
5891 +static void default_banner(void)
5893 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
5895 @@ -164,7 +164,7 @@ unsigned paravirt_patch_insns(void *insn
5896 if (insn_len > len || start == NULL)
5899 - memcpy(insnbuf, start, insn_len);
5900 + memcpy(insnbuf, ktla_ktva(start), insn_len);
5904 @@ -279,21 +279,21 @@ void __init paravirt_use_bytelocks(void)
5908 -struct pv_info pv_info = {
5909 +struct pv_info pv_info __read_only = {
5910 .name = "bare hardware",
5911 .paravirt_enabled = 0,
5913 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
5916 -struct pv_init_ops pv_init_ops = {
5917 +struct pv_init_ops pv_init_ops __read_only = {
5918 .patch = native_patch,
5919 .banner = default_banner,
5920 .arch_setup = paravirt_nop,
5921 .memory_setup = machine_specific_memory_setup,
5924 -struct pv_time_ops pv_time_ops = {
5925 +struct pv_time_ops pv_time_ops __read_only = {
5926 .time_init = hpet_time_init,
5927 .get_wallclock = native_get_wallclock,
5928 .set_wallclock = native_set_wallclock,
5929 @@ -301,7 +301,7 @@ struct pv_time_ops pv_time_ops = {
5930 .get_tsc_khz = native_calibrate_tsc,
5933 -struct pv_irq_ops pv_irq_ops = {
5934 +struct pv_irq_ops pv_irq_ops __read_only = {
5935 .init_IRQ = native_init_IRQ,
5936 .save_fl = native_save_fl,
5937 .restore_fl = native_restore_fl,
5938 @@ -314,7 +314,7 @@ struct pv_irq_ops pv_irq_ops = {
5942 -struct pv_cpu_ops pv_cpu_ops = {
5943 +struct pv_cpu_ops pv_cpu_ops __read_only = {
5944 .cpuid = native_cpuid,
5945 .get_debugreg = native_get_debugreg,
5946 .set_debugreg = native_set_debugreg,
5947 @@ -371,7 +371,7 @@ struct pv_cpu_ops pv_cpu_ops = {
5951 -struct pv_apic_ops pv_apic_ops = {
5952 +struct pv_apic_ops pv_apic_ops __read_only = {
5953 #ifdef CONFIG_X86_LOCAL_APIC
5954 .apic_write = native_apic_write,
5955 .apic_read = native_apic_read,
5956 @@ -381,7 +381,7 @@ struct pv_apic_ops pv_apic_ops = {
5960 -struct pv_mmu_ops pv_mmu_ops = {
5961 +struct pv_mmu_ops pv_mmu_ops __read_only = {
5962 #ifndef CONFIG_X86_64
5963 .pagetable_setup_start = native_pagetable_setup_start,
5964 .pagetable_setup_done = native_pagetable_setup_done,
5965 @@ -461,7 +461,7 @@ struct pv_mmu_ops pv_mmu_ops = {
5966 .set_fixmap = native_set_fixmap,
5969 -struct pv_lock_ops pv_lock_ops = {
5970 +struct pv_lock_ops pv_lock_ops __read_only = {
5972 .spin_is_locked = __ticket_spin_is_locked,
5973 .spin_is_contended = __ticket_spin_is_contended,
5974 diff -urNp linux-2.6.27.10/arch/x86/kernel/process_32.c linux-2.6.27.10/arch/x86/kernel/process_32.c
5975 --- linux-2.6.27.10/arch/x86/kernel/process_32.c 2008-11-07 12:55:34.000000000 -0500
5976 +++ linux-2.6.27.10/arch/x86/kernel/process_32.c 2008-11-18 03:38:44.000000000 -0500
5977 @@ -62,8 +62,10 @@ asmlinkage void ret_from_fork(void) __as
5978 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
5979 EXPORT_PER_CPU_SYMBOL(current_task);
5982 DEFINE_PER_CPU(int, cpu_number);
5983 EXPORT_PER_CPU_SYMBOL(cpu_number);
5987 * Return saved PC of a blocked thread.
5988 @@ -71,6 +73,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
5989 unsigned long thread_saved_pc(struct task_struct *tsk)
5991 return ((unsigned long *)tsk->thread.sp)[3];
5992 +//XXX return tsk->thread.eip;
5995 #ifdef CONFIG_HOTPLUG_CPU
5996 @@ -162,7 +165,7 @@ void __show_registers(struct pt_regs *re
5998 unsigned short ss, gs;
6000 - if (user_mode_vm(regs)) {
6001 + if (user_mode(regs)) {
6003 ss = regs->ss & 0xffff;
6004 savesegment(gs, gs);
6005 @@ -239,8 +242,8 @@ int kernel_thread(int (*fn)(void *), voi
6006 regs.bx = (unsigned long) fn;
6007 regs.dx = (unsigned long) arg;
6009 - regs.ds = __USER_DS;
6010 - regs.es = __USER_DS;
6011 + regs.ds = __KERNEL_DS;
6012 + regs.es = __KERNEL_DS;
6013 regs.fs = __KERNEL_PERCPU;
6015 regs.ip = (unsigned long) kernel_thread_helper;
6016 @@ -262,7 +265,7 @@ void exit_thread(void)
6017 struct task_struct *tsk = current;
6018 struct thread_struct *t = &tsk->thread;
6019 int cpu = get_cpu();
6020 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
6021 + struct tss_struct *tss = init_tss + cpu;
6023 kfree(t->io_bitmap_ptr);
6024 t->io_bitmap_ptr = NULL;
6025 @@ -283,6 +286,7 @@ void flush_thread(void)
6027 struct task_struct *tsk = current;
6029 + loadsegment(gs, 0);
6030 tsk->thread.debugreg0 = 0;
6031 tsk->thread.debugreg1 = 0;
6032 tsk->thread.debugreg2 = 0;
6033 @@ -322,7 +326,7 @@ int copy_thread(int nr, unsigned long cl
6034 struct task_struct *tsk;
6037 - childregs = task_pt_regs(p);
6038 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
6042 @@ -351,6 +355,7 @@ int copy_thread(int nr, unsigned long cl
6043 * Set a new TLS for the child thread?
6045 if (clone_flags & CLONE_SETTLS)
6046 +//XXX needs set_fs()?
6047 err = do_set_thread_area(p, -1,
6048 (struct user_desc __user *)childregs->si, 0);
6050 @@ -550,7 +555,7 @@ struct task_struct * __switch_to(struct
6051 struct thread_struct *prev = &prev_p->thread,
6052 *next = &next_p->thread;
6053 int cpu = smp_processor_id();
6054 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
6055 + struct tss_struct *tss = init_tss + cpu;
6057 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
6059 @@ -578,6 +583,11 @@ struct task_struct * __switch_to(struct
6061 savesegment(gs, prev->gs);
6063 +#ifdef CONFIG_PAX_MEMORY_UDEREF
6064 + if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
6065 + __set_fs(task_thread_info(next_p)->addr_limit, cpu);
6069 * Load the per-thread Thread-Local Storage descriptor.
6071 @@ -716,15 +726,27 @@ unsigned long get_wchan(struct task_stru
6075 -unsigned long arch_align_stack(unsigned long sp)
6076 +#ifdef CONFIG_PAX_RANDKSTACK
6077 +asmlinkage void pax_randomize_kstack(void)
6079 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6080 - sp -= get_random_int() % 8192;
6083 + struct thread_struct *thread = ¤t->thread;
6084 + unsigned long time;
6086 -unsigned long arch_randomize_brk(struct mm_struct *mm)
6088 - unsigned long range_end = mm->brk + 0x02000000;
6089 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
6090 + if (!randomize_va_space)
6095 + /* P4 seems to return a 0 LSB, ignore it */
6096 +#ifdef CONFIG_MPENTIUM4
6104 + thread->sp0 ^= time;
6105 + load_sp0(init_tss + smp_processor_id(), thread);
6108 diff -urNp linux-2.6.27.10/arch/x86/kernel/process_64.c linux-2.6.27.10/arch/x86/kernel/process_64.c
6109 --- linux-2.6.27.10/arch/x86/kernel/process_64.c 2008-11-07 12:55:34.000000000 -0500
6110 +++ linux-2.6.27.10/arch/x86/kernel/process_64.c 2008-11-18 03:38:44.000000000 -0500
6111 @@ -119,6 +119,8 @@ static inline void play_dead(void)
6114 current_thread_info()->status |= TS_POLLING;
6115 + current->stack_canary = pax_get_random_long();
6116 + write_pda(stack_canary, current->stack_canary);
6117 /* endless idle loop with no priority at all */
6119 tick_nohz_stop_sched_tick(1);
6120 @@ -228,7 +230,7 @@ void exit_thread(void)
6121 struct thread_struct *t = &me->thread;
6123 if (me->thread.io_bitmap_ptr) {
6124 - struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
6125 + struct tss_struct *tss = init_tss + get_cpu();
6127 kfree(t->io_bitmap_ptr);
6128 t->io_bitmap_ptr = NULL;
6129 @@ -541,7 +543,7 @@ __switch_to(struct task_struct *prev_p,
6130 struct thread_struct *prev = &prev_p->thread;
6131 struct thread_struct *next = &next_p->thread;
6132 int cpu = smp_processor_id();
6133 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
6134 + struct tss_struct *tss = init_tss + cpu;
6135 unsigned fsindex, gsindex;
6137 /* we're going to use this soon, after a few expensive things */
6138 @@ -630,7 +632,6 @@ __switch_to(struct task_struct *prev_p,
6139 (unsigned long)task_stack_page(next_p) +
6140 THREAD_SIZE - PDA_STACKOFFSET);
6141 #ifdef CONFIG_CC_STACKPROTECTOR
6142 - write_pda(stack_canary, next_p->stack_canary);
6144 * Build time only check to make sure the stack_canary is at
6145 * offset 40 in the pda; this is a gcc ABI requirement
6146 @@ -729,12 +730,11 @@ unsigned long get_wchan(struct task_stru
6147 if (!p || p == current || p->state==TASK_RUNNING)
6149 stack = (unsigned long)task_stack_page(p);
6150 - if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
6151 + if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
6153 fp = *(u64 *)(p->thread.sp);
6155 - if (fp < (unsigned long)stack ||
6156 - fp >= (unsigned long)stack+THREAD_SIZE)
6157 + if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
6159 ip = *(u64 *)(fp+8);
6160 if (!in_sched_functions(ip))
6161 @@ -844,16 +844,3 @@ long sys_arch_prctl(int code, unsigned l
6163 return do_arch_prctl(current, code, addr);
6166 -unsigned long arch_align_stack(unsigned long sp)
6168 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6169 - sp -= get_random_int() % 8192;
6173 -unsigned long arch_randomize_brk(struct mm_struct *mm)
6175 - unsigned long range_end = mm->brk + 0x02000000;
6176 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
6178 diff -urNp linux-2.6.27.10/arch/x86/kernel/ptrace.c linux-2.6.27.10/arch/x86/kernel/ptrace.c
6179 --- linux-2.6.27.10/arch/x86/kernel/ptrace.c 2008-11-07 12:55:34.000000000 -0500
6180 +++ linux-2.6.27.10/arch/x86/kernel/ptrace.c 2008-11-18 03:38:44.000000000 -0500
6181 @@ -1369,7 +1369,7 @@ void send_sigtrap(struct task_struct *ts
6182 info.si_code = TRAP_BRKPT;
6185 - info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
6186 + info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
6188 /* Send us the fake SIGTRAP */
6189 force_sig_info(SIGTRAP, &info, tsk);
6190 diff -urNp linux-2.6.27.10/arch/x86/kernel/reboot.c linux-2.6.27.10/arch/x86/kernel/reboot.c
6191 --- linux-2.6.27.10/arch/x86/kernel/reboot.c 2008-11-07 12:55:34.000000000 -0500
6192 +++ linux-2.6.27.10/arch/x86/kernel/reboot.c 2008-11-18 03:38:44.000000000 -0500
6193 @@ -28,7 +28,7 @@ void (*pm_power_off)(void);
6194 EXPORT_SYMBOL(pm_power_off);
6196 static const struct desc_ptr no_idt = {};
6197 -static int reboot_mode;
6198 +static unsigned short reboot_mode;
6199 enum reboot_type reboot_type = BOOT_KBD;
6202 @@ -193,7 +193,7 @@ static struct dmi_system_id __initdata r
6203 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
6207 + { NULL, NULL, {{0, NULL}}, NULL}
6210 static int __init reboot_init(void)
6211 @@ -209,12 +209,12 @@ core_initcall(reboot_init);
6212 controller to pulse the CPU reset line, which is more thorough, but
6213 doesn't work with at least one type of 486 motherboard. It is easy
6214 to stop this code working; hence the copious comments. */
6215 -static const unsigned long long
6216 -real_mode_gdt_entries [3] =
6217 +static struct desc_struct
6218 +real_mode_gdt_entries [3] __read_only =
6220 - 0x0000000000000000ULL, /* Null descriptor */
6221 - 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
6222 - 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
6223 + {{{0x00000000, 0x00000000}}}, /* Null descriptor */
6224 + {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
6225 + {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
6228 static const struct desc_ptr
6229 @@ -263,7 +263,7 @@ static const unsigned char jump_to_bios
6230 * specified by the code and length parameters.
6231 * We assume that length will aways be less that 100!
6233 -void machine_real_restart(const unsigned char *code, int length)
6234 +void machine_real_restart(const unsigned char *code, unsigned int length)
6236 local_irq_disable();
6238 @@ -283,8 +283,8 @@ void machine_real_restart(const unsigned
6239 /* Remap the kernel at virtual address zero, as well as offset zero
6240 from the kernel segment. This assumes the kernel segment starts at
6241 virtual address PAGE_OFFSET. */
6242 - memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6243 - sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
6244 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6245 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
6248 * Use `swapper_pg_dir' as our page directory.
6249 @@ -296,16 +296,15 @@ void machine_real_restart(const unsigned
6250 boot)". This seems like a fairly standard thing that gets set by
6251 REBOOT.COM programs, and the previous reset routine did this
6253 - *((unsigned short *)0x472) = reboot_mode;
6254 + *(unsigned short *)(__va(0x472)) = reboot_mode;
6256 /* For the switch to real mode, copy some code to low memory. It has
6257 to be in the first 64k because it is running in 16-bit mode, and it
6258 has to have the same physical and virtual address, because it turns
6259 off paging. Copy it near the end of the first page, out of the way
6260 of BIOS variables. */
6261 - memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
6262 - real_mode_switch, sizeof (real_mode_switch));
6263 - memcpy((void *)(0x1000 - 100), code, length);
6264 + memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
6265 + memcpy(__va(0x1000 - 100), code, length);
6267 /* Set up the IDT for real mode. */
6268 load_idt(&real_mode_idt);
6269 diff -urNp linux-2.6.27.10/arch/x86/kernel/setup.c linux-2.6.27.10/arch/x86/kernel/setup.c
6270 --- linux-2.6.27.10/arch/x86/kernel/setup.c 2008-12-21 01:18:11.000000000 -0500
6271 +++ linux-2.6.27.10/arch/x86/kernel/setup.c 2008-12-21 01:18:21.000000000 -0500
6272 @@ -578,6 +578,7 @@ static struct x86_quirks default_x86_qui
6274 struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
6276 +#ifdef CONFIG_X86_RESERVE_LOW_64K
6277 static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
6280 @@ -589,6 +590,7 @@ static int __init dmi_low_memory_corrupt
6286 /* List of systems that have known low memory corruption BIOS problems */
6287 static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
6288 @@ -685,8 +687,8 @@ void __init setup_arch(char **cmdline_p)
6290 if (!boot_params.hdr.root_flags)
6291 root_mountflags &= ~MS_RDONLY;
6292 - init_mm.start_code = (unsigned long) _text;
6293 - init_mm.end_code = (unsigned long) _etext;
6294 + init_mm.start_code = ktla_ktva((unsigned long) _text);
6295 + init_mm.end_code = ktla_ktva((unsigned long) _etext);
6296 init_mm.end_data = (unsigned long) _edata;
6297 #ifdef CONFIG_X86_32
6298 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
6299 @@ -694,9 +696,9 @@ void __init setup_arch(char **cmdline_p)
6300 init_mm.brk = (unsigned long) &_end;
6303 - code_resource.start = virt_to_phys(_text);
6304 - code_resource.end = virt_to_phys(_etext)-1;
6305 - data_resource.start = virt_to_phys(_etext);
6306 + code_resource.start = virt_to_phys(ktla_ktva(_text));
6307 + code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
6308 + data_resource.start = virt_to_phys(_data);
6309 data_resource.end = virt_to_phys(_edata)-1;
6310 bss_resource.start = virt_to_phys(&__bss_start);
6311 bss_resource.end = virt_to_phys(&__bss_stop)-1;
6312 diff -urNp linux-2.6.27.10/arch/x86/kernel/setup_percpu.c linux-2.6.27.10/arch/x86/kernel/setup_percpu.c
6313 --- linux-2.6.27.10/arch/x86/kernel/setup_percpu.c 2008-11-07 12:55:34.000000000 -0500
6314 +++ linux-2.6.27.10/arch/x86/kernel/setup_percpu.c 2008-11-18 03:38:44.000000000 -0500
6315 @@ -166,7 +166,11 @@ void __init setup_per_cpu_areas(void)
6317 ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
6319 +#ifdef CONFIG_X86_32
6320 + __per_cpu_offset[cpu] = ptr - __per_cpu_start;
6322 per_cpu_offset(cpu) = ptr - __per_cpu_start;
6324 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
6327 diff -urNp linux-2.6.27.10/arch/x86/kernel/signal_32.c linux-2.6.27.10/arch/x86/kernel/signal_32.c
6328 --- linux-2.6.27.10/arch/x86/kernel/signal_32.c 2008-11-07 12:55:34.000000000 -0500
6329 +++ linux-2.6.27.10/arch/x86/kernel/signal_32.c 2008-11-18 03:38:44.000000000 -0500
6330 @@ -378,9 +378,9 @@ setup_frame(int sig, struct k_sigaction
6333 if (current->mm->context.vdso)
6334 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
6335 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
6337 - restorer = &frame->retcode;
6338 + restorer = (void __user *)&frame->retcode;
6339 if (ka->sa.sa_flags & SA_RESTORER)
6340 restorer = ka->sa.sa_restorer;
6342 @@ -460,7 +460,7 @@ static int setup_rt_frame(int sig, struc
6345 /* Set up to return from userspace. */
6346 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6347 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6348 if (ka->sa.sa_flags & SA_RESTORER)
6349 restorer = ka->sa.sa_restorer;
6350 err |= __put_user(restorer, &frame->pretcode);
6351 @@ -590,7 +590,7 @@ static void do_signal(struct pt_regs *re
6352 * X86_32: vm86 regs switched out by assembly code before reaching
6353 * here, so testing against kernel CS suffices.
6355 - if (!user_mode(regs))
6356 + if (!user_mode_novm(regs))
6359 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
6360 diff -urNp linux-2.6.27.10/arch/x86/kernel/signal_64.c linux-2.6.27.10/arch/x86/kernel/signal_64.c
6361 --- linux-2.6.27.10/arch/x86/kernel/signal_64.c 2008-11-07 12:55:34.000000000 -0500
6362 +++ linux-2.6.27.10/arch/x86/kernel/signal_64.c 2008-11-18 03:38:44.000000000 -0500
6363 @@ -312,8 +312,8 @@ static int setup_rt_frame(int sig, struc
6364 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
6365 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
6366 if (sizeof(*set) == 16) {
6367 - __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6368 - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6369 + err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6370 + err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6372 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
6374 diff -urNp linux-2.6.27.10/arch/x86/kernel/smpboot.c linux-2.6.27.10/arch/x86/kernel/smpboot.c
6375 --- linux-2.6.27.10/arch/x86/kernel/smpboot.c 2008-12-21 01:18:11.000000000 -0500
6376 +++ linux-2.6.27.10/arch/x86/kernel/smpboot.c 2008-12-21 01:18:21.000000000 -0500
6377 @@ -814,6 +814,11 @@ static int __cpuinit do_boot_cpu(int api
6379 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
6382 +#ifdef CONFIG_PAX_KERNEXEC
6383 + unsigned long cr0;
6386 INIT_WORK(&c_idle.work, do_fork_idle);
6388 #ifdef CONFIG_X86_64
6389 @@ -864,7 +869,17 @@ do_rest:
6390 cpu_pda(cpu)->pcurrent = c_idle.idle;
6391 clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
6394 +#ifdef CONFIG_PAX_KERNEXEC
6395 + pax_open_kernel(cr0);
6398 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
6400 +#ifdef CONFIG_PAX_KERNEXEC
6401 + pax_close_kernel(cr0);
6404 initial_code = (unsigned long)start_secondary;
6405 stack_start.sp = (void *) c_idle.idle->thread.sp;
6407 diff -urNp linux-2.6.27.10/arch/x86/kernel/smpcommon.c linux-2.6.27.10/arch/x86/kernel/smpcommon.c
6408 --- linux-2.6.27.10/arch/x86/kernel/smpcommon.c 2008-11-07 12:55:34.000000000 -0500
6409 +++ linux-2.6.27.10/arch/x86/kernel/smpcommon.c 2008-11-18 03:38:44.000000000 -0500
6412 #include <linux/module.h>
6413 #include <asm/smp.h>
6414 +#include <asm/sections.h>
6416 #ifdef CONFIG_X86_32
6417 -DEFINE_PER_CPU(unsigned long, this_cpu_off);
6418 +DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
6419 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6422 @@ -15,16 +16,19 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6424 __cpuinit void init_gdt(int cpu)
6426 - struct desc_struct gdt;
6427 + struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
6428 + unsigned long base, limit;
6430 - pack_descriptor(&gdt, __per_cpu_offset[cpu], 0xFFFFF,
6431 - 0x2 | DESCTYPE_S, 0x8);
6433 + base = per_cpu_offset(cpu);
6434 + limit = PERCPU_ENOUGH_ROOM - 1;
6435 + if (limit < 64*1024)
6436 + pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
6438 + pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
6440 - write_gdt_entry(get_cpu_gdt_table(cpu),
6441 - GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
6442 + write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
6444 - per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
6445 + per_cpu(this_cpu_off, cpu) = base;
6446 per_cpu(cpu_number, cpu) = cpu;
6449 diff -urNp linux-2.6.27.10/arch/x86/kernel/step.c linux-2.6.27.10/arch/x86/kernel/step.c
6450 --- linux-2.6.27.10/arch/x86/kernel/step.c 2008-11-07 12:55:34.000000000 -0500
6451 +++ linux-2.6.27.10/arch/x86/kernel/step.c 2008-11-18 03:38:44.000000000 -0500
6452 @@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
6453 * and APM bios ones we just ignore here.
6455 if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
6457 + struct desc_struct *desc;
6463 mutex_lock(&child->mm->context.lock);
6464 - if (unlikely((seg >> 3) >= child->mm->context.size))
6465 - addr = -1L; /* bogus selector, access would fault */
6466 + if (unlikely(seg >= child->mm->context.size))
6469 - desc = child->mm->context.ldt + seg;
6470 - base = ((desc[0] >> 16) |
6471 - ((desc[1] & 0xff) << 16) |
6472 - (desc[1] & 0xff000000));
6473 + desc = &child->mm->context.ldt[seg];
6474 + base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
6476 /* 16-bit code segment? */
6477 - if (!((desc[1] >> 22) & 1))
6478 + if (!((desc->b >> 22) & 1))
6482 @@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
6483 unsigned char opcode[15];
6484 unsigned long addr = convert_ip_to_linear(child, regs);
6486 + if (addr == -EINVAL)
6489 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6490 for (i = 0; i < copied; i++) {
6491 switch (opcode[i]) {
6492 @@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
6494 #ifdef CONFIG_X86_64
6496 - if (regs->cs != __USER_CS)
6497 + if ((regs->cs & 0xffff) != __USER_CS)
6498 /* 32-bit mode: register increment */
6500 /* 64-bit mode: REX prefix */
6501 diff -urNp linux-2.6.27.10/arch/x86/kernel/syscall_table_32.S linux-2.6.27.10/arch/x86/kernel/syscall_table_32.S
6502 --- linux-2.6.27.10/arch/x86/kernel/syscall_table_32.S 2008-11-07 12:55:34.000000000 -0500
6503 +++ linux-2.6.27.10/arch/x86/kernel/syscall_table_32.S 2008-11-18 03:38:44.000000000 -0500
6505 +.section .rodata,"a",@progbits
6506 ENTRY(sys_call_table)
6507 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
6509 diff -urNp linux-2.6.27.10/arch/x86/kernel/sys_i386_32.c linux-2.6.27.10/arch/x86/kernel/sys_i386_32.c
6510 --- linux-2.6.27.10/arch/x86/kernel/sys_i386_32.c 2008-11-07 12:55:34.000000000 -0500
6511 +++ linux-2.6.27.10/arch/x86/kernel/sys_i386_32.c 2008-11-18 03:38:44.000000000 -0500
6513 #include <linux/uaccess.h>
6514 #include <linux/unistd.h>
6516 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
6518 + unsigned long pax_task_size = TASK_SIZE;
6520 +#ifdef CONFIG_PAX_SEGMEXEC
6521 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
6522 + pax_task_size = SEGMEXEC_TASK_SIZE;
6525 + if (len > pax_task_size || addr > pax_task_size - len)
6531 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
6532 unsigned long prot, unsigned long flags,
6533 unsigned long fd, unsigned long pgoff)
6534 @@ -81,6 +96,205 @@ out:
6539 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
6540 + unsigned long len, unsigned long pgoff, unsigned long flags)
6542 + struct mm_struct *mm = current->mm;
6543 + struct vm_area_struct *vma;
6544 + unsigned long start_addr, pax_task_size = TASK_SIZE;
6546 +#ifdef CONFIG_PAX_SEGMEXEC
6547 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6548 + pax_task_size = SEGMEXEC_TASK_SIZE;
6551 + if (len > pax_task_size)
6554 + if (flags & MAP_FIXED)
6557 +#ifdef CONFIG_PAX_RANDMMAP
6558 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6562 + addr = PAGE_ALIGN(addr);
6563 + vma = find_vma(mm, addr);
6564 + if (pax_task_size - len >= addr &&
6565 + (!vma || addr + len <= vma->vm_start))
6568 + if (len > mm->cached_hole_size) {
6569 + start_addr = addr = mm->free_area_cache;
6571 + start_addr = addr = mm->mmap_base;
6572 + mm->cached_hole_size = 0;
6575 +#ifdef CONFIG_PAX_PAGEEXEC
6576 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
6577 + start_addr = 0x00110000UL;
6579 +#ifdef CONFIG_PAX_RANDMMAP
6580 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6581 + start_addr += mm->delta_mmap & 0x03FFF000UL;
6584 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
6585 + start_addr = addr = mm->mmap_base;
6587 + addr = start_addr;
6592 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6593 + /* At this point: (!vma || addr < vma->vm_end). */
6594 + if (pax_task_size - len < addr) {
6596 + * Start a new search - just in case we missed
6599 + if (start_addr != mm->mmap_base) {
6600 + start_addr = addr = mm->mmap_base;
6601 + mm->cached_hole_size = 0;
6606 + if (!vma || addr + len <= vma->vm_start) {
6608 + * Remember the place where we stopped the search:
6610 + mm->free_area_cache = addr + len;
6613 + if (addr + mm->cached_hole_size < vma->vm_start)
6614 + mm->cached_hole_size = vma->vm_start - addr;
6615 + addr = vma->vm_end;
6616 + if (mm->start_brk <= addr && addr < mm->mmap_base) {
6617 + start_addr = addr = mm->mmap_base;
6618 + mm->cached_hole_size = 0;
6625 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
6626 + const unsigned long len, const unsigned long pgoff,
6627 + const unsigned long flags)
6629 + struct vm_area_struct *vma;
6630 + struct mm_struct *mm = current->mm;
6631 + unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
6633 +#ifdef CONFIG_PAX_SEGMEXEC
6634 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6635 + pax_task_size = SEGMEXEC_TASK_SIZE;
6638 + /* requested length too big for entire address space */
6639 + if (len > pax_task_size)
6642 + if (flags & MAP_FIXED)
6645 +#ifdef CONFIG_PAX_PAGEEXEC
6646 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
6650 +#ifdef CONFIG_PAX_RANDMMAP
6651 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6654 + /* requesting a specific address */
6656 + addr = PAGE_ALIGN(addr);
6657 + vma = find_vma(mm, addr);
6658 + if (pax_task_size - len >= addr &&
6659 + (!vma || addr + len <= vma->vm_start))
6663 + /* check if free_area_cache is useful for us */
6664 + if (len <= mm->cached_hole_size) {
6665 + mm->cached_hole_size = 0;
6666 + mm->free_area_cache = mm->mmap_base;
6669 + /* either no address requested or can't fit in requested address hole */
6670 + addr = mm->free_area_cache;
6672 + /* make sure it can fit in the remaining address space */
6674 + vma = find_vma(mm, addr-len);
6675 + if (!vma || addr <= vma->vm_start)
6676 + /* remember the address as a hint for next time */
6677 + return (mm->free_area_cache = addr-len);
6680 + if (mm->mmap_base < len)
6683 + addr = mm->mmap_base-len;
6687 + * Lookup failure means no vma is above this address,
6688 + * else if new region fits below vma->vm_start,
6689 + * return with success:
6691 + vma = find_vma(mm, addr);
6692 + if (!vma || addr+len <= vma->vm_start)
6693 + /* remember the address as a hint for next time */
6694 + return (mm->free_area_cache = addr);
6696 + /* remember the largest hole we saw so far */
6697 + if (addr + mm->cached_hole_size < vma->vm_start)
6698 + mm->cached_hole_size = vma->vm_start - addr;
6700 + /* try just below the current vma->vm_start */
6701 + addr = vma->vm_start-len;
6702 + } while (len < vma->vm_start);
6706 + * A failed mmap() very likely causes application failure,
6707 + * so fall back to the bottom-up function here. This scenario
6708 + * can happen with large stack limits and large mmap()
6712 +#ifdef CONFIG_PAX_SEGMEXEC
6713 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6714 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
6718 + mm->mmap_base = TASK_UNMAPPED_BASE;
6720 +#ifdef CONFIG_PAX_RANDMMAP
6721 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6722 + mm->mmap_base += mm->delta_mmap;
6725 + mm->free_area_cache = mm->mmap_base;
6726 + mm->cached_hole_size = ~0UL;
6727 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6729 + * Restore the topdown base:
6731 + mm->mmap_base = base;
6732 + mm->free_area_cache = base;
6733 + mm->cached_hole_size = ~0UL;
6738 struct sel_arg_struct {
6740 diff -urNp linux-2.6.27.10/arch/x86/kernel/sys_x86_64.c linux-2.6.27.10/arch/x86/kernel/sys_x86_64.c
6741 --- linux-2.6.27.10/arch/x86/kernel/sys_x86_64.c 2008-11-07 12:55:34.000000000 -0500
6742 +++ linux-2.6.27.10/arch/x86/kernel/sys_x86_64.c 2008-11-18 03:38:44.000000000 -0500
6743 @@ -45,8 +45,8 @@ out:
6747 -static void find_start_end(unsigned long flags, unsigned long *begin,
6748 - unsigned long *end)
6749 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
6750 + unsigned long *begin, unsigned long *end)
6752 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
6753 unsigned long new_begin;
6754 @@ -65,7 +65,7 @@ static void find_start_end(unsigned long
6758 - *begin = TASK_UNMAPPED_BASE;
6759 + *begin = mm->mmap_base;
6763 @@ -82,11 +82,15 @@ arch_get_unmapped_area(struct file *filp
6764 if (flags & MAP_FIXED)
6767 - find_start_end(flags, &begin, &end);
6768 + find_start_end(mm, flags, &begin, &end);
6773 +#ifdef CONFIG_PAX_RANDMMAP
6774 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6778 addr = PAGE_ALIGN(addr);
6779 vma = find_vma(mm, addr);
6780 @@ -141,7 +145,7 @@ arch_get_unmapped_area_topdown(struct fi
6782 struct vm_area_struct *vma;
6783 struct mm_struct *mm = current->mm;
6784 - unsigned long addr = addr0;
6785 + unsigned long base = mm->mmap_base, addr = addr0;
6787 /* requested length too big for entire address space */
6788 if (len > TASK_SIZE)
6789 @@ -154,6 +158,10 @@ arch_get_unmapped_area_topdown(struct fi
6790 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
6793 +#ifdef CONFIG_PAX_RANDMMAP
6794 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
6797 /* requesting a specific address */
6799 addr = PAGE_ALIGN(addr);
6800 @@ -211,13 +219,21 @@ bottomup:
6801 * can happen with large stack limits and large mmap()
6804 + mm->mmap_base = TASK_UNMAPPED_BASE;
6806 +#ifdef CONFIG_PAX_RANDMMAP
6807 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6808 + mm->mmap_base += mm->delta_mmap;
6811 + mm->free_area_cache = mm->mmap_base;
6812 mm->cached_hole_size = ~0UL;
6813 - mm->free_area_cache = TASK_UNMAPPED_BASE;
6814 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6816 * Restore the topdown base:
6818 - mm->free_area_cache = mm->mmap_base;
6819 + mm->mmap_base = base;
6820 + mm->free_area_cache = base;
6821 mm->cached_hole_size = ~0UL;
6824 diff -urNp linux-2.6.27.10/arch/x86/kernel/time_32.c linux-2.6.27.10/arch/x86/kernel/time_32.c
6825 --- linux-2.6.27.10/arch/x86/kernel/time_32.c 2008-11-07 12:55:34.000000000 -0500
6826 +++ linux-2.6.27.10/arch/x86/kernel/time_32.c 2008-11-18 03:38:44.000000000 -0500
6827 @@ -49,20 +49,30 @@ unsigned long profile_pc(struct pt_regs
6828 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
6829 in_lock_functions(pc)) {
6830 #ifdef CONFIG_FRAME_POINTER
6831 - return *(unsigned long *)(regs->bp + 4);
6832 + return ktla_ktva(*(unsigned long *)(regs->bp + 4));
6834 unsigned long *sp = (unsigned long *)®s->sp;
6836 /* Return address is either directly at stack pointer
6837 or above a saved flags. Eflags has bits 22-31 zero,
6838 kernel addresses don't. */
6840 +#ifdef CONFIG_PAX_KERNEXEC
6841 + return ktla_ktva(sp[0]);
6853 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
6854 + pc = ktla_ktva(pc);
6858 EXPORT_SYMBOL(profile_pc);
6859 diff -urNp linux-2.6.27.10/arch/x86/kernel/tlb_32.c linux-2.6.27.10/arch/x86/kernel/tlb_32.c
6860 --- linux-2.6.27.10/arch/x86/kernel/tlb_32.c 2008-11-07 12:55:34.000000000 -0500
6861 +++ linux-2.6.27.10/arch/x86/kernel/tlb_32.c 2008-11-18 03:38:44.000000000 -0500
6863 #include <asm/tlbflush.h>
6865 DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
6866 - ____cacheline_aligned = { &init_mm, 0, };
6867 + ____cacheline_aligned = { &init_mm, 0, {0} };
6869 /* must come after the send_IPI functions above for inlining */
6870 #include <mach_ipi.h>
6871 diff -urNp linux-2.6.27.10/arch/x86/kernel/tls.c linux-2.6.27.10/arch/x86/kernel/tls.c
6872 --- linux-2.6.27.10/arch/x86/kernel/tls.c 2008-11-07 12:55:34.000000000 -0500
6873 +++ linux-2.6.27.10/arch/x86/kernel/tls.c 2008-11-18 03:38:44.000000000 -0500
6874 @@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
6875 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6878 +#ifdef CONFIG_PAX_SEGMEXEC
6879 + if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6883 set_tls_desc(p, idx, &info, 1);
6886 diff -urNp linux-2.6.27.10/arch/x86/kernel/traps_32.c linux-2.6.27.10/arch/x86/kernel/traps_32.c
6887 --- linux-2.6.27.10/arch/x86/kernel/traps_32.c 2008-11-07 12:55:34.000000000 -0500
6888 +++ linux-2.6.27.10/arch/x86/kernel/traps_32.c 2008-12-10 22:28:27.000000000 -0500
6889 @@ -70,14 +70,6 @@ asmlinkage int system_call(void);
6890 /* Do we ignore FPU interrupts ? */
6891 char ignore_fpu_irq;
6894 - * The IDT has to be page-aligned to simplify the Pentium
6895 - * F0 0F bug workaround.. We have a special link segment
6898 -gate_desc idt_table[256]
6899 - __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
6901 int panic_on_unrecovered_nmi;
6902 int kstack_depth_to_print = 24;
6903 static unsigned int code_bytes = 64;
6904 @@ -320,21 +312,22 @@ void show_registers(struct pt_regs *regs
6905 * When in-kernel, we also print out the stack and code at the
6906 * time of the fault..
6908 - if (!user_mode_vm(regs)) {
6909 + if (!user_mode(regs)) {
6910 unsigned int code_prologue = code_bytes * 43 / 64;
6911 unsigned int code_len = code_bytes;
6914 + unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
6916 printk("\n" KERN_EMERG "Stack: ");
6917 show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG);
6919 printk(KERN_EMERG "Code: ");
6921 - ip = (u8 *)regs->ip - code_prologue;
6922 + ip = (u8 *)regs->ip - code_prologue + cs_base;
6923 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
6924 /* try starting at EIP */
6925 - ip = (u8 *)regs->ip;
6926 + ip = (u8 *)regs->ip + cs_base;
6927 code_len = code_len - code_prologue + 1;
6929 for (i = 0; i < code_len; i++, ip++) {
6930 @@ -343,7 +336,7 @@ void show_registers(struct pt_regs *regs
6931 printk(" Bad EIP value.");
6934 - if (ip == (u8 *)regs->ip)
6935 + if (ip == (u8 *)regs->ip + cs_base)
6936 printk("<%02x> ", c);
6939 @@ -356,6 +349,7 @@ int is_valid_bugaddr(unsigned long ip)
6943 + ip = ktla_ktva(ip);
6944 if (ip < PAGE_OFFSET)
6946 if (probe_kernel_address((unsigned short *)ip, ud2))
6947 @@ -469,7 +463,7 @@ void die(const char *str, struct pt_regs
6949 die_if_kernel(const char *str, struct pt_regs *regs, long err)
6951 - if (!user_mode_vm(regs))
6952 + if (!user_mode(regs))
6953 die(str, regs, err);
6956 @@ -479,13 +473,13 @@ do_trap(int trapnr, int signr, char *str
6958 struct task_struct *tsk = current;
6960 - if (regs->flags & X86_VM_MASK) {
6961 + if (v8086_mode(regs)) {
6967 - if (!user_mode(regs))
6968 + if (!user_mode_novm(regs))
6972 @@ -513,6 +507,12 @@ kernel_trap:
6973 tsk->thread.trap_no = trapnr;
6974 die(str, regs, error_code);
6977 +#ifdef CONFIG_PAX_REFCOUNT
6979 + pax_report_refcount_overflow(regs);
6985 @@ -595,7 +595,7 @@ do_general_protection(struct pt_regs *re
6989 - tss = &per_cpu(init_tss, cpu);
6990 + tss = init_tss + cpu;
6991 thread = ¤t->thread;
6994 @@ -627,13 +627,29 @@ do_general_protection(struct pt_regs *re
6998 - if (regs->flags & X86_VM_MASK)
6999 + if (v8086_mode(regs))
7003 - if (!user_mode(regs))
7004 + if (!user_mode_novm(regs))
7007 +#ifdef CONFIG_PAX_PAGEEXEC
7008 + if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
7009 + struct mm_struct *mm = tsk->mm;
7010 + unsigned long limit;
7012 + down_write(&mm->mmap_sem);
7013 + limit = mm->context.user_cs_limit;
7014 + if (limit < TASK_SIZE) {
7015 + track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
7016 + up_write(&mm->mmap_sem);
7019 + up_write(&mm->mmap_sem);
7023 tsk->thread.error_code = error_code;
7024 tsk->thread.trap_no = 13;
7026 @@ -664,6 +680,13 @@ gp_in_kernel:
7027 if (notify_die(DIE_GPF, "general protection fault", regs,
7028 error_code, 13, SIGSEGV) == NOTIFY_STOP)
7031 +#ifdef CONFIG_PAX_KERNEXEC
7032 + if ((regs->cs & 0xFFFF) == __KERNEL_CS)
7033 + die("PAX: suspicious general protection fault", regs, error_code);
7037 die("general protection fault", regs, error_code);
7040 @@ -766,7 +789,7 @@ void notrace __kprobes die_nmi(char *str
7041 * If we are in kernel we are probably nested up pretty bad
7042 * and might aswell get out now while we still can:
7044 - if (!user_mode_vm(regs)) {
7045 + if (!user_mode(regs)) {
7046 current->thread.trap_no = 2;
7049 @@ -915,7 +938,7 @@ void __kprobes do_debug(struct pt_regs *
7053 - if (regs->flags & X86_VM_MASK)
7054 + if (v8086_mode(regs))
7057 /* Save debug status register where ptrace can see it */
7058 @@ -931,7 +954,7 @@ void __kprobes do_debug(struct pt_regs *
7059 * check for kernel mode by just checking the CPL
7062 - if (!user_mode(regs))
7063 + if (!user_mode_novm(regs))
7064 goto clear_TF_reenable;
7067 @@ -1086,7 +1109,7 @@ void do_simd_coprocessor_error(struct pt
7068 * Handle strange cache flush from user space exception
7069 * in all other cases. This is undocumented behaviour.
7071 - if (regs->flags & X86_VM_MASK) {
7072 + if (v8086_mode(regs)) {
7073 handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
7076 @@ -1106,19 +1129,14 @@ void do_spurious_interrupt_bug(struct pt
7078 unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
7080 - struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
7081 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
7082 unsigned long new_kesp = kesp - base;
7083 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
7084 - __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
7085 + struct desc_struct ss;
7087 /* Set up base for espfix segment */
7088 - desc &= 0x00f0ff0000000000ULL;
7089 - desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
7090 - ((((__u64)base) << 32) & 0xff00000000000000ULL) |
7091 - ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
7092 - (lim_pages & 0xffff);
7093 - *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
7094 + pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
7095 + write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
7099 diff -urNp linux-2.6.27.10/arch/x86/kernel/traps_64.c linux-2.6.27.10/arch/x86/kernel/traps_64.c
7100 --- linux-2.6.27.10/arch/x86/kernel/traps_64.c 2008-11-07 12:55:34.000000000 -0500
7101 +++ linux-2.6.27.10/arch/x86/kernel/traps_64.c 2008-11-18 03:38:44.000000000 -0500
7102 @@ -634,6 +634,12 @@ kernel_trap:
7103 tsk->thread.trap_no = trapnr;
7104 die(str, regs, error_code);
7107 +#ifdef CONFIG_PAX_REFCOUNT
7109 + pax_report_refcount_overflow(regs);
7115 diff -urNp linux-2.6.27.10/arch/x86/kernel/tsc.c linux-2.6.27.10/arch/x86/kernel/tsc.c
7116 --- linux-2.6.27.10/arch/x86/kernel/tsc.c 2008-11-17 20:03:30.000000000 -0500
7117 +++ linux-2.6.27.10/arch/x86/kernel/tsc.c 2008-11-18 03:38:44.000000000 -0500
7118 @@ -554,7 +554,7 @@ static struct dmi_system_id __initdata b
7119 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
7123 + { NULL, NULL, {{0, NULL}}, NULL}
7127 diff -urNp linux-2.6.27.10/arch/x86/kernel/vm86_32.c linux-2.6.27.10/arch/x86/kernel/vm86_32.c
7128 --- linux-2.6.27.10/arch/x86/kernel/vm86_32.c 2008-11-07 12:55:34.000000000 -0500
7129 +++ linux-2.6.27.10/arch/x86/kernel/vm86_32.c 2008-11-18 03:38:44.000000000 -0500
7130 @@ -147,7 +147,7 @@ struct pt_regs *save_v86_state(struct ke
7134 - tss = &per_cpu(init_tss, get_cpu());
7135 + tss = init_tss + get_cpu();
7136 current->thread.sp0 = current->thread.saved_sp0;
7137 current->thread.sysenter_cs = __KERNEL_CS;
7138 load_sp0(tss, ¤t->thread);
7139 @@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
7140 tsk->thread.saved_fs = info->regs32->fs;
7141 savesegment(gs, tsk->thread.saved_gs);
7143 - tss = &per_cpu(init_tss, get_cpu());
7144 + tss = init_tss + get_cpu();
7145 tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
7147 tsk->thread.sysenter_cs = 0;
7148 diff -urNp linux-2.6.27.10/arch/x86/kernel/vmi_32.c linux-2.6.27.10/arch/x86/kernel/vmi_32.c
7149 --- linux-2.6.27.10/arch/x86/kernel/vmi_32.c 2008-12-21 01:18:11.000000000 -0500
7150 +++ linux-2.6.27.10/arch/x86/kernel/vmi_32.c 2008-12-21 01:18:21.000000000 -0500
7151 @@ -102,18 +102,43 @@ static unsigned patch_internal(int call,
7154 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
7156 +#ifdef CONFIG_PAX_KERNEXEC
7157 + unsigned long cr0;
7160 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
7162 case VMI_RELOCATION_CALL_REL:
7165 +#ifdef CONFIG_PAX_KERNEXEC
7166 + pax_open_kernel(cr0);
7169 *(char *)insnbuf = MNEM_CALL;
7170 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
7172 +#ifdef CONFIG_PAX_KERNEXEC
7173 + pax_close_kernel(cr0);
7178 case VMI_RELOCATION_JUMP_REL:
7181 +#ifdef CONFIG_PAX_KERNEXEC
7182 + pax_open_kernel(cr0);
7185 *(char *)insnbuf = MNEM_JMP;
7186 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
7188 +#ifdef CONFIG_PAX_KERNEXEC
7189 + pax_close_kernel(cr0);
7194 case VMI_RELOCATION_NOP:
7195 @@ -516,14 +541,14 @@ static void vmi_set_pud(pud_t *pudp, pud
7197 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
7199 - const pte_t pte = { .pte = 0 };
7200 + const pte_t pte = __pte(0ULL);
7201 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
7202 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
7205 static void vmi_pmd_clear(pmd_t *pmd)
7207 - const pte_t pte = { .pte = 0 };
7208 + const pte_t pte = __pte(0ULL);
7209 vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
7210 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
7212 @@ -552,8 +577,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
7213 ap.ss = __KERNEL_DS;
7214 ap.esp = (unsigned long) start_esp;
7216 - ap.ds = __USER_DS;
7217 - ap.es = __USER_DS;
7218 + ap.ds = __KERNEL_DS;
7219 + ap.es = __KERNEL_DS;
7220 ap.fs = __KERNEL_PERCPU;
7223 @@ -748,12 +773,20 @@ static inline int __init activate_vmi(vo
7225 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
7227 +#ifdef CONFIG_PAX_KERNEXEC
7228 + unsigned long cr0;
7231 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
7232 printk(KERN_ERR "VMI ROM failed to initialize!");
7235 savesegment(cs, kernel_cs);
7237 +#ifdef CONFIG_PAX_KERNEXEC
7238 + pax_open_kernel(cr0);
7241 pv_info.paravirt_enabled = 1;
7242 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
7243 pv_info.name = "vmi";
7244 @@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
7246 para_fill(pv_irq_ops.safe_halt, Halt);
7248 +#ifdef CONFIG_PAX_KERNEXEC
7249 + pax_close_kernel(cr0);
7253 * Alternative instruction rewriting doesn't happen soon enough
7254 * to convert VMI_IRET to a call instead of a jump; so we have
7255 diff -urNp linux-2.6.27.10/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.27.10/arch/x86/kernel/vmlinux_32.lds.S
7256 --- linux-2.6.27.10/arch/x86/kernel/vmlinux_32.lds.S 2008-11-07 12:55:34.000000000 -0500
7257 +++ linux-2.6.27.10/arch/x86/kernel/vmlinux_32.lds.S 2008-11-18 03:38:44.000000000 -0500
7259 #include <asm/page.h>
7260 #include <asm/cache.h>
7261 #include <asm/boot.h>
7262 +#include <asm/segment.h>
7264 +#ifdef CONFIG_X86_PAE
7265 +#define PMD_SHIFT 21
7267 +#define PMD_SHIFT 22
7269 +#define PMD_SIZE (1 << PMD_SHIFT)
7271 +#ifdef CONFIG_PAX_KERNEXEC
7272 +#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
7274 +#define __KERNEL_TEXT_OFFSET 0
7277 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
7279 @@ -22,81 +36,23 @@ ENTRY(phys_startup_32)
7280 jiffies = jiffies_64;
7283 - text PT_LOAD FLAGS(5); /* R_E */
7284 - data PT_LOAD FLAGS(7); /* RWE */
7285 - note PT_NOTE FLAGS(0); /* ___ */
7286 + initdata PT_LOAD FLAGS(6); /* RW_ */
7287 + percpu PT_LOAD FLAGS(6); /* RW_ */
7288 + inittext PT_LOAD FLAGS(5); /* R_E */
7289 + text PT_LOAD FLAGS(5); /* R_E */
7290 + rodata PT_LOAD FLAGS(4); /* R__ */
7291 + data PT_LOAD FLAGS(6); /* RW_ */
7292 + note PT_NOTE FLAGS(0); /* ___ */
7296 - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
7297 - phys_startup_32 = startup_32 - LOAD_OFFSET;
7299 - .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
7300 - _text = .; /* Text and read-only data */
7305 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
7306 - . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
7307 - *(.text.page_aligned)
7314 - _etext = .; /* End of text section */
7318 + . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
7320 - . = ALIGN(16); /* Exception table */
7321 - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7322 - __start___ex_table = .;
7324 - __stop___ex_table = .;
7330 - . = ALIGN(PAGE_SIZE);
7331 - .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7336 - . = ALIGN(PAGE_SIZE);
7337 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
7338 - __nosave_begin = .;
7340 - . = ALIGN(PAGE_SIZE);
7344 - . = ALIGN(PAGE_SIZE);
7345 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7346 - *(.data.page_aligned)
7351 - .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7352 - *(.data.cacheline_aligned)
7355 - /* rarely changed data like cpu maps */
7357 - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
7358 - *(.data.read_mostly)
7359 - _edata = .; /* End of data section */
7362 - . = ALIGN(THREAD_SIZE); /* init_task */
7363 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7364 - *(.data.init_task)
7366 + .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
7367 + __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
7368 + phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
7372 /* might get freed after init */
7373 . = ALIGN(PAGE_SIZE);
7374 @@ -114,14 +70,8 @@ SECTIONS
7375 . = ALIGN(PAGE_SIZE);
7377 /* will be freed after init */
7378 - . = ALIGN(PAGE_SIZE); /* Init code and data */
7379 - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
7385 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
7390 @@ -161,11 +111,6 @@ SECTIONS
7391 *(.parainstructions)
7392 __parainstructions_end = .;
7394 - /* .exit.text is discard at runtime, not link time, to deal with references
7395 - from .altinstructions and .eh_frame */
7396 - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
7399 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
7402 @@ -178,17 +123,136 @@ SECTIONS
7405 . = ALIGN(PAGE_SIZE);
7406 - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
7407 - __per_cpu_start = .;
7408 + per_cpu_start = .;
7409 + .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
7410 + __per_cpu_start = . + per_cpu_start;
7413 *(.data.percpu.shared_aligned)
7414 - __per_cpu_end = .;
7416 + __per_cpu_end = . + per_cpu_start;
7418 + . += per_cpu_start;
7419 . = ALIGN(PAGE_SIZE);
7420 /* freed after init ends here */
7422 + . = ALIGN(PAGE_SIZE); /* Init code and data */
7423 + .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7429 + /* .exit.text is discard at runtime, not link time, to deal with references
7430 + from .altinstructions and .eh_frame */
7431 + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7435 + .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7437 + . = ALIGN(2*PMD_SIZE) - 1;
7440 + /* freed after init ends here */
7442 + .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7443 + __init_end = . + __KERNEL_TEXT_OFFSET;
7444 + KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
7445 + _text = .; /* Text and read-only data */
7450 + .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7451 + . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
7452 + *(.text.page_aligned)
7459 + _etext = .; /* End of text section */
7462 + . += __KERNEL_TEXT_OFFSET;
7464 + . = ALIGN(4096); /* Exception table */
7465 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7466 + __start___ex_table = .;
7468 + __stop___ex_table = .;
7471 + NOTES :rodata :note
7473 + RO_DATA(PAGE_SIZE)
7475 + . = ALIGN(PAGE_SIZE);
7476 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
7478 + . = ALIGN(PAGE_SIZE);
7479 + *(.empty_zero_page)
7480 + *(.swapper_pg_pmd)
7481 + *(.swapper_pg_dir)
7484 +#ifdef CONFIG_PAX_KERNEXEC
7486 +#ifdef CONFIG_MODULES
7487 + . = ALIGN(PAGE_SIZE);
7488 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
7489 + MODULES_VADDR = .;
7491 + . += (6 * 1024 * 1024);
7492 + . = ALIGN( PMD_SIZE) - 1;
7496 + . = ALIGN(PMD_SIZE) - 1;
7502 + . = ALIGN(PAGE_SIZE);
7503 + .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7509 + . = ALIGN(PAGE_SIZE);
7510 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
7511 + __nosave_begin = .;
7513 + . = ALIGN(PAGE_SIZE);
7517 + . = ALIGN(PAGE_SIZE);
7518 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7519 + *(.data.page_aligned)
7523 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7524 + *(.data.cacheline_aligned)
7527 + /* rarely changed data like cpu maps */
7529 + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
7530 + *(.data.read_mostly)
7531 + _edata = .; /* End of data section */
7534 + . = ALIGN(THREAD_SIZE); /* init_task */
7535 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7536 + *(.data.init_task)
7539 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7541 __bss_start = .; /* BSS */
7542 *(.bss.page_aligned)
7544 diff -urNp linux-2.6.27.10/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.27.10/arch/x86/kernel/vmlinux_64.lds.S
7545 --- linux-2.6.27.10/arch/x86/kernel/vmlinux_64.lds.S 2008-11-07 12:55:34.000000000 -0500
7546 +++ linux-2.6.27.10/arch/x86/kernel/vmlinux_64.lds.S 2008-11-18 03:38:44.000000000 -0500
7547 @@ -16,7 +16,7 @@ jiffies_64 = jiffies;
7550 text PT_LOAD FLAGS(5); /* R_E */
7551 - data PT_LOAD FLAGS(7); /* RWE */
7552 + data PT_LOAD FLAGS(6); /* RW_ */
7553 user PT_LOAD FLAGS(7); /* RWE */
7554 data.init PT_LOAD FLAGS(7); /* RWE */
7555 note PT_NOTE FLAGS(0); /* ___ */
7556 @@ -49,17 +49,20 @@ SECTIONS
7557 __stop___ex_table = .;
7561 + RO_DATA(PAGE_SIZE)
7563 +#ifdef CONFIG_PAX_KERNEXEC
7564 + . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
7566 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
7570 .data : AT(ADDR(.data) - LOAD_OFFSET) {
7575 - _edata = .; /* End of data section */
7577 . = ALIGN(PAGE_SIZE);
7578 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
7579 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7580 @@ -70,9 +73,27 @@ SECTIONS
7581 *(.data.read_mostly)
7584 + . = ALIGN(THREAD_SIZE); /* init_task */
7585 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7586 + *(.data.init_task)
7589 + . = ALIGN(PAGE_SIZE);
7590 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7591 + *(.data.page_aligned)
7594 + . = ALIGN(PAGE_SIZE);
7595 + __nosave_begin = .;
7596 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7597 + . = ALIGN(PAGE_SIZE);
7600 + _edata = .; /* End of data section */
7602 #define VSYSCALL_ADDR (-10*1024*1024)
7603 -#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7604 -#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7605 +#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7606 +#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7608 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
7609 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
7610 @@ -120,23 +141,13 @@ SECTIONS
7614 - . = ALIGN(THREAD_SIZE); /* init_task */
7615 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7616 - *(.data.init_task)
7619 - . = ALIGN(PAGE_SIZE);
7620 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7621 - *(.data.page_aligned)
7624 /* might get freed after init */
7625 . = ALIGN(PAGE_SIZE);
7626 __smp_alt_begin = .;
7628 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7632 __smp_locks_end = .;
7633 . = ALIGN(PAGE_SIZE);
7635 @@ -213,16 +224,11 @@ SECTIONS
7636 . = ALIGN(PAGE_SIZE);
7639 - . = ALIGN(PAGE_SIZE);
7640 - __nosave_begin = .;
7641 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7642 - . = ALIGN(PAGE_SIZE);
7645 __bss_start = .; /* BSS */
7646 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7647 *(.bss.page_aligned)
7649 + . = ALIGN(2*1024*1024);
7653 diff -urNp linux-2.6.27.10/arch/x86/kernel/vsyscall_64.c linux-2.6.27.10/arch/x86/kernel/vsyscall_64.c
7654 --- linux-2.6.27.10/arch/x86/kernel/vsyscall_64.c 2008-11-07 12:55:34.000000000 -0500
7655 +++ linux-2.6.27.10/arch/x86/kernel/vsyscall_64.c 2008-11-18 03:38:44.000000000 -0500
7656 @@ -236,13 +236,13 @@ static ctl_table kernel_table2[] = {
7657 .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
7659 .proc_handler = vsyscall_sysctl_change },
7661 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7664 static ctl_table kernel_root_table2[] = {
7665 { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
7666 .child = kernel_table2 },
7668 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7672 diff -urNp linux-2.6.27.10/arch/x86/kvm/svm.c linux-2.6.27.10/arch/x86/kvm/svm.c
7673 --- linux-2.6.27.10/arch/x86/kvm/svm.c 2008-11-07 12:55:34.000000000 -0500
7674 +++ linux-2.6.27.10/arch/x86/kvm/svm.c 2008-11-18 03:38:44.000000000 -0500
7675 @@ -1515,7 +1515,19 @@ static void reload_tss(struct kvm_vcpu *
7676 int cpu = raw_smp_processor_id();
7678 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
7680 +#ifdef CONFIG_PAX_KERNEXEC
7681 + unsigned long cr0;
7683 + pax_open_kernel(cr0);
7686 svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
7688 +#ifdef CONFIG_PAX_KERNEXEC
7689 + pax_close_kernel(cr0);
7695 diff -urNp linux-2.6.27.10/arch/x86/kvm/vmx.c linux-2.6.27.10/arch/x86/kvm/vmx.c
7696 --- linux-2.6.27.10/arch/x86/kvm/vmx.c 2008-11-07 12:55:34.000000000 -0500
7697 +++ linux-2.6.27.10/arch/x86/kvm/vmx.c 2008-11-18 03:38:44.000000000 -0500
7698 @@ -115,7 +115,7 @@ static struct vmcs_config {
7702 -struct vmx_capability {
7703 +static struct vmx_capability {
7707 @@ -484,9 +484,23 @@ static void reload_tss(void)
7708 struct descriptor_table gdt;
7709 struct desc_struct *descs;
7711 +#ifdef CONFIG_PAX_KERNEXEC
7712 + unsigned long cr0;
7716 descs = (void *)gdt.base;
7718 +#ifdef CONFIG_PAX_KERNEXEC
7719 + pax_open_kernel(cr0);
7722 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
7724 +#ifdef CONFIG_PAX_KERNEXEC
7725 + pax_close_kernel(cr0);
7731 @@ -3069,7 +3083,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
7732 (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
7733 (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)) == 0;
7735 - asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
7736 + asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
7739 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
7740 diff -urNp linux-2.6.27.10/arch/x86/kvm/x86.c linux-2.6.27.10/arch/x86/kvm/x86.c
7741 --- linux-2.6.27.10/arch/x86/kvm/x86.c 2008-11-07 12:55:34.000000000 -0500
7742 +++ linux-2.6.27.10/arch/x86/kvm/x86.c 2008-11-18 03:38:44.000000000 -0500
7743 @@ -63,35 +63,35 @@ static int kvm_dev_ioctl_get_supported_c
7744 struct kvm_x86_ops *kvm_x86_ops;
7746 struct kvm_stats_debugfs_item debugfs_entries[] = {
7747 - { "pf_fixed", VCPU_STAT(pf_fixed) },
7748 - { "pf_guest", VCPU_STAT(pf_guest) },
7749 - { "tlb_flush", VCPU_STAT(tlb_flush) },
7750 - { "invlpg", VCPU_STAT(invlpg) },
7751 - { "exits", VCPU_STAT(exits) },
7752 - { "io_exits", VCPU_STAT(io_exits) },
7753 - { "mmio_exits", VCPU_STAT(mmio_exits) },
7754 - { "signal_exits", VCPU_STAT(signal_exits) },
7755 - { "irq_window", VCPU_STAT(irq_window_exits) },
7756 - { "nmi_window", VCPU_STAT(nmi_window_exits) },
7757 - { "halt_exits", VCPU_STAT(halt_exits) },
7758 - { "halt_wakeup", VCPU_STAT(halt_wakeup) },
7759 - { "hypercalls", VCPU_STAT(hypercalls) },
7760 - { "request_irq", VCPU_STAT(request_irq_exits) },
7761 - { "irq_exits", VCPU_STAT(irq_exits) },
7762 - { "host_state_reload", VCPU_STAT(host_state_reload) },
7763 - { "efer_reload", VCPU_STAT(efer_reload) },
7764 - { "fpu_reload", VCPU_STAT(fpu_reload) },
7765 - { "insn_emulation", VCPU_STAT(insn_emulation) },
7766 - { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
7767 - { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
7768 - { "mmu_pte_write", VM_STAT(mmu_pte_write) },
7769 - { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
7770 - { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
7771 - { "mmu_flooded", VM_STAT(mmu_flooded) },
7772 - { "mmu_recycled", VM_STAT(mmu_recycled) },
7773 - { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
7774 - { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
7775 - { "largepages", VM_STAT(lpages) },
7776 + { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
7777 + { "pf_guest", VCPU_STAT(pf_guest), NULL },
7778 + { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
7779 + { "invlpg", VCPU_STAT(invlpg), NULL },
7780 + { "exits", VCPU_STAT(exits), NULL },
7781 + { "io_exits", VCPU_STAT(io_exits), NULL },
7782 + { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
7783 + { "signal_exits", VCPU_STAT(signal_exits), NULL },
7784 + { "irq_window", VCPU_STAT(irq_window_exits), NULL },
7785 + { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
7786 + { "halt_exits", VCPU_STAT(halt_exits), NULL },
7787 + { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
7788 + { "hypercalls", VCPU_STAT(hypercalls), NULL },
7789 + { "request_irq", VCPU_STAT(request_irq_exits), NULL },
7790 + { "irq_exits", VCPU_STAT(irq_exits), NULL },
7791 + { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
7792 + { "efer_reload", VCPU_STAT(efer_reload), NULL },
7793 + { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
7794 + { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
7795 + { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
7796 + { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
7797 + { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
7798 + { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
7799 + { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
7800 + { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
7801 + { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
7802 + { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
7803 + { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
7804 + { "largepages", VM_STAT(lpages), NULL },
7808 @@ -1274,7 +1274,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
7809 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
7810 struct kvm_interrupt *irq)
7812 - if (irq->irq < 0 || irq->irq >= 256)
7813 + if (irq->irq >= 256)
7815 if (irqchip_in_kernel(vcpu->kvm))
7817 diff -urNp linux-2.6.27.10/arch/x86/lib/checksum_32.S linux-2.6.27.10/arch/x86/lib/checksum_32.S
7818 --- linux-2.6.27.10/arch/x86/lib/checksum_32.S 2008-11-07 12:55:34.000000000 -0500
7819 +++ linux-2.6.27.10/arch/x86/lib/checksum_32.S 2008-11-18 03:38:44.000000000 -0500
7821 #include <linux/linkage.h>
7822 #include <asm/dwarf2.h>
7823 #include <asm/errno.h>
7825 +#include <asm/segment.h>
7828 * computes a partial checksum, e.g. for TCP/UDP fragments
7830 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
7835 -ENTRY(csum_partial_copy_generic)
7837 +ENTRY(csum_partial_copy_generic_to_user)
7839 + pushl $(__USER_DS)
7840 + CFI_ADJUST_CFA_OFFSET 4
7842 + CFI_ADJUST_CFA_OFFSET -4
7843 + jmp csum_partial_copy_generic
7845 +ENTRY(csum_partial_copy_generic_from_user)
7846 + pushl $(__USER_DS)
7847 + CFI_ADJUST_CFA_OFFSET 4
7849 + CFI_ADJUST_CFA_OFFSET -4
7851 +ENTRY(csum_partial_copy_generic)
7853 CFI_ADJUST_CFA_OFFSET 4
7855 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
7857 SRC(1: movw (%esi), %bx )
7859 -DST( movw %bx, (%edi) )
7860 +DST( movw %bx, %es:(%edi) )
7864 @@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
7865 SRC(1: movl (%esi), %ebx )
7866 SRC( movl 4(%esi), %edx )
7868 -DST( movl %ebx, (%edi) )
7869 +DST( movl %ebx, %es:(%edi) )
7871 -DST( movl %edx, 4(%edi) )
7872 +DST( movl %edx, %es:4(%edi) )
7874 SRC( movl 8(%esi), %ebx )
7875 SRC( movl 12(%esi), %edx )
7877 -DST( movl %ebx, 8(%edi) )
7878 +DST( movl %ebx, %es:8(%edi) )
7880 -DST( movl %edx, 12(%edi) )
7881 +DST( movl %edx, %es:12(%edi) )
7883 SRC( movl 16(%esi), %ebx )
7884 SRC( movl 20(%esi), %edx )
7886 -DST( movl %ebx, 16(%edi) )
7887 +DST( movl %ebx, %es:16(%edi) )
7889 -DST( movl %edx, 20(%edi) )
7890 +DST( movl %edx, %es:20(%edi) )
7892 SRC( movl 24(%esi), %ebx )
7893 SRC( movl 28(%esi), %edx )
7895 -DST( movl %ebx, 24(%edi) )
7896 +DST( movl %ebx, %es:24(%edi) )
7898 -DST( movl %edx, 28(%edi) )
7899 +DST( movl %edx, %es:28(%edi) )
7903 @@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
7904 shrl $2, %edx # This clears CF
7905 SRC(3: movl (%esi), %ebx )
7907 -DST( movl %ebx, (%edi) )
7908 +DST( movl %ebx, %es:(%edi) )
7912 @@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
7914 SRC( movw (%esi), %cx )
7916 -DST( movw %cx, (%edi) )
7917 +DST( movw %cx, %es:(%edi) )
7921 SRC(5: movb (%esi), %cl )
7922 -DST( movb %cl, (%edi) )
7923 +DST( movb %cl, %es:(%edi) )
7927 @@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
7930 movl ARGBASE+20(%esp), %ebx # src_err_ptr
7931 - movl $-EFAULT, (%ebx)
7932 + movl $-EFAULT, %ss:(%ebx)
7934 # zero the complete destination - computing the rest
7936 @@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
7939 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
7940 - movl $-EFAULT,(%ebx)
7941 + movl $-EFAULT,%ss:(%ebx)
7947 + CFI_ADJUST_CFA_OFFSET 4
7949 + CFI_ADJUST_CFA_OFFSET -4
7951 + CFI_ADJUST_CFA_OFFSET 4
7953 + CFI_ADJUST_CFA_OFFSET -4
7955 CFI_ADJUST_CFA_OFFSET -4
7957 @@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
7958 CFI_ADJUST_CFA_OFFSET -4
7961 -ENDPROC(csum_partial_copy_generic)
7962 +ENDPROC(csum_partial_copy_generic_to_user)
7966 /* Version for PentiumII/PPro */
7970 SRC(movl x(%esi), %ebx ) ; \
7972 - DST(movl %ebx, x(%edi) ) ;
7973 + DST(movl %ebx, %es:x(%edi)) ;
7977 SRC(movl x(%esi), %ebx ) ; \
7979 - DST(movl %ebx, x(%edi) ) ;
7980 + DST(movl %ebx, %es:x(%edi)) ;
7984 -ENTRY(csum_partial_copy_generic)
7986 +ENTRY(csum_partial_copy_generic_to_user)
7988 + pushl $(__USER_DS)
7989 + CFI_ADJUST_CFA_OFFSET 4
7991 + CFI_ADJUST_CFA_OFFSET -4
7992 + jmp csum_partial_copy_generic
7994 +ENTRY(csum_partial_copy_generic_from_user)
7995 + pushl $(__USER_DS)
7996 + CFI_ADJUST_CFA_OFFSET 4
7998 + CFI_ADJUST_CFA_OFFSET -4
8000 +ENTRY(csum_partial_copy_generic)
8002 CFI_ADJUST_CFA_OFFSET 4
8003 CFI_REL_OFFSET ebx, 0
8004 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
8008 - lea 3f(%ebx,%ebx), %ebx
8009 + lea 3f(%ebx,%ebx,2), %ebx
8013 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
8015 SRC( movw (%esi), %dx )
8017 -DST( movw %dx, (%edi) )
8018 +DST( movw %dx, %es:(%edi) )
8023 SRC( movb (%esi), %dl )
8024 -DST( movb %dl, (%edi) )
8025 +DST( movb %dl, %es:(%edi) )
8029 .section .fixup, "ax"
8030 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
8031 - movl $-EFAULT, (%ebx)
8032 + movl $-EFAULT, %ss:(%ebx)
8033 # zero the complete destination (computing the rest is too much work)
8034 movl ARGBASE+8(%esp),%edi # dst
8035 movl ARGBASE+12(%esp),%ecx # len
8036 @@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
8039 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
8040 - movl $-EFAULT, (%ebx)
8041 + movl $-EFAULT, %ss:(%ebx)
8046 + CFI_ADJUST_CFA_OFFSET 4
8048 + CFI_ADJUST_CFA_OFFSET -4
8050 + CFI_ADJUST_CFA_OFFSET 4
8052 + CFI_ADJUST_CFA_OFFSET -4
8054 CFI_ADJUST_CFA_OFFSET -4
8056 @@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
8060 -ENDPROC(csum_partial_copy_generic)
8061 +ENDPROC(csum_partial_copy_generic_to_user)
8065 diff -urNp linux-2.6.27.10/arch/x86/lib/clear_page_64.S linux-2.6.27.10/arch/x86/lib/clear_page_64.S
8066 --- linux-2.6.27.10/arch/x86/lib/clear_page_64.S 2008-11-07 12:55:34.000000000 -0500
8067 +++ linux-2.6.27.10/arch/x86/lib/clear_page_64.S 2008-11-18 03:38:44.000000000 -0500
8068 @@ -44,7 +44,7 @@ ENDPROC(clear_page)
8070 #include <asm/cpufeature.h>
8072 - .section .altinstr_replacement,"ax"
8073 + .section .altinstr_replacement,"a"
8074 1: .byte 0xeb /* jmp <disp8> */
8075 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
8077 diff -urNp linux-2.6.27.10/arch/x86/lib/copy_page_64.S linux-2.6.27.10/arch/x86/lib/copy_page_64.S
8078 --- linux-2.6.27.10/arch/x86/lib/copy_page_64.S 2008-11-07 12:55:34.000000000 -0500
8079 +++ linux-2.6.27.10/arch/x86/lib/copy_page_64.S 2008-11-18 03:38:44.000000000 -0500
8080 @@ -104,7 +104,7 @@ ENDPROC(copy_page)
8082 #include <asm/cpufeature.h>
8084 - .section .altinstr_replacement,"ax"
8085 + .section .altinstr_replacement,"a"
8086 1: .byte 0xeb /* jmp <disp8> */
8087 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
8089 diff -urNp linux-2.6.27.10/arch/x86/lib/copy_user_64.S linux-2.6.27.10/arch/x86/lib/copy_user_64.S
8090 --- linux-2.6.27.10/arch/x86/lib/copy_user_64.S 2008-11-07 12:55:34.000000000 -0500
8091 +++ linux-2.6.27.10/arch/x86/lib/copy_user_64.S 2008-11-18 03:38:44.000000000 -0500
8093 .byte 0xe9 /* 32bit jump */
8094 .long \orig-1f /* by default jump to orig */
8096 - .section .altinstr_replacement,"ax"
8097 + .section .altinstr_replacement,"a"
8098 2: .byte 0xe9 /* near jump with 32bit immediate */
8099 .long \alt-1b /* offset */ /* or alternatively to alt */
8101 @@ -106,6 +106,8 @@ ENDPROC(__copy_from_user_inatomic)
8102 ENTRY(bad_from_user)
8110 diff -urNp linux-2.6.27.10/arch/x86/lib/getuser.S linux-2.6.27.10/arch/x86/lib/getuser.S
8111 --- linux-2.6.27.10/arch/x86/lib/getuser.S 2008-11-07 12:55:34.000000000 -0500
8112 +++ linux-2.6.27.10/arch/x86/lib/getuser.S 2008-11-18 03:38:44.000000000 -0500
8114 #include <asm/asm-offsets.h>
8115 #include <asm/thread_info.h>
8116 #include <asm/asm.h>
8117 +#include <asm/segment.h>
8121 @@ -40,7 +41,19 @@ ENTRY(__get_user_1)
8122 GET_THREAD_INFO(%_ASM_DX)
8123 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
8126 +#ifdef CONFIG_X86_32
8127 + pushl $(__USER_DS)
8131 1: movzb (%_ASM_AX),%edx
8133 +#ifdef CONFIG_X86_32
8141 @@ -53,7 +66,19 @@ ENTRY(__get_user_2)
8142 GET_THREAD_INFO(%_ASM_DX)
8143 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
8146 +#ifdef CONFIG_X86_32
8147 + pushl $(__USER_DS)
8151 2: movzwl -1(%_ASM_AX),%edx
8153 +#ifdef CONFIG_X86_32
8161 @@ -66,7 +91,19 @@ ENTRY(__get_user_4)
8162 GET_THREAD_INFO(%_ASM_DX)
8163 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
8166 +#ifdef CONFIG_X86_32
8167 + pushl $(__USER_DS)
8171 3: mov -3(%_ASM_AX),%edx
8173 +#ifdef CONFIG_X86_32
8181 @@ -89,6 +126,12 @@ ENDPROC(__get_user_8)
8186 +#ifdef CONFIG_X86_32
8192 mov $(-EFAULT),%_ASM_AX
8194 diff -urNp linux-2.6.27.10/arch/x86/lib/memcpy_64.S linux-2.6.27.10/arch/x86/lib/memcpy_64.S
8195 --- linux-2.6.27.10/arch/x86/lib/memcpy_64.S 2008-11-07 12:55:34.000000000 -0500
8196 +++ linux-2.6.27.10/arch/x86/lib/memcpy_64.S 2008-11-18 03:38:44.000000000 -0500
8197 @@ -114,7 +114,7 @@ ENDPROC(__memcpy)
8198 /* Some CPUs run faster using the string copy instructions.
8199 It is also a lot simpler. Use this when possible */
8201 - .section .altinstr_replacement,"ax"
8202 + .section .altinstr_replacement,"a"
8203 1: .byte 0xeb /* jmp <disp8> */
8204 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
8206 diff -urNp linux-2.6.27.10/arch/x86/lib/memset_64.S linux-2.6.27.10/arch/x86/lib/memset_64.S
8207 --- linux-2.6.27.10/arch/x86/lib/memset_64.S 2008-11-07 12:55:34.000000000 -0500
8208 +++ linux-2.6.27.10/arch/x86/lib/memset_64.S 2008-11-18 03:38:44.000000000 -0500
8209 @@ -118,7 +118,7 @@ ENDPROC(__memset)
8211 #include <asm/cpufeature.h>
8213 - .section .altinstr_replacement,"ax"
8214 + .section .altinstr_replacement,"a"
8215 1: .byte 0xeb /* jmp <disp8> */
8216 .byte (memset_c - memset) - (2f - 1b) /* offset */
8218 diff -urNp linux-2.6.27.10/arch/x86/lib/mmx_32.c linux-2.6.27.10/arch/x86/lib/mmx_32.c
8219 --- linux-2.6.27.10/arch/x86/lib/mmx_32.c 2008-11-07 12:55:34.000000000 -0500
8220 +++ linux-2.6.27.10/arch/x86/lib/mmx_32.c 2008-11-18 03:38:44.000000000 -0500
8221 @@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
8225 + unsigned long cr0;
8227 if (unlikely(in_interrupt()))
8228 return __memcpy(to, from, len);
8229 @@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
8232 __asm__ __volatile__ (
8233 - "1: prefetch (%0)\n" /* This set is 28 bytes */
8234 - " prefetch 64(%0)\n"
8235 - " prefetch 128(%0)\n"
8236 - " prefetch 192(%0)\n"
8237 - " prefetch 256(%0)\n"
8238 + "1: prefetch (%1)\n" /* This set is 28 bytes */
8239 + " prefetch 64(%1)\n"
8240 + " prefetch 128(%1)\n"
8241 + " prefetch 192(%1)\n"
8242 + " prefetch 256(%1)\n"
8244 ".section .fixup, \"ax\"\n"
8245 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8248 +#ifdef CONFIG_PAX_KERNEXEC
8249 + " movl %%cr0, %0\n"
8250 + " movl %0, %%eax\n"
8251 + " andl $0xFFFEFFFF, %%eax\n"
8252 + " movl %%eax, %%cr0\n"
8255 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8257 +#ifdef CONFIG_PAX_KERNEXEC
8258 + " movl %0, %%cr0\n"
8263 _ASM_EXTABLE(1b, 3b)
8265 + : "=&r" (cr0) : "r" (from) : "ax");
8267 for ( ; i > 5; i--) {
8268 __asm__ __volatile__ (
8269 - "1: prefetch 320(%0)\n"
8270 - "2: movq (%0), %%mm0\n"
8271 - " movq 8(%0), %%mm1\n"
8272 - " movq 16(%0), %%mm2\n"
8273 - " movq 24(%0), %%mm3\n"
8274 - " movq %%mm0, (%1)\n"
8275 - " movq %%mm1, 8(%1)\n"
8276 - " movq %%mm2, 16(%1)\n"
8277 - " movq %%mm3, 24(%1)\n"
8278 - " movq 32(%0), %%mm0\n"
8279 - " movq 40(%0), %%mm1\n"
8280 - " movq 48(%0), %%mm2\n"
8281 - " movq 56(%0), %%mm3\n"
8282 - " movq %%mm0, 32(%1)\n"
8283 - " movq %%mm1, 40(%1)\n"
8284 - " movq %%mm2, 48(%1)\n"
8285 - " movq %%mm3, 56(%1)\n"
8286 + "1: prefetch 320(%1)\n"
8287 + "2: movq (%1), %%mm0\n"
8288 + " movq 8(%1), %%mm1\n"
8289 + " movq 16(%1), %%mm2\n"
8290 + " movq 24(%1), %%mm3\n"
8291 + " movq %%mm0, (%2)\n"
8292 + " movq %%mm1, 8(%2)\n"
8293 + " movq %%mm2, 16(%2)\n"
8294 + " movq %%mm3, 24(%2)\n"
8295 + " movq 32(%1), %%mm0\n"
8296 + " movq 40(%1), %%mm1\n"
8297 + " movq 48(%1), %%mm2\n"
8298 + " movq 56(%1), %%mm3\n"
8299 + " movq %%mm0, 32(%2)\n"
8300 + " movq %%mm1, 40(%2)\n"
8301 + " movq %%mm2, 48(%2)\n"
8302 + " movq %%mm3, 56(%2)\n"
8303 ".section .fixup, \"ax\"\n"
8304 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8307 +#ifdef CONFIG_PAX_KERNEXEC
8308 + " movl %%cr0, %0\n"
8309 + " movl %0, %%eax\n"
8310 + " andl $0xFFFEFFFF, %%eax\n"
8311 + " movl %%eax, %%cr0\n"
8314 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8316 +#ifdef CONFIG_PAX_KERNEXEC
8317 + " movl %0, %%cr0\n"
8322 _ASM_EXTABLE(1b, 3b)
8323 - : : "r" (from), "r" (to) : "memory");
8324 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8328 @@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
8329 static void fast_copy_page(void *to, void *from)
8332 + unsigned long cr0;
8336 @@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
8337 * but that is for later. -AV
8339 __asm__ __volatile__(
8340 - "1: prefetch (%0)\n"
8341 - " prefetch 64(%0)\n"
8342 - " prefetch 128(%0)\n"
8343 - " prefetch 192(%0)\n"
8344 - " prefetch 256(%0)\n"
8345 + "1: prefetch (%1)\n"
8346 + " prefetch 64(%1)\n"
8347 + " prefetch 128(%1)\n"
8348 + " prefetch 192(%1)\n"
8349 + " prefetch 256(%1)\n"
8351 ".section .fixup, \"ax\"\n"
8352 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8355 +#ifdef CONFIG_PAX_KERNEXEC
8356 + " movl %%cr0, %0\n"
8357 + " movl %0, %%eax\n"
8358 + " andl $0xFFFEFFFF, %%eax\n"
8359 + " movl %%eax, %%cr0\n"
8362 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8364 +#ifdef CONFIG_PAX_KERNEXEC
8365 + " movl %0, %%cr0\n"
8370 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
8371 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
8373 for (i = 0; i < (4096-320)/64; i++) {
8374 __asm__ __volatile__ (
8375 - "1: prefetch 320(%0)\n"
8376 - "2: movq (%0), %%mm0\n"
8377 - " movntq %%mm0, (%1)\n"
8378 - " movq 8(%0), %%mm1\n"
8379 - " movntq %%mm1, 8(%1)\n"
8380 - " movq 16(%0), %%mm2\n"
8381 - " movntq %%mm2, 16(%1)\n"
8382 - " movq 24(%0), %%mm3\n"
8383 - " movntq %%mm3, 24(%1)\n"
8384 - " movq 32(%0), %%mm4\n"
8385 - " movntq %%mm4, 32(%1)\n"
8386 - " movq 40(%0), %%mm5\n"
8387 - " movntq %%mm5, 40(%1)\n"
8388 - " movq 48(%0), %%mm6\n"
8389 - " movntq %%mm6, 48(%1)\n"
8390 - " movq 56(%0), %%mm7\n"
8391 - " movntq %%mm7, 56(%1)\n"
8392 + "1: prefetch 320(%1)\n"
8393 + "2: movq (%1), %%mm0\n"
8394 + " movntq %%mm0, (%2)\n"
8395 + " movq 8(%1), %%mm1\n"
8396 + " movntq %%mm1, 8(%2)\n"
8397 + " movq 16(%1), %%mm2\n"
8398 + " movntq %%mm2, 16(%2)\n"
8399 + " movq 24(%1), %%mm3\n"
8400 + " movntq %%mm3, 24(%2)\n"
8401 + " movq 32(%1), %%mm4\n"
8402 + " movntq %%mm4, 32(%2)\n"
8403 + " movq 40(%1), %%mm5\n"
8404 + " movntq %%mm5, 40(%2)\n"
8405 + " movq 48(%1), %%mm6\n"
8406 + " movntq %%mm6, 48(%2)\n"
8407 + " movq 56(%1), %%mm7\n"
8408 + " movntq %%mm7, 56(%2)\n"
8409 ".section .fixup, \"ax\"\n"
8410 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8413 +#ifdef CONFIG_PAX_KERNEXEC
8414 + " movl %%cr0, %0\n"
8415 + " movl %0, %%eax\n"
8416 + " andl $0xFFFEFFFF, %%eax\n"
8417 + " movl %%eax, %%cr0\n"
8420 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8422 +#ifdef CONFIG_PAX_KERNEXEC
8423 + " movl %0, %%cr0\n"
8428 - _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
8429 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8433 @@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
8434 static void fast_copy_page(void *to, void *from)
8437 + unsigned long cr0;
8441 __asm__ __volatile__ (
8442 - "1: prefetch (%0)\n"
8443 - " prefetch 64(%0)\n"
8444 - " prefetch 128(%0)\n"
8445 - " prefetch 192(%0)\n"
8446 - " prefetch 256(%0)\n"
8447 + "1: prefetch (%1)\n"
8448 + " prefetch 64(%1)\n"
8449 + " prefetch 128(%1)\n"
8450 + " prefetch 192(%1)\n"
8451 + " prefetch 256(%1)\n"
8453 ".section .fixup, \"ax\"\n"
8454 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8457 +#ifdef CONFIG_PAX_KERNEXEC
8458 + " movl %%cr0, %0\n"
8459 + " movl %0, %%eax\n"
8460 + " andl $0xFFFEFFFF, %%eax\n"
8461 + " movl %%eax, %%cr0\n"
8464 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8466 +#ifdef CONFIG_PAX_KERNEXEC
8467 + " movl %0, %%cr0\n"
8472 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
8473 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
8475 for (i = 0; i < 4096/64; i++) {
8476 __asm__ __volatile__ (
8477 - "1: prefetch 320(%0)\n"
8478 - "2: movq (%0), %%mm0\n"
8479 - " movq 8(%0), %%mm1\n"
8480 - " movq 16(%0), %%mm2\n"
8481 - " movq 24(%0), %%mm3\n"
8482 - " movq %%mm0, (%1)\n"
8483 - " movq %%mm1, 8(%1)\n"
8484 - " movq %%mm2, 16(%1)\n"
8485 - " movq %%mm3, 24(%1)\n"
8486 - " movq 32(%0), %%mm0\n"
8487 - " movq 40(%0), %%mm1\n"
8488 - " movq 48(%0), %%mm2\n"
8489 - " movq 56(%0), %%mm3\n"
8490 - " movq %%mm0, 32(%1)\n"
8491 - " movq %%mm1, 40(%1)\n"
8492 - " movq %%mm2, 48(%1)\n"
8493 - " movq %%mm3, 56(%1)\n"
8494 + "1: prefetch 320(%1)\n"
8495 + "2: movq (%1), %%mm0\n"
8496 + " movq 8(%1), %%mm1\n"
8497 + " movq 16(%1), %%mm2\n"
8498 + " movq 24(%1), %%mm3\n"
8499 + " movq %%mm0, (%2)\n"
8500 + " movq %%mm1, 8(%2)\n"
8501 + " movq %%mm2, 16(%2)\n"
8502 + " movq %%mm3, 24(%2)\n"
8503 + " movq 32(%1), %%mm0\n"
8504 + " movq 40(%1), %%mm1\n"
8505 + " movq 48(%1), %%mm2\n"
8506 + " movq 56(%1), %%mm3\n"
8507 + " movq %%mm0, 32(%2)\n"
8508 + " movq %%mm1, 40(%2)\n"
8509 + " movq %%mm2, 48(%2)\n"
8510 + " movq %%mm3, 56(%2)\n"
8511 ".section .fixup, \"ax\"\n"
8512 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8515 +#ifdef CONFIG_PAX_KERNEXEC
8516 + " movl %%cr0, %0\n"
8517 + " movl %0, %%eax\n"
8518 + " andl $0xFFFEFFFF, %%eax\n"
8519 + " movl %%eax, %%cr0\n"
8522 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8524 +#ifdef CONFIG_PAX_KERNEXEC
8525 + " movl %0, %%cr0\n"
8530 _ASM_EXTABLE(1b, 3b)
8531 - : : "r" (from), "r" (to) : "memory");
8532 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8536 diff -urNp linux-2.6.27.10/arch/x86/lib/putuser.S linux-2.6.27.10/arch/x86/lib/putuser.S
8537 --- linux-2.6.27.10/arch/x86/lib/putuser.S 2008-11-07 12:55:34.000000000 -0500
8538 +++ linux-2.6.27.10/arch/x86/lib/putuser.S 2008-11-18 03:38:44.000000000 -0500
8540 #include <asm/thread_info.h>
8541 #include <asm/errno.h>
8542 #include <asm/asm.h>
8543 +#include <asm/segment.h>
8547 @@ -39,7 +40,19 @@ ENTRY(__put_user_1)
8549 cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
8552 +#ifdef CONFIG_X86_32
8553 + pushl $(__USER_DS)
8557 1: movb %al,(%_ASM_CX)
8559 +#ifdef CONFIG_X86_32
8566 ENDPROC(__put_user_1)
8567 @@ -50,7 +63,19 @@ ENTRY(__put_user_2)
8569 cmp %_ASM_BX,%_ASM_CX
8572 +#ifdef CONFIG_X86_32
8573 + pushl $(__USER_DS)
8577 2: movw %ax,(%_ASM_CX)
8579 +#ifdef CONFIG_X86_32
8586 ENDPROC(__put_user_2)
8587 @@ -61,7 +86,19 @@ ENTRY(__put_user_4)
8589 cmp %_ASM_BX,%_ASM_CX
8592 +#ifdef CONFIG_X86_32
8593 + pushl $(__USER_DS)
8597 3: movl %eax,(%_ASM_CX)
8599 +#ifdef CONFIG_X86_32
8606 ENDPROC(__put_user_4)
8607 @@ -72,16 +109,34 @@ ENTRY(__put_user_8)
8609 cmp %_ASM_BX,%_ASM_CX
8612 +#ifdef CONFIG_X86_32
8613 + pushl $(__USER_DS)
8617 4: mov %_ASM_AX,(%_ASM_CX)
8618 #ifdef CONFIG_X86_32
8619 5: movl %edx,4(%_ASM_CX)
8622 +#ifdef CONFIG_X86_32
8629 ENDPROC(__put_user_8)
8634 +#ifdef CONFIG_X86_32
8642 diff -urNp linux-2.6.27.10/arch/x86/lib/usercopy_32.c linux-2.6.27.10/arch/x86/lib/usercopy_32.c
8643 --- linux-2.6.27.10/arch/x86/lib/usercopy_32.c 2008-11-07 12:55:34.000000000 -0500
8644 +++ linux-2.6.27.10/arch/x86/lib/usercopy_32.c 2008-11-18 03:38:44.000000000 -0500
8645 @@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
8646 * Copy a null terminated string from userspace.
8649 -#define __do_strncpy_from_user(dst, src, count, res) \
8651 - int __d0, __d1, __d2; \
8653 - __asm__ __volatile__( \
8654 - " testl %1,%1\n" \
8658 - " testb %%al,%%al\n" \
8662 - "1: subl %1,%0\n" \
8664 - ".section .fixup,\"ax\"\n" \
8665 - "3: movl %5,%0\n" \
8668 - _ASM_EXTABLE(0b,3b) \
8669 - : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \
8671 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
8674 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
8676 + int __d0, __d1, __d2;
8677 + long res = -EFAULT;
8680 + __asm__ __volatile__(
8681 + " movw %w10,%%ds\n"
8686 + " testb %%al,%%al\n"
8694 + ".section .fixup,\"ax\"\n"
8698 + _ASM_EXTABLE(0b,3b)
8699 + : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),
8701 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
8708 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
8709 @@ -78,9 +85,7 @@ do { \
8711 __strncpy_from_user(char *dst, const char __user *src, long count)
8714 - __do_strncpy_from_user(dst, src, count, res);
8716 + return __do_strncpy_from_user(dst, src, count);
8718 EXPORT_SYMBOL(__strncpy_from_user);
8720 @@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char
8723 if (access_ok(VERIFY_READ, src, 1))
8724 - __do_strncpy_from_user(dst, src, count, res);
8725 + res = __do_strncpy_from_user(dst, src, count);
8728 EXPORT_SYMBOL(strncpy_from_user);
8729 @@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
8733 -#define __do_clear_user(addr,size) \
8737 - __asm__ __volatile__( \
8738 - "0: rep; stosl\n" \
8740 - "1: rep; stosb\n" \
8742 - ".section .fixup,\"ax\"\n" \
8743 - "3: lea 0(%2,%0,4),%0\n" \
8746 - _ASM_EXTABLE(0b,3b) \
8747 - _ASM_EXTABLE(1b,2b) \
8748 - : "=&c"(size), "=&D" (__d0) \
8749 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
8751 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
8756 + __asm__ __volatile__(
8757 + " movw %w6,%%es\n"
8764 + ".section .fixup,\"ax\"\n"
8765 + "3: lea 0(%2,%0,4),%0\n"
8768 + _ASM_EXTABLE(0b,3b)
8769 + _ASM_EXTABLE(1b,2b)
8770 + : "=&c"(size), "=&D" (__d0)
8771 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
8777 * clear_user: - Zero a block of memory in user space.
8778 @@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
8781 if (access_ok(VERIFY_WRITE, to, n))
8782 - __do_clear_user(to, n);
8783 + n = __do_clear_user(to, n);
8786 EXPORT_SYMBOL(clear_user);
8787 @@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
8789 __clear_user(void __user *to, unsigned long n)
8791 - __do_clear_user(to, n);
8793 + return __do_clear_user(to, n);
8795 EXPORT_SYMBOL(__clear_user);
8797 @@ -193,14 +203,17 @@ long strnlen_user(const char __user *s,
8800 __asm__ __volatile__(
8801 + " movw %w8,%%es\n"
8804 - " andl %0,%%ecx\n"
8805 + " movl %0,%%ecx\n"
8813 ".section .fixup,\"ax\"\n"
8814 "2: xorl %%eax,%%eax\n"
8816 @@ -212,7 +225,7 @@ long strnlen_user(const char __user *s,
8819 :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp)
8820 - :"0" (n), "1" (s), "2" (0), "3" (mask)
8821 + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
8825 @@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
8827 #ifdef CONFIG_X86_INTEL_USERCOPY
8828 static unsigned long
8829 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
8830 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
8833 __asm__ __volatile__(
8834 + " movw %w6, %%es\n"
8836 "1: movl 32(%4), %%eax\n"
8838 @@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
8840 "3: movl 0(%4), %%eax\n"
8841 "4: movl 4(%4), %%edx\n"
8842 - "5: movl %%eax, 0(%3)\n"
8843 - "6: movl %%edx, 4(%3)\n"
8844 + "5: movl %%eax, %%es:0(%3)\n"
8845 + "6: movl %%edx, %%es:4(%3)\n"
8846 "7: movl 8(%4), %%eax\n"
8847 "8: movl 12(%4),%%edx\n"
8848 - "9: movl %%eax, 8(%3)\n"
8849 - "10: movl %%edx, 12(%3)\n"
8850 + "9: movl %%eax, %%es:8(%3)\n"
8851 + "10: movl %%edx, %%es:12(%3)\n"
8852 "11: movl 16(%4), %%eax\n"
8853 "12: movl 20(%4), %%edx\n"
8854 - "13: movl %%eax, 16(%3)\n"
8855 - "14: movl %%edx, 20(%3)\n"
8856 + "13: movl %%eax, %%es:16(%3)\n"
8857 + "14: movl %%edx, %%es:20(%3)\n"
8858 "15: movl 24(%4), %%eax\n"
8859 "16: movl 28(%4), %%edx\n"
8860 - "17: movl %%eax, 24(%3)\n"
8861 - "18: movl %%edx, 28(%3)\n"
8862 + "17: movl %%eax, %%es:24(%3)\n"
8863 + "18: movl %%edx, %%es:28(%3)\n"
8864 "19: movl 32(%4), %%eax\n"
8865 "20: movl 36(%4), %%edx\n"
8866 - "21: movl %%eax, 32(%3)\n"
8867 - "22: movl %%edx, 36(%3)\n"
8868 + "21: movl %%eax, %%es:32(%3)\n"
8869 + "22: movl %%edx, %%es:36(%3)\n"
8870 "23: movl 40(%4), %%eax\n"
8871 "24: movl 44(%4), %%edx\n"
8872 - "25: movl %%eax, 40(%3)\n"
8873 - "26: movl %%edx, 44(%3)\n"
8874 + "25: movl %%eax, %%es:40(%3)\n"
8875 + "26: movl %%edx, %%es:44(%3)\n"
8876 "27: movl 48(%4), %%eax\n"
8877 "28: movl 52(%4), %%edx\n"
8878 - "29: movl %%eax, 48(%3)\n"
8879 - "30: movl %%edx, 52(%3)\n"
8880 + "29: movl %%eax, %%es:48(%3)\n"
8881 + "30: movl %%edx, %%es:52(%3)\n"
8882 "31: movl 56(%4), %%eax\n"
8883 "32: movl 60(%4), %%edx\n"
8884 - "33: movl %%eax, 56(%3)\n"
8885 - "34: movl %%edx, 60(%3)\n"
8886 + "33: movl %%eax, %%es:56(%3)\n"
8887 + "34: movl %%edx, %%es:60(%3)\n"
8891 @@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
8892 "36: movl %%eax, %0\n"
8897 ".section .fixup,\"ax\"\n"
8898 "101: lea 0(%%eax,%0,4),%0\n"
8900 @@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
8903 : "=&c"(size), "=&D" (d0), "=&S" (d1)
8904 - : "1"(to), "2"(from), "0"(size)
8905 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8906 + : "eax", "edx", "memory");
8910 +static unsigned long
8911 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
8914 + __asm__ __volatile__(
8915 + " movw %w6, %%ds\n"
8916 + " .align 2,0x90\n"
8917 + "1: movl 32(%4), %%eax\n"
8920 + "2: movl 64(%4), %%eax\n"
8921 + " .align 2,0x90\n"
8922 + "3: movl 0(%4), %%eax\n"
8923 + "4: movl 4(%4), %%edx\n"
8924 + "5: movl %%eax, %%es:0(%3)\n"
8925 + "6: movl %%edx, %%es:4(%3)\n"
8926 + "7: movl 8(%4), %%eax\n"
8927 + "8: movl 12(%4),%%edx\n"
8928 + "9: movl %%eax, %%es:8(%3)\n"
8929 + "10: movl %%edx, %%es:12(%3)\n"
8930 + "11: movl 16(%4), %%eax\n"
8931 + "12: movl 20(%4), %%edx\n"
8932 + "13: movl %%eax, %%es:16(%3)\n"
8933 + "14: movl %%edx, %%es:20(%3)\n"
8934 + "15: movl 24(%4), %%eax\n"
8935 + "16: movl 28(%4), %%edx\n"
8936 + "17: movl %%eax, %%es:24(%3)\n"
8937 + "18: movl %%edx, %%es:28(%3)\n"
8938 + "19: movl 32(%4), %%eax\n"
8939 + "20: movl 36(%4), %%edx\n"
8940 + "21: movl %%eax, %%es:32(%3)\n"
8941 + "22: movl %%edx, %%es:36(%3)\n"
8942 + "23: movl 40(%4), %%eax\n"
8943 + "24: movl 44(%4), %%edx\n"
8944 + "25: movl %%eax, %%es:40(%3)\n"
8945 + "26: movl %%edx, %%es:44(%3)\n"
8946 + "27: movl 48(%4), %%eax\n"
8947 + "28: movl 52(%4), %%edx\n"
8948 + "29: movl %%eax, %%es:48(%3)\n"
8949 + "30: movl %%edx, %%es:52(%3)\n"
8950 + "31: movl 56(%4), %%eax\n"
8951 + "32: movl 60(%4), %%edx\n"
8952 + "33: movl %%eax, %%es:56(%3)\n"
8953 + "34: movl %%edx, %%es:60(%3)\n"
8954 + " addl $-64, %0\n"
8959 + "35: movl %0, %%eax\n"
8961 + " andl $3, %%eax\n"
8963 + "99: rep; movsl\n"
8964 + "36: movl %%eax, %0\n"
8965 + "37: rep; movsb\n"
8969 + ".section .fixup,\"ax\"\n"
8970 + "101: lea 0(%%eax,%0,4),%0\n"
8973 + ".section __ex_table,\"a\"\n"
8975 + " .long 1b,100b\n"
8976 + " .long 2b,100b\n"
8977 + " .long 3b,100b\n"
8978 + " .long 4b,100b\n"
8979 + " .long 5b,100b\n"
8980 + " .long 6b,100b\n"
8981 + " .long 7b,100b\n"
8982 + " .long 8b,100b\n"
8983 + " .long 9b,100b\n"
8984 + " .long 10b,100b\n"
8985 + " .long 11b,100b\n"
8986 + " .long 12b,100b\n"
8987 + " .long 13b,100b\n"
8988 + " .long 14b,100b\n"
8989 + " .long 15b,100b\n"
8990 + " .long 16b,100b\n"
8991 + " .long 17b,100b\n"
8992 + " .long 18b,100b\n"
8993 + " .long 19b,100b\n"
8994 + " .long 20b,100b\n"
8995 + " .long 21b,100b\n"
8996 + " .long 22b,100b\n"
8997 + " .long 23b,100b\n"
8998 + " .long 24b,100b\n"
8999 + " .long 25b,100b\n"
9000 + " .long 26b,100b\n"
9001 + " .long 27b,100b\n"
9002 + " .long 28b,100b\n"
9003 + " .long 29b,100b\n"
9004 + " .long 30b,100b\n"
9005 + " .long 31b,100b\n"
9006 + " .long 32b,100b\n"
9007 + " .long 33b,100b\n"
9008 + " .long 34b,100b\n"
9009 + " .long 35b,100b\n"
9010 + " .long 36b,100b\n"
9011 + " .long 37b,100b\n"
9012 + " .long 99b,101b\n"
9014 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
9015 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9016 : "eax", "edx", "memory");
9019 @@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
9022 __asm__ __volatile__(
9023 + " movw %w6, %%ds\n"
9025 "0: movl 32(%4), %%eax\n"
9027 @@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
9029 "2: movl 0(%4), %%eax\n"
9030 "21: movl 4(%4), %%edx\n"
9031 - " movl %%eax, 0(%3)\n"
9032 - " movl %%edx, 4(%3)\n"
9033 + " movl %%eax, %%es:0(%3)\n"
9034 + " movl %%edx, %%es:4(%3)\n"
9035 "3: movl 8(%4), %%eax\n"
9036 "31: movl 12(%4),%%edx\n"
9037 - " movl %%eax, 8(%3)\n"
9038 - " movl %%edx, 12(%3)\n"
9039 + " movl %%eax, %%es:8(%3)\n"
9040 + " movl %%edx, %%es:12(%3)\n"
9041 "4: movl 16(%4), %%eax\n"
9042 "41: movl 20(%4), %%edx\n"
9043 - " movl %%eax, 16(%3)\n"
9044 - " movl %%edx, 20(%3)\n"
9045 + " movl %%eax, %%es:16(%3)\n"
9046 + " movl %%edx, %%es:20(%3)\n"
9047 "10: movl 24(%4), %%eax\n"
9048 "51: movl 28(%4), %%edx\n"
9049 - " movl %%eax, 24(%3)\n"
9050 - " movl %%edx, 28(%3)\n"
9051 + " movl %%eax, %%es:24(%3)\n"
9052 + " movl %%edx, %%es:28(%3)\n"
9053 "11: movl 32(%4), %%eax\n"
9054 "61: movl 36(%4), %%edx\n"
9055 - " movl %%eax, 32(%3)\n"
9056 - " movl %%edx, 36(%3)\n"
9057 + " movl %%eax, %%es:32(%3)\n"
9058 + " movl %%edx, %%es:36(%3)\n"
9059 "12: movl 40(%4), %%eax\n"
9060 "71: movl 44(%4), %%edx\n"
9061 - " movl %%eax, 40(%3)\n"
9062 - " movl %%edx, 44(%3)\n"
9063 + " movl %%eax, %%es:40(%3)\n"
9064 + " movl %%edx, %%es:44(%3)\n"
9065 "13: movl 48(%4), %%eax\n"
9066 "81: movl 52(%4), %%edx\n"
9067 - " movl %%eax, 48(%3)\n"
9068 - " movl %%edx, 52(%3)\n"
9069 + " movl %%eax, %%es:48(%3)\n"
9070 + " movl %%edx, %%es:52(%3)\n"
9071 "14: movl 56(%4), %%eax\n"
9072 "91: movl 60(%4), %%edx\n"
9073 - " movl %%eax, 56(%3)\n"
9074 - " movl %%edx, 60(%3)\n"
9075 + " movl %%eax, %%es:56(%3)\n"
9076 + " movl %%edx, %%es:60(%3)\n"
9080 @@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
9086 ".section .fixup,\"ax\"\n"
9087 "9: lea 0(%%eax,%0,4),%0\n"
9089 @@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
9092 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9093 - : "1"(to), "2"(from), "0"(size)
9094 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9095 : "eax", "edx", "memory");
9098 @@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
9101 __asm__ __volatile__(
9102 + " movw %w6, %%ds\n"
9104 "0: movl 32(%4), %%eax\n"
9106 @@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
9108 "2: movl 0(%4), %%eax\n"
9109 "21: movl 4(%4), %%edx\n"
9110 - " movnti %%eax, 0(%3)\n"
9111 - " movnti %%edx, 4(%3)\n"
9112 + " movnti %%eax, %%es:0(%3)\n"
9113 + " movnti %%edx, %%es:4(%3)\n"
9114 "3: movl 8(%4), %%eax\n"
9115 "31: movl 12(%4),%%edx\n"
9116 - " movnti %%eax, 8(%3)\n"
9117 - " movnti %%edx, 12(%3)\n"
9118 + " movnti %%eax, %%es:8(%3)\n"
9119 + " movnti %%edx, %%es:12(%3)\n"
9120 "4: movl 16(%4), %%eax\n"
9121 "41: movl 20(%4), %%edx\n"
9122 - " movnti %%eax, 16(%3)\n"
9123 - " movnti %%edx, 20(%3)\n"
9124 + " movnti %%eax, %%es:16(%3)\n"
9125 + " movnti %%edx, %%es:20(%3)\n"
9126 "10: movl 24(%4), %%eax\n"
9127 "51: movl 28(%4), %%edx\n"
9128 - " movnti %%eax, 24(%3)\n"
9129 - " movnti %%edx, 28(%3)\n"
9130 + " movnti %%eax, %%es:24(%3)\n"
9131 + " movnti %%edx, %%es:28(%3)\n"
9132 "11: movl 32(%4), %%eax\n"
9133 "61: movl 36(%4), %%edx\n"
9134 - " movnti %%eax, 32(%3)\n"
9135 - " movnti %%edx, 36(%3)\n"
9136 + " movnti %%eax, %%es:32(%3)\n"
9137 + " movnti %%edx, %%es:36(%3)\n"
9138 "12: movl 40(%4), %%eax\n"
9139 "71: movl 44(%4), %%edx\n"
9140 - " movnti %%eax, 40(%3)\n"
9141 - " movnti %%edx, 44(%3)\n"
9142 + " movnti %%eax, %%es:40(%3)\n"
9143 + " movnti %%edx, %%es:44(%3)\n"
9144 "13: movl 48(%4), %%eax\n"
9145 "81: movl 52(%4), %%edx\n"
9146 - " movnti %%eax, 48(%3)\n"
9147 - " movnti %%edx, 52(%3)\n"
9148 + " movnti %%eax, %%es:48(%3)\n"
9149 + " movnti %%edx, %%es:52(%3)\n"
9150 "14: movl 56(%4), %%eax\n"
9151 "91: movl 60(%4), %%edx\n"
9152 - " movnti %%eax, 56(%3)\n"
9153 - " movnti %%edx, 60(%3)\n"
9154 + " movnti %%eax, %%es:56(%3)\n"
9155 + " movnti %%edx, %%es:60(%3)\n"
9159 @@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
9165 ".section .fixup,\"ax\"\n"
9166 "9: lea 0(%%eax,%0,4),%0\n"
9168 @@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
9171 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9172 - : "1"(to), "2"(from), "0"(size)
9173 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9174 : "eax", "edx", "memory");
9177 @@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
9180 __asm__ __volatile__(
9181 + " movw %w6, %%ds\n"
9183 "0: movl 32(%4), %%eax\n"
9185 @@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
9187 "2: movl 0(%4), %%eax\n"
9188 "21: movl 4(%4), %%edx\n"
9189 - " movnti %%eax, 0(%3)\n"
9190 - " movnti %%edx, 4(%3)\n"
9191 + " movnti %%eax, %%es:0(%3)\n"
9192 + " movnti %%edx, %%es:4(%3)\n"
9193 "3: movl 8(%4), %%eax\n"
9194 "31: movl 12(%4),%%edx\n"
9195 - " movnti %%eax, 8(%3)\n"
9196 - " movnti %%edx, 12(%3)\n"
9197 + " movnti %%eax, %%es:8(%3)\n"
9198 + " movnti %%edx, %%es:12(%3)\n"
9199 "4: movl 16(%4), %%eax\n"
9200 "41: movl 20(%4), %%edx\n"
9201 - " movnti %%eax, 16(%3)\n"
9202 - " movnti %%edx, 20(%3)\n"
9203 + " movnti %%eax, %%es:16(%3)\n"
9204 + " movnti %%edx, %%es:20(%3)\n"
9205 "10: movl 24(%4), %%eax\n"
9206 "51: movl 28(%4), %%edx\n"
9207 - " movnti %%eax, 24(%3)\n"
9208 - " movnti %%edx, 28(%3)\n"
9209 + " movnti %%eax, %%es:24(%3)\n"
9210 + " movnti %%edx, %%es:28(%3)\n"
9211 "11: movl 32(%4), %%eax\n"
9212 "61: movl 36(%4), %%edx\n"
9213 - " movnti %%eax, 32(%3)\n"
9214 - " movnti %%edx, 36(%3)\n"
9215 + " movnti %%eax, %%es:32(%3)\n"
9216 + " movnti %%edx, %%es:36(%3)\n"
9217 "12: movl 40(%4), %%eax\n"
9218 "71: movl 44(%4), %%edx\n"
9219 - " movnti %%eax, 40(%3)\n"
9220 - " movnti %%edx, 44(%3)\n"
9221 + " movnti %%eax, %%es:40(%3)\n"
9222 + " movnti %%edx, %%es:44(%3)\n"
9223 "13: movl 48(%4), %%eax\n"
9224 "81: movl 52(%4), %%edx\n"
9225 - " movnti %%eax, 48(%3)\n"
9226 - " movnti %%edx, 52(%3)\n"
9227 + " movnti %%eax, %%es:48(%3)\n"
9228 + " movnti %%edx, %%es:52(%3)\n"
9229 "14: movl 56(%4), %%eax\n"
9230 "91: movl 60(%4), %%edx\n"
9231 - " movnti %%eax, 56(%3)\n"
9232 - " movnti %%edx, 60(%3)\n"
9233 + " movnti %%eax, %%es:56(%3)\n"
9234 + " movnti %%edx, %%es:60(%3)\n"
9238 @@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
9244 ".section .fixup,\"ax\"\n"
9245 "9: lea 0(%%eax,%0,4),%0\n"
9247 @@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
9250 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9251 - : "1"(to), "2"(from), "0"(size)
9252 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9253 : "eax", "edx", "memory");
9256 @@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
9258 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
9259 unsigned long size);
9260 -unsigned long __copy_user_intel(void __user *to, const void *from,
9261 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
9262 + unsigned long size);
9263 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
9264 unsigned long size);
9265 unsigned long __copy_user_zeroing_intel_nocache(void *to,
9266 const void __user *from, unsigned long size);
9267 #endif /* CONFIG_X86_INTEL_USERCOPY */
9269 /* Generic arbitrary sized copy. */
9270 -#define __copy_user(to, from, size) \
9272 - int __d0, __d1, __d2; \
9273 - __asm__ __volatile__( \
9280 - "4: rep; movsb\n" \
9284 - " .align 2,0x90\n" \
9285 - "0: rep; movsl\n" \
9287 - "1: rep; movsb\n" \
9289 - ".section .fixup,\"ax\"\n" \
9290 - "5: addl %3,%0\n" \
9292 - "3: lea 0(%3,%0,4),%0\n" \
9295 - ".section __ex_table,\"a\"\n" \
9297 - " .long 4b,5b\n" \
9298 - " .long 0b,3b\n" \
9299 - " .long 1b,2b\n" \
9301 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9302 - : "3"(size), "0"(size), "1"(to), "2"(from) \
9306 -#define __copy_user_zeroing(to, from, size) \
9308 - int __d0, __d1, __d2; \
9309 - __asm__ __volatile__( \
9316 - "4: rep; movsb\n" \
9320 - " .align 2,0x90\n" \
9321 - "0: rep; movsl\n" \
9323 - "1: rep; movsb\n" \
9325 - ".section .fixup,\"ax\"\n" \
9326 - "5: addl %3,%0\n" \
9328 - "3: lea 0(%3,%0,4),%0\n" \
9330 - " pushl %%eax\n" \
9331 - " xorl %%eax,%%eax\n" \
9337 - ".section __ex_table,\"a\"\n" \
9339 - " .long 4b,5b\n" \
9340 - " .long 0b,3b\n" \
9341 - " .long 1b,6b\n" \
9343 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9344 - : "3"(size), "0"(size), "1"(to), "2"(from) \
9347 +static unsigned long
9348 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
9350 + int __d0, __d1, __d2;
9352 + __asm__ __volatile__(
9353 + " movw %w8,%%es\n"
9364 + " .align 2,0x90\n"
9371 + ".section .fixup,\"ax\"\n"
9374 + "3: lea 0(%3,%0,4),%0\n"
9377 + ".section __ex_table,\"a\"\n"
9383 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9384 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9389 +static unsigned long
9390 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
9392 + int __d0, __d1, __d2;
9394 + __asm__ __volatile__(
9395 + " movw %w8,%%ds\n"
9406 + " .align 2,0x90\n"
9413 + ".section .fixup,\"ax\"\n"
9416 + "3: lea 0(%3,%0,4),%0\n"
9419 + ".section __ex_table,\"a\"\n"
9425 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9426 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9431 +static unsigned long
9432 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
9434 + int __d0, __d1, __d2;
9436 + __asm__ __volatile__(
9437 + " movw %w8,%%ds\n"
9448 + " .align 2,0x90\n"
9455 + ".section .fixup,\"ax\"\n"
9458 + "3: lea 0(%3,%0,4),%0\n"
9461 + " xorl %%eax,%%eax\n"
9467 + ".section __ex_table,\"a\"\n"
9473 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9474 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9479 unsigned long __copy_to_user_ll(void __user *to, const void *from,
9481 @@ -768,9 +959,9 @@ survive:
9484 if (movsl_is_ok(to, from, n))
9485 - __copy_user(to, from, n);
9486 + n = __generic_copy_to_user(to, from, n);
9488 - n = __copy_user_intel(to, from, n);
9489 + n = __generic_copy_to_user_intel(to, from, n);
9492 EXPORT_SYMBOL(__copy_to_user_ll);
9493 @@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
9496 if (movsl_is_ok(to, from, n))
9497 - __copy_user_zeroing(to, from, n);
9498 + n = __copy_user_zeroing(to, from, n);
9500 n = __copy_user_zeroing_intel(to, from, n);
9502 @@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
9505 if (movsl_is_ok(to, from, n))
9506 - __copy_user(to, from, n);
9507 + n = __generic_copy_from_user(to, from, n);
9509 - n = __copy_user_intel((void __user *)to,
9510 - (const void *)from, n);
9511 + n = __generic_copy_from_user_intel(to, from, n);
9514 EXPORT_SYMBOL(__copy_from_user_ll_nozero);
9515 @@ -802,12 +992,12 @@ unsigned long __copy_from_user_ll_nocach
9518 #ifdef CONFIG_X86_INTEL_USERCOPY
9519 - if (n > 64 && cpu_has_xmm2)
9520 + if ( n > 64 && cpu_has_xmm2)
9521 n = __copy_user_zeroing_intel_nocache(to, from, n);
9523 - __copy_user_zeroing(to, from, n);
9524 + n = __copy_user_zeroing(to, from, n);
9526 - __copy_user_zeroing(to, from, n);
9527 + n = __copy_user_zeroing(to, from, n);
9531 @@ -817,12 +1007,12 @@ unsigned long __copy_from_user_ll_nocach
9534 #ifdef CONFIG_X86_INTEL_USERCOPY
9535 - if (n > 64 && cpu_has_xmm2)
9536 + if ( n > 64 && cpu_has_xmm2)
9537 n = __copy_user_intel_nocache(to, from, n);
9539 - __copy_user(to, from, n);
9540 + n = __generic_copy_from_user(to, from, n);
9542 - __copy_user(to, from, n);
9543 + n = __generic_copy_from_user(to, from, n);
9547 @@ -871,8 +1061,35 @@ copy_from_user(void *to, const void __us
9549 if (access_ok(VERIFY_READ, from, n))
9550 n = __copy_from_user(to, from, n);
9552 + else if ((long)n > 0)
9556 EXPORT_SYMBOL(copy_from_user);
9558 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9559 +void __set_fs(mm_segment_t x, int cpu)
9561 + unsigned long limit = x.seg;
9562 + struct desc_struct d;
9564 + current_thread_info()->addr_limit = x;
9565 + if (likely(limit))
9566 + limit = (limit - 1UL) >> PAGE_SHIFT;
9567 + pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
9568 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
9571 +void set_fs(mm_segment_t x)
9573 + __set_fs(x, get_cpu());
9574 + put_cpu_no_resched();
9577 +void set_fs(mm_segment_t x)
9579 + current_thread_info()->addr_limit = x;
9583 +EXPORT_SYMBOL(set_fs);
9584 diff -urNp linux-2.6.27.10/arch/x86/mach-voyager/voyager_basic.c linux-2.6.27.10/arch/x86/mach-voyager/voyager_basic.c
9585 --- linux-2.6.27.10/arch/x86/mach-voyager/voyager_basic.c 2008-11-07 12:55:34.000000000 -0500
9586 +++ linux-2.6.27.10/arch/x86/mach-voyager/voyager_basic.c 2008-11-18 03:38:44.000000000 -0500
9587 @@ -123,7 +123,7 @@ int __init voyager_memory_detect(int reg
9590 unsigned long map_addr;
9591 - unsigned long old;
9594 if (region >= CLICK_ENTRIES) {
9595 printk("Voyager: Illegal ClickMap region %d\n", region);
9596 @@ -138,7 +138,7 @@ int __init voyager_memory_detect(int reg
9598 /* steal page 0 for this */
9600 - pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9601 + pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9603 /* now clear everything out but page 0 */
9604 map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
9605 diff -urNp linux-2.6.27.10/arch/x86/mach-voyager/voyager_smp.c linux-2.6.27.10/arch/x86/mach-voyager/voyager_smp.c
9606 --- linux-2.6.27.10/arch/x86/mach-voyager/voyager_smp.c 2008-11-07 12:55:34.000000000 -0500
9607 +++ linux-2.6.27.10/arch/x86/mach-voyager/voyager_smp.c 2008-11-18 03:38:44.000000000 -0500
9608 @@ -510,6 +510,10 @@ static void __init do_boot_cpu(__u8 cpu)
9609 __u32 *hijack_vector;
9610 __u32 start_phys_address = setup_trampoline();
9612 +#ifdef CONFIG_PAX_KERNEXEC
9613 + unsigned long cr0;
9616 /* There's a clever trick to this: The linux trampoline is
9617 * compiled to begin at absolute location zero, so make the
9618 * address zero but have the data segment selector compensate
9619 @@ -529,7 +533,17 @@ static void __init do_boot_cpu(__u8 cpu)
9622 per_cpu(current_task, cpu) = idle;
9623 - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9625 +#ifdef CONFIG_PAX_KERNEXEC
9626 + pax_open_kernel(cr0);
9629 + early_gdt_descr.address = get_cpu_gdt_table(cpu);
9631 +#ifdef CONFIG_PAX_KERNEXEC
9632 + pax_close_kernel(cr0);
9637 /* Note: Don't modify initial ss override */
9638 @@ -1141,7 +1155,7 @@ void smp_local_timer_interrupt(void)
9639 per_cpu(prof_counter, cpu);
9642 - update_process_times(user_mode_vm(get_irq_regs()));
9643 + update_process_times(user_mode(get_irq_regs()));
9646 if (((1 << cpu) & voyager_extended_vic_processors) == 0)
9647 diff -urNp linux-2.6.27.10/arch/x86/Makefile linux-2.6.27.10/arch/x86/Makefile
9648 --- linux-2.6.27.10/arch/x86/Makefile 2008-11-07 12:55:34.000000000 -0500
9649 +++ linux-2.6.27.10/arch/x86/Makefile 2008-11-18 03:38:44.000000000 -0500
9650 @@ -232,3 +232,12 @@ endef
9651 CLEAN_FILES += arch/x86/boot/fdimage \
9652 arch/x86/boot/image.iso \
9653 arch/x86/boot/mtools.conf
9657 +*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
9658 +*** Please upgrade your binutils to 2.18 or newer
9662 + $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
9663 diff -urNp linux-2.6.27.10/arch/x86/mm/discontig_32.c linux-2.6.27.10/arch/x86/mm/discontig_32.c
9664 --- linux-2.6.27.10/arch/x86/mm/discontig_32.c 2008-12-10 22:35:36.000000000 -0500
9665 +++ linux-2.6.27.10/arch/x86/mm/discontig_32.c 2008-12-10 22:35:46.000000000 -0500
9666 @@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
9670 -extern unsigned long find_max_low_pfn(void);
9671 extern unsigned long highend_pfn, highstart_pfn;
9673 #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
9674 diff -urNp linux-2.6.27.10/arch/x86/mm/extable.c linux-2.6.27.10/arch/x86/mm/extable.c
9675 --- linux-2.6.27.10/arch/x86/mm/extable.c 2008-11-07 12:55:34.000000000 -0500
9676 +++ linux-2.6.27.10/arch/x86/mm/extable.c 2008-11-18 03:38:44.000000000 -0500
9678 #include <linux/module.h>
9679 #include <linux/spinlock.h>
9680 +#include <linux/sort.h>
9681 #include <asm/uaccess.h>
9684 + * The exception table needs to be sorted so that the binary
9685 + * search that we use to find entries in it works properly.
9686 + * This is used both for the kernel exception table and for
9687 + * the exception tables of modules that get loaded.
9689 +static int cmp_ex(const void *a, const void *b)
9691 + const struct exception_table_entry *x = a, *y = b;
9693 + /* avoid overflow */
9694 + if (x->insn > y->insn)
9696 + if (x->insn < y->insn)
9701 +static void swap_ex(void *a, void *b, int size)
9703 + struct exception_table_entry t, *x = a, *y = b;
9705 +#ifdef CONFIG_PAX_KERNEXEC
9706 + unsigned long cr0;
9711 +#ifdef CONFIG_PAX_KERNEXEC
9712 + pax_open_kernel(cr0);
9718 +#ifdef CONFIG_PAX_KERNEXEC
9719 + pax_close_kernel(cr0);
9724 +void sort_extable(struct exception_table_entry *start,
9725 + struct exception_table_entry *finish)
9727 + sort(start, finish - start, sizeof(struct exception_table_entry),
9731 int fixup_exception(struct pt_regs *regs)
9733 const struct exception_table_entry *fixup;
9735 #ifdef CONFIG_PNPBIOS
9736 - if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
9737 + if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
9738 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
9739 extern u32 pnp_bios_is_utter_crap;
9740 pnp_bios_is_utter_crap = 1;
9741 diff -urNp linux-2.6.27.10/arch/x86/mm/fault.c linux-2.6.27.10/arch/x86/mm/fault.c
9742 --- linux-2.6.27.10/arch/x86/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
9743 +++ linux-2.6.27.10/arch/x86/mm/fault.c 2008-12-10 22:28:27.000000000 -0500
9745 #include <linux/kprobes.h>
9746 #include <linux/uaccess.h>
9747 #include <linux/kdebug.h>
9748 +#include <linux/unistd.h>
9749 +#include <linux/compiler.h>
9751 #include <asm/system.h>
9752 #include <asm/desc.h>
9753 @@ -66,7 +68,7 @@ static inline int notify_page_fault(stru
9756 /* kprobe_running() needs smp_processor_id() */
9757 - if (!user_mode_vm(regs)) {
9758 + if (!user_mode(regs)) {
9760 if (kprobe_running() && kprobe_fault_handler(regs, 14))
9762 @@ -264,6 +266,30 @@ bad:
9766 +#ifdef CONFIG_PAX_EMUTRAMP
9767 +static int pax_handle_fetch_fault(struct pt_regs *regs);
9770 +#ifdef CONFIG_PAX_PAGEEXEC
9771 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
9777 + pgd = pgd_offset(mm, address);
9778 + if (!pgd_present(*pgd))
9780 + pud = pud_offset(pgd, address);
9781 + if (!pud_present(*pud))
9783 + pmd = pmd_offset(pud, address);
9784 + if (!pmd_present(*pmd))
9790 #ifdef CONFIG_X86_32
9791 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
9793 @@ -350,7 +376,7 @@ static int is_errata93(struct pt_regs *r
9794 static int is_errata100(struct pt_regs *regs, unsigned long address)
9796 #ifdef CONFIG_X86_64
9797 - if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
9798 + if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
9802 @@ -387,14 +413,31 @@ static void show_fault_oops(struct pt_re
9805 #ifdef CONFIG_X86_PAE
9806 - if (error_code & PF_INSTR) {
9807 + if (nx_enabled && (error_code & PF_INSTR)) {
9809 pte_t *pte = lookup_address(address, &level);
9811 if (pte && pte_present(*pte) && !pte_exec(*pte))
9812 printk(KERN_CRIT "kernel tried to execute "
9813 "NX-protected page - exploit attempt? "
9814 - "(uid: %d)\n", current->uid);
9815 + "(uid: %d, task: %s, pid: %d)\n",
9816 + current->uid, current->comm, task_pid_nr(current));
9820 +#ifdef CONFIG_PAX_KERNEXEC
9821 +#ifdef CONFIG_MODULES
9822 + if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
9824 + if (init_mm.start_code <= address && address < init_mm.end_code)
9827 + if (current->signal->curr_ip)
9828 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9829 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
9831 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9832 + current->comm, task_pid_nr(current), current->uid, current->euid);
9836 @@ -586,13 +629,22 @@ void __kprobes do_page_fault(struct pt_r
9837 struct task_struct *tsk;
9838 struct mm_struct *mm;
9839 struct vm_area_struct *vma;
9840 - unsigned long address;
9843 #ifdef CONFIG_X86_64
9844 unsigned long flags;
9847 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9851 + unsigned char pte_mask;
9854 + /* get the address */
9855 + const unsigned long address = read_cr2();
9858 * We can fault from pretty much anywhere, with unknown IRQ state.
9860 @@ -602,9 +654,6 @@ void __kprobes do_page_fault(struct pt_r
9862 prefetchw(&mm->mmap_sem);
9864 - /* get the address */
9865 - address = read_cr2();
9867 si_code = SEGV_MAPERR;
9869 if (notify_page_fault(regs))
9870 @@ -657,7 +706,7 @@ void __kprobes do_page_fault(struct pt_r
9871 * atomic region then we must not take the fault.
9873 if (in_atomic() || !mm)
9874 - goto bad_area_nosemaphore;
9875 + goto bad_area_nopax;
9876 #else /* CONFIG_X86_64 */
9877 if (likely(regs->flags & X86_EFLAGS_IF))
9879 @@ -670,13 +719,13 @@ void __kprobes do_page_fault(struct pt_r
9880 * atomic region then we must not take the fault.
9882 if (unlikely(in_atomic() || !mm))
9883 - goto bad_area_nosemaphore;
9884 + goto bad_area_nopax;
9887 * User-mode registers count as a user access even for any
9888 * potential system fault or CPU buglet.
9890 - if (user_mode_vm(regs))
9891 + if (user_mode(regs))
9892 error_code |= PF_USER;
9895 @@ -698,10 +747,104 @@ again:
9896 if (!down_read_trylock(&mm->mmap_sem)) {
9897 if ((error_code & PF_USER) == 0 &&
9898 !search_exception_tables(regs->ip))
9899 - goto bad_area_nosemaphore;
9900 + goto bad_area_nopax;
9901 down_read(&mm->mmap_sem);
9904 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9905 + if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
9906 + !(mm->pax_flags & MF_PAX_PAGEEXEC))
9907 + goto not_pax_fault;
9909 + /* PaX: it's our fault, let's handle it if we can */
9911 + /* PaX: take a look at read faults before acquiring any locks */
9912 + if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
9913 + /* instruction fetch attempt from a protected page in user mode */
9914 + up_read(&mm->mmap_sem);
9916 +#ifdef CONFIG_PAX_EMUTRAMP
9917 + switch (pax_handle_fetch_fault(regs)) {
9923 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
9924 + do_group_exit(SIGKILL);
9927 + pmd = pax_get_pmd(mm, address);
9928 + if (unlikely(!pmd))
9929 + goto not_pax_fault;
9931 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
9932 + if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
9933 + pte_unmap_unlock(pte, ptl);
9934 + goto not_pax_fault;
9937 + if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
9938 + /* write attempt to a protected page in user mode */
9939 + pte_unmap_unlock(pte, ptl);
9940 + goto not_pax_fault;
9944 + if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
9946 + if (likely(address > get_limit(regs->cs)))
9949 + set_pte(pte, pte_mkread(*pte));
9950 + __flush_tlb_one(address);
9951 + pte_unmap_unlock(pte, ptl);
9952 + up_read(&mm->mmap_sem);
9956 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
9959 + * PaX: fill DTLB with user rights and retry
9961 + __asm__ __volatile__ (
9962 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9966 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
9968 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
9969 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
9970 + * page fault when examined during a TLB load attempt. this is true not only
9971 + * for PTEs holding a non-present entry but also present entries that will
9972 + * raise a page fault (such as those set up by PaX, or the copy-on-write
9973 + * mechanism). in effect it means that we do *not* need to flush the TLBs
9974 + * for our target pages since their PTEs are simply not in the TLBs at all.
9976 + * the best thing in omitting it is that we gain around 15-20% speed in the
9977 + * fast path of the page fault handler and can get rid of tracing since we
9978 + * can no longer flush unintended entries.
9982 + "testb $0,%%es:(%0)\n"
9984 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9989 + : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
9990 + : "memory", "cc");
9991 + pte_unmap_unlock(pte, ptl);
9992 + up_read(&mm->mmap_sem);
9998 vma = find_vma(mm, address);
10001 @@ -709,16 +852,20 @@ again:
10003 if (!(vma->vm_flags & VM_GROWSDOWN))
10005 - if (error_code & PF_USER) {
10007 - * Accessing the stack below %sp is always a bug.
10008 - * The large cushion allows instructions like enter
10009 - * and pusha to work. ("enter $65535,$31" pushes
10010 - * 32 pointers and then decrements %sp by 65535.)
10012 - if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
10016 + * Accessing the stack below %sp is always a bug.
10017 + * The large cushion allows instructions like enter
10018 + * and pusha to work. ("enter $65535,$31" pushes
10019 + * 32 pointers and then decrements %sp by 65535.)
10021 + if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
10024 +#ifdef CONFIG_PAX_SEGMEXEC
10025 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
10029 if (expand_stack(vma, address))
10032 @@ -728,6 +875,8 @@ again:
10034 si_code = SEGV_ACCERR;
10036 + if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
10038 switch (error_code & (PF_PROT|PF_WRITE)) {
10039 default: /* 3: write, present */
10041 @@ -785,6 +934,54 @@ bad_area:
10042 up_read(&mm->mmap_sem);
10044 bad_area_nosemaphore:
10046 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10047 + if (mm && (error_code & PF_USER)) {
10048 + unsigned long ip = regs->ip;
10050 + if (v8086_mode(regs))
10051 + ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
10054 + * It's possible to have interrupts off here.
10056 + local_irq_enable();
10058 +#ifdef CONFIG_PAX_PAGEEXEC
10059 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
10060 + ((nx_enabled && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && regs->ip == address))) {
10062 +#ifdef CONFIG_PAX_EMUTRAMP
10063 + switch (pax_handle_fetch_fault(regs)) {
10069 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
10070 + do_group_exit(SIGKILL);
10074 +#ifdef CONFIG_PAX_SEGMEXEC
10075 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
10077 +#ifdef CONFIG_PAX_EMUTRAMP
10078 + switch (pax_handle_fetch_fault(regs)) {
10084 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
10085 + do_group_exit(SIGKILL);
10093 /* User mode accesses just cause a SIGSEGV */
10094 if (error_code & PF_USER) {
10096 @@ -863,7 +1060,7 @@ no_context:
10097 #ifdef CONFIG_X86_32
10098 die("Oops", regs, error_code);
10100 - do_exit(SIGKILL);
10101 + do_group_exit(SIGKILL);
10103 if (__die("Oops", regs, error_code))
10105 @@ -877,17 +1074,17 @@ no_context:
10106 * us unable to handle the page fault gracefully.
10109 - up_read(&mm->mmap_sem);
10110 if (is_global_init(tsk)) {
10112 #ifdef CONFIG_X86_32
10113 - down_read(&mm->mmap_sem);
10116 + up_read(&mm->mmap_sem);
10121 + up_read(&mm->mmap_sem);
10122 printk("VM: killing process %s\n", tsk->comm);
10123 if (error_code & PF_USER)
10124 do_group_exit(SIGKILL);
10125 @@ -959,3 +1156,174 @@ void vmalloc_sync_all(void)
10130 +#ifdef CONFIG_PAX_EMUTRAMP
10131 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
10135 + do { /* PaX: gcc trampoline emulation #1 */
10136 + unsigned char mov1, mov2;
10137 + unsigned short jmp;
10138 + unsigned int addr1, addr2;
10140 +#ifdef CONFIG_X86_64
10141 + if ((regs->ip + 11) >> 32)
10145 + err = get_user(mov1, (unsigned char __user *)regs->ip);
10146 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
10147 + err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
10148 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
10149 + err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
10154 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10155 + regs->cx = addr1;
10156 + regs->ax = addr2;
10157 + regs->ip = addr2;
10162 + do { /* PaX: gcc trampoline emulation #2 */
10163 + unsigned char mov, jmp;
10164 + unsigned int addr1, addr2;
10166 +#ifdef CONFIG_X86_64
10167 + if ((regs->ip + 9) >> 32)
10171 + err = get_user(mov, (unsigned char __user *)regs->ip);
10172 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
10173 + err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
10174 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
10179 + if (mov == 0xB9 && jmp == 0xE9) {
10180 + regs->cx = addr1;
10181 + regs->ip = (unsigned int)(regs->ip + addr2 + 10);
10186 + return 1; /* PaX in action */
10189 +#ifdef CONFIG_X86_64
10190 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
10194 + do { /* PaX: gcc trampoline emulation #1 */
10195 + unsigned short mov1, mov2, jmp1;
10196 + unsigned char jmp2;
10197 + unsigned int addr1;
10198 + unsigned long addr2;
10200 + err = get_user(mov1, (unsigned short __user *)regs->ip);
10201 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
10202 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
10203 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
10204 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
10205 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
10210 + if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10211 + regs->r11 = addr1;
10212 + regs->r10 = addr2;
10213 + regs->ip = addr1;
10218 + do { /* PaX: gcc trampoline emulation #2 */
10219 + unsigned short mov1, mov2, jmp1;
10220 + unsigned char jmp2;
10221 + unsigned long addr1, addr2;
10223 + err = get_user(mov1, (unsigned short __user *)regs->ip);
10224 + err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
10225 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
10226 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
10227 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
10228 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
10233 + if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10234 + regs->r11 = addr1;
10235 + regs->r10 = addr2;
10236 + regs->ip = addr1;
10241 + return 1; /* PaX in action */
10246 + * PaX: decide what to do with offenders (regs->ip = fault address)
10248 + * returns 1 when task should be killed
10249 + * 2 when gcc trampoline was detected
10251 +static int pax_handle_fetch_fault(struct pt_regs *regs)
10253 + if (v8086_mode(regs))
10256 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10259 +#ifdef CONFIG_X86_32
10260 + return pax_handle_fetch_fault_32(regs);
10262 + if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
10263 + return pax_handle_fetch_fault_32(regs);
10265 + return pax_handle_fetch_fault_64(regs);
10270 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10271 +void pax_report_insns(void *pc, void *sp)
10275 + printk(KERN_ERR "PAX: bytes at PC: ");
10276 + for (i = 0; i < 20; i++) {
10278 + if (get_user(c, (unsigned char __user *)pc+i))
10279 + printk(KERN_CONT "?? ");
10281 + printk(KERN_CONT "%02x ", c);
10285 + printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
10286 + for (i = -1; i < 80 / sizeof(long); i++) {
10288 + if (get_user(c, (unsigned long __user *)sp+i))
10289 +#ifdef CONFIG_X86_32
10290 + printk(KERN_CONT "???????? ");
10292 + printk(KERN_CONT "???????????????? ");
10295 + printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
10300 diff -urNp linux-2.6.27.10/arch/x86/mm/highmem_32.c linux-2.6.27.10/arch/x86/mm/highmem_32.c
10301 --- linux-2.6.27.10/arch/x86/mm/highmem_32.c 2008-11-07 12:55:34.000000000 -0500
10302 +++ linux-2.6.27.10/arch/x86/mm/highmem_32.c 2008-11-18 03:38:44.000000000 -0500
10303 @@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
10304 enum fixed_addresses idx;
10305 unsigned long vaddr;
10307 +#ifdef CONFIG_PAX_KERNEXEC
10308 + unsigned long cr0;
10311 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
10312 pagefault_disable();
10314 @@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
10315 idx = type + KM_TYPE_NR*smp_processor_id();
10316 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10317 BUG_ON(!pte_none(*(kmap_pte-idx)));
10319 +#ifdef CONFIG_PAX_KERNEXEC
10320 + pax_open_kernel(cr0);
10323 set_pte(kmap_pte-idx, mk_pte(page, prot));
10325 +#ifdef CONFIG_PAX_KERNEXEC
10326 + pax_close_kernel(cr0);
10329 arch_flush_lazy_mmu_mode();
10331 return (void *)vaddr;
10332 @@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
10333 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
10334 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
10336 +#ifdef CONFIG_PAX_KERNEXEC
10337 + unsigned long cr0;
10341 * Force other mappings to Oops if they'll try to access this pte
10342 * without first remap it. Keeping stale mappings around is a bad idea
10343 * also, in case the page changes cacheability attributes or becomes
10344 * a protected page in a hypervisor.
10346 - if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
10347 + if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
10349 +#ifdef CONFIG_PAX_KERNEXEC
10350 + pax_open_kernel(cr0);
10353 kpte_clear_flush(kmap_pte-idx, vaddr);
10356 +#ifdef CONFIG_PAX_KERNEXEC
10357 + pax_close_kernel(cr0);
10361 #ifdef CONFIG_DEBUG_HIGHMEM
10362 BUG_ON(vaddr < PAGE_OFFSET);
10363 BUG_ON(vaddr >= (unsigned long)high_memory);
10364 @@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
10365 enum fixed_addresses idx;
10366 unsigned long vaddr;
10368 +#ifdef CONFIG_PAX_KERNEXEC
10369 + unsigned long cr0;
10372 pagefault_disable();
10374 idx = type + KM_TYPE_NR*smp_processor_id();
10375 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10377 +#ifdef CONFIG_PAX_KERNEXEC
10378 + pax_open_kernel(cr0);
10381 set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
10383 +#ifdef CONFIG_PAX_KERNEXEC
10384 + pax_close_kernel(cr0);
10387 arch_flush_lazy_mmu_mode();
10389 return (void*) vaddr;
10390 diff -urNp linux-2.6.27.10/arch/x86/mm/hugetlbpage.c linux-2.6.27.10/arch/x86/mm/hugetlbpage.c
10391 --- linux-2.6.27.10/arch/x86/mm/hugetlbpage.c 2008-11-07 12:55:34.000000000 -0500
10392 +++ linux-2.6.27.10/arch/x86/mm/hugetlbpage.c 2008-11-18 03:38:44.000000000 -0500
10393 @@ -263,13 +263,18 @@ static unsigned long hugetlb_get_unmappe
10394 struct hstate *h = hstate_file(file);
10395 struct mm_struct *mm = current->mm;
10396 struct vm_area_struct *vma;
10397 - unsigned long start_addr;
10398 + unsigned long start_addr, pax_task_size = TASK_SIZE;
10400 +#ifdef CONFIG_PAX_SEGMEXEC
10401 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10402 + pax_task_size = SEGMEXEC_TASK_SIZE;
10405 if (len > mm->cached_hole_size) {
10406 - start_addr = mm->free_area_cache;
10407 + start_addr = mm->free_area_cache;
10409 - start_addr = TASK_UNMAPPED_BASE;
10410 - mm->cached_hole_size = 0;
10411 + start_addr = mm->mmap_base;
10412 + mm->cached_hole_size = 0;
10416 @@ -277,13 +282,13 @@ full_search:
10418 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
10419 /* At this point: (!vma || addr < vma->vm_end). */
10420 - if (TASK_SIZE - len < addr) {
10421 + if (pax_task_size - len < addr) {
10423 * Start a new search - just in case we missed
10426 - if (start_addr != TASK_UNMAPPED_BASE) {
10427 - start_addr = TASK_UNMAPPED_BASE;
10428 + if (start_addr != mm->mmap_base) {
10429 + start_addr = mm->mmap_base;
10430 mm->cached_hole_size = 0;
10433 @@ -306,9 +311,8 @@ static unsigned long hugetlb_get_unmappe
10434 struct hstate *h = hstate_file(file);
10435 struct mm_struct *mm = current->mm;
10436 struct vm_area_struct *vma, *prev_vma;
10437 - unsigned long base = mm->mmap_base, addr = addr0;
10438 + unsigned long base = mm->mmap_base, addr;
10439 unsigned long largest_hole = mm->cached_hole_size;
10440 - int first_time = 1;
10442 /* don't allow allocations above current base */
10443 if (mm->free_area_cache > base)
10444 @@ -318,7 +322,7 @@ static unsigned long hugetlb_get_unmappe
10446 mm->free_area_cache = base;
10450 /* make sure it can fit in the remaining address space */
10451 if (mm->free_area_cache < len)
10453 @@ -360,22 +364,26 @@ try_again:
10457 - * if hint left us with no space for the requested
10458 - * mapping then try again:
10460 - if (first_time) {
10461 - mm->free_area_cache = base;
10462 - largest_hole = 0;
10467 * A failed mmap() very likely causes application failure,
10468 * so fall back to the bottom-up function here. This scenario
10469 * can happen with large stack limits and large mmap()
10472 - mm->free_area_cache = TASK_UNMAPPED_BASE;
10474 +#ifdef CONFIG_PAX_SEGMEXEC
10475 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10476 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
10480 + mm->mmap_base = TASK_UNMAPPED_BASE;
10482 +#ifdef CONFIG_PAX_RANDMMAP
10483 + if (mm->pax_flags & MF_PAX_RANDMMAP)
10484 + mm->mmap_base += mm->delta_mmap;
10487 + mm->free_area_cache = mm->mmap_base;
10488 mm->cached_hole_size = ~0UL;
10489 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
10490 len, pgoff, flags);
10491 @@ -383,6 +391,7 @@ fail:
10493 * Restore the topdown base:
10495 + mm->mmap_base = base;
10496 mm->free_area_cache = base;
10497 mm->cached_hole_size = ~0UL;
10499 @@ -396,10 +405,17 @@ hugetlb_get_unmapped_area(struct file *f
10500 struct hstate *h = hstate_file(file);
10501 struct mm_struct *mm = current->mm;
10502 struct vm_area_struct *vma;
10503 + unsigned long pax_task_size = TASK_SIZE;
10505 if (len & ~huge_page_mask(h))
10507 - if (len > TASK_SIZE)
10509 +#ifdef CONFIG_PAX_SEGMEXEC
10510 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10511 + pax_task_size = SEGMEXEC_TASK_SIZE;
10514 + if (len > pax_task_size)
10517 if (flags & MAP_FIXED) {
10518 @@ -411,7 +427,7 @@ hugetlb_get_unmapped_area(struct file *f
10520 addr = ALIGN(addr, huge_page_size(h));
10521 vma = find_vma(mm, addr);
10522 - if (TASK_SIZE - len >= addr &&
10523 + if (pax_task_size - len >= addr &&
10524 (!vma || addr + len <= vma->vm_start))
10527 diff -urNp linux-2.6.27.10/arch/x86/mm/init_32.c linux-2.6.27.10/arch/x86/mm/init_32.c
10528 --- linux-2.6.27.10/arch/x86/mm/init_32.c 2008-11-07 12:55:34.000000000 -0500
10529 +++ linux-2.6.27.10/arch/x86/mm/init_32.c 2008-11-18 03:38:44.000000000 -0500
10531 #include <asm/paravirt.h>
10532 #include <asm/setup.h>
10533 #include <asm/cacheflush.h>
10534 +#include <asm/desc.h>
10536 unsigned int __VMALLOC_RESERVE = 128 << 20;
10538 @@ -80,35 +81,6 @@ static __init void *alloc_low_page(unsig
10542 - * Creates a middle page table and puts a pointer to it in the
10543 - * given global directory entry. This only returns the gd entry
10544 - * in non-PAE compilation mode, since the middle layer is folded.
10546 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
10549 - pmd_t *pmd_table;
10551 -#ifdef CONFIG_X86_PAE
10552 - unsigned long phys;
10553 - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
10554 - if (after_init_bootmem)
10555 - pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
10557 - pmd_table = (pmd_t *)alloc_low_page(&phys);
10558 - paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
10559 - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
10560 - pud = pud_offset(pgd, 0);
10561 - BUG_ON(pmd_table != pmd_offset(pud, 0));
10564 - pud = pud_offset(pgd, 0);
10565 - pmd_table = pmd_offset(pud, 0);
10567 - return pmd_table;
10571 * Create a page table and place a pointer to it in a middle page
10574 @@ -130,7 +102,11 @@ static pte_t * __init one_page_table_ini
10577 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
10578 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10579 + set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
10581 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
10583 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
10586 @@ -152,6 +128,7 @@ page_table_range_init(unsigned long star
10587 int pgd_idx, pmd_idx;
10588 unsigned long vaddr;
10594 @@ -160,8 +137,13 @@ page_table_range_init(unsigned long star
10595 pgd = pgd_base + pgd_idx;
10597 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
10598 - pmd = one_md_table_init(pgd);
10599 - pmd = pmd + pmd_index(vaddr);
10600 + pud = pud_offset(pgd, vaddr);
10601 + pmd = pmd_offset(pud, vaddr);
10603 +#ifdef CONFIG_X86_PAE
10604 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10607 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
10608 pmd++, pmd_idx++) {
10609 one_page_table_init(pmd);
10610 @@ -172,11 +154,23 @@ page_table_range_init(unsigned long star
10614 -static inline int is_kernel_text(unsigned long addr)
10615 +static inline int is_kernel_text(unsigned long start, unsigned long end)
10617 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
10620 + unsigned long etext;
10622 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
10623 + etext = ktva_ktla((unsigned long)&MODULES_END);
10625 + etext = (unsigned long)&_etext;
10628 + if ((start > ktla_ktva(etext) ||
10629 + end <= ktla_ktva((unsigned long)_stext)) &&
10630 + (start > ktla_ktva((unsigned long)_einittext) ||
10631 + end <= ktla_ktva((unsigned long)_sinittext)) &&
10632 + (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
10638 @@ -189,9 +183,10 @@ static void __init kernel_physical_mappi
10639 unsigned long end_pfn,
10642 - int pgd_idx, pmd_idx, pte_ofs;
10643 + unsigned int pgd_idx, pmd_idx, pte_ofs;
10649 unsigned pages_2m = 0, pages_4k = 0;
10650 @@ -202,8 +197,13 @@ static void __init kernel_physical_mappi
10652 pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
10653 pgd = pgd_base + pgd_idx;
10654 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
10655 - pmd = one_md_table_init(pgd);
10656 + for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
10657 + pud = pud_offset(pgd, 0);
10658 + pmd = pmd_offset(pud, 0);
10660 +#ifdef CONFIG_X86_PAE
10661 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10664 if (pfn >= end_pfn)
10666 @@ -215,21 +215,16 @@ static void __init kernel_physical_mappi
10668 for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
10669 pmd++, pmd_idx++) {
10670 - unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
10671 + unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
10674 * Map with big pages if possible, otherwise
10675 * create normal page tables:
10678 - unsigned int addr2;
10679 pgprot_t prot = PAGE_KERNEL_LARGE;
10681 - addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
10682 - PAGE_OFFSET + PAGE_SIZE-1;
10684 - if (is_kernel_text(addr) ||
10685 - is_kernel_text(addr2))
10686 + if (is_kernel_text(address, address + PMD_SIZE))
10687 prot = PAGE_KERNEL_LARGE_EXEC;
10690 @@ -243,10 +238,10 @@ static void __init kernel_physical_mappi
10691 pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
10693 for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
10694 - pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
10695 + pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
10696 pgprot_t prot = PAGE_KERNEL;
10698 - if (is_kernel_text(addr))
10699 + if (is_kernel_text(address, address + PAGE_SIZE))
10700 prot = PAGE_KERNEL_EXEC;
10703 @@ -270,7 +265,9 @@ static void __init kernel_physical_mappi
10705 int devmem_is_allowed(unsigned long pagenr)
10707 - if (pagenr <= 256)
10710 + if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10712 if (!page_is_ram(pagenr))
10714 @@ -404,7 +401,7 @@ void __init native_pagetable_setup_start
10716 pud = pud_offset(pgd, va);
10717 pmd = pmd_offset(pud, va);
10718 - if (!pmd_present(*pmd))
10719 + if (!pmd_present(*pmd) || pmd_huge(*pmd))
10722 pte = pte_offset_kernel(pmd, va);
10723 @@ -456,9 +453,7 @@ static void __init early_ioremap_page_ta
10725 static void __init pagetable_init(void)
10727 - pgd_t *pgd_base = swapper_pg_dir;
10729 - permanent_kmaps_init(pgd_base);
10730 + permanent_kmaps_init(swapper_pg_dir);
10733 #ifdef CONFIG_ACPI_SLEEP
10734 @@ -466,12 +461,12 @@ static void __init pagetable_init(void)
10735 * ACPI suspend needs this for resume, because things like the intel-agp
10736 * driver might have split up a kernel 4MB mapping.
10738 -char swsusp_pg_dir[PAGE_SIZE]
10739 +pgd_t swsusp_pg_dir[PTRS_PER_PGD]
10740 __attribute__ ((aligned(PAGE_SIZE)));
10742 static inline void save_pg_dir(void)
10744 - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
10745 + clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
10747 #else /* !CONFIG_ACPI_SLEEP */
10748 static inline void save_pg_dir(void)
10749 @@ -501,13 +496,11 @@ void zap_low_mappings(void)
10753 -pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL);
10754 +pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL);
10755 EXPORT_SYMBOL_GPL(__supported_pte_mask);
10757 #ifdef CONFIG_X86_PAE
10759 -static int disable_nx __initdata;
10764 @@ -516,40 +509,33 @@ static int disable_nx __initdata;
10768 +#if !defined(CONFIG_PAX_PAGEEXEC)
10769 static int __init noexec_setup(char *str)
10771 if (!str || !strcmp(str, "on")) {
10772 - if (cpu_has_nx) {
10773 - __supported_pte_mask |= _PAGE_NX;
10779 - if (!strcmp(str, "off")) {
10781 - __supported_pte_mask &= ~_PAGE_NX;
10783 + if (!strcmp(str, "off"))
10792 early_param("noexec", noexec_setup);
10795 static void __init set_nx(void)
10797 - unsigned int v[4], l, h;
10799 - if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
10800 - cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
10801 + if (!nx_enabled && cpu_has_nx) {
10804 - if ((v[3] & (1 << 20)) && !disable_nx) {
10805 - rdmsr(MSR_EFER, l, h);
10807 - wrmsr(MSR_EFER, l, h);
10809 - __supported_pte_mask |= _PAGE_NX;
10811 + __supported_pte_mask &= ~_PAGE_NX;
10812 + rdmsr(MSR_EFER, l, h);
10814 + wrmsr(MSR_EFER, l, h);
10818 @@ -920,7 +906,7 @@ void __init mem_init(void)
10819 set_highmem_pages_init();
10821 codesize = (unsigned long) &_etext - (unsigned long) &_text;
10822 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
10823 + datasize = (unsigned long) &_edata - (unsigned long) &_data;
10824 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
10826 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
10827 @@ -966,10 +952,10 @@ void __init mem_init(void)
10828 ((unsigned long)&__init_end -
10829 (unsigned long)&__init_begin) >> 10,
10831 - (unsigned long)&_etext, (unsigned long)&_edata,
10832 - ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
10833 + (unsigned long)&_data, (unsigned long)&_edata,
10834 + ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
10836 - (unsigned long)&_text, (unsigned long)&_etext,
10837 + ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
10838 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
10840 #ifdef CONFIG_HIGHMEM
10841 @@ -1099,6 +1085,46 @@ void free_init_pages(char *what, unsigne
10843 void free_initmem(void)
10846 +#ifdef CONFIG_PAX_KERNEXEC
10847 + /* PaX: limit KERNEL_CS to actual size */
10848 + unsigned long addr, limit;
10849 + struct desc_struct d;
10855 +#ifdef CONFIG_MODULES
10856 + limit = ktva_ktla((unsigned long)&MODULES_END);
10858 + limit = (unsigned long)&_etext;
10860 + limit = (limit - 1UL) >> PAGE_SHIFT;
10862 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
10863 + pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
10864 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
10867 + /* PaX: make KERNEL_CS read-only */
10868 + for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
10869 + pgd = pgd_offset_k(addr);
10870 + pud = pud_offset(pgd, addr);
10871 + pmd = pmd_offset(pud, addr);
10872 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10874 +#ifdef CONFIG_X86_PAE
10875 + for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
10876 + pgd = pgd_offset_k(addr);
10877 + pud = pud_offset(pgd, addr);
10878 + pmd = pmd_offset(pud, addr);
10879 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10885 free_init_pages("unused kernel memory",
10886 (unsigned long)(&__init_begin),
10887 (unsigned long)(&__init_end));
10888 diff -urNp linux-2.6.27.10/arch/x86/mm/init_64.c linux-2.6.27.10/arch/x86/mm/init_64.c
10889 --- linux-2.6.27.10/arch/x86/mm/init_64.c 2008-12-21 01:16:51.000000000 -0500
10890 +++ linux-2.6.27.10/arch/x86/mm/init_64.c 2008-12-21 01:13:45.000000000 -0500
10891 @@ -118,6 +118,10 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
10895 +#ifdef CONFIG_PAX_KERNEXEC
10896 + unsigned long cr0;
10899 pud = pud_page + pud_index(vaddr);
10900 if (pud_none(*pud)) {
10901 pmd = (pmd_t *) spp_getpage();
10902 @@ -142,8 +146,17 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
10903 if (!pte_none(*pte) && pte_val(new_pte) &&
10904 pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
10907 +#ifdef CONFIG_PAX_KERNEXEC
10908 + pax_open_kernel(cr0);
10911 set_pte(pte, new_pte);
10913 +#ifdef CONFIG_PAX_KERNEXEC
10914 + pax_close_kernel(cr0);
10918 * It's enough to flush this one mapping.
10919 * (PGE mappings get flushed as well)
10920 @@ -184,14 +197,12 @@ static void __init __init_extra_mapping(
10921 pgd = pgd_offset_k((unsigned long)__va(phys));
10922 if (pgd_none(*pgd)) {
10923 pud = (pud_t *) spp_getpage();
10924 - set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
10926 + set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
10928 pud = pud_offset(pgd, (unsigned long)__va(phys));
10929 if (pud_none(*pud)) {
10930 pmd = (pmd_t *) spp_getpage();
10931 - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
10933 + set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
10935 pmd = pmd_offset(pud, phys);
10936 BUG_ON(!pmd_none(*pmd));
10937 @@ -754,7 +765,9 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
10939 int devmem_is_allowed(unsigned long pagenr)
10941 - if (pagenr <= 256)
10944 + if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10946 if (!page_is_ram(pagenr))
10948 @@ -842,6 +855,39 @@ void free_init_pages(char *what, unsigne
10950 void free_initmem(void)
10953 +#ifdef CONFIG_PAX_KERNEXEC
10954 + unsigned long addr, end;
10959 + /* PaX: make kernel code/rodata read-only, rest non-executable */
10960 + for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
10961 + pgd = pgd_offset_k(addr);
10962 + pud = pud_offset(pgd, addr);
10963 + pmd = pmd_offset(pud, addr);
10964 + if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
10965 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10967 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10970 + addr = (unsigned long)__va(__pa(__START_KERNEL_map));
10971 + end = addr + KERNEL_IMAGE_SIZE;
10972 + for (; addr < end; addr += PMD_SIZE) {
10973 + pgd = pgd_offset_k(addr);
10974 + pud = pud_offset(pgd, addr);
10975 + pmd = pmd_offset(pud, addr);
10976 + if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
10977 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10979 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10985 free_init_pages("unused kernel memory",
10986 (unsigned long)(&__init_begin),
10987 (unsigned long)(&__init_end));
10988 @@ -1014,7 +1060,7 @@ int in_gate_area_no_task(unsigned long a
10990 const char *arch_vma_name(struct vm_area_struct *vma)
10992 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
10993 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
10995 if (vma == &gate_vma)
10996 return "[vsyscall]";
10997 diff -urNp linux-2.6.27.10/arch/x86/mm/ioremap.c linux-2.6.27.10/arch/x86/mm/ioremap.c
10998 --- linux-2.6.27.10/arch/x86/mm/ioremap.c 2008-11-07 12:55:34.000000000 -0500
10999 +++ linux-2.6.27.10/arch/x86/mm/ioremap.c 2008-11-18 03:38:44.000000000 -0500
11000 @@ -63,8 +63,8 @@ int page_is_ram(unsigned long pagenr)
11001 * Second special case: Some BIOSen report the PC BIOS
11002 * area (640->1Mb) as ram even though it is not.
11004 - if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
11005 - pagenr < (BIOS_END >> PAGE_SHIFT))
11006 + if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
11007 + pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
11010 for (i = 0; i < e820.nr_map; i++) {
11011 @@ -217,6 +217,8 @@ static void __iomem *__ioremap_caller(re
11015 + prot = canon_pgprot(prot);
11020 diff -urNp linux-2.6.27.10/arch/x86/mm/mmap.c linux-2.6.27.10/arch/x86/mm/mmap.c
11021 --- linux-2.6.27.10/arch/x86/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
11022 +++ linux-2.6.27.10/arch/x86/mm/mmap.c 2008-11-18 03:38:44.000000000 -0500
11024 * Leave an at least ~128 MB hole.
11026 #define MIN_GAP (128*1024*1024)
11027 -#define MAX_GAP (TASK_SIZE/6*5)
11028 +#define MAX_GAP (pax_task_size/6*5)
11031 * True on X86_32 or when emulating IA32 on X86_64
11032 @@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
11033 return rnd << PAGE_SHIFT;
11036 -static unsigned long mmap_base(void)
11037 +static unsigned long mmap_base(struct mm_struct *mm)
11039 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
11040 + unsigned long pax_task_size = TASK_SIZE;
11042 +#ifdef CONFIG_PAX_SEGMEXEC
11043 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11044 + pax_task_size = SEGMEXEC_TASK_SIZE;
11049 else if (gap > MAX_GAP)
11052 - return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
11053 + return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
11057 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
11058 * does, but not when emulating X86_32
11060 -static unsigned long mmap_legacy_base(void)
11061 +static unsigned long mmap_legacy_base(struct mm_struct *mm)
11063 - if (mmap_is_ia32())
11064 + if (mmap_is_ia32()) {
11066 +#ifdef CONFIG_PAX_SEGMEXEC
11067 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11068 + return SEGMEXEC_TASK_UNMAPPED_BASE;
11072 return TASK_UNMAPPED_BASE;
11075 return TASK_UNMAPPED_BASE + mmap_rnd();
11078 @@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
11079 void arch_pick_mmap_layout(struct mm_struct *mm)
11081 if (mmap_is_legacy()) {
11082 - mm->mmap_base = mmap_legacy_base();
11083 + mm->mmap_base = mmap_legacy_base(mm);
11085 +#ifdef CONFIG_PAX_RANDMMAP
11086 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11087 + mm->mmap_base += mm->delta_mmap;
11090 mm->get_unmapped_area = arch_get_unmapped_area;
11091 mm->unmap_area = arch_unmap_area;
11093 - mm->mmap_base = mmap_base();
11094 + mm->mmap_base = mmap_base(mm);
11096 +#ifdef CONFIG_PAX_RANDMMAP
11097 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11098 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
11101 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
11102 mm->unmap_area = arch_unmap_area_topdown;
11104 diff -urNp linux-2.6.27.10/arch/x86/mm/pageattr.c linux-2.6.27.10/arch/x86/mm/pageattr.c
11105 --- linux-2.6.27.10/arch/x86/mm/pageattr.c 2008-11-07 12:55:34.000000000 -0500
11106 +++ linux-2.6.27.10/arch/x86/mm/pageattr.c 2008-11-18 03:38:44.000000000 -0500
11108 #include <asm/pgalloc.h>
11109 #include <asm/proto.h>
11110 #include <asm/pat.h>
11111 +#include <asm/desc.h>
11114 * The current flushing context - we pass it instead of 5 arguments:
11115 @@ -213,7 +214,7 @@ static inline pgprot_t static_protection
11116 * Does not cover __inittext since that is gone later on. On
11117 * 64bit we do not enforce !NX on the low mapping
11119 - if (within(address, (unsigned long)_text, (unsigned long)_etext))
11120 + if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
11121 pgprot_val(forbidden) |= _PAGE_NX;
11124 @@ -275,8 +276,20 @@ EXPORT_SYMBOL_GPL(lookup_address);
11126 static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
11129 +#ifdef CONFIG_PAX_KERNEXEC
11130 + unsigned long cr0;
11132 + pax_open_kernel(cr0);
11135 /* change init_mm */
11136 set_pte_atomic(kpte, pte);
11138 +#ifdef CONFIG_PAX_KERNEXEC
11139 + pax_close_kernel(cr0);
11142 #ifdef CONFIG_X86_32
11143 if (!SHARED_KERNEL_PMD) {
11145 diff -urNp linux-2.6.27.10/arch/x86/mm/pat.c linux-2.6.27.10/arch/x86/mm/pat.c
11146 --- linux-2.6.27.10/arch/x86/mm/pat.c 2008-11-07 12:55:34.000000000 -0500
11147 +++ linux-2.6.27.10/arch/x86/mm/pat.c 2008-11-18 03:38:44.000000000 -0500
11148 @@ -396,7 +396,7 @@ pgprot_t phys_mem_access_prot(struct fil
11152 -#ifdef CONFIG_STRICT_DEVMEM
11153 +#ifndef CONFIG_STRICT_DEVMEM
11154 /* This check is done in drivers/char/mem.c in case of STRICT_DEVMEM*/
11155 static inline int range_is_allowed(unsigned long pfn, unsigned long size)
11157 diff -urNp linux-2.6.27.10/arch/x86/mm/pgtable_32.c linux-2.6.27.10/arch/x86/mm/pgtable_32.c
11158 --- linux-2.6.27.10/arch/x86/mm/pgtable_32.c 2008-11-07 12:55:34.000000000 -0500
11159 +++ linux-2.6.27.10/arch/x86/mm/pgtable_32.c 2008-11-18 03:38:44.000000000 -0500
11160 @@ -31,6 +31,10 @@ void set_pte_vaddr(unsigned long vaddr,
11164 +#ifdef CONFIG_PAX_KERNEXEC
11165 + unsigned long cr0;
11168 pgd = swapper_pg_dir + pgd_index(vaddr);
11169 if (pgd_none(*pgd)) {
11171 @@ -47,11 +51,20 @@ void set_pte_vaddr(unsigned long vaddr,
11174 pte = pte_offset_kernel(pmd, vaddr);
11176 +#ifdef CONFIG_PAX_KERNEXEC
11177 + pax_open_kernel(cr0);
11180 if (pte_val(pteval))
11181 set_pte_present(&init_mm, vaddr, pte, pteval);
11183 pte_clear(&init_mm, vaddr, pte);
11185 +#ifdef CONFIG_PAX_KERNEXEC
11186 + pax_close_kernel(cr0);
11190 * It's enough to flush this one mapping.
11191 * (PGE mappings get flushed as well)
11192 diff -urNp linux-2.6.27.10/arch/x86/oprofile/backtrace.c linux-2.6.27.10/arch/x86/oprofile/backtrace.c
11193 --- linux-2.6.27.10/arch/x86/oprofile/backtrace.c 2008-11-07 12:55:34.000000000 -0500
11194 +++ linux-2.6.27.10/arch/x86/oprofile/backtrace.c 2008-11-18 03:38:44.000000000 -0500
11195 @@ -37,7 +37,7 @@ static void backtrace_address(void *data
11196 unsigned int *depth = data;
11199 - oprofile_add_trace(addr);
11200 + oprofile_add_trace(ktla_ktva(addr));
11203 static struct stacktrace_ops backtrace_ops = {
11204 @@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
11205 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
11206 unsigned long stack = kernel_trap_sp(regs);
11208 - if (!user_mode_vm(regs)) {
11209 + if (!user_mode(regs)) {
11211 dump_trace(NULL, regs, (unsigned long *)stack, 0,
11212 &backtrace_ops, &depth);
11213 diff -urNp linux-2.6.27.10/arch/x86/oprofile/op_model_p4.c linux-2.6.27.10/arch/x86/oprofile/op_model_p4.c
11214 --- linux-2.6.27.10/arch/x86/oprofile/op_model_p4.c 2008-11-07 12:55:34.000000000 -0500
11215 +++ linux-2.6.27.10/arch/x86/oprofile/op_model_p4.c 2008-11-18 03:38:44.000000000 -0500
11216 @@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
11220 -static int inline addr_increment(void)
11221 +static inline int addr_increment(void)
11224 return smp_num_siblings == 2 ? 2 : 1;
11225 diff -urNp linux-2.6.27.10/arch/x86/pci/common.c linux-2.6.27.10/arch/x86/pci/common.c
11226 --- linux-2.6.27.10/arch/x86/pci/common.c 2008-11-07 12:55:34.000000000 -0500
11227 +++ linux-2.6.27.10/arch/x86/pci/common.c 2008-11-18 03:38:44.000000000 -0500
11228 @@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat
11229 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
11233 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
11236 void __init dmi_check_pciprobe(void)
11237 diff -urNp linux-2.6.27.10/arch/x86/pci/fixup.c linux-2.6.27.10/arch/x86/pci/fixup.c
11238 --- linux-2.6.27.10/arch/x86/pci/fixup.c 2008-11-07 12:55:34.000000000 -0500
11239 +++ linux-2.6.27.10/arch/x86/pci/fixup.c 2008-11-18 03:38:44.000000000 -0500
11240 @@ -365,7 +365,7 @@ static struct dmi_system_id __devinitdat
11241 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
11245 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11249 @@ -436,7 +436,7 @@ static struct dmi_system_id __devinitdat
11250 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
11254 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11257 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
11258 diff -urNp linux-2.6.27.10/arch/x86/pci/irq.c linux-2.6.27.10/arch/x86/pci/irq.c
11259 --- linux-2.6.27.10/arch/x86/pci/irq.c 2008-11-07 12:55:34.000000000 -0500
11260 +++ linux-2.6.27.10/arch/x86/pci/irq.c 2008-11-18 03:38:44.000000000 -0500
11261 @@ -544,7 +544,7 @@ static __init int intel_router_probe(str
11262 static struct pci_device_id __initdata pirq_440gx[] = {
11263 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
11264 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
11266 + { PCI_DEVICE(0, 0) }
11269 /* 440GX has a proprietary PIRQ router -- don't use it */
11270 @@ -1131,7 +1131,7 @@ static struct dmi_system_id __initdata p
11271 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
11275 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11278 int __init pcibios_irq_init(void)
11279 diff -urNp linux-2.6.27.10/arch/x86/pci/pcbios.c linux-2.6.27.10/arch/x86/pci/pcbios.c
11280 --- linux-2.6.27.10/arch/x86/pci/pcbios.c 2008-11-07 12:55:34.000000000 -0500
11281 +++ linux-2.6.27.10/arch/x86/pci/pcbios.c 2008-11-18 03:38:44.000000000 -0500
11282 @@ -57,50 +57,120 @@ union bios32 {
11284 unsigned long address;
11285 unsigned short segment;
11286 -} bios32_indirect = { 0, __KERNEL_CS };
11287 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
11290 * Returns the entry point for the given service, NULL on error
11293 -static unsigned long bios32_service(unsigned long service)
11294 +static unsigned long __devinit bios32_service(unsigned long service)
11296 unsigned char return_code; /* %al */
11297 unsigned long address; /* %ebx */
11298 unsigned long length; /* %ecx */
11299 unsigned long entry; /* %edx */
11300 unsigned long flags;
11301 + struct desc_struct d, *gdt;
11303 +#ifdef CONFIG_PAX_KERNEXEC
11304 + unsigned long cr0;
11307 local_irq_save(flags);
11308 - __asm__("lcall *(%%edi); cld"
11310 + gdt = get_cpu_gdt_table(smp_processor_id());
11312 +#ifdef CONFIG_PAX_KERNEXEC
11313 + pax_open_kernel(cr0);
11316 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
11317 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
11318 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
11319 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
11321 +#ifdef CONFIG_PAX_KERNEXEC
11322 + pax_close_kernel(cr0);
11325 + __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
11326 : "=a" (return_code),
11332 - "D" (&bios32_indirect));
11333 + "D" (&bios32_indirect),
11334 + "r"(__PCIBIOS_DS)
11337 +#ifdef CONFIG_PAX_KERNEXEC
11338 + pax_open_kernel(cr0);
11341 + gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
11342 + gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
11343 + gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
11344 + gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
11346 +#ifdef CONFIG_PAX_KERNEXEC
11347 + pax_close_kernel(cr0);
11350 local_irq_restore(flags);
11352 switch (return_code) {
11354 - return address + entry;
11355 - case 0x80: /* Not present */
11356 - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
11358 - default: /* Shouldn't happen */
11359 - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
11360 - service, return_code);
11363 + unsigned char flags;
11365 + printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
11366 + if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
11367 + printk(KERN_WARNING "bios32_service: not valid\n");
11370 + address = address + PAGE_OFFSET;
11371 + length += 16UL; /* some BIOSs underreport this... */
11373 + if (length >= 64*1024*1024) {
11374 + length >>= PAGE_SHIFT;
11378 +#ifdef CONFIG_PAX_KERNEXEC
11379 + pax_open_kernel(cr0);
11382 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
11383 + gdt = get_cpu_gdt_table(cpu);
11384 + pack_descriptor(&d, address, length, 0x9b, flags);
11385 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
11386 + pack_descriptor(&d, address, length, 0x93, flags);
11387 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
11390 +#ifdef CONFIG_PAX_KERNEXEC
11391 + pax_close_kernel(cr0);
11396 + case 0x80: /* Not present */
11397 + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
11399 + default: /* Shouldn't happen */
11400 + printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
11401 + service, return_code);
11407 unsigned long address;
11408 unsigned short segment;
11409 -} pci_indirect = { 0, __KERNEL_CS };
11410 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
11412 -static int pci_bios_present;
11413 +static int pci_bios_present __read_only;
11415 static int __devinit check_pcibios(void)
11417 @@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
11418 unsigned long flags, pcibios_entry;
11420 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
11421 - pci_indirect.address = pcibios_entry + PAGE_OFFSET;
11422 + pci_indirect.address = pcibios_entry;
11424 local_irq_save(flags);
11426 - "lcall *(%%edi); cld\n\t"
11427 + __asm__("movw %w6, %%ds\n\t"
11428 + "lcall *%%ss:(%%edi); cld\n\t"
11434 @@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
11437 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
11438 - "D" (&pci_indirect)
11439 + "D" (&pci_indirect),
11440 + "r" (__PCIBIOS_DS)
11442 local_irq_restore(flags);
11444 @@ -166,7 +239,10 @@ static int pci_bios_read(unsigned int se
11448 - __asm__("lcall *(%%esi); cld\n\t"
11449 + __asm__("movw %w6, %%ds\n\t"
11450 + "lcall *%%ss:(%%esi); cld\n\t"
11456 @@ -175,7 +251,8 @@ static int pci_bios_read(unsigned int se
11457 : "1" (PCIBIOS_READ_CONFIG_BYTE),
11460 - "S" (&pci_indirect));
11461 + "S" (&pci_indirect),
11462 + "r" (__PCIBIOS_DS));
11464 * Zero-extend the result beyond 8 bits, do not trust the
11465 * BIOS having done it:
11466 @@ -183,7 +260,10 @@ static int pci_bios_read(unsigned int se
11470 - __asm__("lcall *(%%esi); cld\n\t"
11471 + __asm__("movw %w6, %%ds\n\t"
11472 + "lcall *%%ss:(%%esi); cld\n\t"
11478 @@ -192,7 +272,8 @@ static int pci_bios_read(unsigned int se
11479 : "1" (PCIBIOS_READ_CONFIG_WORD),
11482 - "S" (&pci_indirect));
11483 + "S" (&pci_indirect),
11484 + "r" (__PCIBIOS_DS));
11486 * Zero-extend the result beyond 16 bits, do not trust the
11487 * BIOS having done it:
11488 @@ -200,7 +281,10 @@ static int pci_bios_read(unsigned int se
11492 - __asm__("lcall *(%%esi); cld\n\t"
11493 + __asm__("movw %w6, %%ds\n\t"
11494 + "lcall *%%ss:(%%esi); cld\n\t"
11500 @@ -209,7 +293,8 @@ static int pci_bios_read(unsigned int se
11501 : "1" (PCIBIOS_READ_CONFIG_DWORD),
11504 - "S" (&pci_indirect));
11505 + "S" (&pci_indirect),
11506 + "r" (__PCIBIOS_DS));
11510 @@ -232,7 +317,10 @@ static int pci_bios_write(unsigned int s
11514 - __asm__("lcall *(%%esi); cld\n\t"
11515 + __asm__("movw %w6, %%ds\n\t"
11516 + "lcall *%%ss:(%%esi); cld\n\t"
11522 @@ -241,10 +329,14 @@ static int pci_bios_write(unsigned int s
11526 - "S" (&pci_indirect));
11527 + "S" (&pci_indirect),
11528 + "r" (__PCIBIOS_DS));
11531 - __asm__("lcall *(%%esi); cld\n\t"
11532 + __asm__("movw %w6, %%ds\n\t"
11533 + "lcall *%%ss:(%%esi); cld\n\t"
11539 @@ -253,10 +345,14 @@ static int pci_bios_write(unsigned int s
11543 - "S" (&pci_indirect));
11544 + "S" (&pci_indirect),
11545 + "r" (__PCIBIOS_DS));
11548 - __asm__("lcall *(%%esi); cld\n\t"
11549 + __asm__("movw %w6, %%ds\n\t"
11550 + "lcall *%%ss:(%%esi); cld\n\t"
11556 @@ -265,7 +361,8 @@ static int pci_bios_write(unsigned int s
11560 - "S" (&pci_indirect));
11561 + "S" (&pci_indirect),
11562 + "r" (__PCIBIOS_DS));
11566 @@ -369,10 +466,13 @@ struct irq_routing_table * pcibios_get_i
11568 DBG("PCI: Fetching IRQ routing table... ");
11569 __asm__("push %%es\n\t"
11570 + "movw %w8, %%ds\n\t"
11573 - "lcall *(%%esi); cld\n\t"
11574 + "lcall *%%ss:(%%esi); cld\n\t"
11581 @@ -383,7 +483,8 @@ struct irq_routing_table * pcibios_get_i
11584 "S" (&pci_indirect),
11587 + "r" (__PCIBIOS_DS)
11589 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
11591 @@ -407,7 +508,10 @@ int pcibios_set_irq_routing(struct pci_d
11595 - __asm__("lcall *(%%esi); cld\n\t"
11596 + __asm__("movw %w5, %%ds\n\t"
11597 + "lcall *%%ss:(%%esi); cld\n\t"
11603 @@ -415,7 +519,8 @@ int pcibios_set_irq_routing(struct pci_d
11604 : "0" (PCIBIOS_SET_PCI_HW_INT),
11605 "b" ((dev->bus->number << 8) | dev->devfn),
11606 "c" ((irq << 8) | (pin + 10)),
11607 - "S" (&pci_indirect));
11608 + "S" (&pci_indirect),
11609 + "r" (__PCIBIOS_DS));
11610 return !(ret & 0xff00);
11612 EXPORT_SYMBOL(pcibios_set_irq_routing);
11613 diff -urNp linux-2.6.27.10/arch/x86/power/cpu_32.c linux-2.6.27.10/arch/x86/power/cpu_32.c
11614 --- linux-2.6.27.10/arch/x86/power/cpu_32.c 2008-11-07 12:55:34.000000000 -0500
11615 +++ linux-2.6.27.10/arch/x86/power/cpu_32.c 2008-11-18 03:38:44.000000000 -0500
11616 @@ -66,7 +66,7 @@ static void do_fpu_end(void)
11617 static void fix_processor_context(void)
11619 int cpu = smp_processor_id();
11620 - struct tss_struct *t = &per_cpu(init_tss, cpu);
11621 + struct tss_struct *t = init_tss + cpu;
11623 set_tss_desc(cpu, t); /*
11624 * This just modifies memory; should not be
11625 diff -urNp linux-2.6.27.10/arch/x86/power/cpu_64.c linux-2.6.27.10/arch/x86/power/cpu_64.c
11626 --- linux-2.6.27.10/arch/x86/power/cpu_64.c 2008-11-07 12:55:34.000000000 -0500
11627 +++ linux-2.6.27.10/arch/x86/power/cpu_64.c 2008-11-18 03:38:44.000000000 -0500
11628 @@ -136,7 +136,11 @@ void restore_processor_state(void)
11629 static void fix_processor_context(void)
11631 int cpu = smp_processor_id();
11632 - struct tss_struct *t = &per_cpu(init_tss, cpu);
11633 + struct tss_struct *t = init_tss + cpu;
11635 +#ifdef CONFIG_PAX_KERNEXEC
11636 + unsigned long cr0;
11640 * This just modifies memory; should not be necessary. But... This
11641 @@ -145,8 +149,16 @@ static void fix_processor_context(void)
11643 set_tss_desc(cpu, t);
11645 +#ifdef CONFIG_PAX_KERNEXEC
11646 + pax_open_kernel(cr0);
11649 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
11651 +#ifdef CONFIG_PAX_KERNEXEC
11652 + pax_close_kernel(cr0);
11655 syscall_init(); /* This sets MSR_*STAR and related */
11656 load_TR_desc(); /* This does ltr */
11657 load_LDT(¤t->active_mm->context); /* This does lldt */
11658 diff -urNp linux-2.6.27.10/arch/x86/vdso/vdso32-setup.c linux-2.6.27.10/arch/x86/vdso/vdso32-setup.c
11659 --- linux-2.6.27.10/arch/x86/vdso/vdso32-setup.c 2008-11-07 12:55:34.000000000 -0500
11660 +++ linux-2.6.27.10/arch/x86/vdso/vdso32-setup.c 2008-11-18 03:38:44.000000000 -0500
11661 @@ -226,7 +226,7 @@ static inline void map_compat_vdso(int m
11662 void enable_sep_cpu(void)
11664 int cpu = get_cpu();
11665 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
11666 + struct tss_struct *tss = init_tss + cpu;
11668 if (!boot_cpu_has(X86_FEATURE_SEP)) {
11670 @@ -249,7 +249,7 @@ static int __init gate_vma_init(void)
11671 gate_vma.vm_start = FIXADDR_USER_START;
11672 gate_vma.vm_end = FIXADDR_USER_END;
11673 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
11674 - gate_vma.vm_page_prot = __P101;
11675 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
11677 * Make sure the vDSO gets into every core dump.
11678 * Dumping its contents makes post-mortem fully interpretable later
11679 @@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct l
11681 addr = VDSO_HIGH_BASE;
11683 - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
11684 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
11685 if (IS_ERR_VALUE(addr)) {
11688 @@ -358,7 +358,7 @@ int arch_setup_additional_pages(struct l
11692 - current->mm->context.vdso = (void *)addr;
11693 + current->mm->context.vdso = addr;
11694 current_thread_info()->sysenter_return =
11695 VDSO32_SYMBOL(addr, SYSENTER_RETURN);
11697 @@ -384,7 +384,7 @@ static ctl_table abi_table2[] = {
11699 .proc_handler = proc_dointvec
11702 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11705 static ctl_table abi_root_table2[] = {
11706 @@ -394,7 +394,7 @@ static ctl_table abi_root_table2[] = {
11708 .child = abi_table2
11711 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11714 static __init int ia32_binfmt_init(void)
11715 @@ -409,8 +409,14 @@ __initcall(ia32_binfmt_init);
11717 const char *arch_vma_name(struct vm_area_struct *vma)
11719 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
11720 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
11723 +#ifdef CONFIG_PAX_SEGMEXEC
11724 + if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
11731 @@ -419,7 +425,7 @@ struct vm_area_struct *get_gate_vma(stru
11732 struct mm_struct *mm = tsk->mm;
11734 /* Check to see if this task was created in compat vdso mode */
11735 - if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
11736 + if (mm && mm->context.vdso == VDSO_HIGH_BASE)
11740 diff -urNp linux-2.6.27.10/arch/x86/vdso/vma.c linux-2.6.27.10/arch/x86/vdso/vma.c
11741 --- linux-2.6.27.10/arch/x86/vdso/vma.c 2008-11-07 12:55:34.000000000 -0500
11742 +++ linux-2.6.27.10/arch/x86/vdso/vma.c 2008-11-18 03:38:44.000000000 -0500
11743 @@ -123,7 +123,7 @@ int arch_setup_additional_pages(struct l
11747 - current->mm->context.vdso = (void *)addr;
11748 + current->mm->context.vdso = addr;
11750 up_write(&mm->mmap_sem);
11752 diff -urNp linux-2.6.27.10/arch/x86/xen/enlighten.c linux-2.6.27.10/arch/x86/xen/enlighten.c
11753 --- linux-2.6.27.10/arch/x86/xen/enlighten.c 2008-12-10 22:35:37.000000000 -0500
11754 +++ linux-2.6.27.10/arch/x86/xen/enlighten.c 2008-12-10 22:35:46.000000000 -0500
11755 @@ -343,7 +343,7 @@ static void xen_set_ldt(const void *addr
11756 static void xen_load_gdt(const struct desc_ptr *dtr)
11758 unsigned long *frames;
11759 - unsigned long va = dtr->address;
11760 + unsigned long va = (unsigned long)dtr->address;
11761 unsigned int size = dtr->size + 1;
11762 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
11764 @@ -358,7 +358,7 @@ static void xen_load_gdt(const struct de
11765 mcs = xen_mc_entry(sizeof(*frames) * pages);
11768 - for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
11769 + for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
11770 frames[f] = virt_to_mfn(va);
11771 make_lowmem_page_readonly((void *)va);
11773 @@ -467,7 +467,7 @@ static void xen_write_idt_entry(gate_des
11777 - start = __get_cpu_var(idt_desc).address;
11778 + start = (unsigned long)__get_cpu_var(idt_desc).address;
11779 end = start + __get_cpu_var(idt_desc).size + 1;
11782 @@ -1574,6 +1574,8 @@ static __init pgd_t *xen_setup_kernel_pa
11783 convert_pfn_mfn(init_level4_pgt);
11784 convert_pfn_mfn(level3_ident_pgt);
11785 convert_pfn_mfn(level3_kernel_pgt);
11786 + convert_pfn_mfn(level3_vmalloc_pgt);
11787 + convert_pfn_mfn(level3_vmemmap_pgt);
11789 l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
11790 l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
11791 @@ -1592,9 +1594,12 @@ static __init pgd_t *xen_setup_kernel_pa
11792 set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
11793 set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
11794 set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
11795 + set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
11796 + set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
11797 set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
11798 set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
11799 set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
11800 + set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
11802 /* Pin down new L4 */
11803 pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
11804 diff -urNp linux-2.6.27.10/arch/x86/xen/smp.c linux-2.6.27.10/arch/x86/xen/smp.c
11805 --- linux-2.6.27.10/arch/x86/xen/smp.c 2008-11-07 12:55:34.000000000 -0500
11806 +++ linux-2.6.27.10/arch/x86/xen/smp.c 2008-11-18 03:38:44.000000000 -0500
11807 @@ -170,11 +170,6 @@ static void __init xen_smp_prepare_boot_
11809 BUG_ON(smp_processor_id() != 0);
11810 native_smp_prepare_boot_cpu();
11812 - /* We've switched to the "real" per-cpu gdt, so make sure the
11813 - old memory can be recycled */
11814 - make_lowmem_page_readwrite(&per_cpu_var(gdt_page));
11816 xen_setup_vcpu_info_placement();
11819 @@ -232,8 +227,8 @@ cpu_initialize_context(unsigned int cpu,
11820 gdt = get_cpu_gdt_table(cpu);
11822 ctxt->flags = VGCF_IN_KERNEL;
11823 - ctxt->user_regs.ds = __USER_DS;
11824 - ctxt->user_regs.es = __USER_DS;
11825 + ctxt->user_regs.ds = __KERNEL_DS;
11826 + ctxt->user_regs.es = __KERNEL_DS;
11827 ctxt->user_regs.ss = __KERNEL_DS;
11828 #ifdef CONFIG_X86_32
11829 ctxt->user_regs.fs = __KERNEL_PERCPU;
11830 diff -urNp linux-2.6.27.10/crypto/async_tx/async_tx.c linux-2.6.27.10/crypto/async_tx/async_tx.c
11831 --- linux-2.6.27.10/crypto/async_tx/async_tx.c 2008-11-07 12:55:34.000000000 -0500
11832 +++ linux-2.6.27.10/crypto/async_tx/async_tx.c 2008-11-18 03:38:44.000000000 -0500
11833 @@ -358,8 +358,8 @@ async_tx_init(void)
11835 printk(KERN_ERR "async_tx: initialization failure\n");
11837 - while (--cap >= 0)
11838 - free_percpu(channel_table[cap]);
11840 + free_percpu(channel_table[--cap]);
11844 diff -urNp linux-2.6.27.10/crypto/lrw.c linux-2.6.27.10/crypto/lrw.c
11845 --- linux-2.6.27.10/crypto/lrw.c 2008-11-07 12:55:34.000000000 -0500
11846 +++ linux-2.6.27.10/crypto/lrw.c 2008-11-18 03:38:44.000000000 -0500
11847 @@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
11848 struct priv *ctx = crypto_tfm_ctx(parent);
11849 struct crypto_cipher *child = ctx->child;
11851 - be128 tmp = { 0 };
11852 + be128 tmp = { 0, 0 };
11853 int bsize = crypto_cipher_blocksize(child);
11855 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
11856 diff -urNp linux-2.6.27.10/Documentation/dontdiff linux-2.6.27.10/Documentation/dontdiff
11857 --- linux-2.6.27.10/Documentation/dontdiff 2008-11-07 12:55:34.000000000 -0500
11858 +++ linux-2.6.27.10/Documentation/dontdiff 2008-11-18 03:39:50.000000000 -0500
11867 @@ -53,9 +54,14 @@ COPYING
11882 @@ -66,7 +72,6 @@ aic7*reg_print.c*
11890 @@ -74,6 +79,7 @@ bbootsect
11898 @@ -90,6 +96,7 @@ config_data.gz*
11900 consolemap_deftbl.c*
11906 @@ -138,6 +145,7 @@ miboot*
11914 @@ -179,16 +187,21 @@ times.h*
11939 diff -urNp linux-2.6.27.10/drivers/acpi/blacklist.c linux-2.6.27.10/drivers/acpi/blacklist.c
11940 --- linux-2.6.27.10/drivers/acpi/blacklist.c 2008-11-07 12:55:34.000000000 -0500
11941 +++ linux-2.6.27.10/drivers/acpi/blacklist.c 2008-11-18 03:38:44.000000000 -0500
11942 @@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
11943 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
11944 "Incorrect _ADR", 1},
11947 + {"", "", 0, 0, 0, all_versions, 0}
11950 #if CONFIG_ACPI_BLACKLIST_YEAR
11951 diff -urNp linux-2.6.27.10/drivers/acpi/osl.c linux-2.6.27.10/drivers/acpi/osl.c
11952 --- linux-2.6.27.10/drivers/acpi/osl.c 2008-12-21 01:16:51.000000000 -0500
11953 +++ linux-2.6.27.10/drivers/acpi/osl.c 2008-12-21 01:13:45.000000000 -0500
11954 @@ -494,6 +494,8 @@ acpi_os_read_memory(acpi_physical_addres
11955 void __iomem *virt_addr;
11957 virt_addr = ioremap(phys_addr, width);
11959 + return AE_NO_MEMORY;
11963 @@ -522,6 +524,8 @@ acpi_os_write_memory(acpi_physical_addre
11964 void __iomem *virt_addr;
11966 virt_addr = ioremap(phys_addr, width);
11968 + return AE_NO_MEMORY;
11972 diff -urNp linux-2.6.27.10/drivers/acpi/processor_core.c linux-2.6.27.10/drivers/acpi/processor_core.c
11973 --- linux-2.6.27.10/drivers/acpi/processor_core.c 2008-11-07 12:55:34.000000000 -0500
11974 +++ linux-2.6.27.10/drivers/acpi/processor_core.c 2008-11-18 03:38:44.000000000 -0500
11975 @@ -667,7 +667,7 @@ static int __cpuinit acpi_processor_star
11979 - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
11980 + BUG_ON(pr->id >= nr_cpu_ids);
11984 diff -urNp linux-2.6.27.10/drivers/acpi/processor_idle.c linux-2.6.27.10/drivers/acpi/processor_idle.c
11985 --- linux-2.6.27.10/drivers/acpi/processor_idle.c 2008-11-07 12:55:34.000000000 -0500
11986 +++ linux-2.6.27.10/drivers/acpi/processor_idle.c 2008-11-18 03:38:44.000000000 -0500
11987 @@ -182,7 +182,7 @@ static struct dmi_system_id __cpuinitdat
11988 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
11989 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
11992 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
11995 static inline u32 ticks_elapsed(u32 t1, u32 t2)
11996 diff -urNp linux-2.6.27.10/drivers/acpi/tables/tbfadt.c linux-2.6.27.10/drivers/acpi/tables/tbfadt.c
11997 --- linux-2.6.27.10/drivers/acpi/tables/tbfadt.c 2008-11-07 12:55:34.000000000 -0500
11998 +++ linux-2.6.27.10/drivers/acpi/tables/tbfadt.c 2008-11-18 03:38:44.000000000 -0500
12000 ACPI_MODULE_NAME("tbfadt")
12002 /* Local prototypes */
12003 -static void inline
12004 +static inline void
12005 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12006 u8 bit_width, u64 address);
12008 @@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
12010 ******************************************************************************/
12012 -static void inline
12013 +static inline void
12014 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12015 u8 bit_width, u64 address)
12017 diff -urNp linux-2.6.27.10/drivers/ata/ahci.c linux-2.6.27.10/drivers/ata/ahci.c
12018 --- linux-2.6.27.10/drivers/ata/ahci.c 2008-11-07 12:55:34.000000000 -0500
12019 +++ linux-2.6.27.10/drivers/ata/ahci.c 2008-11-18 03:38:44.000000000 -0500
12020 @@ -591,7 +591,7 @@ static const struct pci_device_id ahci_p
12021 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
12022 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
12024 - { } /* terminate list */
12025 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12029 diff -urNp linux-2.6.27.10/drivers/ata/ata_piix.c linux-2.6.27.10/drivers/ata/ata_piix.c
12030 --- linux-2.6.27.10/drivers/ata/ata_piix.c 2008-11-07 12:55:34.000000000 -0500
12031 +++ linux-2.6.27.10/drivers/ata/ata_piix.c 2008-11-18 03:38:44.000000000 -0500
12032 @@ -284,7 +284,7 @@ static const struct pci_device_id piix_p
12033 /* SATA Controller IDE (PCH) */
12034 { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
12036 - { } /* terminate list */
12037 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12040 static struct pci_driver piix_pci_driver = {
12041 @@ -587,7 +587,7 @@ static const struct ich_laptop ich_lapto
12042 { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
12043 { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
12050 @@ -1143,7 +1143,7 @@ static int piix_broken_suspend(void)
12054 - { } /* terminate list */
12055 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
12057 static const char *oemstrs[] = {
12059 diff -urNp linux-2.6.27.10/drivers/ata/libata-core.c linux-2.6.27.10/drivers/ata/libata-core.c
12060 --- linux-2.6.27.10/drivers/ata/libata-core.c 2008-12-21 01:18:11.000000000 -0500
12061 +++ linux-2.6.27.10/drivers/ata/libata-core.c 2008-12-21 01:18:21.000000000 -0500
12062 @@ -746,7 +746,7 @@ static const struct ata_xfer_ent {
12063 { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
12064 { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
12065 { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
12071 @@ -2917,7 +2917,7 @@ static const struct ata_timing ata_timin
12072 { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
12073 { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
12076 + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
12079 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
12080 @@ -4073,7 +4073,7 @@ static const struct ata_blacklist_entry
12081 { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
12085 + { NULL, NULL, 0 }
12088 static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
12089 diff -urNp linux-2.6.27.10/drivers/char/agp/frontend.c linux-2.6.27.10/drivers/char/agp/frontend.c
12090 --- linux-2.6.27.10/drivers/char/agp/frontend.c 2008-11-07 12:55:34.000000000 -0500
12091 +++ linux-2.6.27.10/drivers/char/agp/frontend.c 2008-11-18 03:38:44.000000000 -0500
12092 @@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag
12093 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
12096 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
12097 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
12100 client = agp_find_client_by_pid(reserve.pid);
12101 diff -urNp linux-2.6.27.10/drivers/char/agp/intel-agp.c linux-2.6.27.10/drivers/char/agp/intel-agp.c
12102 --- linux-2.6.27.10/drivers/char/agp/intel-agp.c 2008-11-07 12:55:34.000000000 -0500
12103 +++ linux-2.6.27.10/drivers/char/agp/intel-agp.c 2008-11-18 03:38:44.000000000 -0500
12104 @@ -2332,7 +2332,7 @@ static struct pci_device_id agp_intel_pc
12105 ID(PCI_DEVICE_ID_INTEL_Q45_HB),
12106 ID(PCI_DEVICE_ID_INTEL_G45_HB),
12107 ID(PCI_DEVICE_ID_INTEL_G41_HB),
12109 + { 0, 0, 0, 0, 0, 0, 0 }
12112 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
12113 diff -urNp linux-2.6.27.10/drivers/char/hpet.c linux-2.6.27.10/drivers/char/hpet.c
12114 --- linux-2.6.27.10/drivers/char/hpet.c 2008-11-07 12:55:34.000000000 -0500
12115 +++ linux-2.6.27.10/drivers/char/hpet.c 2008-11-18 03:38:44.000000000 -0500
12116 @@ -959,7 +959,7 @@ static struct acpi_driver hpet_acpi_driv
12120 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
12121 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
12123 static int __init hpet_init(void)
12125 diff -urNp linux-2.6.27.10/drivers/char/keyboard.c linux-2.6.27.10/drivers/char/keyboard.c
12126 --- linux-2.6.27.10/drivers/char/keyboard.c 2008-11-07 12:55:34.000000000 -0500
12127 +++ linux-2.6.27.10/drivers/char/keyboard.c 2008-11-18 03:38:44.000000000 -0500
12128 @@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u
12129 kbd->kbdmode == VC_MEDIUMRAW) &&
12130 value != KVAL(K_SAK))
12131 return; /* SAK is allowed even in raw mode */
12133 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
12135 + void *func = fn_handler[value];
12136 + if (func == fn_show_state || func == fn_show_ptregs ||
12137 + func == fn_show_mem)
12142 fn_handler[value](vc);
12145 @@ -1388,7 +1398,7 @@ static const struct input_device_id kbd_
12146 .evbit = { BIT_MASK(EV_SND) },
12149 - { }, /* Terminating entry */
12150 + { 0 }, /* Terminating entry */
12153 MODULE_DEVICE_TABLE(input, kbd_ids);
12154 diff -urNp linux-2.6.27.10/drivers/char/mem.c linux-2.6.27.10/drivers/char/mem.c
12155 --- linux-2.6.27.10/drivers/char/mem.c 2008-11-07 12:55:34.000000000 -0500
12156 +++ linux-2.6.27.10/drivers/char/mem.c 2008-11-18 03:38:44.000000000 -0500
12158 #include <linux/splice.h>
12159 #include <linux/pfn.h>
12160 #include <linux/smp_lock.h>
12161 +#include <linux/grsecurity.h>
12163 #include <asm/uaccess.h>
12164 #include <asm/io.h>
12166 # include <linux/efi.h>
12169 +#ifdef CONFIG_GRKERNSEC
12170 +extern struct file_operations grsec_fops;
12174 * Architectures vary in how they handle caching for addresses
12175 * outside of main memory.
12176 @@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f
12177 if (!valid_phys_addr_range(p, count))
12180 +#ifdef CONFIG_GRKERNSEC_KMEM
12181 + gr_handle_mem_write();
12187 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
12188 @@ -350,6 +360,11 @@ static int mmap_mem(struct file * file,
12189 &vma->vm_page_prot))
12192 +#ifdef CONFIG_GRKERNSEC_KMEM
12193 + if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
12197 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
12199 vma->vm_page_prot);
12200 @@ -588,6 +603,11 @@ static ssize_t write_kmem(struct file *
12202 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
12204 +#ifdef CONFIG_GRKERNSEC_KMEM
12205 + gr_handle_kmem_write();
12209 if (p < (unsigned long) high_memory) {
12212 @@ -791,6 +811,16 @@ static loff_t memory_lseek(struct file *
12214 static int open_port(struct inode * inode, struct file * filp)
12216 +#ifdef CONFIG_GRKERNSEC_KMEM
12217 + gr_handle_open_port();
12221 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12224 +static int open_mem(struct inode * inode, struct file * filp)
12226 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12229 @@ -798,7 +828,6 @@ static int open_port(struct inode * inod
12230 #define full_lseek null_lseek
12231 #define write_zero write_null
12232 #define read_full read_zero
12233 -#define open_mem open_port
12234 #define open_kmem open_mem
12235 #define open_oldmem open_mem
12237 @@ -938,6 +967,11 @@ static int memory_open(struct inode * in
12238 filp->f_op = &oldmem_fops;
12241 +#ifdef CONFIG_GRKERNSEC
12243 + filp->f_op = &grsec_fops;
12249 @@ -974,6 +1008,9 @@ static const struct {
12250 #ifdef CONFIG_CRASH_DUMP
12251 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
12253 +#ifdef CONFIG_GRKERNSEC
12254 + {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
12258 static struct class *mem_class;
12259 diff -urNp linux-2.6.27.10/drivers/char/nvram.c linux-2.6.27.10/drivers/char/nvram.c
12260 --- linux-2.6.27.10/drivers/char/nvram.c 2008-11-07 12:55:34.000000000 -0500
12261 +++ linux-2.6.27.10/drivers/char/nvram.c 2008-11-18 03:38:44.000000000 -0500
12262 @@ -433,7 +433,10 @@ static const struct file_operations nvra
12263 static struct miscdevice nvram_dev = {
12274 diff -urNp linux-2.6.27.10/drivers/char/random.c linux-2.6.27.10/drivers/char/random.c
12275 --- linux-2.6.27.10/drivers/char/random.c 2008-11-07 12:55:34.000000000 -0500
12276 +++ linux-2.6.27.10/drivers/char/random.c 2008-11-18 03:38:44.000000000 -0500
12277 @@ -249,8 +249,13 @@
12279 * Configuration information
12281 +#ifdef CONFIG_GRKERNSEC_RANDNET
12282 +#define INPUT_POOL_WORDS 512
12283 +#define OUTPUT_POOL_WORDS 128
12285 #define INPUT_POOL_WORDS 128
12286 #define OUTPUT_POOL_WORDS 32
12288 #define SEC_XFER_SIZE 512
12291 @@ -287,10 +292,17 @@ static struct poolinfo {
12293 int tap1, tap2, tap3, tap4, tap5;
12294 } poolinfo_table[] = {
12295 +#ifdef CONFIG_GRKERNSEC_RANDNET
12296 + /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
12297 + { 512, 411, 308, 208, 104, 1 },
12298 + /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
12299 + { 128, 103, 76, 51, 25, 1 },
12301 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
12302 { 128, 103, 76, 51, 25, 1 },
12303 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
12304 { 32, 26, 20, 14, 7, 1 },
12307 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
12308 { 2048, 1638, 1231, 819, 411, 1 },
12309 @@ -1166,7 +1178,7 @@ EXPORT_SYMBOL(generate_random_uuid);
12310 #include <linux/sysctl.h>
12312 static int min_read_thresh = 8, min_write_thresh;
12313 -static int max_read_thresh = INPUT_POOL_WORDS * 32;
12314 +static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
12315 static int max_write_thresh = INPUT_POOL_WORDS * 32;
12316 static char sysctl_bootid[16];
12318 diff -urNp linux-2.6.27.10/drivers/char/tpm/tpm.c linux-2.6.27.10/drivers/char/tpm/tpm.c
12319 --- linux-2.6.27.10/drivers/char/tpm/tpm.c 2008-11-07 12:55:34.000000000 -0500
12320 +++ linux-2.6.27.10/drivers/char/tpm/tpm.c 2008-11-18 03:38:44.000000000 -0500
12321 @@ -1037,7 +1037,7 @@ ssize_t tpm_write(struct file *file, con
12323 mutex_lock(&chip->buffer_mutex);
12325 - if (in_size > TPM_BUFSIZE)
12326 + if (in_size > (unsigned int)TPM_BUFSIZE)
12327 in_size = TPM_BUFSIZE;
12330 diff -urNp linux-2.6.27.10/drivers/char/vt_ioctl.c linux-2.6.27.10/drivers/char/vt_ioctl.c
12331 --- linux-2.6.27.10/drivers/char/vt_ioctl.c 2008-11-07 12:55:34.000000000 -0500
12332 +++ linux-2.6.27.10/drivers/char/vt_ioctl.c 2008-11-18 03:38:44.000000000 -0500
12333 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
12338 +#ifdef CONFIG_GRKERNSEC
12339 + if (!capable(CAP_SYS_TTY_CONFIG))
12343 if (!i && v == K_NOSUCHMAP) {
12344 /* deallocate map */
12345 key_map = key_maps[s];
12346 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
12350 +#ifdef CONFIG_GRKERNSEC
12351 + if (!capable(CAP_SYS_TTY_CONFIG)) {
12358 first_free = funcbufptr + (funcbufsize - funcbufleft);
12359 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
12360 diff -urNp linux-2.6.27.10/drivers/edac/edac_core.h linux-2.6.27.10/drivers/edac/edac_core.h
12361 --- linux-2.6.27.10/drivers/edac/edac_core.h 2008-11-07 12:55:34.000000000 -0500
12362 +++ linux-2.6.27.10/drivers/edac/edac_core.h 2008-11-18 03:38:44.000000000 -0500
12363 @@ -85,11 +85,11 @@ extern int edac_debug_level;
12365 #else /* !CONFIG_EDAC_DEBUG */
12367 -#define debugf0( ... )
12368 -#define debugf1( ... )
12369 -#define debugf2( ... )
12370 -#define debugf3( ... )
12371 -#define debugf4( ... )
12372 +#define debugf0( ... ) do {} while (0)
12373 +#define debugf1( ... ) do {} while (0)
12374 +#define debugf2( ... ) do {} while (0)
12375 +#define debugf3( ... ) do {} while (0)
12376 +#define debugf4( ... ) do {} while (0)
12378 #endif /* !CONFIG_EDAC_DEBUG */
12380 diff -urNp linux-2.6.27.10/drivers/firmware/dmi_scan.c linux-2.6.27.10/drivers/firmware/dmi_scan.c
12381 --- linux-2.6.27.10/drivers/firmware/dmi_scan.c 2008-11-07 12:55:34.000000000 -0500
12382 +++ linux-2.6.27.10/drivers/firmware/dmi_scan.c 2008-11-18 03:38:44.000000000 -0500
12383 @@ -384,11 +384,6 @@ void __init dmi_scan_machine(void)
12388 - * no iounmap() for that ioremap(); it would be a no-op, but
12389 - * it's so early in setup that sucker gets confused into doing
12390 - * what it shouldn't if we actually call it.
12392 p = dmi_ioremap(0xF0000, 0x10000);
12395 diff -urNp linux-2.6.27.10/drivers/hwmon/fscpos.c linux-2.6.27.10/drivers/hwmon/fscpos.c
12396 --- linux-2.6.27.10/drivers/hwmon/fscpos.c 2008-11-07 12:55:34.000000000 -0500
12397 +++ linux-2.6.27.10/drivers/hwmon/fscpos.c 2008-11-18 03:38:44.000000000 -0500
12398 @@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client
12399 unsigned long v = simple_strtoul(buf, NULL, 10);
12401 /* Range: 0..255 */
12402 - if (v < 0) v = 0;
12403 if (v > 255) v = 255;
12405 mutex_lock(&data->update_lock);
12406 diff -urNp linux-2.6.27.10/drivers/hwmon/k8temp.c linux-2.6.27.10/drivers/hwmon/k8temp.c
12407 --- linux-2.6.27.10/drivers/hwmon/k8temp.c 2008-11-07 12:55:34.000000000 -0500
12408 +++ linux-2.6.27.10/drivers/hwmon/k8temp.c 2008-11-18 03:38:44.000000000 -0500
12409 @@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
12411 static struct pci_device_id k8temp_ids[] = {
12412 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
12414 + { 0, 0, 0, 0, 0, 0, 0 },
12417 MODULE_DEVICE_TABLE(pci, k8temp_ids);
12418 diff -urNp linux-2.6.27.10/drivers/hwmon/sis5595.c linux-2.6.27.10/drivers/hwmon/sis5595.c
12419 --- linux-2.6.27.10/drivers/hwmon/sis5595.c 2008-11-07 12:55:34.000000000 -0500
12420 +++ linux-2.6.27.10/drivers/hwmon/sis5595.c 2008-11-18 03:38:44.000000000 -0500
12421 @@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
12423 static struct pci_device_id sis5595_pci_ids[] = {
12424 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12426 + { 0, 0, 0, 0, 0, 0, 0 }
12429 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
12430 diff -urNp linux-2.6.27.10/drivers/hwmon/via686a.c linux-2.6.27.10/drivers/hwmon/via686a.c
12431 --- linux-2.6.27.10/drivers/hwmon/via686a.c 2008-11-07 12:55:34.000000000 -0500
12432 +++ linux-2.6.27.10/drivers/hwmon/via686a.c 2008-11-18 03:38:44.000000000 -0500
12433 @@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
12435 static struct pci_device_id via686a_pci_ids[] = {
12436 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
12438 + { 0, 0, 0, 0, 0, 0, 0 }
12441 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
12442 diff -urNp linux-2.6.27.10/drivers/hwmon/vt8231.c linux-2.6.27.10/drivers/hwmon/vt8231.c
12443 --- linux-2.6.27.10/drivers/hwmon/vt8231.c 2008-11-07 12:55:34.000000000 -0500
12444 +++ linux-2.6.27.10/drivers/hwmon/vt8231.c 2008-11-18 03:38:44.000000000 -0500
12445 @@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
12447 static struct pci_device_id vt8231_pci_ids[] = {
12448 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
12450 + { 0, 0, 0, 0, 0, 0, 0 }
12453 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
12454 diff -urNp linux-2.6.27.10/drivers/hwmon/w83791d.c linux-2.6.27.10/drivers/hwmon/w83791d.c
12455 --- linux-2.6.27.10/drivers/hwmon/w83791d.c 2008-11-07 12:55:34.000000000 -0500
12456 +++ linux-2.6.27.10/drivers/hwmon/w83791d.c 2008-11-18 03:38:44.000000000 -0500
12457 @@ -289,8 +289,8 @@ static int w83791d_detect(struct i2c_cli
12458 struct i2c_board_info *info);
12459 static int w83791d_remove(struct i2c_client *client);
12461 -static int w83791d_read(struct i2c_client *client, u8 register);
12462 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
12463 +static int w83791d_read(struct i2c_client *client, u8 reg);
12464 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
12465 static struct w83791d_data *w83791d_update_device(struct device *dev);
12468 diff -urNp linux-2.6.27.10/drivers/i2c/busses/i2c-i801.c linux-2.6.27.10/drivers/i2c/busses/i2c-i801.c
12469 --- linux-2.6.27.10/drivers/i2c/busses/i2c-i801.c 2008-11-07 12:55:34.000000000 -0500
12470 +++ linux-2.6.27.10/drivers/i2c/busses/i2c-i801.c 2008-11-18 03:38:44.000000000 -0500
12471 @@ -576,7 +576,7 @@ static struct pci_device_id i801_ids[] =
12472 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
12473 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
12474 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
12476 + { 0, 0, 0, 0, 0, 0, 0 }
12479 MODULE_DEVICE_TABLE (pci, i801_ids);
12480 diff -urNp linux-2.6.27.10/drivers/i2c/busses/i2c-piix4.c linux-2.6.27.10/drivers/i2c/busses/i2c-piix4.c
12481 --- linux-2.6.27.10/drivers/i2c/busses/i2c-piix4.c 2008-11-07 12:55:34.000000000 -0500
12482 +++ linux-2.6.27.10/drivers/i2c/busses/i2c-piix4.c 2008-11-18 03:38:44.000000000 -0500
12483 @@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat
12485 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
12488 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
12491 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
12492 @@ -424,7 +424,7 @@ static struct pci_device_id piix4_ids[]
12493 PCI_DEVICE_ID_SERVERWORKS_CSB6) },
12494 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
12495 PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
12497 + { 0, 0, 0, 0, 0, 0, 0 }
12500 MODULE_DEVICE_TABLE (pci, piix4_ids);
12501 diff -urNp linux-2.6.27.10/drivers/i2c/busses/i2c-sis630.c linux-2.6.27.10/drivers/i2c/busses/i2c-sis630.c
12502 --- linux-2.6.27.10/drivers/i2c/busses/i2c-sis630.c 2008-11-07 12:55:34.000000000 -0500
12503 +++ linux-2.6.27.10/drivers/i2c/busses/i2c-sis630.c 2008-11-18 03:38:44.000000000 -0500
12504 @@ -472,7 +472,7 @@ static struct i2c_adapter sis630_adapter
12505 static struct pci_device_id sis630_ids[] __devinitdata = {
12506 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12507 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
12509 + { 0, 0, 0, 0, 0, 0, 0 }
12512 MODULE_DEVICE_TABLE (pci, sis630_ids);
12513 diff -urNp linux-2.6.27.10/drivers/i2c/busses/i2c-sis96x.c linux-2.6.27.10/drivers/i2c/busses/i2c-sis96x.c
12514 --- linux-2.6.27.10/drivers/i2c/busses/i2c-sis96x.c 2008-11-07 12:55:34.000000000 -0500
12515 +++ linux-2.6.27.10/drivers/i2c/busses/i2c-sis96x.c 2008-11-18 03:38:44.000000000 -0500
12516 @@ -248,7 +248,7 @@ static struct i2c_adapter sis96x_adapter
12518 static struct pci_device_id sis96x_ids[] = {
12519 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
12521 + { 0, 0, 0, 0, 0, 0, 0 }
12524 MODULE_DEVICE_TABLE (pci, sis96x_ids);
12525 diff -urNp linux-2.6.27.10/drivers/ieee1394/dv1394.c linux-2.6.27.10/drivers/ieee1394/dv1394.c
12526 --- linux-2.6.27.10/drivers/ieee1394/dv1394.c 2008-11-07 12:55:34.000000000 -0500
12527 +++ linux-2.6.27.10/drivers/ieee1394/dv1394.c 2008-11-18 03:38:44.000000000 -0500
12528 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
12529 based upon DIF section and sequence
12532 -static void inline
12533 +static inline void
12534 frame_put_packet (struct frame *f, struct packet *p)
12536 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
12537 @@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
12538 /* default SYT offset is 3 cycles */
12539 init->syt_offset = 3;
12541 - if ( (init->channel > 63) || (init->channel < 0) )
12542 + if (init->channel > 63)
12543 init->channel = 63;
12545 chan_mask = (u64)1 << init->channel;
12546 @@ -2174,7 +2174,7 @@ static struct ieee1394_device_id dv1394_
12547 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
12548 .version = AVC_SW_VERSION_ENTRY & 0xffffff
12551 + { 0, 0, 0, 0, 0, 0 }
12554 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
12555 diff -urNp linux-2.6.27.10/drivers/ieee1394/eth1394.c linux-2.6.27.10/drivers/ieee1394/eth1394.c
12556 --- linux-2.6.27.10/drivers/ieee1394/eth1394.c 2008-11-07 12:55:34.000000000 -0500
12557 +++ linux-2.6.27.10/drivers/ieee1394/eth1394.c 2008-11-18 03:38:44.000000000 -0500
12558 @@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
12559 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
12560 .version = ETHER1394_GASP_VERSION,
12563 + { 0, 0, 0, 0, 0, 0 }
12566 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
12567 diff -urNp linux-2.6.27.10/drivers/ieee1394/hosts.c linux-2.6.27.10/drivers/ieee1394/hosts.c
12568 --- linux-2.6.27.10/drivers/ieee1394/hosts.c 2008-11-07 12:55:34.000000000 -0500
12569 +++ linux-2.6.27.10/drivers/ieee1394/hosts.c 2008-11-18 03:38:44.000000000 -0500
12570 @@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
12573 static struct hpsb_host_driver dummy_driver = {
12575 .transmit_packet = dummy_transmit_packet,
12576 .devctl = dummy_devctl,
12577 .isoctl = dummy_isoctl
12578 diff -urNp linux-2.6.27.10/drivers/ieee1394/ohci1394.c linux-2.6.27.10/drivers/ieee1394/ohci1394.c
12579 --- linux-2.6.27.10/drivers/ieee1394/ohci1394.c 2008-11-07 12:55:34.000000000 -0500
12580 +++ linux-2.6.27.10/drivers/ieee1394/ohci1394.c 2008-11-18 03:38:44.000000000 -0500
12581 @@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
12582 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
12584 /* Module Parameters */
12585 -static int phys_dma = 1;
12586 +static int phys_dma;
12587 module_param(phys_dma, int, 0444);
12588 -MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
12589 +MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
12591 static void dma_trm_tasklet(unsigned long data);
12592 static void dma_trm_reset(struct dma_trm_ctx *d);
12593 @@ -3437,7 +3437,7 @@ static struct pci_device_id ohci1394_pci
12594 .subvendor = PCI_ANY_ID,
12595 .subdevice = PCI_ANY_ID,
12598 + { 0, 0, 0, 0, 0, 0, 0 },
12601 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
12602 diff -urNp linux-2.6.27.10/drivers/ieee1394/raw1394.c linux-2.6.27.10/drivers/ieee1394/raw1394.c
12603 --- linux-2.6.27.10/drivers/ieee1394/raw1394.c 2008-11-07 12:55:34.000000000 -0500
12604 +++ linux-2.6.27.10/drivers/ieee1394/raw1394.c 2008-11-18 03:38:44.000000000 -0500
12605 @@ -2968,7 +2968,7 @@ static struct ieee1394_device_id raw1394
12606 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12607 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12608 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
12610 + { 0, 0, 0, 0, 0, 0 }
12613 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
12614 diff -urNp linux-2.6.27.10/drivers/ieee1394/sbp2.c linux-2.6.27.10/drivers/ieee1394/sbp2.c
12615 --- linux-2.6.27.10/drivers/ieee1394/sbp2.c 2008-12-10 22:35:37.000000000 -0500
12616 +++ linux-2.6.27.10/drivers/ieee1394/sbp2.c 2008-12-10 22:35:46.000000000 -0500
12617 @@ -290,7 +290,7 @@ static struct ieee1394_device_id sbp2_id
12618 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12619 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
12620 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
12622 + { 0, 0, 0, 0, 0, 0 }
12624 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
12626 @@ -2135,7 +2135,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
12627 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
12628 MODULE_LICENSE("GPL");
12630 -static int sbp2_module_init(void)
12631 +static int __init sbp2_module_init(void)
12635 diff -urNp linux-2.6.27.10/drivers/ieee1394/video1394.c linux-2.6.27.10/drivers/ieee1394/video1394.c
12636 --- linux-2.6.27.10/drivers/ieee1394/video1394.c 2008-11-07 12:55:34.000000000 -0500
12637 +++ linux-2.6.27.10/drivers/ieee1394/video1394.c 2008-11-18 03:38:44.000000000 -0500
12638 @@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
12639 if (unlikely(d == NULL))
12642 - if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
12643 + if (unlikely(v.buffer>=d->num_desc - 1)) {
12644 PRINT(KERN_ERR, ohci->host->id,
12645 "Buffer %d out of range",v.buffer);
12647 @@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
12648 if (unlikely(d == NULL))
12651 - if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
12652 + if (unlikely(v.buffer>d->num_desc - 1)) {
12653 PRINT(KERN_ERR, ohci->host->id,
12654 "Buffer %d out of range",v.buffer);
12656 @@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
12657 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12658 if (d == NULL) return -EFAULT;
12660 - if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
12661 + if (v.buffer>=d->num_desc - 1) {
12662 PRINT(KERN_ERR, ohci->host->id,
12663 "Buffer %d out of range",v.buffer);
12665 @@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
12666 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12667 if (d == NULL) return -EFAULT;
12669 - if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
12670 + if (v.buffer>=d->num_desc-1) {
12671 PRINT(KERN_ERR, ohci->host->id,
12672 "Buffer %d out of range",v.buffer);
12674 @@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
12675 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12676 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
12679 + { 0, 0, 0, 0, 0, 0 }
12682 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
12683 diff -urNp linux-2.6.27.10/drivers/input/keyboard/atkbd.c linux-2.6.27.10/drivers/input/keyboard/atkbd.c
12684 --- linux-2.6.27.10/drivers/input/keyboard/atkbd.c 2008-12-10 22:35:37.000000000 -0500
12685 +++ linux-2.6.27.10/drivers/input/keyboard/atkbd.c 2008-12-10 22:35:46.000000000 -0500
12686 @@ -1148,7 +1148,7 @@ static struct serio_device_id atkbd_seri
12688 .extra = SERIO_ANY,
12694 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
12695 diff -urNp linux-2.6.27.10/drivers/input/mouse/lifebook.c linux-2.6.27.10/drivers/input/mouse/lifebook.c
12696 --- linux-2.6.27.10/drivers/input/mouse/lifebook.c 2008-11-07 12:55:34.000000000 -0500
12697 +++ linux-2.6.27.10/drivers/input/mouse/lifebook.c 2008-11-18 03:38:44.000000000 -0500
12698 @@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
12699 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
12703 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
12706 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
12707 diff -urNp linux-2.6.27.10/drivers/input/mouse/psmouse-base.c linux-2.6.27.10/drivers/input/mouse/psmouse-base.c
12708 --- linux-2.6.27.10/drivers/input/mouse/psmouse-base.c 2008-11-07 12:55:34.000000000 -0500
12709 +++ linux-2.6.27.10/drivers/input/mouse/psmouse-base.c 2008-11-18 03:38:44.000000000 -0500
12710 @@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
12712 .extra = SERIO_ANY,
12718 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
12719 diff -urNp linux-2.6.27.10/drivers/input/mouse/synaptics.c linux-2.6.27.10/drivers/input/mouse/synaptics.c
12720 --- linux-2.6.27.10/drivers/input/mouse/synaptics.c 2008-11-07 12:55:34.000000000 -0500
12721 +++ linux-2.6.27.10/drivers/input/mouse/synaptics.c 2008-11-18 03:38:45.000000000 -0500
12722 @@ -417,7 +417,7 @@ static void synaptics_process_packet(str
12725 if (SYN_MODEL_PEN(priv->model_id))
12726 - ; /* Nothing, treat a pen as a single finger */
12727 + break; /* Nothing, treat a pen as a single finger */
12730 if (SYN_CAP_PALMDETECT(priv->capabilities))
12731 @@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
12732 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
12736 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12740 diff -urNp linux-2.6.27.10/drivers/input/mousedev.c linux-2.6.27.10/drivers/input/mousedev.c
12741 --- linux-2.6.27.10/drivers/input/mousedev.c 2008-11-07 12:55:34.000000000 -0500
12742 +++ linux-2.6.27.10/drivers/input/mousedev.c 2008-11-18 03:38:45.000000000 -0500
12743 @@ -1064,7 +1064,7 @@ static struct input_handler mousedev_han
12745 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
12746 static struct miscdevice psaux_mouse = {
12747 - PSMOUSE_MINOR, "psaux", &mousedev_fops
12748 + PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
12750 static int psaux_registered;
12752 diff -urNp linux-2.6.27.10/drivers/input/serio/i8042-x86ia64io.h linux-2.6.27.10/drivers/input/serio/i8042-x86ia64io.h
12753 --- linux-2.6.27.10/drivers/input/serio/i8042-x86ia64io.h 2008-12-21 01:16:51.000000000 -0500
12754 +++ linux-2.6.27.10/drivers/input/serio/i8042-x86ia64io.h 2008-12-21 01:16:00.000000000 -0500
12755 @@ -143,7 +143,7 @@ static struct dmi_system_id __initdata i
12756 DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
12760 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12764 @@ -351,7 +351,7 @@ static struct dmi_system_id __initdata i
12765 DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
12769 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12773 @@ -363,7 +363,7 @@ static struct dmi_system_id __initdata i
12774 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
12778 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12782 @@ -430,7 +430,7 @@ static struct dmi_system_id __initdata i
12783 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
12787 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12790 #endif /* CONFIG_X86 */
12791 diff -urNp linux-2.6.27.10/drivers/input/serio/serio_raw.c linux-2.6.27.10/drivers/input/serio/serio_raw.c
12792 --- linux-2.6.27.10/drivers/input/serio/serio_raw.c 2008-11-07 12:55:34.000000000 -0500
12793 +++ linux-2.6.27.10/drivers/input/serio/serio_raw.c 2008-11-18 03:38:45.000000000 -0500
12794 @@ -373,7 +373,7 @@ static struct serio_device_id serio_raw_
12796 .extra = SERIO_ANY,
12802 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
12803 diff -urNp linux-2.6.27.10/drivers/md/bitmap.c linux-2.6.27.10/drivers/md/bitmap.c
12804 --- linux-2.6.27.10/drivers/md/bitmap.c 2008-11-07 12:55:34.000000000 -0500
12805 +++ linux-2.6.27.10/drivers/md/bitmap.c 2008-11-18 03:38:45.000000000 -0500
12808 # define PRINTK(x...) printk(KERN_DEBUG x)
12810 -# define PRINTK(x...)
12811 +# define PRINTK(x...) do {} while (0)
12815 diff -urNp linux-2.6.27.10/drivers/mtd/devices/doc2000.c linux-2.6.27.10/drivers/mtd/devices/doc2000.c
12816 --- linux-2.6.27.10/drivers/mtd/devices/doc2000.c 2008-11-07 12:55:34.000000000 -0500
12817 +++ linux-2.6.27.10/drivers/mtd/devices/doc2000.c 2008-11-18 03:38:45.000000000 -0500
12818 @@ -777,7 +777,7 @@ static int doc_write(struct mtd_info *mt
12820 /* The ECC will not be calculated correctly if less than 512 is written */
12822 - if (len != 0x200 && eccbuf)
12823 + if (len != 0x200)
12824 printk(KERN_WARNING
12825 "ECC needs a full sector write (adr: %lx size %lx)\n",
12826 (long) to, (long) len);
12827 diff -urNp linux-2.6.27.10/drivers/mtd/devices/doc2001.c linux-2.6.27.10/drivers/mtd/devices/doc2001.c
12828 --- linux-2.6.27.10/drivers/mtd/devices/doc2001.c 2008-11-07 12:55:34.000000000 -0500
12829 +++ linux-2.6.27.10/drivers/mtd/devices/doc2001.c 2008-11-18 03:38:45.000000000 -0500
12830 @@ -396,6 +396,8 @@ static int doc_read (struct mtd_info *mt
12831 /* Don't allow read past end of device */
12832 if (from >= this->totlen)
12837 /* Don't allow a single read to cross a 512-byte block boundary */
12838 if (from + len > ((from | 0x1ff) + 1))
12839 diff -urNp linux-2.6.27.10/drivers/mtd/devices/slram.c linux-2.6.27.10/drivers/mtd/devices/slram.c
12840 --- linux-2.6.27.10/drivers/mtd/devices/slram.c 2008-11-07 12:55:34.000000000 -0500
12841 +++ linux-2.6.27.10/drivers/mtd/devices/slram.c 2008-11-18 03:38:45.000000000 -0500
12842 @@ -273,7 +273,7 @@ static int parse_cmdline(char *devname,
12844 T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
12845 devname, devstart, devlength);
12846 - if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
12847 + if (devlength % SLRAM_BLK_SZ != 0) {
12848 E("slram: Illegal start / length parameter.\n");
12851 diff -urNp linux-2.6.27.10/drivers/mtd/ubi/build.c linux-2.6.27.10/drivers/mtd/ubi/build.c
12852 --- linux-2.6.27.10/drivers/mtd/ubi/build.c 2008-11-07 12:55:34.000000000 -0500
12853 +++ linux-2.6.27.10/drivers/mtd/ubi/build.c 2008-11-18 03:38:45.000000000 -0500
12854 @@ -1104,7 +1104,7 @@ static int __init bytes_str_to_int(const
12855 unsigned long result;
12857 result = simple_strtoul(str, &endp, 0);
12858 - if (str == endp || result < 0) {
12859 + if (str == endp) {
12860 printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
12863 diff -urNp linux-2.6.27.10/drivers/net/eepro100.c linux-2.6.27.10/drivers/net/eepro100.c
12864 --- linux-2.6.27.10/drivers/net/eepro100.c 2008-11-07 12:55:34.000000000 -0500
12865 +++ linux-2.6.27.10/drivers/net/eepro100.c 2008-11-18 03:38:45.000000000 -0500
12866 @@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
12867 # define rx_align(skb) skb_reserve((skb), 2)
12868 # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
12870 -# define rx_align(skb)
12871 +# define rx_align(skb) do {} while (0)
12872 # define RxFD_ALIGNMENT
12875 @@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
12878 static struct pci_device_id eepro100_pci_tbl[] = {
12879 - { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
12880 - { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
12881 - { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
12882 - { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
12883 - { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
12884 - { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
12885 - { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
12886 - { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
12887 - { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
12888 - { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
12889 - { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
12890 - { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
12891 - { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
12892 - { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
12893 - { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
12894 - { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
12895 - { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
12896 - { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
12897 - { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
12898 - { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
12899 - { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
12900 - { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
12901 - { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
12902 - { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
12903 - { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
12904 - { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
12906 + { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12907 + { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12908 + { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12909 + { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12910 + { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12911 + { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12912 + { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12913 + { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12914 + { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12915 + { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12916 + { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12917 + { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12918 + { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12919 + { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12920 + { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12921 + { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12922 + { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12923 + { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12924 + { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12925 + { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12926 + { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12927 + { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12928 + { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12929 + { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12930 + { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12931 + { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12932 + { 0, 0, 0, 0, 0, 0, 0 }
12934 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
12936 diff -urNp linux-2.6.27.10/drivers/net/irda/vlsi_ir.c linux-2.6.27.10/drivers/net/irda/vlsi_ir.c
12937 --- linux-2.6.27.10/drivers/net/irda/vlsi_ir.c 2008-11-07 12:55:34.000000000 -0500
12938 +++ linux-2.6.27.10/drivers/net/irda/vlsi_ir.c 2008-11-18 03:38:45.000000000 -0500
12939 @@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
12940 /* no race - tx-ring already empty */
12941 vlsi_set_baud(idev, iobase);
12942 netif_wake_queue(ndev);
12947 /* keep the speed change pending like it would
12948 * for any len>0 packet. tx completion interrupt
12949 * will apply it when the tx ring becomes empty.
12952 spin_unlock_irqrestore(&idev->lock, flags);
12953 dev_kfree_skb_any(skb);
12955 diff -urNp linux-2.6.27.10/drivers/net/pcnet32.c linux-2.6.27.10/drivers/net/pcnet32.c
12956 --- linux-2.6.27.10/drivers/net/pcnet32.c 2008-11-07 12:55:34.000000000 -0500
12957 +++ linux-2.6.27.10/drivers/net/pcnet32.c 2008-11-18 03:38:45.000000000 -0500
12958 @@ -78,7 +78,7 @@ static int cards_found;
12960 * VLB I/O addresses
12962 -static unsigned int pcnet32_portlist[] __initdata =
12963 +static unsigned int pcnet32_portlist[] __devinitdata =
12964 { 0x300, 0x320, 0x340, 0x360, 0 };
12966 static int pcnet32_debug = 0;
12967 diff -urNp linux-2.6.27.10/drivers/net/tg3.h linux-2.6.27.10/drivers/net/tg3.h
12968 --- linux-2.6.27.10/drivers/net/tg3.h 2008-11-07 12:55:34.000000000 -0500
12969 +++ linux-2.6.27.10/drivers/net/tg3.h 2008-11-18 03:38:45.000000000 -0500
12970 @@ -102,6 +102,7 @@
12971 #define CHIPREV_ID_5750_A0 0x4000
12972 #define CHIPREV_ID_5750_A1 0x4001
12973 #define CHIPREV_ID_5750_A3 0x4003
12974 +#define CHIPREV_ID_5750_C1 0x4201
12975 #define CHIPREV_ID_5750_C2 0x4202
12976 #define CHIPREV_ID_5752_A0_HW 0x5000
12977 #define CHIPREV_ID_5752_A0 0x6000
12978 diff -urNp linux-2.6.27.10/drivers/net/wireless/iwlwifi/iwl3945-base.c linux-2.6.27.10/drivers/net/wireless/iwlwifi/iwl3945-base.c
12979 --- linux-2.6.27.10/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-11-17 20:03:30.000000000 -0500
12980 +++ linux-2.6.27.10/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-12-27 13:44:22.000000000 -0500
12981 @@ -785,7 +785,7 @@ static int iwl3945_send_cmd_sync(struct
12982 IWL_ERROR("Error: Response NULL in '%s'\n",
12983 get_cmd_string(cmd->id));
12990 diff -urNp linux-2.6.27.10/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.27.10/drivers/pci/hotplug/cpqphp_nvram.c
12991 --- linux-2.6.27.10/drivers/pci/hotplug/cpqphp_nvram.c 2008-11-07 12:55:34.000000000 -0500
12992 +++ linux-2.6.27.10/drivers/pci/hotplug/cpqphp_nvram.c 2008-11-18 03:38:45.000000000 -0500
12993 @@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
12995 void compaq_nvram_init (void __iomem *rom_start)
12998 +#ifndef CONFIG_PAX_KERNEXEC
13000 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
13004 dbg("int15 entry = %p\n", compaq_int15_entry_point);
13006 /* initialize our int15 lock */
13007 diff -urNp linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv.c linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv.c
13008 --- linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv.c 2008-11-07 12:55:34.000000000 -0500
13009 +++ linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv.c 2008-11-18 03:38:45.000000000 -0500
13010 @@ -59,7 +59,7 @@ static struct pcie_port_service_id aer_i
13011 .port_type = PCIE_RC_PORT,
13012 .service_type = PCIE_PORT_SERVICE_AER,
13014 - { /* end: all zeroes */ }
13015 + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13018 static struct pci_error_handlers aer_error_handlers = {
13019 diff -urNp linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv_core.c
13020 --- linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv_core.c 2008-11-07 12:55:34.000000000 -0500
13021 +++ linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv_core.c 2008-11-18 03:38:45.000000000 -0500
13022 @@ -663,7 +663,7 @@ static void aer_isr_one_error(struct pci
13023 struct aer_err_source *e_src)
13025 struct device *s_device;
13026 - struct aer_err_info e_info = {0, 0, 0,};
13027 + struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
13031 diff -urNp linux-2.6.27.10/drivers/pci/pcie/portdrv_pci.c linux-2.6.27.10/drivers/pci/pcie/portdrv_pci.c
13032 --- linux-2.6.27.10/drivers/pci/pcie/portdrv_pci.c 2008-11-07 12:55:34.000000000 -0500
13033 +++ linux-2.6.27.10/drivers/pci/pcie/portdrv_pci.c 2008-11-18 03:38:45.000000000 -0500
13034 @@ -264,7 +264,7 @@ static void pcie_portdrv_err_resume(stru
13035 static const struct pci_device_id port_pci_ids[] = { {
13036 /* handle any PCI-Express port */
13037 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
13038 - }, { /* end: all zeroes */ }
13039 + }, { 0, 0, 0, 0, 0, 0, 0 }
13041 MODULE_DEVICE_TABLE(pci, port_pci_ids);
13043 diff -urNp linux-2.6.27.10/drivers/pci/proc.c linux-2.6.27.10/drivers/pci/proc.c
13044 --- linux-2.6.27.10/drivers/pci/proc.c 2008-11-07 12:55:34.000000000 -0500
13045 +++ linux-2.6.27.10/drivers/pci/proc.c 2008-11-18 03:38:45.000000000 -0500
13046 @@ -470,7 +470,16 @@ static const struct file_operations proc
13047 static int __init pci_proc_init(void)
13049 struct pci_dev *dev = NULL;
13051 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
13052 +#ifdef CONFIG_GRKERNSEC_PROC_USER
13053 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
13054 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
13055 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
13058 proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
13060 proc_create("devices", 0, proc_bus_pci_dir,
13061 &proc_bus_pci_dev_operations);
13062 proc_initialized = 1;
13063 diff -urNp linux-2.6.27.10/drivers/pcmcia/ti113x.h linux-2.6.27.10/drivers/pcmcia/ti113x.h
13064 --- linux-2.6.27.10/drivers/pcmcia/ti113x.h 2008-11-07 12:55:34.000000000 -0500
13065 +++ linux-2.6.27.10/drivers/pcmcia/ti113x.h 2008-11-18 03:38:45.000000000 -0500
13066 @@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
13067 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
13068 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
13071 + { 0, 0, 0, 0, 0, 0, 0 }
13074 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
13075 diff -urNp linux-2.6.27.10/drivers/pcmcia/yenta_socket.c linux-2.6.27.10/drivers/pcmcia/yenta_socket.c
13076 --- linux-2.6.27.10/drivers/pcmcia/yenta_socket.c 2008-11-07 12:55:34.000000000 -0500
13077 +++ linux-2.6.27.10/drivers/pcmcia/yenta_socket.c 2008-11-18 03:38:45.000000000 -0500
13078 @@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
13080 /* match any cardbus bridge */
13081 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
13082 - { /* all zeroes */ }
13083 + { 0, 0, 0, 0, 0, 0, 0 }
13085 MODULE_DEVICE_TABLE(pci, yenta_table);
13087 diff -urNp linux-2.6.27.10/drivers/pnp/pnpbios/bioscalls.c linux-2.6.27.10/drivers/pnp/pnpbios/bioscalls.c
13088 --- linux-2.6.27.10/drivers/pnp/pnpbios/bioscalls.c 2008-11-07 12:55:34.000000000 -0500
13089 +++ linux-2.6.27.10/drivers/pnp/pnpbios/bioscalls.c 2008-11-18 03:38:45.000000000 -0500
13090 @@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
13091 set_limit(gdt[(selname) >> 3], size); \
13094 -static struct desc_struct bad_bios_desc;
13095 +static struct desc_struct bad_bios_desc __read_only;
13098 * At some point we want to use this stack frame pointer to unwind
13099 @@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
13100 struct desc_struct save_desc_40;
13103 +#ifdef CONFIG_PAX_KERNEXEC
13104 + unsigned long cr0;
13108 * PnP BIOSes are generally not terribly re-entrant.
13109 * Also, don't rely on them to save everything correctly.
13110 @@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
13113 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
13115 +#ifdef CONFIG_PAX_KERNEXEC
13116 + pax_open_kernel(cr0);
13119 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
13121 +#ifdef CONFIG_PAX_KERNEXEC
13122 + pax_close_kernel(cr0);
13125 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
13126 spin_lock_irqsave(&pnp_bios_lock, flags);
13128 @@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
13130 spin_unlock_irqrestore(&pnp_bios_lock, flags);
13132 +#ifdef CONFIG_PAX_KERNEXEC
13133 + pax_open_kernel(cr0);
13136 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
13138 +#ifdef CONFIG_PAX_KERNEXEC
13139 + pax_close_kernel(cr0);
13144 /* If we get here and this is set then the PnP BIOS faulted on us. */
13145 @@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
13149 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
13150 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
13154 +#ifdef CONFIG_PAX_KERNEXEC
13155 + unsigned long cr0;
13158 spin_lock_init(&pnp_bios_lock);
13159 pnp_bios_callpoint.offset = header->fields.pm16offset;
13160 pnp_bios_callpoint.segment = PNP_CS16;
13162 +#ifdef CONFIG_PAX_KERNEXEC
13163 + pax_open_kernel(cr0);
13166 bad_bios_desc.a = 0;
13167 - bad_bios_desc.b = 0x00409200;
13168 + bad_bios_desc.b = 0x00409300;
13170 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
13171 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
13172 @@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
13173 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
13174 __va(header->fields.pm16dseg));
13177 +#ifdef CONFIG_PAX_KERNEXEC
13178 + pax_close_kernel(cr0);
13182 diff -urNp linux-2.6.27.10/drivers/pnp/quirks.c linux-2.6.27.10/drivers/pnp/quirks.c
13183 --- linux-2.6.27.10/drivers/pnp/quirks.c 2008-12-21 01:16:51.000000000 -0500
13184 +++ linux-2.6.27.10/drivers/pnp/quirks.c 2008-12-21 01:13:46.000000000 -0500
13185 @@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = {
13186 /* PnP resources that might overlap PCI BARs */
13187 {"PNP0c01", quirk_system_pci_resources},
13188 {"PNP0c02", quirk_system_pci_resources},
13193 void pnp_fixup_device(struct pnp_dev *dev)
13194 diff -urNp linux-2.6.27.10/drivers/pnp/resource.c linux-2.6.27.10/drivers/pnp/resource.c
13195 --- linux-2.6.27.10/drivers/pnp/resource.c 2008-12-21 01:16:51.000000000 -0500
13196 +++ linux-2.6.27.10/drivers/pnp/resource.c 2008-12-21 01:13:46.000000000 -0500
13197 @@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
13200 /* check if the resource is valid */
13201 - if (*irq < 0 || *irq > 15)
13205 /* check if the resource is reserved */
13206 @@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
13209 /* check if the resource is valid */
13210 - if (*dma < 0 || *dma == 4 || *dma > 7)
13211 + if (*dma == 4 || *dma > 7)
13214 /* check if the resource is reserved */
13215 diff -urNp linux-2.6.27.10/drivers/scsi/scsi_logging.h linux-2.6.27.10/drivers/scsi/scsi_logging.h
13216 --- linux-2.6.27.10/drivers/scsi/scsi_logging.h 2008-11-07 12:55:34.000000000 -0500
13217 +++ linux-2.6.27.10/drivers/scsi/scsi_logging.h 2008-11-18 03:38:45.000000000 -0500
13218 @@ -51,7 +51,7 @@ do { \
13222 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
13223 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
13224 #endif /* CONFIG_SCSI_LOGGING */
13227 diff -urNp linux-2.6.27.10/drivers/serial/8250_pci.c linux-2.6.27.10/drivers/serial/8250_pci.c
13228 --- linux-2.6.27.10/drivers/serial/8250_pci.c 2008-11-07 12:55:34.000000000 -0500
13229 +++ linux-2.6.27.10/drivers/serial/8250_pci.c 2008-11-18 03:38:45.000000000 -0500
13230 @@ -2859,7 +2859,7 @@ static struct pci_device_id serial_pci_t
13231 PCI_ANY_ID, PCI_ANY_ID,
13232 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
13233 0xffff00, pbn_default },
13235 + { 0, 0, 0, 0, 0, 0, 0 }
13238 static struct pci_driver serial_pci_driver = {
13239 diff -urNp linux-2.6.27.10/drivers/usb/class/cdc-acm.c linux-2.6.27.10/drivers/usb/class/cdc-acm.c
13240 --- linux-2.6.27.10/drivers/usb/class/cdc-acm.c 2008-11-18 11:38:40.000000000 -0500
13241 +++ linux-2.6.27.10/drivers/usb/class/cdc-acm.c 2008-11-18 11:40:52.000000000 -0500
13242 @@ -1381,7 +1381,7 @@ static struct usb_device_id acm_ids[] =
13243 USB_CDC_ACM_PROTO_AT_CDMA) },
13245 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
13247 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13250 MODULE_DEVICE_TABLE (usb, acm_ids);
13251 diff -urNp linux-2.6.27.10/drivers/usb/class/usblp.c linux-2.6.27.10/drivers/usb/class/usblp.c
13252 --- linux-2.6.27.10/drivers/usb/class/usblp.c 2008-11-07 12:55:34.000000000 -0500
13253 +++ linux-2.6.27.10/drivers/usb/class/usblp.c 2008-11-18 03:38:45.000000000 -0500
13254 @@ -227,7 +227,7 @@ static const struct quirk_printer_struct
13255 { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
13256 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
13257 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
13262 static int usblp_wwait(struct usblp *usblp, int nonblock);
13263 @@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
13264 { USB_INTERFACE_INFO(7, 1, 2) },
13265 { USB_INTERFACE_INFO(7, 1, 3) },
13266 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
13267 - { } /* Terminating entry */
13268 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13271 MODULE_DEVICE_TABLE (usb, usblp_ids);
13272 diff -urNp linux-2.6.27.10/drivers/usb/core/hub.c linux-2.6.27.10/drivers/usb/core/hub.c
13273 --- linux-2.6.27.10/drivers/usb/core/hub.c 2008-11-07 12:55:34.000000000 -0500
13274 +++ linux-2.6.27.10/drivers/usb/core/hub.c 2008-11-18 03:38:45.000000000 -0500
13275 @@ -3111,7 +3111,7 @@ static struct usb_device_id hub_id_table
13276 .bDeviceClass = USB_CLASS_HUB},
13277 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
13278 .bInterfaceClass = USB_CLASS_HUB},
13279 - { } /* Terminating entry */
13280 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13283 MODULE_DEVICE_TABLE (usb, hub_id_table);
13284 diff -urNp linux-2.6.27.10/drivers/usb/host/ehci-pci.c linux-2.6.27.10/drivers/usb/host/ehci-pci.c
13285 --- linux-2.6.27.10/drivers/usb/host/ehci-pci.c 2008-12-10 22:35:37.000000000 -0500
13286 +++ linux-2.6.27.10/drivers/usb/host/ehci-pci.c 2008-12-10 22:35:46.000000000 -0500
13287 @@ -414,7 +414,7 @@ static const struct pci_device_id pci_id
13288 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
13289 .driver_data = (unsigned long) &ehci_pci_hc_driver,
13291 - { /* end: all zeroes */ }
13292 + { 0, 0, 0, 0, 0, 0, 0 }
13294 MODULE_DEVICE_TABLE(pci, pci_ids);
13296 diff -urNp linux-2.6.27.10/drivers/usb/host/uhci-hcd.c linux-2.6.27.10/drivers/usb/host/uhci-hcd.c
13297 --- linux-2.6.27.10/drivers/usb/host/uhci-hcd.c 2008-11-07 12:55:34.000000000 -0500
13298 +++ linux-2.6.27.10/drivers/usb/host/uhci-hcd.c 2008-11-18 03:38:45.000000000 -0500
13299 @@ -928,7 +928,7 @@ static const struct pci_device_id uhci_p
13300 /* handle any USB UHCI controller */
13301 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
13302 .driver_data = (unsigned long) &uhci_driver,
13303 - }, { /* end: all zeroes */ }
13304 + }, { 0, 0, 0, 0, 0, 0, 0 }
13307 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
13308 diff -urNp linux-2.6.27.10/drivers/usb/storage/debug.h linux-2.6.27.10/drivers/usb/storage/debug.h
13309 --- linux-2.6.27.10/drivers/usb/storage/debug.h 2008-11-07 12:55:34.000000000 -0500
13310 +++ linux-2.6.27.10/drivers/usb/storage/debug.h 2008-11-18 03:38:45.000000000 -0500
13311 @@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
13312 #define US_DEBUGPX(x...) printk( x )
13313 #define US_DEBUG(x) x
13315 -#define US_DEBUGP(x...)
13316 -#define US_DEBUGPX(x...)
13317 -#define US_DEBUG(x)
13318 +#define US_DEBUGP(x...) do {} while (0)
13319 +#define US_DEBUGPX(x...) do {} while (0)
13320 +#define US_DEBUG(x) do {} while (0)
13324 diff -urNp linux-2.6.27.10/drivers/usb/storage/usb.c linux-2.6.27.10/drivers/usb/storage/usb.c
13325 --- linux-2.6.27.10/drivers/usb/storage/usb.c 2008-11-07 12:55:34.000000000 -0500
13326 +++ linux-2.6.27.10/drivers/usb/storage/usb.c 2008-11-18 03:38:45.000000000 -0500
13327 @@ -136,7 +136,7 @@ static struct usb_device_id storage_usb_
13330 /* Terminating entry */
13332 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13335 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
13336 @@ -176,7 +176,7 @@ static struct us_unusual_dev us_unusual_
13339 /* Terminating entry */
13341 + { NULL, NULL, 0, 0, NULL }
13345 diff -urNp linux-2.6.27.10/drivers/video/fbcmap.c linux-2.6.27.10/drivers/video/fbcmap.c
13346 --- linux-2.6.27.10/drivers/video/fbcmap.c 2008-11-07 12:55:34.000000000 -0500
13347 +++ linux-2.6.27.10/drivers/video/fbcmap.c 2008-11-18 03:38:45.000000000 -0500
13348 @@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
13349 int rc, size = cmap->len * sizeof(u16);
13350 struct fb_cmap umap;
13352 - if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
13353 - !info->fbops->fb_setcmap))
13354 + if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
13357 memset(&umap, 0, sizeof(struct fb_cmap));
13358 diff -urNp linux-2.6.27.10/drivers/video/fbmem.c linux-2.6.27.10/drivers/video/fbmem.c
13359 --- linux-2.6.27.10/drivers/video/fbmem.c 2008-12-10 22:35:37.000000000 -0500
13360 +++ linux-2.6.27.10/drivers/video/fbmem.c 2008-12-10 22:35:46.000000000 -0500
13361 @@ -395,7 +395,7 @@ static void fb_do_show_logo(struct fb_in
13362 image->dx += image->width + 8;
13364 } else if (rotate == FB_ROTATE_UD) {
13365 - for (x = 0; x < num && image->dx >= 0; x++) {
13366 + for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
13367 info->fbops->fb_imageblit(info, image);
13368 image->dx -= image->width + 8;
13370 @@ -407,7 +407,7 @@ static void fb_do_show_logo(struct fb_in
13371 image->dy += image->height + 8;
13373 } else if (rotate == FB_ROTATE_CCW) {
13374 - for (x = 0; x < num && image->dy >= 0; x++) {
13375 + for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
13376 info->fbops->fb_imageblit(info, image);
13377 image->dy -= image->height + 8;
13379 @@ -1083,7 +1083,7 @@ fb_ioctl(struct inode *inode, struct fil
13381 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
13383 - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
13384 + if (con2fb.framebuffer >= FB_MAX)
13387 if (!registered_fb[con2fb.framebuffer])
13388 diff -urNp linux-2.6.27.10/drivers/video/fbmon.c linux-2.6.27.10/drivers/video/fbmon.c
13389 --- linux-2.6.27.10/drivers/video/fbmon.c 2008-11-07 12:55:34.000000000 -0500
13390 +++ linux-2.6.27.10/drivers/video/fbmon.c 2008-11-18 03:38:45.000000000 -0500
13393 #define DPRINTK(fmt, args...) printk(fmt,## args)
13395 -#define DPRINTK(fmt, args...)
13396 +#define DPRINTK(fmt, args...) do {} while (0)
13399 #define FBMON_FIX_HEADER 1
13400 diff -urNp linux-2.6.27.10/drivers/video/i810/i810_accel.c linux-2.6.27.10/drivers/video/i810/i810_accel.c
13401 --- linux-2.6.27.10/drivers/video/i810/i810_accel.c 2008-11-07 12:55:34.000000000 -0500
13402 +++ linux-2.6.27.10/drivers/video/i810/i810_accel.c 2008-11-18 03:38:45.000000000 -0500
13403 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct
13406 printk("ringbuffer lockup!!!\n");
13407 + printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
13408 i810_report_error(mmio);
13409 par->dev_flags |= LOCKUP;
13410 info->pixmap.scan_align = 1;
13411 diff -urNp linux-2.6.27.10/drivers/video/i810/i810_main.c linux-2.6.27.10/drivers/video/i810/i810_main.c
13412 --- linux-2.6.27.10/drivers/video/i810/i810_main.c 2008-11-07 12:55:34.000000000 -0500
13413 +++ linux-2.6.27.10/drivers/video/i810/i810_main.c 2008-11-18 03:38:45.000000000 -0500
13414 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
13415 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
13416 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
13417 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
13419 + { 0, 0, 0, 0, 0, 0, 0 },
13422 static struct pci_driver i810fb_driver = {
13423 @@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
13424 int size = ((cursor->image.width + 7) >> 3) *
13425 cursor->image.height;
13427 - u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
13428 + u8 *data = kmalloc(64 * 8, GFP_KERNEL);
13432 diff -urNp linux-2.6.27.10/drivers/video/modedb.c linux-2.6.27.10/drivers/video/modedb.c
13433 --- linux-2.6.27.10/drivers/video/modedb.c 2008-11-07 12:55:34.000000000 -0500
13434 +++ linux-2.6.27.10/drivers/video/modedb.c 2008-11-18 03:38:45.000000000 -0500
13435 @@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
13437 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
13438 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
13439 - 0, FB_VMODE_NONINTERLACED
13440 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13442 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
13443 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
13444 - 0, FB_VMODE_NONINTERLACED
13445 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13447 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
13448 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
13449 - 0, FB_VMODE_NONINTERLACED
13450 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13452 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
13453 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
13454 - 0, FB_VMODE_INTERLACED
13455 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13457 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
13458 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
13459 - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13460 + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13462 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
13463 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
13464 - 0, FB_VMODE_NONINTERLACED
13465 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13467 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
13468 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
13469 - 0, FB_VMODE_NONINTERLACED
13470 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13472 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
13473 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
13474 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13475 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13477 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
13478 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
13479 - 0, FB_VMODE_NONINTERLACED
13480 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13482 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
13483 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
13484 - 0, FB_VMODE_INTERLACED
13485 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13487 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
13488 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
13489 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13490 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13492 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
13493 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
13494 - 0, FB_VMODE_NONINTERLACED
13495 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13497 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
13498 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
13499 - 0, FB_VMODE_NONINTERLACED
13500 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13502 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
13503 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
13504 - 0, FB_VMODE_NONINTERLACED
13505 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13507 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
13508 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
13509 - 0, FB_VMODE_NONINTERLACED
13510 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13512 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
13513 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
13514 - 0, FB_VMODE_NONINTERLACED
13515 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13517 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
13518 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
13519 - 0, FB_VMODE_INTERLACED
13520 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13522 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
13523 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
13524 - 0, FB_VMODE_NONINTERLACED
13525 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13527 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
13528 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
13529 - 0, FB_VMODE_NONINTERLACED
13530 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13532 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
13533 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
13534 - 0, FB_VMODE_NONINTERLACED
13535 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13537 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
13538 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
13539 - 0, FB_VMODE_NONINTERLACED
13540 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13542 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
13543 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
13544 - 0, FB_VMODE_NONINTERLACED
13545 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13547 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
13548 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
13549 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13550 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13552 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
13553 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
13554 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13555 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13557 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
13558 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
13559 - 0, FB_VMODE_NONINTERLACED
13560 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13562 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
13563 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
13564 - 0, FB_VMODE_NONINTERLACED
13565 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13567 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
13568 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
13569 - 0, FB_VMODE_NONINTERLACED
13570 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13572 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
13573 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
13574 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13575 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13577 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
13578 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
13579 - 0, FB_VMODE_NONINTERLACED
13580 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13582 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
13583 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
13584 - 0, FB_VMODE_NONINTERLACED
13585 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13587 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
13588 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
13589 - 0, FB_VMODE_NONINTERLACED
13590 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13592 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
13593 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
13594 - 0, FB_VMODE_NONINTERLACED
13595 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13597 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
13598 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
13599 - 0, FB_VMODE_NONINTERLACED
13600 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13602 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
13603 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
13604 - 0, FB_VMODE_NONINTERLACED
13605 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13607 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
13608 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
13609 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13610 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13612 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
13613 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
13614 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13615 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13617 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
13618 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
13619 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13620 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13622 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
13623 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
13624 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13625 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13627 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
13628 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
13629 - 0, FB_VMODE_NONINTERLACED
13630 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13632 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
13633 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
13634 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13635 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13637 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
13638 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
13639 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13640 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13642 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
13643 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
13644 - 0, FB_VMODE_NONINTERLACED
13645 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13647 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
13648 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
13649 - 0, FB_VMODE_NONINTERLACED
13650 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13652 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
13653 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
13654 - 0, FB_VMODE_DOUBLE
13655 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13657 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
13658 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
13659 - 0, FB_VMODE_DOUBLE
13660 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13662 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
13663 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
13664 - 0, FB_VMODE_DOUBLE
13665 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13667 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
13668 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
13669 - 0, FB_VMODE_DOUBLE
13670 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13672 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
13673 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
13674 - 0, FB_VMODE_DOUBLE
13675 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13677 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
13678 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
13679 - 0, FB_VMODE_DOUBLE
13680 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13682 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
13683 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
13684 - 0, FB_VMODE_DOUBLE
13685 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13687 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
13688 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
13689 - 0, FB_VMODE_DOUBLE
13690 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13692 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
13693 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
13694 - 0, FB_VMODE_DOUBLE
13695 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13697 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
13698 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
13699 - 0, FB_VMODE_DOUBLE
13700 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13702 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
13703 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
13704 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
13705 - FB_VMODE_NONINTERLACED
13706 + FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13708 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
13709 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
13710 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13711 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13713 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
13714 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
13715 - 0, FB_VMODE_NONINTERLACED
13716 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13718 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
13719 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
13720 - 0, FB_VMODE_NONINTERLACED
13721 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13725 diff -urNp linux-2.6.27.10/drivers/video/uvesafb.c linux-2.6.27.10/drivers/video/uvesafb.c
13726 --- linux-2.6.27.10/drivers/video/uvesafb.c 2008-11-07 12:55:34.000000000 -0500
13727 +++ linux-2.6.27.10/drivers/video/uvesafb.c 2008-11-18 03:38:45.000000000 -0500
13729 #include <linux/fb.h>
13730 #include <linux/io.h>
13731 #include <linux/mutex.h>
13732 +#include <linux/moduleloader.h>
13733 #include <video/edid.h>
13734 #include <video/uvesafb.h>
13736 @@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
13740 - return call_usermodehelper(v86d_path, argv, envp, 1);
13741 + return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
13745 @@ -569,10 +570,34 @@ static int __devinit uvesafb_vbe_getpmi(
13746 if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
13747 par->pmi_setpal = par->ypan = 0;
13750 +#ifdef CONFIG_PAX_KERNEXEC
13751 +#ifdef CONFIG_MODULES
13752 + unsigned long cr0;
13754 + par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
13756 + if (!par->pmi_code) {
13757 + par->pmi_setpal = par->ypan = 0;
13762 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
13763 + task->t.regs.edi);
13765 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13766 + pax_open_kernel(cr0);
13767 + memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
13768 + pax_close_kernel(cr0);
13770 + par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
13771 + par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
13773 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
13774 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
13777 printk(KERN_INFO "uvesafb: protected mode interface info at "
13779 (u16)task->t.regs.es, (u16)task->t.regs.edi);
13780 @@ -1827,6 +1852,11 @@ out:
13781 if (par->vbe_modes)
13782 kfree(par->vbe_modes);
13784 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13785 + if (par->pmi_code)
13786 + module_free_exec(NULL, par->pmi_code);
13789 framebuffer_release(info);
13792 @@ -1853,6 +1883,12 @@ static int uvesafb_remove(struct platfor
13793 kfree(par->vbe_state_orig);
13794 if (par->vbe_state_saved)
13795 kfree(par->vbe_state_saved);
13797 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13798 + if (par->pmi_code)
13799 + module_free_exec(NULL, par->pmi_code);
13804 framebuffer_release(info);
13805 diff -urNp linux-2.6.27.10/drivers/video/vesafb.c linux-2.6.27.10/drivers/video/vesafb.c
13806 --- linux-2.6.27.10/drivers/video/vesafb.c 2008-11-07 12:55:34.000000000 -0500
13807 +++ linux-2.6.27.10/drivers/video/vesafb.c 2008-11-18 03:38:45.000000000 -0500
13811 #include <linux/module.h>
13812 +#include <linux/moduleloader.h>
13813 #include <linux/kernel.h>
13814 #include <linux/errno.h>
13815 #include <linux/string.h>
13816 @@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
13817 static int vram_total __initdata; /* Set total amount of memory */
13818 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
13819 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
13820 -static void (*pmi_start)(void) __read_mostly;
13821 -static void (*pmi_pal) (void) __read_mostly;
13822 +static void (*pmi_start)(void) __read_only;
13823 +static void (*pmi_pal) (void) __read_only;
13824 static int depth __read_mostly;
13825 static int vga_compat __read_mostly;
13826 /* --------------------------------------------------------------------- */
13827 @@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
13828 unsigned int size_vmode;
13829 unsigned int size_remap;
13830 unsigned int size_total;
13831 + void *pmi_code = NULL;
13833 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
13835 @@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
13836 size_remap = size_total;
13837 vesafb_fix.smem_len = size_remap;
13840 - screen_info.vesapm_seg = 0;
13843 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
13844 printk(KERN_WARNING
13845 "vesafb: cannot reserve video memory at 0x%lx\n",
13846 @@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
13847 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
13848 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
13852 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13853 + pmi_code = module_alloc_exec(screen_info.vesapm_size);
13855 +#elif !defined(CONFIG_PAX_KERNEXEC)
13860 + screen_info.vesapm_seg = 0;
13862 if (screen_info.vesapm_seg) {
13863 - printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
13864 - screen_info.vesapm_seg,screen_info.vesapm_off);
13865 + printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
13866 + screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
13869 if (screen_info.vesapm_seg < 0xc000)
13870 @@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
13872 if (ypan || pmi_setpal) {
13873 unsigned short *pmi_base;
13874 - pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13875 - pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
13876 - pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
13878 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13879 + unsigned long cr0;
13882 + pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13884 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13885 + pax_open_kernel(cr0);
13886 + memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
13888 + pmi_code = pmi_base;
13891 + pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
13892 + pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
13894 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13895 + pmi_start = ktva_ktla(pmi_start);
13896 + pmi_pal = ktva_ktla(pmi_pal);
13897 + pax_close_kernel(cr0);
13900 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
13902 printk(KERN_INFO "vesafb: pmi: ports = ");
13903 @@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
13904 info->node, info->fix.id);
13908 +#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13909 + module_free_exec(NULL, pmi_code);
13912 if (info->screen_base)
13913 iounmap(info->screen_base);
13914 framebuffer_release(info);
13915 diff -urNp linux-2.6.27.10/fs/9p/vfs_inode.c linux-2.6.27.10/fs/9p/vfs_inode.c
13916 --- linux-2.6.27.10/fs/9p/vfs_inode.c 2008-11-07 12:55:34.000000000 -0500
13917 +++ linux-2.6.27.10/fs/9p/vfs_inode.c 2008-11-18 03:38:45.000000000 -0500
13918 @@ -1021,7 +1021,7 @@ static void *v9fs_vfs_follow_link(struct
13920 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
13922 - char *s = nd_get_link(nd);
13923 + const char *s = nd_get_link(nd);
13925 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
13927 diff -urNp linux-2.6.27.10/fs/aio.c linux-2.6.27.10/fs/aio.c
13928 --- linux-2.6.27.10/fs/aio.c 2008-11-07 12:55:34.000000000 -0500
13929 +++ linux-2.6.27.10/fs/aio.c 2008-11-18 03:38:45.000000000 -0500
13930 @@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
13931 size += sizeof(struct io_event) * nr_events;
13932 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
13934 - if (nr_pages < 0)
13935 + if (nr_pages <= 0)
13938 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
13939 diff -urNp linux-2.6.27.10/fs/autofs4/symlink.c linux-2.6.27.10/fs/autofs4/symlink.c
13940 --- linux-2.6.27.10/fs/autofs4/symlink.c 2008-11-07 12:55:34.000000000 -0500
13941 +++ linux-2.6.27.10/fs/autofs4/symlink.c 2008-11-18 03:38:45.000000000 -0500
13943 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
13945 struct autofs_info *ino = autofs4_dentry_ino(dentry);
13946 - nd_set_link(nd, (char *)ino->u.symlink);
13947 + nd_set_link(nd, ino->u.symlink);
13951 diff -urNp linux-2.6.27.10/fs/befs/linuxvfs.c linux-2.6.27.10/fs/befs/linuxvfs.c
13952 --- linux-2.6.27.10/fs/befs/linuxvfs.c 2008-11-07 12:55:34.000000000 -0500
13953 +++ linux-2.6.27.10/fs/befs/linuxvfs.c 2008-11-18 03:38:45.000000000 -0500
13954 @@ -490,7 +490,7 @@ static void befs_put_link(struct dentry
13956 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
13957 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
13958 - char *link = nd_get_link(nd);
13959 + const char *link = nd_get_link(nd);
13963 diff -urNp linux-2.6.27.10/fs/binfmt_aout.c linux-2.6.27.10/fs/binfmt_aout.c
13964 --- linux-2.6.27.10/fs/binfmt_aout.c 2008-11-07 12:55:34.000000000 -0500
13965 +++ linux-2.6.27.10/fs/binfmt_aout.c 2008-11-18 03:38:45.000000000 -0500
13967 #include <linux/personality.h>
13968 #include <linux/init.h>
13969 #include <linux/vs_memory.h>
13970 +#include <linux/grsecurity.h>
13972 #include <asm/system.h>
13973 #include <asm/uaccess.h>
13974 @@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
13975 /* If the size of the dump file exceeds the rlimit, then see what would happen
13976 if we wrote the stack, but not the data area. */
13978 + gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
13979 if ((dump.u_dsize + dump.u_ssize) > limit)
13982 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
13983 if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
13987 /* Make sure we have enough room to write the stack and data areas. */
13989 + gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
13990 if (dump.u_ssize > limit)
13993 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
13994 if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
13997 @@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
13998 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
13999 if (rlim >= RLIM_INFINITY)
14002 + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
14003 if (ex.a_data + ex.a_bss > rlim)
14006 @@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
14008 compute_creds(bprm);
14009 current->flags &= ~PF_FORKNOEXEC;
14011 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14012 + current->mm->pax_flags = 0UL;
14015 +#ifdef CONFIG_PAX_PAGEEXEC
14016 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
14017 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
14019 +#ifdef CONFIG_PAX_EMUTRAMP
14020 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
14021 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
14024 +#ifdef CONFIG_PAX_MPROTECT
14025 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
14026 + current->mm->pax_flags |= MF_PAX_MPROTECT;
14033 if (N_MAGIC(ex) == NMAGIC) {
14034 loff_t pos = fd_offset;
14035 @@ -413,7 +442,7 @@ static int load_aout_binary(struct linux
14037 down_write(¤t->mm->mmap_sem);
14038 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
14039 - PROT_READ | PROT_WRITE | PROT_EXEC,
14040 + PROT_READ | PROT_WRITE,
14041 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
14042 fd_offset + ex.a_text);
14043 up_write(¤t->mm->mmap_sem);
14044 diff -urNp linux-2.6.27.10/fs/binfmt_elf.c linux-2.6.27.10/fs/binfmt_elf.c
14045 --- linux-2.6.27.10/fs/binfmt_elf.c 2008-11-07 12:55:34.000000000 -0500
14046 +++ linux-2.6.27.10/fs/binfmt_elf.c 2008-12-21 00:51:06.000000000 -0500
14047 @@ -38,10 +38,16 @@
14048 #include <linux/elf.h>
14049 #include <linux/utsname.h>
14050 #include <linux/vs_memory.h>
14051 +#include <linux/grsecurity.h>
14053 #include <asm/uaccess.h>
14054 #include <asm/param.h>
14055 #include <asm/page.h>
14057 +#ifdef CONFIG_PAX_SEGMEXEC
14058 +#include <asm/desc.h>
14061 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
14062 static int load_elf_library(struct file *);
14063 static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
14064 @@ -57,6 +63,10 @@ static int elf_core_dump(long signr, str
14065 #define elf_core_dump NULL
14068 +#ifdef CONFIG_PAX_MPROTECT
14069 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags);
14072 #if ELF_EXEC_PAGESIZE > PAGE_SIZE
14073 #define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE
14075 @@ -76,6 +86,11 @@ static struct linux_binfmt elf_format =
14076 .load_binary = load_elf_binary,
14077 .load_shlib = load_elf_library,
14078 .core_dump = elf_core_dump,
14080 +#ifdef CONFIG_PAX_MPROTECT
14081 + .handle_mprotect= elf_handle_mprotect,
14084 .min_coredump = ELF_EXEC_PAGESIZE,
14087 @@ -84,6 +99,8 @@ static struct linux_binfmt elf_format =
14089 static int set_brk(unsigned long start, unsigned long end)
14091 + unsigned long e = end;
14093 start = ELF_PAGEALIGN(start);
14094 end = ELF_PAGEALIGN(end);
14096 @@ -94,7 +111,7 @@ static int set_brk(unsigned long start,
14097 if (BAD_ADDR(addr))
14100 - current->mm->start_brk = current->mm->brk = end;
14101 + current->mm->start_brk = current->mm->brk = e;
14105 @@ -380,10 +397,10 @@ static unsigned long load_elf_interp(str
14107 struct elf_phdr *elf_phdata;
14108 struct elf_phdr *eppnt;
14109 - unsigned long load_addr = 0;
14110 + unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
14111 int load_addr_set = 0;
14112 unsigned long last_bss = 0, elf_bss = 0;
14113 - unsigned long error = ~0UL;
14114 + unsigned long error = -EINVAL;
14115 unsigned long total_size;
14116 int retval, i, size;
14118 @@ -429,6 +446,11 @@ static unsigned long load_elf_interp(str
14122 +#ifdef CONFIG_PAX_SEGMEXEC
14123 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
14124 + pax_task_size = SEGMEXEC_TASK_SIZE;
14127 eppnt = elf_phdata;
14128 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
14129 if (eppnt->p_type == PT_LOAD) {
14130 @@ -472,8 +494,8 @@ static unsigned long load_elf_interp(str
14131 k = load_addr + eppnt->p_vaddr;
14133 eppnt->p_filesz > eppnt->p_memsz ||
14134 - eppnt->p_memsz > TASK_SIZE ||
14135 - TASK_SIZE - eppnt->p_memsz < k) {
14136 + eppnt->p_memsz > pax_task_size ||
14137 + pax_task_size - eppnt->p_memsz < k) {
14141 @@ -527,6 +549,177 @@ out:
14145 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
14146 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
14148 + unsigned long pax_flags = 0UL;
14150 +#ifdef CONFIG_PAX_PAGEEXEC
14151 + if (elf_phdata->p_flags & PF_PAGEEXEC)
14152 + pax_flags |= MF_PAX_PAGEEXEC;
14155 +#ifdef CONFIG_PAX_SEGMEXEC
14156 + if (elf_phdata->p_flags & PF_SEGMEXEC)
14157 + pax_flags |= MF_PAX_SEGMEXEC;
14160 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14161 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14163 + pax_flags &= ~MF_PAX_SEGMEXEC;
14165 + pax_flags &= ~MF_PAX_PAGEEXEC;
14169 +#ifdef CONFIG_PAX_EMUTRAMP
14170 + if (elf_phdata->p_flags & PF_EMUTRAMP)
14171 + pax_flags |= MF_PAX_EMUTRAMP;
14174 +#ifdef CONFIG_PAX_MPROTECT
14175 + if (elf_phdata->p_flags & PF_MPROTECT)
14176 + pax_flags |= MF_PAX_MPROTECT;
14179 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14180 + if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
14181 + pax_flags |= MF_PAX_RANDMMAP;
14184 + return pax_flags;
14188 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14189 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
14191 + unsigned long pax_flags = 0UL;
14193 +#ifdef CONFIG_PAX_PAGEEXEC
14194 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
14195 + pax_flags |= MF_PAX_PAGEEXEC;
14198 +#ifdef CONFIG_PAX_SEGMEXEC
14199 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
14200 + pax_flags |= MF_PAX_SEGMEXEC;
14203 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14204 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14206 + pax_flags &= ~MF_PAX_SEGMEXEC;
14208 + pax_flags &= ~MF_PAX_PAGEEXEC;
14212 +#ifdef CONFIG_PAX_EMUTRAMP
14213 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
14214 + pax_flags |= MF_PAX_EMUTRAMP;
14217 +#ifdef CONFIG_PAX_MPROTECT
14218 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
14219 + pax_flags |= MF_PAX_MPROTECT;
14222 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14223 + if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
14224 + pax_flags |= MF_PAX_RANDMMAP;
14227 + return pax_flags;
14231 +#ifdef CONFIG_PAX_EI_PAX
14232 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
14234 + unsigned long pax_flags = 0UL;
14236 +#ifdef CONFIG_PAX_PAGEEXEC
14237 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
14238 + pax_flags |= MF_PAX_PAGEEXEC;
14241 +#ifdef CONFIG_PAX_SEGMEXEC
14242 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
14243 + pax_flags |= MF_PAX_SEGMEXEC;
14246 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14247 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14249 + pax_flags &= ~MF_PAX_SEGMEXEC;
14251 + pax_flags &= ~MF_PAX_PAGEEXEC;
14255 +#ifdef CONFIG_PAX_EMUTRAMP
14256 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
14257 + pax_flags |= MF_PAX_EMUTRAMP;
14260 +#ifdef CONFIG_PAX_MPROTECT
14261 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
14262 + pax_flags |= MF_PAX_MPROTECT;
14265 +#ifdef CONFIG_PAX_ASLR
14266 + if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
14267 + pax_flags |= MF_PAX_RANDMMAP;
14270 + return pax_flags;
14274 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14275 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
14277 + unsigned long pax_flags = 0UL;
14279 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14283 +#ifdef CONFIG_PAX_EI_PAX
14284 + pax_flags = pax_parse_ei_pax(elf_ex);
14287 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14288 + for (i = 0UL; i < elf_ex->e_phnum; i++)
14289 + if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
14290 + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
14291 + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
14292 + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
14293 + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
14294 + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
14297 +#ifdef CONFIG_PAX_SOFTMODE
14298 + if (pax_softmode)
14299 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
14303 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
14308 + if (0 > pax_check_flags(&pax_flags))
14311 + current->mm->pax_flags = pax_flags;
14317 * These are the functions used to load ELF style executables and shared
14318 * libraries. There is no binary dependent code anywhere else.
14319 @@ -543,6 +736,11 @@ static unsigned long randomize_stack_top
14321 unsigned int random_variable = 0;
14323 +#ifdef CONFIG_PAX_RANDUSTACK
14324 + if (randomize_va_space)
14325 + return stack_top - current->mm->delta_stack;
14328 if ((current->flags & PF_RANDOMIZE) &&
14329 !(current->personality & ADDR_NO_RANDOMIZE)) {
14330 random_variable = get_random_int() & STACK_RND_MASK;
14331 @@ -561,7 +759,7 @@ static int load_elf_binary(struct linux_
14332 unsigned long load_addr = 0, load_bias = 0;
14333 int load_addr_set = 0;
14334 char * elf_interpreter = NULL;
14335 - unsigned long error;
14336 + unsigned long error = 0;
14337 struct elf_phdr *elf_ppnt, *elf_phdata;
14338 unsigned long elf_bss, elf_brk;
14339 int elf_exec_fileno;
14340 @@ -572,11 +770,11 @@ static int load_elf_binary(struct linux_
14341 unsigned long start_code, end_code, start_data, end_data;
14342 unsigned long reloc_func_desc = 0;
14343 int executable_stack = EXSTACK_DEFAULT;
14344 - unsigned long def_flags = 0;
14346 struct elfhdr elf_ex;
14347 struct elfhdr interp_elf_ex;
14349 + unsigned long pax_task_size = TASK_SIZE;
14351 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
14353 @@ -744,11 +942,80 @@ static int load_elf_binary(struct linux_
14355 /* OK, This is the point of no return */
14356 current->flags &= ~PF_FORKNOEXEC;
14357 - current->mm->def_flags = def_flags;
14359 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14360 + current->mm->pax_flags = 0UL;
14363 +#ifdef CONFIG_PAX_DLRESOLVE
14364 + current->mm->call_dl_resolve = 0UL;
14367 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
14368 + current->mm->call_syscall = 0UL;
14371 +#ifdef CONFIG_PAX_ASLR
14372 + current->mm->delta_mmap = 0UL;
14373 + current->mm->delta_stack = 0UL;
14376 + current->mm->def_flags = 0;
14378 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14379 + if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
14380 + send_sig(SIGKILL, current, 0);
14381 + goto out_free_dentry;
14385 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14386 + pax_set_initial_flags(bprm);
14387 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
14388 + if (pax_set_initial_flags_func)
14389 + (pax_set_initial_flags_func)(bprm);
14392 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14393 + if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
14394 + current->mm->context.user_cs_limit = PAGE_SIZE;
14395 + current->mm->def_flags |= VM_PAGEEXEC;
14399 +#ifdef CONFIG_PAX_SEGMEXEC
14400 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
14401 + current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
14402 + current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
14403 + pax_task_size = SEGMEXEC_TASK_SIZE;
14407 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
14408 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14409 + set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
14410 + put_cpu_no_resched();
14414 +#ifdef CONFIG_PAX_ASLR
14415 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
14416 + current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
14417 + current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
14421 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
14422 may depend on the personality. */
14423 SET_PERSONALITY(loc->elf_ex, 0);
14425 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14426 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14427 + executable_stack = EXSTACK_DISABLE_X;
14428 + current->personality &= ~READ_IMPLIES_EXEC;
14432 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
14433 current->personality |= READ_IMPLIES_EXEC;
14435 @@ -829,6 +1096,20 @@ static int load_elf_binary(struct linux_
14437 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
14440 +#ifdef CONFIG_PAX_RANDMMAP
14441 + /* PaX: randomize base address at the default exe base if requested */
14442 + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
14443 +#ifdef CONFIG_SPARC64
14444 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
14446 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
14448 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
14449 + elf_flags |= MAP_FIXED;
14455 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
14456 @@ -861,9 +1142,9 @@ static int load_elf_binary(struct linux_
14457 * allowed task size. Note that p_filesz must always be
14458 * <= p_memsz so it is only necessary to check p_memsz.
14460 - if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14461 - elf_ppnt->p_memsz > TASK_SIZE ||
14462 - TASK_SIZE - elf_ppnt->p_memsz < k) {
14463 + if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14464 + elf_ppnt->p_memsz > pax_task_size ||
14465 + pax_task_size - elf_ppnt->p_memsz < k) {
14466 /* set_brk can never work. Avoid overflows. */
14467 send_sig(SIGKILL, current, 0);
14469 @@ -891,6 +1172,11 @@ static int load_elf_binary(struct linux_
14470 start_data += load_bias;
14471 end_data += load_bias;
14473 +#ifdef CONFIG_PAX_RANDMMAP
14474 + if (current->mm->pax_flags & MF_PAX_RANDMMAP)
14475 + elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
14478 /* Calling set_brk effectively mmaps the pages that we need
14479 * for the bss and break sections. We must do this before
14480 * mapping in the interpreter, to make sure it doesn't wind
14481 @@ -902,9 +1188,11 @@ static int load_elf_binary(struct linux_
14482 goto out_free_dentry;
14484 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
14485 - send_sig(SIGSEGV, current, 0);
14486 - retval = -EFAULT; /* Nobody gets to see this, but.. */
14487 - goto out_free_dentry;
14489 + * This bss-zeroing can fail if the ELF
14490 + * file specifies odd protections. So
14491 + * we don't check the return value
14495 if (elf_interpreter) {
14496 @@ -1141,8 +1429,10 @@ static int dump_seek(struct file *file,
14497 unsigned long n = off;
14500 - if (!dump_write(file, buf, n))
14501 + if (!dump_write(file, buf, n)) {
14502 + free_page((unsigned long)buf);
14507 free_page((unsigned long)buf);
14508 @@ -1154,7 +1444,7 @@ static int dump_seek(struct file *file,
14509 * Decide what to dump of a segment, part, all or none.
14511 static unsigned long vma_dump_size(struct vm_area_struct *vma,
14512 - unsigned long mm_flags)
14513 + unsigned long mm_flags, long signr)
14515 /* The vma can be set up to tell us the answer directly. */
14516 if (vma->vm_flags & VM_ALWAYSDUMP)
14517 @@ -1180,7 +1470,7 @@ static unsigned long vma_dump_size(struc
14518 if (vma->vm_file == NULL)
14521 - if (FILTER(MAPPED_PRIVATE))
14522 + if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
14526 @@ -1266,8 +1556,11 @@ static int writenote(struct memelfnote *
14529 #define DUMP_WRITE(addr, nr) \
14531 + gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
14532 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
14533 - goto end_coredump;
14534 + goto end_coredump; \
14536 #define DUMP_SEEK(off) \
14537 if (!dump_seek(file, (off))) \
14539 @@ -1973,7 +2266,7 @@ static int elf_core_dump(long signr, str
14540 phdr.p_offset = offset;
14541 phdr.p_vaddr = vma->vm_start;
14543 - phdr.p_filesz = vma_dump_size(vma, mm_flags);
14544 + phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
14545 phdr.p_memsz = vma->vm_end - vma->vm_start;
14546 offset += phdr.p_filesz;
14547 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
14548 @@ -2005,7 +2298,7 @@ static int elf_core_dump(long signr, str
14549 unsigned long addr;
14552 - end = vma->vm_start + vma_dump_size(vma, mm_flags);
14553 + end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
14555 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
14557 @@ -2025,6 +2318,7 @@ static int elf_core_dump(long signr, str
14558 flush_cache_page(tmp_vma, addr,
14559 page_to_pfn(page));
14560 kaddr = kmap(page);
14561 + gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
14562 if ((size += PAGE_SIZE) > limit ||
14563 !dump_write(file, kaddr,
14565 @@ -2055,6 +2349,99 @@ out:
14567 #endif /* USE_ELF_CORE_DUMP */
14569 +#ifdef CONFIG_PAX_MPROTECT
14570 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
14571 + * therefore we'll grant them VM_MAYWRITE once during their life. Similarly
14572 + * we'll remove VM_MAYWRITE for good on RELRO segments.
14574 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
14575 + * basis because we want to allow the common case and not the special ones.
14577 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags)
14579 + struct elfhdr elf_h;
14580 + struct elf_phdr elf_p;
14582 + unsigned long oldflags;
14583 + bool is_textrel_rw, is_textrel_rx, is_relro;
14585 + if (!(vma->vm_mm->pax_flags & MF_PAX_MPROTECT))
14588 + oldflags = vma->vm_flags & (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ);
14589 + newflags &= VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ;
14591 +#ifdef CONFIG_PAX_NOELFRELOCS
14592 + is_textrel_rw = false;
14593 + is_textrel_rx = false;
14595 + /* possible TEXTREL */
14596 + is_textrel_rw = vma->vm_file && !vma->anon_vma && !vma->vm_pgoff && oldflags == (VM_MAYEXEC | VM_MAYREAD | VM_EXEC | VM_READ) && newflags == (VM_WRITE | VM_READ);
14597 + is_textrel_rx = vma->vm_file && vma->anon_vma && !vma->vm_pgoff && oldflags == (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_WRITE | VM_READ) && newflags == (VM_EXEC | VM_READ);
14600 + /* possible RELRO */
14601 + is_relro = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ) && newflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ);
14603 + if (!is_textrel_rw && !is_textrel_rx && !is_relro)
14606 + if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
14607 + memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
14609 +#ifdef CONFIG_PAX_ETEXECRELOCS
14610 + ((is_textrel_rw || is_textrel_rx) && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
14612 + ((is_textrel_rw || is_textrel_rx) && elf_h.e_type != ET_DYN) ||
14615 + (is_relro && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
14616 + !elf_check_arch(&elf_h) ||
14617 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
14618 + elf_h.e_phnum > 65536UL / sizeof(struct elf_phdr))
14621 + for (i = 0UL; i < elf_h.e_phnum; i++) {
14622 + if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
14624 + switch (elf_p.p_type) {
14625 + case PT_DYNAMIC: {
14626 + elf_addr_t dyn_offset = 0UL;
14629 + if (!is_textrel_rw && !is_textrel_rx)
14631 + dyn_offset = elf_p.p_offset;
14634 + if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
14636 + if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
14637 + gr_log_textrel(vma);
14638 + if (is_textrel_rw)
14639 + vma->vm_flags |= VM_MAYWRITE;
14641 + /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
14642 + vma->vm_flags &= ~VM_MAYWRITE;
14646 + } while (dyn.d_tag != DT_NULL);
14650 + case PT_GNU_RELRO:
14653 + if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start) {
14654 + vma->vm_flags &= ~VM_MAYWRITE;
14662 static int __init init_elf_binfmt(void)
14664 return register_binfmt(&elf_format);
14665 diff -urNp linux-2.6.27.10/fs/binfmt_flat.c linux-2.6.27.10/fs/binfmt_flat.c
14666 --- linux-2.6.27.10/fs/binfmt_flat.c 2008-11-07 12:55:34.000000000 -0500
14667 +++ linux-2.6.27.10/fs/binfmt_flat.c 2008-11-18 03:38:45.000000000 -0500
14668 @@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
14669 realdatastart = (unsigned long) -ENOMEM;
14670 printk("Unable to allocate RAM for process data, errno %d\n",
14671 (int)-realdatastart);
14672 + down_write(¤t->mm->mmap_sem);
14673 do_munmap(current->mm, textpos, text_len);
14674 + up_write(¤t->mm->mmap_sem);
14675 ret = realdatastart;
14678 @@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
14680 if (result >= (unsigned long)-4096) {
14681 printk("Unable to read data+bss, errno %d\n", (int)-result);
14682 + down_write(¤t->mm->mmap_sem);
14683 do_munmap(current->mm, textpos, text_len);
14684 do_munmap(current->mm, realdatastart, data_len + extra);
14685 + up_write(¤t->mm->mmap_sem);
14689 @@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
14691 if (result >= (unsigned long)-4096) {
14692 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
14693 + down_write(¤t->mm->mmap_sem);
14694 do_munmap(current->mm, textpos, text_len + data_len + extra +
14695 MAX_SHARED_LIBS * sizeof(unsigned long));
14696 + up_write(¤t->mm->mmap_sem);
14700 diff -urNp linux-2.6.27.10/fs/binfmt_misc.c linux-2.6.27.10/fs/binfmt_misc.c
14701 --- linux-2.6.27.10/fs/binfmt_misc.c 2008-12-21 01:16:51.000000000 -0500
14702 +++ linux-2.6.27.10/fs/binfmt_misc.c 2008-12-21 01:13:46.000000000 -0500
14703 @@ -696,7 +696,7 @@ static int bm_fill_super(struct super_bl
14704 static struct tree_descr bm_files[] = {
14705 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
14706 [3] = {"register", &bm_register_operations, S_IWUSR},
14707 - /* last one */ {""}
14708 + /* last one */ {"", NULL, 0}
14710 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
14712 diff -urNp linux-2.6.27.10/fs/bio.c linux-2.6.27.10/fs/bio.c
14713 --- linux-2.6.27.10/fs/bio.c 2008-11-07 12:55:34.000000000 -0500
14714 +++ linux-2.6.27.10/fs/bio.c 2008-11-18 03:38:45.000000000 -0500
14715 @@ -507,7 +507,7 @@ static int __bio_copy_iov(struct bio *bi
14717 while (bv_len && iov_idx < iov_count) {
14718 unsigned int bytes;
14720 + char __user *iov_addr;
14722 bytes = min_t(unsigned int,
14723 iov[iov_idx].iov_len - iov_off, bv_len);
14724 diff -urNp linux-2.6.27.10/fs/buffer.c linux-2.6.27.10/fs/buffer.c
14725 --- linux-2.6.27.10/fs/buffer.c 2008-11-07 12:55:34.000000000 -0500
14726 +++ linux-2.6.27.10/fs/buffer.c 2008-11-18 03:38:45.000000000 -0500
14728 #include <linux/bitops.h>
14729 #include <linux/mpage.h>
14730 #include <linux/bit_spinlock.h>
14731 +#include <linux/grsecurity.h>
14733 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
14735 @@ -2249,6 +2250,7 @@ int generic_cont_expand_simple(struct in
14738 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
14739 + gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
14740 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
14741 send_sig(SIGXFSZ, current, 0);
14743 diff -urNp linux-2.6.27.10/fs/cifs/cifs_uniupr.h linux-2.6.27.10/fs/cifs/cifs_uniupr.h
14744 --- linux-2.6.27.10/fs/cifs/cifs_uniupr.h 2008-11-07 12:55:34.000000000 -0500
14745 +++ linux-2.6.27.10/fs/cifs/cifs_uniupr.h 2008-11-18 03:38:45.000000000 -0500
14746 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
14747 {0x0490, 0x04cc, UniCaseRangeU0490},
14748 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
14749 {0xff40, 0xff5a, UniCaseRangeUff40},
14755 diff -urNp linux-2.6.27.10/fs/cifs/link.c linux-2.6.27.10/fs/cifs/link.c
14756 --- linux-2.6.27.10/fs/cifs/link.c 2008-11-07 12:55:34.000000000 -0500
14757 +++ linux-2.6.27.10/fs/cifs/link.c 2008-11-18 03:38:45.000000000 -0500
14758 @@ -318,7 +318,7 @@ cifs_readlink(struct dentry *direntry, c
14760 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
14762 - char *p = nd_get_link(nd);
14763 + const char *p = nd_get_link(nd);
14767 diff -urNp linux-2.6.27.10/fs/compat.c linux-2.6.27.10/fs/compat.c
14768 --- linux-2.6.27.10/fs/compat.c 2008-11-07 12:55:34.000000000 -0500
14769 +++ linux-2.6.27.10/fs/compat.c 2008-11-18 03:38:45.000000000 -0500
14771 #include <linux/poll.h>
14772 #include <linux/mm.h>
14773 #include <linux/eventpoll.h>
14774 +#include <linux/grsecurity.h>
14776 #include <asm/uaccess.h>
14777 #include <asm/mmu_context.h>
14778 @@ -1298,14 +1299,12 @@ static int compat_copy_strings(int argc,
14779 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
14782 -#ifdef CONFIG_STACK_GROWSUP
14783 ret = expand_stack_downwards(bprm->vma, pos);
14785 /* We've exceed the stack rlimit. */
14790 ret = get_user_pages(current, bprm->mm, pos,
14791 1, 1, 1, &page, NULL);
14793 @@ -1351,6 +1350,11 @@ int compat_do_execve(char * filename,
14794 compat_uptr_t __user *envp,
14795 struct pt_regs * regs)
14797 +#ifdef CONFIG_GRKERNSEC
14798 + struct file *old_exec_file;
14799 + struct acl_subject_label *old_acl;
14800 + struct rlimit old_rlim[RLIM_NLIMITS];
14802 struct linux_binprm *bprm;
14805 @@ -1371,6 +1375,14 @@ int compat_do_execve(char * filename,
14806 bprm->filename = filename;
14807 bprm->interp = filename;
14809 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
14810 + retval = -EAGAIN;
14811 + if (gr_handle_nproc())
14813 + retval = -EACCES;
14814 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
14817 retval = bprm_mm_init(bprm);
14820 @@ -1404,8 +1416,36 @@ int compat_do_execve(char * filename,
14824 + if (!gr_tpe_allow(file)) {
14825 + retval = -EACCES;
14829 + if (gr_check_crash_exec(file)) {
14830 + retval = -EACCES;
14834 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14836 + gr_handle_exec_args(bprm, (char __user * __user *)argv);
14838 +#ifdef CONFIG_GRKERNSEC
14839 + old_acl = current->acl;
14840 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14841 + old_exec_file = current->exec_file;
14843 + current->exec_file = file;
14846 + gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14848 retval = search_binary_handler(bprm, regs);
14850 +#ifdef CONFIG_GRKERNSEC
14851 + if (old_exec_file)
14852 + fput(old_exec_file);
14854 /* execve success */
14855 security_bprm_free(bprm);
14856 acct_update_integrals(current);
14857 @@ -1413,6 +1453,13 @@ int compat_do_execve(char * filename,
14861 +#ifdef CONFIG_GRKERNSEC
14862 + current->acl = old_acl;
14863 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14864 + fput(current->exec_file);
14865 + current->exec_file = old_exec_file;
14869 if (bprm->security)
14870 security_bprm_free(bprm);
14871 diff -urNp linux-2.6.27.10/fs/compat_ioctl.c linux-2.6.27.10/fs/compat_ioctl.c
14872 --- linux-2.6.27.10/fs/compat_ioctl.c 2008-11-07 12:55:34.000000000 -0500
14873 +++ linux-2.6.27.10/fs/compat_ioctl.c 2008-11-18 03:38:45.000000000 -0500
14874 @@ -1831,15 +1831,15 @@ struct ioctl_trans {
14877 #define HANDLE_IOCTL(cmd,handler) \
14878 - { (cmd), (ioctl_trans_handler_t)(handler) },
14879 + { (cmd), (ioctl_trans_handler_t)(handler), NULL },
14881 /* pointer to compatible structure or no argument */
14882 #define COMPATIBLE_IOCTL(cmd) \
14883 - { (cmd), do_ioctl32_pointer },
14884 + { (cmd), do_ioctl32_pointer, NULL },
14886 /* argument is an unsigned long integer, not a pointer */
14887 #define ULONG_IOCTL(cmd) \
14888 - { (cmd), (ioctl_trans_handler_t)sys_ioctl },
14889 + { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
14891 /* ioctl should not be warned about even if it's not implemented.
14892 Valid reasons to use this:
14893 diff -urNp linux-2.6.27.10/fs/debugfs/inode.c linux-2.6.27.10/fs/debugfs/inode.c
14894 --- linux-2.6.27.10/fs/debugfs/inode.c 2008-11-07 12:55:34.000000000 -0500
14895 +++ linux-2.6.27.10/fs/debugfs/inode.c 2008-11-18 03:38:45.000000000 -0500
14896 @@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
14898 static int debug_fill_super(struct super_block *sb, void *data, int silent)
14900 - static struct tree_descr debug_files[] = {{""}};
14901 + static struct tree_descr debug_files[] = {{"", NULL, 0}};
14903 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
14905 diff -urNp linux-2.6.27.10/fs/exec.c linux-2.6.27.10/fs/exec.c
14906 --- linux-2.6.27.10/fs/exec.c 2008-12-21 01:16:51.000000000 -0500
14907 +++ linux-2.6.27.10/fs/exec.c 2008-12-21 01:13:46.000000000 -0500
14909 #include <linux/cn_proc.h>
14910 #include <linux/audit.h>
14911 #include <linux/tracehook.h>
14912 +#include <linux/random.h>
14913 +#include <linux/grsecurity.h>
14915 +#ifdef CONFIG_PAX_REFCOUNT
14916 +#include <linux/kallsyms.h>
14917 +#include <linux/kdebug.h>
14920 #include <asm/uaccess.h>
14921 #include <asm/mmu_context.h>
14923 #include <linux/a.out.h>
14926 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
14927 +void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
14928 +EXPORT_SYMBOL(pax_set_initial_flags_func);
14932 char core_pattern[CORENAME_MAX_SIZE] = "core";
14933 int suid_dumpable = 0;
14934 @@ -172,18 +184,10 @@ static struct page *get_arg_page(struct
14940 -#ifdef CONFIG_STACK_GROWSUP
14942 - ret = expand_stack_downwards(bprm->vma, pos);
14947 - ret = get_user_pages(current, bprm->mm, pos,
14948 - 1, write, 1, &page, NULL);
14950 + if (0 > expand_stack_downwards(bprm->vma, pos))
14952 + if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
14956 @@ -256,6 +260,11 @@ static int __bprm_mm_init(struct linux_b
14957 vma->vm_start = vma->vm_end - PAGE_SIZE;
14959 vma->vm_flags = VM_STACK_FLAGS;
14961 +#ifdef CONFIG_PAX_SEGMEXEC
14962 + vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
14965 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
14966 err = insert_vm_struct(mm, vma);
14968 @@ -268,6 +277,11 @@ static int __bprm_mm_init(struct linux_b
14970 bprm->p = vma->vm_end - sizeof(void *);
14972 +#ifdef CONFIG_PAX_RANDUSTACK
14973 + if (randomize_va_space)
14974 + bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
14980 @@ -391,7 +405,7 @@ static int count(char __user * __user *
14989 @@ -531,6 +545,10 @@ static int shift_arg_pages(struct vm_are
14990 if (vma != find_vma(mm, new_start))
14993 +#ifdef CONFIG_PAX_SEGMEXEC
14994 + BUG_ON(pax_find_mirror_vma(vma));
14998 * cover the whole range: [new_start, old_end)
15000 @@ -619,6 +637,14 @@ int setup_arg_pages(struct linux_binprm
15001 bprm->exec -= stack_shift;
15003 down_write(&mm->mmap_sem);
15005 + /* Move stack pages down in memory. */
15006 + if (stack_shift) {
15007 + ret = shift_arg_pages(vma, stack_shift);
15012 vm_flags = VM_STACK_FLAGS;
15015 @@ -632,21 +658,24 @@ int setup_arg_pages(struct linux_binprm
15016 vm_flags &= ~VM_EXEC;
15017 vm_flags |= mm->def_flags;
15019 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15020 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
15021 + vm_flags &= ~VM_EXEC;
15023 +#ifdef CONFIG_PAX_MPROTECT
15024 + if (mm->pax_flags & MF_PAX_MPROTECT)
15025 + vm_flags &= ~VM_MAYEXEC;
15031 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
15035 BUG_ON(prev != vma);
15037 - /* Move stack pages down in memory. */
15038 - if (stack_shift) {
15039 - ret = shift_arg_pages(vma, stack_shift);
15041 - up_write(&mm->mmap_sem);
15046 #ifdef CONFIG_STACK_GROWSUP
15047 stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
15049 @@ -658,7 +687,7 @@ int setup_arg_pages(struct linux_binprm
15052 up_write(&mm->mmap_sem);
15056 EXPORT_SYMBOL(setup_arg_pages);
15058 @@ -1286,6 +1315,11 @@ int do_execve(char * filename,
15059 char __user *__user *envp,
15060 struct pt_regs * regs)
15062 +#ifdef CONFIG_GRKERNSEC
15063 + struct file *old_exec_file;
15064 + struct acl_subject_label *old_acl;
15065 + struct rlimit old_rlim[RLIM_NLIMITS];
15067 struct linux_binprm *bprm;
15069 struct files_struct *displaced;
15070 @@ -1305,6 +1339,20 @@ int do_execve(char * filename,
15074 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
15076 + if (gr_handle_nproc()) {
15077 + allow_write_access(file);
15082 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
15083 + allow_write_access(file);
15091 @@ -1344,9 +1392,39 @@ int do_execve(char * filename,
15095 + if (!gr_tpe_allow(file)) {
15096 + retval = -EACCES;
15100 + if (gr_check_crash_exec(file)) {
15101 + retval = -EACCES;
15105 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
15107 + gr_handle_exec_args(bprm, argv);
15109 +#ifdef CONFIG_GRKERNSEC
15110 + old_acl = current->acl;
15111 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
15112 + old_exec_file = current->exec_file;
15114 + current->exec_file = file;
15117 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
15121 current->flags &= ~PF_KTHREAD;
15122 retval = search_binary_handler(bprm,regs);
15124 +#ifdef CONFIG_GRKERNSEC
15125 + if (old_exec_file)
15126 + fput(old_exec_file);
15128 /* execve success */
15129 security_bprm_free(bprm);
15130 acct_update_integrals(current);
15131 @@ -1356,6 +1434,14 @@ int do_execve(char * filename,
15136 +#ifdef CONFIG_GRKERNSEC
15137 + current->acl = old_acl;
15138 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
15139 + fput(current->exec_file);
15140 + current->exec_file = old_exec_file;
15144 if (bprm->security)
15145 security_bprm_free(bprm);
15146 @@ -1519,6 +1605,125 @@ out:
15150 +int pax_check_flags(unsigned long *flags)
15154 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
15155 + if (*flags & MF_PAX_SEGMEXEC)
15157 + *flags &= ~MF_PAX_SEGMEXEC;
15158 + retval = -EINVAL;
15162 + if ((*flags & MF_PAX_PAGEEXEC)
15164 +#ifdef CONFIG_PAX_PAGEEXEC
15165 + && (*flags & MF_PAX_SEGMEXEC)
15170 + *flags &= ~MF_PAX_PAGEEXEC;
15171 + retval = -EINVAL;
15174 + if ((*flags & MF_PAX_MPROTECT)
15176 +#ifdef CONFIG_PAX_MPROTECT
15177 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15182 + *flags &= ~MF_PAX_MPROTECT;
15183 + retval = -EINVAL;
15186 + if ((*flags & MF_PAX_EMUTRAMP)
15188 +#ifdef CONFIG_PAX_EMUTRAMP
15189 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15194 + *flags &= ~MF_PAX_EMUTRAMP;
15195 + retval = -EINVAL;
15201 +EXPORT_SYMBOL(pax_check_flags);
15203 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15204 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
15206 + struct task_struct *tsk = current;
15207 + struct mm_struct *mm = current->mm;
15208 + char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
15209 + char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
15210 + char *path_exec = NULL;
15211 + char *path_fault = NULL;
15212 + unsigned long start = 0UL, end = 0UL, offset = 0UL;
15214 + if (buffer_exec && buffer_fault) {
15215 + struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
15217 + down_read(&mm->mmap_sem);
15219 + while (vma && (!vma_exec || !vma_fault)) {
15220 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
15222 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
15224 + vma = vma->vm_next;
15227 + path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
15228 + if (IS_ERR(path_exec))
15229 + path_exec = "<path too long>";
15232 + start = vma_fault->vm_start;
15233 + end = vma_fault->vm_end;
15234 + offset = vma_fault->vm_pgoff << PAGE_SHIFT;
15235 + if (vma_fault->vm_file) {
15236 + path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
15237 + if (IS_ERR(path_fault))
15238 + path_fault = "<path too long>";
15240 + path_fault = "<anonymous mapping>";
15242 + up_read(&mm->mmap_sem);
15244 + if (tsk->signal->curr_ip)
15245 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: execution attempt in: %s, %08lx-%08lx %08lx\n", NIPQUAD(tsk->signal->curr_ip), path_fault, start, end, offset);
15247 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
15248 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
15249 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
15250 + tsk->uid, tsk->euid, pc, sp);
15251 + free_page((unsigned long)buffer_exec);
15252 + free_page((unsigned long)buffer_fault);
15253 + pax_report_insns(pc, sp);
15254 + do_coredump(SIGKILL, SIGKILL, regs);
15258 +#ifdef CONFIG_PAX_REFCOUNT
15259 +void pax_report_refcount_overflow(struct pt_regs *regs)
15261 + printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
15262 + current->comm, task_pid_nr(current), current->uid, current->euid);
15263 + print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
15264 + show_registers(regs);
15265 + force_sig_specific(SIGKILL, current);
15269 static int zap_process(struct task_struct *start)
15271 struct task_struct *t;
15272 @@ -1765,6 +1970,10 @@ int do_coredump(long signr, int exit_cod
15274 clear_thread_flag(TIF_SIGPENDING);
15276 + if (signr == SIGKILL || signr == SIGILL)
15277 + gr_handle_brute_attach(current);
15278 + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
15281 * lock_kernel() because format_corename() is controlled by sysctl, which
15282 * uses lock_kernel()
15283 @@ -1785,6 +1994,8 @@ int do_coredump(long signr, int exit_cod
15286 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
15287 + if (!helper_argv)
15288 + goto fail_unlock;
15289 /* Terminate the string before the first option */
15290 delimit = strchr(corename, ' ');
15292 diff -urNp linux-2.6.27.10/fs/ext2/balloc.c linux-2.6.27.10/fs/ext2/balloc.c
15293 --- linux-2.6.27.10/fs/ext2/balloc.c 2008-12-10 22:35:37.000000000 -0500
15294 +++ linux-2.6.27.10/fs/ext2/balloc.c 2008-12-10 22:35:46.000000000 -0500
15295 @@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
15297 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
15298 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
15299 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
15300 + if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
15301 sbi->s_resuid != current->fsuid &&
15302 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
15304 diff -urNp linux-2.6.27.10/fs/ext3/balloc.c linux-2.6.27.10/fs/ext3/balloc.c
15305 --- linux-2.6.27.10/fs/ext3/balloc.c 2008-12-10 22:35:37.000000000 -0500
15306 +++ linux-2.6.27.10/fs/ext3/balloc.c 2008-12-10 22:35:46.000000000 -0500
15307 @@ -1435,14 +1435,14 @@ static int ext3_has_free_blocks(struct s
15308 DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
15310 cond = (free_blocks < root_blocks + 1 &&
15311 - !capable(CAP_SYS_RESOURCE) &&
15312 + !capable_nolog(CAP_SYS_RESOURCE) &&
15313 sbi->s_resuid != current->fsuid &&
15314 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
15316 vxdprintk(VXD_CBIT(dlim, 3),
15317 "ext3_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
15318 sb, free_blocks, root_blocks,
15319 - !capable(CAP_SYS_RESOURCE)?'1':'0',
15320 + !capable_nolog(CAP_SYS_RESOURCE)?'1':'0',
15321 sbi->s_resuid, current->fsuid, cond?0:1);
15323 return (cond ? 0 : 1);
15324 diff -urNp linux-2.6.27.10/fs/ext3/namei.c linux-2.6.27.10/fs/ext3/namei.c
15325 --- linux-2.6.27.10/fs/ext3/namei.c 2008-11-07 12:55:34.000000000 -0500
15326 +++ linux-2.6.27.10/fs/ext3/namei.c 2008-11-18 03:38:45.000000000 -0500
15327 @@ -1173,9 +1173,9 @@ static struct ext3_dir_entry_2 *do_split
15329 struct dx_map_entry *map;
15330 char *data1 = (*bh)->b_data, *data2;
15331 - unsigned split, move, size, i;
15332 + unsigned split, move, size;
15333 struct ext3_dir_entry_2 *de = NULL, *de2;
15337 bh2 = ext3_append (handle, dir, &newblock, &err);
15339 diff -urNp linux-2.6.27.10/fs/ext3/xattr.c linux-2.6.27.10/fs/ext3/xattr.c
15340 --- linux-2.6.27.10/fs/ext3/xattr.c 2008-11-07 12:55:34.000000000 -0500
15341 +++ linux-2.6.27.10/fs/ext3/xattr.c 2008-11-18 03:38:45.000000000 -0500
15346 -# define ea_idebug(f...)
15347 -# define ea_bdebug(f...)
15348 +# define ea_idebug(f...) do {} while (0)
15349 +# define ea_bdebug(f...) do {} while (0)
15352 static void ext3_xattr_cache_insert(struct buffer_head *);
15353 diff -urNp linux-2.6.27.10/fs/ext4/balloc.c linux-2.6.27.10/fs/ext4/balloc.c
15354 --- linux-2.6.27.10/fs/ext4/balloc.c 2008-11-07 12:55:34.000000000 -0500
15355 +++ linux-2.6.27.10/fs/ext4/balloc.c 2008-11-18 03:38:45.000000000 -0500
15356 @@ -1617,7 +1617,7 @@ ext4_fsblk_t ext4_has_free_blocks(struct
15358 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
15360 - if (!capable(CAP_SYS_RESOURCE) &&
15361 + if (!capable_nolog(CAP_SYS_RESOURCE) &&
15362 sbi->s_resuid != current->fsuid &&
15363 (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid)))
15364 root_blocks = ext4_r_blocks_count(sbi->s_es);
15365 diff -urNp linux-2.6.27.10/fs/ext4/namei.c linux-2.6.27.10/fs/ext4/namei.c
15366 --- linux-2.6.27.10/fs/ext4/namei.c 2008-11-07 12:55:34.000000000 -0500
15367 +++ linux-2.6.27.10/fs/ext4/namei.c 2008-11-18 03:38:45.000000000 -0500
15368 @@ -1176,9 +1176,9 @@ static struct ext4_dir_entry_2 *do_split
15370 struct dx_map_entry *map;
15371 char *data1 = (*bh)->b_data, *data2;
15372 - unsigned split, move, size, i;
15373 + unsigned split, move, size;
15374 struct ext4_dir_entry_2 *de = NULL, *de2;
15378 bh2 = ext4_append (handle, dir, &newblock, &err);
15380 diff -urNp linux-2.6.27.10/fs/fcntl.c linux-2.6.27.10/fs/fcntl.c
15381 --- linux-2.6.27.10/fs/fcntl.c 2008-12-21 01:16:51.000000000 -0500
15382 +++ linux-2.6.27.10/fs/fcntl.c 2008-12-21 01:14:31.000000000 -0500
15384 #include <linux/pid_namespace.h>
15385 #include <linux/smp_lock.h>
15386 #include <linux/vs_limit.h>
15387 +#include <linux/grsecurity.h>
15389 #include <asm/poll.h>
15390 #include <asm/siginfo.h>
15391 @@ -266,6 +267,7 @@ static long do_fcntl(int fd, unsigned in
15394 case F_DUPFD_CLOEXEC:
15395 + gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
15396 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15398 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
15399 @@ -410,7 +412,8 @@ static inline int sigio_perm(struct task
15400 return (((fown->euid == 0) ||
15401 (fown->euid == p->suid) || (fown->euid == p->uid) ||
15402 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
15403 - !security_file_send_sigiotask(p, fown, sig));
15404 + !security_file_send_sigiotask(p, fown, sig) &&
15405 + !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
15408 static void send_sigio_to_task(struct task_struct *p,
15409 diff -urNp linux-2.6.27.10/fs/file.c linux-2.6.27.10/fs/file.c
15410 --- linux-2.6.27.10/fs/file.c 2008-11-07 12:55:34.000000000 -0500
15411 +++ linux-2.6.27.10/fs/file.c 2008-11-18 03:38:45.000000000 -0500
15413 #include <linux/rcupdate.h>
15414 #include <linux/workqueue.h>
15415 #include <linux/vs_limit.h>
15416 +#include <linux/grsecurity.h>
15418 struct fdtable_defer {
15420 @@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi
15421 * N.B. For clone tasks sharing a files structure, this test
15422 * will limit the total number of files that can be opened.
15425 + gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
15426 if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15429 diff -urNp linux-2.6.27.10/fs/fuse/control.c linux-2.6.27.10/fs/fuse/control.c
15430 --- linux-2.6.27.10/fs/fuse/control.c 2008-11-07 12:55:34.000000000 -0500
15431 +++ linux-2.6.27.10/fs/fuse/control.c 2008-11-18 03:38:45.000000000 -0500
15432 @@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
15434 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
15436 - struct tree_descr empty_descr = {""};
15437 + struct tree_descr empty_descr = {"", NULL, 0};
15438 struct fuse_conn *fc;
15441 diff -urNp linux-2.6.27.10/fs/fuse/dir.c linux-2.6.27.10/fs/fuse/dir.c
15442 --- linux-2.6.27.10/fs/fuse/dir.c 2008-11-07 12:55:34.000000000 -0500
15443 +++ linux-2.6.27.10/fs/fuse/dir.c 2008-11-18 03:38:45.000000000 -0500
15444 @@ -1072,7 +1072,7 @@ static char *read_link(struct dentry *de
15448 -static void free_link(char *link)
15449 +static void free_link(const char *link)
15452 free_page((unsigned long) link);
15453 diff -urNp linux-2.6.27.10/fs/hfs/inode.c linux-2.6.27.10/fs/hfs/inode.c
15454 --- linux-2.6.27.10/fs/hfs/inode.c 2008-11-07 12:55:34.000000000 -0500
15455 +++ linux-2.6.27.10/fs/hfs/inode.c 2008-11-18 03:38:45.000000000 -0500
15456 @@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
15458 if (S_ISDIR(main_inode->i_mode)) {
15459 if (fd.entrylength < sizeof(struct hfs_cat_dir))
15462 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15463 sizeof(struct hfs_cat_dir));
15464 if (rec.type != HFS_CDR_DIR ||
15465 @@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
15466 sizeof(struct hfs_cat_file));
15468 if (fd.entrylength < sizeof(struct hfs_cat_file))
15471 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15472 sizeof(struct hfs_cat_file));
15473 if (rec.type != HFS_CDR_FIL ||
15474 diff -urNp linux-2.6.27.10/fs/hfsplus/inode.c linux-2.6.27.10/fs/hfsplus/inode.c
15475 --- linux-2.6.27.10/fs/hfsplus/inode.c 2008-11-07 12:55:34.000000000 -0500
15476 +++ linux-2.6.27.10/fs/hfsplus/inode.c 2008-11-18 03:38:45.000000000 -0500
15477 @@ -417,7 +417,7 @@ int hfsplus_cat_read_inode(struct inode
15478 struct hfsplus_cat_folder *folder = &entry.folder;
15480 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
15483 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15484 sizeof(struct hfsplus_cat_folder));
15485 hfsplus_get_perms(inode, &folder->permissions, 1);
15486 @@ -434,7 +434,7 @@ int hfsplus_cat_read_inode(struct inode
15487 struct hfsplus_cat_file *file = &entry.file;
15489 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
15492 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15493 sizeof(struct hfsplus_cat_file));
15495 @@ -490,7 +490,7 @@ int hfsplus_cat_write_inode(struct inode
15496 struct hfsplus_cat_folder *folder = &entry.folder;
15498 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
15501 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15502 sizeof(struct hfsplus_cat_folder));
15503 /* simple node checks? */
15504 @@ -512,7 +512,7 @@ int hfsplus_cat_write_inode(struct inode
15505 struct hfsplus_cat_file *file = &entry.file;
15507 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
15510 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15511 sizeof(struct hfsplus_cat_file));
15512 hfsplus_inode_write_fork(inode, &file->data_fork);
15513 diff -urNp linux-2.6.27.10/fs/jffs2/debug.h linux-2.6.27.10/fs/jffs2/debug.h
15514 --- linux-2.6.27.10/fs/jffs2/debug.h 2008-11-07 12:55:34.000000000 -0500
15515 +++ linux-2.6.27.10/fs/jffs2/debug.h 2008-11-18 03:38:45.000000000 -0500
15516 @@ -52,13 +52,13 @@
15517 #if CONFIG_JFFS2_FS_DEBUG > 0
15521 +#define D1(x) do {} while (0);
15524 #if CONFIG_JFFS2_FS_DEBUG > 1
15528 +#define D2(x) do {} while (0);
15531 /* The prefixes of JFFS2 messages */
15532 @@ -114,73 +114,73 @@
15533 #ifdef JFFS2_DBG_READINODE_MESSAGES
15534 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15536 -#define dbg_readinode(fmt, ...)
15537 +#define dbg_readinode(fmt, ...) do {} while (0)
15539 #ifdef JFFS2_DBG_READINODE2_MESSAGES
15540 #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15542 -#define dbg_readinode2(fmt, ...)
15543 +#define dbg_readinode2(fmt, ...) do {} while (0)
15546 /* Fragtree build debugging messages */
15547 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
15548 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15550 -#define dbg_fragtree(fmt, ...)
15551 +#define dbg_fragtree(fmt, ...) do {} while (0)
15553 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
15554 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15556 -#define dbg_fragtree2(fmt, ...)
15557 +#define dbg_fragtree2(fmt, ...) do {} while (0)
15560 /* Directory entry list manilulation debugging messages */
15561 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
15562 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15564 -#define dbg_dentlist(fmt, ...)
15565 +#define dbg_dentlist(fmt, ...) do {} while (0)
15568 /* Print the messages about manipulating node_refs */
15569 #ifdef JFFS2_DBG_NODEREF_MESSAGES
15570 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15572 -#define dbg_noderef(fmt, ...)
15573 +#define dbg_noderef(fmt, ...) do {} while (0)
15576 /* Manipulations with the list of inodes (JFFS2 inocache) */
15577 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
15578 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15580 -#define dbg_inocache(fmt, ...)
15581 +#define dbg_inocache(fmt, ...) do {} while (0)
15584 /* Summary debugging messages */
15585 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
15586 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15588 -#define dbg_summary(fmt, ...)
15589 +#define dbg_summary(fmt, ...) do {} while (0)
15592 /* File system build messages */
15593 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
15594 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15596 -#define dbg_fsbuild(fmt, ...)
15597 +#define dbg_fsbuild(fmt, ...) do {} while (0)
15600 /* Watch the object allocations */
15601 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
15602 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15604 -#define dbg_memalloc(fmt, ...)
15605 +#define dbg_memalloc(fmt, ...) do {} while (0)
15608 /* Watch the XATTR subsystem */
15609 #ifdef JFFS2_DBG_XATTR_MESSAGES
15610 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15612 -#define dbg_xattr(fmt, ...)
15613 +#define dbg_xattr(fmt, ...) do {} while (0)
15616 /* "Sanity" checks */
15617 diff -urNp linux-2.6.27.10/fs/jffs2/erase.c linux-2.6.27.10/fs/jffs2/erase.c
15618 --- linux-2.6.27.10/fs/jffs2/erase.c 2008-11-07 12:55:34.000000000 -0500
15619 +++ linux-2.6.27.10/fs/jffs2/erase.c 2008-11-18 03:38:45.000000000 -0500
15620 @@ -431,7 +431,8 @@ static void jffs2_mark_erased_block(stru
15621 struct jffs2_unknown_node marker = {
15622 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
15623 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15624 - .totlen = cpu_to_je32(c->cleanmarker_size)
15625 + .totlen = cpu_to_je32(c->cleanmarker_size),
15626 + .hdr_crc = cpu_to_je32(0)
15629 jffs2_prealloc_raw_node_refs(c, jeb, 1);
15630 diff -urNp linux-2.6.27.10/fs/jffs2/summary.h linux-2.6.27.10/fs/jffs2/summary.h
15631 --- linux-2.6.27.10/fs/jffs2/summary.h 2008-11-07 12:55:34.000000000 -0500
15632 +++ linux-2.6.27.10/fs/jffs2/summary.h 2008-11-18 03:38:45.000000000 -0500
15633 @@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
15635 #define jffs2_sum_active() (0)
15636 #define jffs2_sum_init(a) (0)
15637 -#define jffs2_sum_exit(a)
15638 -#define jffs2_sum_disable_collecting(a)
15639 +#define jffs2_sum_exit(a) do {} while (0)
15640 +#define jffs2_sum_disable_collecting(a) do {} while (0)
15641 #define jffs2_sum_is_disabled(a) (0)
15642 -#define jffs2_sum_reset_collected(a)
15643 +#define jffs2_sum_reset_collected(a) do {} while (0)
15644 #define jffs2_sum_add_kvec(a,b,c,d) (0)
15645 -#define jffs2_sum_move_collected(a,b)
15646 +#define jffs2_sum_move_collected(a,b) do {} while (0)
15647 #define jffs2_sum_write_sumnode(a) (0)
15648 -#define jffs2_sum_add_padding_mem(a,b)
15649 -#define jffs2_sum_add_inode_mem(a,b,c)
15650 -#define jffs2_sum_add_dirent_mem(a,b,c)
15651 -#define jffs2_sum_add_xattr_mem(a,b,c)
15652 -#define jffs2_sum_add_xref_mem(a,b,c)
15653 +#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
15654 +#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
15655 +#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
15656 +#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
15657 +#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
15658 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
15660 #endif /* CONFIG_JFFS2_SUMMARY */
15661 diff -urNp linux-2.6.27.10/fs/jffs2/wbuf.c linux-2.6.27.10/fs/jffs2/wbuf.c
15662 --- linux-2.6.27.10/fs/jffs2/wbuf.c 2008-11-07 12:55:34.000000000 -0500
15663 +++ linux-2.6.27.10/fs/jffs2/wbuf.c 2008-11-18 03:38:45.000000000 -0500
15664 @@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
15666 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
15667 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15668 - .totlen = constant_cpu_to_je32(8)
15669 + .totlen = constant_cpu_to_je32(8),
15670 + .hdr_crc = constant_cpu_to_je32(0)
15674 diff -urNp linux-2.6.27.10/fs/locks.c linux-2.6.27.10/fs/locks.c
15675 --- linux-2.6.27.10/fs/locks.c 2008-11-07 12:55:34.000000000 -0500
15676 +++ linux-2.6.27.10/fs/locks.c 2008-11-18 03:38:45.000000000 -0500
15677 @@ -2005,16 +2005,16 @@ void locks_remove_flock(struct file *fil
15680 if (filp->f_op && filp->f_op->flock) {
15681 - struct file_lock fl = {
15682 + struct file_lock flock = {
15683 .fl_pid = current->tgid,
15685 .fl_flags = FL_FLOCK,
15686 .fl_type = F_UNLCK,
15687 .fl_end = OFFSET_MAX,
15689 - filp->f_op->flock(filp, F_SETLKW, &fl);
15690 - if (fl.fl_ops && fl.fl_ops->fl_release_private)
15691 - fl.fl_ops->fl_release_private(&fl);
15692 + filp->f_op->flock(filp, F_SETLKW, &flock);
15693 + if (flock.fl_ops && flock.fl_ops->fl_release_private)
15694 + flock.fl_ops->fl_release_private(&flock);
15698 diff -urNp linux-2.6.27.10/fs/namei.c linux-2.6.27.10/fs/namei.c
15699 --- linux-2.6.27.10/fs/namei.c 2008-11-07 12:55:34.000000000 -0500
15700 +++ linux-2.6.27.10/fs/namei.c 2008-11-18 04:47:57.000000000 -0500
15702 #include <linux/vs_device.h>
15703 #include <linux/vs_context.h>
15704 #include <linux/pid_namespace.h>
15705 +#include <linux/grsecurity.h>
15707 #include <asm/uaccess.h>
15709 #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
15710 @@ -646,7 +648,7 @@ static __always_inline int __do_follow_l
15711 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
15712 error = PTR_ERR(cookie);
15713 if (!IS_ERR(cookie)) {
15714 - char *s = nd_get_link(nd);
15715 + const char *s = nd_get_link(nd);
15718 error = __vfs_follow_link(nd, s);
15719 @@ -677,6 +679,13 @@ static inline int do_follow_link(struct
15720 err = security_inode_follow_link(path->dentry, nd);
15724 + if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
15725 + path->dentry->d_inode, path->dentry, nd->path.mnt)) {
15730 current->link_count++;
15731 current->total_link_count++;
15733 @@ -1025,11 +1034,18 @@ return_reval:
15737 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
15738 + path_put(&nd->path);
15743 path_put_conditional(&next, nd);
15746 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
15749 path_put(&nd->path);
15752 @@ -1613,9 +1629,17 @@ static int __open_namei_create(struct na
15754 struct dentry *dir = nd->path.dentry;
15756 + if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
15758 + goto out_unlock_dput;
15761 if (!IS_POSIXACL(dir->d_inode))
15762 mode &= ~current->fs->umask;
15763 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
15765 + gr_handle_create(path->dentry, nd->path.mnt);
15767 mutex_unlock(&dir->d_inode->i_mutex);
15768 dput(nd->path.dentry);
15769 nd->path.dentry = path->dentry;
15770 @@ -1696,6 +1720,17 @@ struct file *do_filp_open(int dfd, const
15773 return ERR_PTR(error);
15775 + if (gr_handle_rawio(nd.path.dentry->d_inode)) {
15780 + if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
15788 @@ -1759,6 +1794,20 @@ do_last:
15790 * It already exists.
15793 + if (gr_handle_rawio(path.dentry->d_inode)) {
15795 + goto exit_mutex_unlock;
15797 + if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
15799 + goto exit_mutex_unlock;
15801 + if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
15803 + goto exit_mutex_unlock;
15806 mutex_unlock(&dir->d_inode->i_mutex);
15807 audit_inode(pathname, path.dentry);
15809 @@ -1843,6 +1892,13 @@ do_link:
15810 error = security_inode_follow_link(path.dentry, &nd);
15814 + if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
15815 + path.dentry, nd.path.mnt)) {
15820 error = __do_follow_link(&path, &nd);
15822 /* Does someone understand code flow here? Or it is only
15823 @@ -2015,9 +2071,21 @@ asmlinkage long sys_mknodat(int dfd, con
15824 error = may_mknod(mode);
15828 + if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
15833 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
15838 error = mnt_want_write(nd.path.mnt);
15842 switch (mode & S_IFMT) {
15843 case 0: case S_IFREG:
15844 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
15845 @@ -2031,6 +2099,9 @@ asmlinkage long sys_mknodat(int dfd, con
15848 mnt_drop_write(nd.path.mnt);
15851 + gr_handle_create(dentry, nd.path.mnt);
15855 @@ -2084,6 +2155,11 @@ asmlinkage long sys_mkdirat(int dfd, con
15856 if (IS_ERR(dentry))
15859 + if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
15864 if (!IS_POSIXACL(nd.path.dentry->d_inode))
15865 mode &= ~current->fs->umask;
15866 error = mnt_want_write(nd.path.mnt);
15867 @@ -2091,6 +2167,10 @@ asmlinkage long sys_mkdirat(int dfd, con
15869 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
15870 mnt_drop_write(nd.path.mnt);
15873 + gr_handle_create(dentry, nd.path.mnt);
15878 @@ -2172,6 +2252,8 @@ static long do_rmdir(int dfd, const char
15880 struct dentry *dentry;
15881 struct nameidata nd;
15882 + ino_t saved_ino = 0;
15883 + dev_t saved_dev = 0;
15885 error = user_path_parent(dfd, pathname, &nd, &name);
15887 @@ -2193,11 +2275,26 @@ static long do_rmdir(int dfd, const char
15888 error = PTR_ERR(dentry);
15889 if (IS_ERR(dentry))
15892 + if (dentry->d_inode != NULL) {
15893 + if (dentry->d_inode->i_nlink <= 1) {
15894 + saved_ino = dentry->d_inode->i_ino;
15895 + saved_dev = dentry->d_inode->i_sb->s_dev;
15898 + if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
15904 error = mnt_want_write(nd.path.mnt);
15907 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
15908 mnt_drop_write(nd.path.mnt);
15909 + if (!error && (saved_dev || saved_ino))
15910 + gr_handle_delete(saved_ino, saved_dev);
15914 @@ -2257,6 +2354,8 @@ static long do_unlinkat(int dfd, const c
15915 struct dentry *dentry;
15916 struct nameidata nd;
15917 struct inode *inode = NULL;
15918 + ino_t saved_ino = 0;
15919 + dev_t saved_dev = 0;
15921 error = user_path_parent(dfd, pathname, &nd, &name);
15923 @@ -2273,12 +2372,25 @@ static long do_unlinkat(int dfd, const c
15924 if (nd.last.name[nd.last.len])
15926 inode = dentry->d_inode;
15929 + if (inode->i_nlink <= 1) {
15930 + saved_ino = inode->i_ino;
15931 + saved_dev = inode->i_sb->s_dev;
15934 atomic_inc(&inode->i_count);
15936 + if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
15941 error = mnt_want_write(nd.path.mnt);
15944 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
15945 + if (!error && (saved_ino || saved_dev))
15946 + gr_handle_delete(saved_ino, saved_dev);
15947 mnt_drop_write(nd.path.mnt);
15950 @@ -2356,10 +2468,17 @@ asmlinkage long sys_symlinkat(const char
15951 if (IS_ERR(dentry))
15954 + if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
15959 error = mnt_want_write(nd.path.mnt);
15962 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
15964 + gr_handle_create(dentry, nd.path.mnt);
15965 mnt_drop_write(nd.path.mnt);
15968 @@ -2453,10 +2572,26 @@ asmlinkage long sys_linkat(int olddfd, c
15969 error = PTR_ERR(new_dentry);
15970 if (IS_ERR(new_dentry))
15973 + if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
15974 + old_path.dentry->d_inode,
15975 + old_path.dentry->d_inode->i_mode, to)) {
15980 + if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
15981 + old_path.dentry, old_path.mnt, to)) {
15986 error = mnt_want_write(nd.path.mnt);
15989 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
15991 + gr_handle_create(new_dentry, nd.path.mnt);
15992 mnt_drop_write(nd.path.mnt);
15995 @@ -2612,8 +2747,10 @@ int vfs_rename(struct inode *old_dir, st
15996 error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
15998 error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
16001 const char *new_name = old_dentry->d_name.name;
16003 fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
16004 new_dentry->d_inode, old_dentry);
16006 @@ -2685,11 +2822,21 @@ asmlinkage long sys_renameat(int olddfd,
16007 if (new_dentry == trap)
16010 + error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
16011 + old_dentry, old_dir->d_inode, oldnd.path.mnt,
16016 error = mnt_want_write(oldnd.path.mnt);
16019 error = vfs_rename(old_dir->d_inode, old_dentry,
16020 new_dir->d_inode, new_dentry);
16022 + gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
16023 + new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
16025 mnt_drop_write(oldnd.path.mnt);
16028 diff -urNp linux-2.6.27.10/fs/namespace.c linux-2.6.27.10/fs/namespace.c
16029 --- linux-2.6.27.10/fs/namespace.c 2008-11-18 11:38:40.000000000 -0500
16030 +++ linux-2.6.27.10/fs/namespace.c 2008-11-18 11:40:53.000000000 -0500
16032 #include <linux/vs_tag.h>
16033 #include <linux/vserver/space.h>
16034 #include <linux/vserver/global.h>
16035 +#include <linux/grsecurity.h>
16036 #include <asm/uaccess.h>
16037 #include <asm/unistd.h>
16039 @@ -1094,6 +1095,8 @@ static int do_umount(struct vfsmount *mn
16041 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
16044 + gr_log_remount(mnt->mnt_devname, retval);
16046 up_write(&sb->s_umount);
16048 @@ -1117,6 +1120,9 @@ static int do_umount(struct vfsmount *mn
16049 security_sb_umount_busy(mnt);
16050 up_write(&namespace_sem);
16051 release_mounts(&umount_list);
16053 + gr_log_unmount(mnt->mnt_devname, retval);
16058 @@ -1954,6 +1960,11 @@ long do_mount(char *dev_name, char *dir_
16062 + if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
16067 if (flags & MS_REMOUNT)
16068 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
16070 @@ -1968,6 +1979,9 @@ long do_mount(char *dev_name, char *dir_
16071 dev_name, data_page);
16073 path_put(&nd.path);
16075 + gr_log_mount(dev_name, dir_name, retval);
16080 @@ -2080,6 +2094,9 @@ asmlinkage long sys_mount(char __user *
16084 + if (gr_handle_chroot_pivot())
16088 retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
16089 flags, (void *)data_page);
16090 diff -urNp linux-2.6.27.10/fs/nfs/nfs4proc.c linux-2.6.27.10/fs/nfs/nfs4proc.c
16091 --- linux-2.6.27.10/fs/nfs/nfs4proc.c 2008-11-07 12:55:34.000000000 -0500
16092 +++ linux-2.6.27.10/fs/nfs/nfs4proc.c 2008-11-18 03:38:45.000000000 -0500
16093 @@ -653,7 +653,7 @@ static int _nfs4_do_open_reclaim(struct
16094 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
16096 struct nfs_server *server = NFS_SERVER(state->inode);
16097 - struct nfs4_exception exception = { };
16098 + struct nfs4_exception exception = {0, 0};
16101 err = _nfs4_do_open_reclaim(ctx, state);
16102 @@ -695,7 +695,7 @@ static int _nfs4_open_delegation_recall(
16104 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
16106 - struct nfs4_exception exception = { };
16107 + struct nfs4_exception exception = {0, 0};
16108 struct nfs_server *server = NFS_SERVER(state->inode);
16111 @@ -988,7 +988,7 @@ static int _nfs4_open_expired(struct nfs
16112 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
16114 struct nfs_server *server = NFS_SERVER(state->inode);
16115 - struct nfs4_exception exception = { };
16116 + struct nfs4_exception exception = {0, 0};
16120 @@ -1090,7 +1090,7 @@ out_err:
16122 static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
16124 - struct nfs4_exception exception = { };
16125 + struct nfs4_exception exception = {0, 0};
16126 struct nfs4_state *res;
16129 @@ -1181,7 +1181,7 @@ static int nfs4_do_setattr(struct inode
16130 struct nfs4_state *state)
16132 struct nfs_server *server = NFS_SERVER(inode);
16133 - struct nfs4_exception exception = { };
16134 + struct nfs4_exception exception = {0, 0};
16137 err = nfs4_handle_exception(server,
16138 @@ -1494,7 +1494,7 @@ static int _nfs4_server_capabilities(str
16140 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
16142 - struct nfs4_exception exception = { };
16143 + struct nfs4_exception exception = {0, 0};
16146 err = nfs4_handle_exception(server,
16147 @@ -1527,7 +1527,7 @@ static int _nfs4_lookup_root(struct nfs_
16148 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
16149 struct nfs_fsinfo *info)
16151 - struct nfs4_exception exception = { };
16152 + struct nfs4_exception exception = {0, 0};
16155 err = nfs4_handle_exception(server,
16156 @@ -1616,7 +1616,7 @@ static int _nfs4_proc_getattr(struct nfs
16158 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
16160 - struct nfs4_exception exception = { };
16161 + struct nfs4_exception exception = {0, 0};
16164 err = nfs4_handle_exception(server,
16165 @@ -1702,7 +1702,7 @@ static int nfs4_proc_lookupfh(struct nfs
16166 struct qstr *name, struct nfs_fh *fhandle,
16167 struct nfs_fattr *fattr)
16169 - struct nfs4_exception exception = { };
16170 + struct nfs4_exception exception = {0, 0};
16173 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
16174 @@ -1731,7 +1731,7 @@ static int _nfs4_proc_lookup(struct inod
16176 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
16178 - struct nfs4_exception exception = { };
16179 + struct nfs4_exception exception = {0, 0};
16182 err = nfs4_handle_exception(NFS_SERVER(dir),
16183 @@ -1795,7 +1795,7 @@ static int _nfs4_proc_access(struct inod
16185 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
16187 - struct nfs4_exception exception = { };
16188 + struct nfs4_exception exception = {0, 0};
16191 err = nfs4_handle_exception(NFS_SERVER(inode),
16192 @@ -1850,7 +1850,7 @@ static int _nfs4_proc_readlink(struct in
16193 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
16194 unsigned int pgbase, unsigned int pglen)
16196 - struct nfs4_exception exception = { };
16197 + struct nfs4_exception exception = {0, 0};
16200 err = nfs4_handle_exception(NFS_SERVER(inode),
16201 @@ -1947,7 +1947,7 @@ static int _nfs4_proc_remove(struct inod
16203 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
16205 - struct nfs4_exception exception = { };
16206 + struct nfs4_exception exception = {0, 0};
16209 err = nfs4_handle_exception(NFS_SERVER(dir),
16210 @@ -2019,7 +2019,7 @@ static int _nfs4_proc_rename(struct inod
16211 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
16212 struct inode *new_dir, struct qstr *new_name)
16214 - struct nfs4_exception exception = { };
16215 + struct nfs4_exception exception = {0, 0};
16218 err = nfs4_handle_exception(NFS_SERVER(old_dir),
16219 @@ -2066,7 +2066,7 @@ static int _nfs4_proc_link(struct inode
16221 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
16223 - struct nfs4_exception exception = { };
16224 + struct nfs4_exception exception = {0, 0};
16227 err = nfs4_handle_exception(NFS_SERVER(inode),
16228 @@ -2157,7 +2157,7 @@ out:
16229 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
16230 struct page *page, unsigned int len, struct iattr *sattr)
16232 - struct nfs4_exception exception = { };
16233 + struct nfs4_exception exception = {0, 0};
16236 err = nfs4_handle_exception(NFS_SERVER(dir),
16237 @@ -2188,7 +2188,7 @@ out:
16238 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
16239 struct iattr *sattr)
16241 - struct nfs4_exception exception = { };
16242 + struct nfs4_exception exception = {0, 0};
16245 err = nfs4_handle_exception(NFS_SERVER(dir),
16246 @@ -2237,7 +2237,7 @@ static int _nfs4_proc_readdir(struct den
16247 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
16248 u64 cookie, struct page *page, unsigned int count, int plus)
16250 - struct nfs4_exception exception = { };
16251 + struct nfs4_exception exception = {0, 0};
16254 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
16255 @@ -2285,7 +2285,7 @@ out:
16256 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
16257 struct iattr *sattr, dev_t rdev)
16259 - struct nfs4_exception exception = { };
16260 + struct nfs4_exception exception = {0, 0};
16263 err = nfs4_handle_exception(NFS_SERVER(dir),
16264 @@ -2314,7 +2314,7 @@ static int _nfs4_proc_statfs(struct nfs_
16266 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
16268 - struct nfs4_exception exception = { };
16269 + struct nfs4_exception exception = {0, 0};
16272 err = nfs4_handle_exception(server,
16273 @@ -2342,7 +2342,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
16275 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
16277 - struct nfs4_exception exception = { };
16278 + struct nfs4_exception exception = {0, 0};
16282 @@ -2385,7 +2385,7 @@ static int _nfs4_proc_pathconf(struct nf
16283 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
16284 struct nfs_pathconf *pathconf)
16286 - struct nfs4_exception exception = { };
16287 + struct nfs4_exception exception = {0, 0};
16291 @@ -2672,7 +2672,7 @@ out_free:
16293 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
16295 - struct nfs4_exception exception = { };
16296 + struct nfs4_exception exception = {0, 0};
16299 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
16300 @@ -2729,7 +2729,7 @@ static int __nfs4_proc_set_acl(struct in
16302 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
16304 - struct nfs4_exception exception = { };
16305 + struct nfs4_exception exception = {0, 0};
16308 err = nfs4_handle_exception(NFS_SERVER(inode),
16309 @@ -3020,7 +3020,7 @@ out:
16310 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
16312 struct nfs_server *server = NFS_SERVER(inode);
16313 - struct nfs4_exception exception = { };
16314 + struct nfs4_exception exception = {0, 0};
16317 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
16318 @@ -3095,7 +3095,7 @@ out:
16320 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16322 - struct nfs4_exception exception = { };
16323 + struct nfs4_exception exception = {0, 0};
16327 @@ -3445,7 +3445,7 @@ static int _nfs4_do_setlk(struct nfs4_st
16328 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
16330 struct nfs_server *server = NFS_SERVER(state->inode);
16331 - struct nfs4_exception exception = { };
16332 + struct nfs4_exception exception = {0, 0};
16336 @@ -3463,7 +3463,7 @@ static int nfs4_lock_reclaim(struct nfs4
16337 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
16339 struct nfs_server *server = NFS_SERVER(state->inode);
16340 - struct nfs4_exception exception = { };
16341 + struct nfs4_exception exception = {0, 0};
16344 err = nfs4_set_lock_state(state, request);
16345 @@ -3524,7 +3524,7 @@ out:
16347 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16349 - struct nfs4_exception exception = { };
16350 + struct nfs4_exception exception = {0, 0};
16354 @@ -3574,7 +3574,7 @@ nfs4_proc_lock(struct file *filp, int cm
16355 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
16357 struct nfs_server *server = NFS_SERVER(state->inode);
16358 - struct nfs4_exception exception = { };
16359 + struct nfs4_exception exception = {0, 0};
16362 err = nfs4_set_lock_state(state, fl);
16363 diff -urNp linux-2.6.27.10/fs/nfsd/export.c linux-2.6.27.10/fs/nfsd/export.c
16364 --- linux-2.6.27.10/fs/nfsd/export.c 2008-11-07 12:55:34.000000000 -0500
16365 +++ linux-2.6.27.10/fs/nfsd/export.c 2008-11-18 03:38:45.000000000 -0500
16366 @@ -473,7 +473,7 @@ static int secinfo_parse(char **mesg, ch
16367 * probably discover the problem when someone fails to
16370 - if (f->pseudoflavor < 0)
16371 + if ((s32)f->pseudoflavor < 0)
16373 err = get_int(mesg, &f->flags);
16375 diff -urNp linux-2.6.27.10/fs/nls/nls_base.c linux-2.6.27.10/fs/nls/nls_base.c
16376 --- linux-2.6.27.10/fs/nls/nls_base.c 2008-11-07 12:55:34.000000000 -0500
16377 +++ linux-2.6.27.10/fs/nls/nls_base.c 2008-11-18 03:38:45.000000000 -0500
16378 @@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
16379 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
16380 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
16381 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
16382 - {0, /* end of table */}
16383 + {0, 0, 0, 0, 0, /* end of table */}
16387 diff -urNp linux-2.6.27.10/fs/ntfs/file.c linux-2.6.27.10/fs/ntfs/file.c
16388 --- linux-2.6.27.10/fs/ntfs/file.c 2008-11-07 12:55:34.000000000 -0500
16389 +++ linux-2.6.27.10/fs/ntfs/file.c 2008-11-18 03:38:45.000000000 -0500
16390 @@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
16391 #endif /* NTFS_RW */
16394 -const struct file_operations ntfs_empty_file_ops = {};
16395 +const struct file_operations ntfs_empty_file_ops;
16397 -const struct inode_operations ntfs_empty_inode_ops = {};
16398 +const struct inode_operations ntfs_empty_inode_ops;
16399 diff -urNp linux-2.6.27.10/fs/open.c linux-2.6.27.10/fs/open.c
16400 --- linux-2.6.27.10/fs/open.c 2008-11-07 12:55:34.000000000 -0500
16401 +++ linux-2.6.27.10/fs/open.c 2008-11-18 03:38:45.000000000 -0500
16403 #include <linux/vs_dlimit.h>
16404 #include <linux/vs_tag.h>
16405 #include <linux/vs_cowbl.h>
16406 +#include <linux/grsecurity.h>
16408 int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
16410 @@ -207,6 +208,9 @@ int do_truncate(struct dentry *dentry, l
16414 + if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
16417 newattrs.ia_size = length;
16418 newattrs.ia_valid = ATTR_SIZE | time_attrs;
16420 @@ -491,6 +495,9 @@ asmlinkage long sys_faccessat(int dfd, c
16421 if (__mnt_is_readonly(path.mnt))
16424 + if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
16430 @@ -521,6 +528,8 @@ asmlinkage long sys_chdir(const char __u
16434 + gr_log_chdir(path.dentry, path.mnt);
16436 set_fs_pwd(current->fs, &path);
16439 @@ -547,6 +556,13 @@ asmlinkage long sys_fchdir(unsigned int
16442 error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
16444 + if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
16448 + gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
16451 set_fs_pwd(current->fs, &file->f_path);
16453 @@ -572,7 +588,14 @@ asmlinkage long sys_chroot(const char __
16454 if (!capable(CAP_SYS_CHROOT))
16457 + if (gr_handle_chroot_chroot(path.dentry, path.mnt))
16458 + goto dput_and_out;
16460 set_fs_root(current->fs, &path);
16462 + gr_handle_chroot_caps(current);
16463 + gr_handle_chroot_chdir(&path);
16468 @@ -600,13 +623,28 @@ asmlinkage long sys_fchmod(unsigned int
16469 err = mnt_want_write(file->f_path.mnt);
16473 + if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
16475 + goto out_drop_write;
16478 mutex_lock(&inode->i_mutex);
16479 if (mode == (mode_t) -1)
16480 mode = inode->i_mode;
16482 + if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
16484 + mutex_unlock(&inode->i_mutex);
16485 + goto out_drop_write;
16488 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16489 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16490 err = notify_change(dentry, &newattrs);
16491 mutex_unlock(&inode->i_mutex);
16494 mnt_drop_write(file->f_path.mnt);
16497 @@ -630,13 +668,28 @@ asmlinkage long sys_fchmodat(int dfd, co
16498 error = mnt_want_write(path.mnt);
16502 + if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
16504 + goto out_drop_write;
16507 mutex_lock(&inode->i_mutex);
16508 if (mode == (mode_t) -1)
16509 mode = inode->i_mode;
16511 + if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
16513 + mutex_unlock(&inode->i_mutex);
16514 + goto out_drop_write;
16517 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16518 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16519 error = notify_change(path.dentry, &newattrs);
16520 mutex_unlock(&inode->i_mutex);
16523 mnt_drop_write(path.mnt);
16526 @@ -649,12 +702,15 @@ asmlinkage long sys_chmod(const char __u
16527 return sys_fchmodat(AT_FDCWD, filename, mode);
16530 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
16531 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
16533 struct inode *inode = dentry->d_inode;
16535 struct iattr newattrs;
16537 + if (!gr_acl_handle_chown(dentry, mnt))
16540 newattrs.ia_valid = ATTR_CTIME;
16541 if (user != (uid_t) -1) {
16542 newattrs.ia_valid |= ATTR_UID;
16543 @@ -685,7 +741,7 @@ asmlinkage long sys_chown(const char __u
16544 error = cow_check_and_break(&path);
16547 - error = chown_common(path.dentry, user, group);
16548 + error = chown_common(path.dentry, user, group, path.mnt);
16549 mnt_drop_write(path.mnt);
16552 @@ -710,7 +766,7 @@ asmlinkage long sys_fchownat(int dfd, co
16553 error = cow_check_and_break(&path);
16556 - error = chown_common(path.dentry, user, group);
16557 + error = chown_common(path.dentry, user, group, path.mnt);
16558 mnt_drop_write(path.mnt);
16561 @@ -729,7 +785,7 @@ asmlinkage long sys_lchown(const char __
16562 error = cow_check_and_break(&path);
16565 - error = chown_common(path.dentry, user, group);
16566 + error = chown_common(path.dentry, user, group, path.mnt);
16567 mnt_drop_write(path.mnt);
16570 @@ -753,7 +809,7 @@ asmlinkage long sys_fchown(unsigned int
16572 dentry = file->f_path.dentry;
16573 audit_inode(NULL, dentry);
16574 - error = chown_common(dentry, user, group);
16575 + error = chown_common(dentry, user, group, file->f_path.mnt);
16576 mnt_drop_write(file->f_path.mnt);
16579 diff -urNp linux-2.6.27.10/fs/pipe.c linux-2.6.27.10/fs/pipe.c
16580 --- linux-2.6.27.10/fs/pipe.c 2008-11-07 12:55:34.000000000 -0500
16581 +++ linux-2.6.27.10/fs/pipe.c 2008-11-18 03:38:45.000000000 -0500
16582 @@ -851,7 +851,7 @@ void free_pipe_info(struct inode *inode)
16583 inode->i_pipe = NULL;
16586 -static struct vfsmount *pipe_mnt __read_mostly;
16587 +struct vfsmount *pipe_mnt __read_mostly;
16588 static int pipefs_delete_dentry(struct dentry *dentry)
16591 diff -urNp linux-2.6.27.10/fs/proc/array.c linux-2.6.27.10/fs/proc/array.c
16592 --- linux-2.6.27.10/fs/proc/array.c 2008-11-07 12:55:34.000000000 -0500
16593 +++ linux-2.6.27.10/fs/proc/array.c 2008-11-18 03:38:45.000000000 -0500
16594 @@ -315,6 +315,21 @@ static inline void task_context_switch_c
16598 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16599 +static inline void task_pax(struct seq_file *m, struct task_struct *p)
16602 + seq_printf(m, "PaX:\t%c%c%c%c%c\n",
16603 + p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
16604 + p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
16605 + p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
16606 + p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
16607 + p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
16609 + seq_printf(m, "PaX:\t-----\n");
16613 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
16614 struct pid *pid, struct task_struct *task)
16616 @@ -334,9 +349,20 @@ int proc_pid_status(struct seq_file *m,
16617 task_show_regs(m, task);
16619 task_context_switch_counts(m, task);
16621 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16622 + task_pax(m, task);
16628 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16629 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
16630 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
16631 + _mm->pax_flags & MF_PAX_SEGMEXEC))
16634 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
16635 struct pid *pid, struct task_struct *task, int whole)
16637 @@ -429,6 +455,19 @@ static int do_task_stat(struct seq_file
16638 gtime = task_gtime(task);
16641 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16642 + if (PAX_RAND_FLAGS(mm)) {
16648 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16654 /* scale priority and nice values from timeslices to -20..20 */
16655 /* to make it look like a "normal" Unix priority/nice value */
16656 priority = task_prio(task);
16657 @@ -469,9 +508,15 @@ static int do_task_stat(struct seq_file
16659 mm ? get_mm_rss(mm) : 0,
16661 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16662 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
16663 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
16664 + PAX_RAND_FLAGS(mm) ? 0 : ((permitted && mm) ? mm->start_stack : 0),
16666 mm ? mm->start_code : 0,
16667 mm ? mm->end_code : 0,
16668 (permitted && mm) ? mm->start_stack : 0,
16672 /* The signal information here is obsolete.
16673 @@ -524,3 +569,10 @@ int proc_pid_statm(struct seq_file *m, s
16678 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16679 +int proc_pid_ipaddr(struct task_struct *task, char *buffer)
16681 + return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
16684 diff -urNp linux-2.6.27.10/fs/proc/base.c linux-2.6.27.10/fs/proc/base.c
16685 --- linux-2.6.27.10/fs/proc/base.c 2008-11-07 12:55:34.000000000 -0500
16686 +++ linux-2.6.27.10/fs/proc/base.c 2008-11-18 03:38:45.000000000 -0500
16688 #include <linux/pid_namespace.h>
16689 #include <linux/vs_context.h>
16690 #include <linux/vs_network.h>
16691 +#include <linux/grsecurity.h>
16693 #include "internal.h"
16696 @@ -148,7 +150,7 @@ static unsigned int pid_entry_count_dirs
16701 +int maps_protect = 1;
16702 EXPORT_SYMBOL(maps_protect);
16704 static struct fs_struct *get_fs_struct(struct task_struct *task)
16705 @@ -229,6 +231,9 @@ static int check_mem_permission(struct t
16706 if (task == current)
16709 + if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
16713 * If current is actively ptrace'ing, and would also be
16714 * permitted to freshly attach with ptrace now, permit it.
16715 @@ -312,9 +317,9 @@ static int proc_pid_auxv(struct task_str
16716 struct mm_struct *mm = get_task_mm(task);
16718 unsigned int nwords = 0;
16722 - while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16723 + } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16724 res = nwords * sizeof(mm->saved_auxv[0]);
16725 if (res > PAGE_SIZE)
16727 @@ -1437,7 +1442,11 @@ static struct inode *proc_pid_make_inode
16729 if (task_dumpable(task)) {
16730 inode->i_uid = task->euid;
16731 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16732 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16734 inode->i_gid = task->egid;
16737 security_task_to_inode(task, inode);
16739 @@ -1453,17 +1462,45 @@ static int pid_getattr(struct vfsmount *
16741 struct inode *inode = dentry->d_inode;
16742 struct task_struct *task;
16743 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16744 + struct task_struct *tmp = current;
16747 generic_fillattr(inode, stat);
16752 task = pid_task(proc_pid(inode), PIDTYPE_PID);
16755 + if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
16756 + rcu_read_unlock();
16762 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16763 + && (!tmp->uid || (tmp->uid == task->uid)
16764 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16765 + || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16770 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16771 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16772 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16773 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16774 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16776 task_dumpable(task)) {
16777 stat->uid = task->euid;
16778 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16779 + stat->gid = CONFIG_GRKERNSEC_PROC_GID;
16781 stat->gid = task->egid;
16786 @@ -1491,11 +1528,21 @@ static int pid_revalidate(struct dentry
16788 struct inode *inode = dentry->d_inode;
16789 struct task_struct *task = get_proc_task(inode);
16792 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16793 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16794 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16795 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16796 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16798 task_dumpable(task)) {
16799 inode->i_uid = task->euid;
16800 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16801 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16803 inode->i_gid = task->egid;
16808 @@ -1863,12 +1910,22 @@ static const struct file_operations proc
16809 static int proc_fd_permission(struct inode *inode, int mask)
16812 + struct task_struct *task;
16814 rv = generic_permission(inode, mask, NULL);
16818 if (task_pid(current) == proc_pid(inode))
16821 + task = get_proc_task(inode);
16822 + if (task == NULL)
16825 + if (gr_acl_handle_procpidmem(task))
16828 + put_task_struct(task);
16833 @@ -1979,6 +2036,9 @@ static struct dentry *proc_pident_lookup
16837 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16841 * Yes, it does not scale. And it should not. Don't add
16842 * new entries into /proc/<tgid>/ without very good reasons.
16843 @@ -2023,6 +2083,9 @@ static int proc_pident_readdir(struct fi
16847 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16853 @@ -2385,6 +2448,9 @@ static struct dentry *proc_base_lookup(s
16857 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16860 error = proc_base_instantiate(dir, dentry, task, p);
16863 @@ -2518,6 +2584,9 @@ static const struct pid_entry tgid_base_
16864 #ifdef CONFIG_TASK_IO_ACCOUNTING
16865 INF("io", S_IRUGO, tgid_io_accounting),
16867 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16868 + INF("ipaddr", S_IRUSR, pid_ipaddr),
16870 ONE("nsproxy", S_IRUGO, pid_nsproxy),
16873 @@ -2647,7 +2716,14 @@ static struct dentry *proc_pid_instantia
16877 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16878 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
16879 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16880 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16881 + inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
16883 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
16885 inode->i_op = &proc_tgid_base_inode_operations;
16886 inode->i_fop = &proc_tgid_base_operations;
16887 inode->i_flags|=S_IMMUTABLE;
16888 @@ -2689,7 +2765,11 @@ struct dentry *proc_pid_lookup(struct in
16892 + if (gr_check_hidden_task(task))
16893 + goto out_put_task;
16895 result = proc_pid_instantiate(dir, dentry, task, NULL);
16897 put_task_struct(task);
16900 @@ -2754,6 +2834,9 @@ int proc_pid_readdir(struct file * filp,
16902 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
16903 struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
16904 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16905 + struct task_struct *tmp = current;
16907 struct tgid_iter iter;
16908 struct pid_namespace *ns;
16910 @@ -2772,6 +2855,17 @@ int proc_pid_readdir(struct file * filp,
16911 for (iter = next_tgid(ns, iter);
16913 iter.tgid += 1, iter = next_tgid(ns, iter)) {
16914 + if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
16915 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16916 + || (tmp->uid && (iter.task->uid != tmp->uid)
16917 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16918 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16925 filp->f_pos = iter.tgid + TGID_OFFSET;
16926 if (!vx_proc_task_visible(iter.task))
16928 diff -urNp linux-2.6.27.10/fs/proc/inode.c linux-2.6.27.10/fs/proc/inode.c
16929 --- linux-2.6.27.10/fs/proc/inode.c 2008-11-07 12:55:34.000000000 -0500
16930 +++ linux-2.6.27.10/fs/proc/inode.c 2008-11-18 03:38:45.000000000 -0500
16931 @@ -467,7 +467,11 @@ struct inode *proc_get_inode(struct supe
16933 inode->i_mode = de->mode;
16934 inode->i_uid = de->uid;
16935 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16936 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16938 inode->i_gid = de->gid;
16942 inode->i_size = de->size;
16943 diff -urNp linux-2.6.27.10/fs/proc/internal.h linux-2.6.27.10/fs/proc/internal.h
16944 --- linux-2.6.27.10/fs/proc/internal.h 2008-11-07 12:55:34.000000000 -0500
16945 +++ linux-2.6.27.10/fs/proc/internal.h 2008-11-18 03:38:45.000000000 -0500
16946 @@ -55,6 +55,9 @@ extern int proc_pid_status(struct seq_fi
16947 extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
16948 struct pid *pid, struct task_struct *task);
16950 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16951 +extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
16953 extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
16955 extern const struct file_operations proc_maps_operations;
16956 diff -urNp linux-2.6.27.10/fs/proc/Kconfig linux-2.6.27.10/fs/proc/Kconfig
16957 --- linux-2.6.27.10/fs/proc/Kconfig 2008-11-07 12:55:34.000000000 -0500
16958 +++ linux-2.6.27.10/fs/proc/Kconfig 2008-11-18 03:38:45.000000000 -0500
16959 @@ -30,12 +30,12 @@ config PROC_FS
16962 bool "/proc/kcore support" if !ARM
16963 - depends on PROC_FS && MMU
16964 + depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
16967 bool "/proc/vmcore support (EXPERIMENTAL)"
16968 - depends on PROC_FS && CRASH_DUMP
16970 + depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
16973 Exports the dump image of crashed kernel in ELF format.
16975 diff -urNp linux-2.6.27.10/fs/proc/proc_misc.c linux-2.6.27.10/fs/proc/proc_misc.c
16976 --- linux-2.6.27.10/fs/proc/proc_misc.c 2008-11-07 12:55:34.000000000 -0500
16977 +++ linux-2.6.27.10/fs/proc/proc_misc.c 2008-11-18 03:38:45.000000000 -0500
16978 @@ -860,6 +860,8 @@ struct proc_dir_entry *proc_root_kcore;
16980 void __init proc_misc_init(void)
16986 int (*read_proc)(char*,char**,off_t,int,int*,void*);
16987 @@ -875,13 +877,24 @@ void __init proc_misc_init(void)
16988 {"stram", stram_read_proc},
16990 {"filesystems", filesystems_read_proc},
16991 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
16992 {"cmdline", cmdline_read_proc},
16994 {"execdomains", execdomains_read_proc},
16997 for (p = simple_ones; p->name; p++)
16998 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
17000 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17001 + gr_mode = S_IRUSR;
17002 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17003 + gr_mode = S_IRUSR | S_IRGRP;
17005 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17006 + create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
17009 proc_symlink("mounts", NULL, "self/mounts");
17011 /* And now for trickier ones */
17012 @@ -889,14 +902,18 @@ void __init proc_misc_init(void)
17013 proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
17015 proc_create("locks", 0, NULL, &proc_locks_operations);
17016 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17017 + proc_create("devices", gr_mode, NULL, &proc_devinfo_operations);
17019 proc_create("devices", 0, NULL, &proc_devinfo_operations);
17021 proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
17022 #ifdef CONFIG_BLOCK
17023 proc_create("partitions", 0, NULL, &proc_partitions_operations);
17025 proc_create("stat", 0, NULL, &proc_stat_operations);
17026 proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
17027 -#ifdef CONFIG_SLABINFO
17028 +#if defined(CONFIG_SLABINFO) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
17029 proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
17030 #ifdef CONFIG_DEBUG_SLAB_LEAK
17031 proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
17032 @@ -918,7 +935,7 @@ void __init proc_misc_init(void)
17033 #ifdef CONFIG_SCHEDSTATS
17034 proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
17036 -#ifdef CONFIG_PROC_KCORE
17037 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
17038 proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
17039 if (proc_root_kcore)
17040 proc_root_kcore->size =
17041 diff -urNp linux-2.6.27.10/fs/proc/proc_net.c linux-2.6.27.10/fs/proc/proc_net.c
17042 --- linux-2.6.27.10/fs/proc/proc_net.c 2008-11-07 12:55:34.000000000 -0500
17043 +++ linux-2.6.27.10/fs/proc/proc_net.c 2008-11-18 03:38:45.000000000 -0500
17044 @@ -106,6 +106,14 @@ static struct net *get_proc_task_net(str
17045 struct nsproxy *ns;
17046 struct net *net = NULL;
17048 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17049 + if (current->fsuid)
17051 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17052 + if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
17057 task = pid_task(proc_pid(dir), PIDTYPE_PID);
17058 if (task != NULL) {
17059 diff -urNp linux-2.6.27.10/fs/proc/proc_sysctl.c linux-2.6.27.10/fs/proc/proc_sysctl.c
17060 --- linux-2.6.27.10/fs/proc/proc_sysctl.c 2008-11-18 11:38:40.000000000 -0500
17061 +++ linux-2.6.27.10/fs/proc/proc_sysctl.c 2008-11-18 11:40:53.000000000 -0500
17063 #include <linux/security.h>
17064 #include "internal.h"
17066 +extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
17068 static struct dentry_operations proc_sys_dentry_operations;
17069 static const struct file_operations proc_sys_file_operations;
17070 static const struct inode_operations proc_sys_inode_operations;
17071 @@ -110,6 +112,9 @@ static struct dentry *proc_sys_lookup(st
17075 + if (gr_handle_sysctl(p, MAY_EXEC))
17078 err = ERR_PTR(-ENOMEM);
17079 inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
17081 @@ -229,6 +234,9 @@ static int scan(struct ctl_table_header
17082 if (*pos < file->f_pos)
17085 + if (gr_handle_sysctl(table, 0))
17088 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
17091 @@ -339,6 +347,9 @@ static int proc_sys_getattr(struct vfsmo
17093 return PTR_ERR(head);
17095 + if (table && gr_handle_sysctl(table, MAY_EXEC))
17098 generic_fillattr(inode, stat);
17100 stat->mode = (stat->mode & S_IFMT) | table->mode;
17101 diff -urNp linux-2.6.27.10/fs/proc/root.c linux-2.6.27.10/fs/proc/root.c
17102 --- linux-2.6.27.10/fs/proc/root.c 2008-11-07 12:55:34.000000000 -0500
17103 +++ linux-2.6.27.10/fs/proc/root.c 2008-11-18 03:38:45.000000000 -0500
17104 @@ -135,7 +135,15 @@ void __init proc_root_init(void)
17105 #ifdef CONFIG_PROC_DEVICETREE
17106 proc_device_tree_init();
17108 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17109 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17110 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
17111 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17112 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
17115 proc_mkdir("bus", NULL);
17120 diff -urNp linux-2.6.27.10/fs/proc/task_mmu.c linux-2.6.27.10/fs/proc/task_mmu.c
17121 --- linux-2.6.27.10/fs/proc/task_mmu.c 2008-12-21 01:16:51.000000000 -0500
17122 +++ linux-2.6.27.10/fs/proc/task_mmu.c 2008-12-21 01:13:46.000000000 -0500
17123 @@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
17124 "VmStk:\t%8lu kB\n"
17125 "VmExe:\t%8lu kB\n"
17126 "VmLib:\t%8lu kB\n"
17127 - "VmPTE:\t%8lu kB\n",
17128 - hiwater_vm << (PAGE_SHIFT-10),
17129 + "VmPTE:\t%8lu kB\n"
17131 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
17132 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
17135 + ,hiwater_vm << (PAGE_SHIFT-10),
17136 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
17137 mm->locked_vm << (PAGE_SHIFT-10),
17138 hiwater_rss << (PAGE_SHIFT-10),
17139 total_rss << (PAGE_SHIFT-10),
17140 data << (PAGE_SHIFT-10),
17141 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
17142 - (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
17143 + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
17145 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
17146 + , mm->context.user_cs_base, mm->context.user_cs_limit
17152 unsigned long task_vsize(struct mm_struct *mm)
17153 @@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
17157 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17158 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
17159 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
17160 + _mm->pax_flags & MF_PAX_SEGMEXEC))
17163 static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
17165 struct mm_struct *mm = vma->vm_mm;
17166 @@ -214,13 +231,22 @@ static void show_map_vma(struct seq_file
17169 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
17170 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17171 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
17172 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
17177 flags & VM_READ ? 'r' : '-',
17178 flags & VM_WRITE ? 'w' : '-',
17179 flags & VM_EXEC ? 'x' : '-',
17180 flags & VM_MAYSHARE ? 's' : 'p',
17181 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17182 + PAX_RAND_FLAGS(mm) ? 0UL : ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
17184 ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
17186 MAJOR(dev), MINOR(dev), ino, &len);
17189 @@ -234,11 +260,11 @@ static void show_map_vma(struct seq_file
17190 const char *name = arch_vma_name(vma);
17193 - if (vma->vm_start <= mm->start_brk &&
17194 - vma->vm_end >= mm->brk) {
17195 + if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
17197 - } else if (vma->vm_start <= mm->start_stack &&
17198 - vma->vm_end >= mm->start_stack) {
17199 + } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
17200 + (vma->vm_start <= mm->start_stack &&
17201 + vma->vm_end >= mm->start_stack)) {
17205 @@ -387,9 +413,16 @@ static int show_smap(struct seq_file *m,
17208 memset(&mss, 0, sizeof mss);
17210 - if (vma->vm_mm && !is_vm_hugetlb_page(vma))
17211 - walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
17213 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17214 + if (!PAX_RAND_FLAGS(vma->vm_mm)) {
17217 + if (vma->vm_mm && !is_vm_hugetlb_page(vma))
17218 + walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
17219 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17223 show_map_vma(m, vma);
17225 @@ -403,7 +436,11 @@ static int show_smap(struct seq_file *m,
17226 "Private_Dirty: %8lu kB\n"
17227 "Referenced: %8lu kB\n"
17229 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17230 + PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
17232 (vma->vm_end - vma->vm_start) >> 10,
17234 mss.resident >> 10,
17235 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
17236 mss.shared_clean >> 10,
17237 @@ -757,6 +794,11 @@ static int show_numa_map_checked(struct
17238 struct proc_maps_private *priv = m->private;
17239 struct task_struct *task = priv->task;
17241 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17242 + if (!ptrace_may_access(task, PTRACE_MODE_READ))
17246 if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
17249 diff -urNp linux-2.6.27.10/fs/readdir.c linux-2.6.27.10/fs/readdir.c
17250 --- linux-2.6.27.10/fs/readdir.c 2008-11-07 12:55:34.000000000 -0500
17251 +++ linux-2.6.27.10/fs/readdir.c 2008-11-18 03:38:45.000000000 -0500
17253 #include <linux/security.h>
17254 #include <linux/syscalls.h>
17255 #include <linux/unistd.h>
17256 +#include <linux/namei.h>
17257 +#include <linux/grsecurity.h>
17259 #include <asm/uaccess.h>
17261 @@ -67,6 +69,7 @@ struct old_linux_dirent {
17263 struct readdir_callback {
17264 struct old_linux_dirent __user * dirent;
17265 + struct file * file;
17269 @@ -84,6 +87,10 @@ static int fillonedir(void * __buf, cons
17270 buf->result = -EOVERFLOW;
17274 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17278 dirent = buf->dirent;
17279 if (!access_ok(VERIFY_WRITE, dirent,
17280 @@ -115,6 +122,7 @@ asmlinkage long old_readdir(unsigned int
17283 buf.dirent = dirent;
17286 error = vfs_readdir(file, fillonedir, &buf);
17288 @@ -141,6 +149,7 @@ struct linux_dirent {
17289 struct getdents_callback {
17290 struct linux_dirent __user * current_dir;
17291 struct linux_dirent __user * previous;
17292 + struct file * file;
17296 @@ -161,6 +170,10 @@ static int filldir(void * __buf, const c
17297 buf->error = -EOVERFLOW;
17301 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17304 dirent = buf->previous;
17306 if (__put_user(offset, &dirent->d_off))
17307 @@ -207,6 +220,7 @@ asmlinkage long sys_getdents(unsigned in
17308 buf.previous = NULL;
17313 error = vfs_readdir(file, filldir, &buf);
17315 @@ -229,6 +243,7 @@ out:
17316 struct getdents_callback64 {
17317 struct linux_dirent64 __user * current_dir;
17318 struct linux_dirent64 __user * previous;
17319 + struct file *file;
17323 @@ -243,6 +258,10 @@ static int filldir64(void * __buf, const
17324 buf->error = -EINVAL; /* only used if we fail.. */
17325 if (reclen > buf->count)
17328 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17331 dirent = buf->previous;
17333 if (__put_user(offset, &dirent->d_off))
17334 @@ -289,6 +308,7 @@ asmlinkage long sys_getdents64(unsigned
17336 buf.current_dir = dirent;
17337 buf.previous = NULL;
17342 diff -urNp linux-2.6.27.10/fs/select.c linux-2.6.27.10/fs/select.c
17343 --- linux-2.6.27.10/fs/select.c 2008-11-07 12:55:34.000000000 -0500
17344 +++ linux-2.6.27.10/fs/select.c 2008-11-18 03:38:45.000000000 -0500
17346 #include <linux/fdtable.h>
17347 #include <linux/fs.h>
17348 #include <linux/rcupdate.h>
17349 +#include <linux/grsecurity.h>
17351 #include <asm/uaccess.h>
17353 @@ -658,6 +659,7 @@ int do_sys_poll(struct pollfd __user *uf
17354 struct poll_list *walk = head;
17355 unsigned long todo = nfds;
17357 + gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
17358 if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
17361 diff -urNp linux-2.6.27.10/fs/smbfs/symlink.c linux-2.6.27.10/fs/smbfs/symlink.c
17362 --- linux-2.6.27.10/fs/smbfs/symlink.c 2008-11-07 12:55:34.000000000 -0500
17363 +++ linux-2.6.27.10/fs/smbfs/symlink.c 2008-11-18 03:38:45.000000000 -0500
17364 @@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
17366 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
17368 - char *s = nd_get_link(nd);
17369 + const char *s = nd_get_link(nd);
17373 diff -urNp linux-2.6.27.10/fs/sysfs/symlink.c linux-2.6.27.10/fs/sysfs/symlink.c
17374 --- linux-2.6.27.10/fs/sysfs/symlink.c 2008-11-07 12:55:34.000000000 -0500
17375 +++ linux-2.6.27.10/fs/sysfs/symlink.c 2008-11-18 03:38:45.000000000 -0500
17376 @@ -200,7 +200,7 @@ static void *sysfs_follow_link(struct de
17378 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
17380 - char *page = nd_get_link(nd);
17381 + const char *page = nd_get_link(nd);
17383 free_page((unsigned long)page);
17385 diff -urNp linux-2.6.27.10/fs/udf/balloc.c linux-2.6.27.10/fs/udf/balloc.c
17386 --- linux-2.6.27.10/fs/udf/balloc.c 2008-11-07 12:55:34.000000000 -0500
17387 +++ linux-2.6.27.10/fs/udf/balloc.c 2008-11-18 03:38:45.000000000 -0500
17388 @@ -169,9 +169,7 @@ static void udf_bitmap_free_blocks(struc
17389 unsigned long overflow;
17391 mutex_lock(&sbi->s_alloc_mutex);
17392 - if (bloc.logicalBlockNum < 0 ||
17393 - (bloc.logicalBlockNum + count) >
17394 - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17395 + if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17396 udf_debug("%d < %d || %d + %d > %d\n",
17397 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
17398 sbi->s_partmaps[bloc.partitionReferenceNum].
17399 @@ -239,7 +237,7 @@ static int udf_bitmap_prealloc_blocks(st
17401 mutex_lock(&sbi->s_alloc_mutex);
17402 part_len = sbi->s_partmaps[partition].s_partition_len;
17403 - if (first_block < 0 || first_block >= part_len)
17404 + if (first_block >= part_len)
17407 if (first_block + block_count > part_len)
17408 @@ -300,7 +298,7 @@ static int udf_bitmap_new_block(struct s
17409 mutex_lock(&sbi->s_alloc_mutex);
17412 - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
17413 + if (goal >= sbi->s_partmaps[partition].s_partition_len)
17416 nr_groups = bitmap->s_nr_groups;
17417 @@ -438,9 +436,7 @@ static void udf_table_free_blocks(struct
17418 struct udf_inode_info *iinfo;
17420 mutex_lock(&sbi->s_alloc_mutex);
17421 - if (bloc.logicalBlockNum < 0 ||
17422 - (bloc.logicalBlockNum + count) >
17423 - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17424 + if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17425 udf_debug("%d < %d || %d + %d > %d\n",
17426 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
17427 sbi->s_partmaps[bloc.partitionReferenceNum].
17428 @@ -671,8 +667,7 @@ static int udf_table_prealloc_blocks(str
17430 struct udf_inode_info *iinfo;
17432 - if (first_block < 0 ||
17433 - first_block >= sbi->s_partmaps[partition].s_partition_len)
17434 + if (first_block >= sbi->s_partmaps[partition].s_partition_len)
17437 iinfo = UDF_I(table);
17438 @@ -750,7 +745,7 @@ static int udf_table_new_block(struct su
17441 mutex_lock(&sbi->s_alloc_mutex);
17442 - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
17443 + if (goal >= sbi->s_partmaps[partition].s_partition_len)
17446 /* We search for the closest matching block to goal. If we find
17447 diff -urNp linux-2.6.27.10/fs/ufs/inode.c linux-2.6.27.10/fs/ufs/inode.c
17448 --- linux-2.6.27.10/fs/ufs/inode.c 2008-11-07 12:55:34.000000000 -0500
17449 +++ linux-2.6.27.10/fs/ufs/inode.c 2008-11-18 03:38:45.000000000 -0500
17450 @@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
17453 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
17454 - if (i_block < 0) {
17455 - ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
17456 - } else if (i_block < direct_blocks) {
17457 + if (i_block < direct_blocks) {
17458 offsets[n++] = i_block;
17459 } else if ((i_block -= direct_blocks) < indirect_blocks) {
17460 offsets[n++] = UFS_IND_BLOCK;
17461 @@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
17464 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
17465 - if (fragment < 0)
17466 - goto abort_negative;
17468 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
17469 << uspi->s_fpbshift))
17470 @@ -504,10 +500,6 @@ abort:
17475 - ufs_warning(sb, "ufs_get_block", "block < 0");
17479 ufs_warning(sb, "ufs_get_block", "block > big");
17481 diff -urNp linux-2.6.27.10/fs/utimes.c linux-2.6.27.10/fs/utimes.c
17482 --- linux-2.6.27.10/fs/utimes.c 2008-11-07 12:55:34.000000000 -0500
17483 +++ linux-2.6.27.10/fs/utimes.c 2008-11-18 03:38:45.000000000 -0500
17485 #include <linux/syscalls.h>
17486 #include <linux/mount.h>
17487 #include <linux/vs_cowbl.h>
17488 +#include <linux/grsecurity.h>
17489 #include <asm/uaccess.h>
17490 #include <asm/unistd.h>
17492 @@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
17493 goto mnt_drop_write_and_out;
17497 + if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
17499 + goto mnt_drop_write_and_out;
17502 mutex_lock(&inode->i_mutex);
17503 error = notify_change(path->dentry, &newattrs);
17504 mutex_unlock(&inode->i_mutex);
17505 diff -urNp linux-2.6.27.10/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.27.10/fs/xfs/linux-2.6/xfs_iops.c
17506 --- linux-2.6.27.10/fs/xfs/linux-2.6/xfs_iops.c 2008-11-07 12:55:34.000000000 -0500
17507 +++ linux-2.6.27.10/fs/xfs/linux-2.6/xfs_iops.c 2008-11-18 03:38:45.000000000 -0500
17508 @@ -500,7 +500,7 @@ xfs_vn_put_link(
17509 struct nameidata *nd,
17512 - char *s = nd_get_link(nd);
17513 + const char *s = nd_get_link(nd);
17517 diff -urNp linux-2.6.27.10/fs/xfs/xfs_bmap.c linux-2.6.27.10/fs/xfs/xfs_bmap.c
17518 --- linux-2.6.27.10/fs/xfs/xfs_bmap.c 2008-11-07 12:55:34.000000000 -0500
17519 +++ linux-2.6.27.10/fs/xfs/xfs_bmap.c 2008-11-18 03:38:45.000000000 -0500
17520 @@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
17524 -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
17525 +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
17528 #if defined(XFS_RW_TRACE)
17529 diff -urNp linux-2.6.27.10/grsecurity/gracl_alloc.c linux-2.6.27.10/grsecurity/gracl_alloc.c
17530 --- linux-2.6.27.10/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
17531 +++ linux-2.6.27.10/grsecurity/gracl_alloc.c 2008-11-18 03:38:45.000000000 -0500
17533 +#include <linux/kernel.h>
17534 +#include <linux/mm.h>
17535 +#include <linux/slab.h>
17536 +#include <linux/vmalloc.h>
17537 +#include <linux/gracl.h>
17538 +#include <linux/grsecurity.h>
17540 +static unsigned long alloc_stack_next = 1;
17541 +static unsigned long alloc_stack_size = 1;
17542 +static void **alloc_stack;
17544 +static __inline__ int
17547 + if (alloc_stack_next == 1)
17550 + kfree(alloc_stack[alloc_stack_next - 2]);
17552 + alloc_stack_next--;
17557 +static __inline__ void
17558 +alloc_push(void *buf)
17560 + if (alloc_stack_next >= alloc_stack_size)
17563 + alloc_stack[alloc_stack_next - 1] = buf;
17565 + alloc_stack_next++;
17571 +acl_alloc(unsigned long len)
17575 + if (len > PAGE_SIZE)
17578 + ret = kmalloc(len, GFP_KERNEL);
17587 +acl_free_all(void)
17589 + if (gr_acl_is_enabled() || !alloc_stack)
17592 + while (alloc_pop()) ;
17594 + if (alloc_stack) {
17595 + if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
17596 + kfree(alloc_stack);
17598 + vfree(alloc_stack);
17601 + alloc_stack = NULL;
17602 + alloc_stack_size = 1;
17603 + alloc_stack_next = 1;
17609 +acl_alloc_stack_init(unsigned long size)
17611 + if ((size * sizeof (void *)) <= PAGE_SIZE)
17613 + (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
17615 + alloc_stack = (void **) vmalloc(size * sizeof (void *));
17617 + alloc_stack_size = size;
17619 + if (!alloc_stack)
17624 diff -urNp linux-2.6.27.10/grsecurity/gracl.c linux-2.6.27.10/grsecurity/gracl.c
17625 --- linux-2.6.27.10/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
17626 +++ linux-2.6.27.10/grsecurity/gracl.c 2008-11-18 03:38:45.000000000 -0500
17628 +#include <linux/kernel.h>
17629 +#include <linux/module.h>
17630 +#include <linux/sched.h>
17631 +#include <linux/mm.h>
17632 +#include <linux/file.h>
17633 +#include <linux/fs.h>
17634 +#include <linux/namei.h>
17635 +#include <linux/mount.h>
17636 +#include <linux/tty.h>
17637 +#include <linux/proc_fs.h>
17638 +#include <linux/smp_lock.h>
17639 +#include <linux/slab.h>
17640 +#include <linux/vmalloc.h>
17641 +#include <linux/types.h>
17642 +#include <linux/sysctl.h>
17643 +#include <linux/netdevice.h>
17644 +#include <linux/ptrace.h>
17645 +#include <linux/gracl.h>
17646 +#include <linux/gralloc.h>
17647 +#include <linux/grsecurity.h>
17648 +#include <linux/grinternal.h>
17649 +#include <linux/pid_namespace.h>
17650 +#include <linux/fdtable.h>
17651 +#include <linux/percpu.h>
17653 +#include <asm/uaccess.h>
17654 +#include <asm/errno.h>
17655 +#include <asm/mman.h>
17657 +static struct acl_role_db acl_role_set;
17658 +static struct name_db name_set;
17659 +static struct inodev_db inodev_set;
17661 +/* for keeping track of userspace pointers used for subjects, so we
17662 + can share references in the kernel as well
17665 +static struct dentry *real_root;
17666 +static struct vfsmount *real_root_mnt;
17668 +static struct acl_subj_map_db subj_map_set;
17670 +static struct acl_role_label *default_role;
17672 +static u16 acl_sp_role_value;
17674 +extern char *gr_shared_page[4];
17675 +static DECLARE_MUTEX(gr_dev_sem);
17676 +DEFINE_RWLOCK(gr_inode_lock);
17678 +struct gr_arg *gr_usermode;
17680 +static unsigned int gr_status = GR_STATUS_INIT;
17682 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
17683 +extern void gr_clear_learn_entries(void);
17685 +#ifdef CONFIG_GRKERNSEC_RESLOG
17686 +extern void gr_log_resource(const struct task_struct *task,
17687 + const int res, const unsigned long wanted, const int gt);
17690 +unsigned char *gr_system_salt;
17691 +unsigned char *gr_system_sum;
17693 +static struct sprole_pw **acl_special_roles = NULL;
17694 +static __u16 num_sprole_pws = 0;
17696 +static struct acl_role_label *kernel_role = NULL;
17698 +static unsigned int gr_auth_attempts = 0;
17699 +static unsigned long gr_auth_expires = 0UL;
17701 +extern struct vfsmount *sock_mnt;
17702 +extern struct vfsmount *pipe_mnt;
17703 +extern struct vfsmount *shm_mnt;
17704 +static struct acl_object_label *fakefs_obj;
17706 +extern int gr_init_uidset(void);
17707 +extern void gr_free_uidset(void);
17708 +extern void gr_remove_uid(uid_t uid);
17709 +extern int gr_find_uid(uid_t uid);
17712 +gr_acl_is_enabled(void)
17714 + return (gr_status & GR_READY);
17717 +char gr_roletype_to_char(void)
17719 + switch (current->role->roletype &
17720 + (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
17721 + GR_ROLE_SPECIAL)) {
17722 + case GR_ROLE_DEFAULT:
17724 + case GR_ROLE_USER:
17726 + case GR_ROLE_GROUP:
17728 + case GR_ROLE_SPECIAL:
17736 +gr_acl_tpe_check(void)
17738 + if (unlikely(!(gr_status & GR_READY)))
17740 + if (current->role->roletype & GR_ROLE_TPE)
17747 +gr_handle_rawio(const struct inode *inode)
17749 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17750 + if (inode && S_ISBLK(inode->i_mode) &&
17751 + grsec_enable_chroot_caps && proc_is_chrooted(current) &&
17752 + !capable(CAP_SYS_RAWIO))
17759 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
17762 + unsigned long *l1;
17763 + unsigned long *l2;
17764 + unsigned char *c1;
17765 + unsigned char *c2;
17768 + if (likely(lena != lenb))
17771 + l1 = (unsigned long *)a;
17772 + l2 = (unsigned long *)b;
17774 + num_longs = lena / sizeof(unsigned long);
17776 + for (i = num_longs; i--; l1++, l2++) {
17777 + if (unlikely(*l1 != *l2))
17781 + c1 = (unsigned char *) l1;
17782 + c2 = (unsigned char *) l2;
17784 + i = lena - (num_longs * sizeof(unsigned long));
17786 + for (; i--; c1++, c2++) {
17787 + if (unlikely(*c1 != *c2))
17794 +static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17795 + struct dentry *root, struct vfsmount *rootmnt,
17796 + char *buffer, int buflen)
17798 + char * end = buffer+buflen;
17807 + /* Get '/' right */
17812 + struct dentry * parent;
17814 + if (dentry == root && vfsmnt == rootmnt)
17816 + if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
17817 + /* Global root? */
17818 + spin_lock(&vfsmount_lock);
17819 + if (vfsmnt->mnt_parent == vfsmnt) {
17820 + spin_unlock(&vfsmount_lock);
17821 + goto global_root;
17823 + dentry = vfsmnt->mnt_mountpoint;
17824 + vfsmnt = vfsmnt->mnt_parent;
17825 + spin_unlock(&vfsmount_lock);
17828 + parent = dentry->d_parent;
17829 + prefetch(parent);
17830 + namelen = dentry->d_name.len;
17831 + buflen -= namelen + 1;
17835 + memcpy(end, dentry->d_name.name, namelen);
17844 + namelen = dentry->d_name.len;
17845 + buflen -= namelen;
17848 + retval -= namelen-1; /* hit the slash */
17849 + memcpy(retval, dentry->d_name.name, namelen);
17852 + return ERR_PTR(-ENAMETOOLONG);
17856 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17857 + struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
17861 + retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
17862 + if (unlikely(IS_ERR(retval)))
17863 + retval = strcpy(buf, "<path too long>");
17864 + else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
17865 + retval[1] = '\0';
17871 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17872 + char *buf, int buflen)
17876 + /* we can use real_root, real_root_mnt, because this is only called
17877 + by the RBAC system */
17878 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
17884 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17885 + char *buf, int buflen)
17888 + struct dentry *root;
17889 + struct vfsmount *rootmnt;
17890 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
17892 + /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
17893 + read_lock(&reaper->fs->lock);
17894 + root = dget(reaper->fs->root.dentry);
17895 + rootmnt = mntget(reaper->fs->root.mnt);
17896 + read_unlock(&reaper->fs->lock);
17898 + spin_lock(&dcache_lock);
17899 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
17900 + spin_unlock(&dcache_lock);
17908 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
17911 + spin_lock(&dcache_lock);
17912 + ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17914 + spin_unlock(&dcache_lock);
17919 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
17921 + return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17926 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
17928 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
17933 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
17935 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
17940 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
17942 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
17947 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
17949 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
17954 +to_gr_audit(const __u32 reqmode)
17956 + /* masks off auditable permission flags, then shifts them to create
17957 + auditing flags, and adds the special case of append auditing if
17958 + we're requesting write */
17959 + return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
17962 +struct acl_subject_label *
17963 +lookup_subject_map(const struct acl_subject_label *userp)
17965 + unsigned int index = shash(userp, subj_map_set.s_size);
17966 + struct subject_map *match;
17968 + match = subj_map_set.s_hash[index];
17970 + while (match && match->user != userp)
17971 + match = match->next;
17973 + if (match != NULL)
17974 + return match->kernel;
17980 +insert_subj_map_entry(struct subject_map *subjmap)
17982 + unsigned int index = shash(subjmap->user, subj_map_set.s_size);
17983 + struct subject_map **curr;
17985 + subjmap->prev = NULL;
17987 + curr = &subj_map_set.s_hash[index];
17988 + if (*curr != NULL)
17989 + (*curr)->prev = subjmap;
17991 + subjmap->next = *curr;
17997 +static struct acl_role_label *
17998 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
18001 + unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
18002 + struct acl_role_label *match;
18003 + struct role_allowed_ip *ipp;
18006 + match = acl_role_set.r_hash[index];
18009 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
18010 + for (x = 0; x < match->domain_child_num; x++) {
18011 + if (match->domain_children[x] == uid)
18014 + } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
18016 + match = match->next;
18019 + if (match == NULL) {
18021 + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
18022 + match = acl_role_set.r_hash[index];
18025 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
18026 + for (x = 0; x < match->domain_child_num; x++) {
18027 + if (match->domain_children[x] == gid)
18030 + } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
18032 + match = match->next;
18035 + if (match == NULL)
18036 + match = default_role;
18037 + if (match->allowed_ips == NULL)
18040 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
18042 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
18043 + (ntohl(ipp->addr) & ipp->netmask)))
18046 + match = default_role;
18048 + } else if (match->allowed_ips == NULL) {
18051 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
18053 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
18054 + (ntohl(ipp->addr) & ipp->netmask)))
18063 +struct acl_subject_label *
18064 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
18065 + const struct acl_role_label *role)
18067 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
18068 + struct acl_subject_label *match;
18070 + match = role->subj_hash[index];
18072 + while (match && (match->inode != ino || match->device != dev ||
18073 + (match->mode & GR_DELETED))) {
18074 + match = match->next;
18077 + if (match && !(match->mode & GR_DELETED))
18083 +static struct acl_object_label *
18084 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
18085 + const struct acl_subject_label *subj)
18087 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
18088 + struct acl_object_label *match;
18090 + match = subj->obj_hash[index];
18092 + while (match && (match->inode != ino || match->device != dev ||
18093 + (match->mode & GR_DELETED))) {
18094 + match = match->next;
18097 + if (match && !(match->mode & GR_DELETED))
18103 +static struct acl_object_label *
18104 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
18105 + const struct acl_subject_label *subj)
18107 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
18108 + struct acl_object_label *match;
18110 + match = subj->obj_hash[index];
18112 + while (match && (match->inode != ino || match->device != dev ||
18113 + !(match->mode & GR_DELETED))) {
18114 + match = match->next;
18117 + if (match && (match->mode & GR_DELETED))
18120 + match = subj->obj_hash[index];
18122 + while (match && (match->inode != ino || match->device != dev ||
18123 + (match->mode & GR_DELETED))) {
18124 + match = match->next;
18127 + if (match && !(match->mode & GR_DELETED))
18133 +static struct name_entry *
18134 +lookup_name_entry(const char *name)
18136 + unsigned int len = strlen(name);
18137 + unsigned int key = full_name_hash(name, len);
18138 + unsigned int index = key % name_set.n_size;
18139 + struct name_entry *match;
18141 + match = name_set.n_hash[index];
18143 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
18144 + match = match->next;
18149 +static struct name_entry *
18150 +lookup_name_entry_create(const char *name)
18152 + unsigned int len = strlen(name);
18153 + unsigned int key = full_name_hash(name, len);
18154 + unsigned int index = key % name_set.n_size;
18155 + struct name_entry *match;
18157 + match = name_set.n_hash[index];
18159 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
18160 + !match->deleted))
18161 + match = match->next;
18163 + if (match && match->deleted)
18166 + match = name_set.n_hash[index];
18168 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
18170 + match = match->next;
18172 + if (match && !match->deleted)
18178 +static struct inodev_entry *
18179 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
18181 + unsigned int index = fhash(ino, dev, inodev_set.i_size);
18182 + struct inodev_entry *match;
18184 + match = inodev_set.i_hash[index];
18186 + while (match && (match->nentry->inode != ino || match->nentry->device != dev))
18187 + match = match->next;
18193 +insert_inodev_entry(struct inodev_entry *entry)
18195 + unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
18196 + inodev_set.i_size);
18197 + struct inodev_entry **curr;
18199 + entry->prev = NULL;
18201 + curr = &inodev_set.i_hash[index];
18202 + if (*curr != NULL)
18203 + (*curr)->prev = entry;
18205 + entry->next = *curr;
18212 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
18214 + unsigned int index =
18215 + rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
18216 + struct acl_role_label **curr;
18218 + role->prev = NULL;
18220 + curr = &acl_role_set.r_hash[index];
18221 + if (*curr != NULL)
18222 + (*curr)->prev = role;
18224 + role->next = *curr;
18231 +insert_acl_role_label(struct acl_role_label *role)
18235 + if (role->roletype & GR_ROLE_DOMAIN) {
18236 + for (i = 0; i < role->domain_child_num; i++)
18237 + __insert_acl_role_label(role, role->domain_children[i]);
18239 + __insert_acl_role_label(role, role->uidgid);
18243 +insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
18245 + struct name_entry **curr, *nentry;
18246 + struct inodev_entry *ientry;
18247 + unsigned int len = strlen(name);
18248 + unsigned int key = full_name_hash(name, len);
18249 + unsigned int index = key % name_set.n_size;
18251 + curr = &name_set.n_hash[index];
18253 + while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
18254 + curr = &((*curr)->next);
18256 + if (*curr != NULL)
18259 + nentry = acl_alloc(sizeof (struct name_entry));
18260 + if (nentry == NULL)
18262 + ientry = acl_alloc(sizeof (struct inodev_entry));
18263 + if (ientry == NULL)
18265 + ientry->nentry = nentry;
18267 + nentry->key = key;
18268 + nentry->name = name;
18269 + nentry->inode = inode;
18270 + nentry->device = device;
18271 + nentry->len = len;
18272 + nentry->deleted = deleted;
18274 + nentry->prev = NULL;
18275 + curr = &name_set.n_hash[index];
18276 + if (*curr != NULL)
18277 + (*curr)->prev = nentry;
18278 + nentry->next = *curr;
18281 + /* insert us into the table searchable by inode/dev */
18282 + insert_inodev_entry(ientry);
18288 +insert_acl_obj_label(struct acl_object_label *obj,
18289 + struct acl_subject_label *subj)
18291 + unsigned int index =
18292 + fhash(obj->inode, obj->device, subj->obj_hash_size);
18293 + struct acl_object_label **curr;
18296 + obj->prev = NULL;
18298 + curr = &subj->obj_hash[index];
18299 + if (*curr != NULL)
18300 + (*curr)->prev = obj;
18302 + obj->next = *curr;
18309 +insert_acl_subj_label(struct acl_subject_label *obj,
18310 + struct acl_role_label *role)
18312 + unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
18313 + struct acl_subject_label **curr;
18315 + obj->prev = NULL;
18317 + curr = &role->subj_hash[index];
18318 + if (*curr != NULL)
18319 + (*curr)->prev = obj;
18321 + obj->next = *curr;
18327 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
18330 +create_table(__u32 * len, int elementsize)
18332 + unsigned int table_sizes[] = {
18333 + 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
18334 + 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
18335 + 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
18336 + 268435399, 536870909, 1073741789, 2147483647
18338 + void *newtable = NULL;
18339 + unsigned int pwr = 0;
18341 + while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
18342 + table_sizes[pwr] <= *len)
18345 + if (table_sizes[pwr] <= *len)
18348 + if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
18350 + kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
18352 + newtable = vmalloc(table_sizes[pwr] * elementsize);
18354 + *len = table_sizes[pwr];
18360 +init_variables(const struct gr_arg *arg)
18362 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
18363 + unsigned int stacksize;
18365 + subj_map_set.s_size = arg->role_db.num_subjects;
18366 + acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
18367 + name_set.n_size = arg->role_db.num_objects;
18368 + inodev_set.i_size = arg->role_db.num_objects;
18370 + if (!subj_map_set.s_size || !acl_role_set.r_size ||
18371 + !name_set.n_size || !inodev_set.i_size)
18374 + if (!gr_init_uidset())
18377 + /* set up the stack that holds allocation info */
18379 + stacksize = arg->role_db.num_pointers + 5;
18381 + if (!acl_alloc_stack_init(stacksize))
18384 + /* grab reference for the real root dentry and vfsmount */
18385 + read_lock(&reaper->fs->lock);
18386 + real_root_mnt = mntget(reaper->fs->root.mnt);
18387 + real_root = dget(reaper->fs->root.dentry);
18388 + read_unlock(&reaper->fs->lock);
18390 + fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
18391 + if (fakefs_obj == NULL)
18393 + fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
18395 + subj_map_set.s_hash =
18396 + (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
18397 + acl_role_set.r_hash =
18398 + (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
18399 + name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
18400 + inodev_set.i_hash =
18401 + (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
18403 + if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
18404 + !name_set.n_hash || !inodev_set.i_hash)
18407 + memset(subj_map_set.s_hash, 0,
18408 + sizeof(struct subject_map *) * subj_map_set.s_size);
18409 + memset(acl_role_set.r_hash, 0,
18410 + sizeof (struct acl_role_label *) * acl_role_set.r_size);
18411 + memset(name_set.n_hash, 0,
18412 + sizeof (struct name_entry *) * name_set.n_size);
18413 + memset(inodev_set.i_hash, 0,
18414 + sizeof (struct inodev_entry *) * inodev_set.i_size);
18419 +/* free information not needed after startup
18420 + currently contains user->kernel pointer mappings for subjects
18424 +free_init_variables(void)
18428 + if (subj_map_set.s_hash) {
18429 + for (i = 0; i < subj_map_set.s_size; i++) {
18430 + if (subj_map_set.s_hash[i]) {
18431 + kfree(subj_map_set.s_hash[i]);
18432 + subj_map_set.s_hash[i] = NULL;
18436 + if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
18438 + kfree(subj_map_set.s_hash);
18440 + vfree(subj_map_set.s_hash);
18447 +free_variables(void)
18449 + struct acl_subject_label *s;
18450 + struct acl_role_label *r;
18451 + struct task_struct *task, *task2;
18452 + unsigned int i, x;
18454 + gr_clear_learn_entries();
18456 + read_lock(&tasklist_lock);
18457 + do_each_thread(task2, task) {
18458 + task->acl_sp_role = 0;
18459 + task->acl_role_id = 0;
18460 + task->acl = NULL;
18461 + task->role = NULL;
18462 + } while_each_thread(task2, task);
18463 + read_unlock(&tasklist_lock);
18465 + /* release the reference to the real root dentry and vfsmount */
18468 + real_root = NULL;
18469 + if (real_root_mnt)
18470 + mntput(real_root_mnt);
18471 + real_root_mnt = NULL;
18473 + /* free all object hash tables */
18475 + FOR_EACH_ROLE_START(r, i)
18476 + if (r->subj_hash == NULL)
18478 + FOR_EACH_SUBJECT_START(r, s, x)
18479 + if (s->obj_hash == NULL)
18481 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
18482 + kfree(s->obj_hash);
18484 + vfree(s->obj_hash);
18485 + FOR_EACH_SUBJECT_END(s, x)
18486 + FOR_EACH_NESTED_SUBJECT_START(r, s)
18487 + if (s->obj_hash == NULL)
18489 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
18490 + kfree(s->obj_hash);
18492 + vfree(s->obj_hash);
18493 + FOR_EACH_NESTED_SUBJECT_END(s)
18494 + if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
18495 + kfree(r->subj_hash);
18497 + vfree(r->subj_hash);
18498 + r->subj_hash = NULL;
18499 + FOR_EACH_ROLE_END(r,i)
18503 + if (acl_role_set.r_hash) {
18504 + if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
18506 + kfree(acl_role_set.r_hash);
18508 + vfree(acl_role_set.r_hash);
18510 + if (name_set.n_hash) {
18511 + if ((name_set.n_size * sizeof (struct name_entry *)) <=
18513 + kfree(name_set.n_hash);
18515 + vfree(name_set.n_hash);
18518 + if (inodev_set.i_hash) {
18519 + if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
18521 + kfree(inodev_set.i_hash);
18523 + vfree(inodev_set.i_hash);
18526 + gr_free_uidset();
18528 + memset(&name_set, 0, sizeof (struct name_db));
18529 + memset(&inodev_set, 0, sizeof (struct inodev_db));
18530 + memset(&acl_role_set, 0, sizeof (struct acl_role_db));
18531 + memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
18533 + default_role = NULL;
18539 +count_user_objs(struct acl_object_label *userp)
18541 + struct acl_object_label o_tmp;
18545 + if (copy_from_user(&o_tmp, userp,
18546 + sizeof (struct acl_object_label)))
18549 + userp = o_tmp.prev;
18556 +static struct acl_subject_label *
18557 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
18560 +copy_user_glob(struct acl_object_label *obj)
18562 + struct acl_object_label *g_tmp, **guser;
18563 + unsigned int len;
18566 + if (obj->globbed == NULL)
18569 + guser = &obj->globbed;
18571 + g_tmp = (struct acl_object_label *)
18572 + acl_alloc(sizeof (struct acl_object_label));
18573 + if (g_tmp == NULL)
18576 + if (copy_from_user(g_tmp, *guser,
18577 + sizeof (struct acl_object_label)))
18580 + len = strnlen_user(g_tmp->filename, PATH_MAX);
18582 + if (!len || len >= PATH_MAX)
18585 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18588 + if (copy_from_user(tmp, g_tmp->filename, len))
18591 + g_tmp->filename = tmp;
18594 + guser = &(g_tmp->next);
18601 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
18602 + struct acl_role_label *role)
18604 + struct acl_object_label *o_tmp;
18605 + unsigned int len;
18610 + if ((o_tmp = (struct acl_object_label *)
18611 + acl_alloc(sizeof (struct acl_object_label))) == NULL)
18614 + if (copy_from_user(o_tmp, userp,
18615 + sizeof (struct acl_object_label)))
18618 + userp = o_tmp->prev;
18620 + len = strnlen_user(o_tmp->filename, PATH_MAX);
18622 + if (!len || len >= PATH_MAX)
18625 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18628 + if (copy_from_user(tmp, o_tmp->filename, len))
18631 + o_tmp->filename = tmp;
18633 + insert_acl_obj_label(o_tmp, subj);
18634 + if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
18635 + o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
18638 + ret = copy_user_glob(o_tmp);
18642 + if (o_tmp->nested) {
18643 + o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
18644 + if (IS_ERR(o_tmp->nested))
18645 + return PTR_ERR(o_tmp->nested);
18647 + /* insert into nested subject list */
18648 + o_tmp->nested->next = role->hash->first;
18649 + role->hash->first = o_tmp->nested;
18657 +count_user_subjs(struct acl_subject_label *userp)
18659 + struct acl_subject_label s_tmp;
18663 + if (copy_from_user(&s_tmp, userp,
18664 + sizeof (struct acl_subject_label)))
18667 + userp = s_tmp.prev;
18668 + /* do not count nested subjects against this count, since
18669 + they are not included in the hash table, but are
18670 + attached to objects. We have already counted
18671 + the subjects in userspace for the allocation
18674 + if (!(s_tmp.mode & GR_NESTED))
18682 +copy_user_allowedips(struct acl_role_label *rolep)
18684 + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
18686 + ruserip = rolep->allowed_ips;
18688 + while (ruserip) {
18691 + if ((rtmp = (struct role_allowed_ip *)
18692 + acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
18695 + if (copy_from_user(rtmp, ruserip,
18696 + sizeof (struct role_allowed_ip)))
18699 + ruserip = rtmp->prev;
18702 + rtmp->prev = NULL;
18703 + rolep->allowed_ips = rtmp;
18705 + rlast->next = rtmp;
18706 + rtmp->prev = rlast;
18710 + rtmp->next = NULL;
18717 +copy_user_transitions(struct acl_role_label *rolep)
18719 + struct role_transition *rusertp, *rtmp = NULL, *rlast;
18721 + unsigned int len;
18724 + rusertp = rolep->transitions;
18726 + while (rusertp) {
18729 + if ((rtmp = (struct role_transition *)
18730 + acl_alloc(sizeof (struct role_transition))) == NULL)
18733 + if (copy_from_user(rtmp, rusertp,
18734 + sizeof (struct role_transition)))
18737 + rusertp = rtmp->prev;
18739 + len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
18741 + if (!len || len >= GR_SPROLE_LEN)
18744 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18747 + if (copy_from_user(tmp, rtmp->rolename, len))
18750 + rtmp->rolename = tmp;
18753 + rtmp->prev = NULL;
18754 + rolep->transitions = rtmp;
18756 + rlast->next = rtmp;
18757 + rtmp->prev = rlast;
18761 + rtmp->next = NULL;
18767 +static struct acl_subject_label *
18768 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
18770 + struct acl_subject_label *s_tmp = NULL, *s_tmp2;
18771 + unsigned int len;
18774 + struct acl_ip_label **i_tmp, *i_utmp2;
18775 + struct gr_hash_struct ghash;
18776 + struct subject_map *subjmap;
18777 + unsigned int i_num;
18780 + s_tmp = lookup_subject_map(userp);
18782 + /* we've already copied this subject into the kernel, just return
18783 + the reference to it, and don't copy it over again
18788 + if ((s_tmp = (struct acl_subject_label *)
18789 + acl_alloc(sizeof (struct acl_subject_label))) == NULL)
18790 + return ERR_PTR(-ENOMEM);
18792 + subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
18793 + if (subjmap == NULL)
18794 + return ERR_PTR(-ENOMEM);
18796 + subjmap->user = userp;
18797 + subjmap->kernel = s_tmp;
18798 + insert_subj_map_entry(subjmap);
18800 + if (copy_from_user(s_tmp, userp,
18801 + sizeof (struct acl_subject_label)))
18802 + return ERR_PTR(-EFAULT);
18804 + len = strnlen_user(s_tmp->filename, PATH_MAX);
18806 + if (!len || len >= PATH_MAX)
18807 + return ERR_PTR(-EINVAL);
18809 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18810 + return ERR_PTR(-ENOMEM);
18812 + if (copy_from_user(tmp, s_tmp->filename, len))
18813 + return ERR_PTR(-EFAULT);
18815 + s_tmp->filename = tmp;
18817 + if (!strcmp(s_tmp->filename, "/"))
18818 + role->root_label = s_tmp;
18820 + if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
18821 + return ERR_PTR(-EFAULT);
18823 + /* copy user and group transition tables */
18825 + if (s_tmp->user_trans_num) {
18828 + uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
18829 + if (uidlist == NULL)
18830 + return ERR_PTR(-ENOMEM);
18831 + if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
18832 + return ERR_PTR(-EFAULT);
18834 + s_tmp->user_transitions = uidlist;
18837 + if (s_tmp->group_trans_num) {
18840 + gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
18841 + if (gidlist == NULL)
18842 + return ERR_PTR(-ENOMEM);
18843 + if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
18844 + return ERR_PTR(-EFAULT);
18846 + s_tmp->group_transitions = gidlist;
18849 + /* set up object hash table */
18850 + num_objs = count_user_objs(ghash.first);
18852 + s_tmp->obj_hash_size = num_objs;
18853 + s_tmp->obj_hash =
18854 + (struct acl_object_label **)
18855 + create_table(&(s_tmp->obj_hash_size), sizeof(void *));
18857 + if (!s_tmp->obj_hash)
18858 + return ERR_PTR(-ENOMEM);
18860 + memset(s_tmp->obj_hash, 0,
18861 + s_tmp->obj_hash_size *
18862 + sizeof (struct acl_object_label *));
18864 + /* add in objects */
18865 + err = copy_user_objs(ghash.first, s_tmp, role);
18868 + return ERR_PTR(err);
18870 + /* set pointer for parent subject */
18871 + if (s_tmp->parent_subject) {
18872 + s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
18874 + if (IS_ERR(s_tmp2))
18877 + s_tmp->parent_subject = s_tmp2;
18880 + /* add in ip acls */
18882 + if (!s_tmp->ip_num) {
18883 + s_tmp->ips = NULL;
18888 + (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
18890 + acl_ip_label *));
18893 + return ERR_PTR(-ENOMEM);
18895 + for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
18896 + *(i_tmp + i_num) =
18897 + (struct acl_ip_label *)
18898 + acl_alloc(sizeof (struct acl_ip_label));
18899 + if (!*(i_tmp + i_num))
18900 + return ERR_PTR(-ENOMEM);
18902 + if (copy_from_user
18903 + (&i_utmp2, s_tmp->ips + i_num,
18904 + sizeof (struct acl_ip_label *)))
18905 + return ERR_PTR(-EFAULT);
18907 + if (copy_from_user
18908 + (*(i_tmp + i_num), i_utmp2,
18909 + sizeof (struct acl_ip_label)))
18910 + return ERR_PTR(-EFAULT);
18912 + if ((*(i_tmp + i_num))->iface == NULL)
18915 + len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
18916 + if (!len || len >= IFNAMSIZ)
18917 + return ERR_PTR(-EINVAL);
18918 + tmp = acl_alloc(len);
18920 + return ERR_PTR(-ENOMEM);
18921 + if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
18922 + return ERR_PTR(-EFAULT);
18923 + (*(i_tmp + i_num))->iface = tmp;
18926 + s_tmp->ips = i_tmp;
18929 + if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
18930 + s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
18931 + return ERR_PTR(-ENOMEM);
18937 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
18939 + struct acl_subject_label s_pre;
18940 + struct acl_subject_label * ret;
18944 + if (copy_from_user(&s_pre, userp,
18945 + sizeof (struct acl_subject_label)))
18948 + /* do not add nested subjects here, add
18949 + while parsing objects
18952 + if (s_pre.mode & GR_NESTED) {
18953 + userp = s_pre.prev;
18957 + ret = do_copy_user_subj(userp, role);
18959 + err = PTR_ERR(ret);
18963 + insert_acl_subj_label(ret, role);
18965 + userp = s_pre.prev;
18972 +copy_user_acl(struct gr_arg *arg)
18974 + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
18975 + struct sprole_pw *sptmp;
18976 + struct gr_hash_struct *ghash;
18977 + uid_t *domainlist;
18978 + unsigned int r_num;
18979 + unsigned int len;
18985 + /* we need a default and kernel role */
18986 + if (arg->role_db.num_roles < 2)
18989 + /* copy special role authentication info from userspace */
18991 + num_sprole_pws = arg->num_sprole_pws;
18992 + acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
18994 + if (!acl_special_roles) {
18999 + for (i = 0; i < num_sprole_pws; i++) {
19000 + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
19005 + if (copy_from_user(sptmp, arg->sprole_pws + i,
19006 + sizeof (struct sprole_pw))) {
19012 + strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
19014 + if (!len || len >= GR_SPROLE_LEN) {
19019 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
19024 + if (copy_from_user(tmp, sptmp->rolename, len)) {
19029 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19030 + printk(KERN_ALERT "Copying special role %s\n", tmp);
19032 + sptmp->rolename = tmp;
19033 + acl_special_roles[i] = sptmp;
19036 + r_utmp = (struct acl_role_label **) arg->role_db.r_table;
19038 + for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
19039 + r_tmp = acl_alloc(sizeof (struct acl_role_label));
19046 + if (copy_from_user(&r_utmp2, r_utmp + r_num,
19047 + sizeof (struct acl_role_label *))) {
19052 + if (copy_from_user(r_tmp, r_utmp2,
19053 + sizeof (struct acl_role_label))) {
19058 + len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
19060 + if (!len || len >= PATH_MAX) {
19065 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
19069 + if (copy_from_user(tmp, r_tmp->rolename, len)) {
19073 + r_tmp->rolename = tmp;
19075 + if (!strcmp(r_tmp->rolename, "default")
19076 + && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
19077 + default_role = r_tmp;
19078 + } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
19079 + kernel_role = r_tmp;
19082 + if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
19086 + if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
19091 + r_tmp->hash = ghash;
19093 + num_subjs = count_user_subjs(r_tmp->hash->first);
19095 + r_tmp->subj_hash_size = num_subjs;
19096 + r_tmp->subj_hash =
19097 + (struct acl_subject_label **)
19098 + create_table(&(r_tmp->subj_hash_size), sizeof(void *));
19100 + if (!r_tmp->subj_hash) {
19105 + err = copy_user_allowedips(r_tmp);
19109 + /* copy domain info */
19110 + if (r_tmp->domain_children != NULL) {
19111 + domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
19112 + if (domainlist == NULL) {
19116 + if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
19120 + r_tmp->domain_children = domainlist;
19123 + err = copy_user_transitions(r_tmp);
19127 + memset(r_tmp->subj_hash, 0,
19128 + r_tmp->subj_hash_size *
19129 + sizeof (struct acl_subject_label *));
19131 + err = copy_user_subjs(r_tmp->hash->first, r_tmp);
19136 + /* set nested subject list to null */
19137 + r_tmp->hash->first = NULL;
19139 + insert_acl_role_label(r_tmp);
19144 + free_variables();
19151 +gracl_init(struct gr_arg *args)
19155 + memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
19156 + memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
19158 + if (init_variables(args)) {
19159 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
19161 + free_variables();
19165 + error = copy_user_acl(args);
19166 + free_init_variables();
19168 + free_variables();
19172 + if ((error = gr_set_acls(0))) {
19173 + free_variables();
19177 + gr_status |= GR_READY;
19182 +/* derived from glibc fnmatch() 0: match, 1: no match*/
19185 +glob_match(const char *p, const char *n)
19189 + while ((c = *p++) != '\0') {
19194 + else if (*n == '/')
19202 + for (c = *p++; c == '?' || c == '*'; c = *p++) {
19205 + else if (c == '?') {
19215 + const char *endp;
19217 + if ((endp = strchr(n, '/')) == NULL)
19218 + endp = n + strlen(n);
19221 + for (--p; n < endp; ++n)
19222 + if (!glob_match(p, n))
19224 + } else if (c == '/') {
19225 + while (*n != '\0' && *n != '/')
19227 + if (*n == '/' && !glob_match(p, n + 1))
19230 + for (--p; n < endp; ++n)
19231 + if (*n == c && !glob_match(p, n))
19242 + if (*n == '\0' || *n == '/')
19245 + not = (*p == '!' || *p == '^');
19251 + unsigned char fn = (unsigned char)*n;
19261 + if (c == '-' && *p != ']') {
19262 + unsigned char cend = *p++;
19264 + if (cend == '\0')
19267 + if (cold <= fn && fn <= cend)
19281 + while (c != ']') {
19308 +static struct acl_object_label *
19309 +chk_glob_label(struct acl_object_label *globbed,
19310 + struct dentry *dentry, struct vfsmount *mnt, char **path)
19312 + struct acl_object_label *tmp;
19314 + if (*path == NULL)
19315 + *path = gr_to_filename_nolock(dentry, mnt);
19320 + if (!glob_match(tmp->filename, *path))
19328 +static struct acl_object_label *
19329 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
19330 + const ino_t curr_ino, const dev_t curr_dev,
19331 + const struct acl_subject_label *subj, char **path)
19333 + struct acl_subject_label *tmpsubj;
19334 + struct acl_object_label *retval;
19335 + struct acl_object_label *retval2;
19337 + tmpsubj = (struct acl_subject_label *) subj;
19338 + read_lock(&gr_inode_lock);
19340 + retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
19342 + if (retval->globbed) {
19343 + retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
19344 + (struct vfsmount *)orig_mnt, path);
19346 + retval = retval2;
19350 + } while ((tmpsubj = tmpsubj->parent_subject));
19351 + read_unlock(&gr_inode_lock);
19356 +static __inline__ struct acl_object_label *
19357 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
19358 + const struct dentry *curr_dentry,
19359 + const struct acl_subject_label *subj, char **path)
19361 + return __full_lookup(orig_dentry, orig_mnt,
19362 + curr_dentry->d_inode->i_ino,
19363 + curr_dentry->d_inode->i_sb->s_dev, subj, path);
19366 +static struct acl_object_label *
19367 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19368 + const struct acl_subject_label *subj, char *path)
19370 + struct dentry *dentry = (struct dentry *) l_dentry;
19371 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
19372 + struct acl_object_label *retval;
19374 + spin_lock(&dcache_lock);
19376 + if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
19377 + /* ignore Eric Biederman */
19378 + IS_PRIVATE(l_dentry->d_inode))) {
19379 + retval = fakefs_obj;
19384 + if (dentry == real_root && mnt == real_root_mnt)
19387 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
19388 + if (mnt->mnt_parent == mnt)
19391 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19392 + if (retval != NULL)
19395 + dentry = mnt->mnt_mountpoint;
19396 + mnt = mnt->mnt_parent;
19400 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19401 + if (retval != NULL)
19404 + dentry = dentry->d_parent;
19407 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19409 + if (retval == NULL)
19410 + retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
19412 + spin_unlock(&dcache_lock);
19416 +static __inline__ struct acl_object_label *
19417 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19418 + const struct acl_subject_label *subj)
19420 + char *path = NULL;
19421 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
19424 +static __inline__ struct acl_object_label *
19425 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19426 + const struct acl_subject_label *subj, char *path)
19428 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
19431 +static struct acl_subject_label *
19432 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19433 + const struct acl_role_label *role)
19435 + struct dentry *dentry = (struct dentry *) l_dentry;
19436 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
19437 + struct acl_subject_label *retval;
19439 + spin_lock(&dcache_lock);
19442 + if (dentry == real_root && mnt == real_root_mnt)
19444 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
19445 + if (mnt->mnt_parent == mnt)
19448 + read_lock(&gr_inode_lock);
19450 + lookup_acl_subj_label(dentry->d_inode->i_ino,
19451 + dentry->d_inode->i_sb->s_dev, role);
19452 + read_unlock(&gr_inode_lock);
19453 + if (retval != NULL)
19456 + dentry = mnt->mnt_mountpoint;
19457 + mnt = mnt->mnt_parent;
19461 + read_lock(&gr_inode_lock);
19462 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
19463 + dentry->d_inode->i_sb->s_dev, role);
19464 + read_unlock(&gr_inode_lock);
19465 + if (retval != NULL)
19468 + dentry = dentry->d_parent;
19471 + read_lock(&gr_inode_lock);
19472 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
19473 + dentry->d_inode->i_sb->s_dev, role);
19474 + read_unlock(&gr_inode_lock);
19476 + if (unlikely(retval == NULL)) {
19477 + read_lock(&gr_inode_lock);
19478 + retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
19479 + real_root->d_inode->i_sb->s_dev, role);
19480 + read_unlock(&gr_inode_lock);
19483 + spin_unlock(&dcache_lock);
19489 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
19491 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
19492 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19493 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19494 + 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
19500 +gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
19502 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
19503 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19504 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19505 + 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
19511 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
19512 + const unsigned int effective, const unsigned int fs)
19514 + security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
19515 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19516 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19517 + type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
19523 +gr_check_link(const struct dentry * new_dentry,
19524 + const struct dentry * parent_dentry,
19525 + const struct vfsmount * parent_mnt,
19526 + const struct dentry * old_dentry, const struct vfsmount * old_mnt)
19528 + struct acl_object_label *obj;
19529 + __u32 oldmode, newmode;
19532 + if (unlikely(!(gr_status & GR_READY)))
19533 + return (GR_CREATE | GR_LINK);
19535 + obj = chk_obj_label(old_dentry, old_mnt, current->acl);
19536 + oldmode = obj->mode;
19538 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19539 + oldmode |= (GR_CREATE | GR_LINK);
19541 + needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
19542 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
19543 + needmode |= GR_SETID | GR_AUDIT_SETID;
19546 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
19547 + oldmode | needmode);
19549 + needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
19550 + GR_SETID | GR_READ | GR_FIND | GR_DELETE |
19551 + GR_INHERIT | GR_AUDIT_INHERIT);
19553 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
19556 + if ((oldmode & needmode) != needmode)
19559 + needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
19560 + if ((newmode & needmode) != needmode)
19563 + if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
19566 + needmode = oldmode;
19567 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
19568 + needmode |= GR_SETID;
19570 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
19571 + gr_log_learn(current, old_dentry, old_mnt, needmode);
19572 + return (GR_CREATE | GR_LINK);
19573 + } else if (newmode & GR_SUPPRESS)
19574 + return GR_SUPPRESS;
19580 +gr_search_file(const struct dentry * dentry, const __u32 mode,
19581 + const struct vfsmount * mnt)
19583 + __u32 retval = mode;
19584 + struct acl_subject_label *curracl;
19585 + struct acl_object_label *currobj;
19587 + if (unlikely(!(gr_status & GR_READY)))
19588 + return (mode & ~GR_AUDITS);
19590 + curracl = current->acl;
19592 + currobj = chk_obj_label(dentry, mnt, curracl);
19593 + retval = currobj->mode & mode;
19596 + ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
19597 + && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
19598 + __u32 new_mode = mode;
19600 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19602 + retval = new_mode;
19604 + if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
19605 + new_mode |= GR_INHERIT;
19607 + if (!(mode & GR_NOLEARN))
19608 + gr_log_learn(current, dentry, mnt, new_mode);
19615 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
19616 + const struct vfsmount * mnt, const __u32 mode)
19618 + struct name_entry *match;
19619 + struct acl_object_label *matchpo;
19620 + struct acl_subject_label *curracl;
19624 + if (unlikely(!(gr_status & GR_READY)))
19625 + return (mode & ~GR_AUDITS);
19627 + preempt_disable();
19628 + path = gr_to_filename_rbac(new_dentry, mnt);
19629 + match = lookup_name_entry_create(path);
19632 + goto check_parent;
19634 + curracl = current->acl;
19636 + read_lock(&gr_inode_lock);
19637 + matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
19638 + read_unlock(&gr_inode_lock);
19641 + if ((matchpo->mode & mode) !=
19642 + (mode & ~(GR_AUDITS | GR_SUPPRESS))
19643 + && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
19644 + __u32 new_mode = mode;
19646 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19648 + gr_log_learn(current, new_dentry, mnt, new_mode);
19650 + preempt_enable();
19653 + preempt_enable();
19654 + return (matchpo->mode & mode);
19658 + curracl = current->acl;
19660 + matchpo = chk_obj_create_label(parent, mnt, curracl, path);
19661 + retval = matchpo->mode & mode;
19663 + if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
19664 + && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
19665 + __u32 new_mode = mode;
19667 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19669 + gr_log_learn(current, new_dentry, mnt, new_mode);
19670 + preempt_enable();
19674 + preempt_enable();
19679 +gr_check_hidden_task(const struct task_struct *task)
19681 + if (unlikely(!(gr_status & GR_READY)))
19684 + if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
19691 +gr_check_protected_task(const struct task_struct *task)
19693 + if (unlikely(!(gr_status & GR_READY) || !task))
19696 + if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
19697 + task->acl != current->acl)
19704 +gr_copy_label(struct task_struct *tsk)
19706 + tsk->signal->used_accept = 0;
19707 + tsk->acl_sp_role = 0;
19708 + tsk->acl_role_id = current->acl_role_id;
19709 + tsk->acl = current->acl;
19710 + tsk->role = current->role;
19711 + tsk->signal->curr_ip = current->signal->curr_ip;
19712 + if (current->exec_file)
19713 + get_file(current->exec_file);
19714 + tsk->exec_file = current->exec_file;
19715 + tsk->is_writable = current->is_writable;
19716 + if (unlikely(current->signal->used_accept))
19717 + current->signal->curr_ip = 0;
19723 +gr_set_proc_res(struct task_struct *task)
19725 + struct acl_subject_label *proc;
19726 + unsigned short i;
19728 + proc = task->acl;
19730 + if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
19733 + for (i = 0; i < (GR_NLIMITS - 1); i++) {
19734 + if (!(proc->resmask & (1 << i)))
19737 + task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
19738 + task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
19745 +gr_check_user_change(int real, int effective, int fs)
19752 + int effectiveok = 0;
19755 + if (unlikely(!(gr_status & GR_READY)))
19758 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19759 + gr_log_learn_id_change(current, 'u', real, effective, fs);
19761 + num = current->acl->user_trans_num;
19762 + uidlist = current->acl->user_transitions;
19764 + if (uidlist == NULL)
19769 + if (effective == -1)
19774 + if (current->acl->user_trans_type & GR_ID_ALLOW) {
19775 + for (i = 0; i < num; i++) {
19776 + curuid = (int)uidlist[i];
19777 + if (real == curuid)
19779 + if (effective == curuid)
19781 + if (fs == curuid)
19784 + } else if (current->acl->user_trans_type & GR_ID_DENY) {
19785 + for (i = 0; i < num; i++) {
19786 + curuid = (int)uidlist[i];
19787 + if (real == curuid)
19789 + if (effective == curuid)
19791 + if (fs == curuid)
19794 + /* not in deny list */
19802 + if (realok && effectiveok && fsok)
19805 + gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19811 +gr_check_group_change(int real, int effective, int fs)
19818 + int effectiveok = 0;
19821 + if (unlikely(!(gr_status & GR_READY)))
19824 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19825 + gr_log_learn_id_change(current, 'g', real, effective, fs);
19827 + num = current->acl->group_trans_num;
19828 + gidlist = current->acl->group_transitions;
19830 + if (gidlist == NULL)
19835 + if (effective == -1)
19840 + if (current->acl->group_trans_type & GR_ID_ALLOW) {
19841 + for (i = 0; i < num; i++) {
19842 + curgid = (int)gidlist[i];
19843 + if (real == curgid)
19845 + if (effective == curgid)
19847 + if (fs == curgid)
19850 + } else if (current->acl->group_trans_type & GR_ID_DENY) {
19851 + for (i = 0; i < num; i++) {
19852 + curgid = (int)gidlist[i];
19853 + if (real == curgid)
19855 + if (effective == curgid)
19857 + if (fs == curgid)
19860 + /* not in deny list */
19868 + if (realok && effectiveok && fsok)
19871 + gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19877 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
19879 + struct acl_role_label *role = task->role;
19880 + struct acl_subject_label *subj = NULL;
19881 + struct acl_object_label *obj;
19882 + struct file *filp;
19884 + if (unlikely(!(gr_status & GR_READY)))
19887 + filp = task->exec_file;
19889 + /* kernel process, we'll give them the kernel role */
19890 + if (unlikely(!filp)) {
19891 + task->role = kernel_role;
19892 + task->acl = kernel_role->root_label;
19894 + } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
19895 + role = lookup_acl_role_label(task, uid, gid);
19897 + /* perform subject lookup in possibly new role
19898 + we can use this result below in the case where role == task->role
19900 + subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
19902 + /* if we changed uid/gid, but result in the same role
19903 + and are using inheritance, don't lose the inherited subject
19904 + if current subject is other than what normal lookup
19905 + would result in, we arrived via inheritance, don't
19908 + if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
19909 + (subj == task->acl)))
19910 + task->acl = subj;
19912 + task->role = role;
19914 + task->is_writable = 0;
19916 + /* ignore additional mmap checks for processes that are writable
19917 + by the default ACL */
19918 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
19919 + if (unlikely(obj->mode & GR_WRITE))
19920 + task->is_writable = 1;
19921 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
19922 + if (unlikely(obj->mode & GR_WRITE))
19923 + task->is_writable = 1;
19925 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19926 + printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19929 + gr_set_proc_res(task);
19935 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
19937 + struct task_struct *task = current;
19938 + struct acl_subject_label *newacl;
19939 + struct acl_object_label *obj;
19942 + if (unlikely(!(gr_status & GR_READY)))
19945 + newacl = chk_subj_label(dentry, mnt, task->role);
19948 + if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
19949 + GR_POVERRIDE) && (task->acl != newacl) &&
19950 + !(task->role->roletype & GR_ROLE_GOD) &&
19951 + !gr_search_file(dentry, GR_PTRACERD, mnt) &&
19952 + !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
19953 + (atomic_read(&task->fs->count) > 1 ||
19954 + atomic_read(&task->files->count) > 1 ||
19955 + atomic_read(&task->sighand->count) > 1)) {
19956 + task_unlock(task);
19957 + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
19960 + task_unlock(task);
19962 + obj = chk_obj_label(dentry, mnt, task->acl);
19963 + retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
19965 + if (!(task->acl->mode & GR_INHERITLEARN) &&
19966 + ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
19968 + task->acl = obj->nested;
19970 + task->acl = newacl;
19971 + } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
19972 + gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
19974 + task->is_writable = 0;
19976 + /* ignore additional mmap checks for processes that are writable
19977 + by the default ACL */
19978 + obj = chk_obj_label(dentry, mnt, default_role->root_label);
19979 + if (unlikely(obj->mode & GR_WRITE))
19980 + task->is_writable = 1;
19981 + obj = chk_obj_label(dentry, mnt, task->role->root_label);
19982 + if (unlikely(obj->mode & GR_WRITE))
19983 + task->is_writable = 1;
19985 + gr_set_proc_res(task);
19987 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19988 + printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19993 +/* always called with valid inodev ptr */
19995 +do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
19997 + struct acl_object_label *matchpo;
19998 + struct acl_subject_label *matchps;
19999 + struct acl_subject_label *subj;
20000 + struct acl_role_label *role;
20001 + unsigned int i, x;
20003 + FOR_EACH_ROLE_START(role, i)
20004 + FOR_EACH_SUBJECT_START(role, subj, x)
20005 + if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
20006 + matchpo->mode |= GR_DELETED;
20007 + FOR_EACH_SUBJECT_END(subj,x)
20008 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
20009 + if (subj->inode == ino && subj->device == dev)
20010 + subj->mode |= GR_DELETED;
20011 + FOR_EACH_NESTED_SUBJECT_END(subj)
20012 + if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
20013 + matchps->mode |= GR_DELETED;
20014 + FOR_EACH_ROLE_END(role,i)
20016 + inodev->nentry->deleted = 1;
20022 +gr_handle_delete(const ino_t ino, const dev_t dev)
20024 + struct inodev_entry *inodev;
20026 + if (unlikely(!(gr_status & GR_READY)))
20029 + write_lock(&gr_inode_lock);
20030 + inodev = lookup_inodev_entry(ino, dev);
20031 + if (inodev != NULL)
20032 + do_handle_delete(inodev, ino, dev);
20033 + write_unlock(&gr_inode_lock);
20039 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
20040 + const ino_t newinode, const dev_t newdevice,
20041 + struct acl_subject_label *subj)
20043 + unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
20044 + struct acl_object_label *match;
20046 + match = subj->obj_hash[index];
20048 + while (match && (match->inode != oldinode ||
20049 + match->device != olddevice ||
20050 + !(match->mode & GR_DELETED)))
20051 + match = match->next;
20053 + if (match && (match->inode == oldinode)
20054 + && (match->device == olddevice)
20055 + && (match->mode & GR_DELETED)) {
20056 + if (match->prev == NULL) {
20057 + subj->obj_hash[index] = match->next;
20058 + if (match->next != NULL)
20059 + match->next->prev = NULL;
20061 + match->prev->next = match->next;
20062 + if (match->next != NULL)
20063 + match->next->prev = match->prev;
20065 + match->prev = NULL;
20066 + match->next = NULL;
20067 + match->inode = newinode;
20068 + match->device = newdevice;
20069 + match->mode &= ~GR_DELETED;
20071 + insert_acl_obj_label(match, subj);
20078 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
20079 + const ino_t newinode, const dev_t newdevice,
20080 + struct acl_role_label *role)
20082 + unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
20083 + struct acl_subject_label *match;
20085 + match = role->subj_hash[index];
20087 + while (match && (match->inode != oldinode ||
20088 + match->device != olddevice ||
20089 + !(match->mode & GR_DELETED)))
20090 + match = match->next;
20092 + if (match && (match->inode == oldinode)
20093 + && (match->device == olddevice)
20094 + && (match->mode & GR_DELETED)) {
20095 + if (match->prev == NULL) {
20096 + role->subj_hash[index] = match->next;
20097 + if (match->next != NULL)
20098 + match->next->prev = NULL;
20100 + match->prev->next = match->next;
20101 + if (match->next != NULL)
20102 + match->next->prev = match->prev;
20104 + match->prev = NULL;
20105 + match->next = NULL;
20106 + match->inode = newinode;
20107 + match->device = newdevice;
20108 + match->mode &= ~GR_DELETED;
20110 + insert_acl_subj_label(match, role);
20117 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
20118 + const ino_t newinode, const dev_t newdevice)
20120 + unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
20121 + struct inodev_entry *match;
20123 + match = inodev_set.i_hash[index];
20125 + while (match && (match->nentry->inode != oldinode ||
20126 + match->nentry->device != olddevice || !match->nentry->deleted))
20127 + match = match->next;
20129 + if (match && (match->nentry->inode == oldinode)
20130 + && (match->nentry->device == olddevice) &&
20131 + match->nentry->deleted) {
20132 + if (match->prev == NULL) {
20133 + inodev_set.i_hash[index] = match->next;
20134 + if (match->next != NULL)
20135 + match->next->prev = NULL;
20137 + match->prev->next = match->next;
20138 + if (match->next != NULL)
20139 + match->next->prev = match->prev;
20141 + match->prev = NULL;
20142 + match->next = NULL;
20143 + match->nentry->inode = newinode;
20144 + match->nentry->device = newdevice;
20145 + match->nentry->deleted = 0;
20147 + insert_inodev_entry(match);
20154 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
20155 + const struct vfsmount *mnt)
20157 + struct acl_subject_label *subj;
20158 + struct acl_role_label *role;
20159 + unsigned int i, x;
20161 + FOR_EACH_ROLE_START(role, i)
20162 + update_acl_subj_label(matchn->inode, matchn->device,
20163 + dentry->d_inode->i_ino,
20164 + dentry->d_inode->i_sb->s_dev, role);
20166 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
20167 + if ((subj->inode == dentry->d_inode->i_ino) &&
20168 + (subj->device == dentry->d_inode->i_sb->s_dev)) {
20169 + subj->inode = dentry->d_inode->i_ino;
20170 + subj->device = dentry->d_inode->i_sb->s_dev;
20172 + FOR_EACH_NESTED_SUBJECT_END(subj)
20173 + FOR_EACH_SUBJECT_START(role, subj, x)
20174 + update_acl_obj_label(matchn->inode, matchn->device,
20175 + dentry->d_inode->i_ino,
20176 + dentry->d_inode->i_sb->s_dev, subj);
20177 + FOR_EACH_SUBJECT_END(subj,x)
20178 + FOR_EACH_ROLE_END(role,i)
20180 + update_inodev_entry(matchn->inode, matchn->device,
20181 + dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
20187 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
20189 + struct name_entry *matchn;
20191 + if (unlikely(!(gr_status & GR_READY)))
20194 + preempt_disable();
20195 + matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
20197 + if (unlikely((unsigned long)matchn)) {
20198 + write_lock(&gr_inode_lock);
20199 + do_handle_create(matchn, dentry, mnt);
20200 + write_unlock(&gr_inode_lock);
20202 + preempt_enable();
20208 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
20209 + struct dentry *old_dentry,
20210 + struct dentry *new_dentry,
20211 + struct vfsmount *mnt, const __u8 replace)
20213 + struct name_entry *matchn;
20214 + struct inodev_entry *inodev;
20216 + /* vfs_rename swaps the name and parent link for old_dentry and
20218 + at this point, old_dentry has the new name, parent link, and inode
20219 + for the renamed file
20220 + if a file is being replaced by a rename, new_dentry has the inode
20221 + and name for the replaced file
20224 + if (unlikely(!(gr_status & GR_READY)))
20227 + preempt_disable();
20228 + matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
20230 + /* we wouldn't have to check d_inode if it weren't for
20231 + NFS silly-renaming
20234 + write_lock(&gr_inode_lock);
20235 + if (unlikely(replace && new_dentry->d_inode)) {
20236 + inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
20237 + new_dentry->d_inode->i_sb->s_dev);
20238 + if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
20239 + do_handle_delete(inodev, new_dentry->d_inode->i_ino,
20240 + new_dentry->d_inode->i_sb->s_dev);
20243 + inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
20244 + old_dentry->d_inode->i_sb->s_dev);
20245 + if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
20246 + do_handle_delete(inodev, old_dentry->d_inode->i_ino,
20247 + old_dentry->d_inode->i_sb->s_dev);
20249 + if (unlikely((unsigned long)matchn))
20250 + do_handle_create(matchn, old_dentry, mnt);
20252 + write_unlock(&gr_inode_lock);
20253 + preempt_enable();
20259 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
20260 + unsigned char **sum)
20262 + struct acl_role_label *r;
20263 + struct role_allowed_ip *ipp;
20264 + struct role_transition *trans;
20268 + /* check transition table */
20270 + for (trans = current->role->transitions; trans; trans = trans->next) {
20271 + if (!strcmp(rolename, trans->rolename)) {
20280 + /* handle special roles that do not require authentication
20283 + FOR_EACH_ROLE_START(r, i)
20284 + if (!strcmp(rolename, r->rolename) &&
20285 + (r->roletype & GR_ROLE_SPECIAL)) {
20287 + if (r->allowed_ips != NULL) {
20288 + for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
20289 + if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
20290 + (ntohl(ipp->addr) & ipp->netmask))
20298 + if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
20299 + ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
20305 + FOR_EACH_ROLE_END(r,i)
20307 + for (i = 0; i < num_sprole_pws; i++) {
20308 + if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
20309 + *salt = acl_special_roles[i]->salt;
20310 + *sum = acl_special_roles[i]->sum;
20319 +assign_special_role(char *rolename)
20321 + struct acl_object_label *obj;
20322 + struct acl_role_label *r;
20323 + struct acl_role_label *assigned = NULL;
20324 + struct task_struct *tsk;
20325 + struct file *filp;
20328 + FOR_EACH_ROLE_START(r, i)
20329 + if (!strcmp(rolename, r->rolename) &&
20330 + (r->roletype & GR_ROLE_SPECIAL))
20332 + FOR_EACH_ROLE_END(r,i)
20337 + read_lock(&tasklist_lock);
20338 + read_lock(&grsec_exec_file_lock);
20340 + tsk = current->parent;
20344 + filp = tsk->exec_file;
20345 + if (filp == NULL)
20348 + tsk->is_writable = 0;
20350 + tsk->acl_sp_role = 1;
20351 + tsk->acl_role_id = ++acl_sp_role_value;
20352 + tsk->role = assigned;
20353 + tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
20355 + /* ignore additional mmap checks for processes that are writable
20356 + by the default ACL */
20357 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20358 + if (unlikely(obj->mode & GR_WRITE))
20359 + tsk->is_writable = 1;
20360 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
20361 + if (unlikely(obj->mode & GR_WRITE))
20362 + tsk->is_writable = 1;
20364 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20365 + printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
20369 + read_unlock(&grsec_exec_file_lock);
20370 + read_unlock(&tasklist_lock);
20374 +int gr_check_secure_terminal(struct task_struct *task)
20376 + struct task_struct *p, *p2, *p3;
20377 + struct files_struct *files;
20378 + struct fdtable *fdt;
20379 + struct file *our_file = NULL, *file;
20382 + if (task->signal->tty == NULL)
20385 + files = get_files_struct(task);
20386 + if (files != NULL) {
20388 + fdt = files_fdtable(files);
20389 + for (i=0; i < fdt->max_fds; i++) {
20390 + file = fcheck_files(files, i);
20391 + if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
20396 + rcu_read_unlock();
20397 + put_files_struct(files);
20400 + if (our_file == NULL)
20403 + read_lock(&tasklist_lock);
20404 + do_each_thread(p2, p) {
20405 + files = get_files_struct(p);
20406 + if (files == NULL ||
20407 + (p->signal && p->signal->tty == task->signal->tty)) {
20408 + if (files != NULL)
20409 + put_files_struct(files);
20413 + fdt = files_fdtable(files);
20414 + for (i=0; i < fdt->max_fds; i++) {
20415 + file = fcheck_files(files, i);
20416 + if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
20417 + file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
20419 + while (p3->pid > 0) {
20426 + gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
20427 + gr_handle_alertkill(p);
20428 + rcu_read_unlock();
20429 + put_files_struct(files);
20430 + read_unlock(&tasklist_lock);
20435 + rcu_read_unlock();
20436 + put_files_struct(files);
20437 + } while_each_thread(p2, p);
20438 + read_unlock(&tasklist_lock);
20445 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
20447 + struct gr_arg_wrapper uwrap;
20448 + unsigned char *sprole_salt;
20449 + unsigned char *sprole_sum;
20450 + int error = sizeof (struct gr_arg_wrapper);
20453 + down(&gr_dev_sem);
20455 + if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
20460 + if (count != sizeof (struct gr_arg_wrapper)) {
20461 + gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
20467 + if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
20468 + gr_auth_expires = 0;
20469 + gr_auth_attempts = 0;
20472 + if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
20477 + if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
20482 + if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
20487 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
20488 + gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
20489 + time_after(gr_auth_expires, get_seconds())) {
20494 + /* if non-root trying to do anything other than use a special role,
20495 + do not attempt authentication, do not count towards authentication
20499 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
20500 + gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
20506 + /* ensure pw and special role name are null terminated */
20508 + gr_usermode->pw[GR_PW_LEN - 1] = '\0';
20509 + gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
20512 + * We have our enough of the argument structure..(we have yet
20513 + * to copy_from_user the tables themselves) . Copy the tables
20514 + * only if we need them, i.e. for loading operations. */
20516 + switch (gr_usermode->mode) {
20518 + if (gr_status & GR_READY) {
20520 + if (!gr_check_secure_terminal(current))
20526 + if ((gr_status & GR_READY)
20527 + && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20528 + gr_status &= ~GR_READY;
20529 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
20530 + free_variables();
20531 + memset(gr_usermode, 0, sizeof (struct gr_arg));
20532 + memset(gr_system_salt, 0, GR_SALT_LEN);
20533 + memset(gr_system_sum, 0, GR_SHA_LEN);
20534 + } else if (gr_status & GR_READY) {
20535 + gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
20538 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
20543 + if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
20544 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
20546 + if (gr_status & GR_READY)
20550 + gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
20554 + if (!(gr_status & GR_READY)) {
20555 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
20557 + } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20559 + gr_status &= ~GR_READY;
20560 + free_variables();
20561 + if (!(error2 = gracl_init(gr_usermode))) {
20563 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
20567 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
20570 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
20575 + if (unlikely(!(gr_status & GR_READY))) {
20576 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
20581 + if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20582 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
20583 + if (gr_usermode->segv_device && gr_usermode->segv_inode) {
20584 + struct acl_subject_label *segvacl;
20586 + lookup_acl_subj_label(gr_usermode->segv_inode,
20587 + gr_usermode->segv_device,
20590 + segvacl->crashes = 0;
20591 + segvacl->expires = 0;
20593 + } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
20594 + gr_remove_uid(gr_usermode->segv_uid);
20597 + gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
20603 + if (unlikely(!(gr_status & GR_READY))) {
20604 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
20609 + if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
20610 + current->role->expires = 0;
20611 + current->role->auth_attempts = 0;
20614 + if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
20615 + time_after(current->role->expires, get_seconds())) {
20620 + if (lookup_special_role_auth
20621 + (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
20622 + && ((!sprole_salt && !sprole_sum)
20623 + || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
20625 + assign_special_role(gr_usermode->sp_role);
20626 + read_lock(&tasklist_lock);
20627 + if (current->parent)
20628 + p = current->parent->role->rolename;
20629 + read_unlock(&tasklist_lock);
20630 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
20631 + p, acl_sp_role_value);
20633 + gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
20635 + if(!(current->role->auth_attempts++))
20636 + current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20642 + if (unlikely(!(gr_status & GR_READY))) {
20643 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
20648 + if (current->role->roletype & GR_ROLE_SPECIAL) {
20652 + read_lock(&tasklist_lock);
20653 + if (current->parent) {
20654 + p = current->parent->role->rolename;
20655 + i = current->parent->acl_role_id;
20657 + read_unlock(&tasklist_lock);
20659 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
20662 + gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
20668 + gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
20673 + if (error != -EPERM)
20676 + if(!(gr_auth_attempts++))
20677 + gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20685 +gr_set_acls(const int type)
20687 + struct acl_object_label *obj;
20688 + struct task_struct *task, *task2;
20689 + struct file *filp;
20690 + struct acl_role_label *role = current->role;
20691 + __u16 acl_role_id = current->acl_role_id;
20693 + read_lock(&tasklist_lock);
20694 + read_lock(&grsec_exec_file_lock);
20695 + do_each_thread(task2, task) {
20696 + /* check to see if we're called from the exit handler,
20697 + if so, only replace ACLs that have inherited the admin
20700 + if (type && (task->role != role ||
20701 + task->acl_role_id != acl_role_id))
20704 + task->acl_role_id = 0;
20705 + task->acl_sp_role = 0;
20707 + if ((filp = task->exec_file)) {
20708 + task->role = lookup_acl_role_label(task, task->uid, task->gid);
20711 + chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
20714 + struct acl_subject_label *curr;
20715 + curr = task->acl;
20717 + task->is_writable = 0;
20718 + /* ignore additional mmap checks for processes that are writable
20719 + by the default ACL */
20720 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20721 + if (unlikely(obj->mode & GR_WRITE))
20722 + task->is_writable = 1;
20723 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
20724 + if (unlikely(obj->mode & GR_WRITE))
20725 + task->is_writable = 1;
20727 + gr_set_proc_res(task);
20729 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20730 + printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
20733 + read_unlock(&grsec_exec_file_lock);
20734 + read_unlock(&tasklist_lock);
20735 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
20739 + // it's a kernel process
20740 + task->role = kernel_role;
20741 + task->acl = kernel_role->root_label;
20742 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
20743 + task->acl->mode &= ~GR_PROCFIND;
20746 + } while_each_thread(task2, task);
20747 + read_unlock(&grsec_exec_file_lock);
20748 + read_unlock(&tasklist_lock);
20753 +gr_learn_resource(const struct task_struct *task,
20754 + const int res, const unsigned long wanted, const int gt)
20756 + struct acl_subject_label *acl;
20758 + if (unlikely((gr_status & GR_READY) &&
20759 + task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
20760 + goto skip_reslog;
20762 +#ifdef CONFIG_GRKERNSEC_RESLOG
20763 + gr_log_resource(task, res, wanted, gt);
20767 + if (unlikely(!(gr_status & GR_READY) || !wanted))
20772 + if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
20773 + !(acl->resmask & (1 << (unsigned short) res))))
20776 + if (wanted >= acl->res[res].rlim_cur) {
20777 + unsigned long res_add;
20779 + res_add = wanted;
20782 + res_add += GR_RLIM_CPU_BUMP;
20784 + case RLIMIT_FSIZE:
20785 + res_add += GR_RLIM_FSIZE_BUMP;
20787 + case RLIMIT_DATA:
20788 + res_add += GR_RLIM_DATA_BUMP;
20790 + case RLIMIT_STACK:
20791 + res_add += GR_RLIM_STACK_BUMP;
20793 + case RLIMIT_CORE:
20794 + res_add += GR_RLIM_CORE_BUMP;
20797 + res_add += GR_RLIM_RSS_BUMP;
20799 + case RLIMIT_NPROC:
20800 + res_add += GR_RLIM_NPROC_BUMP;
20802 + case RLIMIT_NOFILE:
20803 + res_add += GR_RLIM_NOFILE_BUMP;
20805 + case RLIMIT_MEMLOCK:
20806 + res_add += GR_RLIM_MEMLOCK_BUMP;
20809 + res_add += GR_RLIM_AS_BUMP;
20811 + case RLIMIT_LOCKS:
20812 + res_add += GR_RLIM_LOCKS_BUMP;
20816 + acl->res[res].rlim_cur = res_add;
20818 + if (wanted > acl->res[res].rlim_max)
20819 + acl->res[res].rlim_max = res_add;
20821 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
20822 + task->role->roletype, acl->filename,
20823 + acl->res[res].rlim_cur, acl->res[res].rlim_max,
20824 + "", (unsigned long) res);
20830 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
20832 +pax_set_initial_flags(struct linux_binprm *bprm)
20834 + struct task_struct *task = current;
20835 + struct acl_subject_label *proc;
20836 + unsigned long flags;
20838 + if (unlikely(!(gr_status & GR_READY)))
20841 + flags = pax_get_flags(task);
20843 + proc = task->acl;
20845 + if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
20846 + flags &= ~MF_PAX_PAGEEXEC;
20847 + if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
20848 + flags &= ~MF_PAX_SEGMEXEC;
20849 + if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
20850 + flags &= ~MF_PAX_RANDMMAP;
20851 + if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
20852 + flags &= ~MF_PAX_EMUTRAMP;
20853 + if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
20854 + flags &= ~MF_PAX_MPROTECT;
20856 + if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
20857 + flags |= MF_PAX_PAGEEXEC;
20858 + if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
20859 + flags |= MF_PAX_SEGMEXEC;
20860 + if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
20861 + flags |= MF_PAX_RANDMMAP;
20862 + if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
20863 + flags |= MF_PAX_EMUTRAMP;
20864 + if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
20865 + flags |= MF_PAX_MPROTECT;
20867 + pax_set_flags(task, flags);
20873 +#ifdef CONFIG_SYSCTL
20874 +/* Eric Biederman likes breaking userland ABI and every inode-based security
20875 + system to save 35kb of memory */
20877 +/* we modify the passed in filename, but adjust it back before returning */
20878 +static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
20880 + struct name_entry *nmatch;
20881 + char *p, *lastp = NULL;
20882 + struct acl_object_label *obj = NULL, *tmp;
20883 + struct acl_subject_label *tmpsubj;
20886 + read_lock(&gr_inode_lock);
20888 + p = name + len - 1;
20890 + nmatch = lookup_name_entry(name);
20891 + if (lastp != NULL)
20894 + if (nmatch == NULL)
20895 + goto next_component;
20896 + tmpsubj = current->acl;
20898 + obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
20899 + if (obj != NULL) {
20900 + tmp = obj->globbed;
20902 + if (!glob_match(tmp->filename, name)) {
20910 + } while ((tmpsubj = tmpsubj->parent_subject));
20916 + while (*p != '/')
20928 + read_unlock(&gr_inode_lock);
20929 + /* obj returned will always be non-null */
20933 +/* returns 0 when allowing, non-zero on error
20934 + op of 0 is used for readdir, so we don't log the names of hidden files
20937 +gr_handle_sysctl(const struct ctl_table *table, const int op)
20940 + const char *proc_sys = "/proc/sys";
20942 + struct acl_object_label *obj;
20943 + unsigned short len = 0, pos = 0, depth = 0, i;
20947 + if (unlikely(!(gr_status & GR_READY)))
20950 + /* for now, ignore operations on non-sysctl entries if it's not a
20952 + if (table->child != NULL && op != 0)
20956 + /* it's only a read if it's an entry, read on dirs is for readdir */
20957 + if (op & MAY_READ)
20959 + if (op & MAY_WRITE)
20960 + mode |= GR_WRITE;
20962 + preempt_disable();
20964 + path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
20966 + /* it's only a read/write if it's an actual entry, not a dir
20967 + (which are opened for readdir)
20970 + /* convert the requested sysctl entry into a pathname */
20972 + for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20973 + len += strlen(tmp->procname);
20978 + if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
20983 + memset(path, 0, PAGE_SIZE);
20985 + memcpy(path, proc_sys, strlen(proc_sys));
20987 + pos += strlen(proc_sys);
20989 + for (; depth > 0; depth--) {
20992 + for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20993 + if (depth == i) {
20994 + memcpy(path + pos, tmp->procname,
20995 + strlen(tmp->procname));
20996 + pos += strlen(tmp->procname);
21002 + obj = gr_lookup_by_name(path, pos);
21003 + err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
21005 + if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
21006 + ((err & mode) != mode))) {
21007 + __u32 new_mode = mode;
21009 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21012 + gr_log_learn_sysctl(current, path, new_mode);
21013 + } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
21014 + gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
21016 + } else if (!(err & GR_FIND)) {
21018 + } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
21019 + gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
21020 + path, (mode & GR_READ) ? " reading" : "",
21021 + (mode & GR_WRITE) ? " writing" : "");
21023 + } else if ((err & mode) != mode) {
21025 + } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
21026 + gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
21027 + path, (mode & GR_READ) ? " reading" : "",
21028 + (mode & GR_WRITE) ? " writing" : "");
21034 + preempt_enable();
21041 +gr_handle_proc_ptrace(struct task_struct *task)
21043 + struct file *filp;
21044 + struct task_struct *tmp = task;
21045 + struct task_struct *curtemp = current;
21048 + if (unlikely(!(gr_status & GR_READY)))
21051 + read_lock(&tasklist_lock);
21052 + read_lock(&grsec_exec_file_lock);
21053 + filp = task->exec_file;
21055 + while (tmp->pid > 0) {
21056 + if (tmp == curtemp)
21058 + tmp = tmp->parent;
21061 + if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
21062 + read_unlock(&grsec_exec_file_lock);
21063 + read_unlock(&tasklist_lock);
21067 + retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
21068 + read_unlock(&grsec_exec_file_lock);
21069 + read_unlock(&tasklist_lock);
21071 + if (retmode & GR_NOPTRACE)
21074 + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
21075 + && (current->acl != task->acl || (current->acl != current->role->root_label
21076 + && current->pid != task->pid)))
21083 +gr_handle_ptrace(struct task_struct *task, const long request)
21085 + struct task_struct *tmp = task;
21086 + struct task_struct *curtemp = current;
21089 + if (unlikely(!(gr_status & GR_READY)))
21092 + read_lock(&tasklist_lock);
21093 + while (tmp->pid > 0) {
21094 + if (tmp == curtemp)
21096 + tmp = tmp->parent;
21099 + if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
21100 + read_unlock(&tasklist_lock);
21101 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21104 + read_unlock(&tasklist_lock);
21106 + read_lock(&grsec_exec_file_lock);
21107 + if (unlikely(!task->exec_file)) {
21108 + read_unlock(&grsec_exec_file_lock);
21112 + retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
21113 + read_unlock(&grsec_exec_file_lock);
21115 + if (retmode & GR_NOPTRACE) {
21116 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21120 + if (retmode & GR_PTRACERD) {
21121 + switch (request) {
21122 + case PTRACE_POKETEXT:
21123 + case PTRACE_POKEDATA:
21124 + case PTRACE_POKEUSR:
21125 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
21126 + case PTRACE_SETREGS:
21127 + case PTRACE_SETFPREGS:
21130 + case PTRACE_SETFPXREGS:
21132 +#ifdef CONFIG_ALTIVEC
21133 + case PTRACE_SETVRREGS:
21139 + } else if (!(current->acl->mode & GR_POVERRIDE) &&
21140 + !(current->role->roletype & GR_ROLE_GOD) &&
21141 + (current->acl != task->acl)) {
21142 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21149 +static int is_writable_mmap(const struct file *filp)
21151 + struct task_struct *task = current;
21152 + struct acl_object_label *obj, *obj2;
21154 + if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
21155 + !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
21156 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
21157 + obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
21158 + task->role->root_label);
21159 + if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
21160 + gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
21168 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
21172 + if (unlikely(!file || !(prot & PROT_EXEC)))
21175 + if (is_writable_mmap(file))
21179 + gr_search_file(file->f_path.dentry,
21180 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
21181 + file->f_path.mnt);
21183 + if (!gr_tpe_allow(file))
21186 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
21187 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21189 + } else if (unlikely(!(mode & GR_EXEC))) {
21191 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
21192 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21200 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
21204 + if (unlikely(!file || !(prot & PROT_EXEC)))
21207 + if (is_writable_mmap(file))
21211 + gr_search_file(file->f_path.dentry,
21212 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
21213 + file->f_path.mnt);
21215 + if (!gr_tpe_allow(file))
21218 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
21219 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21221 + } else if (unlikely(!(mode & GR_EXEC))) {
21223 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
21224 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21232 +gr_acl_handle_psacct(struct task_struct *task, const long code)
21234 + unsigned long runtime;
21235 + unsigned long cputime;
21236 + unsigned int wday, cday;
21240 + struct timespec timeval;
21242 + if (unlikely(!(gr_status & GR_READY) || !task->acl ||
21243 + !(task->acl->mode & GR_PROCACCT)))
21246 + do_posix_clock_monotonic_gettime(&timeval);
21247 + runtime = timeval.tv_sec - task->start_time.tv_sec;
21248 + wday = runtime / (3600 * 24);
21249 + runtime -= wday * (3600 * 24);
21250 + whr = runtime / 3600;
21251 + runtime -= whr * 3600;
21252 + wmin = runtime / 60;
21253 + runtime -= wmin * 60;
21256 + cputime = (task->utime + task->stime) / HZ;
21257 + cday = cputime / (3600 * 24);
21258 + cputime -= cday * (3600 * 24);
21259 + chr = cputime / 3600;
21260 + cputime -= chr * 3600;
21261 + cmin = cputime / 60;
21262 + cputime -= cmin * 60;
21265 + gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
21270 +void gr_set_kernel_label(struct task_struct *task)
21272 + if (gr_status & GR_READY) {
21273 + task->role = kernel_role;
21274 + task->acl = kernel_role->root_label;
21279 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
21281 + struct task_struct *task = current;
21282 + struct dentry *dentry = file->f_path.dentry;
21283 + struct vfsmount *mnt = file->f_path.mnt;
21284 + struct acl_object_label *obj, *tmp;
21285 + struct acl_subject_label *subj;
21286 + unsigned int bufsize;
21290 + if (unlikely(!(gr_status & GR_READY)))
21293 + if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
21296 + /* ignore Eric Biederman */
21297 + if (IS_PRIVATE(dentry->d_inode))
21300 + subj = task->acl;
21302 + obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
21304 + return (obj->mode & GR_FIND) ? 1 : 0;
21305 + } while ((subj = subj->parent_subject));
21307 + obj = chk_obj_label(dentry, mnt, task->acl);
21308 + if (obj->globbed == NULL)
21309 + return (obj->mode & GR_FIND) ? 1 : 0;
21311 + is_not_root = ((obj->filename[0] == '/') &&
21312 + (obj->filename[1] == '\0')) ? 0 : 1;
21313 + bufsize = PAGE_SIZE - namelen - is_not_root;
21315 + /* check bufsize > PAGE_SIZE || bufsize == 0 */
21316 + if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
21319 + preempt_disable();
21320 + path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
21323 + bufsize = strlen(path);
21325 + /* if base is "/", don't append an additional slash */
21327 + *(path + bufsize) = '/';
21328 + memcpy(path + bufsize + is_not_root, name, namelen);
21329 + *(path + bufsize + namelen + is_not_root) = '\0';
21331 + tmp = obj->globbed;
21333 + if (!glob_match(tmp->filename, path)) {
21334 + preempt_enable();
21335 + return (tmp->mode & GR_FIND) ? 1 : 0;
21339 + preempt_enable();
21340 + return (obj->mode & GR_FIND) ? 1 : 0;
21343 +EXPORT_SYMBOL(gr_learn_resource);
21344 +EXPORT_SYMBOL(gr_set_kernel_label);
21345 +#ifdef CONFIG_SECURITY
21346 +EXPORT_SYMBOL(gr_check_user_change);
21347 +EXPORT_SYMBOL(gr_check_group_change);
21350 diff -urNp linux-2.6.27.10/grsecurity/gracl_cap.c linux-2.6.27.10/grsecurity/gracl_cap.c
21351 --- linux-2.6.27.10/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
21352 +++ linux-2.6.27.10/grsecurity/gracl_cap.c 2008-11-18 03:38:45.000000000 -0500
21354 +#include <linux/kernel.h>
21355 +#include <linux/module.h>
21356 +#include <linux/sched.h>
21357 +#include <linux/gracl.h>
21358 +#include <linux/grsecurity.h>
21359 +#include <linux/grinternal.h>
21361 +static const char *captab_log[] = {
21363 + "CAP_DAC_OVERRIDE",
21364 + "CAP_DAC_READ_SEARCH",
21371 + "CAP_LINUX_IMMUTABLE",
21372 + "CAP_NET_BIND_SERVICE",
21373 + "CAP_NET_BROADCAST",
21378 + "CAP_SYS_MODULE",
21380 + "CAP_SYS_CHROOT",
21381 + "CAP_SYS_PTRACE",
21386 + "CAP_SYS_RESOURCE",
21388 + "CAP_SYS_TTY_CONFIG",
21391 + "CAP_AUDIT_WRITE",
21392 + "CAP_AUDIT_CONTROL",
21394 + "CAP_MAC_OVERRIDE",
21398 +EXPORT_SYMBOL(gr_task_is_capable);
21399 +EXPORT_SYMBOL(gr_is_capable_nolog);
21402 +gr_task_is_capable(struct task_struct *task, const int cap)
21404 + struct acl_subject_label *curracl;
21405 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
21407 + if (!gr_acl_is_enabled())
21410 + curracl = task->acl;
21412 + cap_drop = curracl->cap_lower;
21413 + cap_mask = curracl->cap_mask;
21415 + while ((curracl = curracl->parent_subject)) {
21416 + /* if the cap isn't specified in the current computed mask but is specified in the
21417 + current level subject, and is lowered in the current level subject, then add
21418 + it to the set of dropped capabilities
21419 + otherwise, add the current level subject's mask to the current computed mask
21421 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
21422 + cap_raise(cap_mask, cap);
21423 + if (cap_raised(curracl->cap_lower, cap))
21424 + cap_raise(cap_drop, cap);
21428 + if (!cap_raised(cap_drop, cap))
21431 + curracl = task->acl;
21433 + if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
21434 + && cap_raised(task->cap_effective, cap)) {
21435 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
21436 + task->role->roletype, task->uid,
21437 + task->gid, task->exec_file ?
21438 + gr_to_filename(task->exec_file->f_path.dentry,
21439 + task->exec_file->f_path.mnt) : curracl->filename,
21440 + curracl->filename, 0UL,
21441 + 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
21445 + if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
21446 + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
21451 +gr_is_capable_nolog(const int cap)
21453 + struct acl_subject_label *curracl;
21454 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
21456 + if (!gr_acl_is_enabled())
21459 + curracl = current->acl;
21461 + cap_drop = curracl->cap_lower;
21462 + cap_mask = curracl->cap_mask;
21464 + while ((curracl = curracl->parent_subject)) {
21465 + /* if the cap isn't specified in the current computed mask but is specified in the
21466 + current level subject, and is lowered in the current level subject, then add
21467 + it to the set of dropped capabilities
21468 + otherwise, add the current level subject's mask to the current computed mask
21470 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
21471 + cap_raise(cap_mask, cap);
21472 + if (cap_raised(curracl->cap_lower, cap))
21473 + cap_raise(cap_drop, cap);
21477 + if (!cap_raised(cap_drop, cap))
21483 diff -urNp linux-2.6.27.10/grsecurity/gracl_fs.c linux-2.6.27.10/grsecurity/gracl_fs.c
21484 --- linux-2.6.27.10/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
21485 +++ linux-2.6.27.10/grsecurity/gracl_fs.c 2008-11-18 03:38:45.000000000 -0500
21487 +#include <linux/kernel.h>
21488 +#include <linux/sched.h>
21489 +#include <linux/types.h>
21490 +#include <linux/fs.h>
21491 +#include <linux/file.h>
21492 +#include <linux/stat.h>
21493 +#include <linux/grsecurity.h>
21494 +#include <linux/grinternal.h>
21495 +#include <linux/gracl.h>
21498 +gr_acl_handle_hidden_file(const struct dentry * dentry,
21499 + const struct vfsmount * mnt)
21503 + if (unlikely(!dentry->d_inode))
21507 + gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
21509 + if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
21510 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
21512 + } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
21513 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
21515 + } else if (unlikely(!(mode & GR_FIND)))
21522 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
21525 + __u32 reqmode = GR_FIND;
21528 + if (unlikely(!dentry->d_inode))
21531 + if (unlikely(fmode & O_APPEND))
21532 + reqmode |= GR_APPEND;
21533 + else if (unlikely(fmode & FMODE_WRITE))
21534 + reqmode |= GR_WRITE;
21535 + if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
21536 + reqmode |= GR_READ;
21539 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
21542 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21543 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
21544 + reqmode & GR_READ ? " reading" : "",
21545 + reqmode & GR_WRITE ? " writing" : reqmode &
21546 + GR_APPEND ? " appending" : "");
21549 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21551 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
21552 + reqmode & GR_READ ? " reading" : "",
21553 + reqmode & GR_WRITE ? " writing" : reqmode &
21554 + GR_APPEND ? " appending" : "");
21556 + } else if (unlikely((mode & reqmode) != reqmode))
21563 +gr_acl_handle_creat(const struct dentry * dentry,
21564 + const struct dentry * p_dentry,
21565 + const struct vfsmount * p_mnt, const int fmode,
21568 + __u32 reqmode = GR_WRITE | GR_CREATE;
21571 + if (unlikely(fmode & O_APPEND))
21572 + reqmode |= GR_APPEND;
21573 + if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
21574 + reqmode |= GR_READ;
21575 + if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
21576 + reqmode |= GR_SETID;
21579 + gr_check_create(dentry, p_dentry, p_mnt,
21580 + reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
21582 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21583 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
21584 + reqmode & GR_READ ? " reading" : "",
21585 + reqmode & GR_WRITE ? " writing" : reqmode &
21586 + GR_APPEND ? " appending" : "");
21589 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21591 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
21592 + reqmode & GR_READ ? " reading" : "",
21593 + reqmode & GR_WRITE ? " writing" : reqmode &
21594 + GR_APPEND ? " appending" : "");
21596 + } else if (unlikely((mode & reqmode) != reqmode))
21603 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
21606 + __u32 mode, reqmode = GR_FIND;
21608 + if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
21609 + reqmode |= GR_EXEC;
21610 + if (fmode & S_IWOTH)
21611 + reqmode |= GR_WRITE;
21612 + if (fmode & S_IROTH)
21613 + reqmode |= GR_READ;
21616 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
21619 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21620 + gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
21621 + reqmode & GR_READ ? " reading" : "",
21622 + reqmode & GR_WRITE ? " writing" : "",
21623 + reqmode & GR_EXEC ? " executing" : "");
21626 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21628 + gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
21629 + reqmode & GR_READ ? " reading" : "",
21630 + reqmode & GR_WRITE ? " writing" : "",
21631 + reqmode & GR_EXEC ? " executing" : "");
21633 + } else if (unlikely((mode & reqmode) != reqmode))
21639 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
21643 + mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
21645 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21646 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
21648 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21649 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
21651 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
21654 + return (reqmode);
21658 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
21660 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
21664 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
21666 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
21670 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
21672 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
21676 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
21678 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
21682 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
21685 + if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
21688 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21689 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21690 + GR_FCHMOD_ACL_MSG);
21692 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
21697 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
21700 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21701 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21702 + GR_CHMOD_ACL_MSG);
21704 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
21709 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
21711 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
21715 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
21717 + return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
21721 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
21723 + return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
21724 + GR_UNIXCONNECT_ACL_MSG);
21727 +/* hardlinks require at minimum create permission,
21728 + any additional privilege required is based on the
21729 + privilege of the file being linked to
21732 +gr_acl_handle_link(const struct dentry * new_dentry,
21733 + const struct dentry * parent_dentry,
21734 + const struct vfsmount * parent_mnt,
21735 + const struct dentry * old_dentry,
21736 + const struct vfsmount * old_mnt, const char *to)
21739 + __u32 needmode = GR_CREATE | GR_LINK;
21740 + __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
21743 + gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
21746 + if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
21747 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21749 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21750 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21752 + } else if (unlikely((mode & needmode) != needmode))
21759 +gr_acl_handle_symlink(const struct dentry * new_dentry,
21760 + const struct dentry * parent_dentry,
21761 + const struct vfsmount * parent_mnt, const char *from)
21763 + __u32 needmode = GR_WRITE | GR_CREATE;
21767 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
21768 + GR_CREATE | GR_AUDIT_CREATE |
21769 + GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
21771 + if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
21772 + gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21774 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21775 + gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21777 + } else if (unlikely((mode & needmode) != needmode))
21780 + return (GR_WRITE | GR_CREATE);
21783 +static __u32 generic_fs_create_handler(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, __u32 reqmode, const char *fmt)
21787 + mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
21789 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21790 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
21792 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21793 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
21795 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
21798 + return (reqmode);
21802 +gr_acl_handle_mknod(const struct dentry * new_dentry,
21803 + const struct dentry * parent_dentry,
21804 + const struct vfsmount * parent_mnt,
21807 + __u32 reqmode = GR_WRITE | GR_CREATE;
21808 + if (unlikely(mode & (S_ISUID | S_ISGID)))
21809 + reqmode |= GR_SETID;
21811 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21812 + reqmode, GR_MKNOD_ACL_MSG);
21816 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
21817 + const struct dentry *parent_dentry,
21818 + const struct vfsmount *parent_mnt)
21820 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21821 + GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
21824 +#define RENAME_CHECK_SUCCESS(old, new) \
21825 + (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
21826 + ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
21829 +gr_acl_handle_rename(struct dentry *new_dentry,
21830 + struct dentry *parent_dentry,
21831 + const struct vfsmount *parent_mnt,
21832 + struct dentry *old_dentry,
21833 + struct inode *old_parent_inode,
21834 + struct vfsmount *old_mnt, const char *newname)
21836 + __u32 comp1, comp2;
21839 + if (unlikely(!gr_acl_is_enabled()))
21842 + if (!new_dentry->d_inode) {
21843 + comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
21844 + GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
21845 + GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
21846 + comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
21847 + GR_DELETE | GR_AUDIT_DELETE |
21848 + GR_AUDIT_READ | GR_AUDIT_WRITE |
21849 + GR_SUPPRESS, old_mnt);
21851 + comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
21852 + GR_CREATE | GR_DELETE |
21853 + GR_AUDIT_CREATE | GR_AUDIT_DELETE |
21854 + GR_AUDIT_READ | GR_AUDIT_WRITE |
21855 + GR_SUPPRESS, parent_mnt);
21857 + gr_search_file(old_dentry,
21858 + GR_READ | GR_WRITE | GR_AUDIT_READ |
21859 + GR_DELETE | GR_AUDIT_DELETE |
21860 + GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
21863 + if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
21864 + ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
21865 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21866 + else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
21867 + && !(comp2 & GR_SUPPRESS)) {
21868 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21870 + } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
21877 +gr_acl_handle_exit(void)
21881 + struct file *exec_file;
21883 + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
21884 + id = current->acl_role_id;
21885 + rolename = current->role->rolename;
21887 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
21890 + write_lock(&grsec_exec_file_lock);
21891 + exec_file = current->exec_file;
21892 + current->exec_file = NULL;
21893 + write_unlock(&grsec_exec_file_lock);
21900 +gr_acl_handle_procpidmem(const struct task_struct *task)
21902 + if (unlikely(!gr_acl_is_enabled()))
21905 + if (task != current && task->acl->mode & GR_PROTPROCFD)
21910 diff -urNp linux-2.6.27.10/grsecurity/gracl_ip.c linux-2.6.27.10/grsecurity/gracl_ip.c
21911 --- linux-2.6.27.10/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
21912 +++ linux-2.6.27.10/grsecurity/gracl_ip.c 2008-11-18 03:38:45.000000000 -0500
21914 +#include <linux/kernel.h>
21915 +#include <asm/uaccess.h>
21916 +#include <asm/errno.h>
21917 +#include <net/sock.h>
21918 +#include <linux/file.h>
21919 +#include <linux/fs.h>
21920 +#include <linux/net.h>
21921 +#include <linux/in.h>
21922 +#include <linux/skbuff.h>
21923 +#include <linux/ip.h>
21924 +#include <linux/udp.h>
21925 +#include <linux/smp_lock.h>
21926 +#include <linux/types.h>
21927 +#include <linux/sched.h>
21928 +#include <linux/netdevice.h>
21929 +#include <linux/inetdevice.h>
21930 +#include <linux/gracl.h>
21931 +#include <linux/grsecurity.h>
21932 +#include <linux/grinternal.h>
21934 +#define GR_BIND 0x01
21935 +#define GR_CONNECT 0x02
21936 +#define GR_INVERT 0x04
21938 +static const char * gr_protocols[256] = {
21939 + "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
21940 + "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
21941 + "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
21942 + "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
21943 + "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
21944 + "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
21945 + "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
21946 + "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
21947 + "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
21948 + "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
21949 + "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
21950 + "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
21951 + "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
21952 + "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
21953 + "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
21954 + "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
21955 + "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
21956 + "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
21957 + "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
21958 + "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
21959 + "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
21960 + "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
21961 + "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
21962 + "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
21963 + "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
21964 + "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
21965 + "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
21966 + "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
21967 + "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
21968 + "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
21969 + "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
21970 + "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
21973 +static const char * gr_socktypes[11] = {
21974 + "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
21975 + "unknown:7", "unknown:8", "unknown:9", "packet"
21979 +gr_proto_to_name(unsigned char proto)
21981 + return gr_protocols[proto];
21985 +gr_socktype_to_name(unsigned char type)
21987 + return gr_socktypes[type];
21991 +gr_search_socket(const int domain, const int type, const int protocol)
21993 + struct acl_subject_label *curr;
21995 + if (unlikely(!gr_acl_is_enabled()))
21998 + if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
21999 + || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
22000 + goto exit; // let the kernel handle it
22002 + curr = current->acl;
22007 + if ((curr->ip_type & (1 << type)) &&
22008 + (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
22011 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
22012 + /* we don't place acls on raw sockets , and sometimes
22013 + dgram/ip sockets are opened for ioctl and not
22014 + bind/connect, so we'll fake a bind learn log */
22015 + if (type == SOCK_RAW || type == SOCK_PACKET) {
22016 + __u32 fakeip = 0;
22017 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22018 + current->role->roletype, current->uid,
22019 + current->gid, current->exec_file ?
22020 + gr_to_filename(current->exec_file->f_path.dentry,
22021 + current->exec_file->f_path.mnt) :
22022 + curr->filename, curr->filename,
22023 + NIPQUAD(fakeip), 0, type,
22024 + protocol, GR_CONNECT,
22025 +NIPQUAD(current->signal->curr_ip));
22026 + } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
22027 + __u32 fakeip = 0;
22028 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22029 + current->role->roletype, current->uid,
22030 + current->gid, current->exec_file ?
22031 + gr_to_filename(current->exec_file->f_path.dentry,
22032 + current->exec_file->f_path.mnt) :
22033 + curr->filename, curr->filename,
22034 + NIPQUAD(fakeip), 0, type,
22035 + protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
22037 + /* we'll log when they use connect or bind */
22041 + gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
22042 + gr_socktype_to_name(type), gr_proto_to_name(protocol));
22049 +int check_ip_policy(struct acl_ip_label *ip, __u32 ip_addr, __u16 ip_port, __u8 protocol, const int mode, const int type, __u32 our_addr, __u32 our_netmask)
22051 + if ((ip->mode & mode) &&
22052 + (ip_port >= ip->low) &&
22053 + (ip_port <= ip->high) &&
22054 + ((ntohl(ip_addr) & our_netmask) ==
22055 + (ntohl(our_addr) & our_netmask))
22056 + && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
22057 + && (ip->type & (1 << type))) {
22058 + if (ip->mode & GR_INVERT)
22059 + return 2; // specifically denied
22061 + return 1; // allowed
22064 + return 0; // not specifically allowed, may continue parsing
22068 +gr_search_connectbind(const int mode, const struct sock *sk,
22069 + const struct sockaddr_in *addr, const int type)
22071 + char iface[IFNAMSIZ] = {0};
22072 + struct acl_subject_label *curr;
22073 + struct acl_ip_label *ip;
22074 + struct net_device *dev;
22075 + struct in_device *idev;
22078 + __u32 ip_addr = 0;
22080 + __u32 our_netmask;
22082 + __u16 ip_port = 0;
22084 + if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
22087 + curr = current->acl;
22092 + ip_addr = addr->sin_addr.s_addr;
22093 + ip_port = ntohs(addr->sin_port);
22095 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
22096 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22097 + current->role->roletype, current->uid,
22098 + current->gid, current->exec_file ?
22099 + gr_to_filename(current->exec_file->f_path.dentry,
22100 + current->exec_file->f_path.mnt) :
22101 + curr->filename, curr->filename,
22102 + NIPQUAD(ip_addr), ip_port, type,
22103 + sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
22107 + for (i = 0; i < curr->ip_num; i++) {
22108 + ip = *(curr->ips + i);
22109 + if (ip->iface != NULL) {
22110 + strncpy(iface, ip->iface, IFNAMSIZ - 1);
22111 + p = strchr(iface, ':');
22114 + dev = dev_get_by_name(sock_net(sk), iface);
22117 + idev = in_dev_get(dev);
22118 + if (idev == NULL) {
22124 + if (!strcmp(ip->iface, ifa->ifa_label)) {
22125 + our_addr = ifa->ifa_address;
22126 + our_netmask = 0xffffffff;
22127 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
22129 + rcu_read_unlock();
22130 + in_dev_put(idev);
22133 + } else if (ret == 2) {
22134 + rcu_read_unlock();
22135 + in_dev_put(idev);
22140 + } endfor_ifa(idev);
22141 + rcu_read_unlock();
22142 + in_dev_put(idev);
22145 + our_addr = ip->addr;
22146 + our_netmask = ip->netmask;
22147 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
22150 + else if (ret == 2)
22156 + if (mode == GR_BIND)
22157 + gr_log_int5_str2(GR_DONT_AUDIT, GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
22158 + else if (mode == GR_CONNECT)
22159 + gr_log_int5_str2(GR_DONT_AUDIT, GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
22165 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
22167 + return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
22171 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
22173 + return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
22176 +int gr_search_listen(const struct socket *sock)
22178 + struct sock *sk = sock->sk;
22179 + struct sockaddr_in addr;
22181 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
22182 + addr.sin_port = inet_sk(sk)->sport;
22184 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
22187 +int gr_search_accept(const struct socket *sock)
22189 + struct sock *sk = sock->sk;
22190 + struct sockaddr_in addr;
22192 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
22193 + addr.sin_port = inet_sk(sk)->sport;
22195 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
22199 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
22202 + return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
22204 + struct sockaddr_in sin;
22205 + const struct inet_sock *inet = inet_sk(sk);
22207 + sin.sin_addr.s_addr = inet->daddr;
22208 + sin.sin_port = inet->dport;
22210 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
22215 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
22217 + struct sockaddr_in sin;
22219 + if (unlikely(skb->len < sizeof (struct udphdr)))
22220 + return 1; // skip this packet
22222 + sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
22223 + sin.sin_port = udp_hdr(skb)->source;
22225 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
22227 diff -urNp linux-2.6.27.10/grsecurity/gracl_learn.c linux-2.6.27.10/grsecurity/gracl_learn.c
22228 --- linux-2.6.27.10/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
22229 +++ linux-2.6.27.10/grsecurity/gracl_learn.c 2008-11-18 03:38:45.000000000 -0500
22231 +#include <linux/kernel.h>
22232 +#include <linux/mm.h>
22233 +#include <linux/sched.h>
22234 +#include <linux/poll.h>
22235 +#include <linux/smp_lock.h>
22236 +#include <linux/string.h>
22237 +#include <linux/file.h>
22238 +#include <linux/types.h>
22239 +#include <linux/vmalloc.h>
22240 +#include <linux/grinternal.h>
22242 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
22243 + size_t count, loff_t *ppos);
22244 +extern int gr_acl_is_enabled(void);
22246 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
22247 +static int gr_learn_attached;
22249 +/* use a 512k buffer */
22250 +#define LEARN_BUFFER_SIZE (512 * 1024)
22252 +static DEFINE_SPINLOCK(gr_learn_lock);
22253 +static DECLARE_MUTEX(gr_learn_user_sem);
22255 +/* we need to maintain two buffers, so that the kernel context of grlearn
22256 + uses a semaphore around the userspace copying, and the other kernel contexts
22257 + use a spinlock when copying into the buffer, since they cannot sleep
22259 +static char *learn_buffer;
22260 +static char *learn_buffer_user;
22261 +static int learn_buffer_len;
22262 +static int learn_buffer_user_len;
22265 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
22267 + DECLARE_WAITQUEUE(wait, current);
22268 + ssize_t retval = 0;
22270 + add_wait_queue(&learn_wait, &wait);
22271 + set_current_state(TASK_INTERRUPTIBLE);
22273 + down(&gr_learn_user_sem);
22274 + spin_lock(&gr_learn_lock);
22275 + if (learn_buffer_len)
22277 + spin_unlock(&gr_learn_lock);
22278 + up(&gr_learn_user_sem);
22279 + if (file->f_flags & O_NONBLOCK) {
22280 + retval = -EAGAIN;
22283 + if (signal_pending(current)) {
22284 + retval = -ERESTARTSYS;
22291 + memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
22292 + learn_buffer_user_len = learn_buffer_len;
22293 + retval = learn_buffer_len;
22294 + learn_buffer_len = 0;
22296 + spin_unlock(&gr_learn_lock);
22298 + if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
22299 + retval = -EFAULT;
22301 + up(&gr_learn_user_sem);
22303 + set_current_state(TASK_RUNNING);
22304 + remove_wait_queue(&learn_wait, &wait);
22308 +static unsigned int
22309 +poll_learn(struct file * file, poll_table * wait)
22311 + poll_wait(file, &learn_wait, wait);
22313 + if (learn_buffer_len)
22314 + return (POLLIN | POLLRDNORM);
22320 +gr_clear_learn_entries(void)
22324 + down(&gr_learn_user_sem);
22325 + if (learn_buffer != NULL) {
22326 + spin_lock(&gr_learn_lock);
22327 + tmp = learn_buffer;
22328 + learn_buffer = NULL;
22329 + spin_unlock(&gr_learn_lock);
22330 + vfree(learn_buffer);
22332 + if (learn_buffer_user != NULL) {
22333 + vfree(learn_buffer_user);
22334 + learn_buffer_user = NULL;
22336 + learn_buffer_len = 0;
22337 + up(&gr_learn_user_sem);
22343 +gr_add_learn_entry(const char *fmt, ...)
22346 + unsigned int len;
22348 + if (!gr_learn_attached)
22351 + spin_lock(&gr_learn_lock);
22353 + /* leave a gap at the end so we know when it's "full" but don't have to
22354 + compute the exact length of the string we're trying to append
22356 + if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
22357 + spin_unlock(&gr_learn_lock);
22358 + wake_up_interruptible(&learn_wait);
22361 + if (learn_buffer == NULL) {
22362 + spin_unlock(&gr_learn_lock);
22366 + va_start(args, fmt);
22367 + len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
22370 + learn_buffer_len += len + 1;
22372 + spin_unlock(&gr_learn_lock);
22373 + wake_up_interruptible(&learn_wait);
22379 +open_learn(struct inode *inode, struct file *file)
22381 + if (file->f_mode & FMODE_READ && gr_learn_attached)
22383 + if (file->f_mode & FMODE_READ) {
22385 + down(&gr_learn_user_sem);
22386 + if (learn_buffer == NULL)
22387 + learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
22388 + if (learn_buffer_user == NULL)
22389 + learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
22390 + if (learn_buffer == NULL) {
22391 + retval = -ENOMEM;
22394 + if (learn_buffer_user == NULL) {
22395 + retval = -ENOMEM;
22398 + learn_buffer_len = 0;
22399 + learn_buffer_user_len = 0;
22400 + gr_learn_attached = 1;
22402 + up(&gr_learn_user_sem);
22409 +close_learn(struct inode *inode, struct file *file)
22413 + if (file->f_mode & FMODE_READ) {
22414 + down(&gr_learn_user_sem);
22415 + if (learn_buffer != NULL) {
22416 + spin_lock(&gr_learn_lock);
22417 + tmp = learn_buffer;
22418 + learn_buffer = NULL;
22419 + spin_unlock(&gr_learn_lock);
22422 + if (learn_buffer_user != NULL) {
22423 + vfree(learn_buffer_user);
22424 + learn_buffer_user = NULL;
22426 + learn_buffer_len = 0;
22427 + learn_buffer_user_len = 0;
22428 + gr_learn_attached = 0;
22429 + up(&gr_learn_user_sem);
22435 +struct file_operations grsec_fops = {
22436 + .read = read_learn,
22437 + .write = write_grsec_handler,
22438 + .open = open_learn,
22439 + .release = close_learn,
22440 + .poll = poll_learn,
22442 diff -urNp linux-2.6.27.10/grsecurity/gracl_res.c linux-2.6.27.10/grsecurity/gracl_res.c
22443 --- linux-2.6.27.10/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
22444 +++ linux-2.6.27.10/grsecurity/gracl_res.c 2008-11-18 03:38:45.000000000 -0500
22446 +#include <linux/kernel.h>
22447 +#include <linux/sched.h>
22448 +#include <linux/gracl.h>
22449 +#include <linux/grinternal.h>
22451 +static const char *restab_log[] = {
22452 + [RLIMIT_CPU] = "RLIMIT_CPU",
22453 + [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
22454 + [RLIMIT_DATA] = "RLIMIT_DATA",
22455 + [RLIMIT_STACK] = "RLIMIT_STACK",
22456 + [RLIMIT_CORE] = "RLIMIT_CORE",
22457 + [RLIMIT_RSS] = "RLIMIT_RSS",
22458 + [RLIMIT_NPROC] = "RLIMIT_NPROC",
22459 + [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
22460 + [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
22461 + [RLIMIT_AS] = "RLIMIT_AS",
22462 + [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
22463 + [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
22467 +gr_log_resource(const struct task_struct *task,
22468 + const int res, const unsigned long wanted, const int gt)
22470 + if (res == RLIMIT_NPROC &&
22471 + (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
22472 + cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
22474 + else if (res == RLIMIT_MEMLOCK &&
22475 + cap_raised(task->cap_effective, CAP_IPC_LOCK))
22478 + if (!gr_acl_is_enabled() && !grsec_resource_logging)
22481 + preempt_disable();
22483 + if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
22484 + (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
22485 + task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
22486 + gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
22487 + preempt_enable_no_resched();
22491 diff -urNp linux-2.6.27.10/grsecurity/gracl_segv.c linux-2.6.27.10/grsecurity/gracl_segv.c
22492 --- linux-2.6.27.10/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
22493 +++ linux-2.6.27.10/grsecurity/gracl_segv.c 2008-11-18 03:38:45.000000000 -0500
22495 +#include <linux/kernel.h>
22496 +#include <linux/mm.h>
22497 +#include <asm/uaccess.h>
22498 +#include <asm/errno.h>
22499 +#include <asm/mman.h>
22500 +#include <net/sock.h>
22501 +#include <linux/file.h>
22502 +#include <linux/fs.h>
22503 +#include <linux/net.h>
22504 +#include <linux/in.h>
22505 +#include <linux/smp_lock.h>
22506 +#include <linux/slab.h>
22507 +#include <linux/types.h>
22508 +#include <linux/sched.h>
22509 +#include <linux/timer.h>
22510 +#include <linux/gracl.h>
22511 +#include <linux/grsecurity.h>
22512 +#include <linux/grinternal.h>
22514 +static struct crash_uid *uid_set;
22515 +static unsigned short uid_used;
22516 +static DEFINE_SPINLOCK(gr_uid_lock);
22517 +extern rwlock_t gr_inode_lock;
22518 +extern struct acl_subject_label *
22519 + lookup_acl_subj_label(const ino_t inode, const dev_t dev,
22520 + struct acl_role_label *role);
22521 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
22524 +gr_init_uidset(void)
22527 + kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
22530 + return uid_set ? 1 : 0;
22534 +gr_free_uidset(void)
22543 +gr_find_uid(const uid_t uid)
22545 + struct crash_uid *tmp = uid_set;
22547 + int low = 0, high = uid_used - 1, mid;
22549 + while (high >= low) {
22550 + mid = (low + high) >> 1;
22551 + buid = tmp[mid].uid;
22563 +static __inline__ void
22564 +gr_insertsort(void)
22566 + unsigned short i, j;
22567 + struct crash_uid index;
22569 + for (i = 1; i < uid_used; i++) {
22570 + index = uid_set[i];
22572 + while ((j > 0) && uid_set[j - 1].uid > index.uid) {
22573 + uid_set[j] = uid_set[j - 1];
22576 + uid_set[j] = index;
22582 +static __inline__ void
22583 +gr_insert_uid(const uid_t uid, const unsigned long expires)
22587 + if (uid_used == GR_UIDTABLE_MAX)
22590 + loc = gr_find_uid(uid);
22593 + uid_set[loc].expires = expires;
22597 + uid_set[uid_used].uid = uid;
22598 + uid_set[uid_used].expires = expires;
22607 +gr_remove_uid(const unsigned short loc)
22609 + unsigned short i;
22611 + for (i = loc + 1; i < uid_used; i++)
22612 + uid_set[i - 1] = uid_set[i];
22620 +gr_check_crash_uid(const uid_t uid)
22625 + if (unlikely(!gr_acl_is_enabled()))
22628 + spin_lock(&gr_uid_lock);
22629 + loc = gr_find_uid(uid);
22634 + if (time_before_eq(uid_set[loc].expires, get_seconds()))
22635 + gr_remove_uid(loc);
22640 + spin_unlock(&gr_uid_lock);
22644 +static __inline__ int
22645 +proc_is_setxid(const struct task_struct *task)
22647 + if (task->uid != task->euid || task->uid != task->suid ||
22648 + task->uid != task->fsuid)
22650 + if (task->gid != task->egid || task->gid != task->sgid ||
22651 + task->gid != task->fsgid)
22656 +static __inline__ int
22657 +gr_fake_force_sig(int sig, struct task_struct *t)
22659 + unsigned long int flags;
22660 + int ret, blocked, ignored;
22661 + struct k_sigaction *action;
22663 + spin_lock_irqsave(&t->sighand->siglock, flags);
22664 + action = &t->sighand->action[sig-1];
22665 + ignored = action->sa.sa_handler == SIG_IGN;
22666 + blocked = sigismember(&t->blocked, sig);
22667 + if (blocked || ignored) {
22668 + action->sa.sa_handler = SIG_DFL;
22670 + sigdelset(&t->blocked, sig);
22671 + recalc_sigpending_and_wake(t);
22674 + if (action->sa.sa_handler == SIG_DFL)
22675 + t->signal->flags &= ~SIGNAL_UNKILLABLE;
22676 + ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
22678 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
22684 +gr_handle_crash(struct task_struct *task, const int sig)
22686 + struct acl_subject_label *curr;
22687 + struct acl_subject_label *curr2;
22688 + struct task_struct *tsk, *tsk2;
22690 + if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
22693 + if (unlikely(!gr_acl_is_enabled()))
22696 + curr = task->acl;
22698 + if (!(curr->resmask & (1 << GR_CRASH_RES)))
22701 + if (time_before_eq(curr->expires, get_seconds())) {
22702 + curr->expires = 0;
22703 + curr->crashes = 0;
22708 + if (!curr->expires)
22709 + curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
22711 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22712 + time_after(curr->expires, get_seconds())) {
22713 + if (task->uid && proc_is_setxid(task)) {
22714 + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22715 + spin_lock(&gr_uid_lock);
22716 + gr_insert_uid(task->uid, curr->expires);
22717 + spin_unlock(&gr_uid_lock);
22718 + curr->expires = 0;
22719 + curr->crashes = 0;
22720 + read_lock(&tasklist_lock);
22721 + do_each_thread(tsk2, tsk) {
22722 + if (tsk != task && tsk->uid == task->uid)
22723 + gr_fake_force_sig(SIGKILL, tsk);
22724 + } while_each_thread(tsk2, tsk);
22725 + read_unlock(&tasklist_lock);
22727 + gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22728 + read_lock(&tasklist_lock);
22729 + do_each_thread(tsk2, tsk) {
22730 + if (likely(tsk != task)) {
22731 + curr2 = tsk->acl;
22733 + if (curr2->device == curr->device &&
22734 + curr2->inode == curr->inode)
22735 + gr_fake_force_sig(SIGKILL, tsk);
22737 + } while_each_thread(tsk2, tsk);
22738 + read_unlock(&tasklist_lock);
22746 +gr_check_crash_exec(const struct file *filp)
22748 + struct acl_subject_label *curr;
22750 + if (unlikely(!gr_acl_is_enabled()))
22753 + read_lock(&gr_inode_lock);
22754 + curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
22755 + filp->f_path.dentry->d_inode->i_sb->s_dev,
22757 + read_unlock(&gr_inode_lock);
22759 + if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
22760 + (!curr->crashes && !curr->expires))
22763 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22764 + time_after(curr->expires, get_seconds()))
22766 + else if (time_before_eq(curr->expires, get_seconds())) {
22767 + curr->crashes = 0;
22768 + curr->expires = 0;
22775 +gr_handle_alertkill(struct task_struct *task)
22777 + struct acl_subject_label *curracl;
22779 + struct task_struct *p, *p2;
22781 + if (unlikely(!gr_acl_is_enabled()))
22784 + curracl = task->acl;
22785 + curr_ip = task->signal->curr_ip;
22787 + if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
22788 + read_lock(&tasklist_lock);
22789 + do_each_thread(p2, p) {
22790 + if (p->signal->curr_ip == curr_ip)
22791 + gr_fake_force_sig(SIGKILL, p);
22792 + } while_each_thread(p2, p);
22793 + read_unlock(&tasklist_lock);
22794 + } else if (curracl->mode & GR_KILLPROC)
22795 + gr_fake_force_sig(SIGKILL, task);
22799 diff -urNp linux-2.6.27.10/grsecurity/gracl_shm.c linux-2.6.27.10/grsecurity/gracl_shm.c
22800 --- linux-2.6.27.10/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
22801 +++ linux-2.6.27.10/grsecurity/gracl_shm.c 2008-11-18 03:38:45.000000000 -0500
22803 +#include <linux/kernel.h>
22804 +#include <linux/mm.h>
22805 +#include <linux/sched.h>
22806 +#include <linux/file.h>
22807 +#include <linux/ipc.h>
22808 +#include <linux/gracl.h>
22809 +#include <linux/grsecurity.h>
22810 +#include <linux/grinternal.h>
22813 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22814 + const time_t shm_createtime, const uid_t cuid, const int shmid)
22816 + struct task_struct *task;
22818 + if (!gr_acl_is_enabled())
22821 + task = find_task_by_vpid(shm_cprid);
22823 + if (unlikely(!task))
22824 + task = find_task_by_vpid(shm_lapid);
22826 + if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
22827 + (task->pid == shm_lapid)) &&
22828 + (task->acl->mode & GR_PROTSHM) &&
22829 + (task->acl != current->acl))) {
22830 + gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
22836 diff -urNp linux-2.6.27.10/grsecurity/grsec_chdir.c linux-2.6.27.10/grsecurity/grsec_chdir.c
22837 --- linux-2.6.27.10/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
22838 +++ linux-2.6.27.10/grsecurity/grsec_chdir.c 2008-11-18 03:38:45.000000000 -0500
22840 +#include <linux/kernel.h>
22841 +#include <linux/sched.h>
22842 +#include <linux/fs.h>
22843 +#include <linux/file.h>
22844 +#include <linux/grsecurity.h>
22845 +#include <linux/grinternal.h>
22848 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
22850 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
22851 + if ((grsec_enable_chdir && grsec_enable_group &&
22852 + in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
22853 + !grsec_enable_group)) {
22854 + gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
22859 diff -urNp linux-2.6.27.10/grsecurity/grsec_chroot.c linux-2.6.27.10/grsecurity/grsec_chroot.c
22860 --- linux-2.6.27.10/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
22861 +++ linux-2.6.27.10/grsecurity/grsec_chroot.c 2008-11-18 03:38:45.000000000 -0500
22863 +#include <linux/kernel.h>
22864 +#include <linux/module.h>
22865 +#include <linux/sched.h>
22866 +#include <linux/file.h>
22867 +#include <linux/fs.h>
22868 +#include <linux/mount.h>
22869 +#include <linux/types.h>
22870 +#include <linux/pid_namespace.h>
22871 +#include <linux/grsecurity.h>
22872 +#include <linux/grinternal.h>
22875 +gr_handle_chroot_unix(const pid_t pid)
22877 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
22878 + struct pid *spid = NULL;
22880 + if (unlikely(!grsec_enable_chroot_unix))
22883 + if (likely(!proc_is_chrooted(current)))
22886 + read_lock(&tasklist_lock);
22888 + spid = find_vpid(pid);
22890 + struct task_struct *p;
22891 + p = pid_task(spid, PIDTYPE_PID);
22893 + if (unlikely(!have_same_root(current, p))) {
22895 + read_unlock(&tasklist_lock);
22896 + gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
22901 + read_unlock(&tasklist_lock);
22907 +gr_handle_chroot_nice(void)
22909 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22910 + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
22911 + gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
22919 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
22921 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22922 + if (grsec_enable_chroot_nice && (niceval < task_nice(p))
22923 + && proc_is_chrooted(current)) {
22924 + gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
22932 +gr_handle_chroot_rawio(const struct inode *inode)
22934 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
22935 + if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
22936 + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
22943 +gr_pid_is_chrooted(struct task_struct *p)
22945 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
22946 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
22950 + if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
22951 + !have_same_root(current, p)) {
22960 +EXPORT_SYMBOL(gr_pid_is_chrooted);
22962 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
22963 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
22965 + struct dentry *dentry = (struct dentry *)u_dentry;
22966 + struct vfsmount *mnt = (struct vfsmount *)u_mnt;
22967 + struct dentry *realroot;
22968 + struct vfsmount *realrootmnt;
22969 + struct dentry *currentroot;
22970 + struct vfsmount *currentmnt;
22971 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
22974 + read_lock(&reaper->fs->lock);
22975 + realrootmnt = mntget(reaper->fs->root.mnt);
22976 + realroot = dget(reaper->fs->root.dentry);
22977 + read_unlock(&reaper->fs->lock);
22979 + read_lock(¤t->fs->lock);
22980 + currentmnt = mntget(current->fs->root.mnt);
22981 + currentroot = dget(current->fs->root.dentry);
22982 + read_unlock(¤t->fs->lock);
22984 + spin_lock(&dcache_lock);
22986 + if (unlikely((dentry == realroot && mnt == realrootmnt)
22987 + || (dentry == currentroot && mnt == currentmnt)))
22989 + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
22990 + if (mnt->mnt_parent == mnt)
22992 + dentry = mnt->mnt_mountpoint;
22993 + mnt = mnt->mnt_parent;
22996 + dentry = dentry->d_parent;
22998 + spin_unlock(&dcache_lock);
23000 + dput(currentroot);
23001 + mntput(currentmnt);
23003 + /* access is outside of chroot */
23004 + if (dentry == realroot && mnt == realrootmnt)
23008 + mntput(realrootmnt);
23014 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
23016 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23017 + if (!grsec_enable_chroot_fchdir)
23020 + if (!proc_is_chrooted(current))
23022 + else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
23023 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
23031 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23032 + const time_t shm_createtime)
23034 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23035 + struct pid *pid = NULL;
23036 + time_t starttime;
23038 + if (unlikely(!grsec_enable_chroot_shmat))
23041 + if (likely(!proc_is_chrooted(current)))
23044 + read_lock(&tasklist_lock);
23046 + pid = find_vpid(shm_cprid);
23048 + struct task_struct *p;
23049 + p = pid_task(pid, PIDTYPE_PID);
23051 + starttime = p->start_time.tv_sec;
23052 + if (unlikely(!have_same_root(current, p) &&
23053 + time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
23055 + read_unlock(&tasklist_lock);
23056 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
23061 + pid = find_vpid(shm_lapid);
23063 + struct task_struct *p;
23064 + p = pid_task(pid, PIDTYPE_PID);
23066 + if (unlikely(!have_same_root(current, p))) {
23068 + read_unlock(&tasklist_lock);
23069 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
23076 + read_unlock(&tasklist_lock);
23082 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
23084 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23085 + if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
23086 + gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
23092 +gr_handle_chroot_mknod(const struct dentry *dentry,
23093 + const struct vfsmount *mnt, const int mode)
23095 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23096 + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
23097 + proc_is_chrooted(current)) {
23098 + gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
23106 +gr_handle_chroot_mount(const struct dentry *dentry,
23107 + const struct vfsmount *mnt, const char *dev_name)
23109 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23110 + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
23111 + gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
23119 +gr_handle_chroot_pivot(void)
23121 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23122 + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
23123 + gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
23131 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
23133 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23134 + if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
23135 + !gr_is_outside_chroot(dentry, mnt)) {
23136 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
23144 +gr_handle_chroot_caps(struct task_struct *task)
23146 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23147 + if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
23148 + kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
23149 + task->cap_permitted =
23150 + cap_drop(task->cap_permitted, chroot_caps);
23151 + task->cap_inheritable =
23152 + cap_drop(task->cap_inheritable, chroot_caps);
23153 + task->cap_effective =
23154 + cap_drop(task->cap_effective, chroot_caps);
23161 +gr_handle_chroot_sysctl(const int op)
23163 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23164 + if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
23165 + && (op & MAY_WRITE))
23172 +gr_handle_chroot_chdir(struct path *path)
23174 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23175 + if (grsec_enable_chroot_chdir)
23176 + set_fs_pwd(current->fs, path);
23182 +gr_handle_chroot_chmod(const struct dentry *dentry,
23183 + const struct vfsmount *mnt, const int mode)
23185 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23186 + if (grsec_enable_chroot_chmod &&
23187 + ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
23188 + proc_is_chrooted(current)) {
23189 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
23196 +#ifdef CONFIG_SECURITY
23197 +EXPORT_SYMBOL(gr_handle_chroot_caps);
23199 diff -urNp linux-2.6.27.10/grsecurity/grsec_disabled.c linux-2.6.27.10/grsecurity/grsec_disabled.c
23200 --- linux-2.6.27.10/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
23201 +++ linux-2.6.27.10/grsecurity/grsec_disabled.c 2008-11-18 03:38:45.000000000 -0500
23203 +#include <linux/kernel.h>
23204 +#include <linux/module.h>
23205 +#include <linux/sched.h>
23206 +#include <linux/file.h>
23207 +#include <linux/fs.h>
23208 +#include <linux/kdev_t.h>
23209 +#include <linux/net.h>
23210 +#include <linux/in.h>
23211 +#include <linux/ip.h>
23212 +#include <linux/skbuff.h>
23213 +#include <linux/sysctl.h>
23215 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
23217 +pax_set_initial_flags(struct linux_binprm *bprm)
23223 +#ifdef CONFIG_SYSCTL
23225 +gr_handle_sysctl(const struct ctl_table * table, const int op)
23232 +gr_acl_is_enabled(void)
23238 +gr_handle_rawio(const struct inode *inode)
23244 +gr_acl_handle_psacct(struct task_struct *task, const long code)
23250 +gr_handle_ptrace(struct task_struct *task, const long request)
23256 +gr_handle_proc_ptrace(struct task_struct *task)
23262 +gr_learn_resource(const struct task_struct *task,
23263 + const int res, const unsigned long wanted, const int gt)
23269 +gr_set_acls(const int type)
23275 +gr_check_hidden_task(const struct task_struct *tsk)
23281 +gr_check_protected_task(const struct task_struct *task)
23287 +gr_copy_label(struct task_struct *tsk)
23293 +gr_set_pax_flags(struct task_struct *task)
23299 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
23305 +gr_handle_delete(const ino_t ino, const dev_t dev)
23311 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
23317 +gr_handle_crash(struct task_struct *task, const int sig)
23323 +gr_check_crash_exec(const struct file *filp)
23329 +gr_check_crash_uid(const uid_t uid)
23335 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
23336 + struct dentry *old_dentry,
23337 + struct dentry *new_dentry,
23338 + struct vfsmount *mnt, const __u8 replace)
23344 +gr_search_socket(const int family, const int type, const int protocol)
23350 +gr_search_connectbind(const int mode, const struct socket *sock,
23351 + const struct sockaddr_in *addr)
23357 +gr_task_is_capable(struct task_struct *task, const int cap)
23363 +gr_is_capable_nolog(const int cap)
23369 +gr_handle_alertkill(struct task_struct *task)
23375 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
23381 +gr_acl_handle_hidden_file(const struct dentry * dentry,
23382 + const struct vfsmount * mnt)
23388 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
23395 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
23401 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
23407 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
23408 + unsigned int *vm_flags)
23414 +gr_acl_handle_truncate(const struct dentry * dentry,
23415 + const struct vfsmount * mnt)
23421 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
23427 +gr_acl_handle_access(const struct dentry * dentry,
23428 + const struct vfsmount * mnt, const int fmode)
23434 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
23441 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
23448 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
23454 +grsecurity_init(void)
23460 +gr_acl_handle_mknod(const struct dentry * new_dentry,
23461 + const struct dentry * parent_dentry,
23462 + const struct vfsmount * parent_mnt,
23469 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
23470 + const struct dentry * parent_dentry,
23471 + const struct vfsmount * parent_mnt)
23477 +gr_acl_handle_symlink(const struct dentry * new_dentry,
23478 + const struct dentry * parent_dentry,
23479 + const struct vfsmount * parent_mnt, const char *from)
23485 +gr_acl_handle_link(const struct dentry * new_dentry,
23486 + const struct dentry * parent_dentry,
23487 + const struct vfsmount * parent_mnt,
23488 + const struct dentry * old_dentry,
23489 + const struct vfsmount * old_mnt, const char *to)
23495 +gr_acl_handle_rename(const struct dentry *new_dentry,
23496 + const struct dentry *parent_dentry,
23497 + const struct vfsmount *parent_mnt,
23498 + const struct dentry *old_dentry,
23499 + const struct inode *old_parent_inode,
23500 + const struct vfsmount *old_mnt, const char *newname)
23506 +gr_acl_handle_filldir(const struct file *file, const char *name,
23507 + const int namelen, const ino_t ino)
23513 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23514 + const time_t shm_createtime, const uid_t cuid, const int shmid)
23520 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
23526 +gr_search_accept(const struct socket *sock)
23532 +gr_search_listen(const struct socket *sock)
23538 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
23544 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
23550 +gr_acl_handle_creat(const struct dentry * dentry,
23551 + const struct dentry * p_dentry,
23552 + const struct vfsmount * p_mnt, const int fmode,
23559 +gr_acl_handle_exit(void)
23565 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
23571 +gr_set_role_label(const uid_t uid, const gid_t gid)
23577 +gr_acl_handle_procpidmem(const struct task_struct *task)
23583 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
23589 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
23595 +gr_set_kernel_label(struct task_struct *task)
23601 +gr_check_user_change(int real, int effective, int fs)
23607 +gr_check_group_change(int real, int effective, int fs)
23613 +EXPORT_SYMBOL(gr_task_is_capable);
23614 +EXPORT_SYMBOL(gr_is_capable_nolog);
23615 +EXPORT_SYMBOL(gr_learn_resource);
23616 +EXPORT_SYMBOL(gr_set_kernel_label);
23617 +#ifdef CONFIG_SECURITY
23618 +EXPORT_SYMBOL(gr_check_user_change);
23619 +EXPORT_SYMBOL(gr_check_group_change);
23621 diff -urNp linux-2.6.27.10/grsecurity/grsec_exec.c linux-2.6.27.10/grsecurity/grsec_exec.c
23622 --- linux-2.6.27.10/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
23623 +++ linux-2.6.27.10/grsecurity/grsec_exec.c 2008-11-18 03:38:45.000000000 -0500
23625 +#include <linux/kernel.h>
23626 +#include <linux/sched.h>
23627 +#include <linux/file.h>
23628 +#include <linux/binfmts.h>
23629 +#include <linux/smp_lock.h>
23630 +#include <linux/fs.h>
23631 +#include <linux/types.h>
23632 +#include <linux/grdefs.h>
23633 +#include <linux/grinternal.h>
23634 +#include <linux/capability.h>
23636 +#include <asm/uaccess.h>
23638 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23639 +static char gr_exec_arg_buf[132];
23640 +static DECLARE_MUTEX(gr_exec_arg_sem);
23644 +gr_handle_nproc(void)
23646 +#ifdef CONFIG_GRKERNSEC_EXECVE
23647 + if (grsec_enable_execve && current->user &&
23648 + (atomic_read(¤t->user->processes) >
23649 + current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
23650 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
23651 + gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
23659 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
23661 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23662 + char *grarg = gr_exec_arg_buf;
23663 + unsigned int i, x, execlen = 0;
23666 + if (!((grsec_enable_execlog && grsec_enable_group &&
23667 + in_group_p(grsec_audit_gid))
23668 + || (grsec_enable_execlog && !grsec_enable_group)))
23671 + down(&gr_exec_arg_sem);
23672 + memset(grarg, 0, sizeof(gr_exec_arg_buf));
23674 + if (unlikely(argv == NULL))
23677 + for (i = 0; i < bprm->argc && execlen < 128; i++) {
23678 + const char __user *p;
23679 + unsigned int len;
23681 + if (copy_from_user(&p, argv + i, sizeof(p)))
23685 + len = strnlen_user(p, 128 - execlen);
23686 + if (len > 128 - execlen)
23687 + len = 128 - execlen;
23688 + else if (len > 0)
23690 + if (copy_from_user(grarg + execlen, p, len))
23693 + /* rewrite unprintable characters */
23694 + for (x = 0; x < len; x++) {
23695 + c = *(grarg + execlen + x);
23696 + if (c < 32 || c > 126)
23697 + *(grarg + execlen + x) = ' ';
23701 + *(grarg + execlen) = ' ';
23702 + *(grarg + execlen + 1) = '\0';
23707 + gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
23708 + bprm->file->f_path.mnt, grarg);
23709 + up(&gr_exec_arg_sem);
23713 diff -urNp linux-2.6.27.10/grsecurity/grsec_fifo.c linux-2.6.27.10/grsecurity/grsec_fifo.c
23714 --- linux-2.6.27.10/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
23715 +++ linux-2.6.27.10/grsecurity/grsec_fifo.c 2008-11-18 03:38:45.000000000 -0500
23717 +#include <linux/kernel.h>
23718 +#include <linux/sched.h>
23719 +#include <linux/fs.h>
23720 +#include <linux/file.h>
23721 +#include <linux/grinternal.h>
23724 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
23725 + const struct dentry *dir, const int flag, const int acc_mode)
23727 +#ifdef CONFIG_GRKERNSEC_FIFO
23728 + if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
23729 + !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
23730 + (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
23731 + (current->fsuid != dentry->d_inode->i_uid)) {
23732 + if (!generic_permission(dentry->d_inode, acc_mode, NULL))
23733 + gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
23739 diff -urNp linux-2.6.27.10/grsecurity/grsec_fork.c linux-2.6.27.10/grsecurity/grsec_fork.c
23740 --- linux-2.6.27.10/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
23741 +++ linux-2.6.27.10/grsecurity/grsec_fork.c 2008-11-18 03:38:45.000000000 -0500
23743 +#include <linux/kernel.h>
23744 +#include <linux/sched.h>
23745 +#include <linux/grsecurity.h>
23746 +#include <linux/grinternal.h>
23747 +#include <linux/errno.h>
23750 +gr_log_forkfail(const int retval)
23752 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
23753 + if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
23754 + gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
23758 diff -urNp linux-2.6.27.10/grsecurity/grsec_init.c linux-2.6.27.10/grsecurity/grsec_init.c
23759 --- linux-2.6.27.10/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
23760 +++ linux-2.6.27.10/grsecurity/grsec_init.c 2008-11-18 03:38:45.000000000 -0500
23762 +#include <linux/kernel.h>
23763 +#include <linux/sched.h>
23764 +#include <linux/mm.h>
23765 +#include <linux/smp_lock.h>
23766 +#include <linux/gracl.h>
23767 +#include <linux/slab.h>
23768 +#include <linux/vmalloc.h>
23769 +#include <linux/percpu.h>
23771 +int grsec_enable_link;
23772 +int grsec_enable_dmesg;
23773 +int grsec_enable_fifo;
23774 +int grsec_enable_execve;
23775 +int grsec_enable_execlog;
23776 +int grsec_enable_signal;
23777 +int grsec_enable_forkfail;
23778 +int grsec_enable_time;
23779 +int grsec_enable_audit_textrel;
23780 +int grsec_enable_group;
23781 +int grsec_audit_gid;
23782 +int grsec_enable_chdir;
23783 +int grsec_enable_audit_ipc;
23784 +int grsec_enable_mount;
23785 +int grsec_enable_chroot_findtask;
23786 +int grsec_enable_chroot_mount;
23787 +int grsec_enable_chroot_shmat;
23788 +int grsec_enable_chroot_fchdir;
23789 +int grsec_enable_chroot_double;
23790 +int grsec_enable_chroot_pivot;
23791 +int grsec_enable_chroot_chdir;
23792 +int grsec_enable_chroot_chmod;
23793 +int grsec_enable_chroot_mknod;
23794 +int grsec_enable_chroot_nice;
23795 +int grsec_enable_chroot_execlog;
23796 +int grsec_enable_chroot_caps;
23797 +int grsec_enable_chroot_sysctl;
23798 +int grsec_enable_chroot_unix;
23799 +int grsec_enable_tpe;
23800 +int grsec_tpe_gid;
23801 +int grsec_enable_tpe_all;
23802 +int grsec_enable_socket_all;
23803 +int grsec_socket_all_gid;
23804 +int grsec_enable_socket_client;
23805 +int grsec_socket_client_gid;
23806 +int grsec_enable_socket_server;
23807 +int grsec_socket_server_gid;
23808 +int grsec_resource_logging;
23811 +DEFINE_SPINLOCK(grsec_alert_lock);
23812 +unsigned long grsec_alert_wtime = 0;
23813 +unsigned long grsec_alert_fyet = 0;
23815 +DEFINE_SPINLOCK(grsec_audit_lock);
23817 +DEFINE_RWLOCK(grsec_exec_file_lock);
23819 +char *gr_shared_page[4];
23821 +char *gr_alert_log_fmt;
23822 +char *gr_audit_log_fmt;
23823 +char *gr_alert_log_buf;
23824 +char *gr_audit_log_buf;
23826 +extern struct gr_arg *gr_usermode;
23827 +extern unsigned char *gr_system_salt;
23828 +extern unsigned char *gr_system_sum;
23831 +grsecurity_init(void)
23834 + /* create the per-cpu shared pages */
23837 + memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
23840 + for (j = 0; j < 4; j++) {
23841 + gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
23842 + if (gr_shared_page[j] == NULL) {
23843 + panic("Unable to allocate grsecurity shared page");
23848 + /* allocate log buffers */
23849 + gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
23850 + if (!gr_alert_log_fmt) {
23851 + panic("Unable to allocate grsecurity alert log format buffer");
23854 + gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
23855 + if (!gr_audit_log_fmt) {
23856 + panic("Unable to allocate grsecurity audit log format buffer");
23859 + gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23860 + if (!gr_alert_log_buf) {
23861 + panic("Unable to allocate grsecurity alert log buffer");
23864 + gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23865 + if (!gr_audit_log_buf) {
23866 + panic("Unable to allocate grsecurity audit log buffer");
23870 + /* allocate memory for authentication structure */
23871 + gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
23872 + gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
23873 + gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
23875 + if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
23876 + panic("Unable to allocate grsecurity authentication structure");
23880 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
23881 +#ifndef CONFIG_GRKERNSEC_SYSCTL
23884 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
23885 + grsec_enable_audit_textrel = 1;
23887 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
23888 + grsec_enable_group = 1;
23889 + grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
23891 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
23892 + grsec_enable_chdir = 1;
23894 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23895 + grsec_enable_audit_ipc = 1;
23897 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
23898 + grsec_enable_mount = 1;
23900 +#ifdef CONFIG_GRKERNSEC_LINK
23901 + grsec_enable_link = 1;
23903 +#ifdef CONFIG_GRKERNSEC_DMESG
23904 + grsec_enable_dmesg = 1;
23906 +#ifdef CONFIG_GRKERNSEC_FIFO
23907 + grsec_enable_fifo = 1;
23909 +#ifdef CONFIG_GRKERNSEC_EXECVE
23910 + grsec_enable_execve = 1;
23912 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23913 + grsec_enable_execlog = 1;
23915 +#ifdef CONFIG_GRKERNSEC_SIGNAL
23916 + grsec_enable_signal = 1;
23918 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
23919 + grsec_enable_forkfail = 1;
23921 +#ifdef CONFIG_GRKERNSEC_TIME
23922 + grsec_enable_time = 1;
23924 +#ifdef CONFIG_GRKERNSEC_RESLOG
23925 + grsec_resource_logging = 1;
23927 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
23928 + grsec_enable_chroot_findtask = 1;
23930 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23931 + grsec_enable_chroot_unix = 1;
23933 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23934 + grsec_enable_chroot_mount = 1;
23936 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23937 + grsec_enable_chroot_fchdir = 1;
23939 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23940 + grsec_enable_chroot_shmat = 1;
23942 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23943 + grsec_enable_chroot_double = 1;
23945 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23946 + grsec_enable_chroot_pivot = 1;
23948 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23949 + grsec_enable_chroot_chdir = 1;
23951 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23952 + grsec_enable_chroot_chmod = 1;
23954 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23955 + grsec_enable_chroot_mknod = 1;
23957 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23958 + grsec_enable_chroot_nice = 1;
23960 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23961 + grsec_enable_chroot_execlog = 1;
23963 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23964 + grsec_enable_chroot_caps = 1;
23966 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23967 + grsec_enable_chroot_sysctl = 1;
23969 +#ifdef CONFIG_GRKERNSEC_TPE
23970 + grsec_enable_tpe = 1;
23971 + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
23972 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
23973 + grsec_enable_tpe_all = 1;
23976 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
23977 + grsec_enable_socket_all = 1;
23978 + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
23980 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
23981 + grsec_enable_socket_client = 1;
23982 + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
23984 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
23985 + grsec_enable_socket_server = 1;
23986 + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
23992 diff -urNp linux-2.6.27.10/grsecurity/grsec_ipc.c linux-2.6.27.10/grsecurity/grsec_ipc.c
23993 --- linux-2.6.27.10/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
23994 +++ linux-2.6.27.10/grsecurity/grsec_ipc.c 2008-11-18 03:38:45.000000000 -0500
23996 +#include <linux/kernel.h>
23997 +#include <linux/sched.h>
23998 +#include <linux/types.h>
23999 +#include <linux/ipc.h>
24000 +#include <linux/grsecurity.h>
24001 +#include <linux/grinternal.h>
24004 +gr_log_msgget(const int ret, const int msgflg)
24006 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24007 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24008 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24009 + !grsec_enable_group)) && (ret >= 0)
24010 + && (msgflg & IPC_CREAT))
24011 + gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
24017 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
24019 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24020 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24021 + grsec_enable_audit_ipc) ||
24022 + (grsec_enable_audit_ipc && !grsec_enable_group))
24023 + gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
24029 +gr_log_semget(const int err, const int semflg)
24031 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24032 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24033 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24034 + !grsec_enable_group)) && (err >= 0)
24035 + && (semflg & IPC_CREAT))
24036 + gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
24042 +gr_log_semrm(const uid_t uid, const uid_t cuid)
24044 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24045 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24046 + grsec_enable_audit_ipc) ||
24047 + (grsec_enable_audit_ipc && !grsec_enable_group))
24048 + gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
24054 +gr_log_shmget(const int err, const int shmflg, const size_t size)
24056 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24057 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24058 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24059 + !grsec_enable_group)) && (err >= 0)
24060 + && (shmflg & IPC_CREAT))
24061 + gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
24067 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
24069 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24070 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24071 + grsec_enable_audit_ipc) ||
24072 + (grsec_enable_audit_ipc && !grsec_enable_group))
24073 + gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
24077 diff -urNp linux-2.6.27.10/grsecurity/grsec_link.c linux-2.6.27.10/grsecurity/grsec_link.c
24078 --- linux-2.6.27.10/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
24079 +++ linux-2.6.27.10/grsecurity/grsec_link.c 2008-11-18 03:38:45.000000000 -0500
24081 +#include <linux/kernel.h>
24082 +#include <linux/sched.h>
24083 +#include <linux/fs.h>
24084 +#include <linux/file.h>
24085 +#include <linux/grinternal.h>
24088 +gr_handle_follow_link(const struct inode *parent,
24089 + const struct inode *inode,
24090 + const struct dentry *dentry, const struct vfsmount *mnt)
24092 +#ifdef CONFIG_GRKERNSEC_LINK
24093 + if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
24094 + (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
24095 + (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
24096 + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
24104 +gr_handle_hardlink(const struct dentry *dentry,
24105 + const struct vfsmount *mnt,
24106 + struct inode *inode, const int mode, const char *to)
24108 +#ifdef CONFIG_GRKERNSEC_LINK
24109 + if (grsec_enable_link && current->fsuid != inode->i_uid &&
24110 + (!S_ISREG(mode) || (mode & S_ISUID) ||
24111 + ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
24112 + (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
24113 + !capable(CAP_FOWNER) && current->uid) {
24114 + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
24120 diff -urNp linux-2.6.27.10/grsecurity/grsec_log.c linux-2.6.27.10/grsecurity/grsec_log.c
24121 --- linux-2.6.27.10/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
24122 +++ linux-2.6.27.10/grsecurity/grsec_log.c 2008-11-18 03:38:45.000000000 -0500
24124 +#include <linux/kernel.h>
24125 +#include <linux/sched.h>
24126 +#include <linux/file.h>
24127 +#include <linux/tty.h>
24128 +#include <linux/fs.h>
24129 +#include <linux/grinternal.h>
24131 +#define BEGIN_LOCKS(x) \
24132 + read_lock(&tasklist_lock); \
24133 + read_lock(&grsec_exec_file_lock); \
24134 + if (x != GR_DO_AUDIT) \
24135 + spin_lock(&grsec_alert_lock); \
24137 + spin_lock(&grsec_audit_lock)
24139 +#define END_LOCKS(x) \
24140 + if (x != GR_DO_AUDIT) \
24141 + spin_unlock(&grsec_alert_lock); \
24143 + spin_unlock(&grsec_audit_lock); \
24144 + read_unlock(&grsec_exec_file_lock); \
24145 + read_unlock(&tasklist_lock); \
24146 + if (x == GR_DONT_AUDIT) \
24147 + gr_handle_alertkill(current)
24154 +extern char *gr_alert_log_fmt;
24155 +extern char *gr_audit_log_fmt;
24156 +extern char *gr_alert_log_buf;
24157 +extern char *gr_audit_log_buf;
24159 +static int gr_log_start(int audit)
24161 + char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
24162 + char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
24163 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24165 + if (audit == GR_DO_AUDIT)
24168 + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
24169 + grsec_alert_wtime = jiffies;
24170 + grsec_alert_fyet = 0;
24171 + } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
24172 + grsec_alert_fyet++;
24173 + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
24174 + grsec_alert_wtime = jiffies;
24175 + grsec_alert_fyet++;
24176 + printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
24178 + } else return FLOODING;
24181 + memset(buf, 0, PAGE_SIZE);
24182 + if (current->signal->curr_ip && gr_acl_is_enabled()) {
24183 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
24184 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
24185 + } else if (current->signal->curr_ip) {
24186 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
24187 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
24188 + } else if (gr_acl_is_enabled()) {
24189 + sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
24190 + snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
24192 + sprintf(fmt, "%s%s", loglevel, "grsec: ");
24193 + strcpy(buf, fmt);
24196 + return NO_FLOODING;
24199 +static void gr_log_middle(int audit, const char *msg, va_list ap)
24201 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24202 + unsigned int len = strlen(buf);
24204 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
24209 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
24211 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24212 + unsigned int len = strlen(buf);
24215 + va_start(ap, msg);
24216 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
24222 +static void gr_log_end(int audit)
24224 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24225 + unsigned int len = strlen(buf);
24227 + snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
24228 + printk("%s\n", buf);
24233 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
24236 + char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
24237 + char *str1, *str2, *str3;
24239 + unsigned long ulong1, ulong2;
24240 + struct dentry *dentry;
24241 + struct vfsmount *mnt;
24242 + struct file *file;
24243 + struct task_struct *task;
24246 + BEGIN_LOCKS(audit);
24247 + logtype = gr_log_start(audit);
24248 + if (logtype == FLOODING) {
24249 + END_LOCKS(audit);
24252 + va_start(ap, argtypes);
24253 + switch (argtypes) {
24254 + case GR_TTYSNIFF:
24255 + task = va_arg(ap, struct task_struct *);
24256 + gr_log_middle_varargs(audit, msg, NIPQUAD(task->signal->curr_ip), gr_task_fullpath0(task), task->comm, task->pid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid);
24258 + case GR_SYSCTL_HIDDEN:
24259 + str1 = va_arg(ap, char *);
24260 + gr_log_middle_varargs(audit, msg, result, str1);
24263 + dentry = va_arg(ap, struct dentry *);
24264 + mnt = va_arg(ap, struct vfsmount *);
24265 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
24267 + case GR_RBAC_STR:
24268 + dentry = va_arg(ap, struct dentry *);
24269 + mnt = va_arg(ap, struct vfsmount *);
24270 + str1 = va_arg(ap, char *);
24271 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
24273 + case GR_STR_RBAC:
24274 + str1 = va_arg(ap, char *);
24275 + dentry = va_arg(ap, struct dentry *);
24276 + mnt = va_arg(ap, struct vfsmount *);
24277 + gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
24279 + case GR_RBAC_MODE2:
24280 + dentry = va_arg(ap, struct dentry *);
24281 + mnt = va_arg(ap, struct vfsmount *);
24282 + str1 = va_arg(ap, char *);
24283 + str2 = va_arg(ap, char *);
24284 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
24286 + case GR_RBAC_MODE3:
24287 + dentry = va_arg(ap, struct dentry *);
24288 + mnt = va_arg(ap, struct vfsmount *);
24289 + str1 = va_arg(ap, char *);
24290 + str2 = va_arg(ap, char *);
24291 + str3 = va_arg(ap, char *);
24292 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
24294 + case GR_FILENAME:
24295 + dentry = va_arg(ap, struct dentry *);
24296 + mnt = va_arg(ap, struct vfsmount *);
24297 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
24299 + case GR_STR_FILENAME:
24300 + str1 = va_arg(ap, char *);
24301 + dentry = va_arg(ap, struct dentry *);
24302 + mnt = va_arg(ap, struct vfsmount *);
24303 + gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
24305 + case GR_FILENAME_STR:
24306 + dentry = va_arg(ap, struct dentry *);
24307 + mnt = va_arg(ap, struct vfsmount *);
24308 + str1 = va_arg(ap, char *);
24309 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
24311 + case GR_FILENAME_TWO_INT:
24312 + dentry = va_arg(ap, struct dentry *);
24313 + mnt = va_arg(ap, struct vfsmount *);
24314 + num1 = va_arg(ap, int);
24315 + num2 = va_arg(ap, int);
24316 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
24318 + case GR_FILENAME_TWO_INT_STR:
24319 + dentry = va_arg(ap, struct dentry *);
24320 + mnt = va_arg(ap, struct vfsmount *);
24321 + num1 = va_arg(ap, int);
24322 + num2 = va_arg(ap, int);
24323 + str1 = va_arg(ap, char *);
24324 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
24327 + file = va_arg(ap, struct file *);
24328 + ulong1 = va_arg(ap, unsigned long);
24329 + ulong2 = va_arg(ap, unsigned long);
24330 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
24333 + task = va_arg(ap, struct task_struct *);
24334 + gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_path.dentry, task->exec_file->f_path.mnt) : "(none)", task->comm, task->pid);
24336 + case GR_RESOURCE:
24337 + task = va_arg(ap, struct task_struct *);
24338 + ulong1 = va_arg(ap, unsigned long);
24339 + str1 = va_arg(ap, char *);
24340 + ulong2 = va_arg(ap, unsigned long);
24341 + gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
24344 + task = va_arg(ap, struct task_struct *);
24345 + str1 = va_arg(ap, char *);
24346 + gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
24349 + task = va_arg(ap, struct task_struct *);
24350 + num1 = va_arg(ap, int);
24351 + gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
24354 + task = va_arg(ap, struct task_struct *);
24355 + ulong1 = va_arg(ap, unsigned long);
24356 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, task->uid, ulong1);
24359 + task = va_arg(ap, struct task_struct *);
24360 + ulong1 = va_arg(ap, unsigned long);
24361 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, ulong1);
24365 + unsigned int wday, cday;
24369 + char cur_tty[64] = { 0 };
24370 + char parent_tty[64] = { 0 };
24372 + task = va_arg(ap, struct task_struct *);
24373 + wday = va_arg(ap, unsigned int);
24374 + cday = va_arg(ap, unsigned int);
24375 + whr = va_arg(ap, int);
24376 + chr = va_arg(ap, int);
24377 + wmin = va_arg(ap, int);
24378 + cmin = va_arg(ap, int);
24379 + wsec = va_arg(ap, int);
24380 + csec = va_arg(ap, int);
24381 + ulong1 = va_arg(ap, unsigned long);
24383 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, NIPQUAD(task->signal->curr_ip), tty_name(task->signal->tty, cur_tty), task->uid, task->euid, task->gid, task->egid, wday, whr, wmin, wsec, cday, chr, cmin, csec, (task->flags & PF_SIGNALED) ? "killed by signal" : "exited", ulong1, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, NIPQUAD(task->parent->signal->curr_ip), tty_name(task->parent->signal->tty, parent_tty), task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
24387 + gr_log_middle(audit, msg, ap);
24390 + gr_log_end(audit);
24391 + END_LOCKS(audit);
24393 diff -urNp linux-2.6.27.10/grsecurity/grsec_mem.c linux-2.6.27.10/grsecurity/grsec_mem.c
24394 --- linux-2.6.27.10/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
24395 +++ linux-2.6.27.10/grsecurity/grsec_mem.c 2008-11-18 03:38:45.000000000 -0500
24397 +#include <linux/kernel.h>
24398 +#include <linux/sched.h>
24399 +#include <linux/mm.h>
24400 +#include <linux/mman.h>
24401 +#include <linux/grinternal.h>
24404 +gr_handle_ioperm(void)
24406 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
24411 +gr_handle_iopl(void)
24413 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
24418 +gr_handle_mem_write(void)
24420 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
24425 +gr_handle_kmem_write(void)
24427 + gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
24432 +gr_handle_open_port(void)
24434 + gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
24439 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
24441 + unsigned long start, end;
24444 + end = start + vma->vm_end - vma->vm_start;
24446 + if (start > end) {
24447 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
24451 + /* allowed ranges : ISA I/O BIOS */
24452 + if ((start >= __pa(high_memory))
24454 + || (start >= 0x000a0000 && end <= 0x00100000)
24455 + || (start >= 0x00000000 && end <= 0x00001000)
24460 + if (vma->vm_flags & VM_WRITE) {
24461 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
24464 + vma->vm_flags &= ~VM_MAYWRITE;
24468 diff -urNp linux-2.6.27.10/grsecurity/grsec_mount.c linux-2.6.27.10/grsecurity/grsec_mount.c
24469 --- linux-2.6.27.10/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
24470 +++ linux-2.6.27.10/grsecurity/grsec_mount.c 2008-11-18 03:38:45.000000000 -0500
24472 +#include <linux/kernel.h>
24473 +#include <linux/sched.h>
24474 +#include <linux/grsecurity.h>
24475 +#include <linux/grinternal.h>
24478 +gr_log_remount(const char *devname, const int retval)
24480 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24481 + if (grsec_enable_mount && (retval >= 0))
24482 + gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
24488 +gr_log_unmount(const char *devname, const int retval)
24490 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24491 + if (grsec_enable_mount && (retval >= 0))
24492 + gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
24498 +gr_log_mount(const char *from, const char *to, const int retval)
24500 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24501 + if (grsec_enable_mount && (retval >= 0))
24502 + gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
24506 diff -urNp linux-2.6.27.10/grsecurity/grsec_sig.c linux-2.6.27.10/grsecurity/grsec_sig.c
24507 --- linux-2.6.27.10/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
24508 +++ linux-2.6.27.10/grsecurity/grsec_sig.c 2008-11-18 03:38:45.000000000 -0500
24510 +#include <linux/kernel.h>
24511 +#include <linux/sched.h>
24512 +#include <linux/delay.h>
24513 +#include <linux/grsecurity.h>
24514 +#include <linux/grinternal.h>
24517 +gr_log_signal(const int sig, const struct task_struct *t)
24519 +#ifdef CONFIG_GRKERNSEC_SIGNAL
24520 + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
24521 + (sig == SIGABRT) || (sig == SIGBUS))) {
24522 + if (t->pid == current->pid) {
24523 + gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
24525 + gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
24533 +gr_handle_signal(const struct task_struct *p, const int sig)
24535 +#ifdef CONFIG_GRKERNSEC
24536 + if (current->pid > 1 && gr_check_protected_task(p)) {
24537 + gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
24539 + } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
24546 +void gr_handle_brute_attach(struct task_struct *p)
24548 +#ifdef CONFIG_GRKERNSEC_BRUTE
24549 + read_lock(&tasklist_lock);
24550 + read_lock(&grsec_exec_file_lock);
24551 + if (p->parent && p->parent->exec_file == p->exec_file)
24552 + p->parent->brute = 1;
24553 + read_unlock(&grsec_exec_file_lock);
24554 + read_unlock(&tasklist_lock);
24559 +void gr_handle_brute_check(void)
24561 +#ifdef CONFIG_GRKERNSEC_BRUTE
24562 + if (current->brute)
24563 + msleep(30 * 1000);
24568 diff -urNp linux-2.6.27.10/grsecurity/grsec_sock.c linux-2.6.27.10/grsecurity/grsec_sock.c
24569 --- linux-2.6.27.10/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
24570 +++ linux-2.6.27.10/grsecurity/grsec_sock.c 2008-11-18 11:35:13.000000000 -0500
24572 +#include <linux/kernel.h>
24573 +#include <linux/module.h>
24574 +#include <linux/sched.h>
24575 +#include <linux/file.h>
24576 +#include <linux/net.h>
24577 +#include <linux/in.h>
24578 +#include <linux/ip.h>
24579 +#include <net/sock.h>
24580 +#include <net/inet_sock.h>
24581 +#include <linux/grsecurity.h>
24582 +#include <linux/grinternal.h>
24583 +#include <linux/gracl.h>
24585 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
24586 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
24587 +EXPORT_SYMBOL(udp_v4_lookup);
24590 +kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
24591 +EXPORT_SYMBOL(gr_cap_rtnetlink);
24593 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
24594 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
24596 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
24597 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
24599 +#ifdef CONFIG_UNIX_MODULE
24600 +EXPORT_SYMBOL(gr_acl_handle_unix);
24601 +EXPORT_SYMBOL(gr_acl_handle_mknod);
24602 +EXPORT_SYMBOL(gr_handle_chroot_unix);
24603 +EXPORT_SYMBOL(gr_handle_create);
24606 +#ifdef CONFIG_GRKERNSEC
24607 +#define gr_conn_table_size 32749
24608 +struct conn_table_entry {
24609 + struct conn_table_entry *next;
24610 + struct signal_struct *sig;
24613 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
24614 +DEFINE_SPINLOCK(gr_conn_table_lock);
24616 +extern const char * gr_socktype_to_name(unsigned char type);
24617 +extern const char * gr_proto_to_name(unsigned char proto);
24619 +static __inline__ int
24620 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
24622 + return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
24625 +static __inline__ int
24626 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
24627 + __u16 sport, __u16 dport)
24629 + if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
24630 + sig->gr_sport == sport && sig->gr_dport == dport))
24636 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
24638 + struct conn_table_entry **match;
24639 + unsigned int index;
24641 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
24642 + sig->gr_sport, sig->gr_dport,
24643 + gr_conn_table_size);
24645 + newent->sig = sig;
24647 + match = &gr_conn_table[index];
24648 + newent->next = *match;
24654 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
24656 + struct conn_table_entry *match, *last = NULL;
24657 + unsigned int index;
24659 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
24660 + sig->gr_sport, sig->gr_dport,
24661 + gr_conn_table_size);
24663 + match = gr_conn_table[index];
24664 + while (match && !conn_match(match->sig,
24665 + sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
24666 + sig->gr_dport)) {
24668 + match = match->next;
24673 + last->next = match->next;
24675 + gr_conn_table[index] = NULL;
24682 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
24683 + __u16 sport, __u16 dport)
24685 + struct conn_table_entry *match;
24686 + unsigned int index;
24688 + index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
24690 + match = gr_conn_table[index];
24691 + while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
24692 + match = match->next;
24695 + return match->sig;
24702 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
24704 +#ifdef CONFIG_GRKERNSEC
24705 + struct signal_struct *sig = task->signal;
24706 + struct conn_table_entry *newent;
24708 + newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
24709 + if (newent == NULL)
24711 + /* no bh lock needed since we are called with bh disabled */
24712 + spin_lock(&gr_conn_table_lock);
24713 + gr_del_task_from_ip_table_nolock(sig);
24714 + sig->gr_saddr = inet->rcv_saddr;
24715 + sig->gr_daddr = inet->daddr;
24716 + sig->gr_sport = inet->sport;
24717 + sig->gr_dport = inet->dport;
24718 + gr_add_to_task_ip_table_nolock(sig, newent);
24719 + spin_unlock(&gr_conn_table_lock);
24724 +void gr_del_task_from_ip_table(struct task_struct *task)
24726 +#ifdef CONFIG_GRKERNSEC
24727 + spin_lock_bh(&gr_conn_table_lock);
24728 + gr_del_task_from_ip_table_nolock(task->signal);
24729 + spin_unlock_bh(&gr_conn_table_lock);
24735 +gr_attach_curr_ip(const struct sock *sk)
24737 +#ifdef CONFIG_GRKERNSEC
24738 + struct signal_struct *p, *set;
24739 + const struct inet_sock *inet = inet_sk(sk);
24741 + if (unlikely(sk->sk_protocol != IPPROTO_TCP))
24744 + set = current->signal;
24746 + spin_lock_bh(&gr_conn_table_lock);
24747 + p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
24748 + inet->dport, inet->sport);
24749 + if (unlikely(p != NULL)) {
24750 + set->curr_ip = p->curr_ip;
24751 + set->used_accept = 1;
24752 + gr_del_task_from_ip_table_nolock(p);
24753 + spin_unlock_bh(&gr_conn_table_lock);
24756 + spin_unlock_bh(&gr_conn_table_lock);
24758 + set->curr_ip = inet->daddr;
24759 + set->used_accept = 1;
24765 +gr_handle_sock_all(const int family, const int type, const int protocol)
24767 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24768 + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
24769 + (family != AF_UNIX) && (family != AF_LOCAL)) {
24770 + gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
24778 +gr_handle_sock_server(const struct sockaddr *sck)
24780 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24781 + if (grsec_enable_socket_server &&
24782 + in_group_p(grsec_socket_server_gid) &&
24783 + sck && (sck->sa_family != AF_UNIX) &&
24784 + (sck->sa_family != AF_LOCAL)) {
24785 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24793 +gr_handle_sock_server_other(const struct sock *sck)
24795 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24796 + if (grsec_enable_socket_server &&
24797 + in_group_p(grsec_socket_server_gid) &&
24798 + sck && (sck->sk_family != AF_UNIX) &&
24799 + (sck->sk_family != AF_LOCAL)) {
24800 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24808 +gr_handle_sock_client(const struct sockaddr *sck)
24810 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24811 + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
24812 + sck && (sck->sa_family != AF_UNIX) &&
24813 + (sck->sa_family != AF_LOCAL)) {
24814 + gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
24822 +gr_cap_rtnetlink(struct sock *sock)
24824 +#ifdef CONFIG_GRKERNSEC
24825 + if (!gr_acl_is_enabled())
24826 + return current->cap_effective;
24827 + else if (sock->sk_protocol == NETLINK_ISCSI &&
24828 + cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
24829 + gr_task_is_capable(current, CAP_SYS_ADMIN))
24830 + return current->cap_effective;
24831 + else if (sock->sk_protocol == NETLINK_AUDIT &&
24832 + cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
24833 + gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
24834 + cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
24835 + gr_task_is_capable(current, CAP_AUDIT_CONTROL))
24836 + return current->cap_effective;
24837 + else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
24838 + gr_task_is_capable(current, CAP_NET_ADMIN))
24839 + return current->cap_effective;
24841 + return __cap_empty_set;
24843 + return current->cap_effective;
24846 diff -urNp linux-2.6.27.10/grsecurity/grsec_sysctl.c linux-2.6.27.10/grsecurity/grsec_sysctl.c
24847 --- linux-2.6.27.10/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
24848 +++ linux-2.6.27.10/grsecurity/grsec_sysctl.c 2008-11-18 03:38:45.000000000 -0500
24850 +#include <linux/kernel.h>
24851 +#include <linux/sched.h>
24852 +#include <linux/sysctl.h>
24853 +#include <linux/grsecurity.h>
24854 +#include <linux/grinternal.h>
24856 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24857 +int grsec_modstop;
24861 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
24863 +#ifdef CONFIG_GRKERNSEC_SYSCTL
24864 + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
24865 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24869 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24870 + if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
24871 + grsec_modstop && (op & MAY_WRITE)) {
24872 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24879 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
24880 +ctl_table grsecurity_table[] = {
24881 +#ifdef CONFIG_GRKERNSEC_SYSCTL
24882 +#ifdef CONFIG_GRKERNSEC_LINK
24884 + .ctl_name = CTL_UNNUMBERED,
24885 + .procname = "linking_restrictions",
24886 + .data = &grsec_enable_link,
24887 + .maxlen = sizeof(int),
24889 + .proc_handler = &proc_dointvec,
24892 +#ifdef CONFIG_GRKERNSEC_FIFO
24894 + .ctl_name = CTL_UNNUMBERED,
24895 + .procname = "fifo_restrictions",
24896 + .data = &grsec_enable_fifo,
24897 + .maxlen = sizeof(int),
24899 + .proc_handler = &proc_dointvec,
24902 +#ifdef CONFIG_GRKERNSEC_EXECVE
24904 + .ctl_name = CTL_UNNUMBERED,
24905 + .procname = "execve_limiting",
24906 + .data = &grsec_enable_execve,
24907 + .maxlen = sizeof(int),
24909 + .proc_handler = &proc_dointvec,
24912 +#ifdef CONFIG_GRKERNSEC_EXECLOG
24914 + .ctl_name = CTL_UNNUMBERED,
24915 + .procname = "exec_logging",
24916 + .data = &grsec_enable_execlog,
24917 + .maxlen = sizeof(int),
24919 + .proc_handler = &proc_dointvec,
24922 +#ifdef CONFIG_GRKERNSEC_SIGNAL
24924 + .ctl_name = CTL_UNNUMBERED,
24925 + .procname = "signal_logging",
24926 + .data = &grsec_enable_signal,
24927 + .maxlen = sizeof(int),
24929 + .proc_handler = &proc_dointvec,
24932 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
24934 + .ctl_name = CTL_UNNUMBERED,
24935 + .procname = "forkfail_logging",
24936 + .data = &grsec_enable_forkfail,
24937 + .maxlen = sizeof(int),
24939 + .proc_handler = &proc_dointvec,
24942 +#ifdef CONFIG_GRKERNSEC_TIME
24944 + .ctl_name = CTL_UNNUMBERED,
24945 + .procname = "timechange_logging",
24946 + .data = &grsec_enable_time,
24947 + .maxlen = sizeof(int),
24949 + .proc_handler = &proc_dointvec,
24952 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
24954 + .ctl_name = CTL_UNNUMBERED,
24955 + .procname = "chroot_deny_shmat",
24956 + .data = &grsec_enable_chroot_shmat,
24957 + .maxlen = sizeof(int),
24959 + .proc_handler = &proc_dointvec,
24962 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
24964 + .ctl_name = CTL_UNNUMBERED,
24965 + .procname = "chroot_deny_unix",
24966 + .data = &grsec_enable_chroot_unix,
24967 + .maxlen = sizeof(int),
24969 + .proc_handler = &proc_dointvec,
24972 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
24974 + .ctl_name = CTL_UNNUMBERED,
24975 + .procname = "chroot_deny_mount",
24976 + .data = &grsec_enable_chroot_mount,
24977 + .maxlen = sizeof(int),
24979 + .proc_handler = &proc_dointvec,
24982 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
24984 + .ctl_name = CTL_UNNUMBERED,
24985 + .procname = "chroot_deny_fchdir",
24986 + .data = &grsec_enable_chroot_fchdir,
24987 + .maxlen = sizeof(int),
24989 + .proc_handler = &proc_dointvec,
24992 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
24994 + .ctl_name = CTL_UNNUMBERED,
24995 + .procname = "chroot_deny_chroot",
24996 + .data = &grsec_enable_chroot_double,
24997 + .maxlen = sizeof(int),
24999 + .proc_handler = &proc_dointvec,
25002 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
25004 + .ctl_name = CTL_UNNUMBERED,
25005 + .procname = "chroot_deny_pivot",
25006 + .data = &grsec_enable_chroot_pivot,
25007 + .maxlen = sizeof(int),
25009 + .proc_handler = &proc_dointvec,
25012 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
25014 + .ctl_name = CTL_UNNUMBERED,
25015 + .procname = "chroot_enforce_chdir",
25016 + .data = &grsec_enable_chroot_chdir,
25017 + .maxlen = sizeof(int),
25019 + .proc_handler = &proc_dointvec,
25022 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
25024 + .ctl_name = CTL_UNNUMBERED,
25025 + .procname = "chroot_deny_chmod",
25026 + .data = &grsec_enable_chroot_chmod,
25027 + .maxlen = sizeof(int),
25029 + .proc_handler = &proc_dointvec,
25032 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
25034 + .ctl_name = CTL_UNNUMBERED,
25035 + .procname = "chroot_deny_mknod",
25036 + .data = &grsec_enable_chroot_mknod,
25037 + .maxlen = sizeof(int),
25039 + .proc_handler = &proc_dointvec,
25042 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25044 + .ctl_name = CTL_UNNUMBERED,
25045 + .procname = "chroot_restrict_nice",
25046 + .data = &grsec_enable_chroot_nice,
25047 + .maxlen = sizeof(int),
25049 + .proc_handler = &proc_dointvec,
25052 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
25054 + .ctl_name = CTL_UNNUMBERED,
25055 + .procname = "chroot_execlog",
25056 + .data = &grsec_enable_chroot_execlog,
25057 + .maxlen = sizeof(int),
25059 + .proc_handler = &proc_dointvec,
25062 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25064 + .ctl_name = CTL_UNNUMBERED,
25065 + .procname = "chroot_caps",
25066 + .data = &grsec_enable_chroot_caps,
25067 + .maxlen = sizeof(int),
25069 + .proc_handler = &proc_dointvec,
25072 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
25074 + .ctl_name = CTL_UNNUMBERED,
25075 + .procname = "chroot_deny_sysctl",
25076 + .data = &grsec_enable_chroot_sysctl,
25077 + .maxlen = sizeof(int),
25079 + .proc_handler = &proc_dointvec,
25082 +#ifdef CONFIG_GRKERNSEC_TPE
25084 + .ctl_name = CTL_UNNUMBERED,
25085 + .procname = "tpe",
25086 + .data = &grsec_enable_tpe,
25087 + .maxlen = sizeof(int),
25089 + .proc_handler = &proc_dointvec,
25092 + .ctl_name = CTL_UNNUMBERED,
25093 + .procname = "tpe_gid",
25094 + .data = &grsec_tpe_gid,
25095 + .maxlen = sizeof(int),
25097 + .proc_handler = &proc_dointvec,
25100 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
25102 + .ctl_name = CTL_UNNUMBERED,
25103 + .procname = "tpe_restrict_all",
25104 + .data = &grsec_enable_tpe_all,
25105 + .maxlen = sizeof(int),
25107 + .proc_handler = &proc_dointvec,
25110 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
25112 + .ctl_name = CTL_UNNUMBERED,
25113 + .procname = "socket_all",
25114 + .data = &grsec_enable_socket_all,
25115 + .maxlen = sizeof(int),
25117 + .proc_handler = &proc_dointvec,
25120 + .ctl_name = CTL_UNNUMBERED,
25121 + .procname = "socket_all_gid",
25122 + .data = &grsec_socket_all_gid,
25123 + .maxlen = sizeof(int),
25125 + .proc_handler = &proc_dointvec,
25128 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
25130 + .ctl_name = CTL_UNNUMBERED,
25131 + .procname = "socket_client",
25132 + .data = &grsec_enable_socket_client,
25133 + .maxlen = sizeof(int),
25135 + .proc_handler = &proc_dointvec,
25138 + .ctl_name = CTL_UNNUMBERED,
25139 + .procname = "socket_client_gid",
25140 + .data = &grsec_socket_client_gid,
25141 + .maxlen = sizeof(int),
25143 + .proc_handler = &proc_dointvec,
25146 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
25148 + .ctl_name = CTL_UNNUMBERED,
25149 + .procname = "socket_server",
25150 + .data = &grsec_enable_socket_server,
25151 + .maxlen = sizeof(int),
25153 + .proc_handler = &proc_dointvec,
25156 + .ctl_name = CTL_UNNUMBERED,
25157 + .procname = "socket_server_gid",
25158 + .data = &grsec_socket_server_gid,
25159 + .maxlen = sizeof(int),
25161 + .proc_handler = &proc_dointvec,
25164 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
25166 + .ctl_name = CTL_UNNUMBERED,
25167 + .procname = "audit_group",
25168 + .data = &grsec_enable_group,
25169 + .maxlen = sizeof(int),
25171 + .proc_handler = &proc_dointvec,
25174 + .ctl_name = CTL_UNNUMBERED,
25175 + .procname = "audit_gid",
25176 + .data = &grsec_audit_gid,
25177 + .maxlen = sizeof(int),
25179 + .proc_handler = &proc_dointvec,
25182 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
25184 + .ctl_name = CTL_UNNUMBERED,
25185 + .procname = "audit_chdir",
25186 + .data = &grsec_enable_chdir,
25187 + .maxlen = sizeof(int),
25189 + .proc_handler = &proc_dointvec,
25192 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25194 + .ctl_name = CTL_UNNUMBERED,
25195 + .procname = "audit_mount",
25196 + .data = &grsec_enable_mount,
25197 + .maxlen = sizeof(int),
25199 + .proc_handler = &proc_dointvec,
25202 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
25204 + .ctl_name = CTL_UNNUMBERED,
25205 + .procname = "audit_ipc",
25206 + .data = &grsec_enable_audit_ipc,
25207 + .maxlen = sizeof(int),
25209 + .proc_handler = &proc_dointvec,
25212 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
25214 + .ctl_name = CTL_UNNUMBERED,
25215 + .procname = "audit_textrel",
25216 + .data = &grsec_enable_audit_textrel,
25217 + .maxlen = sizeof(int),
25219 + .proc_handler = &proc_dointvec,
25222 +#ifdef CONFIG_GRKERNSEC_DMESG
25224 + .ctl_name = CTL_UNNUMBERED,
25225 + .procname = "dmesg",
25226 + .data = &grsec_enable_dmesg,
25227 + .maxlen = sizeof(int),
25229 + .proc_handler = &proc_dointvec,
25232 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
25234 + .ctl_name = CTL_UNNUMBERED,
25235 + .procname = "chroot_findtask",
25236 + .data = &grsec_enable_chroot_findtask,
25237 + .maxlen = sizeof(int),
25239 + .proc_handler = &proc_dointvec,
25242 +#ifdef CONFIG_GRKERNSEC_RESLOG
25244 + .ctl_name = CTL_UNNUMBERED,
25245 + .procname = "resource_logging",
25246 + .data = &grsec_resource_logging,
25247 + .maxlen = sizeof(int),
25249 + .proc_handler = &proc_dointvec,
25253 + .ctl_name = CTL_UNNUMBERED,
25254 + .procname = "grsec_lock",
25255 + .data = &grsec_lock,
25256 + .maxlen = sizeof(int),
25258 + .proc_handler = &proc_dointvec,
25261 +#ifdef CONFIG_GRKERNSEC_MODSTOP
25263 + .ctl_name = CTL_UNNUMBERED,
25264 + .procname = "disable_modules",
25265 + .data = &grsec_modstop,
25266 + .maxlen = sizeof(int),
25268 + .proc_handler = &proc_dointvec,
25271 + { .ctl_name = 0 }
25275 +int gr_check_modstop(void)
25277 +#ifdef CONFIG_GRKERNSEC_MODSTOP
25278 + if (grsec_modstop == 1) {
25279 + gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
25285 diff -urNp linux-2.6.27.10/grsecurity/grsec_textrel.c linux-2.6.27.10/grsecurity/grsec_textrel.c
25286 --- linux-2.6.27.10/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
25287 +++ linux-2.6.27.10/grsecurity/grsec_textrel.c 2008-11-18 03:38:45.000000000 -0500
25289 +#include <linux/kernel.h>
25290 +#include <linux/sched.h>
25291 +#include <linux/mm.h>
25292 +#include <linux/file.h>
25293 +#include <linux/grinternal.h>
25294 +#include <linux/grsecurity.h>
25297 +gr_log_textrel(struct vm_area_struct * vma)
25299 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
25300 + if (grsec_enable_audit_textrel)
25301 + gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
25305 diff -urNp linux-2.6.27.10/grsecurity/grsec_time.c linux-2.6.27.10/grsecurity/grsec_time.c
25306 --- linux-2.6.27.10/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
25307 +++ linux-2.6.27.10/grsecurity/grsec_time.c 2008-11-18 03:38:45.000000000 -0500
25309 +#include <linux/kernel.h>
25310 +#include <linux/sched.h>
25311 +#include <linux/grinternal.h>
25314 +gr_log_timechange(void)
25316 +#ifdef CONFIG_GRKERNSEC_TIME
25317 + if (grsec_enable_time)
25318 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
25322 diff -urNp linux-2.6.27.10/grsecurity/grsec_tpe.c linux-2.6.27.10/grsecurity/grsec_tpe.c
25323 --- linux-2.6.27.10/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
25324 +++ linux-2.6.27.10/grsecurity/grsec_tpe.c 2008-11-18 03:38:45.000000000 -0500
25326 +#include <linux/kernel.h>
25327 +#include <linux/sched.h>
25328 +#include <linux/file.h>
25329 +#include <linux/fs.h>
25330 +#include <linux/grinternal.h>
25332 +extern int gr_acl_tpe_check(void);
25335 +gr_tpe_allow(const struct file *file)
25337 +#ifdef CONFIG_GRKERNSEC
25338 + struct inode *inode = file->f_path.dentry->d_parent->d_inode;
25340 + if (current->uid && ((grsec_enable_tpe &&
25341 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
25342 + !in_group_p(grsec_tpe_gid)
25344 + in_group_p(grsec_tpe_gid)
25346 + ) || gr_acl_tpe_check()) &&
25347 + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
25348 + (inode->i_mode & S_IWOTH))))) {
25349 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
25352 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
25353 + if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
25354 + ((inode->i_uid && (inode->i_uid != current->uid)) ||
25355 + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
25356 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
25363 diff -urNp linux-2.6.27.10/grsecurity/grsum.c linux-2.6.27.10/grsecurity/grsum.c
25364 --- linux-2.6.27.10/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
25365 +++ linux-2.6.27.10/grsecurity/grsum.c 2008-11-18 03:38:45.000000000 -0500
25367 +#include <linux/err.h>
25368 +#include <linux/kernel.h>
25369 +#include <linux/sched.h>
25370 +#include <linux/mm.h>
25371 +#include <linux/scatterlist.h>
25372 +#include <linux/crypto.h>
25373 +#include <linux/gracl.h>
25376 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
25377 +#error "crypto and sha256 must be built into the kernel"
25381 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
25384 + struct crypto_hash *tfm;
25385 + struct hash_desc desc;
25386 + struct scatterlist sg;
25387 + unsigned char temp_sum[GR_SHA_LEN];
25388 + volatile int retval = 0;
25389 + volatile int dummy = 0;
25392 + tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
25393 + if (IS_ERR(tfm)) {
25394 + /* should never happen, since sha256 should be built in */
25401 + crypto_hash_init(&desc);
25404 + sg_set_buf(&sg, p, GR_SALT_LEN);
25405 + crypto_hash_update(&desc, &sg, sg.length);
25408 + sg_set_buf(&sg, p, strlen(p));
25410 + crypto_hash_update(&desc, &sg, sg.length);
25412 + crypto_hash_final(&desc, temp_sum);
25414 + memset(entry->pw, 0, GR_PW_LEN);
25416 + for (i = 0; i < GR_SHA_LEN; i++)
25417 + if (sum[i] != temp_sum[i])
25420 + dummy = 1; // waste a cycle
25422 + crypto_free_hash(tfm);
25426 diff -urNp linux-2.6.27.10/grsecurity/Kconfig linux-2.6.27.10/grsecurity/Kconfig
25427 --- linux-2.6.27.10/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
25428 +++ linux-2.6.27.10/grsecurity/Kconfig 2008-11-18 11:18:57.000000000 -0500
25431 +# grecurity configuration
25437 + bool "Grsecurity"
25439 + select CRYPTO_SHA256
25441 + select SECURITY_CAPABILITIES
25443 + If you say Y here, you will be able to configure many features
25444 + that will enhance the security of your system. It is highly
25445 + recommended that you say Y here and read through the help
25446 + for each option so that you fully understand the features and
25447 + can evaluate their usefulness for your machine.
25450 + prompt "Security Level"
25451 + depends on GRKERNSEC
25452 + default GRKERNSEC_CUSTOM
25454 +config GRKERNSEC_LOW
25456 + select GRKERNSEC_LINK
25457 + select GRKERNSEC_FIFO
25458 + select GRKERNSEC_EXECVE
25459 + select GRKERNSEC_RANDNET
25460 + select GRKERNSEC_DMESG
25461 + select GRKERNSEC_CHROOT_CHDIR
25462 + select GRKERNSEC_MODSTOP if (MODULES)
25465 + If you choose this option, several of the grsecurity options will
25466 + be enabled that will give you greater protection against a number
25467 + of attacks, while assuring that none of your software will have any
25468 + conflicts with the additional security measures. If you run a lot
25469 + of unusual software, or you are having problems with the higher
25470 + security levels, you should say Y here. With this option, the
25471 + following features are enabled:
25473 + - Linking restrictions
25474 + - FIFO restrictions
25475 + - Enforcing RLIMIT_NPROC on execve
25476 + - Restricted dmesg
25477 + - Enforced chdir("/") on chroot
25478 + - Runtime module disabling
25480 +config GRKERNSEC_MEDIUM
25483 + select PAX_EI_PAX
25484 + select PAX_PT_PAX_FLAGS
25485 + select PAX_HAVE_ACL_FLAGS
25486 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
25487 + select GRKERNSEC_CHROOT_SYSCTL
25488 + select GRKERNSEC_LINK
25489 + select GRKERNSEC_FIFO
25490 + select GRKERNSEC_EXECVE
25491 + select GRKERNSEC_DMESG
25492 + select GRKERNSEC_RANDNET
25493 + select GRKERNSEC_FORKFAIL
25494 + select GRKERNSEC_TIME
25495 + select GRKERNSEC_SIGNAL
25496 + select GRKERNSEC_CHROOT
25497 + select GRKERNSEC_CHROOT_UNIX
25498 + select GRKERNSEC_CHROOT_MOUNT
25499 + select GRKERNSEC_CHROOT_PIVOT
25500 + select GRKERNSEC_CHROOT_DOUBLE
25501 + select GRKERNSEC_CHROOT_CHDIR
25502 + select GRKERNSEC_CHROOT_MKNOD
25503 + select GRKERNSEC_PROC
25504 + select GRKERNSEC_PROC_USERGROUP
25505 + select GRKERNSEC_MODSTOP if (MODULES)
25506 + select PAX_RANDUSTACK
25508 + select PAX_RANDMMAP
25509 + select PAX_REFCOUNT if (X86)
25512 + If you say Y here, several features in addition to those included
25513 + in the low additional security level will be enabled. These
25514 + features provide even more security to your system, though in rare
25515 + cases they may be incompatible with very old or poorly written
25516 + software. If you enable this option, make sure that your auth
25517 + service (identd) is running as gid 1001. With this option,
25518 + the following features (in addition to those provided in the
25519 + low additional security level) will be enabled:
25521 + - Failed fork logging
25522 + - Time change logging
25524 + - Deny mounts in chroot
25525 + - Deny double chrooting
25526 + - Deny sysctl writes in chroot
25527 + - Deny mknod in chroot
25528 + - Deny access to abstract AF_UNIX sockets out of chroot
25529 + - Deny pivot_root in chroot
25530 + - Denied writes of /dev/kmem, /dev/mem, and /dev/port
25531 + - /proc restrictions with special GID set to 10 (usually wheel)
25532 + - Address Space Layout Randomization (ASLR)
25534 +config GRKERNSEC_HIGH
25536 + select GRKERNSEC_LINK
25537 + select GRKERNSEC_FIFO
25538 + select GRKERNSEC_EXECVE
25539 + select GRKERNSEC_DMESG
25540 + select GRKERNSEC_FORKFAIL
25541 + select GRKERNSEC_TIME
25542 + select GRKERNSEC_SIGNAL
25543 + select GRKERNSEC_CHROOT_SHMAT
25544 + select GRKERNSEC_CHROOT_UNIX
25545 + select GRKERNSEC_CHROOT_MOUNT
25546 + select GRKERNSEC_CHROOT_FCHDIR
25547 + select GRKERNSEC_CHROOT_PIVOT
25548 + select GRKERNSEC_CHROOT_DOUBLE
25549 + select GRKERNSEC_CHROOT_CHDIR
25550 + select GRKERNSEC_CHROOT_MKNOD
25551 + select GRKERNSEC_CHROOT_CAPS
25552 + select GRKERNSEC_CHROOT_SYSCTL
25553 + select GRKERNSEC_CHROOT_FINDTASK
25554 + select GRKERNSEC_PROC
25555 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
25556 + select GRKERNSEC_HIDESYM
25557 + select GRKERNSEC_BRUTE
25558 + select GRKERNSEC_PROC_USERGROUP
25559 + select GRKERNSEC_KMEM
25560 + select GRKERNSEC_RESLOG
25561 + select GRKERNSEC_RANDNET
25562 + select GRKERNSEC_PROC_ADD
25563 + select GRKERNSEC_CHROOT_CHMOD
25564 + select GRKERNSEC_CHROOT_NICE
25565 + select GRKERNSEC_AUDIT_MOUNT
25566 + select GRKERNSEC_MODSTOP if (MODULES)
25568 + select PAX_RANDUSTACK
25570 + select PAX_RANDMMAP
25571 + select PAX_NOEXEC
25572 + select PAX_MPROTECT
25573 + select PAX_EI_PAX
25574 + select PAX_PT_PAX_FLAGS
25575 + select PAX_HAVE_ACL_FLAGS
25576 + select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
25577 + select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
25578 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
25579 + select PAX_SEGMEXEC if (X86 && !X86_64)
25580 + select PAX_PAGEEXEC if (!X86)
25581 + select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
25582 + select PAX_DLRESOLVE if (SPARC32 || SPARC64)
25583 + select PAX_SYSCALL if (PPC32)
25584 + select PAX_EMUTRAMP if (PARISC)
25585 + select PAX_EMUSIGRT if (PARISC)
25586 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
25587 + select PAX_REFCOUNT if (X86)
25589 + If you say Y here, many of the features of grsecurity will be
25590 + enabled, which will protect you against many kinds of attacks
25591 + against your system. The heightened security comes at a cost
25592 + of an increased chance of incompatibilities with rare software
25593 + on your machine. Since this security level enables PaX, you should
25594 + view <http://pax.grsecurity.net> and read about the PaX
25595 + project. While you are there, download chpax and run it on
25596 + binaries that cause problems with PaX. Also remember that
25597 + since the /proc restrictions are enabled, you must run your
25598 + identd as gid 1001. This security level enables the following
25599 + features in addition to those listed in the low and medium
25602 + - Additional /proc restrictions
25603 + - Chmod restrictions in chroot
25604 + - No signals, ptrace, or viewing of processes outside of chroot
25605 + - Capability restrictions in chroot
25606 + - Deny fchdir out of chroot
25607 + - Priority restrictions in chroot
25608 + - Segmentation-based implementation of PaX
25609 + - Mprotect restrictions
25610 + - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
25611 + - Kernel stack randomization
25612 + - Mount/unmount/remount logging
25613 + - Kernel symbol hiding
25614 + - Prevention of memory exhaustion-based exploits
25615 +config GRKERNSEC_CUSTOM
25618 + If you say Y here, you will be able to configure every grsecurity
25619 + option, which allows you to enable many more features that aren't
25620 + covered in the basic security levels. These additional features
25621 + include TPE, socket restrictions, and the sysctl system for
25622 + grsecurity. It is advised that you read through the help for
25623 + each option to determine its usefulness in your situation.
25627 +menu "Address Space Protection"
25628 +depends on GRKERNSEC
25630 +config GRKERNSEC_KMEM
25631 + bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
25633 + If you say Y here, /dev/kmem and /dev/mem won't be allowed to
25634 + be written to via mmap or otherwise to modify the running kernel.
25635 + /dev/port will also not be allowed to be opened. If you have module
25636 + support disabled, enabling this will close up four ways that are
25637 + currently used to insert malicious code into the running kernel.
25638 + Even with all these features enabled, we still highly recommend that
25639 + you use the RBAC system, as it is still possible for an attacker to
25640 + modify the running kernel through privileged I/O granted by ioperm/iopl.
25641 + If you are not using XFree86, you may be able to stop this additional
25642 + case by enabling the 'Disable privileged I/O' option. Though nothing
25643 + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
25644 + but only to video memory, which is the only writing we allow in this
25645 + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
25646 + not be allowed to mprotect it with PROT_WRITE later.
25647 + It is highly recommended that you say Y here if you meet all the
25648 + conditions above.
25650 +config GRKERNSEC_IO
25651 + bool "Disable privileged I/O"
25655 + If you say Y here, all ioperm and iopl calls will return an error.
25656 + Ioperm and iopl can be used to modify the running kernel.
25657 + Unfortunately, some programs need this access to operate properly,
25658 + the most notable of which are XFree86 and hwclock. hwclock can be
25659 + remedied by having RTC support in the kernel, so CONFIG_RTC is
25660 + enabled if this option is enabled, to ensure that hwclock operates
25661 + correctly. XFree86 still will not operate correctly with this option
25662 + enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
25663 + and you still want to protect your kernel against modification,
25664 + use the RBAC system.
25666 +config GRKERNSEC_PROC_MEMMAP
25667 + bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
25668 + depends on PAX_NOEXEC || PAX_ASLR
25670 + If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
25671 + give no information about the addresses of its mappings if
25672 + PaX features that rely on random addresses are enabled on the task.
25673 + If you use PaX it is greatly recommended that you say Y here as it
25674 + closes up a hole that makes the full ASLR useless for suid
25677 +config GRKERNSEC_BRUTE
25678 + bool "Deter exploit bruteforcing"
25680 + If you say Y here, attempts to bruteforce exploits against forking
25681 + daemons such as apache or sshd will be deterred. When a child of a
25682 + forking daemon is killed by PaX or crashes due to an illegal
25683 + instruction, the parent process will be delayed 30 seconds upon every
25684 + subsequent fork until the administrator is able to assess the
25685 + situation and restart the daemon. It is recommended that you also
25686 + enable signal logging in the auditing section so that logs are
25687 + generated when a process performs an illegal instruction.
25689 +config GRKERNSEC_MODSTOP
25690 + bool "Runtime module disabling"
25691 + depends on MODULES
25693 + If you say Y here, you will be able to disable the ability to (un)load
25694 + modules at runtime. This feature is useful if you need the ability
25695 + to load kernel modules at boot time, but do not want to allow an
25696 + attacker to load a rootkit kernel module into the system, or to remove
25697 + a loaded kernel module important to system functioning. You should
25698 + enable the /dev/mem protection feature as well, since rootkits can be
25699 + inserted into the kernel via other methods than kernel modules. Since
25700 + an untrusted module could still be loaded by modifying init scripts and
25701 + rebooting the system, it is also recommended that you enable the RBAC
25702 + system. If you enable this option, a sysctl option with name
25703 + "disable_modules" will be created. Setting this option to "1" disables
25704 + module loading. After this option is set, no further writes to it are
25705 + allowed until the system is rebooted.
25707 +config GRKERNSEC_HIDESYM
25708 + bool "Hide kernel symbols"
25710 + If you say Y here, getting information on loaded modules, and
25711 + displaying all kernel symbols through a syscall will be restricted
25712 + to users with CAP_SYS_MODULE. This option is only effective
25713 + provided the following conditions are met:
25714 + 1) The kernel using grsecurity is not precompiled by some distribution
25715 + 2) You are using the RBAC system and hiding other files such as your
25716 + kernel image and System.map
25717 + 3) You have the additional /proc restrictions enabled, which removes
25719 + If the above conditions are met, this option will aid to provide a
25720 + useful protection against local and remote kernel exploitation of
25721 + overflows and arbitrary read/write vulnerabilities.
25724 +menu "Role Based Access Control Options"
25725 +depends on GRKERNSEC
25727 +config GRKERNSEC_ACL_HIDEKERN
25728 + bool "Hide kernel processes"
25730 + If you say Y here, all kernel threads will be hidden to all
25731 + processes but those whose subject has the "view hidden processes"
25734 +config GRKERNSEC_ACL_MAXTRIES
25735 + int "Maximum tries before password lockout"
25738 + This option enforces the maximum number of times a user can attempt
25739 + to authorize themselves with the grsecurity RBAC system before being
25740 + denied the ability to attempt authorization again for a specified time.
25741 + The lower the number, the harder it will be to brute-force a password.
25743 +config GRKERNSEC_ACL_TIMEOUT
25744 + int "Time to wait after max password tries, in seconds"
25747 + This option specifies the time the user must wait after attempting to
25748 + authorize to the RBAC system with the maximum number of invalid
25749 + passwords. The higher the number, the harder it will be to brute-force
25753 +menu "Filesystem Protections"
25754 +depends on GRKERNSEC
25756 +config GRKERNSEC_PROC
25757 + bool "Proc restrictions"
25759 + If you say Y here, the permissions of the /proc filesystem
25760 + will be altered to enhance system security and privacy. You MUST
25761 + choose either a user only restriction or a user and group restriction.
25762 + Depending upon the option you choose, you can either restrict users to
25763 + see only the processes they themselves run, or choose a group that can
25764 + view all processes and files normally restricted to root if you choose
25765 + the "restrict to user only" option. NOTE: If you're running identd as
25766 + a non-root user, you will have to run it as the group you specify here.
25768 +config GRKERNSEC_PROC_USER
25769 + bool "Restrict /proc to user only"
25770 + depends on GRKERNSEC_PROC
25772 + If you say Y here, non-root users will only be able to view their own
25773 + processes, and restricts them from viewing network-related information,
25774 + and viewing kernel symbol and module information.
25776 +config GRKERNSEC_PROC_USERGROUP
25777 + bool "Allow special group"
25778 + depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
25780 + If you say Y here, you will be able to select a group that will be
25781 + able to view all processes, network-related information, and
25782 + kernel and symbol information. This option is useful if you want
25783 + to run identd as a non-root user.
25785 +config GRKERNSEC_PROC_GID
25786 + int "GID for special group"
25787 + depends on GRKERNSEC_PROC_USERGROUP
25790 +config GRKERNSEC_PROC_ADD
25791 + bool "Additional restrictions"
25792 + depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
25794 + If you say Y here, additional restrictions will be placed on
25795 + /proc that keep normal users from viewing device information and
25796 + slabinfo information that could be useful for exploits.
25798 +config GRKERNSEC_LINK
25799 + bool "Linking restrictions"
25801 + If you say Y here, /tmp race exploits will be prevented, since users
25802 + will no longer be able to follow symlinks owned by other users in
25803 + world-writable +t directories (i.e. /tmp), unless the owner of the
25804 + symlink is the owner of the directory. users will also not be
25805 + able to hardlink to files they do not own. If the sysctl option is
25806 + enabled, a sysctl option with name "linking_restrictions" is created.
25808 +config GRKERNSEC_FIFO
25809 + bool "FIFO restrictions"
25811 + If you say Y here, users will not be able to write to FIFOs they don't
25812 + own in world-writable +t directories (i.e. /tmp), unless the owner of
25813 + the FIFO is the same owner of the directory it's held in. If the sysctl
25814 + option is enabled, a sysctl option with name "fifo_restrictions" is
25817 +config GRKERNSEC_CHROOT
25818 + bool "Chroot jail restrictions"
25820 + If you say Y here, you will be able to choose several options that will
25821 + make breaking out of a chrooted jail much more difficult. If you
25822 + encounter no software incompatibilities with the following options, it
25823 + is recommended that you enable each one.
25825 +config GRKERNSEC_CHROOT_MOUNT
25826 + bool "Deny mounts"
25827 + depends on GRKERNSEC_CHROOT
25829 + If you say Y here, processes inside a chroot will not be able to
25830 + mount or remount filesystems. If the sysctl option is enabled, a
25831 + sysctl option with name "chroot_deny_mount" is created.
25833 +config GRKERNSEC_CHROOT_DOUBLE
25834 + bool "Deny double-chroots"
25835 + depends on GRKERNSEC_CHROOT
25837 + If you say Y here, processes inside a chroot will not be able to chroot
25838 + again outside the chroot. This is a widely used method of breaking
25839 + out of a chroot jail and should not be allowed. If the sysctl
25840 + option is enabled, a sysctl option with name
25841 + "chroot_deny_chroot" is created.
25843 +config GRKERNSEC_CHROOT_PIVOT
25844 + bool "Deny pivot_root in chroot"
25845 + depends on GRKERNSEC_CHROOT
25847 + If you say Y here, processes inside a chroot will not be able to use
25848 + a function called pivot_root() that was introduced in Linux 2.3.41. It
25849 + works similar to chroot in that it changes the root filesystem. This
25850 + function could be misused in a chrooted process to attempt to break out
25851 + of the chroot, and therefore should not be allowed. If the sysctl
25852 + option is enabled, a sysctl option with name "chroot_deny_pivot" is
25855 +config GRKERNSEC_CHROOT_CHDIR
25856 + bool "Enforce chdir(\"/\") on all chroots"
25857 + depends on GRKERNSEC_CHROOT
25859 + If you say Y here, the current working directory of all newly-chrooted
25860 + applications will be set to the the root directory of the chroot.
25861 + The man page on chroot(2) states:
25862 + Note that this call does not change the current working
25863 + directory, so that `.' can be outside the tree rooted at
25864 + `/'. In particular, the super-user can escape from a
25865 + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
25867 + It is recommended that you say Y here, since it's not known to break
25868 + any software. If the sysctl option is enabled, a sysctl option with
25869 + name "chroot_enforce_chdir" is created.
25871 +config GRKERNSEC_CHROOT_CHMOD
25872 + bool "Deny (f)chmod +s"
25873 + depends on GRKERNSEC_CHROOT
25875 + If you say Y here, processes inside a chroot will not be able to chmod
25876 + or fchmod files to make them have suid or sgid bits. This protects
25877 + against another published method of breaking a chroot. If the sysctl
25878 + option is enabled, a sysctl option with name "chroot_deny_chmod" is
25881 +config GRKERNSEC_CHROOT_FCHDIR
25882 + bool "Deny fchdir out of chroot"
25883 + depends on GRKERNSEC_CHROOT
25885 + If you say Y here, a well-known method of breaking chroots by fchdir'ing
25886 + to a file descriptor of the chrooting process that points to a directory
25887 + outside the filesystem will be stopped. If the sysctl option
25888 + is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
25890 +config GRKERNSEC_CHROOT_MKNOD
25891 + bool "Deny mknod"
25892 + depends on GRKERNSEC_CHROOT
25894 + If you say Y here, processes inside a chroot will not be allowed to
25895 + mknod. The problem with using mknod inside a chroot is that it
25896 + would allow an attacker to create a device entry that is the same
25897 + as one on the physical root of your system, which could range from
25898 + anything from the console device to a device for your harddrive (which
25899 + they could then use to wipe the drive or steal data). It is recommended
25900 + that you say Y here, unless you run into software incompatibilities.
25901 + If the sysctl option is enabled, a sysctl option with name
25902 + "chroot_deny_mknod" is created.
25904 +config GRKERNSEC_CHROOT_SHMAT
25905 + bool "Deny shmat() out of chroot"
25906 + depends on GRKERNSEC_CHROOT
25908 + If you say Y here, processes inside a chroot will not be able to attach
25909 + to shared memory segments that were created outside of the chroot jail.
25910 + It is recommended that you say Y here. If the sysctl option is enabled,
25911 + a sysctl option with name "chroot_deny_shmat" is created.
25913 +config GRKERNSEC_CHROOT_UNIX
25914 + bool "Deny access to abstract AF_UNIX sockets out of chroot"
25915 + depends on GRKERNSEC_CHROOT
25917 + If you say Y here, processes inside a chroot will not be able to
25918 + connect to abstract (meaning not belonging to a filesystem) Unix
25919 + domain sockets that were bound outside of a chroot. It is recommended
25920 + that you say Y here. If the sysctl option is enabled, a sysctl option
25921 + with name "chroot_deny_unix" is created.
25923 +config GRKERNSEC_CHROOT_FINDTASK
25924 + bool "Protect outside processes"
25925 + depends on GRKERNSEC_CHROOT
25927 + If you say Y here, processes inside a chroot will not be able to
25928 + kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
25929 + or view any process outside of the chroot. If the sysctl
25930 + option is enabled, a sysctl option with name "chroot_findtask" is
25933 +config GRKERNSEC_CHROOT_NICE
25934 + bool "Restrict priority changes"
25935 + depends on GRKERNSEC_CHROOT
25937 + If you say Y here, processes inside a chroot will not be able to raise
25938 + the priority of processes in the chroot, or alter the priority of
25939 + processes outside the chroot. This provides more security than simply
25940 + removing CAP_SYS_NICE from the process' capability set. If the
25941 + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
25944 +config GRKERNSEC_CHROOT_SYSCTL
25945 + bool "Deny sysctl writes"
25946 + depends on GRKERNSEC_CHROOT
25948 + If you say Y here, an attacker in a chroot will not be able to
25949 + write to sysctl entries, either by sysctl(2) or through a /proc
25950 + interface. It is strongly recommended that you say Y here. If the
25951 + sysctl option is enabled, a sysctl option with name
25952 + "chroot_deny_sysctl" is created.
25954 +config GRKERNSEC_CHROOT_CAPS
25955 + bool "Capability restrictions"
25956 + depends on GRKERNSEC_CHROOT
25958 + If you say Y here, the capabilities on all root processes within a
25959 + chroot jail will be lowered to stop module insertion, raw i/o,
25960 + system and net admin tasks, rebooting the system, modifying immutable
25961 + files, modifying IPC owned by another, and changing the system time.
25962 + This is left an option because it can break some apps. Disable this
25963 + if your chrooted apps are having problems performing those kinds of
25964 + tasks. If the sysctl option is enabled, a sysctl option with
25965 + name "chroot_caps" is created.
25968 +menu "Kernel Auditing"
25969 +depends on GRKERNSEC
25971 +config GRKERNSEC_AUDIT_GROUP
25972 + bool "Single group for auditing"
25974 + If you say Y here, the exec, chdir, (un)mount, and ipc logging features
25975 + will only operate on a group you specify. This option is recommended
25976 + if you only want to watch certain users instead of having a large
25977 + amount of logs from the entire system. If the sysctl option is enabled,
25978 + a sysctl option with name "audit_group" is created.
25980 +config GRKERNSEC_AUDIT_GID
25981 + int "GID for auditing"
25982 + depends on GRKERNSEC_AUDIT_GROUP
25985 +config GRKERNSEC_EXECLOG
25986 + bool "Exec logging"
25988 + If you say Y here, all execve() calls will be logged (since the
25989 + other exec*() calls are frontends to execve(), all execution
25990 + will be logged). Useful for shell-servers that like to keep track
25991 + of their users. If the sysctl option is enabled, a sysctl option with
25992 + name "exec_logging" is created.
25993 + WARNING: This option when enabled will produce a LOT of logs, especially
25994 + on an active system.
25996 +config GRKERNSEC_RESLOG
25997 + bool "Resource logging"
25999 + If you say Y here, all attempts to overstep resource limits will
26000 + be logged with the resource name, the requested size, and the current
26001 + limit. It is highly recommended that you say Y here. If the sysctl
26002 + option is enabled, a sysctl option with name "resource_logging" is
26003 + created. If the RBAC system is enabled, the sysctl value is ignored.
26005 +config GRKERNSEC_CHROOT_EXECLOG
26006 + bool "Log execs within chroot"
26008 + If you say Y here, all executions inside a chroot jail will be logged
26009 + to syslog. This can cause a large amount of logs if certain
26010 + applications (eg. djb's daemontools) are installed on the system, and
26011 + is therefore left as an option. If the sysctl option is enabled, a
26012 + sysctl option with name "chroot_execlog" is created.
26014 +config GRKERNSEC_AUDIT_CHDIR
26015 + bool "Chdir logging"
26017 + If you say Y here, all chdir() calls will be logged. If the sysctl
26018 + option is enabled, a sysctl option with name "audit_chdir" is created.
26020 +config GRKERNSEC_AUDIT_MOUNT
26021 + bool "(Un)Mount logging"
26023 + If you say Y here, all mounts and unmounts will be logged. If the
26024 + sysctl option is enabled, a sysctl option with name "audit_mount" is
26027 +config GRKERNSEC_AUDIT_IPC
26028 + bool "IPC logging"
26030 + If you say Y here, creation and removal of message queues, semaphores,
26031 + and shared memory will be logged. If the sysctl option is enabled, a
26032 + sysctl option with name "audit_ipc" is created.
26034 +config GRKERNSEC_SIGNAL
26035 + bool "Signal logging"
26037 + If you say Y here, certain important signals will be logged, such as
26038 + SIGSEGV, which will as a result inform you of when a error in a program
26039 + occurred, which in some cases could mean a possible exploit attempt.
26040 + If the sysctl option is enabled, a sysctl option with name
26041 + "signal_logging" is created.
26043 +config GRKERNSEC_FORKFAIL
26044 + bool "Fork failure logging"
26046 + If you say Y here, all failed fork() attempts will be logged.
26047 + This could suggest a fork bomb, or someone attempting to overstep
26048 + their process limit. If the sysctl option is enabled, a sysctl option
26049 + with name "forkfail_logging" is created.
26051 +config GRKERNSEC_TIME
26052 + bool "Time change logging"
26054 + If you say Y here, any changes of the system clock will be logged.
26055 + If the sysctl option is enabled, a sysctl option with name
26056 + "timechange_logging" is created.
26058 +config GRKERNSEC_PROC_IPADDR
26059 + bool "/proc/<pid>/ipaddr support"
26061 + If you say Y here, a new entry will be added to each /proc/<pid>
26062 + directory that contains the IP address of the person using the task.
26063 + The IP is carried across local TCP and AF_UNIX stream sockets.
26064 + This information can be useful for IDS/IPSes to perform remote response
26065 + to a local attack. The entry is readable by only the owner of the
26066 + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
26067 + the RBAC system), and thus does not create privacy concerns.
26069 +config GRKERNSEC_AUDIT_TEXTREL
26070 + bool 'ELF text relocations logging (READ HELP)'
26071 + depends on PAX_MPROTECT
26073 + If you say Y here, text relocations will be logged with the filename
26074 + of the offending library or binary. The purpose of the feature is
26075 + to help Linux distribution developers get rid of libraries and
26076 + binaries that need text relocations which hinder the future progress
26077 + of PaX. Only Linux distribution developers should say Y here, and
26078 + never on a production machine, as this option creates an information
26079 + leak that could aid an attacker in defeating the randomization of
26080 + a single memory region. If the sysctl option is enabled, a sysctl
26081 + option with name "audit_textrel" is created.
26085 +menu "Executable Protections"
26086 +depends on GRKERNSEC
26088 +config GRKERNSEC_EXECVE
26089 + bool "Enforce RLIMIT_NPROC on execs"
26091 + If you say Y here, users with a resource limit on processes will
26092 + have the value checked during execve() calls. The current system
26093 + only checks the system limit during fork() calls. If the sysctl option
26094 + is enabled, a sysctl option with name "execve_limiting" is created.
26096 +config GRKERNSEC_DMESG
26097 + bool "Dmesg(8) restriction"
26099 + If you say Y here, non-root users will not be able to use dmesg(8)
26100 + to view up to the last 4kb of messages in the kernel's log buffer.
26101 + If the sysctl option is enabled, a sysctl option with name "dmesg" is
26104 +config GRKERNSEC_TPE
26105 + bool "Trusted Path Execution (TPE)"
26107 + If you say Y here, you will be able to choose a gid to add to the
26108 + supplementary groups of users you want to mark as "untrusted."
26109 + These users will not be able to execute any files that are not in
26110 + root-owned directories writable only by root. If the sysctl option
26111 + is enabled, a sysctl option with name "tpe" is created.
26113 +config GRKERNSEC_TPE_ALL
26114 + bool "Partially restrict non-root users"
26115 + depends on GRKERNSEC_TPE
26117 + If you say Y here, All non-root users other than the ones in the
26118 + group specified in the main TPE option will only be allowed to
26119 + execute files in directories they own that are not group or
26120 + world-writable, or in directories owned by root and writable only by
26121 + root. If the sysctl option is enabled, a sysctl option with name
26122 + "tpe_restrict_all" is created.
26124 +config GRKERNSEC_TPE_INVERT
26125 + bool "Invert GID option"
26126 + depends on GRKERNSEC_TPE
26128 + If you say Y here, the group you specify in the TPE configuration will
26129 + decide what group TPE restrictions will be *disabled* for. This
26130 + option is useful if you want TPE restrictions to be applied to most
26131 + users on the system.
26133 +config GRKERNSEC_TPE_GID
26134 + int "GID for untrusted users"
26135 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
26138 + If you have selected the "Invert GID option" above, setting this
26139 + GID determines what group TPE restrictions will be *disabled* for.
26140 + If you have not selected the "Invert GID option" above, setting this
26141 + GID determines what group TPE restrictions will be *enabled* for.
26142 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
26145 +config GRKERNSEC_TPE_GID
26146 + int "GID for trusted users"
26147 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
26150 + If you have selected the "Invert GID option" above, setting this
26151 + GID determines what group TPE restrictions will be *disabled* for.
26152 + If you have not selected the "Invert GID option" above, setting this
26153 + GID determines what group TPE restrictions will be *enabled* for.
26154 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
26158 +menu "Network Protections"
26159 +depends on GRKERNSEC
26161 +config GRKERNSEC_RANDNET
26162 + bool "Larger entropy pools"
26164 + If you say Y here, the entropy pools used for many features of Linux
26165 + and grsecurity will be doubled in size. Since several grsecurity
26166 + features use additional randomness, it is recommended that you say Y
26167 + here. Saying Y here has a similar effect as modifying
26168 + /proc/sys/kernel/random/poolsize.
26170 +config GRKERNSEC_SOCKET
26171 + bool "Socket restrictions"
26173 + If you say Y here, you will be able to choose from several options.
26174 + If you assign a GID on your system and add it to the supplementary
26175 + groups of users you want to restrict socket access to, this patch
26176 + will perform up to three things, based on the option(s) you choose.
26178 +config GRKERNSEC_SOCKET_ALL
26179 + bool "Deny any sockets to group"
26180 + depends on GRKERNSEC_SOCKET
26182 + If you say Y here, you will be able to choose a GID of whose users will
26183 + be unable to connect to other hosts from your machine or run server
26184 + applications from your machine. If the sysctl option is enabled, a
26185 + sysctl option with name "socket_all" is created.
26187 +config GRKERNSEC_SOCKET_ALL_GID
26188 + int "GID to deny all sockets for"
26189 + depends on GRKERNSEC_SOCKET_ALL
26192 + Here you can choose the GID to disable socket access for. Remember to
26193 + add the users you want socket access disabled for to the GID
26194 + specified here. If the sysctl option is enabled, a sysctl option
26195 + with name "socket_all_gid" is created.
26197 +config GRKERNSEC_SOCKET_CLIENT
26198 + bool "Deny client sockets to group"
26199 + depends on GRKERNSEC_SOCKET
26201 + If you say Y here, you will be able to choose a GID of whose users will
26202 + be unable to connect to other hosts from your machine, but will be
26203 + able to run servers. If this option is enabled, all users in the group
26204 + you specify will have to use passive mode when initiating ftp transfers
26205 + from the shell on your machine. If the sysctl option is enabled, a
26206 + sysctl option with name "socket_client" is created.
26208 +config GRKERNSEC_SOCKET_CLIENT_GID
26209 + int "GID to deny client sockets for"
26210 + depends on GRKERNSEC_SOCKET_CLIENT
26213 + Here you can choose the GID to disable client socket access for.
26214 + Remember to add the users you want client socket access disabled for to
26215 + the GID specified here. If the sysctl option is enabled, a sysctl
26216 + option with name "socket_client_gid" is created.
26218 +config GRKERNSEC_SOCKET_SERVER
26219 + bool "Deny server sockets to group"
26220 + depends on GRKERNSEC_SOCKET
26222 + If you say Y here, you will be able to choose a GID of whose users will
26223 + be unable to run server applications from your machine. If the sysctl
26224 + option is enabled, a sysctl option with name "socket_server" is created.
26226 +config GRKERNSEC_SOCKET_SERVER_GID
26227 + int "GID to deny server sockets for"
26228 + depends on GRKERNSEC_SOCKET_SERVER
26231 + Here you can choose the GID to disable server socket access for.
26232 + Remember to add the users you want server socket access disabled for to
26233 + the GID specified here. If the sysctl option is enabled, a sysctl
26234 + option with name "socket_server_gid" is created.
26237 +menu "Sysctl support"
26238 +depends on GRKERNSEC && SYSCTL
26240 +config GRKERNSEC_SYSCTL
26241 + bool "Sysctl support"
26243 + If you say Y here, you will be able to change the options that
26244 + grsecurity runs with at bootup, without having to recompile your
26245 + kernel. You can echo values to files in /proc/sys/kernel/grsecurity
26246 + to enable (1) or disable (0) various features. All the sysctl entries
26247 + are mutable until the "grsec_lock" entry is set to a non-zero value.
26248 + All features enabled in the kernel configuration are disabled at boot
26249 + if you do not say Y to the "Turn on features by default" option.
26250 + All options should be set at startup, and the grsec_lock entry should
26251 + be set to a non-zero value after all the options are set.
26252 + *THIS IS EXTREMELY IMPORTANT*
26254 +config GRKERNSEC_SYSCTL_ON
26255 + bool "Turn on features by default"
26256 + depends on GRKERNSEC_SYSCTL
26258 + If you say Y here, instead of having all features enabled in the
26259 + kernel configuration disabled at boot time, the features will be
26260 + enabled at boot time. It is recommended you say Y here unless
26261 + there is some reason you would want all sysctl-tunable features to
26262 + be disabled by default. As mentioned elsewhere, it is important
26263 + to enable the grsec_lock entry once you have finished modifying
26264 + the sysctl entries.
26267 +menu "Logging Options"
26268 +depends on GRKERNSEC
26270 +config GRKERNSEC_FLOODTIME
26271 + int "Seconds in between log messages (minimum)"
26274 + This option allows you to enforce the number of seconds between
26275 + grsecurity log messages. The default should be suitable for most
26276 + people, however, if you choose to change it, choose a value small enough
26277 + to allow informative logs to be produced, but large enough to
26278 + prevent flooding.
26280 +config GRKERNSEC_FLOODBURST
26281 + int "Number of messages in a burst (maximum)"
26284 + This option allows you to choose the maximum number of messages allowed
26285 + within the flood time interval you chose in a separate option. The
26286 + default should be suitable for most people, however if you find that
26287 + many of your logs are being interpreted as flooding, you may want to
26288 + raise this value.
26293 diff -urNp linux-2.6.27.10/grsecurity/Makefile linux-2.6.27.10/grsecurity/Makefile
26294 --- linux-2.6.27.10/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
26295 +++ linux-2.6.27.10/grsecurity/Makefile 2008-11-18 03:38:45.000000000 -0500
26297 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
26298 +# during 2001-2005 it has been completely redesigned by Brad Spengler
26299 +# into an RBAC system
26301 +# All code in this directory and various hooks inserted throughout the kernel
26302 +# are copyright Brad Spengler, and released under the GPL v2 or higher
26304 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
26305 + grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
26306 + grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
26308 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
26309 + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
26310 + gracl_learn.o grsec_log.o
26311 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
26313 +ifndef CONFIG_GRKERNSEC
26314 +obj-y += grsec_disabled.o
26317 diff -urNp linux-2.6.27.10/include/asm-cris/kmap_types.h linux-2.6.27.10/include/asm-cris/kmap_types.h
26318 --- linux-2.6.27.10/include/asm-cris/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26319 +++ linux-2.6.27.10/include/asm-cris/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26320 @@ -19,6 +19,7 @@ enum km_type {
26328 diff -urNp linux-2.6.27.10/include/asm-frv/kmap_types.h linux-2.6.27.10/include/asm-frv/kmap_types.h
26329 --- linux-2.6.27.10/include/asm-frv/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26330 +++ linux-2.6.27.10/include/asm-frv/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26331 @@ -23,6 +23,7 @@ enum km_type {
26339 diff -urNp linux-2.6.27.10/include/asm-generic/futex.h linux-2.6.27.10/include/asm-generic/futex.h
26340 --- linux-2.6.27.10/include/asm-generic/futex.h 2008-11-07 12:55:34.000000000 -0500
26341 +++ linux-2.6.27.10/include/asm-generic/futex.h 2008-11-18 03:38:45.000000000 -0500
26343 #include <asm/errno.h>
26346 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
26347 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
26349 int op = (encoded_op >> 28) & 7;
26350 int cmp = (encoded_op >> 24) & 15;
26351 @@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
26355 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
26356 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
26360 diff -urNp linux-2.6.27.10/include/asm-generic/vmlinux.lds.h linux-2.6.27.10/include/asm-generic/vmlinux.lds.h
26361 --- linux-2.6.27.10/include/asm-generic/vmlinux.lds.h 2008-11-07 12:55:34.000000000 -0500
26362 +++ linux-2.6.27.10/include/asm-generic/vmlinux.lds.h 2008-11-18 03:38:45.000000000 -0500
26364 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
26365 VMLINUX_SYMBOL(__start_rodata) = .; \
26366 *(.rodata) *(.rodata.*) \
26367 + *(.data.read_only) \
26368 *(__vermagic) /* Kernel version magic */ \
26369 *(__markers_strings) /* Markers: strings */ \
26371 diff -urNp linux-2.6.27.10/include/asm-m32r/kmap_types.h linux-2.6.27.10/include/asm-m32r/kmap_types.h
26372 --- linux-2.6.27.10/include/asm-m32r/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26373 +++ linux-2.6.27.10/include/asm-m32r/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26374 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
26379 +D(13) KM_CLEARPAGE,
26384 diff -urNp linux-2.6.27.10/include/asm-m68k/kmap_types.h linux-2.6.27.10/include/asm-m68k/kmap_types.h
26385 --- linux-2.6.27.10/include/asm-m68k/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26386 +++ linux-2.6.27.10/include/asm-m68k/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26387 @@ -15,6 +15,7 @@ enum km_type {
26395 diff -urNp linux-2.6.27.10/include/asm-mips/elf.h linux-2.6.27.10/include/asm-mips/elf.h
26396 --- linux-2.6.27.10/include/asm-mips/elf.h 2008-11-07 12:55:34.000000000 -0500
26397 +++ linux-2.6.27.10/include/asm-mips/elf.h 2008-11-18 03:38:45.000000000 -0500
26398 @@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
26399 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
26402 +#ifdef CONFIG_PAX_ASLR
26403 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
26405 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26406 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26409 #endif /* _ASM_ELF_H */
26410 diff -urNp linux-2.6.27.10/include/asm-mips/kmap_types.h linux-2.6.27.10/include/asm-mips/kmap_types.h
26411 --- linux-2.6.27.10/include/asm-mips/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26412 +++ linux-2.6.27.10/include/asm-mips/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26413 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26418 +D(13) KM_CLEARPAGE,
26423 diff -urNp linux-2.6.27.10/include/asm-mips/page.h linux-2.6.27.10/include/asm-mips/page.h
26424 --- linux-2.6.27.10/include/asm-mips/page.h 2008-11-07 12:55:34.000000000 -0500
26425 +++ linux-2.6.27.10/include/asm-mips/page.h 2008-11-18 03:38:45.000000000 -0500
26426 @@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
26427 #ifdef CONFIG_CPU_MIPS32
26428 typedef struct { unsigned long pte_low, pte_high; } pte_t;
26429 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
26430 - #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
26431 + #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
26433 typedef struct { unsigned long long pte; } pte_t;
26434 #define pte_val(x) ((x).pte)
26435 diff -urNp linux-2.6.27.10/include/asm-mips/system.h linux-2.6.27.10/include/asm-mips/system.h
26436 --- linux-2.6.27.10/include/asm-mips/system.h 2008-11-07 12:55:34.000000000 -0500
26437 +++ linux-2.6.27.10/include/asm-mips/system.h 2008-11-18 03:38:45.000000000 -0500
26438 @@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
26440 #define __ARCH_WANT_UNLOCKED_CTXSW
26442 -extern unsigned long arch_align_stack(unsigned long sp);
26443 +#define arch_align_stack(x) ((x) & ALMASK)
26445 #endif /* _ASM_SYSTEM_H */
26446 diff -urNp linux-2.6.27.10/include/asm-mn10300/kmap_types.h linux-2.6.27.10/include/asm-mn10300/kmap_types.h
26447 --- linux-2.6.27.10/include/asm-mn10300/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26448 +++ linux-2.6.27.10/include/asm-mn10300/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
26449 @@ -25,6 +25,7 @@ enum km_type {
26457 diff -urNp linux-2.6.27.10/include/asm-parisc/elf.h linux-2.6.27.10/include/asm-parisc/elf.h
26458 --- linux-2.6.27.10/include/asm-parisc/elf.h 2008-11-07 12:55:34.000000000 -0500
26459 +++ linux-2.6.27.10/include/asm-parisc/elf.h 2008-11-18 03:38:45.000000000 -0500
26460 @@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
26462 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
26464 +#ifdef CONFIG_PAX_ASLR
26465 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
26467 +#define PAX_DELTA_MMAP_LEN 16
26468 +#define PAX_DELTA_STACK_LEN 16
26471 /* This yields a mask that user programs can use to figure out what
26472 instruction set this CPU supports. This could be done in user space,
26473 but it's not easy, and we've already done it here. */
26474 diff -urNp linux-2.6.27.10/include/asm-parisc/kmap_types.h linux-2.6.27.10/include/asm-parisc/kmap_types.h
26475 --- linux-2.6.27.10/include/asm-parisc/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26476 +++ linux-2.6.27.10/include/asm-parisc/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26477 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26482 +D(13) KM_CLEARPAGE,
26487 diff -urNp linux-2.6.27.10/include/asm-parisc/pgtable.h linux-2.6.27.10/include/asm-parisc/pgtable.h
26488 --- linux-2.6.27.10/include/asm-parisc/pgtable.h 2008-11-07 12:55:34.000000000 -0500
26489 +++ linux-2.6.27.10/include/asm-parisc/pgtable.h 2008-11-18 03:38:45.000000000 -0500
26490 @@ -202,6 +202,17 @@
26491 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
26492 #define PAGE_COPY PAGE_EXECREAD
26493 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
26495 +#ifdef CONFIG_PAX_PAGEEXEC
26496 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
26497 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26498 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26500 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
26501 +# define PAGE_COPY_NOEXEC PAGE_COPY
26502 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
26505 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
26506 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
26507 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
26508 diff -urNp linux-2.6.27.10/include/asm-um/kmap_types.h linux-2.6.27.10/include/asm-um/kmap_types.h
26509 --- linux-2.6.27.10/include/asm-um/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26510 +++ linux-2.6.27.10/include/asm-um/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26511 @@ -23,6 +23,7 @@ enum km_type {
26519 diff -urNp linux-2.6.27.10/include/asm-um/page.h linux-2.6.27.10/include/asm-um/page.h
26520 --- linux-2.6.27.10/include/asm-um/page.h 2008-11-07 12:55:34.000000000 -0500
26521 +++ linux-2.6.27.10/include/asm-um/page.h 2008-11-18 03:38:45.000000000 -0500
26523 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
26524 #define PAGE_MASK (~(PAGE_SIZE-1))
26526 +#define ktla_ktva(addr) (addr)
26527 +#define ktva_ktla(addr) (addr)
26529 #ifndef __ASSEMBLY__
26532 diff -urNp linux-2.6.27.10/include/asm-x86/alternative.h linux-2.6.27.10/include/asm-x86/alternative.h
26533 --- linux-2.6.27.10/include/asm-x86/alternative.h 2008-11-07 12:55:34.000000000 -0500
26534 +++ linux-2.6.27.10/include/asm-x86/alternative.h 2008-11-18 03:38:45.000000000 -0500
26535 @@ -96,7 +96,7 @@ const unsigned char *const *find_nop_tab
26536 " .byte 662b-661b\n" /* sourcelen */ \
26537 " .byte 664f-663f\n" /* replacementlen */ \
26539 - ".section .altinstr_replacement,\"ax\"\n" \
26540 + ".section .altinstr_replacement,\"a\"\n" \
26541 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26542 ".previous" :: "i" (feature) : "memory")
26544 @@ -120,7 +120,7 @@ const unsigned char *const *find_nop_tab
26545 " .byte 662b-661b\n" /* sourcelen */ \
26546 " .byte 664f-663f\n" /* replacementlen */ \
26548 - ".section .altinstr_replacement,\"ax\"\n" \
26549 + ".section .altinstr_replacement,\"a\"\n" \
26550 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26551 ".previous" :: "i" (feature), ##input)
26553 @@ -135,7 +135,7 @@ const unsigned char *const *find_nop_tab
26554 " .byte 662b-661b\n" /* sourcelen */ \
26555 " .byte 664f-663f\n" /* replacementlen */ \
26557 - ".section .altinstr_replacement,\"ax\"\n" \
26558 + ".section .altinstr_replacement,\"a\"\n" \
26559 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26560 ".previous" : output : [feat] "i" (feature), ##input)
26562 diff -urNp linux-2.6.27.10/include/asm-x86/atomic_32.h linux-2.6.27.10/include/asm-x86/atomic_32.h
26563 --- linux-2.6.27.10/include/asm-x86/atomic_32.h 2008-11-07 12:55:34.000000000 -0500
26564 +++ linux-2.6.27.10/include/asm-x86/atomic_32.h 2008-11-18 03:38:45.000000000 -0500
26565 @@ -47,7 +47,15 @@ typedef struct {
26567 static inline void atomic_add(int i, atomic_t *v)
26569 - asm volatile(LOCK_PREFIX "addl %1,%0"
26570 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
26572 +#ifdef CONFIG_PAX_REFCOUNT
26574 + LOCK_PREFIX "subl %1,%0\n"
26576 + _ASM_EXTABLE(0b, 0b)
26579 : "+m" (v->counter)
26582 @@ -61,7 +69,15 @@ static inline void atomic_add(int i, ato
26584 static inline void atomic_sub(int i, atomic_t *v)
26586 - asm volatile(LOCK_PREFIX "subl %1,%0"
26587 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
26589 +#ifdef CONFIG_PAX_REFCOUNT
26591 + LOCK_PREFIX "addl %1,%0\n"
26593 + _ASM_EXTABLE(0b, 0b)
26596 : "+m" (v->counter)
26599 @@ -79,7 +95,16 @@ static inline int atomic_sub_and_test(in
26603 - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
26604 + asm volatile(LOCK_PREFIX "subl %2,%0\n"
26606 +#ifdef CONFIG_PAX_REFCOUNT
26608 + LOCK_PREFIX "addl %2,%0\n"
26610 + _ASM_EXTABLE(0b, 0b)
26614 : "+m" (v->counter), "=qm" (c)
26615 : "ir" (i) : "memory");
26617 @@ -93,7 +118,18 @@ static inline int atomic_sub_and_test(in
26619 static inline void atomic_inc(atomic_t *v)
26621 - asm volatile(LOCK_PREFIX "incl %0"
26622 + asm volatile(LOCK_PREFIX "incl %0\n"
26624 +#ifdef CONFIG_PAX_REFCOUNT
26626 + ".pushsection .fixup,\"ax\"\n"
26628 + LOCK_PREFIX "decl %0\n"
26631 + _ASM_EXTABLE(0b, 1b)
26634 : "+m" (v->counter));
26637 @@ -105,7 +141,18 @@ static inline void atomic_inc(atomic_t *
26639 static inline void atomic_dec(atomic_t *v)
26641 - asm volatile(LOCK_PREFIX "decl %0"
26642 + asm volatile(LOCK_PREFIX "decl %0\n"
26644 +#ifdef CONFIG_PAX_REFCOUNT
26646 + ".pushsection .fixup,\"ax\"\n"
26648 + LOCK_PREFIX "incl %0\n"
26651 + _ASM_EXTABLE(0b, 1b)
26654 : "+m" (v->counter));
26657 @@ -121,7 +168,19 @@ static inline int atomic_dec_and_test(at
26661 - asm volatile(LOCK_PREFIX "decl %0; sete %1"
26662 + asm volatile(LOCK_PREFIX "decl %0\n"
26664 +#ifdef CONFIG_PAX_REFCOUNT
26666 + ".pushsection .fixup,\"ax\"\n"
26668 + LOCK_PREFIX "incl %0\n"
26671 + _ASM_EXTABLE(0b, 1b)
26675 : "+m" (v->counter), "=qm" (c)
26678 @@ -139,7 +198,19 @@ static inline int atomic_inc_and_test(at
26682 - asm volatile(LOCK_PREFIX "incl %0; sete %1"
26683 + asm volatile(LOCK_PREFIX "incl %0\n"
26685 +#ifdef CONFIG_PAX_REFCOUNT
26687 + ".pushsection .fixup,\"ax\"\n"
26689 + LOCK_PREFIX "decl %0\n"
26692 + _ASM_EXTABLE(0b, 1b)
26696 : "+m" (v->counter), "=qm" (c)
26699 @@ -158,7 +229,16 @@ static inline int atomic_add_negative(in
26703 - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
26704 + asm volatile(LOCK_PREFIX "addl %2,%0\n"
26706 +#ifdef CONFIG_PAX_REFCOUNT
26708 + LOCK_PREFIX "subl %2,%0\n"
26710 + _ASM_EXTABLE(0b, 0b)
26714 : "+m" (v->counter), "=qm" (c)
26715 : "ir" (i) : "memory");
26717 @@ -181,7 +261,15 @@ static inline int atomic_add_return(int
26719 /* Modern 486+ processor */
26721 - asm volatile(LOCK_PREFIX "xaddl %0, %1"
26722 + asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
26724 +#ifdef CONFIG_PAX_REFCOUNT
26728 + _ASM_EXTABLE(0b, 0b)
26731 : "+r" (i), "+m" (v->counter)
26734 diff -urNp linux-2.6.27.10/include/asm-x86/atomic_64.h linux-2.6.27.10/include/asm-x86/atomic_64.h
26735 --- linux-2.6.27.10/include/asm-x86/atomic_64.h 2008-11-07 12:55:34.000000000 -0500
26736 +++ linux-2.6.27.10/include/asm-x86/atomic_64.h 2008-11-18 03:38:45.000000000 -0500
26737 @@ -48,7 +48,15 @@ typedef struct {
26739 static inline void atomic_add(int i, atomic_t *v)
26741 - asm volatile(LOCK_PREFIX "addl %1,%0"
26742 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
26744 +#ifdef CONFIG_PAX_REFCOUNT
26746 + LOCK_PREFIX "subl %1,%0\n"
26748 + _ASM_EXTABLE(0b, 0b)
26751 : "=m" (v->counter)
26752 : "ir" (i), "m" (v->counter));
26754 @@ -62,7 +70,15 @@ static inline void atomic_add(int i, ato
26756 static inline void atomic_sub(int i, atomic_t *v)
26758 - asm volatile(LOCK_PREFIX "subl %1,%0"
26759 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
26761 +#ifdef CONFIG_PAX_REFCOUNT
26763 + LOCK_PREFIX "addl %1,%0\n"
26765 + _ASM_EXTABLE(0b, 0b)
26768 : "=m" (v->counter)
26769 : "ir" (i), "m" (v->counter));
26771 @@ -80,7 +96,16 @@ static inline int atomic_sub_and_test(in
26775 - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
26776 + asm volatile(LOCK_PREFIX "subl %2,%0\n"
26778 +#ifdef CONFIG_PAX_REFCOUNT
26780 + LOCK_PREFIX "addl %2,%0\n"
26782 + _ASM_EXTABLE(0b, 0b)
26786 : "=m" (v->counter), "=qm" (c)
26787 : "ir" (i), "m" (v->counter) : "memory");
26789 @@ -94,7 +119,19 @@ static inline int atomic_sub_and_test(in
26791 static inline void atomic_inc(atomic_t *v)
26793 - asm volatile(LOCK_PREFIX "incl %0"
26794 + asm volatile(LOCK_PREFIX "incl %0\n"
26796 +#ifdef CONFIG_PAX_REFCOUNT
26799 + ".pushsection .fixup,\"ax\"\n"
26801 + LOCK_PREFIX "decl %0\n"
26804 + _ASM_EXTABLE(0b, 1b)
26807 : "=m" (v->counter)
26808 : "m" (v->counter));
26810 @@ -107,7 +144,19 @@ static inline void atomic_inc(atomic_t *
26812 static inline void atomic_dec(atomic_t *v)
26814 - asm volatile(LOCK_PREFIX "decl %0"
26815 + asm volatile(LOCK_PREFIX "decl %0\n"
26817 +#ifdef CONFIG_PAX_REFCOUNT
26820 + ".pushsection .fixup,\"ax\"\n"
26822 + LOCK_PREFIX "incl %0\n"
26825 + _ASM_EXTABLE(0b, 1b)
26828 : "=m" (v->counter)
26829 : "m" (v->counter));
26831 @@ -124,7 +173,20 @@ static inline int atomic_dec_and_test(at
26835 - asm volatile(LOCK_PREFIX "decl %0; sete %1"
26836 + asm volatile(LOCK_PREFIX "decl %0\n"
26838 +#ifdef CONFIG_PAX_REFCOUNT
26841 + ".pushsection .fixup,\"ax\"\n"
26843 + LOCK_PREFIX "incl %0\n"
26846 + _ASM_EXTABLE(0b, 1b)
26850 : "=m" (v->counter), "=qm" (c)
26851 : "m" (v->counter) : "memory");
26853 @@ -142,7 +204,20 @@ static inline int atomic_inc_and_test(at
26857 - asm volatile(LOCK_PREFIX "incl %0; sete %1"
26858 + asm volatile(LOCK_PREFIX "incl %0\n"
26860 +#ifdef CONFIG_PAX_REFCOUNT
26863 + ".pushsection .fixup,\"ax\"\n"
26865 + LOCK_PREFIX "decl %0\n"
26868 + _ASM_EXTABLE(0b, 1b)
26872 : "=m" (v->counter), "=qm" (c)
26873 : "m" (v->counter) : "memory");
26875 @@ -161,7 +236,16 @@ static inline int atomic_add_negative(in
26879 - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
26880 + asm volatile(LOCK_PREFIX "addl %2,%0\n"
26882 +#ifdef CONFIG_PAX_REFCOUNT
26884 + LOCK_PREFIX "subl %2,%0\n"
26886 + _ASM_EXTABLE(0b, 0b)
26890 : "=m" (v->counter), "=qm" (c)
26891 : "ir" (i), "m" (v->counter) : "memory");
26893 @@ -177,7 +261,15 @@ static inline int atomic_add_negative(in
26894 static inline int atomic_add_return(int i, atomic_t *v)
26897 - asm volatile(LOCK_PREFIX "xaddl %0, %1"
26898 + asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
26900 +#ifdef CONFIG_PAX_REFCOUNT
26904 + _ASM_EXTABLE(0b, 0b)
26907 : "+r" (i), "+m" (v->counter)
26910 @@ -226,7 +318,15 @@ typedef struct {
26912 static inline void atomic64_add(long i, atomic64_t *v)
26914 - asm volatile(LOCK_PREFIX "addq %1,%0"
26915 + asm volatile(LOCK_PREFIX "addq %1,%0\n"
26917 +#ifdef CONFIG_PAX_REFCOUNT
26919 + LOCK_PREFIX "subq %1,%0\n"
26921 + _ASM_EXTABLE(0b, 0b)
26924 : "=m" (v->counter)
26925 : "er" (i), "m" (v->counter));
26927 @@ -240,7 +340,15 @@ static inline void atomic64_add(long i,
26929 static inline void atomic64_sub(long i, atomic64_t *v)
26931 - asm volatile(LOCK_PREFIX "subq %1,%0"
26932 + asm volatile(LOCK_PREFIX "subq %1,%0\n"
26934 +#ifdef CONFIG_PAX_REFCOUNT
26936 + LOCK_PREFIX "addq %1,%0\n"
26938 + _ASM_EXTABLE(0b, 0b)
26941 : "=m" (v->counter)
26942 : "er" (i), "m" (v->counter));
26944 @@ -258,7 +366,16 @@ static inline int atomic64_sub_and_test(
26948 - asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
26949 + asm volatile(LOCK_PREFIX "subq %2,%0\n"
26951 +#ifdef CONFIG_PAX_REFCOUNT
26953 + LOCK_PREFIX "addq %2,%0\n"
26955 + _ASM_EXTABLE(0b, 0b)
26959 : "=m" (v->counter), "=qm" (c)
26960 : "er" (i), "m" (v->counter) : "memory");
26962 @@ -272,7 +389,19 @@ static inline int atomic64_sub_and_test(
26964 static inline void atomic64_inc(atomic64_t *v)
26966 - asm volatile(LOCK_PREFIX "incq %0"
26967 + asm volatile(LOCK_PREFIX "incq %0\n"
26969 +#ifdef CONFIG_PAX_REFCOUNT
26972 + ".pushsection .fixup,\"ax\"\n"
26974 + LOCK_PREFIX "decq %0\n"
26977 + _ASM_EXTABLE(0b, 1b)
26980 : "=m" (v->counter)
26981 : "m" (v->counter));
26983 @@ -285,7 +414,19 @@ static inline void atomic64_inc(atomic64
26985 static inline void atomic64_dec(atomic64_t *v)
26987 - asm volatile(LOCK_PREFIX "decq %0"
26988 + asm volatile(LOCK_PREFIX "decq %0\n"
26990 +#ifdef CONFIG_PAX_REFCOUNT
26993 + ".pushsection .fixup,\"ax\"\n"
26995 + LOCK_PREFIX "incq %0\n"
26998 + _ASM_EXTABLE(0b, 1b)
27001 : "=m" (v->counter)
27002 : "m" (v->counter));
27004 @@ -302,7 +443,20 @@ static inline int atomic64_dec_and_test(
27008 - asm volatile(LOCK_PREFIX "decq %0; sete %1"
27009 + asm volatile(LOCK_PREFIX "decq %0\n"
27011 +#ifdef CONFIG_PAX_REFCOUNT
27014 + ".pushsection .fixup,\"ax\"\n"
27016 + LOCK_PREFIX "incq %0\n"
27019 + _ASM_EXTABLE(0b, 1b)
27023 : "=m" (v->counter), "=qm" (c)
27024 : "m" (v->counter) : "memory");
27026 @@ -320,7 +474,20 @@ static inline int atomic64_inc_and_test(
27030 - asm volatile(LOCK_PREFIX "incq %0; sete %1"
27031 + asm volatile(LOCK_PREFIX "incq %0\n"
27033 +#ifdef CONFIG_PAX_REFCOUNT
27036 + ".pushsection .fixup,\"ax\"\n"
27038 + LOCK_PREFIX "decq %0\n"
27041 + _ASM_EXTABLE(0b, 1b)
27045 : "=m" (v->counter), "=qm" (c)
27046 : "m" (v->counter) : "memory");
27048 @@ -339,7 +506,16 @@ static inline int atomic64_add_negative(
27052 - asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
27053 + asm volatile(LOCK_PREFIX "addq %2,%0\n"
27055 +#ifdef CONFIG_PAX_REFCOUNT
27057 + LOCK_PREFIX "subq %2,%0\n"
27059 + _ASM_EXTABLE(0b, 0b)
27063 : "=m" (v->counter), "=qm" (c)
27064 : "er" (i), "m" (v->counter) : "memory");
27066 @@ -355,7 +531,15 @@ static inline int atomic64_add_negative(
27067 static inline long atomic64_add_return(long i, atomic64_t *v)
27070 - asm volatile(LOCK_PREFIX "xaddq %0, %1;"
27071 + asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
27073 +#ifdef CONFIG_PAX_REFCOUNT
27077 + _ASM_EXTABLE(0b, 0b)
27080 : "+r" (i), "+m" (v->counter)
27083 diff -urNp linux-2.6.27.10/include/asm-x86/boot.h linux-2.6.27.10/include/asm-x86/boot.h
27084 --- linux-2.6.27.10/include/asm-x86/boot.h 2008-11-07 12:55:34.000000000 -0500
27085 +++ linux-2.6.27.10/include/asm-x86/boot.h 2008-11-18 03:38:45.000000000 -0500
27086 @@ -13,10 +13,15 @@
27087 #define ASK_VGA 0xfffd /* ask for it at bootup */
27089 /* Physical address where kernel should be loaded. */
27090 -#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
27091 +#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
27092 + (CONFIG_PHYSICAL_ALIGN - 1)) \
27093 & ~(CONFIG_PHYSICAL_ALIGN - 1))
27095 +#ifndef __ASSEMBLY__
27096 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
27097 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
27100 #ifdef CONFIG_X86_64
27101 #define BOOT_HEAP_SIZE 0x7000
27102 #define BOOT_STACK_SIZE 0x4000
27103 diff -urNp linux-2.6.27.10/include/asm-x86/cache.h linux-2.6.27.10/include/asm-x86/cache.h
27104 --- linux-2.6.27.10/include/asm-x86/cache.h 2008-11-07 12:55:34.000000000 -0500
27105 +++ linux-2.6.27.10/include/asm-x86/cache.h 2008-11-18 03:38:45.000000000 -0500
27107 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
27109 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
27110 +#define __read_only __attribute__((__section__(".data.read_only")))
27112 #ifdef CONFIG_X86_VSMP
27113 /* vSMP Internode cacheline shift */
27114 diff -urNp linux-2.6.27.10/include/asm-x86/checksum_32.h linux-2.6.27.10/include/asm-x86/checksum_32.h
27115 --- linux-2.6.27.10/include/asm-x86/checksum_32.h 2008-11-07 12:55:34.000000000 -0500
27116 +++ linux-2.6.27.10/include/asm-x86/checksum_32.h 2008-11-18 03:38:45.000000000 -0500
27117 @@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
27118 int len, __wsum sum,
27119 int *src_err_ptr, int *dst_err_ptr);
27121 +asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
27122 + int len, __wsum sum,
27123 + int *src_err_ptr, int *dst_err_ptr);
27125 +asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
27126 + int len, __wsum sum,
27127 + int *src_err_ptr, int *dst_err_ptr);
27130 * Note: when you get a NULL pointer exception here this means someone
27131 * passed in an incorrect kernel address to one of these functions.
27132 @@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
27136 - return csum_partial_copy_generic((__force void *)src, dst,
27137 + return csum_partial_copy_generic_from_user((__force void *)src, dst,
27138 len, sum, err_ptr, NULL);
27141 @@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
27144 if (access_ok(VERIFY_WRITE, dst, len))
27145 - return csum_partial_copy_generic(src, (__force void *)dst,
27146 + return csum_partial_copy_generic_to_user(src, (__force void *)dst,
27147 len, sum, NULL, err_ptr);
27150 diff -urNp linux-2.6.27.10/include/asm-x86/desc.h linux-2.6.27.10/include/asm-x86/desc.h
27151 --- linux-2.6.27.10/include/asm-x86/desc.h 2008-11-07 12:55:34.000000000 -0500
27152 +++ linux-2.6.27.10/include/asm-x86/desc.h 2008-11-18 03:38:45.000000000 -0500
27153 @@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
27154 desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
27155 desc->type = (info->read_exec_only ^ 1) << 1;
27156 desc->type |= info->contents << 2;
27157 + desc->type |= info->seg_not_present ^ 1;
27160 desc->p = info->seg_not_present ^ 1;
27161 @@ -27,16 +28,12 @@ static inline void fill_ldt(struct desc_
27164 extern struct desc_ptr idt_descr;
27165 -extern gate_desc idt_table[];
27168 - struct desc_struct gdt[GDT_ENTRIES];
27169 -} __attribute__((aligned(PAGE_SIZE)));
27170 -DECLARE_PER_CPU(struct gdt_page, gdt_page);
27171 +extern gate_desc idt_table[256];
27173 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
27174 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
27176 - return per_cpu(gdt_page, cpu).gdt;
27177 + return cpu_gdt_table[cpu];
27180 #ifdef CONFIG_X86_64
27181 @@ -65,7 +62,6 @@ static inline void pack_gate(gate_desc *
27182 gate->b = (base & 0xffff0000) |
27183 (((0x80 | type | (dpl << 5)) & 0xff) << 8);
27188 static inline int desc_empty(const void *ptr)
27189 @@ -102,19 +98,48 @@ static inline int desc_empty(const void
27190 static inline void native_write_idt_entry(gate_desc *idt, int entry,
27191 const gate_desc *gate)
27194 +#ifdef CONFIG_PAX_KERNEXEC
27195 + unsigned long cr0;
27197 + pax_open_kernel(cr0);
27200 memcpy(&idt[entry], gate, sizeof(*gate));
27202 +#ifdef CONFIG_PAX_KERNEXEC
27203 + pax_close_kernel(cr0);
27208 static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
27212 +#ifdef CONFIG_PAX_KERNEXEC
27213 + unsigned long cr0;
27215 + pax_open_kernel(cr0);
27218 memcpy(&ldt[entry], desc, 8);
27220 +#ifdef CONFIG_PAX_KERNEXEC
27221 + pax_close_kernel(cr0);
27226 static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
27227 const void *desc, int type)
27231 +#ifdef CONFIG_PAX_KERNEXEC
27232 + unsigned long cr0;
27237 size = sizeof(tss_desc);
27238 @@ -126,7 +151,17 @@ static inline void native_write_gdt_entr
27239 size = sizeof(struct desc_struct);
27243 +#ifdef CONFIG_PAX_KERNEXEC
27244 + pax_open_kernel(cr0);
27247 memcpy(&gdt[entry], desc, size);
27249 +#ifdef CONFIG_PAX_KERNEXEC
27250 + pax_close_kernel(cr0);
27255 static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
27256 @@ -198,7 +233,19 @@ static inline void native_set_ldt(const
27258 static inline void native_load_tr_desc(void)
27261 +#ifdef CONFIG_PAX_KERNEXEC
27262 + unsigned long cr0;
27264 + pax_open_kernel(cr0);
27267 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
27269 +#ifdef CONFIG_PAX_KERNEXEC
27270 + pax_close_kernel(cr0);
27275 static inline void native_load_gdt(const struct desc_ptr *dtr)
27276 @@ -233,8 +280,19 @@ static inline void native_load_tls(struc
27278 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
27280 +#ifdef CONFIG_PAX_KERNEXEC
27281 + unsigned long cr0;
27283 + pax_open_kernel(cr0);
27286 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
27287 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
27289 +#ifdef CONFIG_PAX_KERNEXEC
27290 + pax_close_kernel(cr0);
27295 #define _LDT_empty(info) \
27296 @@ -372,6 +430,18 @@ static inline void set_system_gate_ist(i
27297 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
27300 +#ifdef CONFIG_X86_32
27301 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
27303 + struct desc_struct d;
27305 + if (likely(limit))
27306 + limit = (limit - 1UL) >> PAGE_SHIFT;
27307 + pack_descriptor(&d, base, limit, 0xFB, 0xC);
27308 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
27314 * GET_DESC_BASE reads the descriptor base of the specified segment.
27315 diff -urNp linux-2.6.27.10/include/asm-x86/e820.h linux-2.6.27.10/include/asm-x86/e820.h
27316 --- linux-2.6.27.10/include/asm-x86/e820.h 2008-11-07 12:55:34.000000000 -0500
27317 +++ linux-2.6.27.10/include/asm-x86/e820.h 2008-11-18 03:38:45.000000000 -0500
27318 @@ -131,7 +131,7 @@ extern char *memory_setup(void);
27319 #define ISA_END_ADDRESS 0x100000
27320 #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
27322 -#define BIOS_BEGIN 0x000a0000
27323 +#define BIOS_BEGIN 0x000c0000
27324 #define BIOS_END 0x00100000
27327 diff -urNp linux-2.6.27.10/include/asm-x86/elf.h linux-2.6.27.10/include/asm-x86/elf.h
27328 --- linux-2.6.27.10/include/asm-x86/elf.h 2008-11-07 12:55:34.000000000 -0500
27329 +++ linux-2.6.27.10/include/asm-x86/elf.h 2008-11-18 03:38:45.000000000 -0500
27330 @@ -251,7 +251,25 @@ extern int force_personality32;
27331 the loader. We need to make sure that it is out of the way of the program
27332 that it will "exec", and that there is sufficient room for the brk. */
27334 +#ifdef CONFIG_PAX_SEGMEXEC
27335 +#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
27337 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
27340 +#ifdef CONFIG_PAX_ASLR
27341 +#ifdef CONFIG_X86_32
27342 +#define PAX_ELF_ET_DYN_BASE 0x10000000UL
27344 +#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
27345 +#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
27347 +#define PAX_ELF_ET_DYN_BASE 0x400000UL
27349 +#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
27350 +#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
27354 /* This yields a mask that user programs can use to figure out what
27355 instruction set this CPU supports. This could be done in user space,
27356 @@ -303,8 +321,7 @@ do { \
27357 #define ARCH_DLINFO \
27359 if (vdso_enabled) \
27360 - NEW_AUX_ENT(AT_SYSINFO_EHDR, \
27361 - (unsigned long)current->mm->context.vdso); \
27362 + NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
27365 #define AT_SYSINFO 32
27366 @@ -315,7 +332,7 @@ do { \
27368 #endif /* !CONFIG_X86_32 */
27370 -#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
27371 +#define VDSO_CURRENT_BASE (current->mm->context.vdso)
27373 #define VDSO_ENTRY \
27374 ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
27375 @@ -329,7 +346,4 @@ extern int arch_setup_additional_pages(s
27376 extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
27377 #define compat_arch_setup_additional_pages syscall32_setup_pages
27379 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
27380 -#define arch_randomize_brk arch_randomize_brk
27383 diff -urNp linux-2.6.27.10/include/asm-x86/futex.h linux-2.6.27.10/include/asm-x86/futex.h
27384 --- linux-2.6.27.10/include/asm-x86/futex.h 2008-11-07 12:55:34.000000000 -0500
27385 +++ linux-2.6.27.10/include/asm-x86/futex.h 2008-11-18 03:38:45.000000000 -0500
27387 #include <asm/processor.h>
27388 #include <asm/system.h>
27390 +#ifdef CONFIG_X86_32
27391 +#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
27393 + "movw\t%w6, %%ds\n" \
27394 + "1:\t" insn "\n" \
27395 + "2:\tpushl\t%%ss\n" \
27396 + "\tpopl\t%%ds\n" \
27397 + "\t.section .fixup,\"ax\"\n" \
27398 + "3:\tmov\t%3, %1\n" \
27400 + "\t.previous\n" \
27401 + _ASM_EXTABLE(1b, 3b) \
27402 + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
27403 + : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
27405 +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
27406 + asm volatile("movw\t%w7, %%es\n" \
27407 + "1:\tmovl\t%%es:%2, %0\n" \
27408 + "\tmovl\t%0, %3\n" \
27410 + "2:\tlock; cmpxchgl %3, %%es:%2\n" \
27412 + "3:\tpushl\t%%ss\n" \
27413 + "\tpopl\t%%es\n" \
27414 + "\t.section .fixup,\"ax\"\n" \
27415 + "4:\tmov\t%5, %1\n" \
27417 + "\t.previous\n" \
27418 + _ASM_EXTABLE(1b, 4b) \
27419 + _ASM_EXTABLE(2b, 4b) \
27420 + : "=&a" (oldval), "=&r" (ret), \
27421 + "+m" (*uaddr), "=&r" (tem) \
27422 + : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
27424 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
27425 asm volatile("1:\t" insn "\n" \
27426 "2:\t.section .fixup,\"ax\"\n" \
27428 : "=&a" (oldval), "=&r" (ret), \
27429 "+m" (*uaddr), "=&r" (tem) \
27430 : "r" (oparg), "i" (-EFAULT), "1" (0))
27433 -static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
27434 +static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
27436 int op = (encoded_op >> 28) & 7;
27437 int cmp = (encoded_op >> 24) & 15;
27438 @@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
27442 +#ifdef CONFIG_X86_32
27443 + __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
27445 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
27449 +#ifdef CONFIG_X86_32
27450 + __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
27453 __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
27458 __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
27459 @@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
27463 -static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
27464 +static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
27468 @@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
27469 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
27472 - asm volatile("1:\tlock; cmpxchgl %3, %1\n"
27474 +#ifdef CONFIG_X86_32
27475 + "\tmovw %w5, %%ds\n"
27476 + "1:\tlock; cmpxchgl %3, %1\n"
27477 + "2:\tpushl %%ss\n"
27479 + "\t.section .fixup, \"ax\"\n"
27481 + "1:\tlock; cmpxchgl %3, %1\n"
27482 "2:\t.section .fixup, \"ax\"\n"
27487 _ASM_EXTABLE(1b, 3b)
27488 : "=a" (oldval), "+m" (*uaddr)
27489 +#ifdef CONFIG_X86_32
27490 + : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
27492 : "i" (-EFAULT), "r" (newval), "0" (oldval)
27497 diff -urNp linux-2.6.27.10/include/asm-x86/i387.h linux-2.6.27.10/include/asm-x86/i387.h
27498 --- linux-2.6.27.10/include/asm-x86/i387.h 2008-11-07 12:55:34.000000000 -0500
27499 +++ linux-2.6.27.10/include/asm-x86/i387.h 2008-11-18 03:38:45.000000000 -0500
27500 @@ -159,13 +159,8 @@ static inline void restore_fpu(struct ta
27503 /* We need a safe address that is cheap to find and that is already
27504 - in L1 during context switch. The best choices are unfortunately
27505 - different for UP and SMP */
27507 -#define safe_address (__per_cpu_offset[0])
27509 -#define safe_address (kstat_cpu(0).cpustat.user)
27511 + in L1 during context switch. */
27512 +#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
27515 * These must be called with preempt disabled
27516 diff -urNp linux-2.6.27.10/include/asm-x86/io_64.h linux-2.6.27.10/include/asm-x86/io_64.h
27517 --- linux-2.6.27.10/include/asm-x86/io_64.h 2008-11-07 12:55:34.000000000 -0500
27518 +++ linux-2.6.27.10/include/asm-x86/io_64.h 2008-11-18 03:38:45.000000000 -0500
27519 @@ -158,6 +158,17 @@ static inline void *phys_to_virt(unsigne
27523 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
27524 +static inline int valid_phys_addr_range (unsigned long addr, size_t count)
27526 + return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
27529 +static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
27531 + return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
27535 * Change "struct page" to physical address.
27537 diff -urNp linux-2.6.27.10/include/asm-x86/irqflags.h linux-2.6.27.10/include/asm-x86/irqflags.h
27538 --- linux-2.6.27.10/include/asm-x86/irqflags.h 2008-11-07 12:55:34.000000000 -0500
27539 +++ linux-2.6.27.10/include/asm-x86/irqflags.h 2008-11-18 03:38:45.000000000 -0500
27540 @@ -141,6 +141,8 @@ static inline unsigned long __raw_local_
27541 #define INTERRUPT_RETURN iret
27542 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
27543 #define GET_CR0_INTO_EAX movl %cr0, %eax
27544 +#define GET_CR0_INTO_EDX movl %cr0, %edx
27545 +#define SET_CR0_FROM_EDX movl %edx, %cr0
27549 diff -urNp linux-2.6.27.10/include/asm-x86/kmap_types.h linux-2.6.27.10/include/asm-x86/kmap_types.h
27550 --- linux-2.6.27.10/include/asm-x86/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
27551 +++ linux-2.6.27.10/include/asm-x86/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
27552 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
27557 +D(13) KM_CLEARPAGE,
27562 diff -urNp linux-2.6.27.10/include/asm-x86/linkage.h linux-2.6.27.10/include/asm-x86/linkage.h
27563 --- linux-2.6.27.10/include/asm-x86/linkage.h 2008-11-07 12:55:34.000000000 -0500
27564 +++ linux-2.6.27.10/include/asm-x86/linkage.h 2008-11-18 03:38:45.000000000 -0500
27566 #ifdef CONFIG_X86_64
27567 #define __ALIGN .p2align 4,,15
27568 #define __ALIGN_STR ".p2align 4,,15"
27570 +#ifdef CONFIG_X86_ALIGNMENT_16
27571 +#define __ALIGN .align 16,0x90
27572 +#define __ALIGN_STR ".align 16,0x90"
27576 #ifdef CONFIG_X86_32
27581 -#ifdef CONFIG_X86_ALIGNMENT_16
27582 -#define __ALIGN .align 16,0x90
27583 -#define __ALIGN_STR ".align 16,0x90"
27588 diff -urNp linux-2.6.27.10/include/asm-x86/local.h linux-2.6.27.10/include/asm-x86/local.h
27589 --- linux-2.6.27.10/include/asm-x86/local.h 2008-11-07 12:55:34.000000000 -0500
27590 +++ linux-2.6.27.10/include/asm-x86/local.h 2008-11-18 03:38:45.000000000 -0500
27591 @@ -18,26 +18,90 @@ typedef struct {
27593 static inline void local_inc(local_t *l)
27595 - asm volatile(_ASM_INC "%0"
27596 + asm volatile(_ASM_INC "%0\n"
27598 +#ifdef CONFIG_PAX_REFCOUNT
27599 +#ifdef CONFIG_X86_32
27605 + ".pushsection .fixup,\"ax\"\n"
27610 + _ASM_EXTABLE(0b, 1b)
27613 : "+m" (l->a.counter));
27616 static inline void local_dec(local_t *l)
27618 - asm volatile(_ASM_DEC "%0"
27619 + asm volatile(_ASM_DEC "%0\n"
27621 +#ifdef CONFIG_PAX_REFCOUNT
27622 +#ifdef CONFIG_X86_32
27628 + ".pushsection .fixup,\"ax\"\n"
27633 + _ASM_EXTABLE(0b, 1b)
27636 : "+m" (l->a.counter));
27639 static inline void local_add(long i, local_t *l)
27641 - asm volatile(_ASM_ADD "%1,%0"
27642 + asm volatile(_ASM_ADD "%1,%0\n"
27644 +#ifdef CONFIG_PAX_REFCOUNT
27645 +#ifdef CONFIG_X86_32
27651 + ".pushsection .fixup,\"ax\"\n"
27653 + _ASM_SUB "%1,%0\n"
27656 + _ASM_EXTABLE(0b, 1b)
27659 : "+m" (l->a.counter)
27663 static inline void local_sub(long i, local_t *l)
27665 - asm volatile(_ASM_SUB "%1,%0"
27666 + asm volatile(_ASM_SUB "%1,%0\n"
27668 +#ifdef CONFIG_PAX_REFCOUNT
27669 +#ifdef CONFIG_X86_32
27675 + ".pushsection .fixup,\"ax\"\n"
27677 + _ASM_ADD "%1,%0\n"
27680 + _ASM_EXTABLE(0b, 1b)
27683 : "+m" (l->a.counter)
27686 @@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
27690 - asm volatile(_ASM_SUB "%2,%0; sete %1"
27691 + asm volatile(_ASM_SUB "%2,%0\n"
27693 +#ifdef CONFIG_PAX_REFCOUNT
27694 +#ifdef CONFIG_X86_32
27700 + ".pushsection .fixup,\"ax\"\n"
27702 + _ASM_ADD "%2,%0\n"
27705 + _ASM_EXTABLE(0b, 1b)
27709 : "+m" (l->a.counter), "=qm" (c)
27710 : "ir" (i) : "memory");
27712 @@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
27716 - asm volatile(_ASM_DEC "%0; sete %1"
27717 + asm volatile(_ASM_DEC "%0\n"
27719 +#ifdef CONFIG_PAX_REFCOUNT
27720 +#ifdef CONFIG_X86_32
27726 + ".pushsection .fixup,\"ax\"\n"
27731 + _ASM_EXTABLE(0b, 1b)
27735 : "+m" (l->a.counter), "=qm" (c)
27738 @@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
27742 - asm volatile(_ASM_INC "%0; sete %1"
27743 + asm volatile(_ASM_INC "%0\n"
27745 +#ifdef CONFIG_PAX_REFCOUNT
27746 +#ifdef CONFIG_X86_32
27752 + ".pushsection .fixup,\"ax\"\n"
27757 + _ASM_EXTABLE(0b, 1b)
27761 : "+m" (l->a.counter), "=qm" (c)
27764 @@ -110,7 +225,24 @@ static inline int local_add_negative(lon
27768 - asm volatile(_ASM_ADD "%2,%0; sets %1"
27769 + asm volatile(_ASM_ADD "%2,%0\n"
27771 +#ifdef CONFIG_PAX_REFCOUNT
27772 +#ifdef CONFIG_X86_32
27778 + ".pushsection .fixup,\"ax\"\n"
27780 + _ASM_SUB "%2,%0\n"
27783 + _ASM_EXTABLE(0b, 1b)
27787 : "+m" (l->a.counter), "=qm" (c)
27788 : "ir" (i) : "memory");
27790 @@ -133,7 +265,23 @@ static inline long local_add_return(long
27792 /* Modern 486+ processor */
27794 - asm volatile(_ASM_XADD "%0, %1;"
27795 + asm volatile(_ASM_XADD "%0, %1\n"
27797 +#ifdef CONFIG_PAX_REFCOUNT
27798 +#ifdef CONFIG_X86_32
27804 + ".pushsection .fixup,\"ax\"\n"
27806 + _ASM_MOV_UL "%0,%1\n"
27809 + _ASM_EXTABLE(0b, 1b)
27812 : "+r" (i), "+m" (l->a.counter)
27815 diff -urNp linux-2.6.27.10/include/asm-x86/mach-default/apm.h linux-2.6.27.10/include/asm-x86/mach-default/apm.h
27816 --- linux-2.6.27.10/include/asm-x86/mach-default/apm.h 2008-11-07 12:55:34.000000000 -0500
27817 +++ linux-2.6.27.10/include/asm-x86/mach-default/apm.h 2008-11-18 03:38:45.000000000 -0500
27818 @@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
27819 __asm__ __volatile__(APM_DO_ZERO_SEGS
27822 - "lcall *%%cs:apm_bios_entry\n\t"
27823 + "lcall *%%ss:apm_bios_entry\n\t"
27827 @@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
27828 __asm__ __volatile__(APM_DO_ZERO_SEGS
27831 - "lcall *%%cs:apm_bios_entry\n\t"
27832 + "lcall *%%ss:apm_bios_entry\n\t"
27836 diff -urNp linux-2.6.27.10/include/asm-x86/mman.h linux-2.6.27.10/include/asm-x86/mman.h
27837 --- linux-2.6.27.10/include/asm-x86/mman.h 2008-11-07 12:55:34.000000000 -0500
27838 +++ linux-2.6.27.10/include/asm-x86/mman.h 2008-11-18 03:38:45.000000000 -0500
27840 #define MCL_CURRENT 1 /* lock all current mappings */
27841 #define MCL_FUTURE 2 /* lock all future mappings */
27844 +#ifndef __ASSEMBLY__
27845 +#ifdef CONFIG_X86_32
27846 +#define arch_mmap_check i386_mmap_check
27847 +int i386_mmap_check(unsigned long addr, unsigned long len,
27848 + unsigned long flags);
27853 #endif /* _ASM_X86_MMAN_H */
27854 diff -urNp linux-2.6.27.10/include/asm-x86/mmu_context_32.h linux-2.6.27.10/include/asm-x86/mmu_context_32.h
27855 --- linux-2.6.27.10/include/asm-x86/mmu_context_32.h 2008-11-07 12:55:34.000000000 -0500
27856 +++ linux-2.6.27.10/include/asm-x86/mmu_context_32.h 2008-11-18 03:38:45.000000000 -0500
27857 @@ -33,6 +33,22 @@ static inline void switch_mm(struct mm_s
27859 if (unlikely(prev->context.ldt != next->context.ldt))
27860 load_LDT_nolock(&next->context);
27862 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27863 + if (!nx_enabled) {
27864 + smp_mb__before_clear_bit();
27865 + cpu_clear(cpu, prev->context.cpu_user_cs_mask);
27866 + smp_mb__after_clear_bit();
27867 + cpu_set(cpu, next->context.cpu_user_cs_mask);
27871 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27872 + if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
27873 + prev->context.user_cs_limit != next->context.user_cs_limit))
27874 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27880 @@ -45,6 +61,19 @@ static inline void switch_mm(struct mm_s
27882 load_cr3(next->pgd);
27883 load_LDT_nolock(&next->context);
27885 +#ifdef CONFIG_PAX_PAGEEXEC
27887 + cpu_set(cpu, next->context.cpu_user_cs_mask);
27890 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27891 +#ifdef CONFIG_PAX_PAGEEXEC
27892 + if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
27894 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27900 diff -urNp linux-2.6.27.10/include/asm-x86/mmu.h linux-2.6.27.10/include/asm-x86/mmu.h
27901 --- linux-2.6.27.10/include/asm-x86/mmu.h 2008-11-07 12:55:34.000000000 -0500
27902 +++ linux-2.6.27.10/include/asm-x86/mmu.h 2008-11-18 03:38:45.000000000 -0500
27903 @@ -11,13 +11,26 @@
27904 * cpu_vm_mask is used to optimize ldt flushing.
27908 + struct desc_struct *ldt;
27909 #ifdef CONFIG_X86_64
27915 + unsigned long vdso;
27917 +#ifdef CONFIG_X86_32
27918 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27919 + unsigned long user_cs_base;
27920 + unsigned long user_cs_limit;
27922 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27923 + cpumask_t cpu_user_cs_mask;
27932 diff -urNp linux-2.6.27.10/include/asm-x86/module.h linux-2.6.27.10/include/asm-x86/module.h
27933 --- linux-2.6.27.10/include/asm-x86/module.h 2008-11-07 12:55:34.000000000 -0500
27934 +++ linux-2.6.27.10/include/asm-x86/module.h 2008-11-18 03:38:45.000000000 -0500
27935 @@ -76,7 +76,12 @@ struct mod_arch_specific {};
27937 # define MODULE_STACKSIZE ""
27939 -# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
27940 +# ifdef CONFIG_GRKERNSEC
27941 +# define MODULE_GRSEC "GRSECURITY "
27943 +# define MODULE_GRSEC ""
27945 +# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
27948 #endif /* _ASM_MODULE_H */
27949 diff -urNp linux-2.6.27.10/include/asm-x86/page_32.h linux-2.6.27.10/include/asm-x86/page_32.h
27950 --- linux-2.6.27.10/include/asm-x86/page_32.h 2008-11-07 12:55:34.000000000 -0500
27951 +++ linux-2.6.27.10/include/asm-x86/page_32.h 2008-11-18 03:38:45.000000000 -0500
27954 #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
27956 +#ifdef CONFIG_PAX_KERNEXEC
27957 +#ifndef __ASSEMBLY__
27958 +extern unsigned char MODULES_VADDR[];
27959 +extern unsigned char MODULES_END[];
27960 +extern unsigned char KERNEL_TEXT_OFFSET[];
27961 +#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
27962 +#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
27965 +#define ktla_ktva(addr) (addr)
27966 +#define ktva_ktla(addr) (addr)
27969 +#ifdef CONFIG_PAX_PAGEEXEC
27970 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
27973 #ifdef CONFIG_4KSTACKS
27974 #define THREAD_ORDER 0
27976 diff -urNp linux-2.6.27.10/include/asm-x86/page_64.h linux-2.6.27.10/include/asm-x86/page_64.h
27977 --- linux-2.6.27.10/include/asm-x86/page_64.h 2008-11-07 12:55:34.000000000 -0500
27978 +++ linux-2.6.27.10/include/asm-x86/page_64.h 2008-11-18 03:38:45.000000000 -0500
27980 #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
27981 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
27983 +#define ktla_ktva(addr) (addr)
27984 +#define ktva_ktla(addr) (addr)
27986 /* See Documentation/x86_64/mm.txt for a description of the memory map. */
27987 #define __PHYSICAL_MASK_SHIFT 46
27988 #define __VIRTUAL_MASK_SHIFT 48
27989 @@ -101,5 +104,6 @@ extern void init_extra_mapping_wb(unsign
27990 #define pfn_valid(pfn) ((pfn) < max_pfn)
27993 +#define nx_enabled (1)
27995 #endif /* _X86_64_PAGE_H */
27996 diff -urNp linux-2.6.27.10/include/asm-x86/paravirt.h linux-2.6.27.10/include/asm-x86/paravirt.h
27997 --- linux-2.6.27.10/include/asm-x86/paravirt.h 2008-11-07 12:55:34.000000000 -0500
27998 +++ linux-2.6.27.10/include/asm-x86/paravirt.h 2008-11-18 03:38:45.000000000 -0500
27999 @@ -1557,7 +1557,7 @@ static inline unsigned long __raw_local_
28000 #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax
28001 #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
28002 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
28003 -#define PARA_INDIRECT(addr) *%cs:addr
28004 +#define PARA_INDIRECT(addr) *%ss:addr
28007 #define INTERRUPT_RETURN \
28008 diff -urNp linux-2.6.27.10/include/asm-x86/pda.h linux-2.6.27.10/include/asm-x86/pda.h
28009 --- linux-2.6.27.10/include/asm-x86/pda.h 2008-11-07 12:55:34.000000000 -0500
28010 +++ linux-2.6.27.10/include/asm-x86/pda.h 2008-11-18 03:38:45.000000000 -0500
28011 @@ -16,11 +16,9 @@ struct x8664_pda {
28012 unsigned long oldrsp; /* 24 user rsp for system call */
28013 int irqcount; /* 32 Irq nesting counter. Starts -1 */
28014 unsigned int cpunumber; /* 36 Logical CPU number */
28015 -#ifdef CONFIG_CC_STACKPROTECTOR
28016 unsigned long stack_canary; /* 40 stack canary value */
28017 /* gcc-ABI: this canary MUST be at
28021 short nodenumber; /* number of current node (32k max) */
28022 short in_bootmem; /* pda lives in bootmem */
28023 diff -urNp linux-2.6.27.10/include/asm-x86/percpu.h linux-2.6.27.10/include/asm-x86/percpu.h
28024 --- linux-2.6.27.10/include/asm-x86/percpu.h 2008-11-07 12:55:34.000000000 -0500
28025 +++ linux-2.6.27.10/include/asm-x86/percpu.h 2008-11-18 03:38:45.000000000 -0500
28026 @@ -93,6 +93,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
28028 #define __my_cpu_offset x86_read_percpu(this_cpu_off)
28030 +#include <asm-generic/sections.h>
28031 +#include <linux/threads.h>
28032 +#define __per_cpu_offset __per_cpu_offset
28033 +extern unsigned long __per_cpu_offset[NR_CPUS];
28034 +#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
28036 /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
28037 #define __percpu_seg "%%fs:"
28039 diff -urNp linux-2.6.27.10/include/asm-x86/pgalloc.h linux-2.6.27.10/include/asm-x86/pgalloc.h
28040 --- linux-2.6.27.10/include/asm-x86/pgalloc.h 2008-11-07 12:55:34.000000000 -0500
28041 +++ linux-2.6.27.10/include/asm-x86/pgalloc.h 2008-11-18 03:38:45.000000000 -0500
28042 @@ -51,7 +51,7 @@ static inline void pmd_populate_kernel(s
28043 pmd_t *pmd, pte_t *pte)
28045 paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
28046 - set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
28047 + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
28050 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
28051 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable-2level.h linux-2.6.27.10/include/asm-x86/pgtable-2level.h
28052 --- linux-2.6.27.10/include/asm-x86/pgtable-2level.h 2008-11-07 12:55:34.000000000 -0500
28053 +++ linux-2.6.27.10/include/asm-x86/pgtable-2level.h 2008-11-18 03:38:45.000000000 -0500
28054 @@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
28056 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
28059 +#ifdef CONFIG_PAX_KERNEXEC
28060 + unsigned long cr0;
28062 + pax_open_kernel(cr0);
28067 +#ifdef CONFIG_PAX_KERNEXEC
28068 + pax_close_kernel(cr0);
28073 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
28074 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable_32.h linux-2.6.27.10/include/asm-x86/pgtable_32.h
28075 --- linux-2.6.27.10/include/asm-x86/pgtable_32.h 2008-11-07 12:55:34.000000000 -0500
28076 +++ linux-2.6.27.10/include/asm-x86/pgtable_32.h 2008-11-18 03:38:45.000000000 -0500
28079 struct vm_area_struct;
28081 -extern pgd_t swapper_pg_dir[1024];
28083 static inline void pgtable_cache_init(void) { }
28084 static inline void check_pgt_cache(void) { }
28085 void paging_init(void);
28086 @@ -45,6 +43,11 @@ void paging_init(void);
28087 # include <asm/pgtable-2level-defs.h>
28090 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
28091 +#ifdef CONFIG_X86_PAE
28092 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
28095 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
28096 #define PGDIR_MASK (~(PGDIR_SIZE - 1))
28098 @@ -81,7 +84,7 @@ void paging_init(void);
28099 #undef TEST_ACCESS_OK
28101 /* The boot page tables (all created as a single array) */
28102 -extern unsigned long pg0[];
28103 +extern pte_t pg0[];
28105 #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
28107 @@ -173,6 +176,9 @@ do { \
28109 #endif /* !__ASSEMBLY__ */
28111 +#define HAVE_ARCH_UNMAPPED_AREA
28112 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
28115 * kern_addr_valid() is (1) for FLATMEM and (0) for
28116 * SPARSEMEM and DISCONTIGMEM
28117 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable-3level.h linux-2.6.27.10/include/asm-x86/pgtable-3level.h
28118 --- linux-2.6.27.10/include/asm-x86/pgtable-3level.h 2008-11-07 12:55:34.000000000 -0500
28119 +++ linux-2.6.27.10/include/asm-x86/pgtable-3level.h 2008-11-18 03:38:45.000000000 -0500
28120 @@ -70,12 +70,36 @@ static inline void native_set_pte_atomic
28122 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
28125 +#ifdef CONFIG_PAX_KERNEXEC
28126 + unsigned long cr0;
28128 + pax_open_kernel(cr0);
28131 set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
28133 +#ifdef CONFIG_PAX_KERNEXEC
28134 + pax_close_kernel(cr0);
28139 static inline void native_set_pud(pud_t *pudp, pud_t pud)
28142 +#ifdef CONFIG_PAX_KERNEXEC
28143 + unsigned long cr0;
28145 + pax_open_kernel(cr0);
28148 set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
28150 +#ifdef CONFIG_PAX_KERNEXEC
28151 + pax_close_kernel(cr0);
28157 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable_64.h linux-2.6.27.10/include/asm-x86/pgtable_64.h
28158 --- linux-2.6.27.10/include/asm-x86/pgtable_64.h 2008-11-07 12:55:34.000000000 -0500
28159 +++ linux-2.6.27.10/include/asm-x86/pgtable_64.h 2008-11-18 03:38:45.000000000 -0500
28162 extern pud_t level3_kernel_pgt[512];
28163 extern pud_t level3_ident_pgt[512];
28164 +extern pud_t level3_vmalloc_pgt[512];
28165 +extern pud_t level3_vmemmap_pgt[512];
28166 extern pmd_t level2_kernel_pgt[512];
28167 extern pmd_t level2_fixmap_pgt[512];
28168 extern pmd_t level2_ident_pgt[512];
28169 +extern pte_t level1_fixmap_pgt[512];
28170 extern pgd_t init_level4_pgt[];
28172 #define swapper_pg_dir init_level4_pgt
28173 @@ -106,7 +109,19 @@ static inline pte_t native_ptep_get_and_
28175 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
28178 +#ifdef CONFIG_PAX_KERNEXEC
28179 + unsigned long cr0;
28181 + pax_open_kernel(cr0);
28186 +#ifdef CONFIG_PAX_KERNEXEC
28187 + pax_close_kernel(cr0);
28192 static inline void native_pmd_clear(pmd_t *pmd)
28193 @@ -158,17 +173,17 @@ static inline void native_pgd_clear(pgd_
28195 static inline int pgd_bad(pgd_t pgd)
28197 - return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
28198 + return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
28201 static inline int pud_bad(pud_t pud)
28203 - return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
28204 + return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
28207 static inline int pmd_bad(pmd_t pmd)
28209 - return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
28210 + return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
28213 #define pte_none(x) (!pte_val((x)))
28214 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable.h linux-2.6.27.10/include/asm-x86/pgtable.h
28215 --- linux-2.6.27.10/include/asm-x86/pgtable.h 2008-11-07 12:55:34.000000000 -0500
28216 +++ linux-2.6.27.10/include/asm-x86/pgtable.h 2008-11-18 03:38:45.000000000 -0500
28218 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
28219 #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
28221 -#define _PAGE_NX (_AT(pteval_t, 0))
28222 +#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
28225 /* If _PAGE_PRESENT is clear, we use these: */
28227 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
28230 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
28231 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
28233 #define __PAGE_KERNEL_EXEC \
28234 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
28235 #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
28237 #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
28238 #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
28239 #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
28240 -#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
28241 +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
28242 #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
28243 #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
28244 #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
28245 @@ -142,10 +145,17 @@ extern unsigned long empty_zero_page[PAG
28246 extern spinlock_t pgd_lock;
28247 extern struct list_head pgd_list;
28249 +extern pteval_t __supported_pte_mask;
28252 * The following only work if pte_present() is true.
28253 * Undefined behaviour if not..
28255 +static inline int pte_user(pte_t pte)
28257 + return pte_val(pte) & _PAGE_USER;
28260 static inline int pte_dirty(pte_t pte)
28262 return pte_flags(pte) & _PAGE_DIRTY;
28263 @@ -207,9 +217,29 @@ static inline pte_t pte_wrprotect(pte_t
28264 return __pte(pte_val(pte) & ~_PAGE_RW);
28267 +static inline pte_t pte_mkread(pte_t pte)
28269 + return __pte(pte_val(pte) | _PAGE_USER);
28272 static inline pte_t pte_mkexec(pte_t pte)
28274 - return __pte(pte_val(pte) & ~_PAGE_NX);
28275 +#ifdef CONFIG_X86_PAE
28276 + if (__supported_pte_mask & _PAGE_NX)
28277 + return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
28280 + return __pte(pte_val(pte) | _PAGE_USER);
28283 +static inline pte_t pte_exprotect(pte_t pte)
28285 +#ifdef CONFIG_X86_PAE
28286 + if (__supported_pte_mask & _PAGE_NX)
28287 + return __pte(pte_val(pte) | _PAGE_NX);
28290 + return __pte(pte_val(pte) & ~_PAGE_USER);
28293 static inline pte_t pte_mkdirty(pte_t pte)
28294 @@ -252,8 +282,6 @@ static inline pte_t pte_mkspecial(pte_t
28295 return __pte(pte_val(pte) | _PAGE_SPECIAL);
28298 -extern pteval_t __supported_pte_mask;
28300 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
28302 return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
28303 @@ -514,7 +542,19 @@ static inline void ptep_set_wrprotect(st
28305 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
28307 - memcpy(dst, src, count * sizeof(pgd_t));
28309 +#ifdef CONFIG_PAX_KERNEXEC
28310 + unsigned long cr0;
28312 + pax_open_kernel(cr0);
28315 + memcpy(dst, src, count * sizeof(pgd_t));
28317 +#ifdef CONFIG_PAX_KERNEXEC
28318 + pax_close_kernel(cr0);
28324 diff -urNp linux-2.6.27.10/include/asm-x86/processor.h linux-2.6.27.10/include/asm-x86/processor.h
28325 --- linux-2.6.27.10/include/asm-x86/processor.h 2008-11-07 12:55:34.000000000 -0500
28326 +++ linux-2.6.27.10/include/asm-x86/processor.h 2008-11-18 03:38:45.000000000 -0500
28327 @@ -269,7 +269,7 @@ struct tss_struct {
28329 } ____cacheline_aligned;
28331 -DECLARE_PER_CPU(struct tss_struct, init_tss);
28332 +extern struct tss_struct init_tss[NR_CPUS];
28335 * Save the original ist values for checking stack pointers during debugging
28336 @@ -832,11 +832,20 @@ static inline void spin_lock_prefetch(co
28337 * User space process size: 3GB (default).
28339 #define TASK_SIZE PAGE_OFFSET
28341 +#ifdef CONFIG_PAX_SEGMEXEC
28342 +#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
28345 +#ifdef CONFIG_PAX_SEGMEXEC
28346 +#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
28348 #define STACK_TOP TASK_SIZE
28349 -#define STACK_TOP_MAX STACK_TOP
28351 +#define STACK_TOP_MAX TASK_SIZE
28353 #define INIT_THREAD { \
28354 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
28355 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
28356 .vm86_info = NULL, \
28357 .sysenter_cs = __KERNEL_CS, \
28358 .io_bitmap_ptr = NULL, \
28359 @@ -851,7 +860,7 @@ static inline void spin_lock_prefetch(co
28361 #define INIT_TSS { \
28363 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
28364 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
28365 .ss0 = __KERNEL_DS, \
28366 .ss1 = __KERNEL_CS, \
28367 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
28368 @@ -862,11 +871,7 @@ static inline void spin_lock_prefetch(co
28369 extern unsigned long thread_saved_pc(struct task_struct *tsk);
28371 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
28372 -#define KSTK_TOP(info) \
28374 - unsigned long *__ptr = (unsigned long *)(info); \
28375 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
28377 +#define KSTK_TOP(info) ((info)->task.thread.sp0)
28380 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
28381 @@ -881,7 +886,7 @@ extern unsigned long thread_saved_pc(str
28382 #define task_pt_regs(task) \
28384 struct pt_regs *__regs__; \
28385 - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
28386 + __regs__ = (struct pt_regs *)((task)->thread.sp0); \
28390 @@ -897,7 +902,7 @@ extern unsigned long thread_saved_pc(str
28391 * space during mmap's.
28393 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
28394 - 0xc0000000 : 0xFFFFe000)
28395 + 0xc0000000 : 0xFFFFf000)
28397 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
28398 IA32_PAGE_OFFSET : TASK_SIZE64)
28399 @@ -934,6 +939,10 @@ extern void start_thread(struct pt_regs
28401 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
28403 +#ifdef CONFIG_PAX_SEGMEXEC
28404 +#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
28407 #define KSTK_EIP(task) (task_pt_regs(task)->ip)
28409 /* Get/set a process' ability to use the timestamp counter instruction */
28410 diff -urNp linux-2.6.27.10/include/asm-x86/ptrace.h linux-2.6.27.10/include/asm-x86/ptrace.h
28411 --- linux-2.6.27.10/include/asm-x86/ptrace.h 2008-11-07 12:55:34.000000000 -0500
28412 +++ linux-2.6.27.10/include/asm-x86/ptrace.h 2008-11-18 03:38:45.000000000 -0500
28413 @@ -131,6 +131,7 @@ struct pt_regs {
28415 /* the DS BTS struct is used for ptrace as well */
28416 #include <asm/ds.h>
28417 +#include <asm/segment.h>
28419 struct task_struct;
28421 @@ -154,28 +155,29 @@ static inline unsigned long regs_return_
28425 - * user_mode_vm(regs) determines whether a register set came from user mode.
28426 + * user_mode(regs) determines whether a register set came from user mode.
28427 * This is true if V8086 mode was enabled OR if the register set was from
28428 * protected mode with RPL-3 CS value. This tricky test checks that with
28429 * one comparison. Many places in the kernel can bypass this full check
28430 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
28431 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
28434 -static inline int user_mode(struct pt_regs *regs)
28435 +static inline int user_mode_novm(struct pt_regs *regs)
28437 #ifdef CONFIG_X86_32
28438 return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
28440 - return !!(regs->cs & 3);
28441 + return !!(regs->cs & SEGMENT_RPL_MASK);
28445 -static inline int user_mode_vm(struct pt_regs *regs)
28446 +static inline int user_mode(struct pt_regs *regs)
28448 #ifdef CONFIG_X86_32
28449 return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
28452 - return user_mode(regs);
28453 + return user_mode_novm(regs);
28457 diff -urNp linux-2.6.27.10/include/asm-x86/reboot.h linux-2.6.27.10/include/asm-x86/reboot.h
28458 --- linux-2.6.27.10/include/asm-x86/reboot.h 2008-11-07 12:55:34.000000000 -0500
28459 +++ linux-2.6.27.10/include/asm-x86/reboot.h 2008-11-18 03:38:45.000000000 -0500
28460 @@ -16,6 +16,6 @@ extern struct machine_ops machine_ops;
28462 void native_machine_crash_shutdown(struct pt_regs *regs);
28463 void native_machine_shutdown(void);
28464 -void machine_real_restart(const unsigned char *code, int length);
28465 +void machine_real_restart(const unsigned char *code, unsigned int length);
28467 #endif /* _ASM_REBOOT_H */
28468 diff -urNp linux-2.6.27.10/include/asm-x86/rwsem.h linux-2.6.27.10/include/asm-x86/rwsem.h
28469 --- linux-2.6.27.10/include/asm-x86/rwsem.h 2008-11-07 12:55:34.000000000 -0500
28470 +++ linux-2.6.27.10/include/asm-x86/rwsem.h 2008-11-18 03:38:45.000000000 -0500
28471 @@ -106,10 +106,26 @@ static inline void __down_read(struct rw
28473 asm volatile("# beginning down_read\n\t"
28474 LOCK_PREFIX " incl (%%eax)\n\t"
28476 +#ifdef CONFIG_PAX_REFCOUNT
28477 +#ifdef CONFIG_X86_32
28483 + ".pushsection .fixup,\"ax\"\n"
28485 + LOCK_PREFIX "decl (%%eax)\n"
28488 + _ASM_EXTABLE(0b, 1b)
28491 /* adds 0x00000001, returns the old value */
28494 " call call_rwsem_down_read_failed\n"
28497 "# ending down_read\n\t"
28498 : "+m" (sem->count)
28500 @@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
28502 asm volatile("# beginning __down_read_trylock\n\t"
28510 +#ifdef CONFIG_PAX_REFCOUNT
28511 +#ifdef CONFIG_X86_32
28517 + ".pushsection .fixup,\"ax\"\n"
28522 + _ASM_EXTABLE(0b, 1b)
28526 LOCK_PREFIX " cmpxchgl %2,%0\n\t"
28531 "# ending __down_read_trylock\n\t"
28532 : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
28533 : "i" (RWSEM_ACTIVE_READ_BIAS)
28534 @@ -148,12 +180,28 @@ static inline void __down_write_nested(s
28535 tmp = RWSEM_ACTIVE_WRITE_BIAS;
28536 asm volatile("# beginning down_write\n\t"
28537 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
28539 +#ifdef CONFIG_PAX_REFCOUNT
28540 +#ifdef CONFIG_X86_32
28546 + ".pushsection .fixup,\"ax\"\n"
28548 + "movl %%edx,(%%eax)\n"
28551 + _ASM_EXTABLE(0b, 1b)
28554 /* subtract 0x0000ffff, returns the old value */
28555 " testl %%edx,%%edx\n\t"
28556 /* was the count 0 before? */
28559 " call call_rwsem_down_write_failed\n"
28562 "# ending down_write"
28563 : "+m" (sem->count), "=d" (tmp)
28564 : "a" (sem), "1" (tmp)
28565 @@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
28566 __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
28567 asm volatile("# beginning __up_read\n\t"
28568 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
28570 +#ifdef CONFIG_PAX_REFCOUNT
28571 +#ifdef CONFIG_X86_32
28577 + ".pushsection .fixup,\"ax\"\n"
28579 + "movl %%edx,(%%eax)\n"
28582 + _ASM_EXTABLE(0b, 1b)
28585 /* subtracts 1, returns the old value */
28588 " call call_rwsem_wake\n"
28591 "# ending __up_read\n"
28592 : "+m" (sem->count), "=d" (tmp)
28593 : "a" (sem), "1" (tmp)
28594 @@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
28595 asm volatile("# beginning __up_write\n\t"
28596 " movl %2,%%edx\n\t"
28597 LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
28599 +#ifdef CONFIG_PAX_REFCOUNT
28600 +#ifdef CONFIG_X86_32
28606 + ".pushsection .fixup,\"ax\"\n"
28608 + "movl %%edx,(%%eax)\n"
28611 + _ASM_EXTABLE(0b, 1b)
28614 /* tries to transition
28615 0xffff0001 -> 0x00000000 */
28618 " call call_rwsem_wake\n"
28621 "# ending __up_write\n"
28622 : "+m" (sem->count)
28623 : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
28624 @@ -222,10 +302,26 @@ static inline void __downgrade_write(str
28626 asm volatile("# beginning __downgrade_write\n\t"
28627 LOCK_PREFIX " addl %2,(%%eax)\n\t"
28629 +#ifdef CONFIG_PAX_REFCOUNT
28630 +#ifdef CONFIG_X86_32
28636 + ".pushsection .fixup,\"ax\"\n"
28638 + LOCK_PREFIX "subl %2,(%%eax)\n"
28641 + _ASM_EXTABLE(0b, 1b)
28644 /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
28647 " call call_rwsem_downgrade_wake\n"
28650 "# ending __downgrade_write\n"
28651 : "+m" (sem->count)
28652 : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
28653 @@ -237,7 +333,23 @@ static inline void __downgrade_write(str
28655 static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
28657 - asm volatile(LOCK_PREFIX "addl %1,%0"
28658 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
28660 +#ifdef CONFIG_PAX_REFCOUNT
28661 +#ifdef CONFIG_X86_32
28667 + ".pushsection .fixup,\"ax\"\n"
28669 + LOCK_PREFIX "subl %1,%0\n"
28672 + _ASM_EXTABLE(0b, 1b)
28675 : "+m" (sem->count)
28678 @@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
28682 - asm volatile(LOCK_PREFIX "xadd %0,%1"
28683 + asm volatile(LOCK_PREFIX "xadd %0,%1\n"
28685 +#ifdef CONFIG_PAX_REFCOUNT
28686 +#ifdef CONFIG_X86_32
28692 + ".pushsection .fixup,\"ax\"\n"
28697 + _ASM_EXTABLE(0b, 1b)
28700 : "+r" (tmp), "+m" (sem->count)
28703 diff -urNp linux-2.6.27.10/include/asm-x86/segment.h linux-2.6.27.10/include/asm-x86/segment.h
28704 --- linux-2.6.27.10/include/asm-x86/segment.h 2008-11-07 12:55:34.000000000 -0500
28705 +++ linux-2.6.27.10/include/asm-x86/segment.h 2008-11-18 03:38:45.000000000 -0500
28706 @@ -88,13 +88,19 @@
28707 #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
28708 #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
28710 -#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
28711 +#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
28713 #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
28715 #define __KERNEL_PERCPU 0
28718 +#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
28719 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
28721 +#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
28722 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
28724 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
28727 @@ -135,10 +141,10 @@
28728 #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
28730 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
28731 -#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
28732 +#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
28734 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
28735 -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
28736 +#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
28740 diff -urNp linux-2.6.27.10/include/asm-x86/spinlock.h linux-2.6.27.10/include/asm-x86/spinlock.h
28741 --- linux-2.6.27.10/include/asm-x86/spinlock.h 2008-11-07 12:55:34.000000000 -0500
28742 +++ linux-2.6.27.10/include/asm-x86/spinlock.h 2008-11-18 03:38:45.000000000 -0500
28743 @@ -315,18 +315,50 @@ static inline int __raw_write_can_lock(r
28744 static inline void __raw_read_lock(raw_rwlock_t *rw)
28746 asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
28748 - "call __read_lock_failed\n\t"
28750 +#ifdef CONFIG_PAX_REFCOUNT
28751 +#ifdef CONFIG_X86_32
28757 + ".pushsection .fixup,\"ax\"\n"
28759 + LOCK_PREFIX " addl $1,(%0)\n"
28762 + _ASM_EXTABLE(0b, 1b)
28766 + "call __read_lock_failed\n\t"
28768 ::LOCK_PTR_REG (rw) : "memory");
28771 static inline void __raw_write_lock(raw_rwlock_t *rw)
28773 asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
28775 - "call __write_lock_failed\n\t"
28777 +#ifdef CONFIG_PAX_REFCOUNT
28778 +#ifdef CONFIG_X86_32
28784 + ".pushsection .fixup,\"ax\"\n"
28786 + LOCK_PREFIX " addl %1,(%0)\n"
28789 + _ASM_EXTABLE(0b, 1b)
28793 + "call __write_lock_failed\n\t"
28795 ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
28798 @@ -353,12 +385,45 @@ static inline int __raw_write_trylock(ra
28800 static inline void __raw_read_unlock(raw_rwlock_t *rw)
28802 - asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
28803 + asm volatile(LOCK_PREFIX "incl %0\n"
28805 +#ifdef CONFIG_PAX_REFCOUNT
28806 +#ifdef CONFIG_X86_32
28812 + ".pushsection .fixup,\"ax\"\n"
28814 + LOCK_PREFIX "decl %0\n"
28817 + _ASM_EXTABLE(0b, 1b)
28820 + :"+m" (rw->lock) : : "memory");
28823 static inline void __raw_write_unlock(raw_rwlock_t *rw)
28825 - asm volatile(LOCK_PREFIX "addl %1, %0"
28826 + asm volatile(LOCK_PREFIX "addl %1, %0\n"
28828 +#ifdef CONFIG_PAX_REFCOUNT
28829 +#ifdef CONFIG_X86_32
28835 + ".pushsection .fixup,\"ax\"\n"
28837 + LOCK_PREFIX "subl %1,%0\n"
28840 + _ASM_EXTABLE(0b, 1b)
28843 : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
28846 diff -urNp linux-2.6.27.10/include/asm-x86/system.h linux-2.6.27.10/include/asm-x86/system.h
28847 --- linux-2.6.27.10/include/asm-x86/system.h 2008-11-07 12:55:34.000000000 -0500
28848 +++ linux-2.6.27.10/include/asm-x86/system.h 2008-11-18 03:38:45.000000000 -0500
28849 @@ -92,6 +92,8 @@ do { \
28850 ".globl thread_return\n" \
28851 "thread_return:\n\t" \
28852 "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
28853 + "movq %P[task_canary](%%rsi),%%r8\n\t" \
28854 + "movq %%r8,%%gs:%P[pda_canary]\n\t" \
28855 "movq %P[thread_info](%%rsi),%%r8\n\t" \
28856 LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
28857 "movq %%rax,%%rdi\n\t" \
28858 @@ -103,7 +105,9 @@ do { \
28859 [ti_flags] "i" (offsetof(struct thread_info, flags)), \
28860 [tif_fork] "i" (TIF_FORK), \
28861 [thread_info] "i" (offsetof(struct task_struct, stack)), \
28862 - [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
28863 + [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
28864 + [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
28865 + [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
28866 : "memory", "cc" __EXTRA_CLOBBER)
28869 @@ -166,7 +170,7 @@ static inline unsigned long get_limit(un
28871 unsigned long __limit;
28872 asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
28873 - return __limit + 1;
28877 static inline void native_clts(void)
28878 @@ -292,6 +296,21 @@ static inline void native_wbinvd(void)
28880 #define stts() write_cr0(read_cr0() | X86_CR0_TS)
28882 +#define pax_open_kernel(cr0) \
28884 + typecheck(unsigned long, cr0); \
28885 + preempt_disable(); \
28886 + cr0 = read_cr0(); \
28887 + write_cr0(cr0 & ~X86_CR0_WP); \
28890 +#define pax_close_kernel(cr0) \
28892 + typecheck(unsigned long, cr0); \
28893 + write_cr0(cr0); \
28894 + preempt_enable_no_resched(); \
28897 #endif /* __KERNEL__ */
28899 static inline void clflush(volatile void *__p)
28900 @@ -306,7 +325,7 @@ void enable_hlt(void);
28902 void cpu_idle_wait(void);
28904 -extern unsigned long arch_align_stack(unsigned long sp);
28905 +#define arch_align_stack(x) ((x) & ~0xfUL)
28906 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
28908 void default_idle(void);
28909 diff -urNp linux-2.6.27.10/include/asm-x86/uaccess_64.h linux-2.6.27.10/include/asm-x86/uaccess_64.h
28910 --- linux-2.6.27.10/include/asm-x86/uaccess_64.h 2008-11-07 12:55:34.000000000 -0500
28911 +++ linux-2.6.27.10/include/asm-x86/uaccess_64.h 2008-11-18 03:38:45.000000000 -0500
28913 #include <linux/lockdep.h>
28914 #include <asm/page.h>
28916 +#define set_fs(x) (current_thread_info()->addr_limit = (x))
28919 * Copy To/From Userspace
28921 diff -urNp linux-2.6.27.10/include/asm-x86/uaccess.h linux-2.6.27.10/include/asm-x86/uaccess.h
28922 --- linux-2.6.27.10/include/asm-x86/uaccess.h 2008-11-07 12:55:34.000000000 -0500
28923 +++ linux-2.6.27.10/include/asm-x86/uaccess.h 2008-11-18 03:38:45.000000000 -0500
28925 #include <linux/string.h>
28926 #include <asm/asm.h>
28927 #include <asm/page.h>
28928 +#include <asm/segment.h>
28930 #define VERIFY_READ 0
28931 #define VERIFY_WRITE 1
28934 #define get_ds() (KERNEL_DS)
28935 #define get_fs() (current_thread_info()->addr_limit)
28936 +#ifdef CONFIG_X86_32
28937 +void __set_fs(mm_segment_t x, int cpu);
28938 +void set_fs(mm_segment_t x);
28940 #define set_fs(x) (current_thread_info()->addr_limit = (x))
28943 #define segment_eq(a, b) ((a).seg == (b).seg)
28945 @@ -97,6 +103,7 @@ struct exception_table_entry {
28948 extern int fixup_exception(struct pt_regs *regs);
28949 +#define ARCH_HAS_SORT_EXTABLE
28952 * These are the main single-value transfer routines. They automatically
28953 @@ -186,9 +193,12 @@ extern int __get_user_bad(void);
28955 #ifdef CONFIG_X86_32
28956 #define __put_user_u64(x, addr, err) \
28957 - asm volatile("1: movl %%eax,0(%2)\n" \
28958 - "2: movl %%edx,4(%2)\n" \
28959 + asm volatile(" movw %w5,%%ds\n" \
28960 + "1: movl %%eax,%%ds:0(%2)\n" \
28961 + "2: movl %%edx,%%ds:4(%2)\n" \
28963 + " pushl %%ss\n" \
28965 ".section .fixup,\"ax\"\n" \
28966 "4: movl %3,%0\n" \
28968 @@ -196,7 +206,8 @@ extern int __get_user_bad(void);
28969 _ASM_EXTABLE(1b, 4b) \
28970 _ASM_EXTABLE(2b, 4b) \
28972 - : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
28973 + : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err), \
28976 #define __put_user_x8(x, ptr, __ret_pu) \
28977 asm volatile("call __put_user_8" : "=a" (__ret_pu) \
28978 @@ -336,6 +347,22 @@ do { \
28982 +#ifdef CONFIG_X86_32
28983 +#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28984 + asm volatile(" movw %w5,%%ds\n" \
28985 + "1: mov"itype" %%ds:%2,%"rtype"1\n" \
28987 + " pushl %%ss\n" \
28989 + ".section .fixup,\"ax\"\n" \
28990 + "3: movl %3,%0\n" \
28991 + " xor"itype" %"rtype"1,%"rtype"1\n" \
28994 + _ASM_EXTABLE(1b, 3b) \
28995 + : "=r" (err), ltype (x) \
28996 + : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
28998 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28999 asm volatile("1: mov"itype" %2,%"rtype"1\n" \
29001 @@ -347,6 +374,7 @@ do { \
29002 _ASM_EXTABLE(1b, 3b) \
29003 : "=r" (err), ltype(x) \
29004 : "m" (__m(addr)), "i" (errret), "0" (err))
29007 #define __put_user_nocheck(x, ptr, size) \
29009 @@ -373,6 +401,22 @@ struct __large_struct { unsigned long bu
29010 * we do not write to any memory gcc knows about, so there are no
29013 +#ifdef CONFIG_X86_32
29014 +#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
29015 + asm volatile(" movw %w5,%%ds\n" \
29016 + "1: mov"itype" %"rtype"1,%%ds:%2\n" \
29018 + " pushl %%ss\n" \
29020 + ".section .fixup,\"ax\"\n" \
29021 + "3: movl %3,%0\n" \
29024 + _ASM_EXTABLE(1b, 3b) \
29026 + : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
29029 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
29030 asm volatile("1: mov"itype" %"rtype"1,%2\n" \
29032 @@ -383,6 +427,7 @@ struct __large_struct { unsigned long bu
29033 _ASM_EXTABLE(1b, 3b) \
29035 : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
29038 * __get_user: - Get a simple variable from user space, with less checking.
29039 * @x: Variable to store result.
29040 @@ -447,6 +492,7 @@ extern struct movsl_mask {
29041 # include "uaccess_32.h"
29043 # define ARCH_HAS_SEARCH_EXTABLE
29044 +# define ARCH_HAS_SORT_EXTABLE
29045 # include "uaccess_64.h"
29048 diff -urNp linux-2.6.27.10/include/asm-xtensa/kmap_types.h linux-2.6.27.10/include/asm-xtensa/kmap_types.h
29049 --- linux-2.6.27.10/include/asm-xtensa/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
29050 +++ linux-2.6.27.10/include/asm-xtensa/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
29051 @@ -25,6 +25,7 @@ enum km_type {
29059 diff -urNp linux-2.6.27.10/include/linux/a.out.h linux-2.6.27.10/include/linux/a.out.h
29060 --- linux-2.6.27.10/include/linux/a.out.h 2008-11-07 12:55:34.000000000 -0500
29061 +++ linux-2.6.27.10/include/linux/a.out.h 2008-11-18 03:38:45.000000000 -0500
29062 @@ -39,6 +39,14 @@ enum machine_type {
29063 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
29066 +/* Constants for the N_FLAGS field */
29067 +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29068 +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
29069 +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
29070 +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
29071 +/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29072 +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29074 #if !defined (N_MAGIC)
29075 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
29077 diff -urNp linux-2.6.27.10/include/linux/binfmts.h linux-2.6.27.10/include/linux/binfmts.h
29078 --- linux-2.6.27.10/include/linux/binfmts.h 2008-12-21 01:16:52.000000000 -0500
29079 +++ linux-2.6.27.10/include/linux/binfmts.h 2008-12-21 01:13:46.000000000 -0500
29080 @@ -71,6 +71,7 @@ struct linux_binfmt {
29081 int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
29082 int (*load_shlib)(struct file *);
29083 int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
29084 + void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags);
29085 unsigned long min_coredump; /* minimal dump size */
29088 diff -urNp linux-2.6.27.10/include/linux/cache.h linux-2.6.27.10/include/linux/cache.h
29089 --- linux-2.6.27.10/include/linux/cache.h 2008-11-07 12:55:34.000000000 -0500
29090 +++ linux-2.6.27.10/include/linux/cache.h 2008-11-18 03:38:45.000000000 -0500
29092 #define __read_mostly
29095 +#ifndef __read_only
29096 +#define __read_only __read_mostly
29099 #ifndef ____cacheline_aligned
29100 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
29102 diff -urNp linux-2.6.27.10/include/linux/capability.h linux-2.6.27.10/include/linux/capability.h
29103 --- linux-2.6.27.10/include/linux/capability.h 2008-11-07 12:55:34.000000000 -0500
29104 +++ linux-2.6.27.10/include/linux/capability.h 2008-11-18 03:38:45.000000000 -0500
29105 @@ -516,6 +516,7 @@ kernel_cap_t cap_set_effective(const ker
29106 #define has_capability(t, cap) (security_capable((t), (cap)) == 0)
29108 extern int capable(int cap);
29109 +int capable_nolog(int cap);
29111 #endif /* __KERNEL__ */
29113 diff -urNp linux-2.6.27.10/include/linux/cpumask.h linux-2.6.27.10/include/linux/cpumask.h
29114 --- linux-2.6.27.10/include/linux/cpumask.h 2008-11-07 12:55:34.000000000 -0500
29115 +++ linux-2.6.27.10/include/linux/cpumask.h 2008-11-18 03:38:45.000000000 -0500
29116 @@ -139,7 +139,6 @@
29117 #include <linux/bitmap.h>
29119 typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
29120 -extern cpumask_t _unused_cpumask_arg_;
29122 #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
29123 static inline void __cpu_set(int cpu, volatile cpumask_t *dstp)
29124 diff -urNp linux-2.6.27.10/include/linux/elf.h linux-2.6.27.10/include/linux/elf.h
29125 --- linux-2.6.27.10/include/linux/elf.h 2008-11-07 12:55:34.000000000 -0500
29126 +++ linux-2.6.27.10/include/linux/elf.h 2008-12-21 00:44:29.000000000 -0500
29127 @@ -49,6 +49,17 @@ typedef __s64 Elf64_Sxword;
29128 #define PT_GNU_EH_FRAME 0x6474e550
29130 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
29131 +#define PT_GNU_RELRO (PT_LOOS + 0x474e552)
29133 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
29135 +/* Constants for the e_flags field */
29136 +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29137 +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
29138 +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
29139 +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
29140 +/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29141 +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29143 /* These constants define the different elf file types */
29145 @@ -84,6 +95,8 @@ typedef __s64 Elf64_Sxword;
29146 #define DT_DEBUG 21
29147 #define DT_TEXTREL 22
29148 #define DT_JMPREL 23
29149 +#define DT_FLAGS 30
29150 + #define DF_TEXTREL 0x00000004
29151 #define DT_ENCODING 32
29152 #define OLD_DT_LOOS 0x60000000
29153 #define DT_LOOS 0x6000000d
29154 @@ -230,6 +243,19 @@ typedef struct elf64_hdr {
29158 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
29159 +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
29160 +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
29161 +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
29162 +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
29163 +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
29164 +/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
29165 +/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
29166 +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
29167 +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
29168 +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
29169 +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
29171 typedef struct elf32_phdr{
29173 Elf32_Off p_offset;
29174 @@ -322,6 +348,8 @@ typedef struct elf64_shdr {
29180 #define ELFMAG0 0x7f /* EI_MAG */
29181 #define ELFMAG1 'E'
29182 #define ELFMAG2 'L'
29183 @@ -383,6 +411,7 @@ extern Elf32_Dyn _DYNAMIC [];
29184 #define elf_phdr elf32_phdr
29185 #define elf_note elf32_note
29186 #define elf_addr_t Elf32_Off
29187 +#define elf_dyn Elf32_Dyn
29191 @@ -391,6 +420,7 @@ extern Elf64_Dyn _DYNAMIC [];
29192 #define elf_phdr elf64_phdr
29193 #define elf_note elf64_note
29194 #define elf_addr_t Elf64_Off
29195 +#define elf_dyn Elf64_Dyn
29199 diff -urNp linux-2.6.27.10/include/linux/gracl.h linux-2.6.27.10/include/linux/gracl.h
29200 --- linux-2.6.27.10/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
29201 +++ linux-2.6.27.10/include/linux/gracl.h 2008-11-18 03:38:45.000000000 -0500
29206 +#include <linux/grdefs.h>
29207 +#include <linux/resource.h>
29208 +#include <linux/capability.h>
29209 +#include <linux/dcache.h>
29210 +#include <asm/resource.h>
29212 +/* Major status information */
29214 +#define GR_VERSION "grsecurity 2.1.12"
29215 +#define GRSECURITY_VERSION 0x2112
29230 +/* Password setup definitions
29231 + * kernel/grhash.c */
29234 + GR_SALT_LEN = 16,
29239 + GR_SPROLE_LEN = 64,
29242 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
29244 +/* Begin Data Structures */
29246 +struct sprole_pw {
29247 + unsigned char *rolename;
29248 + unsigned char salt[GR_SALT_LEN];
29249 + unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
29252 +struct name_entry {
29259 + struct name_entry *prev;
29260 + struct name_entry *next;
29263 +struct inodev_entry {
29264 + struct name_entry *nentry;
29265 + struct inodev_entry *prev;
29266 + struct inodev_entry *next;
29269 +struct acl_role_db {
29270 + struct acl_role_label **r_hash;
29274 +struct inodev_db {
29275 + struct inodev_entry **i_hash;
29280 + struct name_entry **n_hash;
29284 +struct crash_uid {
29286 + unsigned long expires;
29289 +struct gr_hash_struct {
29291 + void **nametable;
29293 + __u32 table_size;
29298 +/* Userspace Grsecurity ACL data structures */
29300 +struct acl_subject_label {
29305 + kernel_cap_t cap_mask;
29306 + kernel_cap_t cap_lower;
29308 + struct rlimit res[GR_NLIMITS];
29311 + __u8 user_trans_type;
29312 + __u8 group_trans_type;
29313 + uid_t *user_transitions;
29314 + gid_t *group_transitions;
29315 + __u16 user_trans_num;
29316 + __u16 group_trans_num;
29318 + __u32 ip_proto[8];
29320 + struct acl_ip_label **ips;
29324 + unsigned long expires;
29326 + struct acl_subject_label *parent_subject;
29327 + struct gr_hash_struct *hash;
29328 + struct acl_subject_label *prev;
29329 + struct acl_subject_label *next;
29331 + struct acl_object_label **obj_hash;
29332 + __u32 obj_hash_size;
29336 +struct role_allowed_ip {
29340 + struct role_allowed_ip *prev;
29341 + struct role_allowed_ip *next;
29344 +struct role_transition {
29347 + struct role_transition *prev;
29348 + struct role_transition *next;
29351 +struct acl_role_label {
29356 + __u16 auth_attempts;
29357 + unsigned long expires;
29359 + struct acl_subject_label *root_label;
29360 + struct gr_hash_struct *hash;
29362 + struct acl_role_label *prev;
29363 + struct acl_role_label *next;
29365 + struct role_transition *transitions;
29366 + struct role_allowed_ip *allowed_ips;
29367 + uid_t *domain_children;
29368 + __u16 domain_child_num;
29370 + struct acl_subject_label **subj_hash;
29371 + __u32 subj_hash_size;
29374 +struct user_acl_role_db {
29375 + struct acl_role_label **r_table;
29376 + __u32 num_pointers; /* Number of allocations to track */
29377 + __u32 num_roles; /* Number of roles */
29378 + __u32 num_domain_children; /* Number of domain children */
29379 + __u32 num_subjects; /* Number of subjects */
29380 + __u32 num_objects; /* Number of objects */
29383 +struct acl_object_label {
29389 + struct acl_subject_label *nested;
29390 + struct acl_object_label *globbed;
29392 + /* next two structures not used */
29394 + struct acl_object_label *prev;
29395 + struct acl_object_label *next;
29398 +struct acl_ip_label {
29407 + /* next two structures not used */
29409 + struct acl_ip_label *prev;
29410 + struct acl_ip_label *next;
29414 + struct user_acl_role_db role_db;
29415 + unsigned char pw[GR_PW_LEN];
29416 + unsigned char salt[GR_SALT_LEN];
29417 + unsigned char sum[GR_SHA_LEN];
29418 + unsigned char sp_role[GR_SPROLE_LEN];
29419 + struct sprole_pw *sprole_pws;
29420 + dev_t segv_device;
29421 + ino_t segv_inode;
29423 + __u16 num_sprole_pws;
29427 +struct gr_arg_wrapper {
29428 + struct gr_arg *arg;
29433 +struct subject_map {
29434 + struct acl_subject_label *user;
29435 + struct acl_subject_label *kernel;
29436 + struct subject_map *prev;
29437 + struct subject_map *next;
29440 +struct acl_subj_map_db {
29441 + struct subject_map **s_hash;
29445 +/* End Data Structures Section */
29447 +/* Hash functions generated by empirical testing by Brad Spengler
29448 + Makes good use of the low bits of the inode. Generally 0-1 times
29449 + in loop for successful match. 0-3 for unsuccessful match.
29450 + Shift/add algorithm with modulus of table size and an XOR*/
29452 +static __inline__ unsigned int
29453 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
29455 + return (((uid << type) + (uid ^ type)) % sz);
29458 + static __inline__ unsigned int
29459 +shash(const struct acl_subject_label *userp, const unsigned int sz)
29461 + return ((const unsigned long)userp % sz);
29464 +static __inline__ unsigned int
29465 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
29467 + return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
29470 +static __inline__ unsigned int
29471 +nhash(const char *name, const __u16 len, const unsigned int sz)
29473 + return full_name_hash(name, len) % sz;
29476 +#define FOR_EACH_ROLE_START(role,iter) \
29479 + while (iter < acl_role_set.r_size) { \
29480 + if (role == NULL) \
29481 + role = acl_role_set.r_hash[iter]; \
29482 + if (role == NULL) { \
29487 +#define FOR_EACH_ROLE_END(role,iter) \
29488 + role = role->next; \
29489 + if (role == NULL) \
29493 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
29496 + while (iter < role->subj_hash_size) { \
29497 + if (subj == NULL) \
29498 + subj = role->subj_hash[iter]; \
29499 + if (subj == NULL) { \
29504 +#define FOR_EACH_SUBJECT_END(subj,iter) \
29505 + subj = subj->next; \
29506 + if (subj == NULL) \
29511 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
29512 + subj = role->hash->first; \
29513 + while (subj != NULL) {
29515 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
29516 + subj = subj->next; \
29521 diff -urNp linux-2.6.27.10/include/linux/gralloc.h linux-2.6.27.10/include/linux/gralloc.h
29522 --- linux-2.6.27.10/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
29523 +++ linux-2.6.27.10/include/linux/gralloc.h 2008-11-18 03:38:45.000000000 -0500
29525 +#ifndef __GRALLOC_H
29526 +#define __GRALLOC_H
29528 +void acl_free_all(void);
29529 +int acl_alloc_stack_init(unsigned long size);
29530 +void *acl_alloc(unsigned long len);
29533 diff -urNp linux-2.6.27.10/include/linux/grdefs.h linux-2.6.27.10/include/linux/grdefs.h
29534 --- linux-2.6.27.10/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
29535 +++ linux-2.6.27.10/include/linux/grdefs.h 2008-11-18 03:38:45.000000000 -0500
29540 +/* Begin grsecurity status declarations */
29544 + GR_STATUS_INIT = 0x00 // disabled state
29547 +/* Begin ACL declarations */
29552 + GR_ROLE_USER = 0x0001,
29553 + GR_ROLE_GROUP = 0x0002,
29554 + GR_ROLE_DEFAULT = 0x0004,
29555 + GR_ROLE_SPECIAL = 0x0008,
29556 + GR_ROLE_AUTH = 0x0010,
29557 + GR_ROLE_NOPW = 0x0020,
29558 + GR_ROLE_GOD = 0x0040,
29559 + GR_ROLE_LEARN = 0x0080,
29560 + GR_ROLE_TPE = 0x0100,
29561 + GR_ROLE_DOMAIN = 0x0200,
29562 + GR_ROLE_PAM = 0x0400
29565 +/* ACL Subject and Object mode flags */
29567 + GR_DELETED = 0x80000000
29570 +/* ACL Object-only mode flags */
29572 + GR_READ = 0x00000001,
29573 + GR_APPEND = 0x00000002,
29574 + GR_WRITE = 0x00000004,
29575 + GR_EXEC = 0x00000008,
29576 + GR_FIND = 0x00000010,
29577 + GR_INHERIT = 0x00000020,
29578 + GR_SETID = 0x00000040,
29579 + GR_CREATE = 0x00000080,
29580 + GR_DELETE = 0x00000100,
29581 + GR_LINK = 0x00000200,
29582 + GR_AUDIT_READ = 0x00000400,
29583 + GR_AUDIT_APPEND = 0x00000800,
29584 + GR_AUDIT_WRITE = 0x00001000,
29585 + GR_AUDIT_EXEC = 0x00002000,
29586 + GR_AUDIT_FIND = 0x00004000,
29587 + GR_AUDIT_INHERIT= 0x00008000,
29588 + GR_AUDIT_SETID = 0x00010000,
29589 + GR_AUDIT_CREATE = 0x00020000,
29590 + GR_AUDIT_DELETE = 0x00040000,
29591 + GR_AUDIT_LINK = 0x00080000,
29592 + GR_PTRACERD = 0x00100000,
29593 + GR_NOPTRACE = 0x00200000,
29594 + GR_SUPPRESS = 0x00400000,
29595 + GR_NOLEARN = 0x00800000
29598 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
29599 + GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
29600 + GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
29602 +/* ACL subject-only mode flags */
29604 + GR_KILL = 0x00000001,
29605 + GR_VIEW = 0x00000002,
29606 + GR_PROTECTED = 0x00000004,
29607 + GR_LEARN = 0x00000008,
29608 + GR_OVERRIDE = 0x00000010,
29609 + /* just a placeholder, this mode is only used in userspace */
29610 + GR_DUMMY = 0x00000020,
29611 + GR_PROTSHM = 0x00000040,
29612 + GR_KILLPROC = 0x00000080,
29613 + GR_KILLIPPROC = 0x00000100,
29614 + /* just a placeholder, this mode is only used in userspace */
29615 + GR_NOTROJAN = 0x00000200,
29616 + GR_PROTPROCFD = 0x00000400,
29617 + GR_PROCACCT = 0x00000800,
29618 + GR_RELAXPTRACE = 0x00001000,
29619 + GR_NESTED = 0x00002000,
29620 + GR_INHERITLEARN = 0x00004000,
29621 + GR_PROCFIND = 0x00008000,
29622 + GR_POVERRIDE = 0x00010000,
29623 + GR_KERNELAUTH = 0x00020000,
29627 + GR_PAX_ENABLE_SEGMEXEC = 0x0001,
29628 + GR_PAX_ENABLE_PAGEEXEC = 0x0002,
29629 + GR_PAX_ENABLE_MPROTECT = 0x0004,
29630 + GR_PAX_ENABLE_RANDMMAP = 0x0008,
29631 + GR_PAX_ENABLE_EMUTRAMP = 0x0010,
29632 + GR_PAX_DISABLE_SEGMEXEC = 0x0100,
29633 + GR_PAX_DISABLE_PAGEEXEC = 0x0200,
29634 + GR_PAX_DISABLE_MPROTECT = 0x0400,
29635 + GR_PAX_DISABLE_RANDMMAP = 0x0800,
29636 + GR_PAX_DISABLE_EMUTRAMP = 0x1000,
29640 + GR_ID_USER = 0x01,
29641 + GR_ID_GROUP = 0x02,
29645 + GR_ID_ALLOW = 0x01,
29646 + GR_ID_DENY = 0x02,
29649 +#define GR_CRASH_RES 11
29650 +#define GR_UIDTABLE_MAX 500
29652 +/* begin resource learning section */
29654 + GR_RLIM_CPU_BUMP = 60,
29655 + GR_RLIM_FSIZE_BUMP = 50000,
29656 + GR_RLIM_DATA_BUMP = 10000,
29657 + GR_RLIM_STACK_BUMP = 1000,
29658 + GR_RLIM_CORE_BUMP = 10000,
29659 + GR_RLIM_RSS_BUMP = 500000,
29660 + GR_RLIM_NPROC_BUMP = 1,
29661 + GR_RLIM_NOFILE_BUMP = 5,
29662 + GR_RLIM_MEMLOCK_BUMP = 50000,
29663 + GR_RLIM_AS_BUMP = 500000,
29664 + GR_RLIM_LOCKS_BUMP = 2
29668 diff -urNp linux-2.6.27.10/include/linux/grinternal.h linux-2.6.27.10/include/linux/grinternal.h
29669 --- linux-2.6.27.10/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
29670 +++ linux-2.6.27.10/include/linux/grinternal.h 2008-11-18 03:38:45.000000000 -0500
29672 +#ifndef __GRINTERNAL_H
29673 +#define __GRINTERNAL_H
29675 +#ifdef CONFIG_GRKERNSEC
29677 +#include <linux/fs.h>
29678 +#include <linux/gracl.h>
29679 +#include <linux/grdefs.h>
29680 +#include <linux/grmsg.h>
29682 +void gr_add_learn_entry(const char *fmt, ...);
29683 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
29684 + const struct vfsmount *mnt);
29685 +__u32 gr_check_create(const struct dentry *new_dentry,
29686 + const struct dentry *parent,
29687 + const struct vfsmount *mnt, const __u32 mode);
29688 +int gr_check_protected_task(const struct task_struct *task);
29689 +__u32 to_gr_audit(const __u32 reqmode);
29690 +int gr_set_acls(const int type);
29692 +int gr_acl_is_enabled(void);
29693 +char gr_roletype_to_char(void);
29695 +void gr_handle_alertkill(struct task_struct *task);
29696 +char *gr_to_filename(const struct dentry *dentry,
29697 + const struct vfsmount *mnt);
29698 +char *gr_to_filename1(const struct dentry *dentry,
29699 + const struct vfsmount *mnt);
29700 +char *gr_to_filename2(const struct dentry *dentry,
29701 + const struct vfsmount *mnt);
29702 +char *gr_to_filename3(const struct dentry *dentry,
29703 + const struct vfsmount *mnt);
29705 +extern int grsec_enable_link;
29706 +extern int grsec_enable_fifo;
29707 +extern int grsec_enable_execve;
29708 +extern int grsec_enable_shm;
29709 +extern int grsec_enable_execlog;
29710 +extern int grsec_enable_signal;
29711 +extern int grsec_enable_forkfail;
29712 +extern int grsec_enable_time;
29713 +extern int grsec_enable_chroot_shmat;
29714 +extern int grsec_enable_chroot_findtask;
29715 +extern int grsec_enable_chroot_mount;
29716 +extern int grsec_enable_chroot_double;
29717 +extern int grsec_enable_chroot_pivot;
29718 +extern int grsec_enable_chroot_chdir;
29719 +extern int grsec_enable_chroot_chmod;
29720 +extern int grsec_enable_chroot_mknod;
29721 +extern int grsec_enable_chroot_fchdir;
29722 +extern int grsec_enable_chroot_nice;
29723 +extern int grsec_enable_chroot_execlog;
29724 +extern int grsec_enable_chroot_caps;
29725 +extern int grsec_enable_chroot_sysctl;
29726 +extern int grsec_enable_chroot_unix;
29727 +extern int grsec_enable_tpe;
29728 +extern int grsec_tpe_gid;
29729 +extern int grsec_enable_tpe_all;
29730 +extern int grsec_enable_sidcaps;
29731 +extern int grsec_enable_socket_all;
29732 +extern int grsec_socket_all_gid;
29733 +extern int grsec_enable_socket_client;
29734 +extern int grsec_socket_client_gid;
29735 +extern int grsec_enable_socket_server;
29736 +extern int grsec_socket_server_gid;
29737 +extern int grsec_audit_gid;
29738 +extern int grsec_enable_group;
29739 +extern int grsec_enable_audit_ipc;
29740 +extern int grsec_enable_audit_textrel;
29741 +extern int grsec_enable_mount;
29742 +extern int grsec_enable_chdir;
29743 +extern int grsec_resource_logging;
29744 +extern int grsec_lock;
29746 +extern spinlock_t grsec_alert_lock;
29747 +extern unsigned long grsec_alert_wtime;
29748 +extern unsigned long grsec_alert_fyet;
29750 +extern spinlock_t grsec_audit_lock;
29752 +extern rwlock_t grsec_exec_file_lock;
29754 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
29755 + gr_to_filename2(tsk->exec_file->f_path.dentry, \
29756 + tsk->exec_file->f_vfsmnt) : "/")
29758 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
29759 + gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
29760 + tsk->parent->exec_file->f_vfsmnt) : "/")
29762 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
29763 + gr_to_filename(tsk->exec_file->f_path.dentry, \
29764 + tsk->exec_file->f_vfsmnt) : "/")
29766 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
29767 + gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
29768 + tsk->parent->exec_file->f_vfsmnt) : "/")
29770 +#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
29771 + ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
29772 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
29773 + (tsk_a->fs->root.dentry->d_inode->i_ino != \
29774 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
29776 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
29777 + (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
29778 + tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
29779 + (tsk_a->fs->root.dentry->d_inode->i_ino == \
29780 + tsk_b->fs->root.dentry->d_inode->i_ino))
29782 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
29783 + task->pid, task->uid, \
29784 + task->euid, task->gid, task->egid, \
29785 + gr_parent_task_fullpath(task), \
29786 + task->parent->comm, task->parent->pid, \
29787 + task->parent->uid, task->parent->euid, \
29788 + task->parent->gid, task->parent->egid
29790 +#define GR_CHROOT_CAPS {{ \
29791 + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
29792 + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
29793 + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
29794 + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
29795 + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
29796 + CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
29798 +#define security_learn(normal_msg,args...) \
29800 + read_lock(&grsec_exec_file_lock); \
29801 + gr_add_learn_entry(normal_msg "\n", ## args); \
29802 + read_unlock(&grsec_exec_file_lock); \
29808 + GR_DONT_AUDIT_GOOD
29819 + GR_SYSCTL_HIDDEN,
29822 + GR_ONE_INT_TWO_STR,
29827 + GR_FIVE_INT_TWO_STR,
29833 + GR_FILENAME_TWO_INT,
29834 + GR_FILENAME_TWO_INT_STR,
29845 +#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
29846 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
29847 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
29848 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
29849 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
29850 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
29851 +#define gr_log_fs_rbac_mode3(audit, msg, dentry, mnt, str1, str2, str3) gr_log_varargs(audit, msg, GR_RBAC_MODE3, dentry, mnt, str1, str2, str3)
29852 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
29853 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
29854 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
29855 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
29856 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
29857 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
29858 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
29859 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
29860 +#define gr_log_int5_str2(audit, msg, num1, num2, str1, str2) gr_log_varargs(audit, msg, GR_FIVE_INT_TWO_STR, num1, num2, str1, str2)
29861 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
29862 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
29863 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
29864 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
29865 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
29866 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
29867 +#define gr_log_fs_int2_str(audit, msg, dentry, mnt, num1, num2, str) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT_STR, dentry, mnt, num1, num2, str)
29868 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
29869 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
29870 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
29871 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
29872 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
29873 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
29874 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
29875 +#define gr_log_procacct(audit, msg, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) gr_log_varargs(audit, msg, GR_PSACCT, task, num1, num2, num3, num4, num5, num6, num7, num8, num9)
29877 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
29882 diff -urNp linux-2.6.27.10/include/linux/grmsg.h linux-2.6.27.10/include/linux/grmsg.h
29883 --- linux-2.6.27.10/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
29884 +++ linux-2.6.27.10/include/linux/grmsg.h 2008-11-18 03:38:45.000000000 -0500
29886 +#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u"
29887 +#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u"
29888 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
29889 +#define GR_STOPMOD_MSG "denied modification of module state by "
29890 +#define GR_IOPERM_MSG "denied use of ioperm() by "
29891 +#define GR_IOPL_MSG "denied use of iopl() by "
29892 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
29893 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
29894 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
29895 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
29896 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
29897 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
29898 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
29899 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
29900 +#define GR_LEARN_AUDIT_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%lu\t%lu\t%.4095s\t%lu\t%u.%u.%u.%u"
29901 +#define GR_ID_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%c\t%d\t%d\t%d\t%u.%u.%u.%u"
29902 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
29903 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
29904 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
29905 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
29906 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
29907 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
29908 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
29909 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
29910 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
29911 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
29912 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
29913 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
29914 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
29915 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
29916 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
29917 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
29918 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
29919 +#define GR_NPROC_MSG "denied overstep of process limit by "
29920 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
29921 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
29922 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
29923 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
29924 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
29925 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
29926 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
29927 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
29928 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
29929 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
29930 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
29931 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
29932 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
29933 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
29934 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
29935 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
29936 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
29937 +#define GR_DISABLED_ACL_MSG "Error loading %s, trying to run kernel with acls disabled. To disable acls at startup use <kernel image name> gracl=off from your boot loader"
29938 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
29939 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
29940 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
29941 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
29942 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
29943 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
29944 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
29945 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
29946 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
29947 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
29948 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
29949 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
29950 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
29951 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
29952 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
29953 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
29954 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
29955 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
29956 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
29957 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
29958 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
29959 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
29960 +#define GR_NICE_CHROOT_MSG "denied priority change by "
29961 +#define GR_UNISIGLOG_MSG "signal %d sent to "
29962 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
29963 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
29964 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
29965 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
29966 +#define GR_TIME_MSG "time set by "
29967 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
29968 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
29969 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
29970 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
29971 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
29972 +#define GR_BIND_MSG "denied bind() by "
29973 +#define GR_CONNECT_MSG "denied connect() by "
29974 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
29975 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
29976 +#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%u.%u.%u.%u\t%u\t%u\t%u\t%u\t%u.%u.%u.%u"
29977 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
29978 +#define GR_CAP_ACL_MSG "use of %s denied for "
29979 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
29980 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
29981 +#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
29982 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
29983 +#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
29984 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
29985 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
29986 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
29987 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
29988 +#define GR_SEM_AUDIT_MSG "semaphore created by "
29989 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
29990 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
29991 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
29992 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
29993 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
29994 diff -urNp linux-2.6.27.10/include/linux/grsecurity.h linux-2.6.27.10/include/linux/grsecurity.h
29995 --- linux-2.6.27.10/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
29996 +++ linux-2.6.27.10/include/linux/grsecurity.h 2008-11-18 03:38:45.000000000 -0500
29998 +#ifndef GR_SECURITY_H
29999 +#define GR_SECURITY_H
30000 +#include <linux/fs.h>
30001 +#include <linux/binfmts.h>
30002 +#include <linux/gracl.h>
30004 +/* notify of brain-dead configs */
30005 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
30006 +#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
30008 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
30009 +#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
30011 +#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
30012 +#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
30014 +#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
30015 +#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
30017 +#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
30018 +#error "CONFIG_PAX enabled, but no PaX options are enabled."
30021 +void gr_handle_brute_attach(struct task_struct *p);
30022 +void gr_handle_brute_check(void);
30024 +char gr_roletype_to_char(void);
30026 +int gr_check_user_change(int real, int effective, int fs);
30027 +int gr_check_group_change(int real, int effective, int fs);
30029 +void gr_del_task_from_ip_table(struct task_struct *p);
30031 +int gr_pid_is_chrooted(struct task_struct *p);
30032 +int gr_handle_chroot_nice(void);
30033 +int gr_handle_chroot_sysctl(const int op);
30034 +int gr_handle_chroot_setpriority(struct task_struct *p,
30035 + const int niceval);
30036 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
30037 +int gr_handle_chroot_chroot(const struct dentry *dentry,
30038 + const struct vfsmount *mnt);
30039 +void gr_handle_chroot_caps(struct task_struct *task);
30040 +void gr_handle_chroot_chdir(struct path *path);
30041 +int gr_handle_chroot_chmod(const struct dentry *dentry,
30042 + const struct vfsmount *mnt, const int mode);
30043 +int gr_handle_chroot_mknod(const struct dentry *dentry,
30044 + const struct vfsmount *mnt, const int mode);
30045 +int gr_handle_chroot_mount(const struct dentry *dentry,
30046 + const struct vfsmount *mnt,
30047 + const char *dev_name);
30048 +int gr_handle_chroot_pivot(void);
30049 +int gr_handle_chroot_unix(const pid_t pid);
30051 +int gr_handle_rawio(const struct inode *inode);
30052 +int gr_handle_nproc(void);
30054 +void gr_handle_ioperm(void);
30055 +void gr_handle_iopl(void);
30057 +int gr_tpe_allow(const struct file *file);
30059 +int gr_random_pid(void);
30061 +void gr_log_forkfail(const int retval);
30062 +void gr_log_timechange(void);
30063 +void gr_log_signal(const int sig, const struct task_struct *t);
30064 +void gr_log_chdir(const struct dentry *dentry,
30065 + const struct vfsmount *mnt);
30066 +void gr_log_chroot_exec(const struct dentry *dentry,
30067 + const struct vfsmount *mnt);
30068 +void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
30069 +void gr_log_remount(const char *devname, const int retval);
30070 +void gr_log_unmount(const char *devname, const int retval);
30071 +void gr_log_mount(const char *from, const char *to, const int retval);
30072 +void gr_log_msgget(const int ret, const int msgflg);
30073 +void gr_log_msgrm(const uid_t uid, const uid_t cuid);
30074 +void gr_log_semget(const int err, const int semflg);
30075 +void gr_log_semrm(const uid_t uid, const uid_t cuid);
30076 +void gr_log_shmget(const int err, const int shmflg, const size_t size);
30077 +void gr_log_shmrm(const uid_t uid, const uid_t cuid);
30078 +void gr_log_textrel(struct vm_area_struct *vma);
30080 +int gr_handle_follow_link(const struct inode *parent,
30081 + const struct inode *inode,
30082 + const struct dentry *dentry,
30083 + const struct vfsmount *mnt);
30084 +int gr_handle_fifo(const struct dentry *dentry,
30085 + const struct vfsmount *mnt,
30086 + const struct dentry *dir, const int flag,
30087 + const int acc_mode);
30088 +int gr_handle_hardlink(const struct dentry *dentry,
30089 + const struct vfsmount *mnt,
30090 + struct inode *inode,
30091 + const int mode, const char *to);
30093 +int gr_task_is_capable(struct task_struct *task, const int cap);
30094 +int gr_is_capable_nolog(const int cap);
30095 +void gr_learn_resource(const struct task_struct *task, const int limit,
30096 + const unsigned long wanted, const int gt);
30097 +void gr_copy_label(struct task_struct *tsk);
30098 +void gr_handle_crash(struct task_struct *task, const int sig);
30099 +int gr_handle_signal(const struct task_struct *p, const int sig);
30100 +int gr_check_crash_uid(const uid_t uid);
30101 +int gr_check_protected_task(const struct task_struct *task);
30102 +int gr_acl_handle_mmap(const struct file *file,
30103 + const unsigned long prot);
30104 +int gr_acl_handle_mprotect(const struct file *file,
30105 + const unsigned long prot);
30106 +int gr_check_hidden_task(const struct task_struct *tsk);
30107 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
30108 + const struct vfsmount *mnt);
30109 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
30110 + const struct vfsmount *mnt);
30111 +__u32 gr_acl_handle_access(const struct dentry *dentry,
30112 + const struct vfsmount *mnt, const int fmode);
30113 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
30114 + const struct vfsmount *mnt, mode_t mode);
30115 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
30116 + const struct vfsmount *mnt, mode_t mode);
30117 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
30118 + const struct vfsmount *mnt);
30119 +int gr_handle_ptrace(struct task_struct *task, const long request);
30120 +int gr_handle_proc_ptrace(struct task_struct *task);
30121 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
30122 + const struct vfsmount *mnt);
30123 +int gr_check_crash_exec(const struct file *filp);
30124 +int gr_acl_is_enabled(void);
30125 +void gr_set_kernel_label(struct task_struct *task);
30126 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
30127 + const gid_t gid);
30128 +int gr_set_proc_label(const struct dentry *dentry,
30129 + const struct vfsmount *mnt);
30130 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
30131 + const struct vfsmount *mnt);
30132 +__u32 gr_acl_handle_open(const struct dentry *dentry,
30133 + const struct vfsmount *mnt, const int fmode);
30134 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
30135 + const struct dentry *p_dentry,
30136 + const struct vfsmount *p_mnt, const int fmode,
30137 + const int imode);
30138 +void gr_handle_create(const struct dentry *dentry,
30139 + const struct vfsmount *mnt);
30140 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
30141 + const struct dentry *parent_dentry,
30142 + const struct vfsmount *parent_mnt,
30144 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
30145 + const struct dentry *parent_dentry,
30146 + const struct vfsmount *parent_mnt);
30147 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
30148 + const struct vfsmount *mnt);
30149 +void gr_handle_delete(const ino_t ino, const dev_t dev);
30150 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
30151 + const struct vfsmount *mnt);
30152 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
30153 + const struct dentry *parent_dentry,
30154 + const struct vfsmount *parent_mnt,
30155 + const char *from);
30156 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
30157 + const struct dentry *parent_dentry,
30158 + const struct vfsmount *parent_mnt,
30159 + const struct dentry *old_dentry,
30160 + const struct vfsmount *old_mnt, const char *to);
30161 +int gr_acl_handle_rename(struct dentry *new_dentry,
30162 + struct dentry *parent_dentry,
30163 + const struct vfsmount *parent_mnt,
30164 + struct dentry *old_dentry,
30165 + struct inode *old_parent_inode,
30166 + struct vfsmount *old_mnt, const char *newname);
30167 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
30168 + struct dentry *old_dentry,
30169 + struct dentry *new_dentry,
30170 + struct vfsmount *mnt, const __u8 replace);
30171 +__u32 gr_check_link(const struct dentry *new_dentry,
30172 + const struct dentry *parent_dentry,
30173 + const struct vfsmount *parent_mnt,
30174 + const struct dentry *old_dentry,
30175 + const struct vfsmount *old_mnt);
30176 +int gr_acl_handle_filldir(const struct file *file, const char *name,
30177 + const unsigned int namelen, const ino_t ino);
30179 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
30180 + const struct vfsmount *mnt);
30181 +void gr_acl_handle_exit(void);
30182 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
30183 +int gr_acl_handle_procpidmem(const struct task_struct *task);
30185 +#ifdef CONFIG_GRKERNSEC
30186 +void gr_handle_mem_write(void);
30187 +void gr_handle_kmem_write(void);
30188 +void gr_handle_open_port(void);
30189 +int gr_handle_mem_mmap(const unsigned long offset,
30190 + struct vm_area_struct *vma);
30192 +extern int grsec_enable_dmesg;
30193 +extern int grsec_enable_randsrc;
30194 +extern int grsec_enable_shm;
30198 diff -urNp linux-2.6.27.10/include/linux/highmem.h linux-2.6.27.10/include/linux/highmem.h
30199 --- linux-2.6.27.10/include/linux/highmem.h 2008-11-07 12:55:34.000000000 -0500
30200 +++ linux-2.6.27.10/include/linux/highmem.h 2008-11-18 03:38:45.000000000 -0500
30201 @@ -122,6 +122,13 @@ static inline void clear_highpage(struct
30202 kunmap_atomic(kaddr, KM_USER0);
30205 +static inline void sanitize_highpage(struct page *page)
30207 + void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
30208 + clear_page(kaddr);
30209 + kunmap_atomic(kaddr, KM_CLEARPAGE);
30212 static inline void zero_user_segments(struct page *page,
30213 unsigned start1, unsigned end1,
30214 unsigned start2, unsigned end2)
30215 diff -urNp linux-2.6.27.10/include/linux/jbd2.h linux-2.6.27.10/include/linux/jbd2.h
30216 --- linux-2.6.27.10/include/linux/jbd2.h 2008-12-10 22:35:38.000000000 -0500
30217 +++ linux-2.6.27.10/include/linux/jbd2.h 2008-12-10 22:35:46.000000000 -0500
30218 @@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
30222 -#define jbd_debug(f, a...) /**/
30223 +#define jbd_debug(f, a...) do {} while (0)
30226 static inline void *jbd2_alloc(size_t size, gfp_t flags)
30227 diff -urNp linux-2.6.27.10/include/linux/jbd.h linux-2.6.27.10/include/linux/jbd.h
30228 --- linux-2.6.27.10/include/linux/jbd.h 2008-12-21 01:16:52.000000000 -0500
30229 +++ linux-2.6.27.10/include/linux/jbd.h 2008-12-21 01:13:46.000000000 -0500
30230 @@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
30234 -#define jbd_debug(f, a...) /**/
30235 +#define jbd_debug(f, a...) do {} while (0)
30238 static inline void *jbd_alloc(size_t size, gfp_t flags)
30239 diff -urNp linux-2.6.27.10/include/linux/libata.h linux-2.6.27.10/include/linux/libata.h
30240 --- linux-2.6.27.10/include/linux/libata.h 2008-12-10 22:35:38.000000000 -0500
30241 +++ linux-2.6.27.10/include/linux/libata.h 2008-12-10 22:35:46.000000000 -0500
30242 @@ -64,11 +64,11 @@
30243 #ifdef ATA_VERBOSE_DEBUG
30244 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30246 -#define VPRINTK(fmt, args...)
30247 +#define VPRINTK(fmt, args...) do {} while (0)
30248 #endif /* ATA_VERBOSE_DEBUG */
30250 -#define DPRINTK(fmt, args...)
30251 -#define VPRINTK(fmt, args...)
30252 +#define DPRINTK(fmt, args...) do {} while (0)
30253 +#define VPRINTK(fmt, args...) do {} while (0)
30254 #endif /* ATA_DEBUG */
30256 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30257 diff -urNp linux-2.6.27.10/include/linux/mm.h linux-2.6.27.10/include/linux/mm.h
30258 --- linux-2.6.27.10/include/linux/mm.h 2008-11-07 12:55:34.000000000 -0500
30259 +++ linux-2.6.27.10/include/linux/mm.h 2008-12-21 00:44:29.000000000 -0500
30260 @@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
30261 #include <asm/page.h>
30262 #include <asm/pgtable.h>
30263 #include <asm/processor.h>
30264 +#include <asm/mman.h>
30266 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
30268 @@ -114,6 +115,10 @@ extern unsigned int kobjsize(const void
30269 #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
30270 #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
30272 +#ifdef CONFIG_PAX_PAGEEXEC
30273 +#define VM_PAGEEXEC 0x40000000 /* vma->vm_page_prot needs special handling */
30276 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
30277 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
30279 @@ -874,6 +879,8 @@ struct shrinker {
30280 extern void register_shrinker(struct shrinker *);
30281 extern void unregister_shrinker(struct shrinker *);
30283 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
30285 int vma_wants_writenotify(struct vm_area_struct *vma);
30287 extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
30288 @@ -1129,6 +1136,7 @@ out:
30291 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
30292 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
30294 extern unsigned long do_brk(unsigned long, unsigned long);
30296 @@ -1181,6 +1189,10 @@ extern struct vm_area_struct * find_vma(
30297 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
30298 struct vm_area_struct **pprev);
30300 +extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
30301 +extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
30302 +extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
30304 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
30305 NULL if none. Assume start_addr < end_addr. */
30306 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
30307 @@ -1197,7 +1209,6 @@ static inline unsigned long vma_pages(st
30308 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
30311 -pgprot_t vm_get_page_prot(unsigned long vm_flags);
30312 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
30313 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
30314 unsigned long pfn, unsigned long size, pgprot_t);
30315 @@ -1286,5 +1297,11 @@ int vmemmap_populate_basepages(struct pa
30316 int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
30317 void vmemmap_populate_print_last(void);
30319 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
30320 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
30322 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
30325 #endif /* __KERNEL__ */
30326 #endif /* _LINUX_MM_H */
30327 diff -urNp linux-2.6.27.10/include/linux/mm_types.h linux-2.6.27.10/include/linux/mm_types.h
30328 --- linux-2.6.27.10/include/linux/mm_types.h 2008-11-07 12:55:34.000000000 -0500
30329 +++ linux-2.6.27.10/include/linux/mm_types.h 2008-11-18 03:38:45.000000000 -0500
30330 @@ -158,6 +158,8 @@ struct vm_area_struct {
30332 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
30335 + struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
30338 struct core_thread {
30339 @@ -257,6 +259,24 @@ struct mm_struct {
30340 #ifdef CONFIG_MMU_NOTIFIER
30341 struct mmu_notifier_mm *mmu_notifier_mm;
30344 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30345 + unsigned long pax_flags;
30348 +#ifdef CONFIG_PAX_DLRESOLVE
30349 + unsigned long call_dl_resolve;
30352 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
30353 + unsigned long call_syscall;
30356 +#ifdef CONFIG_PAX_ASLR
30357 + unsigned long delta_mmap; /* randomized offset */
30358 + unsigned long delta_stack; /* randomized offset */
30363 #endif /* _LINUX_MM_TYPES_H */
30364 diff -urNp linux-2.6.27.10/include/linux/module.h linux-2.6.27.10/include/linux/module.h
30365 --- linux-2.6.27.10/include/linux/module.h 2008-11-07 12:55:34.000000000 -0500
30366 +++ linux-2.6.27.10/include/linux/module.h 2008-11-18 03:38:45.000000000 -0500
30367 @@ -282,16 +282,16 @@ struct module
30370 /* If this is non-NULL, vfree after init() returns */
30371 - void *module_init;
30372 + void *module_init_rx, *module_init_rw;
30374 /* Here is the actual code + data, vfree'd on unload. */
30375 - void *module_core;
30376 + void *module_core_rx, *module_core_rw;
30378 /* Here are the sizes of the init and core sections */
30379 - unsigned int init_size, core_size;
30380 + unsigned int init_size_rw, core_size_rw;
30382 /* The size of the executable code in each section. */
30383 - unsigned int init_text_size, core_text_size;
30384 + unsigned int init_size_rx, core_size_rx;
30386 /* The handle returned from unwind_add_table. */
30388 diff -urNp linux-2.6.27.10/include/linux/moduleloader.h linux-2.6.27.10/include/linux/moduleloader.h
30389 --- linux-2.6.27.10/include/linux/moduleloader.h 2008-11-07 12:55:34.000000000 -0500
30390 +++ linux-2.6.27.10/include/linux/moduleloader.h 2008-11-18 03:38:45.000000000 -0500
30391 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
30392 sections. Returns NULL on failure. */
30393 void *module_alloc(unsigned long size);
30395 +#ifdef CONFIG_PAX_KERNEXEC
30396 +void *module_alloc_exec(unsigned long size);
30398 +#define module_alloc_exec(x) module_alloc(x)
30401 /* Free memory returned from module_alloc. */
30402 void module_free(struct module *mod, void *module_region);
30404 +#ifdef CONFIG_PAX_KERNEXEC
30405 +void module_free_exec(struct module *mod, void *module_region);
30407 +#define module_free_exec(x, y) module_free(x, y)
30410 /* Apply the given relocation to the (simplified) ELF. Return -error
30412 int apply_relocate(Elf_Shdr *sechdrs,
30413 diff -urNp linux-2.6.27.10/include/linux/namei.h linux-2.6.27.10/include/linux/namei.h
30414 --- linux-2.6.27.10/include/linux/namei.h 2008-11-07 12:55:34.000000000 -0500
30415 +++ linux-2.6.27.10/include/linux/namei.h 2008-11-18 03:38:45.000000000 -0500
30416 @@ -21,7 +21,7 @@ struct nameidata {
30417 unsigned int flags;
30420 - char *saved_names[MAX_NESTED_LINKS + 1];
30421 + const char *saved_names[MAX_NESTED_LINKS + 1];
30425 @@ -80,12 +80,12 @@ extern int follow_up(struct vfsmount **,
30426 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
30427 extern void unlock_rename(struct dentry *, struct dentry *);
30429 -static inline void nd_set_link(struct nameidata *nd, char *path)
30430 +static inline void nd_set_link(struct nameidata *nd, const char *path)
30432 nd->saved_names[nd->depth] = path;
30435 -static inline char *nd_get_link(struct nameidata *nd)
30436 +static inline const char *nd_get_link(struct nameidata *nd)
30438 return nd->saved_names[nd->depth];
30440 diff -urNp linux-2.6.27.10/include/linux/nodemask.h linux-2.6.27.10/include/linux/nodemask.h
30441 --- linux-2.6.27.10/include/linux/nodemask.h 2008-11-07 12:55:34.000000000 -0500
30442 +++ linux-2.6.27.10/include/linux/nodemask.h 2008-11-18 03:38:45.000000000 -0500
30443 @@ -442,11 +442,11 @@ static inline int num_node_state(enum no
30445 #define any_online_node(mask) \
30448 - for_each_node_mask(node, (mask)) \
30449 - if (node_online(node)) \
30451 + for_each_node_mask(__node, (mask)) \
30452 + if (node_online(__node)) \
30458 #define num_online_nodes() num_node_state(N_ONLINE)
30459 diff -urNp linux-2.6.27.10/include/linux/percpu.h linux-2.6.27.10/include/linux/percpu.h
30460 --- linux-2.6.27.10/include/linux/percpu.h 2008-11-07 12:55:34.000000000 -0500
30461 +++ linux-2.6.27.10/include/linux/percpu.h 2008-11-18 03:38:45.000000000 -0500
30465 #define PERCPU_ENOUGH_ROOM \
30466 - (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
30467 + ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
30468 #endif /* PERCPU_ENOUGH_ROOM */
30471 diff -urNp linux-2.6.27.10/include/linux/poison.h linux-2.6.27.10/include/linux/poison.h
30472 --- linux-2.6.27.10/include/linux/poison.h 2008-11-07 12:55:34.000000000 -0500
30473 +++ linux-2.6.27.10/include/linux/poison.h 2008-11-18 03:38:45.000000000 -0500
30475 * under normal circumstances, used to verify that nobody uses
30476 * non-initialized list entries.
30478 -#define LIST_POISON1 ((void *) 0x00100100)
30479 -#define LIST_POISON2 ((void *) 0x00200200)
30480 +#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
30481 +#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
30483 /********** include/linux/timer.h **********/
30485 diff -urNp linux-2.6.27.10/include/linux/random.h linux-2.6.27.10/include/linux/random.h
30486 --- linux-2.6.27.10/include/linux/random.h 2008-11-07 12:55:34.000000000 -0500
30487 +++ linux-2.6.27.10/include/linux/random.h 2008-11-18 03:38:45.000000000 -0500
30488 @@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
30489 u32 random32(void);
30490 void srandom32(u32 seed);
30492 +static inline unsigned long pax_get_random_long(void)
30494 + return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
30497 #endif /* __KERNEL___ */
30499 #endif /* _LINUX_RANDOM_H */
30500 diff -urNp linux-2.6.27.10/include/linux/sched.h linux-2.6.27.10/include/linux/sched.h
30501 --- linux-2.6.27.10/include/linux/sched.h 2008-12-10 22:35:38.000000000 -0500
30502 +++ linux-2.6.27.10/include/linux/sched.h 2008-12-10 22:35:46.000000000 -0500
30503 @@ -96,6 +96,7 @@ struct exec_domain;
30504 struct futex_pi_state;
30505 struct robust_list_head;
30507 +struct linux_binprm;
30510 * List of flags we want to share for kernel threads,
30511 @@ -545,6 +546,15 @@ struct signal_struct {
30512 unsigned audit_tty;
30513 struct tty_audit_buf *tty_audit_buf;
30516 +#ifdef CONFIG_GRKERNSEC
30522 + u8 used_accept:1;
30526 /* Context switch must be unlocked if interrupts are to be enabled */
30527 @@ -1030,7 +1040,7 @@ struct sched_rt_entity {
30529 struct task_struct {
30530 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
30532 + struct thread_info *stack;
30534 unsigned int flags; /* per process flags, defined below */
30535 unsigned int ptrace;
30536 @@ -1095,10 +1105,9 @@ struct task_struct {
30540 -#ifdef CONFIG_CC_STACKPROTECTOR
30541 /* Canary value for the -fstack-protector gcc feature */
30542 unsigned long stack_canary;
30546 * pointers to (original) parent process, youngest child, younger sibling,
30547 * older sibling, respectively. (p->father can be replaced with
30548 @@ -1126,8 +1135,8 @@ struct task_struct {
30549 struct list_head thread_group;
30551 struct completion *vfork_done; /* for vfork() */
30552 - int __user *set_child_tid; /* CLONE_CHILD_SETTID */
30553 - int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30554 + pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
30555 + pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30557 cputime_t utime, stime, utimescaled, stimescaled;
30559 @@ -1307,8 +1316,64 @@ struct task_struct {
30560 int latency_record_count;
30561 struct latency_record latency_record[LT_SAVECOUNT];
30564 +#ifdef CONFIG_GRKERNSEC
30566 + struct acl_subject_label *acl;
30567 + struct acl_role_label *role;
30568 + struct file *exec_file;
30577 +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
30578 +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
30579 +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
30580 +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
30581 +/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
30582 +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
30584 +#ifdef CONFIG_PAX_SOFTMODE
30585 +extern unsigned int pax_softmode;
30588 +extern int pax_check_flags(unsigned long *);
30590 +/* if tsk != current then task_lock must be held on it */
30591 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30592 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
30594 + if (likely(tsk->mm))
30595 + return tsk->mm->pax_flags;
30600 +/* if tsk != current then task_lock must be held on it */
30601 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
30603 + if (likely(tsk->mm)) {
30604 + tsk->mm->pax_flags = flags;
30611 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
30612 +extern void pax_set_initial_flags(struct linux_binprm *bprm);
30613 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
30614 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
30617 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
30618 +void pax_report_insns(void *pc, void *sp);
30619 +void pax_report_refcount_overflow(struct pt_regs *regs);
30622 * Priority of a process goes from 0..MAX_PRIO-1, valid RT
30623 * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
30624 @@ -1849,7 +1914,7 @@ extern void __cleanup_sighand(struct sig
30625 extern void exit_itimers(struct signal_struct *);
30626 extern void flush_itimer_signals(void);
30628 -extern NORET_TYPE void do_group_exit(int);
30629 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
30631 extern void daemonize(const char *, ...);
30632 extern int allow_signal(int);
30633 @@ -1952,8 +2017,8 @@ static inline void unlock_task_sighand(s
30635 #ifndef __HAVE_THREAD_FUNCTIONS
30637 -#define task_thread_info(task) ((struct thread_info *)(task)->stack)
30638 -#define task_stack_page(task) ((task)->stack)
30639 +#define task_thread_info(task) ((task)->stack)
30640 +#define task_stack_page(task) ((void *)(task)->stack)
30642 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
30644 diff -urNp linux-2.6.27.10/include/linux/screen_info.h linux-2.6.27.10/include/linux/screen_info.h
30645 --- linux-2.6.27.10/include/linux/screen_info.h 2008-11-07 12:55:34.000000000 -0500
30646 +++ linux-2.6.27.10/include/linux/screen_info.h 2008-11-18 03:38:45.000000000 -0500
30647 @@ -42,7 +42,8 @@ struct screen_info {
30648 __u16 pages; /* 0x32 */
30649 __u16 vesa_attributes; /* 0x34 */
30650 __u32 capabilities; /* 0x36 */
30651 - __u8 _reserved[6]; /* 0x3a */
30652 + __u16 vesapm_size; /* 0x3a */
30653 + __u8 _reserved[4]; /* 0x3c */
30654 } __attribute__((packed));
30656 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
30657 diff -urNp linux-2.6.27.10/include/linux/shm.h linux-2.6.27.10/include/linux/shm.h
30658 --- linux-2.6.27.10/include/linux/shm.h 2008-11-07 12:55:34.000000000 -0500
30659 +++ linux-2.6.27.10/include/linux/shm.h 2008-11-18 03:38:45.000000000 -0500
30660 @@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
30663 struct user_struct *mlock_user;
30664 +#ifdef CONFIG_GRKERNSEC
30665 + time_t shm_createtime;
30670 /* shm_mode upper byte flags */
30671 diff -urNp linux-2.6.27.10/include/linux/slab.h linux-2.6.27.10/include/linux/slab.h
30672 --- linux-2.6.27.10/include/linux/slab.h 2008-11-07 12:55:34.000000000 -0500
30673 +++ linux-2.6.27.10/include/linux/slab.h 2008-11-18 03:38:45.000000000 -0500
30675 * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
30676 * Both make kfree a no-op.
30678 -#define ZERO_SIZE_PTR ((void *)16)
30679 +#define ZERO_SIZE_PTR ((void *)-1024L)
30681 -#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
30682 - (unsigned long)ZERO_SIZE_PTR)
30683 +#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
30686 * struct kmem_cache related prototypes
30687 diff -urNp linux-2.6.27.10/include/linux/sysctl.h linux-2.6.27.10/include/linux/sysctl.h
30688 --- linux-2.6.27.10/include/linux/sysctl.h 2008-11-07 12:55:34.000000000 -0500
30689 +++ linux-2.6.27.10/include/linux/sysctl.h 2008-11-18 03:38:45.000000000 -0500
30690 @@ -165,7 +165,11 @@ enum
30691 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
30695 +#ifdef CONFIG_PAX_SOFTMODE
30697 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
30701 /* CTL_VM names: */
30703 diff -urNp linux-2.6.27.10/include/linux/thread_info.h linux-2.6.27.10/include/linux/thread_info.h
30704 --- linux-2.6.27.10/include/linux/thread_info.h 2008-11-07 12:55:34.000000000 -0500
30705 +++ linux-2.6.27.10/include/linux/thread_info.h 2008-11-18 03:38:45.000000000 -0500
30706 @@ -23,7 +23,7 @@ struct restart_block {
30708 /* For futex_wait */
30711 + u32 __user *uaddr;
30715 diff -urNp linux-2.6.27.10/include/linux/uaccess.h linux-2.6.27.10/include/linux/uaccess.h
30716 --- linux-2.6.27.10/include/linux/uaccess.h 2008-11-07 12:55:34.000000000 -0500
30717 +++ linux-2.6.27.10/include/linux/uaccess.h 2008-11-18 03:38:45.000000000 -0500
30718 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
30720 mm_segment_t old_fs = get_fs(); \
30722 - set_fs(KERNEL_DS); \
30723 pagefault_disable(); \
30724 + set_fs(KERNEL_DS); \
30725 ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
30726 - pagefault_enable(); \
30728 + pagefault_enable(); \
30732 diff -urNp linux-2.6.27.10/include/linux/vmalloc.h linux-2.6.27.10/include/linux/vmalloc.h
30733 --- linux-2.6.27.10/include/linux/vmalloc.h 2008-11-07 12:55:34.000000000 -0500
30734 +++ linux-2.6.27.10/include/linux/vmalloc.h 2008-11-18 03:38:45.000000000 -0500
30735 @@ -12,6 +12,11 @@ struct vm_area_struct; /* vma defining
30736 #define VM_MAP 0x00000004 /* vmap()ed pages */
30737 #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
30738 #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
30740 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
30741 +#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
30744 /* bits [20..32] reserved for arch specific ioremap internals */
30747 diff -urNp linux-2.6.27.10/include/net/sctp/sctp.h linux-2.6.27.10/include/net/sctp/sctp.h
30748 --- linux-2.6.27.10/include/net/sctp/sctp.h 2008-11-07 12:55:34.000000000 -0500
30749 +++ linux-2.6.27.10/include/net/sctp/sctp.h 2008-11-18 03:38:45.000000000 -0500
30750 @@ -309,8 +309,8 @@ extern int sctp_debug_flag;
30752 #else /* SCTP_DEBUG */
30754 -#define SCTP_DEBUG_PRINTK(whatever...)
30755 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
30756 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
30757 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
30758 #define SCTP_ENABLE_DEBUG
30759 #define SCTP_DISABLE_DEBUG
30760 #define SCTP_ASSERT(expr, str, func)
30761 diff -urNp linux-2.6.27.10/include/sound/core.h linux-2.6.27.10/include/sound/core.h
30762 --- linux-2.6.27.10/include/sound/core.h 2008-11-07 12:55:34.000000000 -0500
30763 +++ linux-2.6.27.10/include/sound/core.h 2008-11-18 03:38:45.000000000 -0500
30764 @@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
30766 #else /* !CONFIG_SND_DEBUG */
30768 -#define snd_printd(fmt, args...) /* nothing */
30769 +#define snd_printd(fmt, args...) do {} while (0)
30770 #define snd_assert(expr, args...) (void)(expr)
30771 -#define snd_BUG() /* nothing */
30772 +#define snd_BUG() do {} while (0)
30774 #endif /* CONFIG_SND_DEBUG */
30776 @@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
30778 #define snd_printdd(format, args...) snd_printk(format, ##args)
30780 -#define snd_printdd(format, args...) /* nothing */
30781 +#define snd_printdd(format, args...) do {} while (0)
30785 diff -urNp linux-2.6.27.10/include/video/uvesafb.h linux-2.6.27.10/include/video/uvesafb.h
30786 --- linux-2.6.27.10/include/video/uvesafb.h 2008-11-07 12:55:34.000000000 -0500
30787 +++ linux-2.6.27.10/include/video/uvesafb.h 2008-11-18 03:38:45.000000000 -0500
30788 @@ -175,6 +175,7 @@ struct uvesafb_par {
30789 u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
30790 u8 pmi_setpal; /* PMI for palette changes */
30791 u16 *pmi_base; /* protected mode interface location */
30792 + u8 *pmi_code; /* protected mode code location */
30795 u8 *vbe_state_orig; /*
30796 diff -urNp linux-2.6.27.10/init/do_mounts.c linux-2.6.27.10/init/do_mounts.c
30797 --- linux-2.6.27.10/init/do_mounts.c 2008-11-07 12:55:34.000000000 -0500
30798 +++ linux-2.6.27.10/init/do_mounts.c 2008-11-18 03:38:45.000000000 -0500
30799 @@ -214,11 +214,11 @@ static void __init get_fs_names(char *pa
30801 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
30803 - int err = sys_mount(name, "/root", fs, flags, data);
30804 + int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
30808 - sys_chdir("/root");
30809 + sys_chdir((char __user *)"/root");
30810 ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
30811 printk("VFS: Mounted root (%s filesystem)%s.\n",
30812 current->fs->pwd.mnt->mnt_sb->s_type->name,
30813 @@ -304,18 +304,18 @@ void __init change_floppy(char *fmt, ...
30814 va_start(args, fmt);
30815 vsprintf(buf, fmt, args);
30817 - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
30818 + fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
30820 sys_ioctl(fd, FDEJECT, 0);
30823 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
30824 - fd = sys_open("/dev/console", O_RDWR, 0);
30825 + fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
30827 sys_ioctl(fd, TCGETS, (long)&termios);
30828 termios.c_lflag &= ~ICANON;
30829 sys_ioctl(fd, TCSETSF, (long)&termios);
30830 - sys_read(fd, &c, 1);
30831 + sys_read(fd, (char __user *)&c, 1);
30832 termios.c_lflag |= ICANON;
30833 sys_ioctl(fd, TCSETSF, (long)&termios);
30835 @@ -402,7 +402,7 @@ void __init prepare_namespace(void)
30839 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
30841 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
30842 + sys_chroot((char __user *)".");
30845 diff -urNp linux-2.6.27.10/init/do_mounts.h linux-2.6.27.10/init/do_mounts.h
30846 --- linux-2.6.27.10/init/do_mounts.h 2008-11-07 12:55:34.000000000 -0500
30847 +++ linux-2.6.27.10/init/do_mounts.h 2008-11-18 03:38:45.000000000 -0500
30848 @@ -14,15 +14,15 @@ extern int root_mountflags;
30850 static inline int create_dev(char *name, dev_t dev)
30852 - sys_unlink(name);
30853 - return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
30854 + sys_unlink((char __user *)name);
30855 + return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
30858 #if BITS_PER_LONG == 32
30859 static inline u32 bstat(char *name)
30861 struct stat64 stat;
30862 - if (sys_stat64(name, &stat) != 0)
30863 + if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
30865 if (!S_ISBLK(stat.st_mode))
30867 diff -urNp linux-2.6.27.10/init/do_mounts_initrd.c linux-2.6.27.10/init/do_mounts_initrd.c
30868 --- linux-2.6.27.10/init/do_mounts_initrd.c 2008-11-07 12:55:34.000000000 -0500
30869 +++ linux-2.6.27.10/init/do_mounts_initrd.c 2008-11-18 03:38:45.000000000 -0500
30870 @@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
30871 sys_close(old_fd);sys_close(root_fd);
30872 sys_close(0);sys_close(1);sys_close(2);
30874 - (void) sys_open("/dev/console",O_RDWR,0);
30875 + (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
30878 return kernel_execve(shell, argv, envp_init);
30879 @@ -47,13 +47,13 @@ static void __init handle_initrd(void)
30880 create_dev("/dev/root.old", Root_RAM0);
30881 /* mount initrd on rootfs' /root */
30882 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
30883 - sys_mkdir("/old", 0700);
30884 - root_fd = sys_open("/", 0, 0);
30885 - old_fd = sys_open("/old", 0, 0);
30886 + sys_mkdir((const char __user *)"/old", 0700);
30887 + root_fd = sys_open((const char __user *)"/", 0, 0);
30888 + old_fd = sys_open((const char __user *)"/old", 0, 0);
30889 /* move initrd over / and chdir/chroot in initrd root */
30890 - sys_chdir("/root");
30891 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
30893 + sys_chdir((const char __user *)"/root");
30894 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
30895 + sys_chroot((const char __user *)".");
30898 * In case that a resume from disk is carried out by linuxrc or one of
30899 @@ -70,15 +70,15 @@ static void __init handle_initrd(void)
30901 /* move initrd to rootfs' /old */
30902 sys_fchdir(old_fd);
30903 - sys_mount("/", ".", NULL, MS_MOVE, NULL);
30904 + sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
30905 /* switch root and cwd back to / of rootfs */
30906 sys_fchdir(root_fd);
30908 + sys_chroot((const char __user *)".");
30910 sys_close(root_fd);
30912 if (new_decode_dev(real_root_dev) == Root_RAM0) {
30913 - sys_chdir("/old");
30914 + sys_chdir((const char __user *)"/old");
30918 @@ -86,17 +86,17 @@ static void __init handle_initrd(void)
30921 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
30922 - error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
30923 + error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
30927 - int fd = sys_open("/dev/root.old", O_RDWR, 0);
30928 + int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
30929 if (error == -ENOENT)
30930 printk("/initrd does not exist. Ignored.\n");
30932 printk("failed\n");
30933 printk(KERN_NOTICE "Unmounting old root\n");
30934 - sys_umount("/old", MNT_DETACH);
30935 + sys_umount((char __user *)"/old", MNT_DETACH);
30936 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
30939 @@ -119,11 +119,11 @@ int __init initrd_load(void)
30940 * mounted in the normal path.
30942 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
30943 - sys_unlink("/initrd.image");
30944 + sys_unlink((const char __user *)"/initrd.image");
30949 - sys_unlink("/initrd.image");
30950 + sys_unlink((const char __user *)"/initrd.image");
30953 diff -urNp linux-2.6.27.10/init/do_mounts_md.c linux-2.6.27.10/init/do_mounts_md.c
30954 --- linux-2.6.27.10/init/do_mounts_md.c 2008-11-07 12:55:34.000000000 -0500
30955 +++ linux-2.6.27.10/init/do_mounts_md.c 2008-11-18 03:38:45.000000000 -0500
30956 @@ -166,7 +166,7 @@ static void __init md_setup_drive(void)
30957 partitioned ? "_d" : "", minor,
30958 md_setup_args[ent].device_names);
30960 - fd = sys_open(name, 0, 0);
30961 + fd = sys_open((char __user *)name, 0, 0);
30963 printk(KERN_ERR "md: open failed - cannot start "
30964 "array %s\n", name);
30965 @@ -229,7 +229,7 @@ static void __init md_setup_drive(void)
30969 - fd = sys_open(name, 0, 0);
30970 + fd = sys_open((char __user *)name, 0, 0);
30971 sys_ioctl(fd, BLKRRPART, 0);
30974 @@ -270,7 +270,7 @@ void __init md_run_setup(void)
30975 if (raid_noautodetect)
30976 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
30978 - int fd = sys_open("/dev/md0", 0, 0);
30979 + int fd = sys_open((char __user *)"/dev/md0", 0, 0);
30981 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
30983 diff -urNp linux-2.6.27.10/init/initramfs.c linux-2.6.27.10/init/initramfs.c
30984 --- linux-2.6.27.10/init/initramfs.c 2008-11-07 12:55:34.000000000 -0500
30985 +++ linux-2.6.27.10/init/initramfs.c 2008-11-18 03:38:45.000000000 -0500
30986 @@ -230,7 +230,7 @@ static int __init maybe_link(void)
30988 char *old = find_link(major, minor, ino, mode, collected);
30990 - return (sys_link(old, collected) < 0) ? -1 : 1;
30991 + return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
30995 @@ -239,11 +239,11 @@ static void __init clean_path(char *path
30999 - if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
31000 + if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
31001 if (S_ISDIR(st.st_mode))
31003 + sys_rmdir((char __user *)path);
31005 - sys_unlink(path);
31006 + sys_unlink((char __user *)path);
31010 @@ -266,7 +266,7 @@ static int __init do_name(void)
31011 int openflags = O_WRONLY|O_CREAT;
31013 openflags |= O_TRUNC;
31014 - wfd = sys_open(collected, openflags, mode);
31015 + wfd = sys_open((char __user *)collected, openflags, mode);
31018 sys_fchown(wfd, uid, gid);
31019 @@ -275,15 +275,15 @@ static int __init do_name(void)
31022 } else if (S_ISDIR(mode)) {
31023 - sys_mkdir(collected, mode);
31024 - sys_chown(collected, uid, gid);
31025 - sys_chmod(collected, mode);
31026 + sys_mkdir((char __user *)collected, mode);
31027 + sys_chown((char __user *)collected, uid, gid);
31028 + sys_chmod((char __user *)collected, mode);
31029 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
31030 S_ISFIFO(mode) || S_ISSOCK(mode)) {
31031 if (maybe_link() == 0) {
31032 - sys_mknod(collected, mode, rdev);
31033 - sys_chown(collected, uid, gid);
31034 - sys_chmod(collected, mode);
31035 + sys_mknod((char __user *)collected, mode, rdev);
31036 + sys_chown((char __user *)collected, uid, gid);
31037 + sys_chmod((char __user *)collected, mode);
31041 @@ -292,13 +292,13 @@ static int __init do_name(void)
31042 static int __init do_copy(void)
31044 if (count >= body_len) {
31045 - sys_write(wfd, victim, body_len);
31046 + sys_write(wfd, (char __user *)victim, body_len);
31052 - sys_write(wfd, victim, count);
31053 + sys_write(wfd, (char __user *)victim, count);
31057 @@ -309,8 +309,8 @@ static int __init do_symlink(void)
31059 collected[N_ALIGN(name_len) + body_len] = '\0';
31060 clean_path(collected, 0);
31061 - sys_symlink(collected + N_ALIGN(name_len), collected);
31062 - sys_lchown(collected, uid, gid);
31063 + sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
31064 + sys_lchown((char __user *)collected, uid, gid);
31066 next_state = Reset;
31068 diff -urNp linux-2.6.27.10/init/Kconfig linux-2.6.27.10/init/Kconfig
31069 --- linux-2.6.27.10/init/Kconfig 2008-11-07 12:55:34.000000000 -0500
31070 +++ linux-2.6.27.10/init/Kconfig 2008-11-18 03:38:45.000000000 -0500
31071 @@ -561,6 +561,7 @@ config SYSCTL_SYSCALL
31073 bool "Load all symbols for debugging/ksymoops" if EMBEDDED
31075 + depends on !GRKERNSEC_HIDESYM
31077 Say Y here to let the kernel print out symbolic crash information and
31078 symbolic stack backtraces. This increases the size of the kernel
31079 @@ -780,8 +781,8 @@ config MARKERS
31080 source "arch/Kconfig"
31082 config PROC_PAGE_MONITOR
31084 - depends on PROC_FS && MMU
31086 + depends on PROC_FS && MMU && !GRKERNSEC
31087 bool "Enable /proc page monitoring" if EMBEDDED
31089 Various /proc files exist to monitor process memory utilization:
31090 @@ -797,9 +798,9 @@ config HAVE_GENERIC_DMA_COHERENT
31094 - depends on PROC_FS
31095 + depends on PROC_FS && !GRKERNSEC_PROC_ADD
31096 depends on SLAB || SLUB_DEBUG
31102 diff -urNp linux-2.6.27.10/init/main.c linux-2.6.27.10/init/main.c
31103 --- linux-2.6.27.10/init/main.c 2008-11-07 12:55:34.000000000 -0500
31104 +++ linux-2.6.27.10/init/main.c 2008-11-18 03:38:45.000000000 -0500
31105 @@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void)
31107 extern void tc_init(void);
31109 +extern void grsecurity_init(void);
31111 enum system_states system_state;
31112 EXPORT_SYMBOL(system_state);
31113 @@ -187,6 +188,40 @@ static int __init set_reset_devices(char
31115 __setup("reset_devices", set_reset_devices);
31117 +#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
31118 +static int __init setup_pax_nouderef(char *str)
31120 + unsigned int cpu;
31122 +#ifdef CONFIG_PAX_KERNEXEC
31123 + unsigned long cr0;
31125 + pax_open_kernel(cr0);
31128 + for (cpu = 0; cpu < NR_CPUS; cpu++)
31129 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
31131 +#ifdef CONFIG_PAX_KERNEXEC
31132 + pax_close_kernel(cr0);
31137 +__setup("pax_nouderef", setup_pax_nouderef);
31140 +#ifdef CONFIG_PAX_SOFTMODE
31141 +unsigned int pax_softmode;
31143 +static int __init setup_pax_softmode(char *str)
31145 + get_option(&str, &pax_softmode);
31148 +__setup("pax_softmode=", setup_pax_softmode);
31151 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
31152 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
31153 static const char *panic_later, *panic_param;
31154 @@ -385,7 +420,7 @@ static void __init setup_nr_cpu_ids(void
31157 #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
31158 -unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
31159 +unsigned long __per_cpu_offset[NR_CPUS] __read_only;
31161 EXPORT_SYMBOL(__per_cpu_offset);
31163 @@ -704,6 +739,7 @@ int do_one_initcall(initcall_t fn)
31165 int count = preempt_count();
31166 ktime_t t0, t1, delta;
31167 + const char *msg1 = "", *msg2 = "";
31171 @@ -729,15 +765,15 @@ int do_one_initcall(initcall_t fn)
31172 sprintf(msgbuf, "error code %d ", result);
31174 if (preempt_count() != count) {
31175 - strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
31176 + msg1 = " preemption imbalance";
31177 preempt_count() = count;
31179 if (irqs_disabled()) {
31180 - strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
31181 + msg2 = " disabled interrupts";
31182 local_irq_enable();
31185 - printk("initcall %pF returned with %s\n", fn, msgbuf);
31186 + if (msgbuf[0] || *msg1 || *msg2) {
31187 + printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
31191 @@ -876,6 +912,8 @@ static int __init kernel_init(void * unu
31192 prepare_namespace();
31195 + grsecurity_init();
31198 * Ok, we have completed the initial bootup, and
31199 * we're essentially up and running. Get rid of the
31200 diff -urNp linux-2.6.27.10/init/noinitramfs.c linux-2.6.27.10/init/noinitramfs.c
31201 --- linux-2.6.27.10/init/noinitramfs.c 2008-11-07 12:55:34.000000000 -0500
31202 +++ linux-2.6.27.10/init/noinitramfs.c 2008-11-18 03:38:45.000000000 -0500
31203 @@ -29,7 +29,7 @@ static int __init default_rootfs(void)
31207 - err = sys_mkdir("/dev", 0755);
31208 + err = sys_mkdir((const char __user *)"/dev", 0755);
31212 @@ -39,7 +39,7 @@ static int __init default_rootfs(void)
31216 - err = sys_mkdir("/root", 0700);
31217 + err = sys_mkdir((const char __user *)"/root", 0700);
31221 diff -urNp linux-2.6.27.10/ipc/ipc_sysctl.c linux-2.6.27.10/ipc/ipc_sysctl.c
31222 --- linux-2.6.27.10/ipc/ipc_sysctl.c 2008-11-07 12:55:34.000000000 -0500
31223 +++ linux-2.6.27.10/ipc/ipc_sysctl.c 2008-11-18 03:38:45.000000000 -0500
31224 @@ -268,7 +268,7 @@ static struct ctl_table ipc_kern_table[]
31229 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31232 static struct ctl_table ipc_root_table[] = {
31233 @@ -278,7 +278,7 @@ static struct ctl_table ipc_root_table[]
31235 .child = ipc_kern_table,
31238 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31241 static int __init ipc_sysctl_init(void)
31242 diff -urNp linux-2.6.27.10/ipc/msg.c linux-2.6.27.10/ipc/msg.c
31243 --- linux-2.6.27.10/ipc/msg.c 2008-11-07 12:55:34.000000000 -0500
31244 +++ linux-2.6.27.10/ipc/msg.c 2008-11-18 03:38:45.000000000 -0500
31246 #include <linux/nsproxy.h>
31247 #include <linux/ipc_namespace.h>
31248 #include <linux/vs_base.h>
31249 +#include <linux/grsecurity.h>
31251 #include <asm/current.h>
31252 #include <asm/uaccess.h>
31253 @@ -314,6 +315,7 @@ asmlinkage long sys_msgget(key_t key, in
31254 struct ipc_namespace *ns;
31255 struct ipc_ops msg_ops;
31256 struct ipc_params msg_params;
31259 ns = current->nsproxy->ipc_ns;
31261 @@ -324,7 +326,11 @@ asmlinkage long sys_msgget(key_t key, in
31262 msg_params.key = key;
31263 msg_params.flg = msgflg;
31265 - return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31266 + err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31268 + gr_log_msgget(err, msgflg);
31273 static inline unsigned long
31274 @@ -434,6 +440,7 @@ static int msgctl_down(struct ipc_namesp
31278 + gr_log_msgrm(ipcp->uid, ipcp->cuid);
31282 diff -urNp linux-2.6.27.10/ipc/sem.c linux-2.6.27.10/ipc/sem.c
31283 --- linux-2.6.27.10/ipc/sem.c 2008-11-07 12:55:34.000000000 -0500
31284 +++ linux-2.6.27.10/ipc/sem.c 2008-11-18 03:38:45.000000000 -0500
31286 #include <linux/ipc_namespace.h>
31287 #include <linux/vs_base.h>
31288 #include <linux/vs_limit.h>
31289 +#include <linux/grsecurity.h>
31291 #include <asm/uaccess.h>
31293 @@ -313,6 +314,7 @@ asmlinkage long sys_semget(key_t key, in
31294 struct ipc_namespace *ns;
31295 struct ipc_ops sem_ops;
31296 struct ipc_params sem_params;
31299 ns = current->nsproxy->ipc_ns;
31301 @@ -327,7 +329,11 @@ asmlinkage long sys_semget(key_t key, in
31302 sem_params.flg = semflg;
31303 sem_params.u.nsems = nsems;
31305 - return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31306 + err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31308 + gr_log_semget(err, semflg);
31314 @@ -870,6 +876,7 @@ static int semctl_down(struct ipc_namesp
31318 + gr_log_semrm(ipcp->uid, ipcp->cuid);
31322 diff -urNp linux-2.6.27.10/ipc/shm.c linux-2.6.27.10/ipc/shm.c
31323 --- linux-2.6.27.10/ipc/shm.c 2008-11-07 12:55:34.000000000 -0500
31324 +++ linux-2.6.27.10/ipc/shm.c 2008-11-18 03:38:45.000000000 -0500
31326 #include <linux/ipc_namespace.h>
31327 #include <linux/vs_context.h>
31328 #include <linux/vs_limit.h>
31329 +#include <linux/grsecurity.h>
31331 #include <asm/uaccess.h>
31333 @@ -69,6 +70,14 @@ static void shm_destroy (struct ipc_name
31334 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
31337 +#ifdef CONFIG_GRKERNSEC
31338 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31339 + const time_t shm_createtime, const uid_t cuid,
31340 + const int shmid);
31341 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31342 + const time_t shm_createtime);
31345 void shm_init_ns(struct ipc_namespace *ns)
31347 ns->shm_ctlmax = SHMMAX;
31348 @@ -87,6 +96,8 @@ static void do_shm_rmid(struct ipc_names
31349 struct shmid_kernel *shp;
31350 shp = container_of(ipcp, struct shmid_kernel, shm_perm);
31352 + gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
31354 if (shp->shm_nattch){
31355 shp->shm_perm.mode |= SHM_DEST;
31356 /* Do not find it any more */
31357 @@ -392,6 +403,14 @@ static int newseg(struct ipc_namespace *
31358 shp->shm_lprid = 0;
31359 shp->shm_atim = shp->shm_dtim = 0;
31360 shp->shm_ctim = get_seconds();
31361 +#ifdef CONFIG_GRKERNSEC
31363 + struct timespec timeval;
31364 + do_posix_clock_monotonic_gettime(&timeval);
31366 + shp->shm_createtime = timeval.tv_sec;
31369 shp->shm_segsz = size;
31370 shp->shm_nattch = 0;
31371 shp->shm_file = file;
31372 @@ -445,6 +464,7 @@ asmlinkage long sys_shmget (key_t key, s
31373 struct ipc_namespace *ns;
31374 struct ipc_ops shm_ops;
31375 struct ipc_params shm_params;
31378 ns = current->nsproxy->ipc_ns;
31380 @@ -456,7 +476,11 @@ asmlinkage long sys_shmget (key_t key, s
31381 shm_params.flg = shmflg;
31382 shm_params.u.size = size;
31384 - return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31385 + err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31387 + gr_log_shmget(err, shmflg, size);
31392 static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
31393 @@ -869,9 +893,21 @@ long do_shmat(int shmid, char __user *sh
31397 +#ifdef CONFIG_GRKERNSEC
31398 + if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
31399 + shp->shm_perm.cuid, shmid) ||
31400 + !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
31406 path.dentry = dget(shp->shm_file->f_path.dentry);
31407 path.mnt = shp->shm_file->f_path.mnt;
31409 +#ifdef CONFIG_GRKERNSEC
31410 + shp->shm_lapid = current->pid;
31412 size = i_size_read(path.dentry->d_inode);
31415 diff -urNp linux-2.6.27.10/kernel/acct.c linux-2.6.27.10/kernel/acct.c
31416 --- linux-2.6.27.10/kernel/acct.c 2008-11-07 12:55:34.000000000 -0500
31417 +++ linux-2.6.27.10/kernel/acct.c 2008-11-18 03:38:45.000000000 -0500
31418 @@ -573,7 +573,7 @@ static void do_acct_process(struct bsd_a
31420 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
31421 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
31422 - file->f_op->write(file, (char *)&ac,
31423 + file->f_op->write(file, (char __user *)&ac,
31424 sizeof(acct_t), &file->f_pos);
31425 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
31427 diff -urNp linux-2.6.27.10/kernel/capability.c linux-2.6.27.10/kernel/capability.c
31428 --- linux-2.6.27.10/kernel/capability.c 2008-11-07 12:55:34.000000000 -0500
31429 +++ linux-2.6.27.10/kernel/capability.c 2008-11-18 03:38:45.000000000 -0500
31431 #include <linux/syscalls.h>
31432 #include <linux/pid_namespace.h>
31433 #include <linux/vs_context.h>
31434 +#include <linux/grsecurity.h>
31435 #include <asm/uaccess.h>
31438 @@ -498,10 +499,21 @@ asmlinkage long sys_capset(cap_user_head
31439 /* here for now so we don't require task locking */
31440 if (vs_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap))
31442 - if (has_capability(current, cap)) {
31443 + if (has_capability(current, cap) && gr_task_is_capable(current, cap)) {
31444 current->flags |= PF_SUPERPRIV;
31450 +int capable_nolog(int cap)
31452 + if (has_capability(current, cap) && gr_is_capable_nolog(cap)) {
31453 + current->flags |= PF_SUPERPRIV;
31459 EXPORT_SYMBOL(capable);
31460 +EXPORT_SYMBOL(capable_nolog);
31461 diff -urNp linux-2.6.27.10/kernel/configs.c linux-2.6.27.10/kernel/configs.c
31462 --- linux-2.6.27.10/kernel/configs.c 2008-11-07 12:55:34.000000000 -0500
31463 +++ linux-2.6.27.10/kernel/configs.c 2008-11-18 03:38:45.000000000 -0500
31464 @@ -79,8 +79,19 @@ static int __init ikconfig_init(void)
31465 struct proc_dir_entry *entry;
31467 /* create the current config file */
31468 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
31469 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31470 + entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
31471 + &ikconfig_file_ops);
31472 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31473 + entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
31474 + &ikconfig_file_ops);
31477 entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
31478 &ikconfig_file_ops);
31484 diff -urNp linux-2.6.27.10/kernel/cpu.c linux-2.6.27.10/kernel/cpu.c
31485 --- linux-2.6.27.10/kernel/cpu.c 2008-11-07 12:55:34.000000000 -0500
31486 +++ linux-2.6.27.10/kernel/cpu.c 2008-11-18 03:38:45.000000000 -0500
31487 @@ -40,7 +40,7 @@ EXPORT_SYMBOL(cpu_possible_map);
31488 /* Serializes the updates to cpu_online_map, cpu_present_map */
31489 static DEFINE_MUTEX(cpu_add_remove_lock);
31491 -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
31492 +static RAW_NOTIFIER_HEAD(cpu_chain);
31494 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
31495 * Should always be manipulated under cpu_add_remove_lock
31496 diff -urNp linux-2.6.27.10/kernel/exit.c linux-2.6.27.10/kernel/exit.c
31497 --- linux-2.6.27.10/kernel/exit.c 2008-11-07 12:55:34.000000000 -0500
31498 +++ linux-2.6.27.10/kernel/exit.c 2008-11-29 19:01:27.000000000 -0500
31500 #include <linux/cn_proc.h>
31501 #include <linux/mutex.h>
31502 #include <linux/futex.h>
31503 -#include <linux/compat.h>
31504 #include <linux/pipe_fs_i.h>
31505 #include <linux/audit.h> /* for audit_free() */
31506 #include <linux/resource.h>
31508 #include <linux/vs_network.h>
31509 #include <linux/vs_pid.h>
31510 #include <linux/vserver/global.h>
31511 +#include <linux/grsecurity.h>
31513 +#ifdef CONFIG_GRKERNSEC
31514 +extern rwlock_t grsec_exec_file_lock;
31517 #include <asm/uaccess.h>
31518 #include <asm/unistd.h>
31519 @@ -133,7 +137,6 @@ static void __exit_signal(struct task_st
31520 * doing sigqueue_free() if we have SIGQUEUE_PREALLOC signals.
31522 flush_sigqueue(&tsk->pending);
31524 tsk->signal = NULL;
31525 tsk->sighand = NULL;
31526 spin_unlock(&sighand->siglock);
31527 @@ -158,6 +161,8 @@ void release_task(struct task_struct * p
31528 struct task_struct *leader;
31531 + gr_del_task_from_ip_table(p);
31533 tracehook_prepare_release_task(p);
31534 atomic_dec(&p->user->processes);
31535 proc_flush_task(p);
31536 @@ -321,11 +326,22 @@ static void reparent_to_kthreadd(void)
31538 write_lock_irq(&tasklist_lock);
31540 +#ifdef CONFIG_GRKERNSEC
31541 + write_lock(&grsec_exec_file_lock);
31542 + if (current->exec_file) {
31543 + fput(current->exec_file);
31544 + current->exec_file = NULL;
31546 + write_unlock(&grsec_exec_file_lock);
31549 ptrace_unlink(current);
31550 /* Reparent to init */
31551 current->real_parent = current->parent = kthreadd_task;
31552 list_move_tail(¤t->sibling, ¤t->real_parent->children);
31554 + gr_set_kernel_label(current);
31556 /* Set the exit signal to SIGCHLD so we signal init on exit */
31557 current->exit_signal = SIGCHLD;
31559 @@ -419,6 +435,17 @@ void daemonize(const char *name, ...)
31560 vsnprintf(current->comm, sizeof(current->comm), name, args);
31563 +#ifdef CONFIG_GRKERNSEC
31564 + write_lock(&grsec_exec_file_lock);
31565 + if (current->exec_file) {
31566 + fput(current->exec_file);
31567 + current->exec_file = NULL;
31569 + write_unlock(&grsec_exec_file_lock);
31572 + gr_set_kernel_label(current);
31575 * If we were started as result of loading a module, close all of the
31576 * user space pages. We don't need them, and if we didn't close them
31577 @@ -1054,14 +1081,6 @@ NORET_TYPE void do_exit(long code)
31578 exit_itimers(tsk->signal);
31580 acct_collect(code, group_dead);
31581 -#ifdef CONFIG_FUTEX
31582 - if (unlikely(tsk->robust_list))
31583 - exit_robust_list(tsk);
31584 -#ifdef CONFIG_COMPAT
31585 - if (unlikely(tsk->compat_robust_list))
31586 - compat_exit_robust_list(tsk);
31591 if (unlikely(tsk->audit_context))
31592 @@ -1070,6 +1089,9 @@ NORET_TYPE void do_exit(long code)
31593 tsk->exit_code = code;
31594 taskstats_exit(tsk, group_dead);
31596 + gr_acl_handle_psacct(tsk, code);
31597 + gr_acl_handle_exit();
31602 @@ -1272,7 +1294,7 @@ static int wait_task_zombie(struct task_
31603 if (unlikely(options & WNOWAIT)) {
31604 uid_t uid = p->uid;
31605 int exit_code = p->exit_code;
31609 get_task_struct(p);
31610 read_unlock(&tasklist_lock);
31611 diff -urNp linux-2.6.27.10/kernel/fork.c linux-2.6.27.10/kernel/fork.c
31612 --- linux-2.6.27.10/kernel/fork.c 2008-12-21 01:16:52.000000000 -0500
31613 +++ linux-2.6.27.10/kernel/fork.c 2008-12-21 01:13:46.000000000 -0500
31615 #include <linux/jiffies.h>
31616 #include <linux/tracehook.h>
31617 #include <linux/futex.h>
31618 +#include <linux/compat.h>
31619 #include <linux/task_io_accounting_ops.h>
31620 #include <linux/rcupdate.h>
31621 #include <linux/ptrace.h>
31623 #include <linux/vs_limit.h>
31624 #include <linux/vs_memory.h>
31625 #include <linux/vserver/global.h>
31626 +#include <linux/grsecurity.h>
31628 #include <asm/pgtable.h>
31629 #include <asm/pgalloc.h>
31630 @@ -234,7 +236,7 @@ static struct task_struct *dup_task_stru
31631 setup_thread_stack(tsk, orig);
31633 #ifdef CONFIG_CC_STACKPROTECTOR
31634 - tsk->stack_canary = get_random_int();
31635 + tsk->stack_canary = pax_get_random_long();
31638 /* One for us, one for whoever does the "release_task()" (usually parent) */
31639 @@ -271,8 +273,8 @@ static int dup_mmap(struct mm_struct *mm
31642 mm->mmap_cache = NULL;
31643 - mm->free_area_cache = oldmm->mmap_base;
31644 - mm->cached_hole_size = ~0UL;
31645 + mm->free_area_cache = oldmm->free_area_cache;
31646 + mm->cached_hole_size = oldmm->cached_hole_size;
31648 cpus_clear(mm->cpu_vm_mask);
31649 mm->mm_rb = RB_ROOT;
31650 @@ -309,6 +311,7 @@ static int dup_mmap(struct mm_struct *mm
31651 tmp->vm_flags &= ~VM_LOCKED;
31653 tmp->vm_next = NULL;
31654 + tmp->vm_mirror = NULL;
31655 anon_vma_link(tmp);
31656 file = tmp->vm_file;
31658 @@ -356,6 +359,31 @@ static int dup_mmap(struct mm_struct *mm
31663 +#ifdef CONFIG_PAX_SEGMEXEC
31664 + if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
31665 + struct vm_area_struct *mpnt_m;
31667 + for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
31668 + BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
31670 + if (!mpnt->vm_mirror)
31673 + if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
31674 + BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
31675 + mpnt->vm_mirror = mpnt_m;
31677 + BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
31678 + mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
31679 + mpnt_m->vm_mirror->vm_mirror = mpnt_m;
31680 + mpnt->vm_mirror->vm_mirror = mpnt;
31687 /* a new mm has just been created */
31688 arch_dup_mmap(oldmm, mm);
31690 @@ -521,6 +549,18 @@ void mm_release(struct task_struct *tsk,
31692 struct completion *vfork_done = tsk->vfork_done;
31694 + /* Get rid of any futexes when releasing the mm */
31695 +#ifdef CONFIG_FUTEX
31696 + if (unlikely(tsk->robust_list))
31697 + exit_robust_list(tsk);
31698 + tsk->robust_list = NULL;
31699 +#ifdef CONFIG_COMPAT
31700 + if (unlikely(tsk->compat_robust_list))
31701 + compat_exit_robust_list(tsk);
31702 + tsk->compat_robust_list = NULL;
31706 /* Get rid of any cached register state */
31707 deactivate_mm(tsk, mm);
31709 @@ -539,7 +579,7 @@ void mm_release(struct task_struct *tsk,
31710 if (tsk->clear_child_tid
31711 && !(tsk->flags & PF_SIGNALED)
31712 && atomic_read(&mm->mm_users) > 1) {
31713 - u32 __user * tidptr = tsk->clear_child_tid;
31714 + pid_t __user * tidptr = tsk->clear_child_tid;
31715 tsk->clear_child_tid = NULL;
31718 @@ -547,7 +587,7 @@ void mm_release(struct task_struct *tsk,
31719 * not set up a proper pointer then tough luck.
31721 put_user(0, tidptr);
31722 - sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31723 + sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31727 @@ -942,6 +982,9 @@ static struct task_struct *copy_process(
31728 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
31732 + gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
31734 if (!vx_nproc_avail(1))
31735 goto bad_fork_cleanup_vm;
31736 if (atomic_read(&p->user->processes) >=
31737 @@ -1108,6 +1151,8 @@ static struct task_struct *copy_process(
31738 goto bad_fork_free_pid;
31741 + gr_copy_label(p);
31743 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
31745 * Clear TID on mm_release()?
31746 @@ -1293,6 +1338,8 @@ bad_fork_cleanup_count:
31750 + gr_log_forkfail(retval);
31752 return ERR_PTR(retval);
31755 @@ -1369,6 +1416,8 @@ long do_fork(unsigned long clone_flags,
31756 if (clone_flags & CLONE_PARENT_SETTID)
31757 put_user(nr, parent_tidptr);
31759 + gr_handle_brute_check();
31761 if (clone_flags & CLONE_VFORK) {
31762 p->vfork_done = &vfork;
31763 init_completion(&vfork);
31764 diff -urNp linux-2.6.27.10/kernel/futex.c linux-2.6.27.10/kernel/futex.c
31765 --- linux-2.6.27.10/kernel/futex.c 2008-11-07 12:55:34.000000000 -0500
31766 +++ linux-2.6.27.10/kernel/futex.c 2008-11-18 03:38:45.000000000 -0500
31767 @@ -188,6 +188,11 @@ static int get_futex_key(u32 __user *uad
31771 +#ifdef CONFIG_PAX_SEGMEXEC
31772 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
31777 * The futex address must be "naturally" aligned.
31779 @@ -214,8 +219,8 @@ static int get_futex_key(u32 __user *uad
31780 * The futex is hashed differently depending on whether
31781 * it's in a shared or private mapping. So check vma first.
31783 - vma = find_extend_vma(mm, address);
31784 - if (unlikely(!vma))
31785 + vma = find_vma(mm, address);
31786 + if (unlikely(!vma || address < vma->vm_start))
31790 @@ -1345,7 +1350,7 @@ static int futex_wait(u32 __user *uaddr,
31791 struct restart_block *restart;
31792 restart = ¤t_thread_info()->restart_block;
31793 restart->fn = futex_wait_restart;
31794 - restart->futex.uaddr = (u32 *)uaddr;
31795 + restart->futex.uaddr = uaddr;
31796 restart->futex.val = val;
31797 restart->futex.time = abs_time->tv64;
31798 restart->futex.bitset = bitset;
31799 @@ -1906,7 +1911,7 @@ retry:
31801 static inline int fetch_robust_entry(struct robust_list __user **entry,
31802 struct robust_list __user * __user *head,
31804 + unsigned int *pi)
31806 unsigned long uentry;
31808 diff -urNp linux-2.6.27.10/kernel/irq/handle.c linux-2.6.27.10/kernel/irq/handle.c
31809 --- linux-2.6.27.10/kernel/irq/handle.c 2008-11-07 12:55:34.000000000 -0500
31810 +++ linux-2.6.27.10/kernel/irq/handle.c 2008-11-18 03:38:45.000000000 -0500
31811 @@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
31813 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
31815 - .affinity = CPU_MASK_ALL
31816 + .affinity = CPU_MASK_ALL,
31821 diff -urNp linux-2.6.27.10/kernel/kallsyms.c linux-2.6.27.10/kernel/kallsyms.c
31822 --- linux-2.6.27.10/kernel/kallsyms.c 2008-11-07 12:55:34.000000000 -0500
31823 +++ linux-2.6.27.10/kernel/kallsyms.c 2008-11-18 03:38:45.000000000 -0500
31824 @@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
31826 static inline int is_kernel(unsigned long addr)
31829 +#ifdef CONFIG_PAX_KERNEXEC
31831 +#ifdef CONFIG_MODULES
31832 + if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
31833 + ktla_ktva(addr) < (unsigned long)MODULES_END)
31837 + if (is_kernel_inittext(addr))
31841 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
31843 return in_gate_area_no_task(addr);
31844 @@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
31846 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
31848 - iter->name[0] = '\0';
31849 iter->nameoff = get_symbol_offset(new_pos);
31850 iter->pos = new_pos;
31852 @@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
31853 struct kallsym_iter *iter;
31856 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
31857 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
31860 reset_iter(iter, 0);
31861 @@ -472,7 +484,15 @@ static const struct file_operations kall
31863 static int __init kallsyms_init(void)
31865 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
31866 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31867 + proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
31868 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31869 + proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
31872 proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
31876 __initcall(kallsyms_init);
31877 diff -urNp linux-2.6.27.10/kernel/kmod.c linux-2.6.27.10/kernel/kmod.c
31878 --- linux-2.6.27.10/kernel/kmod.c 2008-11-07 12:55:34.000000000 -0500
31879 +++ linux-2.6.27.10/kernel/kmod.c 2008-11-18 03:38:45.000000000 -0500
31880 @@ -108,7 +108,7 @@ int request_module(const char *fmt, ...)
31884 - ret = call_usermodehelper(modprobe_path, argv, envp, 1);
31885 + ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
31886 atomic_dec(&kmod_concurrent);
31889 diff -urNp linux-2.6.27.10/kernel/kprobes.c linux-2.6.27.10/kernel/kprobes.c
31890 --- linux-2.6.27.10/kernel/kprobes.c 2008-11-07 12:55:34.000000000 -0500
31891 +++ linux-2.6.27.10/kernel/kprobes.c 2008-11-18 03:38:45.000000000 -0500
31892 @@ -182,7 +182,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
31893 * kernel image and loaded module images reside. This is required
31894 * so x86_64 can correctly handle the %rip-relative fixups.
31896 - kip->insns = module_alloc(PAGE_SIZE);
31897 + kip->insns = module_alloc_exec(PAGE_SIZE);
31901 @@ -214,7 +214,7 @@ static int __kprobes collect_one_slot(st
31902 hlist_add_head(&kip->hlist,
31903 &kprobe_insn_pages);
31905 - module_free(NULL, kip->insns);
31906 + module_free_exec(NULL, kip->insns);
31910 diff -urNp linux-2.6.27.10/kernel/lockdep.c linux-2.6.27.10/kernel/lockdep.c
31911 --- linux-2.6.27.10/kernel/lockdep.c 2008-11-07 12:55:34.000000000 -0500
31912 +++ linux-2.6.27.10/kernel/lockdep.c 2008-11-18 03:38:45.000000000 -0500
31913 @@ -627,6 +627,10 @@ static int static_obj(void *obj)
31917 +#ifdef CONFIG_PAX_KERNEXEC
31918 + start = (unsigned long )&_data;
31924 @@ -638,9 +642,12 @@ static int static_obj(void *obj)
31927 for_each_possible_cpu(i) {
31928 +#ifdef CONFIG_X86_32
31929 + start = per_cpu_offset(i);
31931 start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
31932 - end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
31933 - + per_cpu_offset(i);
31935 + end = start + PERCPU_ENOUGH_ROOM;
31937 if ((addr >= start) && (addr < end))
31939 diff -urNp linux-2.6.27.10/kernel/module.c linux-2.6.27.10/kernel/module.c
31940 --- linux-2.6.27.10/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
31941 +++ linux-2.6.27.10/kernel/module.c 2008-12-21 01:17:47.000000000 -0500
31943 #include <linux/unwind.h>
31944 #include <asm/uaccess.h>
31945 #include <asm/cacheflush.h>
31947 +#ifdef CONFIG_PAX_KERNEXEC
31948 +#include <asm/desc.h>
31951 #include <linux/license.h>
31952 #include <asm/sections.h>
31954 @@ -71,7 +76,10 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
31955 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
31957 /* Bounds of module allocation, for speeding __module_text_address */
31958 -static unsigned long module_addr_min = -1UL, module_addr_max = 0;
31959 +static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
31960 +static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
31962 +extern int gr_check_modstop(void);
31964 int register_module_notifier(struct notifier_block * nb)
31966 @@ -217,7 +225,7 @@ static bool each_symbol(bool (*fn)(const
31969 list_for_each_entry(mod, &modules, list) {
31970 - struct symsearch arr[] = {
31971 + struct symsearch modarr[] = {
31972 { mod->syms, mod->syms + mod->num_syms, mod->crcs,
31973 NOT_GPL_ONLY, false },
31974 { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
31975 @@ -239,7 +247,7 @@ static bool each_symbol(bool (*fn)(const
31979 - if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
31980 + if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
31984 @@ -375,6 +383,8 @@ static inline unsigned int block_size(in
31988 +EXPORT_SYMBOL(__per_cpu_start);
31990 static void *percpu_modalloc(unsigned long size, unsigned long align,
31993 @@ -382,7 +392,7 @@ static void *percpu_modalloc(unsigned lo
31997 - if (align > PAGE_SIZE) {
31998 + if (align-1 >= PAGE_SIZE) {
31999 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
32000 name, align, PAGE_SIZE);
32002 @@ -464,7 +474,11 @@ static void percpu_modcopy(void *pcpudes
32005 for_each_possible_cpu(cpu)
32006 +#ifdef CONFIG_X86_32
32007 + memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
32009 memcpy(pcpudest + per_cpu_offset(cpu), from, size);
32013 static int percpu_modinit(void)
32014 @@ -722,6 +736,9 @@ sys_delete_module(const char __user *nam
32015 char name[MODULE_NAME_LEN];
32016 int ret, forced = 0;
32018 + if (gr_check_modstop())
32021 if (!capable(CAP_SYS_MODULE))
32024 @@ -1430,16 +1447,19 @@ static void free_module(struct module *m
32025 module_unload_free(mod);
32027 /* This may be NULL, but that's OK */
32028 - module_free(mod, mod->module_init);
32029 + module_free(mod, mod->module_init_rw);
32030 + module_free_exec(mod, mod->module_init_rx);
32033 percpu_modfree(mod->percpu);
32035 /* Free lock-classes: */
32036 - lockdep_free_key_range(mod->module_core, mod->core_size);
32037 + lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
32038 + lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
32040 /* Finally, free the core (containing the module structure) */
32041 - module_free(mod, mod->module_core);
32042 + module_free_exec(mod, mod->module_core_rx);
32043 + module_free(mod, mod->module_core_rw);
32046 void *__symbol_get(const char *symbol)
32047 @@ -1505,10 +1525,14 @@ static int simplify_symbols(Elf_Shdr *se
32048 struct module *mod)
32050 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
32051 - unsigned long secbase;
32052 + unsigned long secbase, symbol;
32053 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32056 +#ifdef CONFIG_PAX_KERNEXEC
32057 + unsigned long cr0;
32060 for (i = 1; i < n; i++) {
32061 switch (sym[i].st_shndx) {
32063 @@ -1527,10 +1551,19 @@ static int simplify_symbols(Elf_Shdr *se
32068 - = resolve_symbol(sechdrs, versindex,
32069 + symbol = resolve_symbol(sechdrs, versindex,
32070 strtab + sym[i].st_name, mod);
32072 +#ifdef CONFIG_PAX_KERNEXEC
32073 + pax_open_kernel(cr0);
32076 + sym[i].st_value = symbol;
32078 +#ifdef CONFIG_PAX_KERNEXEC
32079 + pax_close_kernel(cr0);
32082 /* Ok if resolved. */
32083 if (!IS_ERR_VALUE(sym[i].st_value))
32085 @@ -1545,11 +1578,27 @@ static int simplify_symbols(Elf_Shdr *se
32088 /* Divert to percpu allocation if a percpu var. */
32089 - if (sym[i].st_shndx == pcpuindex)
32090 + if (sym[i].st_shndx == pcpuindex) {
32092 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
32093 + secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
32095 secbase = (unsigned long)mod->percpu;
32100 secbase = sechdrs[sym[i].st_shndx].sh_addr;
32102 +#ifdef CONFIG_PAX_KERNEXEC
32103 + pax_open_kernel(cr0);
32106 sym[i].st_value += secbase;
32108 +#ifdef CONFIG_PAX_KERNEXEC
32109 + pax_close_kernel(cr0);
32115 @@ -1601,11 +1650,12 @@ static void layout_sections(struct modul
32116 || strncmp(secstrings + s->sh_name,
32119 - s->sh_entsize = get_offset(&mod->core_size, s);
32120 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32121 + s->sh_entsize = get_offset(&mod->core_size_rw, s);
32123 + s->sh_entsize = get_offset(&mod->core_size_rx, s);
32124 DEBUGP("\t%s\n", secstrings + s->sh_name);
32127 - mod->core_text_size = mod->core_size;
32130 DEBUGP("Init section allocation order:\n");
32131 @@ -1619,12 +1669,13 @@ static void layout_sections(struct modul
32132 || strncmp(secstrings + s->sh_name,
32135 - s->sh_entsize = (get_offset(&mod->init_size, s)
32136 - | INIT_OFFSET_MASK);
32137 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32138 + s->sh_entsize = get_offset(&mod->init_size_rw, s);
32140 + s->sh_entsize = get_offset(&mod->init_size_rx, s);
32141 + s->sh_entsize |= INIT_OFFSET_MASK;
32142 DEBUGP("\t%s\n", secstrings + s->sh_name);
32145 - mod->init_text_size = mod->init_size;
32149 @@ -1764,14 +1815,31 @@ static void add_kallsyms(struct module *
32153 +#ifdef CONFIG_PAX_KERNEXEC
32154 + unsigned long cr0;
32157 mod->symtab = (void *)sechdrs[symindex].sh_addr;
32158 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32159 mod->strtab = (void *)sechdrs[strindex].sh_addr;
32161 /* Set types up while we still have access to sections. */
32162 - for (i = 0; i < mod->num_symtab; i++)
32163 - mod->symtab[i].st_info
32164 - = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32166 + for (i = 0; i < mod->num_symtab; i++) {
32167 + char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32169 +#ifdef CONFIG_PAX_KERNEXEC
32170 + pax_open_kernel(cr0);
32173 + mod->symtab[i].st_info = type;
32175 +#ifdef CONFIG_PAX_KERNEXEC
32176 + pax_close_kernel(cr0);
32183 static inline void add_kallsyms(struct module *mod,
32184 @@ -1783,16 +1851,30 @@ static inline void add_kallsyms(struct m
32186 #endif /* CONFIG_KALLSYMS */
32188 -static void *module_alloc_update_bounds(unsigned long size)
32189 +static void *module_alloc_update_bounds_rw(unsigned long size)
32191 void *ret = module_alloc(size);
32194 /* Update module bounds. */
32195 - if ((unsigned long)ret < module_addr_min)
32196 - module_addr_min = (unsigned long)ret;
32197 - if ((unsigned long)ret + size > module_addr_max)
32198 - module_addr_max = (unsigned long)ret + size;
32199 + if ((unsigned long)ret < module_addr_min_rw)
32200 + module_addr_min_rw = (unsigned long)ret;
32201 + if ((unsigned long)ret + size > module_addr_max_rw)
32202 + module_addr_max_rw = (unsigned long)ret + size;
32207 +static void *module_alloc_update_bounds_rx(unsigned long size)
32209 + void *ret = module_alloc_exec(size);
32212 + /* Update module bounds. */
32213 + if ((unsigned long)ret < module_addr_min_rx)
32214 + module_addr_min_rx = (unsigned long)ret;
32215 + if ((unsigned long)ret + size > module_addr_max_rx)
32216 + module_addr_max_rx = (unsigned long)ret + size;
32220 @@ -1837,6 +1919,10 @@ static noinline struct module *load_modu
32221 struct exception_table_entry *extable;
32222 mm_segment_t old_fs;
32224 +#ifdef CONFIG_PAX_KERNEXEC
32225 + unsigned long cr0;
32228 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
32230 if (len < sizeof(*hdr))
32231 @@ -1998,22 +2084,57 @@ static noinline struct module *load_modu
32232 layout_sections(mod, hdr, sechdrs, secstrings);
32234 /* Do the allocs. */
32235 - ptr = module_alloc_update_bounds(mod->core_size);
32236 + ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
32241 - memset(ptr, 0, mod->core_size);
32242 - mod->module_core = ptr;
32243 + memset(ptr, 0, mod->core_size_rw);
32244 + mod->module_core_rw = ptr;
32246 + ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
32247 + if (!ptr && mod->init_size_rw) {
32249 + goto free_core_rw;
32251 + memset(ptr, 0, mod->init_size_rw);
32252 + mod->module_init_rw = ptr;
32254 + ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
32257 + goto free_init_rw;
32260 +#ifdef CONFIG_PAX_KERNEXEC
32261 + pax_open_kernel(cr0);
32264 + memset(ptr, 0, mod->core_size_rx);
32266 - ptr = module_alloc_update_bounds(mod->init_size);
32267 - if (!ptr && mod->init_size) {
32268 +#ifdef CONFIG_PAX_KERNEXEC
32269 + pax_close_kernel(cr0);
32272 + mod->module_core_rx = ptr;
32274 + ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
32275 + if (!ptr && mod->init_size_rx) {
32278 + goto free_core_rx;
32280 - memset(ptr, 0, mod->init_size);
32281 - mod->module_init = ptr;
32283 +#ifdef CONFIG_PAX_KERNEXEC
32284 + pax_open_kernel(cr0);
32287 + memset(ptr, 0, mod->init_size_rx);
32289 +#ifdef CONFIG_PAX_KERNEXEC
32290 + pax_close_kernel(cr0);
32293 + mod->module_init_rx = ptr;
32294 /* Transfer each section which specifies SHF_ALLOC */
32295 DEBUGP("final section addresses:\n");
32296 for (i = 0; i < hdr->e_shnum; i++) {
32297 @@ -2022,17 +2143,41 @@ static noinline struct module *load_modu
32298 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
32301 - if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
32302 - dest = mod->module_init
32303 - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32305 - dest = mod->module_core + sechdrs[i].sh_entsize;
32306 + if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
32307 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32308 + dest = mod->module_init_rw
32309 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32311 + dest = mod->module_init_rx
32312 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32314 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32315 + dest = mod->module_core_rw + sechdrs[i].sh_entsize;
32317 + dest = mod->module_core_rx + sechdrs[i].sh_entsize;
32320 - if (sechdrs[i].sh_type != SHT_NOBITS)
32321 - memcpy(dest, (void *)sechdrs[i].sh_addr,
32322 - sechdrs[i].sh_size);
32323 + if (sechdrs[i].sh_type != SHT_NOBITS) {
32325 +#ifdef CONFIG_PAX_KERNEXEC
32326 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
32327 + pax_open_kernel(cr0);
32328 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32329 + pax_close_kernel(cr0);
32333 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32335 /* Update sh_addr to point to copy in image. */
32336 - sechdrs[i].sh_addr = (unsigned long)dest;
32338 +#ifdef CONFIG_PAX_KERNEXEC
32339 + if (sechdrs[i].sh_flags & SHF_EXECINSTR)
32340 + sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
32344 + sechdrs[i].sh_addr = (unsigned long)dest;
32345 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
32347 /* Module has been moved. */
32348 @@ -2120,8 +2265,8 @@ static noinline struct module *load_modu
32350 /* Now do relocations. */
32351 for (i = 1; i < hdr->e_shnum; i++) {
32352 - const char *strtab = (char *)sechdrs[strindex].sh_addr;
32353 unsigned int info = sechdrs[i].sh_info;
32354 + strtab = (char *)sechdrs[strindex].sh_addr;
32356 /* Not a valid relocation section? */
32357 if (info >= hdr->e_shnum)
32358 @@ -2180,12 +2325,12 @@ static noinline struct module *load_modu
32359 * Do it before processing of module parameters, so the module
32360 * can provide parameter accessor functions of its own.
32362 - if (mod->module_init)
32363 - flush_icache_range((unsigned long)mod->module_init,
32364 - (unsigned long)mod->module_init
32365 - + mod->init_size);
32366 - flush_icache_range((unsigned long)mod->module_core,
32367 - (unsigned long)mod->module_core + mod->core_size);
32368 + if (mod->module_init_rx)
32369 + flush_icache_range((unsigned long)mod->module_init_rx,
32370 + (unsigned long)mod->module_init_rx
32371 + + mod->init_size_rx);
32372 + flush_icache_range((unsigned long)mod->module_core_rx,
32373 + (unsigned long)mod->module_core_rx + mod->core_size_rx);
32377 @@ -2238,9 +2383,13 @@ static noinline struct module *load_modu
32378 kobject_put(&mod->mkobj.kobj);
32380 module_unload_free(mod);
32381 - module_free(mod, mod->module_init);
32383 - module_free(mod, mod->module_core);
32384 + module_free_exec(mod, mod->module_init_rx);
32386 + module_free_exec(mod, mod->module_core_rx);
32388 + module_free(mod, mod->module_init_rw);
32390 + module_free(mod, mod->module_core_rw);
32393 percpu_modfree(percpu);
32394 @@ -2265,6 +2414,9 @@ sys_init_module(void __user *umod,
32395 struct module *mod;
32398 + if (gr_check_modstop())
32401 /* Must have permission */
32402 if (!capable(CAP_SYS_MODULE))
32404 @@ -2320,10 +2472,12 @@ sys_init_module(void __user *umod,
32405 /* Drop initial reference. */
32407 unwind_remove_table(mod->unwind_info, 1);
32408 - module_free(mod, mod->module_init);
32409 - mod->module_init = NULL;
32410 - mod->init_size = 0;
32411 - mod->init_text_size = 0;
32412 + module_free(mod, mod->module_init_rw);
32413 + module_free_exec(mod, mod->module_init_rx);
32414 + mod->module_init_rw = NULL;
32415 + mod->module_init_rx = NULL;
32416 + mod->init_size_rw = 0;
32417 + mod->init_size_rx = 0;
32418 mutex_unlock(&module_mutex);
32421 @@ -2331,6 +2485,13 @@ sys_init_module(void __user *umod,
32423 static inline int within(unsigned long addr, void *start, unsigned long size)
32426 +#ifdef CONFIG_PAX_KERNEXEC
32427 + if (ktla_ktva(addr) >= (unsigned long)start &&
32428 + ktla_ktva(addr) < (unsigned long)start + size)
32432 return ((void *)addr >= start && (void *)addr < start + size);
32435 @@ -2354,10 +2515,14 @@ static const char *get_ksymbol(struct mo
32436 unsigned long nextval;
32438 /* At worse, next value is at end of module */
32439 - if (within(addr, mod->module_init, mod->init_size))
32440 - nextval = (unsigned long)mod->module_init+mod->init_text_size;
32441 + if (within(addr, mod->module_init_rx, mod->init_size_rx))
32442 + nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
32443 + else if (within(addr, mod->module_init_rw, mod->init_size_rw))
32444 + nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
32445 + else if (within(addr, mod->module_core_rx, mod->core_size_rx))
32446 + nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
32448 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
32449 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
32451 /* Scan for closest preceeding symbol, and next symbol. (ELF
32452 starts real symbols at 1). */
32453 @@ -2402,8 +2567,10 @@ const char *module_address_lookup(unsign
32456 list_for_each_entry(mod, &modules, list) {
32457 - if (within(addr, mod->module_init, mod->init_size)
32458 - || within(addr, mod->module_core, mod->core_size)) {
32459 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32460 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
32461 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
32462 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
32464 *modname = mod->name;
32465 ret = get_ksymbol(mod, addr, size, offset);
32466 @@ -2425,8 +2592,10 @@ int lookup_module_symbol_name(unsigned l
32469 list_for_each_entry(mod, &modules, list) {
32470 - if (within(addr, mod->module_init, mod->init_size) ||
32471 - within(addr, mod->module_core, mod->core_size)) {
32472 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32473 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
32474 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
32475 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
32478 sym = get_ksymbol(mod, addr, NULL, NULL);
32479 @@ -2449,8 +2618,10 @@ int lookup_module_symbol_attrs(unsigned
32482 list_for_each_entry(mod, &modules, list) {
32483 - if (within(addr, mod->module_init, mod->init_size) ||
32484 - within(addr, mod->module_core, mod->core_size)) {
32485 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32486 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
32487 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
32488 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
32491 sym = get_ksymbol(mod, addr, size, offset);
32492 @@ -2581,7 +2752,7 @@ static int m_show(struct seq_file *m, vo
32495 seq_printf(m, "%s %u",
32496 - mod->name, mod->init_size + mod->core_size);
32497 + mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
32498 print_unload_info(m, mod);
32500 /* Informative for users. */
32501 @@ -2590,7 +2761,7 @@ static int m_show(struct seq_file *m, vo
32502 mod->state == MODULE_STATE_COMING ? "Loading":
32504 /* Used by oprofile and other similar tools. */
32505 - seq_printf(m, " 0x%p", mod->module_core);
32506 + seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
32510 @@ -2646,7 +2817,8 @@ int is_module_address(unsigned long addr
32513 list_for_each_entry(mod, &modules, list) {
32514 - if (within(addr, mod->module_core, mod->core_size)) {
32515 + if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
32516 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
32520 @@ -2663,12 +2835,16 @@ struct module *__module_text_address(uns
32522 struct module *mod;
32524 - if (addr < module_addr_min || addr > module_addr_max)
32525 +#ifdef CONFIG_X86_32
32526 + addr = ktla_ktva(addr);
32529 + if (addr < module_addr_min_rx || addr > module_addr_max_rx)
32532 list_for_each_entry(mod, &modules, list)
32533 - if (within(addr, mod->module_init, mod->init_text_size)
32534 - || within(addr, mod->module_core, mod->core_text_size))
32535 + if (within(addr, mod->module_init_rx, mod->init_size_rx)
32536 + || within(addr, mod->module_core_rx, mod->core_size_rx))
32540 diff -urNp linux-2.6.27.10/kernel/mutex.c linux-2.6.27.10/kernel/mutex.c
32541 --- linux-2.6.27.10/kernel/mutex.c 2008-11-07 12:55:34.000000000 -0500
32542 +++ linux-2.6.27.10/kernel/mutex.c 2008-11-18 03:38:45.000000000 -0500
32543 @@ -83,7 +83,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
32545 * This function is similar to (but not equivalent to) down().
32547 -void inline __sched mutex_lock(struct mutex *lock)
32548 +inline void __sched mutex_lock(struct mutex *lock)
32552 diff -urNp linux-2.6.27.10/kernel/panic.c linux-2.6.27.10/kernel/panic.c
32553 --- linux-2.6.27.10/kernel/panic.c 2008-11-07 12:55:34.000000000 -0500
32554 +++ linux-2.6.27.10/kernel/panic.c 2008-11-18 03:38:45.000000000 -0500
32555 @@ -349,6 +349,8 @@ EXPORT_SYMBOL(warn_slowpath);
32557 void __stack_chk_fail(void)
32559 + print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
32561 panic("stack-protector: Kernel stack is corrupted");
32563 EXPORT_SYMBOL(__stack_chk_fail);
32564 diff -urNp linux-2.6.27.10/kernel/pid.c linux-2.6.27.10/kernel/pid.c
32565 --- linux-2.6.27.10/kernel/pid.c 2008-11-07 12:55:34.000000000 -0500
32566 +++ linux-2.6.27.10/kernel/pid.c 2008-11-18 03:38:45.000000000 -0500
32568 #include <linux/syscalls.h>
32569 #include <linux/vs_pid.h>
32570 #include <linux/vserver/global.h>
32571 +#include <linux/grsecurity.h>
32573 #define pid_hashfn(nr, ns) \
32574 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
32575 @@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
32577 int pid_max = PID_MAX_DEFAULT;
32579 -#define RESERVED_PIDS 300
32580 +#define RESERVED_PIDS 500
32582 int pid_max_min = RESERVED_PIDS + 1;
32583 int pid_max_max = PID_MAX_LIMIT;
32584 @@ -381,7 +382,14 @@ EXPORT_SYMBOL(pid_task);
32585 struct task_struct *find_task_by_pid_type_ns(int type, int nr,
32586 struct pid_namespace *ns)
32588 - return pid_task(find_pid_ns(nr, ns), type);
32589 + struct task_struct *task;
32591 + task = pid_task(find_pid_ns(nr, ns), type);
32593 + if (gr_pid_is_chrooted(task))
32599 EXPORT_SYMBOL(find_task_by_pid_type_ns);
32600 diff -urNp linux-2.6.27.10/kernel/posix-cpu-timers.c linux-2.6.27.10/kernel/posix-cpu-timers.c
32601 --- linux-2.6.27.10/kernel/posix-cpu-timers.c 2008-11-07 12:55:34.000000000 -0500
32602 +++ linux-2.6.27.10/kernel/posix-cpu-timers.c 2008-11-18 03:38:45.000000000 -0500
32604 #include <linux/posix-timers.h>
32605 #include <linux/errno.h>
32606 #include <linux/math64.h>
32607 +#include <linux/grsecurity.h>
32608 #include <asm/uaccess.h>
32610 static int check_clock(const clockid_t which_clock)
32611 @@ -1176,6 +1177,7 @@ static void check_process_timers(struct
32612 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
32615 + gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
32616 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
32618 * At the soft limit, send a SIGXCPU every second.
32619 @@ -1370,17 +1372,17 @@ void run_posix_cpu_timers(struct task_st
32620 * timer call will interfere.
32622 list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
32625 spin_lock(&timer->it_lock);
32626 list_del_init(&timer->it.cpu.entry);
32627 - firing = timer->it.cpu.firing;
32628 + __firing = timer->it.cpu.firing;
32629 timer->it.cpu.firing = 0;
32631 * The firing flag is -1 if we collided with a reset
32632 * of the timer, which already reported this
32633 * almost-firing as an overrun. So don't generate an event.
32635 - if (likely(firing >= 0)) {
32636 + if (likely(__firing >= 0)) {
32637 cpu_timer_fire(timer);
32639 spin_unlock(&timer->it_lock);
32640 diff -urNp linux-2.6.27.10/kernel/power/poweroff.c linux-2.6.27.10/kernel/power/poweroff.c
32641 --- linux-2.6.27.10/kernel/power/poweroff.c 2008-11-07 12:55:34.000000000 -0500
32642 +++ linux-2.6.27.10/kernel/power/poweroff.c 2008-11-18 03:38:45.000000000 -0500
32643 @@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
32644 .enable_mask = SYSRQ_ENABLE_BOOT,
32647 -static int pm_sysrq_init(void)
32648 +static int __init pm_sysrq_init(void)
32650 register_sysrq_key('o', &sysrq_poweroff_op);
32652 diff -urNp linux-2.6.27.10/kernel/printk.c linux-2.6.27.10/kernel/printk.c
32653 --- linux-2.6.27.10/kernel/printk.c 2008-11-07 12:55:34.000000000 -0500
32654 +++ linux-2.6.27.10/kernel/printk.c 2008-11-18 03:38:45.000000000 -0500
32656 #include <linux/bootmem.h>
32657 #include <linux/syscalls.h>
32658 #include <linux/vs_cvirt.h>
32659 +#include <linux/grsecurity.h>
32661 #include <asm/uaccess.h>
32663 @@ -293,6 +294,11 @@ int do_syslog(int type, char __user *buf
32667 +#ifdef CONFIG_GRKERNSEC_DMESG
32668 + if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
32672 error = security_syslog(type);
32675 diff -urNp linux-2.6.27.10/kernel/ptrace.c linux-2.6.27.10/kernel/ptrace.c
32676 --- linux-2.6.27.10/kernel/ptrace.c 2008-11-07 12:55:34.000000000 -0500
32677 +++ linux-2.6.27.10/kernel/ptrace.c 2008-11-18 03:38:45.000000000 -0500
32679 #include <linux/pid_namespace.h>
32680 #include <linux/syscalls.h>
32681 #include <linux/vs_context.h>
32682 +#include <linux/grsecurity.h>
32684 #include <asm/pgtable.h>
32685 #include <asm/uaccess.h>
32686 @@ -132,12 +133,12 @@ int __ptrace_may_access(struct task_stru
32687 (current->uid != task->uid) ||
32688 (current->gid != task->egid) ||
32689 (current->gid != task->sgid) ||
32690 - (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
32691 + (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
32695 dumpable = get_dumpable(task->mm);
32696 - if (!dumpable && !capable(CAP_SYS_PTRACE))
32697 + if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
32700 return security_ptrace_may_access(task, mode);
32701 @@ -193,7 +194,7 @@ repeat:
32704 task->ptrace |= PT_PTRACED;
32705 - if (capable(CAP_SYS_PTRACE))
32706 + if (capable_nolog(CAP_SYS_PTRACE))
32707 task->ptrace |= PT_PTRACE_CAP;
32709 __ptrace_link(task, current);
32710 @@ -582,6 +583,11 @@ asmlinkage long sys_ptrace(long request,
32712 goto out_put_task_struct;
32714 + if (gr_handle_ptrace(child, request)) {
32716 + goto out_put_task_struct;
32719 ret = arch_ptrace(child, request, addr, data);
32721 goto out_put_task_struct;
32722 diff -urNp linux-2.6.27.10/kernel/relay.c linux-2.6.27.10/kernel/relay.c
32723 --- linux-2.6.27.10/kernel/relay.c 2008-11-07 12:55:34.000000000 -0500
32724 +++ linux-2.6.27.10/kernel/relay.c 2008-11-18 03:38:45.000000000 -0500
32725 @@ -1291,7 +1291,7 @@ static int subbuf_splice_actor(struct fi
32728 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
32729 - if (ret < 0 || ret < total_len)
32730 + if ((int)ret < 0 || ret < total_len)
32733 if (read_start + ret == nonpad_end)
32734 diff -urNp linux-2.6.27.10/kernel/resource.c linux-2.6.27.10/kernel/resource.c
32735 --- linux-2.6.27.10/kernel/resource.c 2008-11-07 12:55:34.000000000 -0500
32736 +++ linux-2.6.27.10/kernel/resource.c 2008-11-18 03:38:45.000000000 -0500
32737 @@ -131,8 +131,18 @@ static const struct file_operations proc
32739 static int __init ioresources_init(void)
32741 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
32742 +#ifdef CONFIG_GRKERNSEC_PROC_USER
32743 + proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
32744 + proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
32745 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
32746 + proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
32747 + proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
32750 proc_create("ioports", 0, NULL, &proc_ioports_operations);
32751 proc_create("iomem", 0, NULL, &proc_iomem_operations);
32755 __initcall(ioresources_init);
32756 diff -urNp linux-2.6.27.10/kernel/sched.c linux-2.6.27.10/kernel/sched.c
32757 --- linux-2.6.27.10/kernel/sched.c 2008-12-21 01:16:52.000000000 -0500
32758 +++ linux-2.6.27.10/kernel/sched.c 2008-12-21 01:13:46.000000000 -0500
32760 #include <linux/ftrace.h>
32761 #include <linux/vs_sched.h>
32762 #include <linux/vs_cvirt.h>
32763 +#include <linux/grsecurity.h>
32765 #include <asm/tlb.h>
32766 #include <asm/irq_regs.h>
32767 @@ -4962,7 +4963,8 @@ asmlinkage long sys_nice(int increment)
32771 - if (increment < 0 && !can_nice(current, nice))
32772 + if (increment < 0 && (!can_nice(current, nice) ||
32773 + gr_handle_chroot_nice()))
32774 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
32776 retval = security_task_setnice(current, nice);
32777 @@ -6225,7 +6227,7 @@ static struct ctl_table sd_ctl_dir[] = {
32778 .procname = "sched_domain",
32782 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32785 static struct ctl_table sd_ctl_root[] = {
32786 @@ -6235,7 +6237,7 @@ static struct ctl_table sd_ctl_root[] =
32788 .child = sd_ctl_dir,
32791 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32794 static struct ctl_table *sd_alloc_ctl_entry(int n)
32795 diff -urNp linux-2.6.27.10/kernel/signal.c linux-2.6.27.10/kernel/signal.c
32796 --- linux-2.6.27.10/kernel/signal.c 2008-11-07 12:55:34.000000000 -0500
32797 +++ linux-2.6.27.10/kernel/signal.c 2008-11-18 03:38:45.000000000 -0500
32799 #include <linux/capability.h>
32800 #include <linux/freezer.h>
32801 #include <linux/pid_namespace.h>
32802 +#include <linux/grsecurity.h>
32803 #include <linux/nsproxy.h>
32804 #include <linux/vs_context.h>
32805 #include <linux/vs_pid.h>
32806 @@ -595,6 +596,9 @@ static int check_kill_permission(int sig
32810 + if (gr_handle_signal(t, sig))
32813 return security_task_kill(t, info, sig, 0);
32816 @@ -884,8 +888,8 @@ static void print_fatal_signal(struct pt
32817 for (i = 0; i < 16; i++) {
32818 unsigned char insn;
32820 - __get_user(insn, (unsigned char *)(regs->ip + i));
32821 - printk("%02x ", insn);
32822 + if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
32823 + printk("%02x ", insn);
32827 @@ -908,7 +912,7 @@ __group_send_sig_info(int sig, struct si
32828 return send_signal(sig, info, p, 1);
32833 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
32835 return send_signal(sig, info, t, 0);
32836 @@ -946,8 +950,12 @@ force_sig_info(int sig, struct siginfo *
32837 if (action->sa.sa_handler == SIG_DFL)
32838 t->signal->flags &= ~SIGNAL_UNKILLABLE;
32839 ret = specific_send_sig_info(sig, info, t);
32841 spin_unlock_irqrestore(&t->sighand->siglock, flags);
32843 + gr_log_signal(sig, t);
32844 + gr_handle_crash(t, sig);
32849 @@ -1018,6 +1026,8 @@ int group_send_sig_info(int sig, struct
32850 ret = __group_send_sig_info(sig, info, p);
32851 unlock_task_sighand(p, &flags);
32854 + gr_log_signal(sig, p);
32858 diff -urNp linux-2.6.27.10/kernel/softirq.c linux-2.6.27.10/kernel/softirq.c
32859 --- linux-2.6.27.10/kernel/softirq.c 2008-11-07 12:55:34.000000000 -0500
32860 +++ linux-2.6.27.10/kernel/softirq.c 2008-11-18 03:38:45.000000000 -0500
32861 @@ -453,9 +453,9 @@ void tasklet_kill(struct tasklet_struct
32862 printk("Attempt to kill tasklet from interrupt\n");
32864 while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
32868 - while (test_bit(TASKLET_STATE_SCHED, &t->state));
32869 + } while (test_bit(TASKLET_STATE_SCHED, &t->state));
32871 tasklet_unlock_wait(t);
32872 clear_bit(TASKLET_STATE_SCHED, &t->state);
32873 diff -urNp linux-2.6.27.10/kernel/sys.c linux-2.6.27.10/kernel/sys.c
32874 --- linux-2.6.27.10/kernel/sys.c 2008-11-07 12:55:34.000000000 -0500
32875 +++ linux-2.6.27.10/kernel/sys.c 2008-11-18 03:38:45.000000000 -0500
32877 #include <linux/task_io_accounting_ops.h>
32878 #include <linux/seccomp.h>
32879 #include <linux/cpu.h>
32880 +#include <linux/grsecurity.h>
32882 #include <linux/compat.h>
32883 #include <linux/syscalls.h>
32884 @@ -125,6 +126,12 @@ static int set_one_prio(struct task_stru
32889 + if (gr_handle_chroot_setpriority(p, niceval)) {
32894 no_nice = security_task_setnice(p, niceval);
32897 @@ -181,10 +188,10 @@ asmlinkage long sys_setpriority(int whic
32898 if ((who != current->uid) && !(user = find_user(who)))
32899 goto out_unlock; /* No processes for this user */
32901 - do_each_thread(g, p)
32902 + do_each_thread(g, p) {
32904 error = set_one_prio(p, niceval, error);
32905 - while_each_thread(g, p);
32906 + } while_each_thread(g, p);
32907 if (who != current->uid)
32908 free_uid(user); /* For find_user() */
32910 @@ -243,13 +250,13 @@ asmlinkage long sys_getpriority(int whic
32911 if ((who != current->uid) && !(user = find_user(who)))
32912 goto out_unlock; /* No processes for this user */
32914 - do_each_thread(g, p)
32915 + do_each_thread(g, p) {
32916 if (p->uid == who) {
32917 niceval = 20 - task_nice(p);
32918 if (niceval > retval)
32921 - while_each_thread(g, p);
32922 + } while_each_thread(g, p);
32923 if (who != current->uid)
32924 free_uid(user); /* for find_user() */
32926 @@ -499,6 +506,10 @@ asmlinkage long sys_setregid(gid_t rgid,
32931 + if (gr_check_group_change(new_rgid, new_egid, -1))
32934 if (new_egid != old_egid) {
32935 set_dumpable(current->mm, suid_dumpable);
32937 @@ -506,6 +517,9 @@ asmlinkage long sys_setregid(gid_t rgid,
32938 if (rgid != (gid_t) -1 ||
32939 (egid != (gid_t) -1 && egid != old_rgid))
32940 current->sgid = new_egid;
32942 + gr_set_role_label(current, current->uid, new_rgid);
32944 current->fsgid = new_egid;
32945 current->egid = new_egid;
32946 current->gid = new_rgid;
32947 @@ -528,11 +542,17 @@ asmlinkage long sys_setgid(gid_t gid)
32951 + if (gr_check_group_change(gid, gid, gid))
32954 if (capable(CAP_SETGID)) {
32955 if (old_egid != gid) {
32956 set_dumpable(current->mm, suid_dumpable);
32960 + gr_set_role_label(current, current->uid, gid);
32962 current->gid = current->egid = current->sgid = current->fsgid = gid;
32963 } else if ((gid == current->gid) || (gid == current->sgid)) {
32964 if (old_egid != gid) {
32965 @@ -570,6 +590,9 @@ static int set_user(uid_t new_ruid, int
32966 set_dumpable(current->mm, suid_dumpable);
32970 + gr_set_role_label(current, new_ruid, current->gid);
32972 current->uid = new_ruid;
32975 @@ -619,6 +642,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
32979 + if (gr_check_user_change(new_ruid, new_euid, -1))
32982 if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
32985 @@ -665,6 +691,12 @@ asmlinkage long sys_setuid(uid_t uid)
32986 old_suid = current->suid;
32987 new_suid = old_suid;
32989 + if (gr_check_crash_uid(uid))
32992 + if (gr_check_user_change(uid, uid, uid))
32995 if (capable(CAP_SETUID)) {
32996 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
32998 @@ -712,6 +744,10 @@ asmlinkage long sys_setresuid(uid_t ruid
32999 (suid != current->euid) && (suid != current->suid))
33003 + if (gr_check_user_change(ruid, euid, -1))
33006 if (ruid != (uid_t) -1) {
33007 if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
33009 @@ -766,6 +802,10 @@ asmlinkage long sys_setresgid(gid_t rgid
33010 (sgid != current->egid) && (sgid != current->sgid))
33014 + if (gr_check_group_change(rgid, egid, -1))
33017 if (egid != (gid_t) -1) {
33018 if (egid != current->egid) {
33019 set_dumpable(current->mm, suid_dumpable);
33020 @@ -774,8 +814,10 @@ asmlinkage long sys_setresgid(gid_t rgid
33021 current->egid = egid;
33023 current->fsgid = current->egid;
33024 - if (rgid != (gid_t) -1)
33025 + if (rgid != (gid_t) -1) {
33026 + gr_set_role_label(current, current->uid, rgid);
33027 current->gid = rgid;
33029 if (sgid != (gid_t) -1)
33030 current->sgid = sgid;
33032 @@ -810,6 +852,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
33033 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
33036 + if (gr_check_user_change(-1, -1, uid))
33037 + return old_fsuid;
33039 if (uid == current->uid || uid == current->euid ||
33040 uid == current->suid || uid == current->fsuid ||
33041 capable(CAP_SETUID)) {
33042 @@ -842,6 +887,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
33043 if (gid == current->gid || gid == current->egid ||
33044 gid == current->sgid || gid == current->fsgid ||
33045 capable(CAP_SETGID)) {
33046 + if (gr_check_group_change(-1, -1, gid))
33047 + return old_fsgid;
33049 if (gid != old_fsgid) {
33050 set_dumpable(current->mm, suid_dumpable);
33052 @@ -923,7 +971,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
33053 write_lock_irq(&tasklist_lock);
33056 - p = find_task_by_vpid(pid);
33057 + /* grsec: replaced find_task_by_vpid with equivalent call which
33058 + lacks the chroot restriction
33060 + p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
33064 @@ -1655,7 +1706,7 @@ asmlinkage long sys_prctl(int option, un
33065 error = get_dumpable(current->mm);
33067 case PR_SET_DUMPABLE:
33068 - if (arg2 < 0 || arg2 > 1) {
33073 diff -urNp linux-2.6.27.10/kernel/sysctl.c linux-2.6.27.10/kernel/sysctl.c
33074 --- linux-2.6.27.10/kernel/sysctl.c 2008-12-10 22:35:38.000000000 -0500
33075 +++ linux-2.6.27.10/kernel/sysctl.c 2008-12-10 22:35:46.000000000 -0500
33077 static int deprecated_sysctl_warning(struct __sysctl_args *args);
33079 #if defined(CONFIG_SYSCTL)
33080 +#include <linux/grsecurity.h>
33081 +#include <linux/grinternal.h>
33083 +extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
33084 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
33086 +extern int gr_handle_chroot_sysctl(const int op);
33088 /* External variables not in a header file. */
33090 @@ -155,6 +162,7 @@ static int proc_do_cad_pid(struct ctl_ta
33091 static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
33092 void __user *buffer, size_t *lenp, loff_t *ppos);
33094 +extern ctl_table grsecurity_table[];
33096 static struct ctl_table root_table[];
33097 static struct ctl_table_root sysctl_table_root;
33098 @@ -187,6 +195,21 @@ extern struct ctl_table epoll_table[];
33099 int sysctl_legacy_va_layout;
33102 +#ifdef CONFIG_PAX_SOFTMODE
33103 +static ctl_table pax_table[] = {
33105 + .ctl_name = CTL_UNNUMBERED,
33106 + .procname = "softmode",
33107 + .data = &pax_softmode,
33108 + .maxlen = sizeof(unsigned int),
33110 + .proc_handler = &proc_dointvec,
33113 + { .ctl_name = 0 }
33117 extern int prove_locking;
33118 extern int lock_stat;
33120 @@ -223,6 +246,7 @@ static struct ctl_table root_table[] = {
33122 .child = dev_table,
33126 * NOTE: do not add new entries to this table unless you have read
33127 * Documentation/sysctl/ctl_unnumbered.txt
33128 @@ -850,6 +874,25 @@ static struct ctl_table kern_table[] = {
33129 .proc_handler = &proc_dointvec,
33133 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
33135 + .ctl_name = CTL_UNNUMBERED,
33136 + .procname = "grsecurity",
33138 + .child = grsecurity_table,
33142 +#ifdef CONFIG_PAX_SOFTMODE
33144 + .ctl_name = CTL_UNNUMBERED,
33145 + .procname = "pax",
33147 + .child = pax_table,
33152 * NOTE: do not add new entries to this table unless you have read
33153 * Documentation/sysctl/ctl_unnumbered.txt
33154 @@ -1179,6 +1222,7 @@ static struct ctl_table vm_table[] = {
33160 * NOTE: do not add new entries to this table unless you have read
33161 * Documentation/sysctl/ctl_unnumbered.txt
33162 @@ -1553,6 +1597,8 @@ static int do_sysctl_strategy(struct ctl
33166 +static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
33168 static int parse_table(int __user *name, int nlen,
33169 void __user *oldval, size_t __user *oldlenp,
33170 void __user *newval, size_t newlen,
33171 @@ -1571,7 +1617,7 @@ repeat:
33172 if (n == table->ctl_name) {
33174 if (table->child) {
33175 - if (sysctl_perm(root, table, MAY_EXEC))
33176 + if (sysctl_perm_nochk(root, table, MAY_EXEC))
33180 @@ -1656,6 +1702,33 @@ int sysctl_perm(struct ctl_table_root *r
33184 + if (table->parent != NULL && table->parent->procname != NULL &&
33185 + table->procname != NULL &&
33186 + gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
33188 + if (gr_handle_chroot_sysctl(op))
33190 + error = gr_handle_sysctl(table, op);
33194 + error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
33198 + if (root->permissions)
33199 + mode = root->permissions(root, current->nsproxy, table);
33201 + mode = table->mode;
33203 + return test_perm(mode, op);
33206 +int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
33211 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
33214 diff -urNp linux-2.6.27.10/kernel/time/tick-broadcast.c linux-2.6.27.10/kernel/time/tick-broadcast.c
33215 --- linux-2.6.27.10/kernel/time/tick-broadcast.c 2008-11-07 12:55:34.000000000 -0500
33216 +++ linux-2.6.27.10/kernel/time/tick-broadcast.c 2008-11-18 03:38:45.000000000 -0500
33217 @@ -114,7 +114,7 @@ int tick_device_uses_broadcast(struct cl
33218 * then clear the broadcast bit.
33220 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
33221 - int cpu = smp_processor_id();
33222 + cpu = smp_processor_id();
33224 cpu_clear(cpu, tick_broadcast_mask);
33225 tick_broadcast_clear_oneshot(cpu);
33226 diff -urNp linux-2.6.27.10/kernel/time.c linux-2.6.27.10/kernel/time.c
33227 --- linux-2.6.27.10/kernel/time.c 2008-11-07 12:55:34.000000000 -0500
33228 +++ linux-2.6.27.10/kernel/time.c 2008-11-18 03:38:45.000000000 -0500
33230 #include <linux/fs.h>
33231 #include <linux/slab.h>
33232 #include <linux/math64.h>
33233 +#include <linux/grsecurity.h>
33235 #include <asm/uaccess.h>
33236 #include <asm/unistd.h>
33237 @@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user
33240 vx_settimeofday(&tv);
33242 + gr_log_timechange();
33247 @@ -200,6 +204,8 @@ asmlinkage long sys_settimeofday(struct
33251 + gr_log_timechange();
33253 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
33256 @@ -238,7 +244,7 @@ EXPORT_SYMBOL(current_fs_time);
33257 * Avoid unnecessary multiplications/divisions in the
33258 * two most common HZ cases:
33260 -unsigned int inline jiffies_to_msecs(const unsigned long j)
33261 +inline unsigned int jiffies_to_msecs(const unsigned long j)
33263 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
33264 return (MSEC_PER_SEC / HZ) * j;
33265 @@ -254,7 +260,7 @@ unsigned int inline jiffies_to_msecs(con
33267 EXPORT_SYMBOL(jiffies_to_msecs);
33269 -unsigned int inline jiffies_to_usecs(const unsigned long j)
33270 +inline unsigned int jiffies_to_usecs(const unsigned long j)
33272 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
33273 return (USEC_PER_SEC / HZ) * j;
33274 diff -urNp linux-2.6.27.10/kernel/utsname_sysctl.c linux-2.6.27.10/kernel/utsname_sysctl.c
33275 --- linux-2.6.27.10/kernel/utsname_sysctl.c 2008-11-07 12:55:34.000000000 -0500
33276 +++ linux-2.6.27.10/kernel/utsname_sysctl.c 2008-11-18 03:38:45.000000000 -0500
33277 @@ -124,7 +124,7 @@ static struct ctl_table uts_kern_table[]
33278 .proc_handler = proc_do_uts_string,
33279 .strategy = sysctl_uts_string,
33282 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33285 static struct ctl_table uts_root_table[] = {
33286 @@ -134,7 +134,7 @@ static struct ctl_table uts_root_table[]
33288 .child = uts_kern_table,
33291 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33294 static int __init utsname_sysctl_init(void)
33295 diff -urNp linux-2.6.27.10/lib/radix-tree.c linux-2.6.27.10/lib/radix-tree.c
33296 --- linux-2.6.27.10/lib/radix-tree.c 2008-11-07 12:55:34.000000000 -0500
33297 +++ linux-2.6.27.10/lib/radix-tree.c 2008-11-18 03:38:45.000000000 -0500
33298 @@ -81,7 +81,7 @@ struct radix_tree_preload {
33300 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
33302 -DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
33303 +DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
33305 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
33307 diff -urNp linux-2.6.27.10/localversion-grsec linux-2.6.27.10/localversion-grsec
33308 --- linux-2.6.27.10/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
33309 +++ linux-2.6.27.10/localversion-grsec 2008-11-18 03:38:45.000000000 -0500
33312 diff -urNp linux-2.6.27.10/Makefile linux-2.6.27.10/Makefile
33313 --- linux-2.6.27.10/Makefile 2008-12-21 01:18:11.000000000 -0500
33314 +++ linux-2.6.27.10/Makefile 2008-12-21 01:18:21.000000000 -0500
33315 @@ -221,7 +221,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
33319 -HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
33320 +HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
33323 # Decide whether to build built-in, modular, or both.
33324 @@ -619,7 +619,7 @@ export mod_strip_cmd
33327 ifeq ($(KBUILD_EXTMOD),)
33328 -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
33329 +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
33331 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
33332 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
33333 diff -urNp linux-2.6.27.10/mm/filemap.c linux-2.6.27.10/mm/filemap.c
33334 --- linux-2.6.27.10/mm/filemap.c 2008-11-07 12:55:34.000000000 -0500
33335 +++ linux-2.6.27.10/mm/filemap.c 2008-11-18 03:38:45.000000000 -0500
33337 #include <linux/cpuset.h>
33338 #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
33339 #include <linux/memcontrol.h>
33340 +#include <linux/grsecurity.h>
33341 #include "internal.h"
33344 @@ -1588,7 +1589,7 @@ int generic_file_mmap(struct file * file
33345 struct address_space *mapping = file->f_mapping;
33347 if (!mapping->a_ops->readpage)
33350 file_accessed(file);
33351 vma->vm_ops = &generic_file_vm_ops;
33352 vma->vm_flags |= VM_CAN_NONLINEAR;
33353 @@ -1949,6 +1950,7 @@ inline int generic_write_checks(struct f
33354 *pos = i_size_read(inode);
33356 if (limit != RLIM_INFINITY) {
33357 + gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
33358 if (*pos >= limit) {
33359 send_sig(SIGXFSZ, current, 0);
33361 diff -urNp linux-2.6.27.10/mm/fremap.c linux-2.6.27.10/mm/fremap.c
33362 --- linux-2.6.27.10/mm/fremap.c 2008-11-07 12:55:34.000000000 -0500
33363 +++ linux-2.6.27.10/mm/fremap.c 2008-11-18 03:38:45.000000000 -0500
33364 @@ -151,6 +151,13 @@ asmlinkage long sys_remap_file_pages(uns
33366 vma = find_vma(mm, start);
33368 +#ifdef CONFIG_PAX_SEGMEXEC
33369 + if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
33370 + up_read(&mm->mmap_sem);
33376 * Make sure the vma is shared, that it supports prefaulting,
33377 * and that the remapped range is valid and fully within
33378 diff -urNp linux-2.6.27.10/mm/hugetlb.c linux-2.6.27.10/mm/hugetlb.c
33379 --- linux-2.6.27.10/mm/hugetlb.c 2008-11-18 11:38:40.000000000 -0500
33380 +++ linux-2.6.27.10/mm/hugetlb.c 2008-11-18 11:40:53.000000000 -0500
33381 @@ -1833,6 +1833,26 @@ int unmap_ref_private(struct mm_struct *
33385 +#ifdef CONFIG_PAX_SEGMEXEC
33386 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
33388 + struct mm_struct *mm = vma->vm_mm;
33389 + struct vm_area_struct *vma_m;
33390 + unsigned long address_m;
33393 + vma_m = pax_find_mirror_vma(vma);
33397 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33398 + address_m = address + SEGMEXEC_TASK_SIZE;
33399 + ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
33400 + get_page(page_m);
33401 + set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
33405 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
33406 unsigned long address, pte_t *ptep, pte_t pte,
33407 struct page *pagecache_page)
33408 @@ -1904,6 +1924,11 @@ retry_avoidcopy:
33409 huge_ptep_clear_flush(vma, address, ptep);
33410 set_huge_pte_at(mm, address, ptep,
33411 make_huge_pte(vma, new_page, 1));
33413 +#ifdef CONFIG_PAX_SEGMEXEC
33414 + pax_mirror_huge_pte(vma, address, new_page);
33417 /* Make the old page be freed below */
33418 new_page = old_page;
33420 @@ -2013,6 +2038,10 @@ retry:
33421 && (vma->vm_flags & VM_SHARED)));
33422 set_huge_pte_at(mm, address, ptep, new_pte);
33424 +#ifdef CONFIG_PAX_SEGMEXEC
33425 + pax_mirror_huge_pte(vma, address, page);
33428 if (write_access && !(vma->vm_flags & VM_SHARED)) {
33429 /* Optimization, do the COW without a second fault */
33430 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
33431 @@ -2041,6 +2070,28 @@ int hugetlb_fault(struct mm_struct *mm,
33432 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
33433 struct hstate *h = hstate_vma(vma);
33435 +#ifdef CONFIG_PAX_SEGMEXEC
33436 + struct vm_area_struct *vma_m;
33438 + vma_m = pax_find_mirror_vma(vma);
33440 + unsigned long address_m;
33442 + if (vma->vm_start > vma_m->vm_start) {
33443 + address_m = address;
33444 + address -= SEGMEXEC_TASK_SIZE;
33446 + h = hstate_vma(vma);
33448 + address_m = address + SEGMEXEC_TASK_SIZE;
33450 + if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
33451 + return VM_FAULT_OOM;
33452 + address_m &= HPAGE_MASK;
33453 + unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
33457 ptep = huge_pte_alloc(mm, address, huge_page_size(h));
33459 return VM_FAULT_OOM;
33460 diff -urNp linux-2.6.27.10/mm/madvise.c linux-2.6.27.10/mm/madvise.c
33461 --- linux-2.6.27.10/mm/madvise.c 2008-11-07 12:55:34.000000000 -0500
33462 +++ linux-2.6.27.10/mm/madvise.c 2008-11-18 03:38:45.000000000 -0500
33463 @@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
33465 int new_flags = vma->vm_flags;
33467 +#ifdef CONFIG_PAX_SEGMEXEC
33468 + struct vm_area_struct *vma_m;
33471 switch (behavior) {
33473 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
33474 @@ -92,6 +96,13 @@ success:
33476 * vm_flags is protected by the mmap_sem held in write mode.
33479 +#ifdef CONFIG_PAX_SEGMEXEC
33480 + vma_m = pax_find_mirror_vma(vma);
33482 + vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
33485 vma->vm_flags = new_flags;
33488 @@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
33490 case MADV_DONTNEED:
33491 error = madvise_dontneed(vma, prev, start, end);
33493 +#ifdef CONFIG_PAX_SEGMEXEC
33495 + struct vm_area_struct *vma_m, *prev_m;
33497 + vma_m = pax_find_mirror_vma(vma);
33499 + error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
33506 @@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
33510 +#ifdef CONFIG_PAX_SEGMEXEC
33511 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
33512 + if (end > SEGMEXEC_TASK_SIZE)
33517 + if (end > TASK_SIZE)
33523 diff -urNp linux-2.6.27.10/mm/memory.c linux-2.6.27.10/mm/memory.c
33524 --- linux-2.6.27.10/mm/memory.c 2008-11-07 12:55:34.000000000 -0500
33525 +++ linux-2.6.27.10/mm/memory.c 2008-11-18 03:38:45.000000000 -0500
33527 #include <linux/writeback.h>
33528 #include <linux/memcontrol.h>
33529 #include <linux/mmu_notifier.h>
33530 +#include <linux/grsecurity.h>
33532 #include <asm/pgalloc.h>
33533 #include <asm/uaccess.h>
33534 @@ -1146,11 +1147,11 @@ int get_user_pages(struct task_struct *t
33535 vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
33540 struct vm_area_struct *vma;
33541 unsigned int foll_flags;
33543 - vma = find_extend_vma(mm, start);
33544 + vma = find_vma(mm, start);
33545 if (!vma && in_gate_area(tsk, start)) {
33546 unsigned long pg = start & PAGE_MASK;
33547 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
33548 @@ -1190,7 +1191,7 @@ int get_user_pages(struct task_struct *t
33552 - if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
33553 + if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
33554 || !(vm_flags & vma->vm_flags))
33555 return i ? : -EFAULT;
33557 @@ -1263,7 +1264,7 @@ int get_user_pages(struct task_struct *t
33558 start += PAGE_SIZE;
33560 } while (len && start < vma->vm_end);
33565 EXPORT_SYMBOL(get_user_pages);
33566 @@ -1741,6 +1742,186 @@ static inline void cow_user_page(struct
33567 copy_user_highpage(dst, src, va, vma);
33570 +#ifdef CONFIG_PAX_SEGMEXEC
33571 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
33573 + struct mm_struct *mm = vma->vm_mm;
33575 + pte_t *pte, entry;
33577 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
33579 + if (!pte_present(entry)) {
33580 + if (!pte_none(entry)) {
33581 + BUG_ON(pte_file(entry));
33582 + free_swap_and_cache(pte_to_swp_entry(entry));
33583 + pte_clear_not_present_full(mm, address, pte, 0);
33586 + struct page *page;
33588 + flush_cache_page(vma, address, pte_pfn(entry));
33589 + entry = ptep_clear_flush(vma, address, pte);
33590 + BUG_ON(pte_dirty(entry));
33591 + page = vm_normal_page(vma, address, entry);
33593 + update_hiwater_rss(mm);
33594 + if (PageAnon(page))
33595 + dec_mm_counter(mm, anon_rss);
33597 + dec_mm_counter(mm, file_rss);
33598 + page_remove_rmap(page, vma);
33599 + page_cache_release(page);
33602 + pte_unmap_unlock(pte, ptl);
33605 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
33607 + * the ptl of the lower mapped page is held on entry and is not released on exit
33608 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
33610 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33612 + struct mm_struct *mm = vma->vm_mm;
33613 + unsigned long address_m;
33614 + spinlock_t *ptl_m;
33615 + struct vm_area_struct *vma_m;
33617 + pte_t *pte_m, entry_m;
33619 + BUG_ON(!page_m || !PageAnon(page_m));
33621 + vma_m = pax_find_mirror_vma(vma);
33625 + BUG_ON(!PageLocked(page_m));
33626 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33627 + address_m = address + SEGMEXEC_TASK_SIZE;
33628 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33629 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33630 + ptl_m = pte_lockptr(mm, pmd_m);
33631 + if (ptl != ptl_m) {
33632 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33633 + if (!pte_none(*pte_m))
33637 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33638 + page_cache_get(page_m);
33639 + page_add_anon_rmap(page_m, vma_m, address_m);
33640 + inc_mm_counter(mm, anon_rss);
33641 + set_pte_at(mm, address_m, pte_m, entry_m);
33642 + update_mmu_cache(vma_m, address_m, entry_m);
33644 + if (ptl != ptl_m)
33645 + spin_unlock(ptl_m);
33646 + pte_unmap_nested(pte_m);
33647 + unlock_page(page_m);
33650 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33652 + struct mm_struct *mm = vma->vm_mm;
33653 + unsigned long address_m;
33654 + spinlock_t *ptl_m;
33655 + struct vm_area_struct *vma_m;
33657 + pte_t *pte_m, entry_m;
33659 + BUG_ON(!page_m || PageAnon(page_m));
33661 + vma_m = pax_find_mirror_vma(vma);
33665 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33666 + address_m = address + SEGMEXEC_TASK_SIZE;
33667 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33668 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33669 + ptl_m = pte_lockptr(mm, pmd_m);
33670 + if (ptl != ptl_m) {
33671 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33672 + if (!pte_none(*pte_m))
33676 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33677 + page_cache_get(page_m);
33678 + page_add_file_rmap(page_m);
33679 + inc_mm_counter(mm, file_rss);
33680 + set_pte_at(mm, address_m, pte_m, entry_m);
33681 + update_mmu_cache(vma_m, address_m, entry_m);
33683 + if (ptl != ptl_m)
33684 + spin_unlock(ptl_m);
33685 + pte_unmap_nested(pte_m);
33688 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
33690 + struct mm_struct *mm = vma->vm_mm;
33691 + unsigned long address_m;
33692 + spinlock_t *ptl_m;
33693 + struct vm_area_struct *vma_m;
33695 + pte_t *pte_m, entry_m;
33697 + vma_m = pax_find_mirror_vma(vma);
33701 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33702 + address_m = address + SEGMEXEC_TASK_SIZE;
33703 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33704 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33705 + ptl_m = pte_lockptr(mm, pmd_m);
33706 + if (ptl != ptl_m) {
33707 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33708 + if (!pte_none(*pte_m))
33712 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
33713 + set_pte_at(mm, address_m, pte_m, entry_m);
33715 + if (ptl != ptl_m)
33716 + spin_unlock(ptl_m);
33717 + pte_unmap_nested(pte_m);
33720 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
33722 + struct page *page_m;
33725 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
33729 + page_m = vm_normal_page(vma, address, entry);
33731 + pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
33732 + else if (PageAnon(page_m)) {
33733 + if (pax_find_mirror_vma(vma)) {
33734 + pte_unmap_unlock(pte, ptl);
33735 + lock_page(page_m);
33736 + pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
33737 + if (pte_same(entry, *pte))
33738 + pax_mirror_anon_pte(vma, address, page_m, ptl);
33740 + unlock_page(page_m);
33743 + pax_mirror_file_pte(vma, address, page_m, ptl);
33746 + pte_unmap_unlock(pte, ptl);
33751 * This routine handles present pages, when users try to write
33752 * to a shared page. It is done by copying the page to a new address
33753 @@ -1869,6 +2050,12 @@ gotten:
33755 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33756 if (likely(pte_same(*page_table, orig_pte))) {
33758 +#ifdef CONFIG_PAX_SEGMEXEC
33759 + if (pax_find_mirror_vma(vma))
33760 + BUG_ON(!trylock_page(new_page));
33764 if (!PageAnon(old_page)) {
33765 dec_mm_counter(mm, file_rss);
33766 @@ -1917,6 +2104,10 @@ gotten:
33767 page_remove_rmap(old_page, vma);
33770 +#ifdef CONFIG_PAX_SEGMEXEC
33771 + pax_mirror_anon_pte(vma, address, new_page, ptl);
33774 /* Free the old page.. */
33775 new_page = old_page;
33776 ret |= VM_FAULT_WRITE;
33777 @@ -2176,6 +2367,7 @@ int vmtruncate(struct inode * inode, lof
33778 unsigned long limit;
33780 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
33781 + gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
33782 if (limit != RLIM_INFINITY && offset > limit)
33784 if (offset > inode->i_sb->s_maxbytes)
33785 @@ -2326,6 +2518,11 @@ static int do_swap_page(struct mm_struct
33787 if (vm_swap_full())
33788 remove_exclusive_swap_page(page);
33790 +#ifdef CONFIG_PAX_SEGMEXEC
33791 + if (write_access || !pax_find_mirror_vma(vma))
33796 if (write_access) {
33797 @@ -2337,6 +2534,11 @@ static int do_swap_page(struct mm_struct
33799 /* No need to invalidate - it was non-present before */
33800 update_mmu_cache(vma, address, pte);
33802 +#ifdef CONFIG_PAX_SEGMEXEC
33803 + pax_mirror_anon_pte(vma, address, page, ptl);
33807 pte_unmap_unlock(page_table, ptl);
33809 @@ -2381,6 +2583,12 @@ static int do_anonymous_page(struct mm_s
33810 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33811 if (!pte_none(*page_table))
33814 +#ifdef CONFIG_PAX_SEGMEXEC
33815 + if (pax_find_mirror_vma(vma))
33816 + BUG_ON(!trylock_page(page));
33819 inc_mm_counter(mm, anon_rss);
33820 lru_cache_add_active(page);
33821 page_add_new_anon_rmap(page, vma, address);
33822 @@ -2388,6 +2596,11 @@ static int do_anonymous_page(struct mm_s
33824 /* No need to invalidate - it was non-present before */
33825 update_mmu_cache(vma, address, entry);
33827 +#ifdef CONFIG_PAX_SEGMEXEC
33828 + pax_mirror_anon_pte(vma, address, page, ptl);
33832 pte_unmap_unlock(page_table, ptl);
33834 @@ -2516,6 +2729,12 @@ static int __do_fault(struct mm_struct *
33836 /* Only go through if we didn't race with anybody else... */
33837 if (likely(pte_same(*page_table, orig_pte))) {
33839 +#ifdef CONFIG_PAX_SEGMEXEC
33840 + if (anon && pax_find_mirror_vma(vma))
33841 + BUG_ON(!trylock_page(page));
33844 flush_icache_page(vma, page);
33845 entry = mk_pte(page, vma->vm_page_prot);
33846 if (flags & FAULT_FLAG_WRITE)
33847 @@ -2536,6 +2755,14 @@ static int __do_fault(struct mm_struct *
33849 /* no need to invalidate: a not-present page won't be cached */
33850 update_mmu_cache(vma, address, entry);
33852 +#ifdef CONFIG_PAX_SEGMEXEC
33854 + pax_mirror_anon_pte(vma, address, page, ptl);
33856 + pax_mirror_file_pte(vma, address, page, ptl);
33860 mem_cgroup_uncharge_page(page);
33862 @@ -2668,6 +2895,12 @@ static inline int handle_pte_fault(struc
33864 flush_tlb_page(vma, address);
33867 +#ifdef CONFIG_PAX_SEGMEXEC
33868 + pax_mirror_pte(vma, address, pte, pmd, ptl);
33873 pte_unmap_unlock(pte, ptl);
33875 @@ -2684,6 +2917,10 @@ int handle_mm_fault(struct mm_struct *mm
33879 +#ifdef CONFIG_PAX_SEGMEXEC
33880 + struct vm_area_struct *vma_m;
33883 __set_current_state(TASK_RUNNING);
33885 count_vm_event(PGFAULT);
33886 @@ -2691,6 +2928,34 @@ int handle_mm_fault(struct mm_struct *mm
33887 if (unlikely(is_vm_hugetlb_page(vma)))
33888 return hugetlb_fault(mm, vma, address, write_access);
33890 +#ifdef CONFIG_PAX_SEGMEXEC
33891 + vma_m = pax_find_mirror_vma(vma);
33893 + unsigned long address_m;
33898 + if (vma->vm_start > vma_m->vm_start) {
33899 + address_m = address;
33900 + address -= SEGMEXEC_TASK_SIZE;
33903 + address_m = address + SEGMEXEC_TASK_SIZE;
33905 + pgd_m = pgd_offset(mm, address_m);
33906 + pud_m = pud_alloc(mm, pgd_m, address_m);
33908 + return VM_FAULT_OOM;
33909 + pmd_m = pmd_alloc(mm, pud_m, address_m);
33911 + return VM_FAULT_OOM;
33912 + if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
33913 + return VM_FAULT_OOM;
33914 + pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
33918 pgd = pgd_offset(mm, address);
33919 pud = pud_alloc(mm, pgd, address);
33921 @@ -2798,7 +3063,7 @@ static int __init gate_vma_init(void)
33922 gate_vma.vm_start = FIXADDR_USER_START;
33923 gate_vma.vm_end = FIXADDR_USER_END;
33924 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
33925 - gate_vma.vm_page_prot = __P101;
33926 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
33928 * Make sure the vDSO gets into every core dump.
33929 * Dumping its contents makes post-mortem fully interpretable later
33930 diff -urNp linux-2.6.27.10/mm/mempolicy.c linux-2.6.27.10/mm/mempolicy.c
33931 --- linux-2.6.27.10/mm/mempolicy.c 2008-11-07 12:55:34.000000000 -0500
33932 +++ linux-2.6.27.10/mm/mempolicy.c 2008-11-18 03:38:45.000000000 -0500
33933 @@ -555,6 +555,10 @@ static int mbind_range(struct vm_area_st
33934 struct vm_area_struct *next;
33937 +#ifdef CONFIG_PAX_SEGMEXEC
33938 + struct vm_area_struct *vma_m;
33942 for (; vma && vma->vm_start < end; vma = next) {
33943 next = vma->vm_next;
33944 @@ -566,6 +570,16 @@ static int mbind_range(struct vm_area_st
33945 err = policy_vma(vma, new);
33949 +#ifdef CONFIG_PAX_SEGMEXEC
33950 + vma_m = pax_find_mirror_vma(vma);
33952 + err = policy_vma(vma_m, new);
33961 @@ -951,6 +965,17 @@ static long do_mbind(unsigned long start
33966 +#ifdef CONFIG_PAX_SEGMEXEC
33967 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
33968 + if (end > SEGMEXEC_TASK_SIZE)
33973 + if (end > TASK_SIZE)
33979 diff -urNp linux-2.6.27.10/mm/mlock.c linux-2.6.27.10/mm/mlock.c
33980 --- linux-2.6.27.10/mm/mlock.c 2008-11-07 12:55:34.000000000 -0500
33981 +++ linux-2.6.27.10/mm/mlock.c 2008-11-18 03:38:45.000000000 -0500
33983 #include <linux/sched.h>
33984 #include <linux/module.h>
33985 #include <linux/vs_memory.h>
33986 +#include <linux/grsecurity.h>
33988 int can_do_mlock(void)
33990 @@ -93,6 +94,17 @@ static int do_mlock(unsigned long start,
33995 +#ifdef CONFIG_PAX_SEGMEXEC
33996 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
33997 + if (end > SEGMEXEC_TASK_SIZE)
34002 + if (end > TASK_SIZE)
34005 vma = find_vma_prev(current->mm, start, &prev);
34006 if (!vma || vma->vm_start > start)
34008 @@ -150,6 +162,7 @@ asmlinkage long sys_mlock(unsigned long
34009 lock_limit >>= PAGE_SHIFT;
34011 /* check against resource limits */
34012 + gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
34013 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
34014 error = do_mlock(start, len, 1);
34015 up_write(¤t->mm->mmap_sem);
34016 @@ -171,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
34017 static int do_mlockall(int flags)
34019 struct vm_area_struct * vma, * prev = NULL;
34020 - unsigned int def_flags = 0;
34021 + unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
34023 if (flags & MCL_FUTURE)
34024 - def_flags = VM_LOCKED;
34025 + def_flags |= VM_LOCKED;
34026 current->mm->def_flags = def_flags;
34027 if (flags == MCL_FUTURE)
34029 @@ -182,6 +195,12 @@ static int do_mlockall(int flags)
34030 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
34031 unsigned int newflags;
34033 +#ifdef CONFIG_PAX_SEGMEXEC
34034 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
34038 + BUG_ON(vma->vm_end > TASK_SIZE);
34039 newflags = vma->vm_flags | VM_LOCKED;
34040 if (!(flags & MCL_CURRENT))
34041 newflags &= ~VM_LOCKED;
34042 @@ -211,6 +230,7 @@ asmlinkage long sys_mlockall(int flags)
34043 lock_limit >>= PAGE_SHIFT;
34046 + gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
34047 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
34049 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
34050 diff -urNp linux-2.6.27.10/mm/mmap.c linux-2.6.27.10/mm/mmap.c
34051 --- linux-2.6.27.10/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
34052 +++ linux-2.6.27.10/mm/mmap.c 2008-12-21 00:44:29.000000000 -0500
34054 #include <linux/mempolicy.h>
34055 #include <linux/rmap.h>
34056 #include <linux/mmu_notifier.h>
34057 +#include <linux/grsecurity.h>
34059 #include <asm/uaccess.h>
34060 #include <asm/cacheflush.h>
34062 #define arch_rebalance_pgtables(addr, len) (addr)
34065 +static inline void verify_mm_writelocked(struct mm_struct *mm)
34067 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
34068 + if (unlikely(down_read_trylock(&mm->mmap_sem))) {
34069 + up_read(&mm->mmap_sem);
34075 static void unmap_region(struct mm_struct *mm,
34076 struct vm_area_struct *vma, struct vm_area_struct *prev,
34077 unsigned long start, unsigned long end);
34078 @@ -68,16 +79,25 @@ static void unmap_region(struct mm_struc
34079 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
34082 -pgprot_t protection_map[16] = {
34083 +pgprot_t protection_map[16] __read_only = {
34084 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
34085 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
34088 pgprot_t vm_get_page_prot(unsigned long vm_flags)
34090 - return __pgprot(pgprot_val(protection_map[vm_flags &
34091 + pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
34092 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
34093 pgprot_val(arch_vm_get_page_prot(vm_flags)));
34095 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34096 + if (!nx_enabled &&
34097 + (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
34098 + (vm_flags & (VM_READ | VM_WRITE)))
34099 + prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
34104 EXPORT_SYMBOL(vm_get_page_prot);
34106 @@ -232,6 +252,7 @@ static struct vm_area_struct *remove_vma
34107 struct vm_area_struct *next = vma->vm_next;
34110 + BUG_ON(vma->vm_mirror);
34111 if (vma->vm_ops && vma->vm_ops->close)
34112 vma->vm_ops->close(vma);
34113 if (vma->vm_file) {
34114 @@ -268,6 +289,7 @@ asmlinkage unsigned long sys_brk(unsigne
34115 * not page aligned -Ram Gupta
34117 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
34118 + gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
34119 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
34120 (mm->end_data - mm->start_data) > rlim)
34122 @@ -697,6 +719,12 @@ static int
34123 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
34124 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34127 +#ifdef CONFIG_PAX_SEGMEXEC
34128 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
34132 if (is_mergeable_vma(vma, file, vm_flags) &&
34133 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34134 if (vma->vm_pgoff == vm_pgoff)
34135 @@ -716,6 +744,12 @@ static int
34136 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
34137 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34140 +#ifdef CONFIG_PAX_SEGMEXEC
34141 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
34145 if (is_mergeable_vma(vma, file, vm_flags) &&
34146 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34148 @@ -758,12 +792,19 @@ can_vma_merge_after(struct vm_area_struc
34149 struct vm_area_struct *vma_merge(struct mm_struct *mm,
34150 struct vm_area_struct *prev, unsigned long addr,
34151 unsigned long end, unsigned long vm_flags,
34152 - struct anon_vma *anon_vma, struct file *file,
34153 + struct anon_vma *anon_vma, struct file *file,
34154 pgoff_t pgoff, struct mempolicy *policy)
34156 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
34157 struct vm_area_struct *area, *next;
34159 +#ifdef CONFIG_PAX_SEGMEXEC
34160 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
34161 + struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
34163 + BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
34167 * We later require that vma->vm_flags == vm_flags,
34168 * so this tests vma->vm_flags & VM_SPECIAL, too.
34169 @@ -779,6 +820,15 @@ struct vm_area_struct *vma_merge(struct
34170 if (next && next->vm_end == end) /* cases 6, 7, 8 */
34171 next = next->vm_next;
34173 +#ifdef CONFIG_PAX_SEGMEXEC
34175 + prev_m = pax_find_mirror_vma(prev);
34177 + area_m = pax_find_mirror_vma(area);
34179 + next_m = pax_find_mirror_vma(next);
34183 * Can it merge with the predecessor?
34185 @@ -798,9 +848,24 @@ struct vm_area_struct *vma_merge(struct
34187 vma_adjust(prev, prev->vm_start,
34188 next->vm_end, prev->vm_pgoff, NULL);
34189 - } else /* cases 2, 5, 7 */
34191 +#ifdef CONFIG_PAX_SEGMEXEC
34193 + vma_adjust(prev_m, prev_m->vm_start,
34194 + next_m->vm_end, prev_m->vm_pgoff, NULL);
34197 + } else { /* cases 2, 5, 7 */
34198 vma_adjust(prev, prev->vm_start,
34199 end, prev->vm_pgoff, NULL);
34201 +#ifdef CONFIG_PAX_SEGMEXEC
34203 + vma_adjust(prev_m, prev_m->vm_start,
34204 + end_m, prev_m->vm_pgoff, NULL);
34211 @@ -811,12 +876,27 @@ struct vm_area_struct *vma_merge(struct
34212 mpol_equal(policy, vma_policy(next)) &&
34213 can_vma_merge_before(next, vm_flags,
34214 anon_vma, file, pgoff+pglen)) {
34215 - if (prev && addr < prev->vm_end) /* case 4 */
34216 + if (prev && addr < prev->vm_end) { /* case 4 */
34217 vma_adjust(prev, prev->vm_start,
34218 addr, prev->vm_pgoff, NULL);
34219 - else /* cases 3, 8 */
34221 +#ifdef CONFIG_PAX_SEGMEXEC
34223 + vma_adjust(prev_m, prev_m->vm_start,
34224 + addr_m, prev_m->vm_pgoff, NULL);
34227 + } else { /* cases 3, 8 */
34228 vma_adjust(area, addr, next->vm_end,
34229 next->vm_pgoff - pglen, NULL);
34231 +#ifdef CONFIG_PAX_SEGMEXEC
34233 + vma_adjust(area_m, addr_m, next_m->vm_end,
34234 + next_m->vm_pgoff - pglen, NULL);
34241 @@ -891,14 +971,11 @@ none:
34242 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
34243 struct file *file, long pages)
34245 - const unsigned long stack_flags
34246 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
34249 mm->shared_vm += pages;
34250 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
34251 mm->exec_vm += pages;
34252 - } else if (flags & stack_flags)
34253 + } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
34254 mm->stack_vm += pages;
34255 if (flags & (VM_RESERVED|VM_IO))
34256 mm->reserved_vm += pages;
34257 @@ -926,7 +1003,7 @@ unsigned long do_mmap_pgoff(struct file
34258 * (the exception is when the underlying filesystem is noexec
34259 * mounted, in which case we dont add PROT_EXEC.)
34261 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
34262 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
34263 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
34266 @@ -936,15 +1013,15 @@ unsigned long do_mmap_pgoff(struct file
34267 if (!(flags & MAP_FIXED))
34268 addr = round_hint_to_min(addr);
34270 - error = arch_mmap_check(addr, len, flags);
34274 /* Careful about overflows.. */
34275 len = PAGE_ALIGN(len);
34276 if (!len || len > TASK_SIZE)
34279 + error = arch_mmap_check(addr, len, flags);
34283 /* offset overflow? */
34284 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
34286 @@ -956,7 +1033,7 @@ unsigned long do_mmap_pgoff(struct file
34287 /* Obtain the address to map to. we verify (or select) it and ensure
34288 * that it represents a valid section of the address space.
34290 - addr = get_unmapped_area(file, addr, len, pgoff, flags);
34291 + addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
34292 if (addr & ~PAGE_MASK)
34295 @@ -967,6 +1044,26 @@ unsigned long do_mmap_pgoff(struct file
34296 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
34297 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
34299 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
34300 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
34302 +#ifdef CONFIG_PAX_MPROTECT
34303 + if (mm->pax_flags & MF_PAX_MPROTECT) {
34304 + if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
34305 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
34307 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
34314 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34315 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
34316 + vm_flags &= ~VM_PAGEEXEC;
34319 if (flags & MAP_LOCKED) {
34320 if (!can_do_mlock())
34322 @@ -979,6 +1076,7 @@ unsigned long do_mmap_pgoff(struct file
34323 locked += mm->locked_vm;
34324 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
34325 lock_limit >>= PAGE_SHIFT;
34326 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34327 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
34330 @@ -1051,6 +1149,9 @@ unsigned long do_mmap_pgoff(struct file
34334 + if (!gr_acl_handle_mmap(file, prot))
34337 return mmap_region(file, addr, len, flags, vm_flags, pgoff,
34340 @@ -1064,10 +1165,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
34342 int vma_wants_writenotify(struct vm_area_struct *vma)
34344 - unsigned int vm_flags = vma->vm_flags;
34345 + unsigned long vm_flags = vma->vm_flags;
34347 /* If it was private or non-writable, the write bit is already clear */
34348 - if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
34349 + if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
34352 /* The backer wishes to know when pages are first written to? */
34353 @@ -1101,14 +1202,24 @@ unsigned long mmap_region(struct file *f
34354 unsigned long charged = 0;
34355 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
34357 +#ifdef CONFIG_PAX_SEGMEXEC
34358 + struct vm_area_struct *vma_m = NULL;
34362 + * mm->mmap_sem is required to protect against another thread
34363 + * changing the mappings in case we sleep.
34365 + verify_mm_writelocked(mm);
34367 /* Clear old maps */
34370 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34371 if (vma && vma->vm_start < addr + len) {
34372 if (do_munmap(mm, addr, len))
34374 - goto munmap_back;
34375 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34376 + BUG_ON(vma && vma->vm_start < addr + len);
34379 /* Check against address space limit. */
34380 @@ -1155,6 +1266,16 @@ munmap_back:
34384 +#ifdef CONFIG_PAX_SEGMEXEC
34385 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
34386 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34395 vma->vm_start = addr;
34396 vma->vm_end = addr + len;
34397 @@ -1177,6 +1298,19 @@ munmap_back:
34398 error = file->f_op->mmap(file, vma);
34400 goto unmap_and_free_vma;
34402 +#ifdef CONFIG_PAX_SEGMEXEC
34403 + if (vma_m && (vm_flags & VM_EXECUTABLE))
34404 + added_exe_file_vma(mm);
34407 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34408 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
34409 + vma->vm_flags |= VM_PAGEEXEC;
34410 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
34414 if (vm_flags & VM_EXECUTABLE)
34415 added_exe_file_vma(mm);
34416 } else if (vm_flags & VM_SHARED) {
34417 @@ -1209,12 +1343,29 @@ munmap_back:
34418 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
34419 mpol_put(vma_policy(vma));
34420 kmem_cache_free(vm_area_cachep, vma);
34424 +#ifdef CONFIG_PAX_SEGMEXEC
34426 + kmem_cache_free(vm_area_cachep, vma_m);
34428 + if (vm_flags & VM_EXECUTABLE)
34429 + removed_exe_file_vma(mm);
34433 if (vm_flags & VM_EXECUTABLE)
34434 removed_exe_file_vma(mm);
34436 vma_link(mm, vma, prev, rb_link, rb_parent);
34437 file = vma->vm_file;
34439 +#ifdef CONFIG_PAX_SEGMEXEC
34441 + pax_mirror_vma(vma_m, vma);
34446 /* Once vma denies write, undo our temporary denial count */
34447 @@ -1223,6 +1374,7 @@ munmap_back:
34449 mm->total_vm += len >> PAGE_SHIFT;
34450 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
34451 + track_exec_limit(mm, addr, addr + len, vm_flags);
34452 if (vm_flags & VM_LOCKED) {
34453 mm->locked_vm += len >> PAGE_SHIFT;
34454 make_pages_present(addr, addr + len);
34455 @@ -1241,6 +1393,12 @@ unmap_and_free_vma:
34456 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
34460 +#ifdef CONFIG_PAX_SEGMEXEC
34462 + kmem_cache_free(vm_area_cachep, vma_m);
34465 kmem_cache_free(vm_area_cachep, vma);
34468 @@ -1274,6 +1432,10 @@ arch_get_unmapped_area(struct file *filp
34469 if (flags & MAP_FIXED)
34472 +#ifdef CONFIG_PAX_RANDMMAP
34473 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34477 addr = PAGE_ALIGN(addr);
34478 vma = find_vma(mm, addr);
34479 @@ -1282,10 +1444,10 @@ arch_get_unmapped_area(struct file *filp
34482 if (len > mm->cached_hole_size) {
34483 - start_addr = addr = mm->free_area_cache;
34484 + start_addr = addr = mm->free_area_cache;
34486 - start_addr = addr = TASK_UNMAPPED_BASE;
34487 - mm->cached_hole_size = 0;
34488 + start_addr = addr = mm->mmap_base;
34489 + mm->cached_hole_size = 0;
34493 @@ -1296,9 +1458,8 @@ full_search:
34494 * Start a new search - just in case we missed
34497 - if (start_addr != TASK_UNMAPPED_BASE) {
34498 - addr = TASK_UNMAPPED_BASE;
34499 - start_addr = addr;
34500 + if (start_addr != mm->mmap_base) {
34501 + start_addr = addr = mm->mmap_base;
34502 mm->cached_hole_size = 0;
34505 @@ -1320,10 +1481,16 @@ full_search:
34507 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
34510 +#ifdef CONFIG_PAX_SEGMEXEC
34511 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34516 * Is this a new hole at the lowest possible address?
34518 - if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
34519 + if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
34520 mm->free_area_cache = addr;
34521 mm->cached_hole_size = ~0UL;
34523 @@ -1341,7 +1508,7 @@ arch_get_unmapped_area_topdown(struct fi
34525 struct vm_area_struct *vma;
34526 struct mm_struct *mm = current->mm;
34527 - unsigned long addr = addr0;
34528 + unsigned long base = mm->mmap_base, addr = addr0;
34530 /* requested length too big for entire address space */
34531 if (len > TASK_SIZE)
34532 @@ -1350,6 +1517,10 @@ arch_get_unmapped_area_topdown(struct fi
34533 if (flags & MAP_FIXED)
34536 +#ifdef CONFIG_PAX_RANDMMAP
34537 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34540 /* requesting a specific address */
34542 addr = PAGE_ALIGN(addr);
34543 @@ -1407,13 +1578,21 @@ bottomup:
34544 * can happen with large stack limits and large mmap()
34547 + mm->mmap_base = TASK_UNMAPPED_BASE;
34549 +#ifdef CONFIG_PAX_RANDMMAP
34550 + if (mm->pax_flags & MF_PAX_RANDMMAP)
34551 + mm->mmap_base += mm->delta_mmap;
34554 + mm->free_area_cache = mm->mmap_base;
34555 mm->cached_hole_size = ~0UL;
34556 - mm->free_area_cache = TASK_UNMAPPED_BASE;
34557 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
34559 * Restore the topdown base:
34561 - mm->free_area_cache = mm->mmap_base;
34562 + mm->mmap_base = base;
34563 + mm->free_area_cache = base;
34564 mm->cached_hole_size = ~0UL;
34567 @@ -1422,6 +1601,12 @@ bottomup:
34569 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
34572 +#ifdef CONFIG_PAX_SEGMEXEC
34573 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34578 * Is this a new hole at the highest possible address?
34580 @@ -1429,8 +1614,10 @@ void arch_unmap_area_topdown(struct mm_s
34581 mm->free_area_cache = addr;
34583 /* dont allow allocations above current base */
34584 - if (mm->free_area_cache > mm->mmap_base)
34585 + if (mm->free_area_cache > mm->mmap_base) {
34586 mm->free_area_cache = mm->mmap_base;
34587 + mm->cached_hole_size = ~0UL;
34592 @@ -1530,6 +1717,27 @@ out:
34593 return prev ? prev->vm_next : vma;
34596 +#ifdef CONFIG_PAX_SEGMEXEC
34597 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
34599 + struct vm_area_struct *vma_m;
34601 + BUG_ON(!vma || vma->vm_start >= vma->vm_end);
34602 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
34603 + BUG_ON(vma->vm_mirror);
34606 + BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
34607 + vma_m = vma->vm_mirror;
34608 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
34609 + BUG_ON(vma->vm_file != vma_m->vm_file);
34610 + BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
34611 + BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
34612 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
34618 * Verify that the stack growth is acceptable and
34619 * update accounting. This is shared with both the
34620 @@ -1546,6 +1754,7 @@ static int acct_stack_growth(struct vm_a
34623 /* Stack limit test */
34624 + gr_learn_resource(current, RLIMIT_STACK, size, 1);
34625 if (size > rlim[RLIMIT_STACK].rlim_cur)
34628 @@ -1555,6 +1764,7 @@ static int acct_stack_growth(struct vm_a
34629 unsigned long limit;
34630 locked = mm->locked_vm + grow;
34631 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
34632 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34633 if (locked > limit && !capable(CAP_IPC_LOCK))
34636 @@ -1569,7 +1779,7 @@ static int acct_stack_growth(struct vm_a
34637 * Overcommit.. This must be the final test, as it will
34638 * update security statistics.
34640 - if (security_vm_enough_memory(grow))
34641 + if (security_vm_enough_memory_mm(mm, grow))
34644 /* Ok, everything looks good - let it rip */
34645 @@ -1590,35 +1800,40 @@ static inline
34647 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
34650 + int error, locknext;
34652 if (!(vma->vm_flags & VM_GROWSUP))
34655 + /* Also guard against wrapping around to address 0. */
34656 + if (address < PAGE_ALIGN(address+1))
34657 + address = PAGE_ALIGN(address+1);
34662 * We must make sure the anon_vma is allocated
34663 * so that the anon_vma locking is not a noop.
34665 if (unlikely(anon_vma_prepare(vma)))
34667 + locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
34668 + if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
34670 anon_vma_lock(vma);
34672 + anon_vma_lock(vma->vm_next);
34675 * vma->vm_start/vm_end cannot change under us because the caller
34676 * is required to hold the mmap_sem in read mode. We need the
34677 - * anon_vma lock to serialize against concurrent expand_stacks.
34678 - * Also guard against wrapping around to address 0.
34679 + * anon_vma locks to serialize against concurrent expand_stacks
34680 + * and expand_upwards.
34682 - if (address < PAGE_ALIGN(address+4))
34683 - address = PAGE_ALIGN(address+4);
34685 - anon_vma_unlock(vma);
34690 /* Somebody else might have raced and expanded it already */
34691 - if (address > vma->vm_end) {
34692 + if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
34693 unsigned long size, grow;
34695 size = address - vma->vm_start;
34696 @@ -1628,6 +1843,8 @@ int expand_upwards(struct vm_area_struct
34698 vma->vm_end = address;
34701 + anon_vma_unlock(vma->vm_next);
34702 anon_vma_unlock(vma);
34705 @@ -1639,7 +1856,8 @@ int expand_upwards(struct vm_area_struct
34706 static inline int expand_downwards(struct vm_area_struct *vma,
34707 unsigned long address)
34710 + int error, lockprev = 0;
34711 + struct vm_area_struct *prev = NULL;
34714 * We must make sure the anon_vma is allocated
34715 @@ -1653,6 +1871,15 @@ static inline int expand_downwards(struc
34719 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
34720 + find_vma_prev(vma->vm_mm, address, &prev);
34721 + lockprev = prev && (prev->vm_flags & VM_GROWSUP);
34723 + if (lockprev && unlikely(anon_vma_prepare(prev)))
34726 + anon_vma_lock(prev);
34728 anon_vma_lock(vma);
34731 @@ -1662,9 +1889,15 @@ static inline int expand_downwards(struc
34734 /* Somebody else might have raced and expanded it already */
34735 - if (address < vma->vm_start) {
34736 + if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
34737 unsigned long size, grow;
34739 +#ifdef CONFIG_PAX_SEGMEXEC
34740 + struct vm_area_struct *vma_m;
34742 + vma_m = pax_find_mirror_vma(vma);
34745 size = vma->vm_end - address;
34746 grow = (vma->vm_start - address) >> PAGE_SHIFT;
34748 @@ -1672,9 +1905,20 @@ static inline int expand_downwards(struc
34750 vma->vm_start = address;
34751 vma->vm_pgoff -= grow;
34752 + track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
34754 +#ifdef CONFIG_PAX_SEGMEXEC
34756 + vma_m->vm_start -= grow << PAGE_SHIFT;
34757 + vma_m->vm_pgoff -= grow;
34763 anon_vma_unlock(vma);
34765 + anon_vma_unlock(prev);
34769 @@ -1746,6 +1990,13 @@ static void remove_vma_list(struct mm_st
34771 long nrpages = vma_pages(vma);
34773 +#ifdef CONFIG_PAX_SEGMEXEC
34774 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
34775 + vma = remove_vma(vma);
34780 vx_vmpages_sub(mm, nrpages);
34781 if (vma->vm_flags & VM_LOCKED)
34782 mm->locked_vm -= nrpages;
34783 @@ -1792,6 +2043,16 @@ detach_vmas_to_be_unmapped(struct mm_str
34785 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
34788 +#ifdef CONFIG_PAX_SEGMEXEC
34789 + if (vma->vm_mirror) {
34790 + BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
34791 + vma->vm_mirror->vm_mirror = NULL;
34792 + vma->vm_mirror->vm_flags &= ~VM_EXEC;
34793 + vma->vm_mirror = NULL;
34797 rb_erase(&vma->vm_rb, &mm->mm_rb);
34800 @@ -1811,6 +2072,108 @@ detach_vmas_to_be_unmapped(struct mm_str
34801 * Split a vma into two pieces at address 'addr', a new vma is allocated
34802 * either for the first part or the tail.
34805 +#ifdef CONFIG_PAX_SEGMEXEC
34806 +int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
34807 + unsigned long addr, int new_below)
34809 + struct mempolicy *pol;
34810 + struct vm_area_struct *new, *vma_m, *new_m = NULL;
34811 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
34813 + if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
34816 + vma_m = pax_find_mirror_vma(vma);
34818 + BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
34819 + if (mm->map_count >= sysctl_max_map_count-1)
34821 + } else if (mm->map_count >= sysctl_max_map_count)
34824 + new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34829 + new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34831 + kmem_cache_free(vm_area_cachep, new);
34836 + /* most fields are the same, copy all, and then fixup */
34840 + new->vm_end = addr;
34842 + new->vm_start = addr;
34843 + new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
34848 + new_m->vm_mirror = new;
34849 + new->vm_mirror = new_m;
34852 + new_m->vm_end = addr_m;
34854 + new_m->vm_start = addr_m;
34855 + new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
34859 + pol = mpol_dup(vma_policy(vma));
34860 + if (IS_ERR(pol)) {
34862 + kmem_cache_free(vm_area_cachep, new_m);
34863 + kmem_cache_free(vm_area_cachep, new);
34864 + return PTR_ERR(pol);
34866 + vma_set_policy(new, pol);
34868 + if (new->vm_file) {
34869 + get_file(new->vm_file);
34870 + if (vma->vm_flags & VM_EXECUTABLE)
34871 + added_exe_file_vma(mm);
34874 + if (new->vm_ops && new->vm_ops->open)
34875 + new->vm_ops->open(new);
34878 + vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
34879 + ((addr - new->vm_start) >> PAGE_SHIFT), new);
34881 + vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
34885 + vma_set_policy(new_m, pol);
34887 + if (new_m->vm_file) {
34888 + get_file(new_m->vm_file);
34889 + if (vma_m->vm_flags & VM_EXECUTABLE)
34890 + added_exe_file_vma(mm);
34893 + if (new_m->vm_ops && new_m->vm_ops->open)
34894 + new_m->vm_ops->open(new_m);
34897 + vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
34898 + ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
34900 + vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
34906 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
34907 unsigned long addr, int new_below)
34909 @@ -1862,17 +2225,37 @@ int split_vma(struct mm_struct * mm, str
34915 /* Munmap is split into 2 main parts -- this part which finds
34916 * what needs doing, and the areas themselves, which do the
34917 * work. This now handles partial unmappings.
34918 * Jeremy Fitzhardinge <jeremy@goop.org>
34920 +#ifdef CONFIG_PAX_SEGMEXEC
34921 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
34923 + int ret = __do_munmap(mm, start, len);
34924 + if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
34927 + return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
34930 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
34932 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
34936 struct vm_area_struct *vma, *prev, *last;
34939 + * mm->mmap_sem is required to protect against another thread
34940 + * changing the mappings in case we sleep.
34942 + verify_mm_writelocked(mm);
34944 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
34947 @@ -1922,6 +2305,8 @@ int do_munmap(struct mm_struct *mm, unsi
34948 /* Fix up all other VM information */
34949 remove_vma_list(mm, vma);
34951 + track_exec_limit(mm, start, end, 0UL);
34956 @@ -1934,22 +2319,18 @@ asmlinkage long sys_munmap(unsigned long
34958 profile_munmap(addr);
34960 +#ifdef CONFIG_PAX_SEGMEXEC
34961 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
34962 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
34966 down_write(&mm->mmap_sem);
34967 ret = do_munmap(mm, addr, len);
34968 up_write(&mm->mmap_sem);
34972 -static inline void verify_mm_writelocked(struct mm_struct *mm)
34974 -#ifdef CONFIG_DEBUG_VM
34975 - if (unlikely(down_read_trylock(&mm->mmap_sem))) {
34977 - up_read(&mm->mmap_sem);
34983 * this is really a simplified "do_mmap". it only handles
34984 * anonymous maps. eventually we may be able to do some
34985 @@ -1963,6 +2344,11 @@ unsigned long do_brk(unsigned long addr,
34986 struct rb_node ** rb_link, * rb_parent;
34987 pgoff_t pgoff = addr >> PAGE_SHIFT;
34989 + unsigned long charged;
34991 +#ifdef CONFIG_PAX_SEGMEXEC
34992 + struct vm_area_struct *vma_m = NULL;
34995 len = PAGE_ALIGN(len);
34997 @@ -1980,19 +2366,34 @@ unsigned long do_brk(unsigned long addr,
34999 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
35001 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
35002 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
35003 + flags &= ~VM_EXEC;
35005 +#ifdef CONFIG_PAX_MPROTECT
35006 + if (mm->pax_flags & MF_PAX_MPROTECT)
35007 + flags &= ~VM_MAYEXEC;
35013 error = arch_mmap_check(addr, len, flags);
35017 + charged = len >> PAGE_SHIFT;
35020 * mlock MCL_FUTURE?
35022 if (mm->def_flags & VM_LOCKED) {
35023 unsigned long locked, lock_limit;
35024 - locked = len >> PAGE_SHIFT;
35025 + locked = charged;
35026 locked += mm->locked_vm;
35027 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
35028 lock_limit >>= PAGE_SHIFT;
35029 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
35030 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
35033 @@ -2006,23 +2407,23 @@ unsigned long do_brk(unsigned long addr,
35035 * Clear old maps. this also does some error checking for us
35038 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35039 if (vma && vma->vm_start < addr + len) {
35040 if (do_munmap(mm, addr, len))
35042 - goto munmap_back;
35043 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35044 + BUG_ON(vma && vma->vm_start < addr + len);
35047 /* Check against address space limits *after* clearing old maps... */
35048 - if (!may_expand_vm(mm, len >> PAGE_SHIFT))
35049 + if (!may_expand_vm(mm, charged))
35052 if (mm->map_count > sysctl_max_map_count)
35055 - if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
35056 - !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
35057 + if (security_vm_enough_memory(charged) ||
35058 + !vx_vmpages_avail(mm, charged))
35061 /* Can we just expand an old private anonymous mapping? */
35062 @@ -2034,10 +2435,21 @@ unsigned long do_brk(unsigned long addr,
35064 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35066 - vm_unacct_memory(len >> PAGE_SHIFT);
35067 + vm_unacct_memory(charged);
35071 +#ifdef CONFIG_PAX_SEGMEXEC
35072 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
35073 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35075 + kmem_cache_free(vm_area_cachep, vma);
35076 + vm_unacct_memory(charged);
35083 vma->vm_start = addr;
35084 vma->vm_end = addr + len;
35085 @@ -2045,12 +2457,19 @@ unsigned long do_brk(unsigned long addr,
35086 vma->vm_flags = flags;
35087 vma->vm_page_prot = vm_get_page_prot(flags);
35088 vma_link(mm, vma, prev, rb_link, rb_parent);
35090 +#ifdef CONFIG_PAX_SEGMEXEC
35092 + pax_mirror_vma(vma_m, vma);
35096 - vx_vmpages_add(mm, len >> PAGE_SHIFT);
35097 + vx_vmpages_add(mm, charged);
35098 if (flags & VM_LOCKED) {
35099 - vx_vmlocked_add(mm, len >> PAGE_SHIFT);
35100 + vx_vmlocked_add(mm, charged);
35101 make_pages_present(addr, addr + len);
35103 + track_exec_limit(mm, addr, addr + len, flags);
35107 @@ -2082,8 +2501,10 @@ void exit_mmap(struct mm_struct *mm)
35108 * Walk the list again, actually closing and freeing it,
35109 * with preemption enabled, without holding any MM locks.
35113 + vma->vm_mirror = NULL;
35114 vma = remove_vma(vma);
35117 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
35119 @@ -2097,6 +2518,10 @@ int insert_vm_struct(struct mm_struct *
35120 struct vm_area_struct * __vma, * prev;
35121 struct rb_node ** rb_link, * rb_parent;
35123 +#ifdef CONFIG_PAX_SEGMEXEC
35124 + struct vm_area_struct *vma_m = NULL;
35128 * The vm_pgoff of a purely anonymous vma should be irrelevant
35129 * until its first write fault, when page's anon_vma and index
35130 @@ -2119,7 +2544,22 @@ int insert_vm_struct(struct mm_struct *
35131 if ((vma->vm_flags & VM_ACCOUNT) &&
35132 security_vm_enough_memory_mm(mm, vma_pages(vma)))
35135 +#ifdef CONFIG_PAX_SEGMEXEC
35136 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
35137 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35143 vma_link(mm, vma, prev, rb_link, rb_parent);
35145 +#ifdef CONFIG_PAX_SEGMEXEC
35147 + pax_mirror_vma(vma_m, vma);
35153 @@ -2137,6 +2577,8 @@ struct vm_area_struct *copy_vma(struct v
35154 struct rb_node **rb_link, *rb_parent;
35155 struct mempolicy *pol;
35157 + BUG_ON(vma->vm_mirror);
35160 * If anonymous vma has not yet been faulted, update new pgoff
35161 * to match new location, to increase its chance of merging.
35162 @@ -2180,6 +2622,35 @@ struct vm_area_struct *copy_vma(struct v
35166 +#ifdef CONFIG_PAX_SEGMEXEC
35167 +void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
35169 + struct vm_area_struct *prev_m;
35170 + struct rb_node **rb_link_m, *rb_parent_m;
35171 + struct mempolicy *pol_m;
35173 + BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
35174 + BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
35175 + BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
35177 + pol_m = vma_policy(vma_m);
35179 + vma_set_policy(vma_m, pol_m);
35180 + vma_m->vm_start += SEGMEXEC_TASK_SIZE;
35181 + vma_m->vm_end += SEGMEXEC_TASK_SIZE;
35182 + vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
35183 + vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
35184 + if (vma_m->vm_file)
35185 + get_file(vma_m->vm_file);
35186 + if (vma_m->vm_ops && vma_m->vm_ops->open)
35187 + vma_m->vm_ops->open(vma_m);
35188 + find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
35189 + vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
35190 + vma_m->vm_mirror = vma;
35191 + vma->vm_mirror = vma_m;
35196 * Return true if the calling process may expand its vm space by the passed
35198 @@ -2190,7 +2661,7 @@ int may_expand_vm(struct mm_struct *mm,
35201 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
35203 + gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
35204 if (cur + npages > lim)
35207 @@ -2259,6 +2730,15 @@ int install_special_mapping(struct mm_st
35208 vma->vm_start = addr;
35209 vma->vm_end = addr + len;
35211 +#ifdef CONFIG_PAX_MPROTECT
35212 + if (mm->pax_flags & MF_PAX_MPROTECT) {
35213 + if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
35214 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
35216 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
35220 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
35221 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
35223 diff -urNp linux-2.6.27.10/mm/mprotect.c linux-2.6.27.10/mm/mprotect.c
35224 --- linux-2.6.27.10/mm/mprotect.c 2008-11-07 12:55:34.000000000 -0500
35225 +++ linux-2.6.27.10/mm/mprotect.c 2008-12-21 00:45:45.000000000 -0500
35226 @@ -22,10 +22,17 @@
35227 #include <linux/swap.h>
35228 #include <linux/swapops.h>
35229 #include <linux/mmu_notifier.h>
35230 +#include <linux/grsecurity.h>
35232 +#ifdef CONFIG_PAX_MPROTECT
35233 +#include <linux/elf.h>
35236 #include <asm/uaccess.h>
35237 #include <asm/pgtable.h>
35238 #include <asm/cacheflush.h>
35239 #include <asm/tlbflush.h>
35240 +#include <asm/mmu_context.h>
35242 #ifndef pgprot_modify
35243 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
35244 @@ -133,6 +140,48 @@ static void change_protection(struct vm_
35245 flush_tlb_range(vma, start, end);
35248 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35249 +/* called while holding the mmap semaphor for writing except stack expansion */
35250 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
35252 + unsigned long oldlimit, newlimit = 0UL;
35254 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
35257 + spin_lock(&mm->page_table_lock);
35258 + oldlimit = mm->context.user_cs_limit;
35259 + if ((prot & VM_EXEC) && oldlimit < end)
35260 + /* USER_CS limit moved up */
35262 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
35263 + /* USER_CS limit moved down */
35264 + newlimit = start;
35267 + mm->context.user_cs_limit = newlimit;
35271 + cpus_clear(mm->context.cpu_user_cs_mask);
35272 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
35275 + set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
35277 + spin_unlock(&mm->page_table_lock);
35278 + if (newlimit == end) {
35279 + struct vm_area_struct *vma = find_vma(mm, oldlimit);
35281 + for (; vma && vma->vm_start < end; vma = vma->vm_next)
35282 + if (is_vm_hugetlb_page(vma))
35283 + hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
35285 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
35291 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
35292 unsigned long start, unsigned long end, unsigned long newflags)
35293 @@ -145,6 +194,14 @@ mprotect_fixup(struct vm_area_struct *vm
35295 int dirty_accountable = 0;
35297 +#ifdef CONFIG_PAX_SEGMEXEC
35298 + struct vm_area_struct *vma_m = NULL;
35299 + unsigned long start_m, end_m;
35301 + start_m = start + SEGMEXEC_TASK_SIZE;
35302 + end_m = end + SEGMEXEC_TASK_SIZE;
35305 if (newflags == oldflags) {
35308 @@ -165,6 +222,38 @@ mprotect_fixup(struct vm_area_struct *vm
35312 +#ifdef CONFIG_PAX_SEGMEXEC
35313 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
35314 + if (start != vma->vm_start) {
35315 + error = split_vma(mm, vma, start, 1);
35318 + BUG_ON(!*pprev || (*pprev)->vm_next == vma);
35319 + *pprev = (*pprev)->vm_next;
35322 + if (end != vma->vm_end) {
35323 + error = split_vma(mm, vma, end, 0);
35328 + if (pax_find_mirror_vma(vma)) {
35329 + error = __do_munmap(mm, start_m, end_m - start_m);
35333 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35338 + vma->vm_flags = newflags;
35339 + pax_mirror_vma(vma_m, vma);
35345 * First try to merge with previous and/or next vma.
35347 @@ -196,8 +285,14 @@ success:
35348 * held in write mode.
35350 vma->vm_flags = newflags;
35352 +#ifdef CONFIG_PAX_MPROTECT
35353 + if (current->binfmt && current->binfmt->handle_mprotect)
35354 + current->binfmt->handle_mprotect(vma, newflags);
35357 vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
35358 - vm_get_page_prot(newflags));
35359 + vm_get_page_prot(vma->vm_flags));
35361 if (vma_wants_writenotify(vma)) {
35362 vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
35363 @@ -238,6 +333,17 @@ sys_mprotect(unsigned long start, size_t
35368 +#ifdef CONFIG_PAX_SEGMEXEC
35369 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
35370 + if (end > SEGMEXEC_TASK_SIZE)
35375 + if (end > TASK_SIZE)
35378 if (!arch_validate_prot(prot))
35381 @@ -245,7 +351,7 @@ sys_mprotect(unsigned long start, size_t
35383 * Does the application expect PROT_READ to imply PROT_EXEC:
35385 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
35386 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
35389 vm_flags = calc_vm_prot_bits(prot);
35390 @@ -277,6 +383,16 @@ sys_mprotect(unsigned long start, size_t
35391 if (start > vma->vm_start)
35394 + if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
35399 +#ifdef CONFIG_PAX_MPROTECT
35400 + if (current->binfmt && current->binfmt->handle_mprotect)
35401 + current->binfmt->handle_mprotect(vma, vm_flags);
35404 for (nstart = start ; ; ) {
35405 unsigned long newflags;
35407 @@ -300,6 +416,9 @@ sys_mprotect(unsigned long start, size_t
35408 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
35412 + track_exec_limit(current->mm, nstart, tmp, vm_flags);
35416 if (nstart < prev->vm_end)
35417 diff -urNp linux-2.6.27.10/mm/mremap.c linux-2.6.27.10/mm/mremap.c
35418 --- linux-2.6.27.10/mm/mremap.c 2008-11-07 12:55:34.000000000 -0500
35419 +++ linux-2.6.27.10/mm/mremap.c 2008-11-18 03:38:45.000000000 -0500
35420 @@ -111,6 +111,12 @@ static void move_ptes(struct vm_area_str
35422 pte = ptep_clear_flush(vma, old_addr, old_pte);
35423 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
35425 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35426 + if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
35427 + pte = pte_exprotect(pte);
35430 set_pte_at(mm, new_addr, new_pte, pte);
35433 @@ -260,6 +266,7 @@ unsigned long do_mremap(unsigned long ad
35434 struct vm_area_struct *vma;
35435 unsigned long ret = -EINVAL;
35436 unsigned long charged = 0;
35437 + unsigned long pax_task_size = TASK_SIZE;
35439 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
35441 @@ -278,6 +285,15 @@ unsigned long do_mremap(unsigned long ad
35445 +#ifdef CONFIG_PAX_SEGMEXEC
35446 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
35447 + pax_task_size = SEGMEXEC_TASK_SIZE;
35450 + if (new_len > pax_task_size || addr > pax_task_size-new_len ||
35451 + old_len > pax_task_size || addr > pax_task_size-old_len)
35454 /* new_addr is only valid if MREMAP_FIXED is specified */
35455 if (flags & MREMAP_FIXED) {
35456 if (new_addr & ~PAGE_MASK)
35457 @@ -285,16 +301,13 @@ unsigned long do_mremap(unsigned long ad
35458 if (!(flags & MREMAP_MAYMOVE))
35461 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
35462 + if (new_addr > pax_task_size - new_len)
35465 /* Check if the location we're moving into overlaps the
35466 * old location at all, and fail if it does.
35468 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
35471 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
35472 + if (addr + old_len > new_addr && new_addr + new_len > addr)
35475 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
35476 @@ -332,6 +345,14 @@ unsigned long do_mremap(unsigned long ad
35481 +#ifdef CONFIG_PAX_SEGMEXEC
35482 + if (pax_find_mirror_vma(vma)) {
35488 /* We can't remap across vm area boundaries */
35489 if (old_len > vma->vm_end - addr)
35491 @@ -365,7 +386,7 @@ unsigned long do_mremap(unsigned long ad
35492 if (old_len == vma->vm_end - addr &&
35493 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
35494 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
35495 - unsigned long max_addr = TASK_SIZE;
35496 + unsigned long max_addr = pax_task_size;
35498 max_addr = vma->vm_next->vm_start;
35499 /* can we just expand the current mapping? */
35500 @@ -383,6 +404,7 @@ unsigned long do_mremap(unsigned long ad
35504 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
35508 @@ -393,8 +415,8 @@ unsigned long do_mremap(unsigned long ad
35511 if (flags & MREMAP_MAYMOVE) {
35512 + unsigned long map_flags = 0;
35513 if (!(flags & MREMAP_FIXED)) {
35514 - unsigned long map_flags = 0;
35515 if (vma->vm_flags & VM_MAYSHARE)
35516 map_flags |= MAP_SHARED;
35518 @@ -409,7 +431,12 @@ unsigned long do_mremap(unsigned long ad
35522 + map_flags = vma->vm_flags;
35523 ret = move_vma(vma, addr, old_len, new_len, new_addr);
35524 + if (!(ret & ~PAGE_MASK)) {
35525 + track_exec_limit(current->mm, addr, addr + old_len, 0UL);
35526 + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
35530 if (ret & ~PAGE_MASK)
35531 diff -urNp linux-2.6.27.10/mm/nommu.c linux-2.6.27.10/mm/nommu.c
35532 --- linux-2.6.27.10/mm/nommu.c 2008-11-07 12:55:34.000000000 -0500
35533 +++ linux-2.6.27.10/mm/nommu.c 2008-11-18 03:38:45.000000000 -0500
35534 @@ -437,15 +437,6 @@ struct vm_area_struct *find_vma(struct m
35536 EXPORT_SYMBOL(find_vma);
35540 - * - we don't extend stack VMAs under NOMMU conditions
35542 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
35544 - return find_vma(mm, addr);
35547 int expand_stack(struct vm_area_struct *vma, unsigned long address)
35550 diff -urNp linux-2.6.27.10/mm/page_alloc.c linux-2.6.27.10/mm/page_alloc.c
35551 --- linux-2.6.27.10/mm/page_alloc.c 2008-12-21 01:18:12.000000000 -0500
35552 +++ linux-2.6.27.10/mm/page_alloc.c 2008-12-21 01:18:22.000000000 -0500
35553 @@ -515,9 +515,20 @@ static void free_pages_bulk(struct zone
35555 static void free_one_page(struct zone *zone, struct page *page, int order)
35558 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35559 + unsigned long index = 1UL << order;
35562 spin_lock(&zone->lock);
35563 zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
35564 zone->pages_scanned = 0;
35566 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35567 + for (; index; --index)
35568 + sanitize_highpage(page + index - 1);
35571 __free_one_page(page, zone, order);
35572 spin_unlock(&zone->lock);
35574 @@ -635,8 +646,10 @@ static int prep_new_page(struct page *pa
35575 arch_alloc_page(page, order);
35576 kernel_map_pages(page, 1 << order, 1);
35578 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
35579 if (gfp_flags & __GFP_ZERO)
35580 prep_zero_page(page, order, gfp_flags);
35583 if (order && (gfp_flags & __GFP_COMP))
35584 prep_compound_page(page, order);
35585 @@ -1009,6 +1022,11 @@ static void free_hot_cold_page(struct pa
35586 list_add(&page->lru, &pcp->list);
35587 set_page_private(page, get_pageblock_migratetype(page));
35590 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35591 + sanitize_highpage(page);
35594 if (pcp->count >= pcp->high) {
35595 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
35596 pcp->count -= pcp->batch;
35597 diff -urNp linux-2.6.27.10/mm/rmap.c linux-2.6.27.10/mm/rmap.c
35598 --- linux-2.6.27.10/mm/rmap.c 2008-11-07 12:55:34.000000000 -0500
35599 +++ linux-2.6.27.10/mm/rmap.c 2008-11-18 03:38:45.000000000 -0500
35600 @@ -91,6 +91,10 @@ int anon_vma_prepare(struct vm_area_stru
35601 struct mm_struct *mm = vma->vm_mm;
35602 struct anon_vma *allocated;
35604 +#ifdef CONFIG_PAX_SEGMEXEC
35605 + struct vm_area_struct *vma_m;
35608 anon_vma = find_mergeable_anon_vma(vma);
35611 @@ -104,6 +108,15 @@ int anon_vma_prepare(struct vm_area_stru
35612 /* page_table_lock to protect against threads */
35613 spin_lock(&mm->page_table_lock);
35614 if (likely(!vma->anon_vma)) {
35616 +#ifdef CONFIG_PAX_SEGMEXEC
35617 + vma_m = pax_find_mirror_vma(vma);
35619 + vma_m->anon_vma = anon_vma;
35620 + __anon_vma_link(vma_m);
35624 vma->anon_vma = anon_vma;
35625 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
35627 diff -urNp linux-2.6.27.10/mm/shmem.c linux-2.6.27.10/mm/shmem.c
35628 --- linux-2.6.27.10/mm/shmem.c 2008-11-07 12:55:34.000000000 -0500
35629 +++ linux-2.6.27.10/mm/shmem.c 2008-11-18 03:38:45.000000000 -0500
35630 @@ -2483,7 +2483,7 @@ static struct file_system_type tmpfs_fs_
35631 .get_sb = shmem_get_sb,
35632 .kill_sb = kill_litter_super,
35634 -static struct vfsmount *shm_mnt;
35635 +struct vfsmount *shm_mnt;
35637 static int __init init_tmpfs(void)
35639 diff -urNp linux-2.6.27.10/mm/slab.c linux-2.6.27.10/mm/slab.c
35640 --- linux-2.6.27.10/mm/slab.c 2008-11-07 12:55:34.000000000 -0500
35641 +++ linux-2.6.27.10/mm/slab.c 2008-11-18 03:38:45.000000000 -0500
35642 @@ -304,7 +304,7 @@ struct kmem_list3 {
35643 * Need this for bootstrapping a per node allocator.
35645 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
35646 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
35647 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
35648 #define CACHE_CACHE 0
35649 #define SIZE_AC MAX_NUMNODES
35650 #define SIZE_L3 (2 * MAX_NUMNODES)
35651 @@ -653,14 +653,14 @@ struct cache_names {
35652 static struct cache_names __initdata cache_names[] = {
35653 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
35654 #include <linux/kmalloc_sizes.h>
35660 static struct arraycache_init initarray_cache __initdata =
35661 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35662 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35663 static struct arraycache_init initarray_generic =
35664 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35665 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35667 /* internal cache of cache description objs */
35668 static struct kmem_cache cache_cache = {
35669 @@ -2996,7 +2996,7 @@ retry:
35670 * there must be at least one object available for
35673 - BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
35674 + BUG_ON(slabp->inuse >= cachep->num);
35676 while (slabp->inuse < cachep->num && batchcount--) {
35677 STATS_INC_ALLOCED(cachep);
35678 diff -urNp linux-2.6.27.10/mm/tiny-shmem.c linux-2.6.27.10/mm/tiny-shmem.c
35679 --- linux-2.6.27.10/mm/tiny-shmem.c 2008-11-07 12:55:34.000000000 -0500
35680 +++ linux-2.6.27.10/mm/tiny-shmem.c 2008-11-18 03:38:45.000000000 -0500
35681 @@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
35682 .kill_sb = kill_litter_super,
35685 -static struct vfsmount *shm_mnt;
35686 +struct vfsmount *shm_mnt;
35688 static int __init init_tmpfs(void)
35690 diff -urNp linux-2.6.27.10/mm/util.c linux-2.6.27.10/mm/util.c
35691 --- linux-2.6.27.10/mm/util.c 2008-11-07 12:55:34.000000000 -0500
35692 +++ linux-2.6.27.10/mm/util.c 2008-11-18 03:38:45.000000000 -0500
35693 @@ -167,6 +167,12 @@ EXPORT_SYMBOL(strndup_user);
35694 void arch_pick_mmap_layout(struct mm_struct *mm)
35696 mm->mmap_base = TASK_UNMAPPED_BASE;
35698 +#ifdef CONFIG_PAX_RANDMMAP
35699 + if (mm->pax_flags & MF_PAX_RANDMMAP)
35700 + mm->mmap_base += mm->delta_mmap;
35703 mm->get_unmapped_area = arch_get_unmapped_area;
35704 mm->unmap_area = arch_unmap_area;
35706 diff -urNp linux-2.6.27.10/mm/vmalloc.c linux-2.6.27.10/mm/vmalloc.c
35707 --- linux-2.6.27.10/mm/vmalloc.c 2008-11-07 12:55:34.000000000 -0500
35708 +++ linux-2.6.27.10/mm/vmalloc.c 2008-11-18 03:38:45.000000000 -0500
35709 @@ -98,19 +98,36 @@ static int vmap_pte_range(pmd_t *pmd, un
35710 unsigned long end, pgprot_t prot, struct page ***pages)
35713 + int ret = -ENOMEM;
35715 +#ifdef CONFIG_PAX_KERNEXEC
35716 + unsigned long cr0;
35719 pte = pte_alloc_kernel(pmd, addr);
35723 +#ifdef CONFIG_PAX_KERNEXEC
35724 + pax_open_kernel(cr0);
35728 struct page *page = **pages;
35729 WARN_ON(!pte_none(*pte));
35733 set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
35735 } while (pte++, addr += PAGE_SIZE, addr != end);
35740 +#ifdef CONFIG_PAX_KERNEXEC
35741 + pax_close_kernel(cr0);
35747 static inline int vmap_pmd_range(pud_t *pud, unsigned long addr,
35748 @@ -215,6 +232,16 @@ __get_vm_area_node(unsigned long size, u
35749 unsigned long addr;
35751 BUG_ON(in_interrupt());
35753 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35754 + if (flags & VM_KERNEXEC) {
35755 + if (start != VMALLOC_START || end != VMALLOC_END)
35757 + start = (unsigned long)MODULES_VADDR;
35758 + end = (unsigned long)MODULES_END;
35762 if (flags & VM_IOREMAP) {
35763 int bit = fls(size);
35765 @@ -248,20 +275,15 @@ __get_vm_area_node(unsigned long size, u
35766 (unsigned long)tmp->addr, align);
35769 - if ((size + addr) < addr)
35771 if (size + addr <= (unsigned long)tmp->addr)
35774 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
35775 - if (addr > end - size)
35778 if ((size + addr) < addr)
35780 if (addr > end - size)
35787 @@ -466,6 +488,11 @@ void *vmap(struct page **pages, unsigned
35788 if (count > num_physpages)
35791 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35792 + if (!(pgprot_val(prot) & _PAGE_NX))
35793 + flags |= VM_KERNEXEC;
35796 area = get_vm_area_caller((count << PAGE_SHIFT), flags,
35797 __builtin_return_address(0));
35799 @@ -560,6 +587,13 @@ static void *__vmalloc_node(unsigned lon
35800 if (!size || (size >> PAGE_SHIFT) > num_physpages)
35803 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35804 + if (!(pgprot_val(prot) & _PAGE_NX))
35805 + area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
35806 + node, gfp_mask, caller);
35810 area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
35811 node, gfp_mask, caller);
35813 @@ -651,7 +685,7 @@ EXPORT_SYMBOL(vmalloc_node);
35815 void *vmalloc_exec(unsigned long size)
35817 - return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
35818 + return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC);
35821 #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
35822 diff -urNp linux-2.6.27.10/net/bridge/br_stp_if.c linux-2.6.27.10/net/bridge/br_stp_if.c
35823 --- linux-2.6.27.10/net/bridge/br_stp_if.c 2008-11-07 12:55:34.000000000 -0500
35824 +++ linux-2.6.27.10/net/bridge/br_stp_if.c 2008-11-18 03:38:45.000000000 -0500
35825 @@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg
35826 char *envp[] = { NULL };
35828 if (br->stp_enabled == BR_USER_STP) {
35829 - r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
35830 + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
35831 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
35834 diff -urNp linux-2.6.27.10/net/core/flow.c linux-2.6.27.10/net/core/flow.c
35835 --- linux-2.6.27.10/net/core/flow.c 2008-11-07 12:55:34.000000000 -0500
35836 +++ linux-2.6.27.10/net/core/flow.c 2008-11-18 03:38:45.000000000 -0500
35837 @@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
35839 static u32 flow_hash_shift;
35840 #define flow_hash_size (1 << flow_hash_shift)
35841 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
35842 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
35844 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
35846 @@ -52,7 +52,7 @@ struct flow_percpu_info {
35850 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
35851 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
35853 #define flow_hash_rnd_recalc(cpu) \
35854 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
35855 @@ -69,7 +69,7 @@ struct flow_flush_info {
35857 struct completion completion;
35859 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
35860 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
35862 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
35864 diff -urNp linux-2.6.27.10/net/dccp/ccids/ccid3.c linux-2.6.27.10/net/dccp/ccids/ccid3.c
35865 --- linux-2.6.27.10/net/dccp/ccids/ccid3.c 2008-11-07 12:55:34.000000000 -0500
35866 +++ linux-2.6.27.10/net/dccp/ccids/ccid3.c 2008-11-18 03:38:45.000000000 -0500
35868 static int ccid3_debug;
35869 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
35871 -#define ccid3_pr_debug(format, a...)
35872 +#define ccid3_pr_debug(format, a...) do {} while (0)
35876 diff -urNp linux-2.6.27.10/net/dccp/dccp.h linux-2.6.27.10/net/dccp/dccp.h
35877 --- linux-2.6.27.10/net/dccp/dccp.h 2008-11-07 12:55:34.000000000 -0500
35878 +++ linux-2.6.27.10/net/dccp/dccp.h 2008-11-18 03:38:45.000000000 -0500
35879 @@ -43,8 +43,8 @@ extern int dccp_debug;
35880 #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
35881 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
35883 -#define dccp_pr_debug(format, a...)
35884 -#define dccp_pr_debug_cat(format, a...)
35885 +#define dccp_pr_debug(format, a...) do {} while (0)
35886 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
35889 extern struct inet_hashinfo dccp_hashinfo;
35890 diff -urNp linux-2.6.27.10/net/ipv4/inet_connection_sock.c linux-2.6.27.10/net/ipv4/inet_connection_sock.c
35891 --- linux-2.6.27.10/net/ipv4/inet_connection_sock.c 2008-11-07 12:55:34.000000000 -0500
35892 +++ linux-2.6.27.10/net/ipv4/inet_connection_sock.c 2008-11-18 03:38:45.000000000 -0500
35895 #include <linux/module.h>
35896 #include <linux/jhash.h>
35897 +#include <linux/grsecurity.h>
35899 #include <net/inet_connection_sock.h>
35900 #include <net/inet_hashtables.h>
35901 diff -urNp linux-2.6.27.10/net/ipv4/inet_hashtables.c linux-2.6.27.10/net/ipv4/inet_hashtables.c
35902 --- linux-2.6.27.10/net/ipv4/inet_hashtables.c 2008-11-07 12:55:34.000000000 -0500
35903 +++ linux-2.6.27.10/net/ipv4/inet_hashtables.c 2008-11-18 03:38:45.000000000 -0500
35904 @@ -18,12 +18,15 @@
35905 #include <linux/sched.h>
35906 #include <linux/slab.h>
35907 #include <linux/wait.h>
35908 +#include <linux/grsecurity.h>
35910 #include <net/inet_connection_sock.h>
35911 #include <net/inet_hashtables.h>
35912 #include <net/route.h>
35913 #include <net/ip.h>
35915 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
35918 * Allocate and initialize a new local port bind bucket.
35919 * The bindhash mutex for snum's hash chain must be held here.
35920 @@ -487,6 +490,8 @@ ok:
35922 spin_unlock(&head->lock);
35924 + gr_update_task_in_ip_table(current, inet_sk(sk));
35927 inet_twsk_deschedule(tw, death_row);
35929 diff -urNp linux-2.6.27.10/net/ipv4/netfilter/ipt_stealth.c linux-2.6.27.10/net/ipv4/netfilter/ipt_stealth.c
35930 --- linux-2.6.27.10/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
35931 +++ linux-2.6.27.10/net/ipv4/netfilter/ipt_stealth.c 2008-11-18 03:38:45.000000000 -0500
35933 +/* Kernel module to add stealth support.
35935 + * Copyright (C) 2002-2006 Brad Spengler <spender@grsecurity.net>
35939 +#include <linux/kernel.h>
35940 +#include <linux/module.h>
35941 +#include <linux/skbuff.h>
35942 +#include <linux/net.h>
35943 +#include <linux/sched.h>
35944 +#include <linux/inet.h>
35945 +#include <linux/stddef.h>
35947 +#include <net/ip.h>
35948 +#include <net/sock.h>
35949 +#include <net/tcp.h>
35950 +#include <net/udp.h>
35951 +#include <net/route.h>
35952 +#include <net/inet_common.h>
35954 +#include <linux/netfilter_ipv4/ip_tables.h>
35956 +MODULE_LICENSE("GPL");
35958 +extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
35961 +match(const struct sk_buff *skb,
35962 + const struct net_device *in,
35963 + const struct net_device *out,
35964 + const struct xt_match *match,
35965 + const void *matchinfo,
35967 + unsigned int protoff,
35970 + struct iphdr *ip = ip_hdr(skb);
35971 + struct tcphdr th;
35972 + struct udphdr uh;
35973 + struct sock *sk = NULL;
35975 + if (!ip || offset) return false;
35977 + switch(ip->protocol) {
35978 + case IPPROTO_TCP:
35979 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
35983 + if (!(th.syn && !th.ack)) return false;
35984 + sk = inet_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
35986 + case IPPROTO_UDP:
35987 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
35991 + sk = udp_v4_lookup(dev_net(skb->dev), ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
35997 + if(!sk) // port is being listened on, match this
36005 +/* Called when user tries to insert an entry of this type. */
36007 +checkentry(const char *tablename,
36009 + const struct xt_match *match,
36011 + unsigned int hook_mask)
36013 + const struct ipt_ip *ip = (const struct ipt_ip *)nip;
36015 + if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
36016 + ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
36017 + && (hook_mask & (1 << NF_INET_LOCAL_IN)))
36020 + printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
36026 +static struct xt_match stealth_match __read_mostly = {
36027 + .name = "stealth",
36028 + .family = AF_INET,
36030 + .checkentry = checkentry,
36032 + .me = THIS_MODULE
36035 +static int __init init(void)
36037 + return xt_register_match(&stealth_match);
36040 +static void __exit fini(void)
36042 + xt_unregister_match(&stealth_match);
36045 +module_init(init);
36046 +module_exit(fini);
36047 diff -urNp linux-2.6.27.10/net/ipv4/netfilter/Kconfig linux-2.6.27.10/net/ipv4/netfilter/Kconfig
36048 --- linux-2.6.27.10/net/ipv4/netfilter/Kconfig 2008-11-07 12:55:34.000000000 -0500
36049 +++ linux-2.6.27.10/net/ipv4/netfilter/Kconfig 2008-11-18 03:38:45.000000000 -0500
36050 @@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
36051 If you want to compile it as a module, say M here and read
36052 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
36054 +config IP_NF_MATCH_STEALTH
36055 + tristate "stealth match support"
36056 + depends on IP_NF_IPTABLES
36058 + Enabling this option will drop all syn packets coming to unserved tcp
36059 + ports as well as all packets coming to unserved udp ports. If you
36060 + are using your system to route any type of packets (ie. via NAT)
36061 + you should put this module at the end of your ruleset, since it will
36062 + drop packets that aren't going to ports that are listening on your
36063 + machine itself, it doesn't take into account that the packet might be
36064 + destined for someone on your internal network if you're using NAT for
36067 + To compile it as a module, choose M here. If unsure, say N.
36069 # `filter', generic and specific targets
36070 config IP_NF_FILTER
36071 tristate "Packet filtering"
36072 @@ -407,4 +422,3 @@ config IP_NF_ARP_MANGLE
36073 hardware and network addresses.
36077 diff -urNp linux-2.6.27.10/net/ipv4/netfilter/Makefile linux-2.6.27.10/net/ipv4/netfilter/Makefile
36078 --- linux-2.6.27.10/net/ipv4/netfilter/Makefile 2008-11-07 12:55:34.000000000 -0500
36079 +++ linux-2.6.27.10/net/ipv4/netfilter/Makefile 2008-11-18 03:38:45.000000000 -0500
36080 @@ -59,6 +59,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
36081 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
36082 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
36083 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
36084 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
36085 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
36086 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
36088 diff -urNp linux-2.6.27.10/net/ipv4/tcp_ipv4.c linux-2.6.27.10/net/ipv4/tcp_ipv4.c
36089 --- linux-2.6.27.10/net/ipv4/tcp_ipv4.c 2008-11-07 12:55:34.000000000 -0500
36090 +++ linux-2.6.27.10/net/ipv4/tcp_ipv4.c 2008-11-18 03:38:45.000000000 -0500
36092 #include <linux/jhash.h>
36093 #include <linux/init.h>
36094 #include <linux/times.h>
36095 +#include <linux/grsecurity.h>
36097 #include <net/net_namespace.h>
36098 #include <net/icmp.h>
36099 diff -urNp linux-2.6.27.10/net/ipv4/udp.c linux-2.6.27.10/net/ipv4/udp.c
36100 --- linux-2.6.27.10/net/ipv4/udp.c 2008-12-21 01:16:52.000000000 -0500
36101 +++ linux-2.6.27.10/net/ipv4/udp.c 2008-12-21 01:13:47.000000000 -0500
36103 #include <linux/skbuff.h>
36104 #include <linux/proc_fs.h>
36105 #include <linux/seq_file.h>
36106 +#include <linux/grsecurity.h>
36107 #include <net/net_namespace.h>
36108 #include <net/icmp.h>
36109 #include <net/route.h>
36110 @@ -104,6 +105,11 @@
36111 #include <net/xfrm.h>
36112 #include "udp_impl.h"
36114 +extern int gr_search_udp_recvmsg(const struct sock *sk,
36115 + const struct sk_buff *skb);
36116 +extern int gr_search_udp_sendmsg(const struct sock *sk,
36117 + const struct sockaddr_in *addr);
36120 * Snmp MIB for the UDP layer
36122 @@ -302,6 +308,13 @@ static struct sock *__udp4_lib_lookup(st
36126 +struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
36127 + __be32 daddr, __be16 dport, int dif)
36129 + return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
36133 static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk,
36134 __be16 loc_port, __be32 loc_addr,
36135 __be16 rmt_port, __be32 rmt_addr,
36136 @@ -592,9 +605,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
36137 dport = usin->sin_port;
36141 + if (!gr_search_udp_sendmsg(sk, usin))
36144 if (sk->sk_state != TCP_ESTABLISHED)
36145 return -EDESTADDRREQ;
36147 + if (!gr_search_udp_sendmsg(sk, NULL))
36150 daddr = inet->daddr;
36151 dport = inet->dport;
36152 /* Open fast path for connected socket.
36153 @@ -859,6 +879,11 @@ try_again:
36157 + if (!gr_search_udp_recvmsg(sk, skb)) {
36162 ulen = skb->len - sizeof(struct udphdr);
36165 diff -urNp linux-2.6.27.10/net/ipv6/exthdrs.c linux-2.6.27.10/net/ipv6/exthdrs.c
36166 --- linux-2.6.27.10/net/ipv6/exthdrs.c 2008-11-07 12:55:34.000000000 -0500
36167 +++ linux-2.6.27.10/net/ipv6/exthdrs.c 2008-11-18 03:38:45.000000000 -0500
36168 @@ -624,7 +624,7 @@ static struct tlvtype_proc tlvprochopopt
36169 .type = IPV6_TLV_JUMBO,
36170 .func = ipv6_hop_jumbo,
36176 int ipv6_parse_hopopts(struct sk_buff *skb)
36177 diff -urNp linux-2.6.27.10/net/ipv6/raw.c linux-2.6.27.10/net/ipv6/raw.c
36178 --- linux-2.6.27.10/net/ipv6/raw.c 2008-11-07 12:55:34.000000000 -0500
36179 +++ linux-2.6.27.10/net/ipv6/raw.c 2008-11-18 03:38:45.000000000 -0500
36180 @@ -600,7 +600,7 @@ out:
36184 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
36185 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
36186 struct flowi *fl, struct rt6_info *rt,
36187 unsigned int flags)
36189 diff -urNp linux-2.6.27.10/net/irda/ircomm/ircomm_tty.c linux-2.6.27.10/net/irda/ircomm/ircomm_tty.c
36190 --- linux-2.6.27.10/net/irda/ircomm/ircomm_tty.c 2008-11-07 12:55:34.000000000 -0500
36191 +++ linux-2.6.27.10/net/irda/ircomm/ircomm_tty.c 2008-11-18 03:38:45.000000000 -0500
36192 @@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
36193 IRDA_DEBUG(2, "%s()\n", __func__ );
36196 - if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
36197 + if (line >= IRCOMM_TTY_PORTS) {
36201 diff -urNp linux-2.6.27.10/net/sctp/socket.c linux-2.6.27.10/net/sctp/socket.c
36202 --- linux-2.6.27.10/net/sctp/socket.c 2008-11-07 12:55:34.000000000 -0500
36203 +++ linux-2.6.27.10/net/sctp/socket.c 2008-11-18 03:38:45.000000000 -0500
36204 @@ -1434,7 +1434,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
36205 struct sctp_sndrcvinfo *sinfo;
36206 struct sctp_initmsg *sinit;
36207 sctp_assoc_t associd = 0;
36208 - sctp_cmsgs_t cmsgs = { NULL };
36209 + sctp_cmsgs_t cmsgs = { NULL, NULL };
36211 sctp_scope_t scope;
36213 @@ -5616,7 +5616,6 @@ pp_found:
36215 int reuse = sk->sk_reuse;
36217 - struct hlist_node *node;
36219 SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
36220 if (pp->fastreuse && sk->sk_reuse &&
36221 diff -urNp linux-2.6.27.10/net/socket.c linux-2.6.27.10/net/socket.c
36222 --- linux-2.6.27.10/net/socket.c 2008-11-07 12:55:34.000000000 -0500
36223 +++ linux-2.6.27.10/net/socket.c 2008-11-18 03:38:45.000000000 -0500
36225 #include <linux/audit.h>
36226 #include <linux/wireless.h>
36227 #include <linux/nsproxy.h>
36228 +#include <linux/in.h>
36230 #include <asm/uaccess.h>
36231 #include <asm/unistd.h>
36233 #include <net/sock.h>
36234 #include <linux/netfilter.h>
36236 +extern void gr_attach_curr_ip(const struct sock *sk);
36237 +extern int gr_handle_sock_all(const int family, const int type,
36238 + const int protocol);
36239 +extern int gr_handle_sock_server(const struct sockaddr *sck);
36240 +extern int gr_handle_sock_server_other(const struct socket *sck);
36241 +extern int gr_handle_sock_client(const struct sockaddr *sck);
36242 +extern int gr_search_connect(const struct socket * sock,
36243 + const struct sockaddr_in * addr);
36244 +extern int gr_search_bind(const struct socket * sock,
36245 + const struct sockaddr_in * addr);
36246 +extern int gr_search_listen(const struct socket * sock);
36247 +extern int gr_search_accept(const struct socket * sock);
36248 +extern int gr_search_socket(const int domain, const int type,
36249 + const int protocol);
36251 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
36252 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
36253 unsigned long nr_segs, loff_t pos);
36254 @@ -300,7 +316,7 @@ static int sockfs_get_sb(struct file_sys
36258 -static struct vfsmount *sock_mnt __read_mostly;
36259 +struct vfsmount *sock_mnt __read_mostly;
36261 static struct file_system_type sock_fs_type = {
36263 @@ -1236,6 +1252,16 @@ asmlinkage long sys_socket(int family, i
36264 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
36265 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
36267 + if(!gr_search_socket(family, type, protocol)) {
36268 + retval = -EACCES;
36272 + if (gr_handle_sock_all(family, type, protocol)) {
36273 + retval = -EACCES;
36277 retval = sock_create(family, type, protocol, &sock);
36280 @@ -1375,6 +1401,12 @@ asmlinkage long sys_bind(int fd, struct
36282 err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
36284 + if (!gr_search_bind(sock, (struct sockaddr_in *)&address) ||
36285 + gr_handle_sock_server((struct sockaddr *)&address)) {
36290 err = security_socket_bind(sock,
36291 (struct sockaddr *)&address,
36293 @@ -1383,6 +1415,7 @@ asmlinkage long sys_bind(int fd, struct
36294 (struct sockaddr *)
36295 &address, addrlen);
36298 fput_light(sock->file, fput_needed);
36301 @@ -1406,10 +1439,17 @@ asmlinkage long sys_listen(int fd, int b
36302 if ((unsigned)backlog > somaxconn)
36303 backlog = somaxconn;
36305 + if (gr_handle_sock_server_other(sock) ||
36306 + !gr_search_listen(sock)) {
36311 err = security_socket_listen(sock, backlog);
36313 err = sock->ops->listen(sock, backlog);
36316 fput_light(sock->file, fput_needed);
36319 @@ -1452,6 +1492,13 @@ long do_accept(int fd, struct sockaddr _
36320 newsock->type = sock->type;
36321 newsock->ops = sock->ops;
36323 + if (gr_handle_sock_server_other(sock) ||
36324 + !gr_search_accept(sock)) {
36326 + sock_release(newsock);
36331 * We don't need try_module_get here, as the listening socket (sock)
36332 * has the protocol module (sock->ops->owner) held.
36333 @@ -1495,6 +1542,7 @@ long do_accept(int fd, struct sockaddr _
36336 security_socket_post_accept(sock, newsock);
36337 + gr_attach_curr_ip(newsock->sk);
36340 fput_light(sock->file, fput_needed);
36341 @@ -1589,6 +1637,7 @@ asmlinkage long sys_connect(int fd, stru
36344 struct socket *sock;
36345 + struct sockaddr *sck;
36346 struct sockaddr_storage address;
36347 int err, fput_needed;
36349 @@ -1599,6 +1648,13 @@ asmlinkage long sys_connect(int fd, stru
36353 + sck = (struct sockaddr *)&address;
36354 + if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
36355 + gr_handle_sock_client(sck)) {
36361 security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
36363 @@ -1866,6 +1922,7 @@ asmlinkage long sys_shutdown(int fd, int
36364 err = sock->ops->shutdown(sock, how);
36365 fput_light(sock->file, fput_needed);
36371 diff -urNp linux-2.6.27.10/net/unix/af_unix.c linux-2.6.27.10/net/unix/af_unix.c
36372 --- linux-2.6.27.10/net/unix/af_unix.c 2008-12-21 01:16:52.000000000 -0500
36373 +++ linux-2.6.27.10/net/unix/af_unix.c 2008-12-21 01:13:47.000000000 -0500
36374 @@ -114,6 +114,7 @@
36375 #include <linux/security.h>
36376 #include <linux/vs_context.h>
36377 #include <linux/vs_limit.h>
36378 +#include <linux/grsecurity.h>
36380 static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
36381 static DEFINE_SPINLOCK(unix_table_lock);
36382 @@ -725,6 +726,12 @@ static struct sock *unix_find_other(stru
36383 err = -ECONNREFUSED;
36384 if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
36387 + if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
36392 u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
36395 @@ -745,6 +752,13 @@ static struct sock *unix_find_other(stru
36397 struct dentry *dentry;
36398 dentry = unix_sk(u)->dentry;
36400 + if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
36407 touch_atime(unix_sk(u)->mnt, dentry);
36409 @@ -827,10 +841,20 @@ static int unix_bind(struct socket *sock
36410 err = mnt_want_write(nd.path.mnt);
36412 goto out_mknod_dput;
36414 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
36416 + mnt_drop_write(nd.path.mnt);
36417 + goto out_mknod_dput;
36420 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
36421 mnt_drop_write(nd.path.mnt);
36423 goto out_mknod_dput;
36425 + gr_handle_create(dentry, nd.path.mnt);
36427 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
36428 dput(nd.path.dentry);
36429 nd.path.dentry = dentry;
36430 @@ -848,6 +872,10 @@ static int unix_bind(struct socket *sock
36434 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
36435 + sk->sk_peercred.pid = current->pid;
36438 list = &unix_socket_table[addr->hash];
36440 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
36441 diff -urNp linux-2.6.27.10/scripts/pnmtologo.c linux-2.6.27.10/scripts/pnmtologo.c
36442 --- linux-2.6.27.10/scripts/pnmtologo.c 2008-11-07 12:55:34.000000000 -0500
36443 +++ linux-2.6.27.10/scripts/pnmtologo.c 2008-11-18 03:38:45.000000000 -0500
36444 @@ -237,14 +237,14 @@ static void write_header(void)
36445 fprintf(out, " * Linux logo %s\n", logoname);
36446 fputs(" */\n\n", out);
36447 fputs("#include <linux/linux_logo.h>\n\n", out);
36448 - fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
36449 + fprintf(out, "static unsigned char %s_data[] = {\n",
36453 static void write_footer(void)
36455 fputs("\n};\n\n", out);
36456 - fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
36457 + fprintf(out, "struct linux_logo %s = {\n", logoname);
36458 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
36459 fprintf(out, " .width\t= %d,\n", logo_width);
36460 fprintf(out, " .height\t= %d,\n", logo_height);
36461 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
36462 fputs("\n};\n\n", out);
36464 /* write logo clut */
36465 - fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
36466 + fprintf(out, "static unsigned char %s_clut[] = {\n",
36469 for (i = 0; i < logo_clutsize; i++) {
36470 diff -urNp linux-2.6.27.10/security/commoncap.c linux-2.6.27.10/security/commoncap.c
36471 --- linux-2.6.27.10/security/commoncap.c 2008-11-07 12:55:34.000000000 -0500
36472 +++ linux-2.6.27.10/security/commoncap.c 2008-11-18 03:38:45.000000000 -0500
36473 @@ -26,10 +26,13 @@
36474 #include <linux/prctl.h>
36475 #include <linux/securebits.h>
36476 #include <linux/vs_context.h>
36477 +#include <linux/grsecurity.h>
36479 +extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
36481 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
36483 - NETLINK_CB(skb).eff_cap = vx_mbcaps(current->cap_effective);
36484 + NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
36488 @@ -51,7 +54,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
36489 int cap_capable (struct task_struct *tsk, int cap)
36491 /* Derived from include/linux/sched.h:capable. */
36492 - if (vx_cap_raised(vxi, tsk->cap_effective, cap))
36493 + if (vx_cap_raised(vxi, tsk->cap_effective, cap))
36498 +int cap_capable_nolog (struct task_struct *tsk, int cap)
36500 + /* tsk = current for all callers */
36501 + if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
36505 @@ -379,8 +390,11 @@ void cap_bprm_apply_creds (struct linux_
36509 - current->suid = current->euid = current->fsuid = bprm->e_uid;
36510 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
36511 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
36512 + current->suid = current->euid = current->fsuid = bprm->e_uid;
36514 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
36515 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
36517 /* For init, we want to retain the capabilities set
36518 * in the init_task struct. Thus we skip the usual
36519 @@ -393,6 +407,8 @@ void cap_bprm_apply_creds (struct linux_
36520 cap_clear(current->cap_effective);
36523 + gr_handle_chroot_caps(current);
36525 /* AUD: Audit candidate if current->cap_effective is set */
36527 current->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
36528 @@ -705,7 +721,7 @@ int cap_vm_enough_memory(struct mm_struc
36530 int cap_sys_admin = 0;
36532 - if (cap_capable(current, CAP_SYS_ADMIN) == 0)
36533 + if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
36535 return __vm_enough_memory(mm, pages, cap_sys_admin);
36537 diff -urNp linux-2.6.27.10/security/Kconfig linux-2.6.27.10/security/Kconfig
36538 --- linux-2.6.27.10/security/Kconfig 2008-11-07 12:55:34.000000000 -0500
36539 +++ linux-2.6.27.10/security/Kconfig 2008-11-18 03:38:45.000000000 -0500
36542 menu "Security options"
36544 +source grsecurity/Kconfig
36549 + bool "Enable various PaX features"
36550 + depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
36552 + This allows you to enable various PaX features. PaX adds
36553 + intrusion prevention mechanisms to the kernel that reduce
36554 + the risks posed by exploitable memory corruption bugs.
36556 +menu "PaX Control"
36559 +config PAX_SOFTMODE
36560 + bool 'Support soft mode'
36562 + Enabling this option will allow you to run PaX in soft mode, that
36563 + is, PaX features will not be enforced by default, only on executables
36564 + marked explicitly. You must also enable PT_PAX_FLAGS support as it
36565 + is the only way to mark executables for soft mode use.
36567 + Soft mode can be activated by using the "pax_softmode=1" kernel command
36568 + line option on boot. Furthermore you can control various PaX features
36569 + at runtime via the entries in /proc/sys/kernel/pax.
36572 + bool 'Use legacy ELF header marking'
36574 + Enabling this option will allow you to control PaX features on
36575 + a per executable basis via the 'chpax' utility available at
36576 + http://pax.grsecurity.net/. The control flags will be read from
36577 + an otherwise reserved part of the ELF header. This marking has
36578 + numerous drawbacks (no support for soft-mode, toolchain does not
36579 + know about the non-standard use of the ELF header) therefore it
36580 + has been deprecated in favour of PT_PAX_FLAGS support.
36582 + If you have applications not marked by the PT_PAX_FLAGS ELF
36583 + program header then you MUST enable this option otherwise they
36584 + will not get any protection.
36586 + Note that if you enable PT_PAX_FLAGS marking support as well,
36587 + the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
36589 +config PAX_PT_PAX_FLAGS
36590 + bool 'Use ELF program header marking'
36592 + Enabling this option will allow you to control PaX features on
36593 + a per executable basis via the 'paxctl' utility available at
36594 + http://pax.grsecurity.net/. The control flags will be read from
36595 + a PaX specific ELF program header (PT_PAX_FLAGS). This marking
36596 + has the benefits of supporting both soft mode and being fully
36597 + integrated into the toolchain (the binutils patch is available
36598 + from http://pax.grsecurity.net).
36600 + If you have applications not marked by the PT_PAX_FLAGS ELF
36601 + program header then you MUST enable the EI_PAX marking support
36602 + otherwise they will not get any protection.
36604 + Note that if you enable the legacy EI_PAX marking support as well,
36605 + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
36608 + prompt 'MAC system integration'
36609 + default PAX_HAVE_ACL_FLAGS
36611 + Mandatory Access Control systems have the option of controlling
36612 + PaX flags on a per executable basis, choose the method supported
36613 + by your particular system.
36615 + - "none": if your MAC system does not interact with PaX,
36616 + - "direct": if your MAC system defines pax_set_initial_flags() itself,
36617 + - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
36619 + NOTE: this option is for developers/integrators only.
36621 + config PAX_NO_ACL_FLAGS
36624 + config PAX_HAVE_ACL_FLAGS
36627 + config PAX_HOOK_ACL_FLAGS
36633 +menu "Non-executable pages"
36637 + bool "Enforce non-executable pages"
36638 + depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
36640 + By design some architectures do not allow for protecting memory
36641 + pages against execution or even if they do, Linux does not make
36642 + use of this feature. In practice this means that if a page is
36643 + readable (such as the stack or heap) it is also executable.
36645 + There is a well known exploit technique that makes use of this
36646 + fact and a common programming mistake where an attacker can
36647 + introduce code of his choice somewhere in the attacked program's
36648 + memory (typically the stack or the heap) and then execute it.
36650 + If the attacked program was running with different (typically
36651 + higher) privileges than that of the attacker, then he can elevate
36652 + his own privilege level (e.g. get a root shell, write to files for
36653 + which he does not have write access to, etc).
36655 + Enabling this option will let you choose from various features
36656 + that prevent the injection and execution of 'foreign' code in
36659 + This will also break programs that rely on the old behaviour and
36660 + expect that dynamically allocated memory via the malloc() family
36661 + of functions is executable (which it is not). Notable examples
36662 + are the XFree86 4.x server, the java runtime and wine.
36664 +config PAX_PAGEEXEC
36665 + bool "Paging based non-executable pages"
36666 + depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7)
36668 + This implementation is based on the paging feature of the CPU.
36669 + On i386 without hardware non-executable bit support there is a
36670 + variable but usually low performance impact, however on Intel's
36671 + P4 core based CPUs it is very high so you should not enable this
36672 + for kernels meant to be used on such CPUs.
36674 + On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
36675 + with hardware non-executable bit support there is no performance
36676 + impact, on ppc the impact is negligible.
36678 + Note that several architectures require various emulations due to
36679 + badly designed userland ABIs, this will cause a performance impact
36680 + but will disappear as soon as userland is fixed (e.g., ppc users
36681 + can make use of the secure-plt feature found in binutils).
36683 +config PAX_SEGMEXEC
36684 + bool "Segmentation based non-executable pages"
36685 + depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
36687 + This implementation is based on the segmentation feature of the
36688 + CPU and has a very small performance impact, however applications
36689 + will be limited to a 1.5 GB address space instead of the normal
36692 +config PAX_EMUTRAMP
36693 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
36694 + default y if PARISC || PPC32
36696 + There are some programs and libraries that for one reason or
36697 + another attempt to execute special small code snippets from
36698 + non-executable memory pages. Most notable examples are the
36699 + signal handler return code generated by the kernel itself and
36700 + the GCC trampolines.
36702 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
36703 + such programs will no longer work under your kernel.
36705 + As a remedy you can say Y here and use the 'chpax' or 'paxctl'
36706 + utilities to enable trampoline emulation for the affected programs
36707 + yet still have the protection provided by the non-executable pages.
36709 + On parisc and ppc you MUST enable this option and EMUSIGRT as
36710 + well, otherwise your system will not even boot.
36712 + Alternatively you can say N here and use the 'chpax' or 'paxctl'
36713 + utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
36714 + for the affected files.
36716 + NOTE: enabling this feature *may* open up a loophole in the
36717 + protection provided by non-executable pages that an attacker
36718 + could abuse. Therefore the best solution is to not have any
36719 + files on your system that would require this option. This can
36720 + be achieved by not using libc5 (which relies on the kernel
36721 + signal handler return code) and not using or rewriting programs
36722 + that make use of the nested function implementation of GCC.
36723 + Skilled users can just fix GCC itself so that it implements
36724 + nested function calls in a way that does not interfere with PaX.
36726 +config PAX_EMUSIGRT
36727 + bool "Automatically emulate sigreturn trampolines"
36728 + depends on PAX_EMUTRAMP && (PARISC || PPC32)
36731 + Enabling this option will have the kernel automatically detect
36732 + and emulate signal return trampolines executing on the stack
36733 + that would otherwise lead to task termination.
36735 + This solution is intended as a temporary one for users with
36736 + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
36737 + Modula-3 runtime, etc) or executables linked to such, basically
36738 + everything that does not specify its own SA_RESTORER function in
36739 + normal executable memory like glibc 2.1+ does.
36741 + On parisc and ppc you MUST enable this option, otherwise your
36742 + system will not even boot.
36744 + NOTE: this feature cannot be disabled on a per executable basis
36745 + and since it *does* open up a loophole in the protection provided
36746 + by non-executable pages, the best solution is to not have any
36747 + files on your system that would require this option.
36749 +config PAX_MPROTECT
36750 + bool "Restrict mprotect()"
36751 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
36753 + Enabling this option will prevent programs from
36754 + - changing the executable status of memory pages that were
36755 + not originally created as executable,
36756 + - making read-only executable pages writable again,
36757 + - creating executable pages from anonymous memory.
36759 + You should say Y here to complete the protection provided by
36760 + the enforcement of non-executable pages.
36762 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36763 + this feature on a per file basis.
36765 +config PAX_NOELFRELOCS
36766 + bool "Disallow ELF text relocations"
36767 + depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
36769 + Non-executable pages and mprotect() restrictions are effective
36770 + in preventing the introduction of new executable code into an
36771 + attacked task's address space. There remain only two venues
36772 + for this kind of attack: if the attacker can execute already
36773 + existing code in the attacked task then he can either have it
36774 + create and mmap() a file containing his code or have it mmap()
36775 + an already existing ELF library that does not have position
36776 + independent code in it and use mprotect() on it to make it
36777 + writable and copy his code there. While protecting against
36778 + the former approach is beyond PaX, the latter can be prevented
36779 + by having only PIC ELF libraries on one's system (which do not
36780 + need to relocate their code). If you are sure this is your case,
36781 + then enable this option otherwise be careful as you may not even
36782 + be able to boot or log on your system (for example, some PAM
36783 + modules are erroneously compiled as non-PIC by default).
36785 + NOTE: if you are using dynamic ELF executables (as suggested
36786 + when using ASLR) then you must have made sure that you linked
36787 + your files using the PIC version of crt1 (the et_dyn.tar.gz package
36788 + referenced there has already been updated to support this).
36790 +config PAX_ETEXECRELOCS
36791 + bool "Allow ELF ET_EXEC text relocations"
36792 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
36795 + On some architectures there are incorrectly created applications
36796 + that require text relocations and would not work without enabling
36797 + this option. If you are an alpha, ia64 or parisc user, you should
36798 + enable this option and disable it once you have made sure that
36799 + none of your applications need it.
36802 + bool "Automatically emulate ELF PLT"
36803 + depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
36806 + Enabling this option will have the kernel automatically detect
36807 + and emulate the Procedure Linkage Table entries in ELF files.
36808 + On some architectures such entries are in writable memory, and
36809 + become non-executable leading to task termination. Therefore
36810 + it is mandatory that you enable this option on alpha, parisc,
36811 + ppc (if secure-plt is not used throughout in userland), sparc
36812 + and sparc64, otherwise your system would not even boot.
36814 + NOTE: this feature *does* open up a loophole in the protection
36815 + provided by the non-executable pages, therefore the proper
36816 + solution is to modify the toolchain to produce a PLT that does
36817 + not need to be writable.
36819 +config PAX_DLRESOLVE
36821 + depends on PAX_EMUPLT && (SPARC32 || SPARC64)
36824 +config PAX_SYSCALL
36826 + depends on PAX_PAGEEXEC && PPC32
36829 +config PAX_KERNEXEC
36830 + bool "Enforce non-executable kernel pages"
36831 + depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
36833 + This is the kernel land equivalent of PAGEEXEC and MPROTECT,
36834 + that is, enabling this option will make it harder to inject
36835 + and execute 'foreign' code in kernel memory itself.
36839 +menu "Address Space Layout Randomization"
36843 + bool "Address Space Layout Randomization"
36844 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
36846 + Many if not most exploit techniques rely on the knowledge of
36847 + certain addresses in the attacked program. The following options
36848 + will allow the kernel to apply a certain amount of randomization
36849 + to specific parts of the program thereby forcing an attacker to
36850 + guess them in most cases. Any failed guess will most likely crash
36851 + the attacked program which allows the kernel to detect such attempts
36852 + and react on them. PaX itself provides no reaction mechanisms,
36853 + instead it is strongly encouraged that you make use of Nergal's
36854 + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
36855 + (http://www.grsecurity.net/) built-in crash detection features or
36856 + develop one yourself.
36858 + By saying Y here you can choose to randomize the following areas:
36859 + - top of the task's kernel stack
36860 + - top of the task's userland stack
36861 + - base address for mmap() requests that do not specify one
36862 + (this includes all libraries)
36863 + - base address of the main executable
36865 + It is strongly recommended to say Y here as address space layout
36866 + randomization has negligible impact on performance yet it provides
36867 + a very effective protection.
36869 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36870 + this feature on a per file basis.
36872 +config PAX_RANDKSTACK
36873 + bool "Randomize kernel stack base"
36874 + depends on PAX_ASLR && X86_TSC && X86_32
36876 + By saying Y here the kernel will randomize every task's kernel
36877 + stack on every system call. This will not only force an attacker
36878 + to guess it but also prevent him from making use of possible
36879 + leaked information about it.
36881 + Since the kernel stack is a rather scarce resource, randomization
36882 + may cause unexpected stack overflows, therefore you should very
36883 + carefully test your system. Note that once enabled in the kernel
36884 + configuration, this feature cannot be disabled on a per file basis.
36886 +config PAX_RANDUSTACK
36887 + bool "Randomize user stack base"
36888 + depends on PAX_ASLR
36890 + By saying Y here the kernel will randomize every task's userland
36891 + stack. The randomization is done in two steps where the second
36892 + one may apply a big amount of shift to the top of the stack and
36893 + cause problems for programs that want to use lots of memory (more
36894 + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
36895 + For this reason the second step can be controlled by 'chpax' or
36896 + 'paxctl' on a per file basis.
36898 +config PAX_RANDMMAP
36899 + bool "Randomize mmap() base"
36900 + depends on PAX_ASLR
36902 + By saying Y here the kernel will use a randomized base address for
36903 + mmap() requests that do not specify one themselves. As a result
36904 + all dynamically loaded libraries will appear at random addresses
36905 + and therefore be harder to exploit by a technique where an attacker
36906 + attempts to execute library code for his purposes (e.g. spawn a
36907 + shell from an exploited program that is running at an elevated
36908 + privilege level).
36910 + Furthermore, if a program is relinked as a dynamic ELF file, its
36911 + base address will be randomized as well, completing the full
36912 + randomization of the address space layout. Attacking such programs
36913 + becomes a guess game. You can find an example of doing this at
36914 + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
36915 + http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
36917 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
36918 + feature on a per file basis.
36922 +menu "Miscellaneous hardening features"
36924 +config PAX_MEMORY_SANITIZE
36925 + bool "Sanitize all freed memory"
36927 + By saying Y here the kernel will erase memory pages as soon as they
36928 + are freed. This in turn reduces the lifetime of data stored in the
36929 + pages, making it less likely that sensitive information such as
36930 + passwords, cryptographic secrets, etc stay in memory for too long.
36932 + This is especially useful for programs whose runtime is short, long
36933 + lived processes and the kernel itself benefit from this as long as
36934 + they operate on whole memory pages and ensure timely freeing of pages
36935 + that may hold sensitive information.
36937 + The tradeoff is performance impact, on a single CPU system kernel
36938 + compilation sees a 3% slowdown, other systems and workloads may vary
36939 + and you are advised to test this feature on your expected workload
36940 + before deploying it.
36942 + Note that this feature does not protect data stored in live pages,
36943 + e.g., process memory swapped to disk may stay there for a long time.
36945 +config PAX_MEMORY_UDEREF
36946 + bool "Prevent invalid userland pointer dereference"
36947 + depends on X86_32 && !COMPAT_VDSO && !UML_X86
36949 + By saying Y here the kernel will be prevented from dereferencing
36950 + userland pointers in contexts where the kernel expects only kernel
36951 + pointers. This is both a useful runtime debugging feature and a
36952 + security measure that prevents exploiting a class of kernel bugs.
36954 + The tradeoff is that some virtualization solutions may experience
36955 + a huge slowdown and therefore you should not enable this feature
36956 + for kernels meant to run in such environments. Whether a given VM
36957 + solution is affected or not is best determined by simply trying it
36958 + out, the performance impact will be obvious right on boot as this
36959 + mechanism engages from very early on. A good rule of thumb is that
36960 + VMs running on CPUs without hardware virtualization support (i.e.,
36961 + the majority of IA-32 CPUs) will likely experience the slowdown.
36963 +config PAX_REFCOUNT
36964 + bool "Prevent various kernel object reference counter overflows"
36967 + By saying Y here the kernel will detect and prevent overflowing
36968 + various (but not all) kinds of object reference counters. Such
36969 + overflows can normally occur due to bugs only and are often, if
36970 + not always, exploitable.
36972 + The tradeoff is that data structures protected by an oveflowed
36973 + refcount will never be freed and therefore will leak memory. Note
36974 + that this leak also happens even without this protection but in
36975 + that case the overflow can eventually trigger the freeing of the
36976 + data structure while it is still being used elsewhere, resulting
36977 + in the exploitable situation that this feature prevents.
36979 + Since this has a negligible performance impact, you should enable
36986 bool "Enable access key retention support"
36988 diff -urNp linux-2.6.27.10/sound/core/oss/pcm_oss.c linux-2.6.27.10/sound/core/oss/pcm_oss.c
36989 --- linux-2.6.27.10/sound/core/oss/pcm_oss.c 2008-11-07 12:55:34.000000000 -0500
36990 +++ linux-2.6.27.10/sound/core/oss/pcm_oss.c 2008-11-18 03:38:45.000000000 -0500
36991 @@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
36994 #else /* !CONFIG_SND_VERBOSE_PROCFS */
36995 -#define snd_pcm_oss_proc_init(pcm)
36996 -#define snd_pcm_oss_proc_done(pcm)
36997 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
36998 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
36999 #endif /* CONFIG_SND_VERBOSE_PROCFS */
37002 diff -urNp linux-2.6.27.10/sound/core/seq/seq_lock.h linux-2.6.27.10/sound/core/seq/seq_lock.h
37003 --- linux-2.6.27.10/sound/core/seq/seq_lock.h 2008-11-07 12:55:34.000000000 -0500
37004 +++ linux-2.6.27.10/sound/core/seq/seq_lock.h 2008-11-18 03:38:45.000000000 -0500
37005 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
37006 #else /* SMP || CONFIG_SND_DEBUG */
37008 typedef spinlock_t snd_use_lock_t; /* dummy */
37009 -#define snd_use_lock_init(lockp) /**/
37010 -#define snd_use_lock_use(lockp) /**/
37011 -#define snd_use_lock_free(lockp) /**/
37012 -#define snd_use_lock_sync(lockp) /**/
37013 +#define snd_use_lock_init(lockp) do {} while (0)
37014 +#define snd_use_lock_use(lockp) do {} while (0)
37015 +#define snd_use_lock_free(lockp) do {} while (0)
37016 +#define snd_use_lock_sync(lockp) do {} while (0)
37018 #endif /* SMP || CONFIG_SND_DEBUG */
37020 diff -urNp linux-2.6.27.10/sound/pci/ac97/ac97_patch.c linux-2.6.27.10/sound/pci/ac97/ac97_patch.c
37021 --- linux-2.6.27.10/sound/pci/ac97/ac97_patch.c 2008-11-07 12:55:34.000000000 -0500
37022 +++ linux-2.6.27.10/sound/pci/ac97/ac97_patch.c 2008-11-18 03:38:45.000000000 -0500
37023 @@ -1498,7 +1498,7 @@ static const struct snd_ac97_res_table a
37024 { AC97_VIDEO, 0x9f1f },
37025 { AC97_AUX, 0x9f1f },
37026 { AC97_PCM, 0x9f1f },
37027 - { } /* terminator */
37028 + { 0, 0 } /* terminator */
37031 static int patch_ad1819(struct snd_ac97 * ac97)
37032 @@ -3668,7 +3668,7 @@ static struct snd_ac97_res_table lm4550_
37033 { AC97_AUX, 0x1f1f },
37034 { AC97_PCM, 0x1f1f },
37035 { AC97_REC_GAIN, 0x0f0f },
37036 - { } /* terminator */
37037 + { 0, 0 } /* terminator */
37040 static int patch_lm4550(struct snd_ac97 *ac97)
37041 diff -urNp linux-2.6.27.10/sound/pci/ens1370.c linux-2.6.27.10/sound/pci/ens1370.c
37042 --- linux-2.6.27.10/sound/pci/ens1370.c 2008-11-07 12:55:34.000000000 -0500
37043 +++ linux-2.6.27.10/sound/pci/ens1370.c 2008-11-18 03:38:45.000000000 -0500
37044 @@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
37045 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
37046 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
37049 + { 0, 0, 0, 0, 0, 0, 0 }
37052 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
37053 diff -urNp linux-2.6.27.10/sound/pci/intel8x0.c linux-2.6.27.10/sound/pci/intel8x0.c
37054 --- linux-2.6.27.10/sound/pci/intel8x0.c 2008-11-07 12:55:34.000000000 -0500
37055 +++ linux-2.6.27.10/sound/pci/intel8x0.c 2008-11-18 03:38:45.000000000 -0500
37056 @@ -437,7 +437,7 @@ static struct pci_device_id snd_intel8x0
37057 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37058 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
37059 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37061 + { 0, 0, 0, 0, 0, 0, 0 }
37064 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
37065 @@ -2076,7 +2076,7 @@ static struct ac97_quirk ac97_quirks[] _
37066 .type = AC97_TUNE_HP_ONLY
37069 - { } /* terminator */
37070 + { 0, 0, 0, 0, NULL, 0 } /* terminator */
37073 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
37074 diff -urNp linux-2.6.27.10/sound/pci/intel8x0m.c linux-2.6.27.10/sound/pci/intel8x0m.c
37075 --- linux-2.6.27.10/sound/pci/intel8x0m.c 2008-11-07 12:55:34.000000000 -0500
37076 +++ linux-2.6.27.10/sound/pci/intel8x0m.c 2008-11-18 03:38:45.000000000 -0500
37077 @@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
37078 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37079 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37082 + { 0, 0, 0, 0, 0, 0, 0 }
37085 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
37086 @@ -1257,7 +1257,7 @@ static struct shortname_table {
37087 { 0x5455, "ALi M5455" },
37088 { 0x746d, "AMD AMD8111" },
37094 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
37095 diff -urNp linux-2.6.27.10/virt/kvm/kvm_main.c linux-2.6.27.10/virt/kvm/kvm_main.c
37096 --- linux-2.6.27.10/virt/kvm/kvm_main.c 2008-11-07 12:55:34.000000000 -0500
37097 +++ linux-2.6.27.10/virt/kvm/kvm_main.c 2008-11-18 03:38:45.000000000 -0500
37098 @@ -1469,6 +1469,9 @@ static struct miscdevice kvm_dev = {
37107 static void hardware_enable(void *junk)