1 diff -urNp linux-2.6.29/arch/alpha/include/asm/elf.h linux-2.6.29/arch/alpha/include/asm/elf.h
2 --- linux-2.6.29/arch/alpha/include/asm/elf.h 2009-03-23 19:12:14.000000000 -0400
3 +++ linux-2.6.29/arch/alpha/include/asm/elf.h 2009-03-28 14:26:18.000000000 -0400
4 @@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
8 +#ifdef CONFIG_PAX_ASLR
9 +#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
11 +#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
12 +#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
15 /* $0 is set by ld.so to a pointer to a function which might be
16 registered using atexit. This provides a mean for the dynamic
17 linker to call DT_FINI functions for shared libraries that have
18 diff -urNp linux-2.6.29/arch/alpha/include/asm/kmap_types.h linux-2.6.29/arch/alpha/include/asm/kmap_types.h
19 --- linux-2.6.29/arch/alpha/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
20 +++ linux-2.6.29/arch/alpha/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
21 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
31 diff -urNp linux-2.6.29/arch/alpha/include/asm/pgtable.h linux-2.6.29/arch/alpha/include/asm/pgtable.h
32 --- linux-2.6.29/arch/alpha/include/asm/pgtable.h 2009-03-23 19:12:14.000000000 -0400
33 +++ linux-2.6.29/arch/alpha/include/asm/pgtable.h 2009-03-28 14:26:18.000000000 -0400
34 @@ -101,6 +101,17 @@ struct vm_area_struct;
35 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
36 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
37 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
39 +#ifdef CONFIG_PAX_PAGEEXEC
40 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
41 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
42 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
44 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
45 +# define PAGE_COPY_NOEXEC PAGE_COPY
46 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
49 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
51 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
52 diff -urNp linux-2.6.29/arch/alpha/kernel/module.c linux-2.6.29/arch/alpha/kernel/module.c
53 --- linux-2.6.29/arch/alpha/kernel/module.c 2009-03-23 19:12:14.000000000 -0400
54 +++ linux-2.6.29/arch/alpha/kernel/module.c 2009-03-28 14:26:18.000000000 -0400
55 @@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
57 /* The small sections were sorted to the end of the segment.
58 The following should definitely cover them. */
59 - gp = (u64)me->module_core + me->core_size - 0x8000;
60 + gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
61 got = sechdrs[me->arch.gotsecindex].sh_addr;
63 for (i = 0; i < n; i++) {
64 diff -urNp linux-2.6.29/arch/alpha/kernel/osf_sys.c linux-2.6.29/arch/alpha/kernel/osf_sys.c
65 --- linux-2.6.29/arch/alpha/kernel/osf_sys.c 2009-03-23 19:12:14.000000000 -0400
66 +++ linux-2.6.29/arch/alpha/kernel/osf_sys.c 2009-03-28 14:26:18.000000000 -0400
67 @@ -1217,6 +1217,10 @@ arch_get_unmapped_area(struct file *filp
68 merely specific addresses, but regions of memory -- perhaps
69 this feature should be incorporated into all ports? */
71 +#ifdef CONFIG_PAX_RANDMMAP
72 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
76 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
77 if (addr != (unsigned long) -ENOMEM)
78 @@ -1224,8 +1228,8 @@ arch_get_unmapped_area(struct file *filp
81 /* Next, try allocating at TASK_UNMAPPED_BASE. */
82 - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
84 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
86 if (addr != (unsigned long) -ENOMEM)
89 diff -urNp linux-2.6.29/arch/alpha/kernel/ptrace.c linux-2.6.29/arch/alpha/kernel/ptrace.c
90 --- linux-2.6.29/arch/alpha/kernel/ptrace.c 2009-03-23 19:12:14.000000000 -0400
91 +++ linux-2.6.29/arch/alpha/kernel/ptrace.c 2009-03-28 14:26:18.000000000 -0400
92 @@ -266,6 +266,9 @@ long arch_ptrace(struct task_struct *chi
96 + if (gr_handle_ptrace(child, request))
100 /* When I and D space are separate, these will need to be fixed. */
101 case PTRACE_PEEKTEXT: /* read word at location addr. */
102 diff -urNp linux-2.6.29/arch/alpha/mm/fault.c linux-2.6.29/arch/alpha/mm/fault.c
103 --- linux-2.6.29/arch/alpha/mm/fault.c 2009-03-23 19:12:14.000000000 -0400
104 +++ linux-2.6.29/arch/alpha/mm/fault.c 2009-03-28 14:26:18.000000000 -0400
105 @@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
106 __reload_thread(pcb);
109 +#ifdef CONFIG_PAX_PAGEEXEC
111 + * PaX: decide what to do with offenders (regs->pc = fault address)
113 + * returns 1 when task should be killed
114 + * 2 when patched PLT trampoline was detected
115 + * 3 when unpatched PLT trampoline was detected
117 +static int pax_handle_fetch_fault(struct pt_regs *regs)
120 +#ifdef CONFIG_PAX_EMUPLT
123 + do { /* PaX: patched PLT emulation #1 */
124 + unsigned int ldah, ldq, jmp;
126 + err = get_user(ldah, (unsigned int *)regs->pc);
127 + err |= get_user(ldq, (unsigned int *)(regs->pc+4));
128 + err |= get_user(jmp, (unsigned int *)(regs->pc+8));
133 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
134 + (ldq & 0xFFFF0000U) == 0xA77B0000U &&
135 + jmp == 0x6BFB0000U)
137 + unsigned long r27, addr;
138 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
139 + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
141 + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
142 + err = get_user(r27, (unsigned long *)addr);
152 + do { /* PaX: patched PLT emulation #2 */
153 + unsigned int ldah, lda, br;
155 + err = get_user(ldah, (unsigned int *)regs->pc);
156 + err |= get_user(lda, (unsigned int *)(regs->pc+4));
157 + err |= get_user(br, (unsigned int *)(regs->pc+8));
162 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
163 + (lda & 0xFFFF0000U) == 0xA77B0000U &&
164 + (br & 0xFFE00000U) == 0xC3E00000U)
166 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
167 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
168 + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
170 + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
171 + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
176 + do { /* PaX: unpatched PLT emulation */
179 + err = get_user(br, (unsigned int *)regs->pc);
181 + if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
182 + unsigned int br2, ldq, nop, jmp;
183 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
185 + addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
186 + err = get_user(br2, (unsigned int *)addr);
187 + err |= get_user(ldq, (unsigned int *)(addr+4));
188 + err |= get_user(nop, (unsigned int *)(addr+8));
189 + err |= get_user(jmp, (unsigned int *)(addr+12));
190 + err |= get_user(resolver, (unsigned long *)(addr+16));
195 + if (br2 == 0xC3600000U &&
196 + ldq == 0xA77B000CU &&
197 + nop == 0x47FF041FU &&
198 + jmp == 0x6B7B0000U)
200 + regs->r28 = regs->pc+4;
201 + regs->r27 = addr+16;
202 + regs->pc = resolver;
212 +void pax_report_insns(void *pc, void *sp)
216 + printk(KERN_ERR "PAX: bytes at PC: ");
217 + for (i = 0; i < 5; i++) {
219 + if (get_user(c, (unsigned int *)pc+i))
220 + printk(KERN_CONT "???????? ");
222 + printk(KERN_CONT "%08x ", c);
229 * This routine handles page faults. It determines the address,
230 @@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
232 si_code = SEGV_ACCERR;
234 - if (!(vma->vm_flags & VM_EXEC))
235 + if (!(vma->vm_flags & VM_EXEC)) {
237 +#ifdef CONFIG_PAX_PAGEEXEC
238 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
241 + up_read(&mm->mmap_sem);
242 + switch (pax_handle_fetch_fault(regs)) {
244 +#ifdef CONFIG_PAX_EMUPLT
251 + pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
252 + do_group_exit(SIGKILL);
259 /* Allow reads even for write-only mappings */
260 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
261 diff -urNp linux-2.6.29/arch/arm/include/asm/elf.h linux-2.6.29/arch/arm/include/asm/elf.h
262 --- linux-2.6.29/arch/arm/include/asm/elf.h 2009-03-23 19:12:14.000000000 -0400
263 +++ linux-2.6.29/arch/arm/include/asm/elf.h 2009-03-28 14:26:18.000000000 -0400
264 @@ -99,7 +99,14 @@ extern int arm_elf_read_implies_exec(con
265 the loader. We need to make sure that it is out of the way of the program
266 that it will "exec", and that there is sufficient room for the brk. */
268 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
269 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
271 +#ifdef CONFIG_PAX_ASLR
272 +#define PAX_ELF_ET_DYN_BASE 0x00008000UL
274 +#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
275 +#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
278 /* When the program starts, a1 contains a pointer to a function to be
279 registered with atexit, as per the SVR4 ABI. A value of 0 means we
280 diff -urNp linux-2.6.29/arch/arm/include/asm/kmap_types.h linux-2.6.29/arch/arm/include/asm/kmap_types.h
281 --- linux-2.6.29/arch/arm/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
282 +++ linux-2.6.29/arch/arm/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
283 @@ -18,6 +18,7 @@ enum km_type {
291 diff -urNp linux-2.6.29/arch/arm/mm/mmap.c linux-2.6.29/arch/arm/mm/mmap.c
292 --- linux-2.6.29/arch/arm/mm/mmap.c 2009-03-23 19:12:14.000000000 -0400
293 +++ linux-2.6.29/arch/arm/mm/mmap.c 2009-03-28 14:26:18.000000000 -0400
294 @@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
298 +#ifdef CONFIG_PAX_RANDMMAP
299 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
304 addr = COLOUR_ALIGN(addr, pgoff);
305 @@ -74,10 +78,10 @@ arch_get_unmapped_area(struct file *filp
308 if (len > mm->cached_hole_size) {
309 - start_addr = addr = mm->free_area_cache;
310 + start_addr = addr = mm->free_area_cache;
312 - start_addr = addr = TASK_UNMAPPED_BASE;
313 - mm->cached_hole_size = 0;
314 + start_addr = addr = mm->mmap_base;
315 + mm->cached_hole_size = 0;
319 @@ -93,8 +97,8 @@ full_search:
320 * Start a new search - just in case we missed
323 - if (start_addr != TASK_UNMAPPED_BASE) {
324 - start_addr = addr = TASK_UNMAPPED_BASE;
325 + if (start_addr != mm->mmap_base) {
326 + start_addr = addr = mm->mmap_base;
327 mm->cached_hole_size = 0;
330 diff -urNp linux-2.6.29/arch/avr32/include/asm/elf.h linux-2.6.29/arch/avr32/include/asm/elf.h
331 --- linux-2.6.29/arch/avr32/include/asm/elf.h 2009-03-23 19:12:14.000000000 -0400
332 +++ linux-2.6.29/arch/avr32/include/asm/elf.h 2009-03-28 14:26:18.000000000 -0400
333 @@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
334 the loader. We need to make sure that it is out of the way of the program
335 that it will "exec", and that there is sufficient room for the brk. */
337 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
338 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
340 +#ifdef CONFIG_PAX_ASLR
341 +#define PAX_ELF_ET_DYN_BASE 0x00001000UL
343 +#define PAX_DELTA_MMAP_LEN 15
344 +#define PAX_DELTA_STACK_LEN 15
347 /* This yields a mask that user programs can use to figure out what
348 instruction set this CPU supports. This could be done in user space,
349 diff -urNp linux-2.6.29/arch/avr32/include/asm/kmap_types.h linux-2.6.29/arch/avr32/include/asm/kmap_types.h
350 --- linux-2.6.29/arch/avr32/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
351 +++ linux-2.6.29/arch/avr32/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
352 @@ -22,7 +22,8 @@ D(10) KM_IRQ0,
362 diff -urNp linux-2.6.29/arch/avr32/mm/fault.c linux-2.6.29/arch/avr32/mm/fault.c
363 --- linux-2.6.29/arch/avr32/mm/fault.c 2009-03-23 19:12:14.000000000 -0400
364 +++ linux-2.6.29/arch/avr32/mm/fault.c 2009-03-28 14:26:18.000000000 -0400
365 @@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
367 int exception_trace = 1;
369 +#ifdef CONFIG_PAX_PAGEEXEC
370 +void pax_report_insns(void *pc, void *sp)
374 + printk(KERN_ERR "PAX: bytes at PC: ");
375 + for (i = 0; i < 20; i++) {
377 + if (get_user(c, (unsigned char *)pc+i))
378 + printk(KERN_CONT "???????? ");
380 + printk(KERN_CONT "%02x ", c);
387 * This routine handles page faults. It determines the address and the
388 * problem, and then passes it off to one of the appropriate routines.
389 @@ -157,6 +174,16 @@ bad_area:
390 up_read(&mm->mmap_sem);
392 if (user_mode(regs)) {
394 +#ifdef CONFIG_PAX_PAGEEXEC
395 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
396 + if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
397 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
398 + do_group_exit(SIGKILL);
403 if (exception_trace && printk_ratelimit())
404 printk("%s%s[%d]: segfault at %08lx pc %08lx "
405 "sp %08lx ecr %lu\n",
406 diff -urNp linux-2.6.29/arch/blackfin/include/asm/kmap_types.h linux-2.6.29/arch/blackfin/include/asm/kmap_types.h
407 --- linux-2.6.29/arch/blackfin/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
408 +++ linux-2.6.29/arch/blackfin/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
409 @@ -15,6 +15,7 @@ enum km_type {
417 diff -urNp linux-2.6.29/arch/cris/include/asm/kmap_types.h linux-2.6.29/arch/cris/include/asm/kmap_types.h
418 --- linux-2.6.29/arch/cris/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
419 +++ linux-2.6.29/arch/cris/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
420 @@ -19,6 +19,7 @@ enum km_type {
428 diff -urNp linux-2.6.29/arch/h8300/include/asm/kmap_types.h linux-2.6.29/arch/h8300/include/asm/kmap_types.h
429 --- linux-2.6.29/arch/h8300/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
430 +++ linux-2.6.29/arch/h8300/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
431 @@ -15,6 +15,7 @@ enum km_type {
439 diff -urNp linux-2.6.29/arch/ia64/ia32/binfmt_elf32.c linux-2.6.29/arch/ia64/ia32/binfmt_elf32.c
440 --- linux-2.6.29/arch/ia64/ia32/binfmt_elf32.c 2009-03-23 19:12:14.000000000 -0400
441 +++ linux-2.6.29/arch/ia64/ia32/binfmt_elf32.c 2009-03-28 14:26:18.000000000 -0400
442 @@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
444 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
446 +#ifdef CONFIG_PAX_ASLR
447 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
449 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
450 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
453 /* Ugly but avoids duplication */
454 #include "../../../fs/binfmt_elf.c"
456 diff -urNp linux-2.6.29/arch/ia64/ia32/ia32priv.h linux-2.6.29/arch/ia64/ia32/ia32priv.h
457 --- linux-2.6.29/arch/ia64/ia32/ia32priv.h 2009-03-23 19:12:14.000000000 -0400
458 +++ linux-2.6.29/arch/ia64/ia32/ia32priv.h 2009-03-28 14:26:18.000000000 -0400
459 @@ -296,7 +296,14 @@ typedef struct compat_siginfo {
460 #define ELF_DATA ELFDATA2LSB
461 #define ELF_ARCH EM_386
463 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
464 +#ifdef CONFIG_PAX_RANDUSTACK
465 +#define __IA32_DELTA_STACK (current->mm->delta_stack)
467 +#define __IA32_DELTA_STACK 0UL
470 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
472 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
473 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
475 diff -urNp linux-2.6.29/arch/ia64/include/asm/elf.h linux-2.6.29/arch/ia64/include/asm/elf.h
476 --- linux-2.6.29/arch/ia64/include/asm/elf.h 2009-03-23 19:12:14.000000000 -0400
477 +++ linux-2.6.29/arch/ia64/include/asm/elf.h 2009-03-28 14:26:18.000000000 -0400
480 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
482 +#ifdef CONFIG_PAX_ASLR
483 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
485 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
486 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
489 #define PT_IA_64_UNWIND 0x70000001
491 /* IA-64 relocations: */
492 diff -urNp linux-2.6.29/arch/ia64/include/asm/kmap_types.h linux-2.6.29/arch/ia64/include/asm/kmap_types.h
493 --- linux-2.6.29/arch/ia64/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
494 +++ linux-2.6.29/arch/ia64/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
495 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
505 diff -urNp linux-2.6.29/arch/ia64/include/asm/pgtable.h linux-2.6.29/arch/ia64/include/asm/pgtable.h
506 --- linux-2.6.29/arch/ia64/include/asm/pgtable.h 2009-03-23 19:12:14.000000000 -0400
507 +++ linux-2.6.29/arch/ia64/include/asm/pgtable.h 2009-03-28 14:26:18.000000000 -0400
509 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
510 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
511 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
513 +#ifdef CONFIG_PAX_PAGEEXEC
514 +# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
515 +# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
516 +# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
518 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
519 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
520 +# define PAGE_COPY_NOEXEC PAGE_COPY
523 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
524 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
525 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
526 diff -urNp linux-2.6.29/arch/ia64/kernel/module.c linux-2.6.29/arch/ia64/kernel/module.c
527 --- linux-2.6.29/arch/ia64/kernel/module.c 2009-03-23 19:12:14.000000000 -0400
528 +++ linux-2.6.29/arch/ia64/kernel/module.c 2009-03-28 14:26:18.000000000 -0400
529 @@ -312,8 +312,7 @@ module_alloc (unsigned long size)
531 module_free (struct module *mod, void *module_region)
533 - if (mod && mod->arch.init_unw_table &&
534 - module_region == mod->module_init) {
535 + if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
536 unw_remove_unwind_table(mod->arch.init_unw_table);
537 mod->arch.init_unw_table = NULL;
539 @@ -491,15 +490,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
543 +in_init_rx (const struct module *mod, uint64_t addr)
545 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
549 +in_init_rw (const struct module *mod, uint64_t addr)
551 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
555 in_init (const struct module *mod, uint64_t addr)
557 - return addr - (uint64_t) mod->module_init < mod->init_size;
558 + return in_init_rx(mod, addr) || in_init_rw(mod, addr);
562 +in_core_rx (const struct module *mod, uint64_t addr)
564 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
568 +in_core_rw (const struct module *mod, uint64_t addr)
570 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
574 in_core (const struct module *mod, uint64_t addr)
576 - return addr - (uint64_t) mod->module_core < mod->core_size;
577 + return in_core_rx(mod, addr) || in_core_rw(mod, addr);
581 @@ -683,7 +706,14 @@ do_reloc (struct module *mod, uint8_t r_
585 - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
586 + if (in_init_rx(mod, val))
587 + val -= (uint64_t) mod->module_init_rx;
588 + else if (in_init_rw(mod, val))
589 + val -= (uint64_t) mod->module_init_rw;
590 + else if (in_core_rx(mod, val))
591 + val -= (uint64_t) mod->module_core_rx;
592 + else if (in_core_rw(mod, val))
593 + val -= (uint64_t) mod->module_core_rw;
597 @@ -817,15 +847,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
598 * addresses have been selected...
601 - if (mod->core_size > MAX_LTOFF)
602 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
604 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
605 * at the end of the module.
607 - gp = mod->core_size - MAX_LTOFF / 2;
608 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
610 - gp = mod->core_size / 2;
611 - gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
612 + gp = (mod->core_size_rx + mod->core_size_rw) / 2;
613 + gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
615 DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
617 diff -urNp linux-2.6.29/arch/ia64/kernel/sys_ia64.c linux-2.6.29/arch/ia64/kernel/sys_ia64.c
618 --- linux-2.6.29/arch/ia64/kernel/sys_ia64.c 2009-03-23 19:12:14.000000000 -0400
619 +++ linux-2.6.29/arch/ia64/kernel/sys_ia64.c 2009-03-28 14:26:18.000000000 -0400
620 @@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
621 if (REGION_NUMBER(addr) == RGN_HPAGE)
625 +#ifdef CONFIG_PAX_RANDMMAP
626 + if (mm->pax_flags & MF_PAX_RANDMMAP)
627 + addr = mm->free_area_cache;
632 addr = mm->free_area_cache;
634 @@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
635 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
636 /* At this point: (!vma || addr < vma->vm_end). */
637 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
638 - if (start_addr != TASK_UNMAPPED_BASE) {
639 + if (start_addr != mm->mmap_base) {
640 /* Start a new search --- just in case we missed some holes. */
641 - addr = TASK_UNMAPPED_BASE;
642 + addr = mm->mmap_base;
646 diff -urNp linux-2.6.29/arch/ia64/mm/fault.c linux-2.6.29/arch/ia64/mm/fault.c
647 --- linux-2.6.29/arch/ia64/mm/fault.c 2009-03-23 19:12:14.000000000 -0400
648 +++ linux-2.6.29/arch/ia64/mm/fault.c 2009-03-28 14:26:18.000000000 -0400
649 @@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
650 return pte_present(pte);
653 +#ifdef CONFIG_PAX_PAGEEXEC
654 +void pax_report_insns(void *pc, void *sp)
658 + printk(KERN_ERR "PAX: bytes at PC: ");
659 + for (i = 0; i < 8; i++) {
661 + if (get_user(c, (unsigned int *)pc+i))
662 + printk(KERN_CONT "???????? ");
664 + printk(KERN_CONT "%08x ", c);
671 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
673 @@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
674 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
675 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
677 - if ((vma->vm_flags & mask) != mask)
678 + if ((vma->vm_flags & mask) != mask) {
680 +#ifdef CONFIG_PAX_PAGEEXEC
681 + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
682 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
685 + up_read(&mm->mmap_sem);
686 + pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
687 + do_group_exit(SIGKILL);
697 * If for any reason at all we couldn't handle the fault, make
698 diff -urNp linux-2.6.29/arch/ia64/mm/init.c linux-2.6.29/arch/ia64/mm/init.c
699 --- linux-2.6.29/arch/ia64/mm/init.c 2009-03-23 19:12:14.000000000 -0400
700 +++ linux-2.6.29/arch/ia64/mm/init.c 2009-03-28 14:26:18.000000000 -0400
701 @@ -121,6 +121,19 @@ ia64_init_addr_space (void)
702 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
703 vma->vm_end = vma->vm_start + PAGE_SIZE;
704 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
706 +#ifdef CONFIG_PAX_PAGEEXEC
707 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
708 + vma->vm_flags &= ~VM_EXEC;
710 +#ifdef CONFIG_PAX_MPROTECT
711 + if (current->mm->pax_flags & MF_PAX_MPROTECT)
712 + vma->vm_flags &= ~VM_MAYEXEC;
718 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
719 down_write(¤t->mm->mmap_sem);
720 if (insert_vm_struct(current->mm, vma)) {
721 diff -urNp linux-2.6.29/arch/m68k/include/asm/kmap_types_mm.h linux-2.6.29/arch/m68k/include/asm/kmap_types_mm.h
722 --- linux-2.6.29/arch/m68k/include/asm/kmap_types_mm.h 2009-03-23 19:12:14.000000000 -0400
723 +++ linux-2.6.29/arch/m68k/include/asm/kmap_types_mm.h 2009-03-28 14:26:18.000000000 -0400
724 @@ -15,6 +15,7 @@ enum km_type {
732 diff -urNp linux-2.6.29/arch/m68k/include/asm/kmap_types_no.h linux-2.6.29/arch/m68k/include/asm/kmap_types_no.h
733 --- linux-2.6.29/arch/m68k/include/asm/kmap_types_no.h 2009-03-23 19:12:14.000000000 -0400
734 +++ linux-2.6.29/arch/m68k/include/asm/kmap_types_no.h 2009-03-28 14:26:18.000000000 -0400
735 @@ -15,6 +15,7 @@ enum km_type {
743 diff -urNp linux-2.6.29/arch/mips/include/asm/elf.h linux-2.6.29/arch/mips/include/asm/elf.h
744 --- linux-2.6.29/arch/mips/include/asm/elf.h 2009-03-23 19:12:14.000000000 -0400
745 +++ linux-2.6.29/arch/mips/include/asm/elf.h 2009-03-28 14:26:18.000000000 -0400
746 @@ -364,4 +364,11 @@ extern int dump_task_fpu(struct task_str
747 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
750 +#ifdef CONFIG_PAX_ASLR
751 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
753 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
754 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
757 #endif /* _ASM_ELF_H */
758 diff -urNp linux-2.6.29/arch/mips/include/asm/kmap_types.h linux-2.6.29/arch/mips/include/asm/kmap_types.h
759 --- linux-2.6.29/arch/mips/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
760 +++ linux-2.6.29/arch/mips/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
761 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
771 diff -urNp linux-2.6.29/arch/mips/include/asm/page.h linux-2.6.29/arch/mips/include/asm/page.h
772 --- linux-2.6.29/arch/mips/include/asm/page.h 2009-03-23 19:12:14.000000000 -0400
773 +++ linux-2.6.29/arch/mips/include/asm/page.h 2009-03-28 14:26:18.000000000 -0400
774 @@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
775 #ifdef CONFIG_CPU_MIPS32
776 typedef struct { unsigned long pte_low, pte_high; } pte_t;
777 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
778 - #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
779 + #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
781 typedef struct { unsigned long long pte; } pte_t;
782 #define pte_val(x) ((x).pte)
783 diff -urNp linux-2.6.29/arch/mips/include/asm/system.h linux-2.6.29/arch/mips/include/asm/system.h
784 --- linux-2.6.29/arch/mips/include/asm/system.h 2009-03-23 19:12:14.000000000 -0400
785 +++ linux-2.6.29/arch/mips/include/asm/system.h 2009-03-28 14:26:18.000000000 -0400
786 @@ -217,6 +217,6 @@ extern void per_cpu_trap_init(void);
788 #define __ARCH_WANT_UNLOCKED_CTXSW
790 -extern unsigned long arch_align_stack(unsigned long sp);
791 +#define arch_align_stack(x) ((x) & ALMASK)
793 #endif /* _ASM_SYSTEM_H */
794 diff -urNp linux-2.6.29/arch/mips/kernel/binfmt_elfn32.c linux-2.6.29/arch/mips/kernel/binfmt_elfn32.c
795 --- linux-2.6.29/arch/mips/kernel/binfmt_elfn32.c 2009-03-23 19:12:14.000000000 -0400
796 +++ linux-2.6.29/arch/mips/kernel/binfmt_elfn32.c 2009-03-28 14:26:18.000000000 -0400
797 @@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
798 #undef ELF_ET_DYN_BASE
799 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
801 +#ifdef CONFIG_PAX_ASLR
802 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
804 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
805 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
808 #include <asm/processor.h>
809 #include <linux/module.h>
810 #include <linux/elfcore.h>
811 diff -urNp linux-2.6.29/arch/mips/kernel/binfmt_elfo32.c linux-2.6.29/arch/mips/kernel/binfmt_elfo32.c
812 --- linux-2.6.29/arch/mips/kernel/binfmt_elfo32.c 2009-03-23 19:12:14.000000000 -0400
813 +++ linux-2.6.29/arch/mips/kernel/binfmt_elfo32.c 2009-03-28 14:26:18.000000000 -0400
814 @@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
815 #undef ELF_ET_DYN_BASE
816 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
818 +#ifdef CONFIG_PAX_ASLR
819 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
821 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
822 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
825 #include <asm/processor.h>
826 #include <linux/module.h>
827 #include <linux/elfcore.h>
828 diff -urNp linux-2.6.29/arch/mips/kernel/process.c linux-2.6.29/arch/mips/kernel/process.c
829 --- linux-2.6.29/arch/mips/kernel/process.c 2009-03-23 19:12:14.000000000 -0400
830 +++ linux-2.6.29/arch/mips/kernel/process.c 2009-03-28 14:26:18.000000000 -0400
831 @@ -457,15 +457,3 @@ unsigned long get_wchan(struct task_stru
837 - * Don't forget that the stack pointer must be aligned on a 8 bytes
838 - * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
840 -unsigned long arch_align_stack(unsigned long sp)
842 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
843 - sp -= get_random_int() & ~PAGE_MASK;
845 - return sp & ALMASK;
847 diff -urNp linux-2.6.29/arch/mips/kernel/syscall.c linux-2.6.29/arch/mips/kernel/syscall.c
848 --- linux-2.6.29/arch/mips/kernel/syscall.c 2009-03-23 19:12:14.000000000 -0400
849 +++ linux-2.6.29/arch/mips/kernel/syscall.c 2009-03-28 14:26:18.000000000 -0400
850 @@ -99,6 +99,11 @@ unsigned long arch_get_unmapped_area(str
852 if (filp || (flags & MAP_SHARED))
855 +#ifdef CONFIG_PAX_RANDMMAP
856 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
861 addr = COLOUR_ALIGN(addr, pgoff);
862 @@ -109,7 +114,7 @@ unsigned long arch_get_unmapped_area(str
863 (!vmm || addr + len <= vmm->vm_start))
866 - addr = TASK_UNMAPPED_BASE;
867 + addr = current->mm->mmap_base;
869 addr = COLOUR_ALIGN(addr, pgoff);
871 diff -urNp linux-2.6.29/arch/mips/mm/fault.c linux-2.6.29/arch/mips/mm/fault.c
872 --- linux-2.6.29/arch/mips/mm/fault.c 2009-03-23 19:12:14.000000000 -0400
873 +++ linux-2.6.29/arch/mips/mm/fault.c 2009-03-28 14:26:18.000000000 -0400
875 #include <asm/ptrace.h>
876 #include <asm/highmem.h> /* For VMALLOC_END */
878 +#ifdef CONFIG_PAX_PAGEEXEC
879 +void pax_report_insns(void *pc)
883 + printk(KERN_ERR "PAX: bytes at PC: ");
884 + for (i = 0; i < 5; i++) {
886 + if (get_user(c, (unsigned int *)pc+i))
887 + printk(KERN_CONT "???????? ");
889 + printk(KERN_CONT "%08x ", c);
896 * This routine handles page faults. It determines the address,
897 * and the problem, and then passes it off to one of the appropriate
898 diff -urNp linux-2.6.29/arch/parisc/include/asm/elf.h linux-2.6.29/arch/parisc/include/asm/elf.h
899 --- linux-2.6.29/arch/parisc/include/asm/elf.h 2009-03-23 19:12:14.000000000 -0400
900 +++ linux-2.6.29/arch/parisc/include/asm/elf.h 2009-03-28 14:26:18.000000000 -0400
901 @@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
903 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
905 +#ifdef CONFIG_PAX_ASLR
906 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
908 +#define PAX_DELTA_MMAP_LEN 16
909 +#define PAX_DELTA_STACK_LEN 16
912 /* This yields a mask that user programs can use to figure out what
913 instruction set this CPU supports. This could be done in user space,
914 but it's not easy, and we've already done it here. */
915 diff -urNp linux-2.6.29/arch/parisc/include/asm/kmap_types.h linux-2.6.29/arch/parisc/include/asm/kmap_types.h
916 --- linux-2.6.29/arch/parisc/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
917 +++ linux-2.6.29/arch/parisc/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
918 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
928 diff -urNp linux-2.6.29/arch/parisc/include/asm/pgtable.h linux-2.6.29/arch/parisc/include/asm/pgtable.h
929 --- linux-2.6.29/arch/parisc/include/asm/pgtable.h 2009-03-23 19:12:14.000000000 -0400
930 +++ linux-2.6.29/arch/parisc/include/asm/pgtable.h 2009-03-28 14:26:18.000000000 -0400
932 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
933 #define PAGE_COPY PAGE_EXECREAD
934 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
936 +#ifdef CONFIG_PAX_PAGEEXEC
937 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
938 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
939 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
941 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
942 +# define PAGE_COPY_NOEXEC PAGE_COPY
943 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
946 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
947 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
948 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
949 diff -urNp linux-2.6.29/arch/parisc/kernel/module.c linux-2.6.29/arch/parisc/kernel/module.c
950 --- linux-2.6.29/arch/parisc/kernel/module.c 2009-03-23 19:12:14.000000000 -0400
951 +++ linux-2.6.29/arch/parisc/kernel/module.c 2009-03-28 14:26:18.000000000 -0400
954 /* three functions to determine where in the module core
955 * or init pieces the location is */
956 +static inline int in_init_rx(struct module *me, void *loc)
958 + return (loc >= me->module_init_rx &&
959 + loc < (me->module_init_rx + me->init_size_rx));
962 +static inline int in_init_rw(struct module *me, void *loc)
964 + return (loc >= me->module_init_rw &&
965 + loc < (me->module_init_rw + me->init_size_rw));
968 static inline int in_init(struct module *me, void *loc)
970 - return (loc >= me->module_init &&
971 - loc <= (me->module_init + me->init_size));
972 + return in_init_rx(me, loc) || in_init_rw(me, loc);
975 +static inline int in_core_rx(struct module *me, void *loc)
977 + return (loc >= me->module_core_rx &&
978 + loc < (me->module_core_rx + me->core_size_rx));
981 +static inline int in_core_rw(struct module *me, void *loc)
983 + return (loc >= me->module_core_rw &&
984 + loc < (me->module_core_rw + me->core_size_rw));
987 static inline int in_core(struct module *me, void *loc)
989 - return (loc >= me->module_core &&
990 - loc <= (me->module_core + me->core_size));
991 + return in_core_rx(me, loc) || in_core_rw(me, loc);
994 static inline int in_local(struct module *me, void *loc)
995 @@ -340,13 +362,13 @@ int module_frob_arch_sections(CONST Elf_
998 /* align things a bit */
999 - me->core_size = ALIGN(me->core_size, 16);
1000 - me->arch.got_offset = me->core_size;
1001 - me->core_size += gots * sizeof(struct got_entry);
1003 - me->core_size = ALIGN(me->core_size, 16);
1004 - me->arch.fdesc_offset = me->core_size;
1005 - me->core_size += fdescs * sizeof(Elf_Fdesc);
1006 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
1007 + me->arch.got_offset = me->core_size_rw;
1008 + me->core_size_rw += gots * sizeof(struct got_entry);
1010 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
1011 + me->arch.fdesc_offset = me->core_size_rw;
1012 + me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
1014 me->arch.got_max = gots;
1015 me->arch.fdesc_max = fdescs;
1016 @@ -364,7 +386,7 @@ static Elf64_Word get_got(struct module
1020 - got = me->module_core + me->arch.got_offset;
1021 + got = me->module_core_rw + me->arch.got_offset;
1022 for (i = 0; got[i].addr; i++)
1023 if (got[i].addr == value)
1025 @@ -382,7 +404,7 @@ static Elf64_Word get_got(struct module
1027 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
1029 - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
1030 + Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
1033 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
1034 @@ -400,7 +422,7 @@ static Elf_Addr get_fdesc(struct module
1036 /* Create new one */
1037 fdesc->addr = value;
1038 - fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1039 + fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1040 return (Elf_Addr)fdesc;
1042 #endif /* CONFIG_64BIT */
1043 @@ -816,7 +838,7 @@ register_unwind_table(struct module *me,
1045 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
1046 end = table + sechdrs[me->arch.unwind_section].sh_size;
1047 - gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1048 + gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1050 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
1051 me->arch.unwind_section, table, end, gp);
1052 diff -urNp linux-2.6.29/arch/parisc/kernel/sys_parisc.c linux-2.6.29/arch/parisc/kernel/sys_parisc.c
1053 --- linux-2.6.29/arch/parisc/kernel/sys_parisc.c 2009-03-23 19:12:14.000000000 -0400
1054 +++ linux-2.6.29/arch/parisc/kernel/sys_parisc.c 2009-03-28 14:26:18.000000000 -0400
1055 @@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
1056 if (flags & MAP_FIXED)
1059 - addr = TASK_UNMAPPED_BASE;
1060 + addr = current->mm->mmap_base;
1063 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
1064 diff -urNp linux-2.6.29/arch/parisc/kernel/traps.c linux-2.6.29/arch/parisc/kernel/traps.c
1065 --- linux-2.6.29/arch/parisc/kernel/traps.c 2009-03-23 19:12:14.000000000 -0400
1066 +++ linux-2.6.29/arch/parisc/kernel/traps.c 2009-03-28 14:26:18.000000000 -0400
1067 @@ -731,9 +731,7 @@ void handle_interruption(int code, struc
1069 down_read(¤t->mm->mmap_sem);
1070 vma = find_vma(current->mm,regs->iaoq[0]);
1071 - if (vma && (regs->iaoq[0] >= vma->vm_start)
1072 - && (vma->vm_flags & VM_EXEC)) {
1074 + if (vma && (regs->iaoq[0] >= vma->vm_start)) {
1075 fault_address = regs->iaoq[0];
1076 fault_space = regs->iasq[0];
1078 diff -urNp linux-2.6.29/arch/parisc/mm/fault.c linux-2.6.29/arch/parisc/mm/fault.c
1079 --- linux-2.6.29/arch/parisc/mm/fault.c 2009-03-23 19:12:14.000000000 -0400
1080 +++ linux-2.6.29/arch/parisc/mm/fault.c 2009-03-28 14:26:18.000000000 -0400
1082 #include <linux/sched.h>
1083 #include <linux/interrupt.h>
1084 #include <linux/module.h>
1085 +#include <linux/unistd.h>
1087 #include <asm/uaccess.h>
1088 #include <asm/traps.h>
1089 @@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
1090 static unsigned long
1091 parisc_acctyp(unsigned long code, unsigned int inst)
1093 - if (code == 6 || code == 16)
1094 + if (code == 6 || code == 7 || code == 16)
1097 switch (inst & 0xf0000000) {
1098 @@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
1102 +#ifdef CONFIG_PAX_PAGEEXEC
1104 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
1106 + * returns 1 when task should be killed
1107 + * 2 when rt_sigreturn trampoline was detected
1108 + * 3 when unpatched PLT trampoline was detected
1110 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1113 +#ifdef CONFIG_PAX_EMUPLT
1116 + do { /* PaX: unpatched PLT emulation */
1117 + unsigned int bl, depwi;
1119 + err = get_user(bl, (unsigned int *)instruction_pointer(regs));
1120 + err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
1125 + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
1126 + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
1128 + err = get_user(ldw, (unsigned int *)addr);
1129 + err |= get_user(bv, (unsigned int *)(addr+4));
1130 + err |= get_user(ldw2, (unsigned int *)(addr+8));
1135 + if (ldw == 0x0E801096U &&
1136 + bv == 0xEAC0C000U &&
1137 + ldw2 == 0x0E881095U)
1139 + unsigned int resolver, map;
1141 + err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
1142 + err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
1146 + regs->gr[20] = instruction_pointer(regs)+8;
1147 + regs->gr[21] = map;
1148 + regs->gr[22] = resolver;
1149 + regs->iaoq[0] = resolver | 3UL;
1150 + regs->iaoq[1] = regs->iaoq[0] + 4;
1157 +#ifdef CONFIG_PAX_EMUTRAMP
1159 +#ifndef CONFIG_PAX_EMUSIGRT
1160 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
1164 + do { /* PaX: rt_sigreturn emulation */
1165 + unsigned int ldi1, ldi2, bel, nop;
1167 + err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
1168 + err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
1169 + err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
1170 + err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
1175 + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
1176 + ldi2 == 0x3414015AU &&
1177 + bel == 0xE4008200U &&
1178 + nop == 0x08000240U)
1180 + regs->gr[25] = (ldi1 & 2) >> 1;
1181 + regs->gr[20] = __NR_rt_sigreturn;
1182 + regs->gr[31] = regs->iaoq[1] + 16;
1183 + regs->sr[0] = regs->iasq[1];
1184 + regs->iaoq[0] = 0x100UL;
1185 + regs->iaoq[1] = regs->iaoq[0] + 4;
1186 + regs->iasq[0] = regs->sr[2];
1187 + regs->iasq[1] = regs->sr[2];
1196 +void pax_report_insns(void *pc, void *sp)
1200 + printk(KERN_ERR "PAX: bytes at PC: ");
1201 + for (i = 0; i < 5; i++) {
1203 + if (get_user(c, (unsigned int *)pc+i))
1204 + printk(KERN_CONT "???????? ");
1206 + printk(KERN_CONT "%08x ", c);
1212 int fixup_exception(struct pt_regs *regs)
1214 const struct exception_table_entry *fix;
1215 @@ -193,8 +304,33 @@ good_area:
1217 acc_type = parisc_acctyp(code,regs->iir);
1219 - if ((vma->vm_flags & acc_type) != acc_type)
1220 + if ((vma->vm_flags & acc_type) != acc_type) {
1222 +#ifdef CONFIG_PAX_PAGEEXEC
1223 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
1224 + (address & ~3UL) == instruction_pointer(regs))
1226 + up_read(&mm->mmap_sem);
1227 + switch (pax_handle_fetch_fault(regs)) {
1229 +#ifdef CONFIG_PAX_EMUPLT
1234 +#ifdef CONFIG_PAX_EMUTRAMP
1240 + pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1241 + do_group_exit(SIGKILL);
1249 * If for any reason at all we couldn't handle the fault, make
1250 diff -urNp linux-2.6.29/arch/powerpc/include/asm/elf.h linux-2.6.29/arch/powerpc/include/asm/elf.h
1251 --- linux-2.6.29/arch/powerpc/include/asm/elf.h 2009-03-23 19:12:14.000000000 -0400
1252 +++ linux-2.6.29/arch/powerpc/include/asm/elf.h 2009-03-28 14:26:18.000000000 -0400
1253 @@ -180,6 +180,18 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
1255 #define ELF_ET_DYN_BASE (0x20000000)
1257 +#ifdef CONFIG_PAX_ASLR
1258 +#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
1260 +#ifdef __powerpc64__
1261 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1262 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1264 +#define PAX_DELTA_MMAP_LEN 15
1265 +#define PAX_DELTA_STACK_LEN 15
1270 * Our registers are always unsigned longs, whether we're a 32 bit
1271 * process or 64 bit, on either a 64 bit or 32 bit kernel.
1272 diff -urNp linux-2.6.29/arch/powerpc/include/asm/kmap_types.h linux-2.6.29/arch/powerpc/include/asm/kmap_types.h
1273 --- linux-2.6.29/arch/powerpc/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
1274 +++ linux-2.6.29/arch/powerpc/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
1275 @@ -26,6 +26,7 @@ enum km_type {
1283 diff -urNp linux-2.6.29/arch/powerpc/include/asm/page_64.h linux-2.6.29/arch/powerpc/include/asm/page_64.h
1284 --- linux-2.6.29/arch/powerpc/include/asm/page_64.h 2009-03-23 19:12:14.000000000 -0400
1285 +++ linux-2.6.29/arch/powerpc/include/asm/page_64.h 2009-03-28 14:26:18.000000000 -0400
1286 @@ -170,15 +170,18 @@ do { \
1287 * stack by default, so in the absense of a PT_GNU_STACK program header
1288 * we turn execute permission off.
1290 -#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1291 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1292 +#define VM_STACK_DEFAULT_FLAGS32 \
1293 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1294 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1296 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1297 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1299 +#ifndef CONFIG_PAX_PAGEEXEC
1300 #define VM_STACK_DEFAULT_FLAGS \
1301 (test_thread_flag(TIF_32BIT) ? \
1302 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
1305 #include <asm-generic/page.h>
1307 diff -urNp linux-2.6.29/arch/powerpc/include/asm/page.h linux-2.6.29/arch/powerpc/include/asm/page.h
1308 --- linux-2.6.29/arch/powerpc/include/asm/page.h 2009-03-23 19:12:14.000000000 -0400
1309 +++ linux-2.6.29/arch/powerpc/include/asm/page.h 2009-03-28 14:26:18.000000000 -0400
1310 @@ -114,8 +114,9 @@ extern phys_addr_t kernstart_addr;
1311 * and needs to be executable. This means the whole heap ends
1312 * up being executable.
1314 -#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1315 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1316 +#define VM_DATA_DEFAULT_FLAGS32 \
1317 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1318 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1320 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1321 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1322 diff -urNp linux-2.6.29/arch/powerpc/kernel/module_32.c linux-2.6.29/arch/powerpc/kernel/module_32.c
1323 --- linux-2.6.29/arch/powerpc/kernel/module_32.c 2009-03-23 19:12:14.000000000 -0400
1324 +++ linux-2.6.29/arch/powerpc/kernel/module_32.c 2009-03-28 14:26:18.000000000 -0400
1325 @@ -162,7 +162,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1326 me->arch.core_plt_section = i;
1328 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1329 - printk("Module doesn't contain .plt or .init.plt sections.\n");
1330 + printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1334 @@ -203,11 +203,16 @@ static uint32_t do_plt_call(void *locati
1336 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1337 /* Init, or core PLT? */
1338 - if (location >= mod->module_core
1339 - && location < mod->module_core + mod->core_size)
1340 + if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1341 + (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1342 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1344 + else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1345 + (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1346 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1348 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1352 /* Find this entry, or if that fails, the next avail. entry */
1353 while (entry->jump[0]) {
1354 diff -urNp linux-2.6.29/arch/powerpc/kernel/signal_32.c linux-2.6.29/arch/powerpc/kernel/signal_32.c
1355 --- linux-2.6.29/arch/powerpc/kernel/signal_32.c 2009-03-23 19:12:14.000000000 -0400
1356 +++ linux-2.6.29/arch/powerpc/kernel/signal_32.c 2009-03-28 14:26:18.000000000 -0400
1357 @@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig
1358 /* Save user registers on the stack */
1359 frame = &rt_sf->uc.uc_mcontext;
1361 - if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1362 + if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1363 if (save_user_regs(regs, frame, 0, 1))
1365 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1366 diff -urNp linux-2.6.29/arch/powerpc/kernel/signal_64.c linux-2.6.29/arch/powerpc/kernel/signal_64.c
1367 --- linux-2.6.29/arch/powerpc/kernel/signal_64.c 2009-03-23 19:12:14.000000000 -0400
1368 +++ linux-2.6.29/arch/powerpc/kernel/signal_64.c 2009-03-28 14:26:18.000000000 -0400
1369 @@ -429,7 +429,7 @@ int handle_rt_signal64(int signr, struct
1370 current->thread.fpscr.val = 0;
1372 /* Set up to return from userspace. */
1373 - if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1374 + if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1375 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1377 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1378 diff -urNp linux-2.6.29/arch/powerpc/kernel/vdso.c linux-2.6.29/arch/powerpc/kernel/vdso.c
1379 --- linux-2.6.29/arch/powerpc/kernel/vdso.c 2009-03-23 19:12:14.000000000 -0400
1380 +++ linux-2.6.29/arch/powerpc/kernel/vdso.c 2009-03-28 14:26:18.000000000 -0400
1381 @@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
1382 vdso_base = VDSO32_MBASE;
1385 - current->mm->context.vdso_base = 0;
1386 + current->mm->context.vdso_base = ~0UL;
1388 /* vDSO has a problem and was disabled, just don't "enable" it for the
1390 @@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
1392 down_write(&mm->mmap_sem);
1393 vdso_base = get_unmapped_area(NULL, vdso_base,
1394 - vdso_pages << PAGE_SHIFT, 0, 0);
1395 + vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1396 if (IS_ERR_VALUE(vdso_base)) {
1399 diff -urNp linux-2.6.29/arch/powerpc/mm/fault.c linux-2.6.29/arch/powerpc/mm/fault.c
1400 --- linux-2.6.29/arch/powerpc/mm/fault.c 2009-03-23 19:12:14.000000000 -0400
1401 +++ linux-2.6.29/arch/powerpc/mm/fault.c 2009-03-28 14:26:18.000000000 -0400
1403 #include <linux/module.h>
1404 #include <linux/kprobes.h>
1405 #include <linux/kdebug.h>
1406 +#include <linux/slab.h>
1407 +#include <linux/pagemap.h>
1408 +#include <linux/compiler.h>
1409 +#include <linux/unistd.h>
1411 #include <asm/firmware.h>
1412 #include <asm/page.h>
1413 @@ -63,6 +67,363 @@ static inline int notify_page_fault(stru
1417 +#ifdef CONFIG_PAX_EMUSIGRT
1418 +void pax_syscall_close(struct vm_area_struct *vma)
1420 + vma->vm_mm->call_syscall = 0UL;
1423 +static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1425 + unsigned int *kaddr;
1427 + vmf->page = alloc_page(GFP_HIGHUSER);
1429 + return VM_FAULT_OOM;
1431 + kaddr = kmap(vmf->page);
1432 + memset(kaddr, 0, PAGE_SIZE);
1433 + kaddr[0] = 0x44000002U; /* sc */
1434 + __flush_dcache_icache(kaddr);
1435 + kunmap(vmf->page);
1436 + return VM_FAULT_MAJOR;
1439 +static struct vm_operations_struct pax_vm_ops = {
1440 + .close = pax_syscall_close,
1441 + .fault = pax_syscall_fault
1444 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1448 + vma->vm_mm = current->mm;
1449 + vma->vm_start = addr;
1450 + vma->vm_end = addr + PAGE_SIZE;
1451 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1452 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1453 + vma->vm_ops = &pax_vm_ops;
1455 + ret = insert_vm_struct(current->mm, vma);
1459 + ++current->mm->total_vm;
1464 +#ifdef CONFIG_PAX_PAGEEXEC
1466 + * PaX: decide what to do with offenders (regs->nip = fault address)
1468 + * returns 1 when task should be killed
1469 + * 2 when patched GOT trampoline was detected
1470 + * 3 when patched PLT trampoline was detected
1471 + * 4 when unpatched PLT trampoline was detected
1472 + * 5 when sigreturn trampoline was detected
1473 + * 6 when rt_sigreturn trampoline was detected
1475 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1478 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1482 +#ifdef CONFIG_PAX_EMUPLT
1483 + do { /* PaX: patched GOT emulation */
1484 + unsigned int blrl;
1486 + err = get_user(blrl, (unsigned int *)regs->nip);
1488 + if (!err && blrl == 0x4E800021U) {
1489 + unsigned long temp = regs->nip;
1491 + regs->nip = regs->link & 0xFFFFFFFCUL;
1492 + regs->link = temp + 4UL;
1497 + do { /* PaX: patched PLT emulation #1 */
1500 + err = get_user(b, (unsigned int *)regs->nip);
1502 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
1503 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1508 + do { /* PaX: unpatched PLT emulation #1 */
1509 + unsigned int li, b;
1511 + err = get_user(li, (unsigned int *)regs->nip);
1512 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1514 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1515 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1516 + unsigned long addr = b | 0xFC000000UL;
1518 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1519 + err = get_user(rlwinm, (unsigned int *)addr);
1520 + err |= get_user(add, (unsigned int *)(addr+4));
1521 + err |= get_user(li2, (unsigned int *)(addr+8));
1522 + err |= get_user(addis2, (unsigned int *)(addr+12));
1523 + err |= get_user(mtctr, (unsigned int *)(addr+16));
1524 + err |= get_user(li3, (unsigned int *)(addr+20));
1525 + err |= get_user(addis3, (unsigned int *)(addr+24));
1526 + err |= get_user(bctr, (unsigned int *)(addr+28));
1531 + if (rlwinm == 0x556C083CU &&
1532 + add == 0x7D6C5A14U &&
1533 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1534 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1535 + mtctr == 0x7D8903A6U &&
1536 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1537 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1538 + bctr == 0x4E800420U)
1540 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1541 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1542 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1543 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1544 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1545 + regs->nip = regs->ctr;
1552 + do { /* PaX: unpatched PLT emulation #2 */
1553 + unsigned int lis, lwzu, b, bctr;
1555 + err = get_user(lis, (unsigned int *)regs->nip);
1556 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1557 + err |= get_user(b, (unsigned int *)(regs->nip+8));
1558 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1563 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
1564 + (lwzu & 0xU) == 0xU &&
1565 + (b & 0xFC000003U) == 0x48000000U &&
1566 + bctr == 0x4E800420U)
1568 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1569 + unsigned long addr = b | 0xFC000000UL;
1571 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1572 + err = get_user(addis, (unsigned int *)addr);
1573 + err |= get_user(addi, (unsigned int *)(addr+4));
1574 + err |= get_user(rlwinm, (unsigned int *)(addr+8));
1575 + err |= get_user(add, (unsigned int *)(addr+12));
1576 + err |= get_user(li2, (unsigned int *)(addr+16));
1577 + err |= get_user(addis2, (unsigned int *)(addr+20));
1578 + err |= get_user(mtctr, (unsigned int *)(addr+24));
1579 + err |= get_user(li3, (unsigned int *)(addr+28));
1580 + err |= get_user(addis3, (unsigned int *)(addr+32));
1581 + err |= get_user(bctr, (unsigned int *)(addr+36));
1586 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1587 + (addi & 0xFFFF0000U) == 0x396B0000U &&
1588 + rlwinm == 0x556C083CU &&
1589 + add == 0x7D6C5A14U &&
1590 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1591 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1592 + mtctr == 0x7D8903A6U &&
1593 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1594 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1595 + bctr == 0x4E800420U)
1597 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1598 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1599 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1600 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1601 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1602 + regs->nip = regs->ctr;
1609 + do { /* PaX: unpatched PLT emulation #3 */
1610 + unsigned int li, b;
1612 + err = get_user(li, (unsigned int *)regs->nip);
1613 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1615 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1616 + unsigned int addis, lwz, mtctr, bctr;
1617 + unsigned long addr = b | 0xFC000000UL;
1619 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1620 + err = get_user(addis, (unsigned int *)addr);
1621 + err |= get_user(lwz, (unsigned int *)(addr+4));
1622 + err |= get_user(mtctr, (unsigned int *)(addr+8));
1623 + err |= get_user(bctr, (unsigned int *)(addr+12));
1628 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1629 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
1630 + mtctr == 0x7D6903A6U &&
1631 + bctr == 0x4E800420U)
1635 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1636 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1638 + err = get_user(r11, (unsigned int *)addr);
1642 + regs->gpr[PT_R11] = r11;
1651 +#ifdef CONFIG_PAX_EMUSIGRT
1652 + do { /* PaX: sigreturn emulation */
1653 + unsigned int li, sc;
1655 + err = get_user(li, (unsigned int *)regs->nip);
1656 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1658 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1659 + struct vm_area_struct *vma;
1660 + unsigned long call_syscall;
1662 + down_read(¤t->mm->mmap_sem);
1663 + call_syscall = current->mm->call_syscall;
1664 + up_read(¤t->mm->mmap_sem);
1665 + if (likely(call_syscall))
1668 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1670 + down_write(¤t->mm->mmap_sem);
1671 + if (current->mm->call_syscall) {
1672 + call_syscall = current->mm->call_syscall;
1673 + up_write(¤t->mm->mmap_sem);
1675 + kmem_cache_free(vm_area_cachep, vma);
1679 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1680 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1681 + up_write(¤t->mm->mmap_sem);
1683 + kmem_cache_free(vm_area_cachep, vma);
1687 + if (pax_insert_vma(vma, call_syscall)) {
1688 + up_write(¤t->mm->mmap_sem);
1689 + kmem_cache_free(vm_area_cachep, vma);
1693 + current->mm->call_syscall = call_syscall;
1694 + up_write(¤t->mm->mmap_sem);
1697 + regs->gpr[PT_R0] = __NR_sigreturn;
1698 + regs->nip = call_syscall;
1703 + do { /* PaX: rt_sigreturn emulation */
1704 + unsigned int li, sc;
1706 + err = get_user(li, (unsigned int *)regs->nip);
1707 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1709 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1710 + struct vm_area_struct *vma;
1711 + unsigned int call_syscall;
1713 + down_read(¤t->mm->mmap_sem);
1714 + call_syscall = current->mm->call_syscall;
1715 + up_read(¤t->mm->mmap_sem);
1716 + if (likely(call_syscall))
1719 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1721 + down_write(¤t->mm->mmap_sem);
1722 + if (current->mm->call_syscall) {
1723 + call_syscall = current->mm->call_syscall;
1724 + up_write(¤t->mm->mmap_sem);
1726 + kmem_cache_free(vm_area_cachep, vma);
1730 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1731 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1732 + up_write(¤t->mm->mmap_sem);
1734 + kmem_cache_free(vm_area_cachep, vma);
1738 + if (pax_insert_vma(vma, call_syscall)) {
1739 + up_write(¤t->mm->mmap_sem);
1740 + kmem_cache_free(vm_area_cachep, vma);
1744 + current->mm->call_syscall = call_syscall;
1745 + up_write(¤t->mm->mmap_sem);
1748 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
1749 + regs->nip = call_syscall;
1758 +void pax_report_insns(void *pc, void *sp)
1762 + printk(KERN_ERR "PAX: bytes at PC: ");
1763 + for (i = 0; i < 5; i++) {
1765 + if (get_user(c, (unsigned int *)pc+i))
1766 + printk(KERN_CONT "???????? ");
1768 + printk(KERN_CONT "%08x ", c);
1775 * Check whether the instruction at regs->nip is a store using
1776 * an update addressing form which will update r1.
1777 @@ -133,7 +494,7 @@ int __kprobes do_page_fault(struct pt_re
1778 * indicate errors in DSISR but can validly be set in SRR1.
1781 - error_code &= 0x48200000;
1782 + error_code &= 0x58200000;
1784 is_write = error_code & DSISR_ISSTORE;
1786 @@ -339,6 +700,37 @@ bad_area:
1787 bad_area_nosemaphore:
1788 /* User mode accesses cause a SIGSEGV */
1789 if (user_mode(regs)) {
1791 +#ifdef CONFIG_PAX_PAGEEXEC
1792 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1793 +#ifdef CONFIG_PPC64
1794 + if (is_exec && (error_code & DSISR_PROTFAULT)) {
1796 + if (is_exec && regs->nip == address) {
1798 + switch (pax_handle_fetch_fault(regs)) {
1800 +#ifdef CONFIG_PAX_EMUPLT
1807 +#ifdef CONFIG_PAX_EMUSIGRT
1815 + pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
1816 + do_group_exit(SIGKILL);
1821 _exception(SIGSEGV, regs, code, address);
1824 diff -urNp linux-2.6.29/arch/powerpc/mm/mmap.c linux-2.6.29/arch/powerpc/mm/mmap.c
1825 --- linux-2.6.29/arch/powerpc/mm/mmap.c 2009-03-23 19:12:14.000000000 -0400
1826 +++ linux-2.6.29/arch/powerpc/mm/mmap.c 2009-03-28 14:26:18.000000000 -0400
1827 @@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1829 if (mmap_is_legacy()) {
1830 mm->mmap_base = TASK_UNMAPPED_BASE;
1832 +#ifdef CONFIG_PAX_RANDMMAP
1833 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1834 + mm->mmap_base += mm->delta_mmap;
1837 mm->get_unmapped_area = arch_get_unmapped_area;
1838 mm->unmap_area = arch_unmap_area;
1840 mm->mmap_base = mmap_base();
1842 +#ifdef CONFIG_PAX_RANDMMAP
1843 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1844 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1847 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1848 mm->unmap_area = arch_unmap_area_topdown;
1850 diff -urNp linux-2.6.29/arch/s390/include/asm/kmap_types.h linux-2.6.29/arch/s390/include/asm/kmap_types.h
1851 --- linux-2.6.29/arch/s390/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
1852 +++ linux-2.6.29/arch/s390/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
1853 @@ -16,6 +16,7 @@ enum km_type {
1861 diff -urNp linux-2.6.29/arch/s390/kernel/module.c linux-2.6.29/arch/s390/kernel/module.c
1862 --- linux-2.6.29/arch/s390/kernel/module.c 2009-03-23 19:12:14.000000000 -0400
1863 +++ linux-2.6.29/arch/s390/kernel/module.c 2009-03-28 14:26:18.000000000 -0400
1864 @@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
1866 /* Increase core size by size of got & plt and set start
1867 offsets for got and plt. */
1868 - me->core_size = ALIGN(me->core_size, 4);
1869 - me->arch.got_offset = me->core_size;
1870 - me->core_size += me->arch.got_size;
1871 - me->arch.plt_offset = me->core_size;
1872 - me->core_size += me->arch.plt_size;
1873 + me->core_size_rw = ALIGN(me->core_size_rw, 4);
1874 + me->arch.got_offset = me->core_size_rw;
1875 + me->core_size_rw += me->arch.got_size;
1876 + me->arch.plt_offset = me->core_size_rx;
1877 + me->core_size_rx += me->arch.plt_size;
1881 @@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1882 if (info->got_initialized == 0) {
1885 - gotent = me->module_core + me->arch.got_offset +
1886 + gotent = me->module_core_rw + me->arch.got_offset +
1889 info->got_initialized = 1;
1890 @@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1891 else if (r_type == R_390_GOTENT ||
1892 r_type == R_390_GOTPLTENT)
1893 *(unsigned int *) loc =
1894 - (val + (Elf_Addr) me->module_core - loc) >> 1;
1895 + (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
1896 else if (r_type == R_390_GOT64 ||
1897 r_type == R_390_GOTPLT64)
1898 *(unsigned long *) loc = val;
1899 @@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1900 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
1901 if (info->plt_initialized == 0) {
1903 - ip = me->module_core + me->arch.plt_offset +
1904 + ip = me->module_core_rx + me->arch.plt_offset +
1906 #ifndef CONFIG_64BIT
1907 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
1908 @@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1909 val = me->arch.plt_offset - me->arch.got_offset +
1910 info->plt_offset + rela->r_addend;
1912 - val = (Elf_Addr) me->module_core +
1913 + val = (Elf_Addr) me->module_core_rx +
1914 me->arch.plt_offset + info->plt_offset +
1915 rela->r_addend - loc;
1916 if (r_type == R_390_PLT16DBL)
1917 @@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1918 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
1919 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
1920 val = val + rela->r_addend -
1921 - ((Elf_Addr) me->module_core + me->arch.got_offset);
1922 + ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
1923 if (r_type == R_390_GOTOFF16)
1924 *(unsigned short *) loc = val;
1925 else if (r_type == R_390_GOTOFF32)
1926 @@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1928 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
1929 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
1930 - val = (Elf_Addr) me->module_core + me->arch.got_offset +
1931 + val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
1932 rela->r_addend - loc;
1933 if (r_type == R_390_GOTPC)
1934 *(unsigned int *) loc = val;
1935 diff -urNp linux-2.6.29/arch/sh/include/asm/kmap_types.h linux-2.6.29/arch/sh/include/asm/kmap_types.h
1936 --- linux-2.6.29/arch/sh/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
1937 +++ linux-2.6.29/arch/sh/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
1938 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
1943 +D(13) KM_CLEARPAGE,
1948 diff -urNp linux-2.6.29/arch/sparc/include/asm/elf_32.h linux-2.6.29/arch/sparc/include/asm/elf_32.h
1949 --- linux-2.6.29/arch/sparc/include/asm/elf_32.h 2009-03-23 19:12:14.000000000 -0400
1950 +++ linux-2.6.29/arch/sparc/include/asm/elf_32.h 2009-03-28 14:26:18.000000000 -0400
1951 @@ -116,6 +116,13 @@ typedef struct {
1953 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
1955 +#ifdef CONFIG_PAX_ASLR
1956 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
1958 +#define PAX_DELTA_MMAP_LEN 16
1959 +#define PAX_DELTA_STACK_LEN 16
1962 /* This yields a mask that user programs can use to figure out what
1963 instruction set this cpu supports. This can NOT be done in userspace
1965 diff -urNp linux-2.6.29/arch/sparc/include/asm/elf_64.h linux-2.6.29/arch/sparc/include/asm/elf_64.h
1966 --- linux-2.6.29/arch/sparc/include/asm/elf_64.h 2009-03-23 19:12:14.000000000 -0400
1967 +++ linux-2.6.29/arch/sparc/include/asm/elf_64.h 2009-03-28 14:26:18.000000000 -0400
1968 @@ -163,6 +163,12 @@ typedef struct {
1969 #define ELF_ET_DYN_BASE 0x0000010000000000UL
1970 #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
1972 +#ifdef CONFIG_PAX_ASLR
1973 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
1975 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
1976 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
1979 /* This yields a mask that user programs can use to figure out what
1980 instruction set this cpu supports. */
1981 diff -urNp linux-2.6.29/arch/sparc/include/asm/kmap_types.h linux-2.6.29/arch/sparc/include/asm/kmap_types.h
1982 --- linux-2.6.29/arch/sparc/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
1983 +++ linux-2.6.29/arch/sparc/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
1984 @@ -19,6 +19,7 @@ enum km_type {
1992 diff -urNp linux-2.6.29/arch/sparc/include/asm/pgtable_32.h linux-2.6.29/arch/sparc/include/asm/pgtable_32.h
1993 --- linux-2.6.29/arch/sparc/include/asm/pgtable_32.h 2009-03-23 19:12:14.000000000 -0400
1994 +++ linux-2.6.29/arch/sparc/include/asm/pgtable_32.h 2009-03-28 14:26:18.000000000 -0400
1995 @@ -43,6 +43,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
1996 BTFIXUPDEF_INT(page_none)
1997 BTFIXUPDEF_INT(page_copy)
1998 BTFIXUPDEF_INT(page_readonly)
2000 +#ifdef CONFIG_PAX_PAGEEXEC
2001 +BTFIXUPDEF_INT(page_shared_noexec)
2002 +BTFIXUPDEF_INT(page_copy_noexec)
2003 +BTFIXUPDEF_INT(page_readonly_noexec)
2006 BTFIXUPDEF_INT(page_kernel)
2008 #define PMD_SHIFT SUN4C_PMD_SHIFT
2009 @@ -64,6 +71,16 @@ extern pgprot_t PAGE_SHARED;
2010 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
2011 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
2013 +#ifdef CONFIG_PAX_PAGEEXEC
2014 +extern pgprot_t PAGE_SHARED_NOEXEC;
2015 +# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
2016 +# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
2018 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
2019 +# define PAGE_COPY_NOEXEC PAGE_COPY
2020 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
2023 extern unsigned long page_kernel;
2026 diff -urNp linux-2.6.29/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.29/arch/sparc/include/asm/pgtsrmmu.h
2027 --- linux-2.6.29/arch/sparc/include/asm/pgtsrmmu.h 2009-03-23 19:12:14.000000000 -0400
2028 +++ linux-2.6.29/arch/sparc/include/asm/pgtsrmmu.h 2009-03-28 14:26:18.000000000 -0400
2029 @@ -115,6 +115,13 @@
2030 SRMMU_EXEC | SRMMU_REF)
2031 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
2032 SRMMU_EXEC | SRMMU_REF)
2034 +#ifdef CONFIG_PAX_PAGEEXEC
2035 +#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
2036 +#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
2037 +#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
2040 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
2041 SRMMU_DIRTY | SRMMU_REF)
2043 diff -urNp linux-2.6.29/arch/sparc/kernel/Makefile linux-2.6.29/arch/sparc/kernel/Makefile
2044 --- linux-2.6.29/arch/sparc/kernel/Makefile 2009-03-23 19:12:14.000000000 -0400
2045 +++ linux-2.6.29/arch/sparc/kernel/Makefile 2009-03-28 14:26:18.000000000 -0400
2050 -ccflags-y := -Werror
2051 +#ccflags-y := -Werror
2053 extra-y := head_$(BITS).o
2054 extra-y += init_task.o
2055 diff -urNp linux-2.6.29/arch/sparc/kernel/sys_sparc_32.c linux-2.6.29/arch/sparc/kernel/sys_sparc_32.c
2056 --- linux-2.6.29/arch/sparc/kernel/sys_sparc_32.c 2009-03-23 19:12:14.000000000 -0400
2057 +++ linux-2.6.29/arch/sparc/kernel/sys_sparc_32.c 2009-03-28 14:26:18.000000000 -0400
2058 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
2059 if (ARCH_SUN4C && len > 0x20000000)
2062 - addr = TASK_UNMAPPED_BASE;
2063 + addr = current->mm->mmap_base;
2065 if (flags & MAP_SHARED)
2066 addr = COLOUR_ALIGN(addr);
2067 diff -urNp linux-2.6.29/arch/sparc/kernel/sys_sparc_64.c linux-2.6.29/arch/sparc/kernel/sys_sparc_64.c
2068 --- linux-2.6.29/arch/sparc/kernel/sys_sparc_64.c 2009-03-23 19:12:14.000000000 -0400
2069 +++ linux-2.6.29/arch/sparc/kernel/sys_sparc_64.c 2009-03-28 14:26:18.000000000 -0400
2070 @@ -125,7 +125,7 @@ unsigned long arch_get_unmapped_area(str
2071 /* We do not accept a shared mapping if it would violate
2072 * cache aliasing constraints.
2074 - if ((flags & MAP_SHARED) &&
2075 + if ((filp || (flags & MAP_SHARED)) &&
2076 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2079 @@ -140,6 +140,10 @@ unsigned long arch_get_unmapped_area(str
2080 if (filp || (flags & MAP_SHARED))
2083 +#ifdef CONFIG_PAX_RANDMMAP
2084 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
2089 addr = COLOUR_ALIGN(addr, pgoff);
2090 @@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str
2093 if (len > mm->cached_hole_size) {
2094 - start_addr = addr = mm->free_area_cache;
2095 + start_addr = addr = mm->free_area_cache;
2097 - start_addr = addr = TASK_UNMAPPED_BASE;
2098 ++ start_addr = addr = mm->mmap_base;
2099 mm->cached_hole_size = 0;
2102 @@ -175,8 +179,8 @@ full_search:
2103 vma = find_vma(mm, VA_EXCLUDE_END);
2105 if (unlikely(task_size < addr)) {
2106 - if (start_addr != TASK_UNMAPPED_BASE) {
2107 - start_addr = addr = TASK_UNMAPPED_BASE;
2108 + if (start_addr != mm->mmap_base) {
2109 + start_addr = addr = mm->mmap_base;
2110 mm->cached_hole_size = 0;
2113 @@ -216,7 +220,7 @@ arch_get_unmapped_area_topdown(struct fi
2114 /* We do not accept a shared mapping if it would violate
2115 * cache aliasing constraints.
2117 - if ((flags & MAP_SHARED) &&
2118 + if ((filp || (flags & MAP_SHARED)) &&
2119 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2122 @@ -380,6 +384,12 @@ void arch_pick_mmap_layout(struct mm_str
2123 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2124 sysctl_legacy_va_layout) {
2125 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2127 +#ifdef CONFIG_PAX_RANDMMAP
2128 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2129 + mm->mmap_base += mm->delta_mmap;
2132 mm->get_unmapped_area = arch_get_unmapped_area;
2133 mm->unmap_area = arch_unmap_area;
2135 @@ -394,6 +404,12 @@ void arch_pick_mmap_layout(struct mm_str
2136 gap = (task_size / 6 * 5);
2138 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2140 +#ifdef CONFIG_PAX_RANDMMAP
2141 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2142 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2145 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2146 mm->unmap_area = arch_unmap_area_topdown;
2148 diff -urNp linux-2.6.29/arch/sparc/Makefile linux-2.6.29/arch/sparc/Makefile
2149 --- linux-2.6.29/arch/sparc/Makefile 2009-03-23 19:12:14.000000000 -0400
2150 +++ linux-2.6.29/arch/sparc/Makefile 2009-03-28 14:26:18.000000000 -0400
2151 @@ -81,7 +81,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
2152 # Export what is needed by arch/sparc/boot/Makefile
2153 export VMLINUX_INIT VMLINUX_MAIN
2154 VMLINUX_INIT := $(head-y) $(init-y)
2155 -VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/
2156 +VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
2157 VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
2158 VMLINUX_MAIN += $(drivers-y) $(net-y)
2160 diff -urNp linux-2.6.29/arch/sparc/mm/fault_32.c linux-2.6.29/arch/sparc/mm/fault_32.c
2161 --- linux-2.6.29/arch/sparc/mm/fault_32.c 2009-03-23 19:12:14.000000000 -0400
2162 +++ linux-2.6.29/arch/sparc/mm/fault_32.c 2009-03-28 14:26:18.000000000 -0400
2164 #include <linux/interrupt.h>
2165 #include <linux/module.h>
2166 #include <linux/kdebug.h>
2167 +#include <linux/slab.h>
2168 +#include <linux/pagemap.h>
2169 +#include <linux/compiler.h>
2171 #include <asm/system.h>
2172 #include <asm/page.h>
2173 @@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
2174 return safe_compute_effective_address(regs, insn);
2177 +#ifdef CONFIG_PAX_PAGEEXEC
2178 +void pax_emuplt_close(struct vm_area_struct *vma)
2180 + vma->vm_mm->call_dl_resolve = 0UL;
2183 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2185 + unsigned int *kaddr;
2187 + vmf->page = alloc_page(GFP_HIGHUSER);
2189 + return VM_FAULT_OOM;
2191 + kaddr = kmap(vmf->page);
2192 + memset(kaddr, 0, PAGE_SIZE);
2193 + kaddr[0] = 0x9DE3BFA8U; /* save */
2194 + flush_dcache_page(vmf->page);
2195 + kunmap(vmf->page);
2196 + return VM_FAULT_MAJOR;
2199 +static struct vm_operations_struct pax_vm_ops = {
2200 + .close = pax_emuplt_close,
2201 + .fault = pax_emuplt_fault
2204 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2208 + vma->vm_mm = current->mm;
2209 + vma->vm_start = addr;
2210 + vma->vm_end = addr + PAGE_SIZE;
2211 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2212 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2213 + vma->vm_ops = &pax_vm_ops;
2215 + ret = insert_vm_struct(current->mm, vma);
2219 + ++current->mm->total_vm;
2224 + * PaX: decide what to do with offenders (regs->pc = fault address)
2226 + * returns 1 when task should be killed
2227 + * 2 when patched PLT trampoline was detected
2228 + * 3 when unpatched PLT trampoline was detected
2230 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2233 +#ifdef CONFIG_PAX_EMUPLT
2236 + do { /* PaX: patched PLT emulation #1 */
2237 + unsigned int sethi1, sethi2, jmpl;
2239 + err = get_user(sethi1, (unsigned int *)regs->pc);
2240 + err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
2241 + err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
2246 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2247 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2248 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2250 + unsigned int addr;
2252 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2253 + addr = regs->u_regs[UREG_G1];
2254 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2256 + regs->npc = addr+4;
2261 + { /* PaX: patched PLT emulation #2 */
2264 + err = get_user(ba, (unsigned int *)regs->pc);
2266 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2267 + unsigned int addr;
2269 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2271 + regs->npc = addr+4;
2276 + do { /* PaX: patched PLT emulation #3 */
2277 + unsigned int sethi, jmpl, nop;
2279 + err = get_user(sethi, (unsigned int *)regs->pc);
2280 + err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
2281 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
2286 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2287 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2288 + nop == 0x01000000U)
2290 + unsigned int addr;
2292 + addr = (sethi & 0x003FFFFFU) << 10;
2293 + regs->u_regs[UREG_G1] = addr;
2294 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2296 + regs->npc = addr+4;
2301 + do { /* PaX: unpatched PLT emulation step 1 */
2302 + unsigned int sethi, ba, nop;
2304 + err = get_user(sethi, (unsigned int *)regs->pc);
2305 + err |= get_user(ba, (unsigned int *)(regs->pc+4));
2306 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
2311 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2312 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2313 + nop == 0x01000000U)
2315 + unsigned int addr, save, call;
2317 + if ((ba & 0xFFC00000U) == 0x30800000U)
2318 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2320 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2322 + err = get_user(save, (unsigned int *)addr);
2323 + err |= get_user(call, (unsigned int *)(addr+4));
2324 + err |= get_user(nop, (unsigned int *)(addr+8));
2328 + if (save == 0x9DE3BFA8U &&
2329 + (call & 0xC0000000U) == 0x40000000U &&
2330 + nop == 0x01000000U)
2332 + struct vm_area_struct *vma;
2333 + unsigned long call_dl_resolve;
2335 + down_read(¤t->mm->mmap_sem);
2336 + call_dl_resolve = current->mm->call_dl_resolve;
2337 + up_read(¤t->mm->mmap_sem);
2338 + if (likely(call_dl_resolve))
2341 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2343 + down_write(¤t->mm->mmap_sem);
2344 + if (current->mm->call_dl_resolve) {
2345 + call_dl_resolve = current->mm->call_dl_resolve;
2346 + up_write(¤t->mm->mmap_sem);
2348 + kmem_cache_free(vm_area_cachep, vma);
2352 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2353 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2354 + up_write(¤t->mm->mmap_sem);
2356 + kmem_cache_free(vm_area_cachep, vma);
2360 + if (pax_insert_vma(vma, call_dl_resolve)) {
2361 + up_write(¤t->mm->mmap_sem);
2362 + kmem_cache_free(vm_area_cachep, vma);
2366 + current->mm->call_dl_resolve = call_dl_resolve;
2367 + up_write(¤t->mm->mmap_sem);
2370 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2371 + regs->pc = call_dl_resolve;
2372 + regs->npc = addr+4;
2378 + do { /* PaX: unpatched PLT emulation step 2 */
2379 + unsigned int save, call, nop;
2381 + err = get_user(save, (unsigned int *)(regs->pc-4));
2382 + err |= get_user(call, (unsigned int *)regs->pc);
2383 + err |= get_user(nop, (unsigned int *)(regs->pc+4));
2387 + if (save == 0x9DE3BFA8U &&
2388 + (call & 0xC0000000U) == 0x40000000U &&
2389 + nop == 0x01000000U)
2391 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2393 + regs->u_regs[UREG_RETPC] = regs->pc;
2394 + regs->pc = dl_resolve;
2395 + regs->npc = dl_resolve+4;
2404 +void pax_report_insns(void *pc, void *sp)
2408 + printk(KERN_ERR "PAX: bytes at PC: ");
2409 + for (i = 0; i < 5; i++) {
2411 + if (get_user(c, (unsigned int *)pc+i))
2412 + printk(KERN_CONT "???????? ");
2414 + printk(KERN_CONT "%08x ", c);
2420 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2421 unsigned long address)
2423 @@ -231,6 +477,24 @@ good_area:
2424 if(!(vma->vm_flags & VM_WRITE))
2428 +#ifdef CONFIG_PAX_PAGEEXEC
2429 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
2430 + up_read(&mm->mmap_sem);
2431 + switch (pax_handle_fetch_fault(regs)) {
2433 +#ifdef CONFIG_PAX_EMUPLT
2440 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2441 + do_group_exit(SIGKILL);
2445 /* Allow reads even for write-only mappings */
2446 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2448 diff -urNp linux-2.6.29/arch/sparc/mm/fault_64.c linux-2.6.29/arch/sparc/mm/fault_64.c
2449 --- linux-2.6.29/arch/sparc/mm/fault_64.c 2009-03-23 19:12:14.000000000 -0400
2450 +++ linux-2.6.29/arch/sparc/mm/fault_64.c 2009-03-28 14:26:18.000000000 -0400
2452 #include <linux/kprobes.h>
2453 #include <linux/kdebug.h>
2454 #include <linux/percpu.h>
2455 +#include <linux/slab.h>
2456 +#include <linux/pagemap.h>
2457 +#include <linux/compiler.h>
2459 #include <asm/page.h>
2460 #include <asm/pgtable.h>
2461 @@ -249,6 +252,367 @@ static void noinline bogus_32bit_fault_a
2465 +#ifdef CONFIG_PAX_PAGEEXEC
2466 +#ifdef CONFIG_PAX_EMUPLT
2467 +static void pax_emuplt_close(struct vm_area_struct *vma)
2469 + vma->vm_mm->call_dl_resolve = 0UL;
2472 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2474 + unsigned int *kaddr;
2476 + vmf->page = alloc_page(GFP_HIGHUSER);
2478 + return VM_FAULT_OOM;
2480 + kaddr = kmap(vmf->page);
2481 + memset(kaddr, 0, PAGE_SIZE);
2482 + kaddr[0] = 0x9DE3BFA8U; /* save */
2483 + flush_dcache_page(vmf->page);
2484 + kunmap(vmf->page);
2485 + return VM_FAULT_MAJOR;
2488 +static struct vm_operations_struct pax_vm_ops = {
2489 + .close = pax_emuplt_close,
2490 + .fault = pax_emuplt_fault
2493 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2497 + vma->vm_mm = current->mm;
2498 + vma->vm_start = addr;
2499 + vma->vm_end = addr + PAGE_SIZE;
2500 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2501 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2502 + vma->vm_ops = &pax_vm_ops;
2504 + ret = insert_vm_struct(current->mm, vma);
2508 + ++current->mm->total_vm;
2514 + * PaX: decide what to do with offenders (regs->tpc = fault address)
2516 + * returns 1 when task should be killed
2517 + * 2 when patched PLT trampoline was detected
2518 + * 3 when unpatched PLT trampoline was detected
2520 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2523 +#ifdef CONFIG_PAX_EMUPLT
2526 + do { /* PaX: patched PLT emulation #1 */
2527 + unsigned int sethi1, sethi2, jmpl;
2529 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2530 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2531 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
2536 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2537 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2538 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2540 + unsigned long addr;
2542 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2543 + addr = regs->u_regs[UREG_G1];
2544 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2546 + regs->tnpc = addr+4;
2551 + { /* PaX: patched PLT emulation #2 */
2554 + err = get_user(ba, (unsigned int *)regs->tpc);
2556 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2557 + unsigned long addr;
2559 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2561 + regs->tnpc = addr+4;
2566 + do { /* PaX: patched PLT emulation #3 */
2567 + unsigned int sethi, jmpl, nop;
2569 + err = get_user(sethi, (unsigned int *)regs->tpc);
2570 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
2571 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2576 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2577 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2578 + nop == 0x01000000U)
2580 + unsigned long addr;
2582 + addr = (sethi & 0x003FFFFFU) << 10;
2583 + regs->u_regs[UREG_G1] = addr;
2584 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2586 + regs->tnpc = addr+4;
2591 + do { /* PaX: patched PLT emulation #4 */
2592 + unsigned int mov1, call, mov2;
2594 + err = get_user(mov1, (unsigned int *)regs->tpc);
2595 + err |= get_user(call, (unsigned int *)(regs->tpc+4));
2596 + err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
2601 + if (mov1 == 0x8210000FU &&
2602 + (call & 0xC0000000U) == 0x40000000U &&
2603 + mov2 == 0x9E100001U)
2605 + unsigned long addr;
2607 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2608 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2610 + regs->tnpc = addr+4;
2615 + do { /* PaX: patched PLT emulation #5 */
2616 + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
2618 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2619 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2620 + err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2621 + err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2622 + err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2623 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2624 + err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2629 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2630 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2631 + (or1 & 0xFFFFE000U) == 0x82106000U &&
2632 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
2633 + sllx == 0x83287020 &&
2634 + jmpl == 0x81C04005U &&
2635 + nop == 0x01000000U)
2637 + unsigned long addr;
2639 + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2640 + regs->u_regs[UREG_G1] <<= 32;
2641 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2642 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2644 + regs->tnpc = addr+4;
2649 + do { /* PaX: patched PLT emulation #6 */
2650 + unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
2652 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2653 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2654 + err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2655 + err |= get_user(or, (unsigned int *)(regs->tpc+12));
2656 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2657 + err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2662 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2663 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2664 + sllx == 0x83287020 &&
2665 + (or & 0xFFFFE000U) == 0x8A116000U &&
2666 + jmpl == 0x81C04005U &&
2667 + nop == 0x01000000U)
2669 + unsigned long addr;
2671 + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2672 + regs->u_regs[UREG_G1] <<= 32;
2673 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2674 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2676 + regs->tnpc = addr+4;
2681 + do { /* PaX: patched PLT emulation #7 */
2682 + unsigned int sethi, ba, nop;
2684 + err = get_user(sethi, (unsigned int *)regs->tpc);
2685 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2686 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2691 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2692 + (ba & 0xFFF00000U) == 0x30600000U &&
2693 + nop == 0x01000000U)
2695 + unsigned long addr;
2697 + addr = (sethi & 0x003FFFFFU) << 10;
2698 + regs->u_regs[UREG_G1] = addr;
2699 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2701 + regs->tnpc = addr+4;
2706 + do { /* PaX: unpatched PLT emulation step 1 */
2707 + unsigned int sethi, ba, nop;
2709 + err = get_user(sethi, (unsigned int *)regs->tpc);
2710 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2711 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2716 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2717 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2718 + nop == 0x01000000U)
2720 + unsigned long addr;
2721 + unsigned int save, call;
2723 + if ((ba & 0xFFC00000U) == 0x30800000U)
2724 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2726 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2728 + err = get_user(save, (unsigned int *)addr);
2729 + err |= get_user(call, (unsigned int *)(addr+4));
2730 + err |= get_user(nop, (unsigned int *)(addr+8));
2734 + if (save == 0x9DE3BFA8U &&
2735 + (call & 0xC0000000U) == 0x40000000U &&
2736 + nop == 0x01000000U)
2738 + struct vm_area_struct *vma;
2739 + unsigned long call_dl_resolve;
2741 + down_read(¤t->mm->mmap_sem);
2742 + call_dl_resolve = current->mm->call_dl_resolve;
2743 + up_read(¤t->mm->mmap_sem);
2744 + if (likely(call_dl_resolve))
2747 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2749 + down_write(¤t->mm->mmap_sem);
2750 + if (current->mm->call_dl_resolve) {
2751 + call_dl_resolve = current->mm->call_dl_resolve;
2752 + up_write(¤t->mm->mmap_sem);
2754 + kmem_cache_free(vm_area_cachep, vma);
2758 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2759 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2760 + up_write(¤t->mm->mmap_sem);
2762 + kmem_cache_free(vm_area_cachep, vma);
2766 + if (pax_insert_vma(vma, call_dl_resolve)) {
2767 + up_write(¤t->mm->mmap_sem);
2768 + kmem_cache_free(vm_area_cachep, vma);
2772 + current->mm->call_dl_resolve = call_dl_resolve;
2773 + up_write(¤t->mm->mmap_sem);
2776 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2777 + regs->tpc = call_dl_resolve;
2778 + regs->tnpc = addr+4;
2784 + do { /* PaX: unpatched PLT emulation step 2 */
2785 + unsigned int save, call, nop;
2787 + err = get_user(save, (unsigned int *)(regs->tpc-4));
2788 + err |= get_user(call, (unsigned int *)regs->tpc);
2789 + err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2793 + if (save == 0x9DE3BFA8U &&
2794 + (call & 0xC0000000U) == 0x40000000U &&
2795 + nop == 0x01000000U)
2797 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2799 + regs->u_regs[UREG_RETPC] = regs->tpc;
2800 + regs->tpc = dl_resolve;
2801 + regs->tnpc = dl_resolve+4;
2810 +void pax_report_insns(void *pc, void *sp)
2814 + printk(KERN_ERR "PAX: bytes at PC: ");
2815 + for (i = 0; i < 5; i++) {
2817 + if (get_user(c, (unsigned int *)pc+i))
2818 + printk(KERN_CONT "???????? ");
2820 + printk(KERN_CONT "%08x ", c);
2826 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2828 struct mm_struct *mm = current->mm;
2829 @@ -315,6 +679,29 @@ asmlinkage void __kprobes do_sparc64_fau
2833 +#ifdef CONFIG_PAX_PAGEEXEC
2834 + /* PaX: detect ITLB misses on non-exec pages */
2835 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2836 + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2838 + if (address != regs->tpc)
2841 + up_read(&mm->mmap_sem);
2842 + switch (pax_handle_fetch_fault(regs)) {
2844 +#ifdef CONFIG_PAX_EMUPLT
2851 + pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
2852 + do_group_exit(SIGKILL);
2856 /* Pure DTLB misses do not tell us whether the fault causing
2857 * load/store/atomic was a write or not, it only says that there
2858 * was no match. So in such a case we (carefully) read the
2859 diff -urNp linux-2.6.29/arch/sparc/mm/init_32.c linux-2.6.29/arch/sparc/mm/init_32.c
2860 --- linux-2.6.29/arch/sparc/mm/init_32.c 2009-03-23 19:12:14.000000000 -0400
2861 +++ linux-2.6.29/arch/sparc/mm/init_32.c 2009-03-28 14:26:18.000000000 -0400
2862 @@ -316,6 +316,9 @@ extern void device_scan(void);
2863 pgprot_t PAGE_SHARED __read_mostly;
2864 EXPORT_SYMBOL(PAGE_SHARED);
2866 +pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
2867 +EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
2869 void __init paging_init(void)
2871 switch(sparc_cpu_model) {
2872 @@ -341,17 +344,17 @@ void __init paging_init(void)
2874 /* Initialize the protection map with non-constant, MMU dependent values. */
2875 protection_map[0] = PAGE_NONE;
2876 - protection_map[1] = PAGE_READONLY;
2877 - protection_map[2] = PAGE_COPY;
2878 - protection_map[3] = PAGE_COPY;
2879 + protection_map[1] = PAGE_READONLY_NOEXEC;
2880 + protection_map[2] = PAGE_COPY_NOEXEC;
2881 + protection_map[3] = PAGE_COPY_NOEXEC;
2882 protection_map[4] = PAGE_READONLY;
2883 protection_map[5] = PAGE_READONLY;
2884 protection_map[6] = PAGE_COPY;
2885 protection_map[7] = PAGE_COPY;
2886 protection_map[8] = PAGE_NONE;
2887 - protection_map[9] = PAGE_READONLY;
2888 - protection_map[10] = PAGE_SHARED;
2889 - protection_map[11] = PAGE_SHARED;
2890 + protection_map[9] = PAGE_READONLY_NOEXEC;
2891 + protection_map[10] = PAGE_SHARED_NOEXEC;
2892 + protection_map[11] = PAGE_SHARED_NOEXEC;
2893 protection_map[12] = PAGE_READONLY;
2894 protection_map[13] = PAGE_READONLY;
2895 protection_map[14] = PAGE_SHARED;
2896 diff -urNp linux-2.6.29/arch/sparc/mm/Makefile linux-2.6.29/arch/sparc/mm/Makefile
2897 --- linux-2.6.29/arch/sparc/mm/Makefile 2009-03-23 19:12:14.000000000 -0400
2898 +++ linux-2.6.29/arch/sparc/mm/Makefile 2009-03-28 14:26:18.000000000 -0400
2903 -ccflags-y := -Werror
2904 +#ccflags-y := -Werror
2906 obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o
2907 obj-y += fault_$(BITS).o
2908 diff -urNp linux-2.6.29/arch/sparc/mm/srmmu.c linux-2.6.29/arch/sparc/mm/srmmu.c
2909 --- linux-2.6.29/arch/sparc/mm/srmmu.c 2009-03-23 19:12:14.000000000 -0400
2910 +++ linux-2.6.29/arch/sparc/mm/srmmu.c 2009-03-28 14:26:18.000000000 -0400
2911 @@ -2148,6 +2148,13 @@ void __init ld_mmu_srmmu(void)
2912 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
2913 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
2914 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
2916 +#ifdef CONFIG_PAX_PAGEEXEC
2917 + PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2918 + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2919 + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2922 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2923 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2925 diff -urNp linux-2.6.29/arch/um/include/asm/kmap_types.h linux-2.6.29/arch/um/include/asm/kmap_types.h
2926 --- linux-2.6.29/arch/um/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
2927 +++ linux-2.6.29/arch/um/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
2928 @@ -23,6 +23,7 @@ enum km_type {
2936 diff -urNp linux-2.6.29/arch/um/include/asm/page.h linux-2.6.29/arch/um/include/asm/page.h
2937 --- linux-2.6.29/arch/um/include/asm/page.h 2009-03-23 19:12:14.000000000 -0400
2938 +++ linux-2.6.29/arch/um/include/asm/page.h 2009-03-28 14:26:18.000000000 -0400
2940 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
2941 #define PAGE_MASK (~(PAGE_SIZE-1))
2943 +#define ktla_ktva(addr) (addr)
2944 +#define ktva_ktla(addr) (addr)
2946 #ifndef __ASSEMBLY__
2949 diff -urNp linux-2.6.29/arch/um/sys-i386/syscalls.c linux-2.6.29/arch/um/sys-i386/syscalls.c
2950 --- linux-2.6.29/arch/um/sys-i386/syscalls.c 2009-03-23 19:12:14.000000000 -0400
2951 +++ linux-2.6.29/arch/um/sys-i386/syscalls.c 2009-03-28 14:26:18.000000000 -0400
2953 #include "asm/uaccess.h"
2954 #include "asm/unistd.h"
2956 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
2958 + unsigned long pax_task_size = TASK_SIZE;
2960 +#ifdef CONFIG_PAX_SEGMEXEC
2961 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2962 + pax_task_size = SEGMEXEC_TASK_SIZE;
2965 + if (len > pax_task_size || addr > pax_task_size - len)
2972 * Perform the select(nd, in, out, ex, tv) and mmap() system
2973 * calls. Linux/i386 didn't use to be able to handle more than
2974 diff -urNp linux-2.6.29/arch/x86/boot/bitops.h linux-2.6.29/arch/x86/boot/bitops.h
2975 --- linux-2.6.29/arch/x86/boot/bitops.h 2009-03-23 19:12:14.000000000 -0400
2976 +++ linux-2.6.29/arch/x86/boot/bitops.h 2009-03-28 14:26:18.000000000 -0400
2977 @@ -26,7 +26,7 @@ static inline int variable_test_bit(int
2979 const u32 *p = (const u32 *)addr;
2981 - asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2982 + asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2986 @@ -37,7 +37,7 @@ static inline int variable_test_bit(int
2988 static inline void set_bit(int nr, void *addr)
2990 - asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2991 + asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2994 #endif /* BOOT_BITOPS_H */
2995 diff -urNp linux-2.6.29/arch/x86/boot/boot.h linux-2.6.29/arch/x86/boot/boot.h
2996 --- linux-2.6.29/arch/x86/boot/boot.h 2009-03-23 19:12:14.000000000 -0400
2997 +++ linux-2.6.29/arch/x86/boot/boot.h 2009-03-28 14:26:18.000000000 -0400
2998 @@ -80,7 +80,7 @@ static inline void io_delay(void)
2999 static inline u16 ds(void)
3002 - asm("movw %%ds,%0" : "=rm" (seg));
3003 + asm volatile("movw %%ds,%0" : "=rm" (seg));
3007 @@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t
3008 static inline int memcmp(const void *s1, const void *s2, size_t len)
3011 - asm("repe; cmpsb; setnz %0"
3012 + asm volatile("repe; cmpsb; setnz %0"
3013 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
3016 diff -urNp linux-2.6.29/arch/x86/boot/compressed/head_32.S linux-2.6.29/arch/x86/boot/compressed/head_32.S
3017 --- linux-2.6.29/arch/x86/boot/compressed/head_32.S 2009-03-23 19:12:14.000000000 -0400
3018 +++ linux-2.6.29/arch/x86/boot/compressed/head_32.S 2009-03-28 14:26:18.000000000 -0400
3019 @@ -70,7 +70,7 @@ startup_32:
3020 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
3021 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
3023 - movl $LOAD_PHYSICAL_ADDR, %ebx
3024 + movl $____LOAD_PHYSICAL_ADDR, %ebx
3027 /* Replace the compressed data size with the uncompressed size */
3028 @@ -80,8 +80,8 @@ startup_32:
3029 /* Add 8 bytes for every 32K input block */
3032 - /* Add 32K + 18 bytes of extra slack */
3033 - addl $(32768 + 18), %ebx
3034 + /* Add 64K of extra slack */
3036 /* Align on a 4K boundary */
3039 @@ -105,7 +105,7 @@ startup_32:
3040 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
3041 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
3043 - movl $LOAD_PHYSICAL_ADDR, %ebp
3044 + movl $____LOAD_PHYSICAL_ADDR, %ebp
3048 @@ -160,16 +160,15 @@ relocated:
3049 * and where it was actually loaded.
3052 - subl $LOAD_PHYSICAL_ADDR, %ebx
3053 + subl $____LOAD_PHYSICAL_ADDR, %ebx
3054 jz 2f /* Nothing to be done if loaded at compiled addr. */
3056 * Process relocations.
3060 - movl 0(%edi), %ecx
3065 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
3068 diff -urNp linux-2.6.29/arch/x86/boot/compressed/misc.c linux-2.6.29/arch/x86/boot/compressed/misc.c
3069 --- linux-2.6.29/arch/x86/boot/compressed/misc.c 2009-03-23 19:12:14.000000000 -0400
3070 +++ linux-2.6.29/arch/x86/boot/compressed/misc.c 2009-03-28 14:26:18.000000000 -0400
3071 @@ -373,7 +373,7 @@ static void parse_elf(void *output)
3073 #ifdef CONFIG_RELOCATABLE
3075 - dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
3076 + dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
3078 dest = (void *)(phdr->p_paddr);
3080 @@ -425,7 +425,7 @@ asmlinkage void decompress_kernel(void *
3081 if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
3082 error("Destination address too large");
3083 #ifndef CONFIG_RELOCATABLE
3084 - if ((u32)output != LOAD_PHYSICAL_ADDR)
3085 + if ((u32)output != ____LOAD_PHYSICAL_ADDR)
3086 error("Wrong destination address");
3089 diff -urNp linux-2.6.29/arch/x86/boot/compressed/relocs.c linux-2.6.29/arch/x86/boot/compressed/relocs.c
3090 --- linux-2.6.29/arch/x86/boot/compressed/relocs.c 2009-03-23 19:12:14.000000000 -0400
3091 +++ linux-2.6.29/arch/x86/boot/compressed/relocs.c 2009-03-28 14:26:18.000000000 -0400
3096 +#include "../../../../include/linux/autoconf.h"
3098 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3099 static Elf32_Ehdr ehdr;
3100 +static Elf32_Phdr *phdr;
3101 static unsigned long reloc_count, reloc_idx;
3102 static unsigned long *relocs;
3104 @@ -245,6 +248,36 @@ static void read_ehdr(FILE *fp)
3108 +static void read_phdrs(FILE *fp)
3112 + phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
3114 + die("Unable to allocate %d program headers\n",
3117 + if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3118 + die("Seek to %d failed: %s\n",
3119 + ehdr.e_phoff, strerror(errno));
3121 + if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3122 + die("Cannot read ELF program headers: %s\n",
3125 + for(i = 0; i < ehdr.e_phnum; i++) {
3126 + phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
3127 + phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
3128 + phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
3129 + phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
3130 + phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
3131 + phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
3132 + phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
3133 + phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
3138 static void read_shdrs(FILE *fp)
3141 @@ -341,6 +374,8 @@ static void read_symtabs(FILE *fp)
3142 static void read_relocs(FILE *fp)
3147 for (i = 0; i < ehdr.e_shnum; i++) {
3148 struct section *sec = &secs[i];
3149 if (sec->shdr.sh_type != SHT_REL) {
3150 @@ -360,9 +395,18 @@ static void read_relocs(FILE *fp)
3151 die("Cannot read symbol table: %s\n",
3155 + for (j = 0; j < ehdr.e_phnum; j++) {
3156 + if (phdr[j].p_type != PT_LOAD )
3158 + if (secs[sec->shdr.sh_info].shdr.sh_offset < phdr[j].p_offset || secs[sec->shdr.sh_info].shdr.sh_offset >= phdr[j].p_offset + phdr[j].p_filesz)
3160 + base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3163 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
3164 Elf32_Rel *rel = &sec->reltab[j];
3165 - rel->r_offset = elf32_to_cpu(rel->r_offset);
3166 + rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
3167 rel->r_info = elf32_to_cpu(rel->r_info);
3170 @@ -504,6 +548,23 @@ static void walk_relocs(void (*visit)(El
3171 if (sym->st_shndx == SHN_ABS) {
3174 + /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
3175 + if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
3177 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3178 + /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3179 + if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
3181 + if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
3183 + if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3184 + if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3185 + strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3188 + if (!strcmp(sec_name(sym->st_shndx), ".text"))
3191 if (r_type == R_386_PC32) {
3192 /* PC relative relocations don't need to be adjusted */
3194 @@ -631,6 +692,7 @@ int main(int argc, char **argv)
3195 fname, strerror(errno));
3202 diff -urNp linux-2.6.29/arch/x86/boot/cpucheck.c linux-2.6.29/arch/x86/boot/cpucheck.c
3203 --- linux-2.6.29/arch/x86/boot/cpucheck.c 2009-03-23 19:12:14.000000000 -0400
3204 +++ linux-2.6.29/arch/x86/boot/cpucheck.c 2009-03-28 14:26:18.000000000 -0400
3205 @@ -74,7 +74,7 @@ static int has_fpu(void)
3206 u16 fcw = -1, fsw = -1;
3209 - asm("movl %%cr0,%0" : "=r" (cr0));
3210 + asm volatile("movl %%cr0,%0" : "=r" (cr0));
3211 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3212 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3213 asm volatile("movl %0,%%cr0" : : "r" (cr0));
3214 @@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
3219 + asm volatile("pushfl ; "
3223 @@ -115,7 +115,7 @@ static void get_flags(void)
3224 set_bit(X86_FEATURE_FPU, cpu.flags);
3226 if (has_eflag(X86_EFLAGS_ID)) {
3228 + asm volatile("cpuid"
3229 : "=a" (max_intel_level),
3230 "=b" (cpu_vendor[0]),
3231 "=d" (cpu_vendor[1]),
3232 @@ -124,7 +124,7 @@ static void get_flags(void)
3234 if (max_intel_level >= 0x00000001 &&
3235 max_intel_level <= 0x0000ffff) {
3237 + asm volatile("cpuid"
3239 "=c" (cpu.flags[4]),
3241 @@ -136,7 +136,7 @@ static void get_flags(void)
3242 cpu.model += ((tfms >> 16) & 0xf) << 4;
3246 + asm volatile("cpuid"
3247 : "=a" (max_amd_level)
3249 : "ebx", "ecx", "edx");
3250 @@ -144,7 +144,7 @@ static void get_flags(void)
3251 if (max_amd_level >= 0x80000001 &&
3252 max_amd_level <= 0x8000ffff) {
3253 u32 eax = 0x80000001;
3255 + asm volatile("cpuid"
3257 "=c" (cpu.flags[6]),
3259 @@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3260 u32 ecx = MSR_K7_HWCR;
3263 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3264 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3266 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3267 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3269 get_flags(); /* Make sure it really did something */
3270 err = check_flags();
3271 @@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3272 u32 ecx = MSR_VIA_FCR;
3275 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3276 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3277 eax |= (1<<1)|(1<<7);
3278 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3279 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3281 set_bit(X86_FEATURE_CX8, cpu.flags);
3282 err = check_flags();
3283 @@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
3287 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3288 - asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3290 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3291 + asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3292 + asm volatile("cpuid"
3293 : "+a" (level), "=d" (cpu.flags[0])
3295 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3296 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3298 err = check_flags();
3300 diff -urNp linux-2.6.29/arch/x86/boot/edd.c linux-2.6.29/arch/x86/boot/edd.c
3301 --- linux-2.6.29/arch/x86/boot/edd.c 2009-03-23 19:12:14.000000000 -0400
3302 +++ linux-2.6.29/arch/x86/boot/edd.c 2009-03-28 14:26:18.000000000 -0400
3303 @@ -81,7 +81,7 @@ static int get_edd_info(u8 devno, struct
3307 - asm("pushfl; stc; int $0x13; setc %%al; popfl"
3308 + asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
3309 : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3312 @@ -100,7 +100,7 @@ static int get_edd_info(u8 devno, struct
3313 ei->params.length = sizeof(ei->params);
3316 - asm("pushfl; int $0x13; popfl"
3317 + asm volatile("pushfl; int $0x13; popfl"
3318 : "+a" (ax), "+d" (dx), "=m" (ei->params)
3320 : "ebx", "ecx", "edi");
3321 @@ -111,7 +111,7 @@ static int get_edd_info(u8 devno, struct
3325 - asm("pushw %%es; "
3326 + asm volatile("pushw %%es; "
3328 "pushfl; stc; int $0x13; setc %%al; popfl; "
3330 diff -urNp linux-2.6.29/arch/x86/boot/main.c linux-2.6.29/arch/x86/boot/main.c
3331 --- linux-2.6.29/arch/x86/boot/main.c 2009-03-23 19:12:14.000000000 -0400
3332 +++ linux-2.6.29/arch/x86/boot/main.c 2009-03-28 14:26:18.000000000 -0400
3333 @@ -78,7 +78,7 @@ static void query_ist(void)
3338 + asm volatile("int $0x15"
3339 : "=a" (boot_params.ist_info.signature),
3340 "=b" (boot_params.ist_info.command),
3341 "=c" (boot_params.ist_info.event),
3342 diff -urNp linux-2.6.29/arch/x86/boot/mca.c linux-2.6.29/arch/x86/boot/mca.c
3343 --- linux-2.6.29/arch/x86/boot/mca.c 2009-03-23 19:12:14.000000000 -0400
3344 +++ linux-2.6.29/arch/x86/boot/mca.c 2009-03-28 14:26:18.000000000 -0400
3345 @@ -19,7 +19,7 @@ int query_mca(void)
3349 - asm("pushw %%es ; "
3350 + asm volatile("pushw %%es ; "
3354 diff -urNp linux-2.6.29/arch/x86/boot/memory.c linux-2.6.29/arch/x86/boot/memory.c
3355 --- linux-2.6.29/arch/x86/boot/memory.c 2009-03-23 19:12:14.000000000 -0400
3356 +++ linux-2.6.29/arch/x86/boot/memory.c 2009-03-28 14:26:18.000000000 -0400
3357 @@ -30,7 +30,7 @@ static int detect_memory_e820(void)
3358 /* Important: %edx is clobbered by some BIOSes,
3359 so it must be either used for the error output
3360 or explicitly marked clobbered. */
3361 - asm("int $0x15; setc %0"
3362 + asm volatile("int $0x15; setc %0"
3363 : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
3365 : "D" (desc), "d" (SMAP), "a" (0xe820));
3366 @@ -65,7 +65,7 @@ static int detect_memory_e801(void)
3370 - asm("stc; int $0x15; setc %0"
3371 + asm volatile("stc; int $0x15; setc %0"
3372 : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3375 @@ -95,7 +95,7 @@ static int detect_memory_88(void)
3379 - asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3380 + asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3382 boot_params.screen_info.ext_mem_k = ax;
3384 diff -urNp linux-2.6.29/arch/x86/boot/video.c linux-2.6.29/arch/x86/boot/video.c
3385 --- linux-2.6.29/arch/x86/boot/video.c 2009-03-23 19:12:14.000000000 -0400
3386 +++ linux-2.6.29/arch/x86/boot/video.c 2009-03-28 14:26:18.000000000 -0400
3387 @@ -23,7 +23,7 @@ static void store_cursor_position(void)
3392 + asm volatile(INT10
3393 : "=d" (curpos), "+a" (ax), "+b" (bx)
3394 : : "ecx", "esi", "edi");
3396 @@ -38,7 +38,7 @@ static void store_video_mode(void)
3397 /* N.B.: the saving of the video page here is a bit silly,
3398 since we pretty much assume page 0 everywhere. */
3401 + asm volatile(INT10
3402 : "+a" (ax), "=b" (page)
3403 : : "ecx", "edx", "esi", "edi");
3405 diff -urNp linux-2.6.29/arch/x86/boot/video-vesa.c linux-2.6.29/arch/x86/boot/video-vesa.c
3406 --- linux-2.6.29/arch/x86/boot/video-vesa.c 2009-03-23 19:12:14.000000000 -0400
3407 +++ linux-2.6.29/arch/x86/boot/video-vesa.c 2009-03-28 14:26:18.000000000 -0400
3408 @@ -41,7 +41,7 @@ static int vesa_probe(void)
3411 di = (size_t)&vginfo;
3413 + asm volatile(INT10
3414 : "+a" (ax), "+D" (di), "=m" (vginfo)
3415 : : "ebx", "ecx", "edx", "esi");
3417 @@ -68,7 +68,7 @@ static int vesa_probe(void)
3420 di = (size_t)&vminfo;
3422 + asm volatile(INT10
3423 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3424 : : "ebx", "edx", "esi");
3426 @@ -120,7 +120,7 @@ static int vesa_set_mode(struct mode_inf
3429 di = (size_t)&vminfo;
3431 + asm volatile(INT10
3432 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3433 : : "ebx", "edx", "esi");
3435 @@ -202,19 +202,20 @@ static void vesa_dac_set_8bits(void)
3436 /* Save the VESA protected mode info */
3437 static void vesa_store_pm_info(void)
3439 - u16 ax, bx, di, es;
3440 + u16 ax, bx, cx, di, es;
3444 - asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3445 - : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3446 - : : "ecx", "esi");
3448 + asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3449 + : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3455 boot_params.screen_info.vesapm_seg = es;
3456 boot_params.screen_info.vesapm_off = di;
3457 + boot_params.screen_info.vesapm_size = cx;
3461 @@ -268,7 +269,7 @@ void vesa_store_edid(void)
3462 /* Note: The VBE DDC spec is different from the main VESA spec;
3463 we genuinely have to assume all registers are destroyed here. */
3465 - asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3466 + asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3467 : "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3470 @@ -283,7 +284,7 @@ void vesa_store_edid(void)
3471 cx = 0; /* Controller 0 */
3472 dx = 0; /* EDID block number */
3473 di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
3475 + asm volatile(INT10
3476 : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info),
3477 "+c" (cx), "+D" (di)
3479 diff -urNp linux-2.6.29/arch/x86/boot/video-vga.c linux-2.6.29/arch/x86/boot/video-vga.c
3480 --- linux-2.6.29/arch/x86/boot/video-vga.c 2009-03-23 19:12:14.000000000 -0400
3481 +++ linux-2.6.29/arch/x86/boot/video-vga.c 2009-03-28 14:26:18.000000000 -0400
3482 @@ -225,7 +225,7 @@ static int vga_probe(void)
3487 + asm volatile(INT10
3489 : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
3490 : "ecx", "edx", "esi", "edi");
3491 @@ -237,7 +237,7 @@ static int vga_probe(void)
3492 /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
3493 if ((u8)ega_bx != 0x10) {
3496 + asm volatile(INT10
3499 : "ebx", "ecx", "edx", "esi", "edi");
3500 diff -urNp linux-2.6.29/arch/x86/boot/voyager.c linux-2.6.29/arch/x86/boot/voyager.c
3501 --- linux-2.6.29/arch/x86/boot/voyager.c 2009-03-23 19:12:14.000000000 -0400
3502 +++ linux-2.6.29/arch/x86/boot/voyager.c 2009-03-28 14:26:18.000000000 -0400
3503 @@ -23,7 +23,7 @@ int query_voyager(void)
3505 data_ptr[0] = 0xff; /* Flag on config not found(?) */
3507 - asm("pushw %%es ; "
3508 + asm volatile("pushw %%es ; "
3512 diff -urNp linux-2.6.29/arch/x86/ia32/ia32_signal.c linux-2.6.29/arch/x86/ia32/ia32_signal.c
3513 --- linux-2.6.29/arch/x86/ia32/ia32_signal.c 2009-03-23 19:12:14.000000000 -0400
3514 +++ linux-2.6.29/arch/x86/ia32/ia32_signal.c 2009-03-28 14:26:18.000000000 -0400
3515 @@ -489,6 +489,7 @@ int ia32_setup_rt_frame(int sig, struct
3516 __NR_ia32_rt_sigreturn,
3522 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
3523 diff -urNp linux-2.6.29/arch/x86/include/asm/alternative.h linux-2.6.29/arch/x86/include/asm/alternative.h
3524 --- linux-2.6.29/arch/x86/include/asm/alternative.h 2009-03-23 19:12:14.000000000 -0400
3525 +++ linux-2.6.29/arch/x86/include/asm/alternative.h 2009-03-28 14:26:18.000000000 -0400
3526 @@ -96,7 +96,7 @@ const unsigned char *const *find_nop_tab
3527 " .byte 662b-661b\n" /* sourcelen */ \
3528 " .byte 664f-663f\n" /* replacementlen */ \
3530 - ".section .altinstr_replacement,\"ax\"\n" \
3531 + ".section .altinstr_replacement,\"a\"\n" \
3532 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
3533 ".previous" :: "i" (feature) : "memory")
3535 @@ -120,7 +120,7 @@ const unsigned char *const *find_nop_tab
3536 " .byte 662b-661b\n" /* sourcelen */ \
3537 " .byte 664f-663f\n" /* replacementlen */ \
3539 - ".section .altinstr_replacement,\"ax\"\n" \
3540 + ".section .altinstr_replacement,\"a\"\n" \
3541 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
3542 ".previous" :: "i" (feature), ##input)
3544 @@ -135,7 +135,7 @@ const unsigned char *const *find_nop_tab
3545 " .byte 662b-661b\n" /* sourcelen */ \
3546 " .byte 664f-663f\n" /* replacementlen */ \
3548 - ".section .altinstr_replacement,\"ax\"\n" \
3549 + ".section .altinstr_replacement,\"a\"\n" \
3550 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
3551 ".previous" : output : [feat] "i" (feature), ##input)
3553 diff -urNp linux-2.6.29/arch/x86/include/asm/atomic_32.h linux-2.6.29/arch/x86/include/asm/atomic_32.h
3554 --- linux-2.6.29/arch/x86/include/asm/atomic_32.h 2009-03-23 19:12:14.000000000 -0400
3555 +++ linux-2.6.29/arch/x86/include/asm/atomic_32.h 2009-03-28 14:26:18.000000000 -0400
3558 static inline void atomic_add(int i, atomic_t *v)
3560 - asm volatile(LOCK_PREFIX "addl %1,%0"
3561 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
3563 +#ifdef CONFIG_PAX_REFCOUNT
3565 + LOCK_PREFIX "subl %1,%0\n"
3567 + _ASM_EXTABLE(0b, 0b)
3570 + : "+m" (v->counter)
3575 + * atomic_add_unchecked - add integer to atomic variable
3576 + * @i: integer value to add
3577 + * @v: pointer of type atomic_t
3579 + * Atomically adds @i to @v.
3581 +static inline void atomic_add_unchecked(int i, atomic_t *v)
3583 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
3587 @@ -53,7 +75,15 @@ static inline void atomic_add(int i, ato
3589 static inline void atomic_sub(int i, atomic_t *v)
3591 - asm volatile(LOCK_PREFIX "subl %1,%0"
3592 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
3594 +#ifdef CONFIG_PAX_REFCOUNT
3596 + LOCK_PREFIX "addl %1,%0\n"
3598 + _ASM_EXTABLE(0b, 0b)
3604 @@ -71,7 +101,16 @@ static inline int atomic_sub_and_test(in
3608 - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
3609 + asm volatile(LOCK_PREFIX "subl %2,%0\n"
3611 +#ifdef CONFIG_PAX_REFCOUNT
3613 + LOCK_PREFIX "addl %2,%0\n"
3615 + _ASM_EXTABLE(0b, 0b)
3619 : "+m" (v->counter), "=qm" (c)
3620 : "ir" (i) : "memory");
3622 @@ -85,7 +124,18 @@ static inline int atomic_sub_and_test(in
3624 static inline void atomic_inc(atomic_t *v)
3626 - asm volatile(LOCK_PREFIX "incl %0"
3627 + asm volatile(LOCK_PREFIX "incl %0\n"
3629 +#ifdef CONFIG_PAX_REFCOUNT
3631 + ".pushsection .fixup,\"ax\"\n"
3633 + LOCK_PREFIX "decl %0\n"
3636 + _ASM_EXTABLE(0b, 1b)
3639 : "+m" (v->counter));
3642 @@ -97,7 +147,18 @@ static inline void atomic_inc(atomic_t *
3644 static inline void atomic_dec(atomic_t *v)
3646 - asm volatile(LOCK_PREFIX "decl %0"
3647 + asm volatile(LOCK_PREFIX "decl %0\n"
3649 +#ifdef CONFIG_PAX_REFCOUNT
3651 + ".pushsection .fixup,\"ax\"\n"
3653 + LOCK_PREFIX "incl %0\n"
3656 + _ASM_EXTABLE(0b, 1b)
3659 : "+m" (v->counter));
3662 @@ -113,7 +174,19 @@ static inline int atomic_dec_and_test(at
3666 - asm volatile(LOCK_PREFIX "decl %0; sete %1"
3667 + asm volatile(LOCK_PREFIX "decl %0\n"
3669 +#ifdef CONFIG_PAX_REFCOUNT
3671 + ".pushsection .fixup,\"ax\"\n"
3673 + LOCK_PREFIX "incl %0\n"
3676 + _ASM_EXTABLE(0b, 1b)
3680 : "+m" (v->counter), "=qm" (c)
3683 @@ -131,7 +204,19 @@ static inline int atomic_inc_and_test(at
3687 - asm volatile(LOCK_PREFIX "incl %0; sete %1"
3688 + asm volatile(LOCK_PREFIX "incl %0\n"
3690 +#ifdef CONFIG_PAX_REFCOUNT
3692 + ".pushsection .fixup,\"ax\"\n"
3694 + LOCK_PREFIX "decl %0\n"
3697 + _ASM_EXTABLE(0b, 1b)
3701 : "+m" (v->counter), "=qm" (c)
3704 @@ -150,7 +235,16 @@ static inline int atomic_add_negative(in
3708 - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
3709 + asm volatile(LOCK_PREFIX "addl %2,%0\n"
3711 +#ifdef CONFIG_PAX_REFCOUNT
3713 + LOCK_PREFIX "subl %2,%0\n"
3715 + _ASM_EXTABLE(0b, 0b)
3719 : "+m" (v->counter), "=qm" (c)
3720 : "ir" (i) : "memory");
3722 @@ -173,7 +267,15 @@ static inline int atomic_add_return(int
3724 /* Modern 486+ processor */
3726 - asm volatile(LOCK_PREFIX "xaddl %0, %1"
3727 + asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
3729 +#ifdef CONFIG_PAX_REFCOUNT
3733 + _ASM_EXTABLE(0b, 0b)
3736 : "+r" (i), "+m" (v->counter)
3739 @@ -214,17 +316,28 @@ static inline int atomic_sub_return(int
3741 static inline int atomic_add_unless(atomic_t *v, int a, int u)
3747 - if (unlikely(c == (u)))
3748 + if (unlikely(c == u))
3750 - old = atomic_cmpxchg((v), c, c + (a));
3752 + asm volatile("addl %2,%0\n"
3754 +#ifdef CONFIG_PAX_REFCOUNT
3756 + _ASM_EXTABLE(0b, 0b)
3760 + : "0" (c), "ir" (a));
3762 + old = atomic_cmpxchg(v, c, new);
3763 if (likely(old == c))
3771 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
3772 diff -urNp linux-2.6.29/arch/x86/include/asm/atomic_64.h linux-2.6.29/arch/x86/include/asm/atomic_64.h
3773 --- linux-2.6.29/arch/x86/include/asm/atomic_64.h 2009-03-23 19:12:14.000000000 -0400
3774 +++ linux-2.6.29/arch/x86/include/asm/atomic_64.h 2009-03-28 15:30:54.000000000 -0400
3777 static inline void atomic_add(int i, atomic_t *v)
3779 - asm volatile(LOCK_PREFIX "addl %1,%0"
3780 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
3782 +#ifdef CONFIG_PAX_REFCOUNT
3784 + LOCK_PREFIX "subl %1,%0\n"
3786 + _ASM_EXTABLE(0b, 0b)
3789 + : "=m" (v->counter)
3790 + : "ir" (i), "m" (v->counter));
3794 + * atomic_add_unchecked - add integer to atomic variable
3795 + * @i: integer value to add
3796 + * @v: pointer of type atomic_t
3798 + * Atomically adds @i to @v.
3800 +static inline void atomic_add_unchecked(int i, atomic_t *v)
3802 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
3804 : "ir" (i), "m" (v->counter));
3806 @@ -52,7 +74,15 @@ static inline void atomic_add(int i, ato
3808 static inline void atomic_sub(int i, atomic_t *v)
3810 - asm volatile(LOCK_PREFIX "subl %1,%0"
3811 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
3813 +#ifdef CONFIG_PAX_REFCOUNT
3815 + LOCK_PREFIX "addl %1,%0\n"
3817 + _ASM_EXTABLE(0b, 0b)
3821 : "ir" (i), "m" (v->counter));
3823 @@ -70,7 +100,16 @@ static inline int atomic_sub_and_test(in
3827 - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
3828 + asm volatile(LOCK_PREFIX "subl %2,%0\n"
3830 +#ifdef CONFIG_PAX_REFCOUNT
3832 + LOCK_PREFIX "addl %2,%0\n"
3834 + _ASM_EXTABLE(0b, 0b)
3838 : "=m" (v->counter), "=qm" (c)
3839 : "ir" (i), "m" (v->counter) : "memory");
3841 @@ -84,7 +123,19 @@ static inline int atomic_sub_and_test(in
3843 static inline void atomic_inc(atomic_t *v)
3845 - asm volatile(LOCK_PREFIX "incl %0"
3846 + asm volatile(LOCK_PREFIX "incl %0\n"
3848 +#ifdef CONFIG_PAX_REFCOUNT
3851 + ".pushsection .fixup,\"ax\"\n"
3853 + LOCK_PREFIX "decl %0\n"
3856 + _ASM_EXTABLE(0b, 1b)
3860 : "m" (v->counter));
3862 @@ -97,7 +148,19 @@ static inline void atomic_inc(atomic_t *
3864 static inline void atomic_dec(atomic_t *v)
3866 - asm volatile(LOCK_PREFIX "decl %0"
3867 + asm volatile(LOCK_PREFIX "decl %0\n"
3869 +#ifdef CONFIG_PAX_REFCOUNT
3872 + ".pushsection .fixup,\"ax\"\n"
3874 + LOCK_PREFIX "incl %0\n"
3877 + _ASM_EXTABLE(0b, 1b)
3881 : "m" (v->counter));
3883 @@ -114,7 +177,20 @@ static inline int atomic_dec_and_test(at
3887 - asm volatile(LOCK_PREFIX "decl %0; sete %1"
3888 + asm volatile(LOCK_PREFIX "decl %0\n"
3890 +#ifdef CONFIG_PAX_REFCOUNT
3893 + ".pushsection .fixup,\"ax\"\n"
3895 + LOCK_PREFIX "incl %0\n"
3898 + _ASM_EXTABLE(0b, 1b)
3902 : "=m" (v->counter), "=qm" (c)
3903 : "m" (v->counter) : "memory");
3905 @@ -132,7 +208,20 @@ static inline int atomic_inc_and_test(at
3909 - asm volatile(LOCK_PREFIX "incl %0; sete %1"
3910 + asm volatile(LOCK_PREFIX "incl %0\n"
3912 +#ifdef CONFIG_PAX_REFCOUNT
3915 + ".pushsection .fixup,\"ax\"\n"
3917 + LOCK_PREFIX "decl %0\n"
3920 + _ASM_EXTABLE(0b, 1b)
3924 : "=m" (v->counter), "=qm" (c)
3925 : "m" (v->counter) : "memory");
3927 @@ -151,7 +240,16 @@ static inline int atomic_add_negative(in
3931 - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
3932 + asm volatile(LOCK_PREFIX "addl %2,%0\n"
3934 +#ifdef CONFIG_PAX_REFCOUNT
3936 + LOCK_PREFIX "subl %2,%0\n"
3938 + _ASM_EXTABLE(0b, 0b)
3942 : "=m" (v->counter), "=qm" (c)
3943 : "ir" (i), "m" (v->counter) : "memory");
3945 @@ -167,7 +265,15 @@ static inline int atomic_add_negative(in
3946 static inline int atomic_add_return(int i, atomic_t *v)
3949 - asm volatile(LOCK_PREFIX "xaddl %0, %1"
3950 + asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
3952 +#ifdef CONFIG_PAX_REFCOUNT
3956 + _ASM_EXTABLE(0b, 0b)
3959 : "+r" (i), "+m" (v->counter)
3962 @@ -212,7 +318,15 @@ static inline int atomic_sub_return(int
3964 static inline void atomic64_add(long i, atomic64_t *v)
3966 - asm volatile(LOCK_PREFIX "addq %1,%0"
3967 + asm volatile(LOCK_PREFIX "addq %1,%0\n"
3969 +#ifdef CONFIG_PAX_REFCOUNT
3971 + LOCK_PREFIX "subq %1,%0\n"
3973 + _ASM_EXTABLE(0b, 0b)
3977 : "er" (i), "m" (v->counter));
3979 @@ -226,7 +340,15 @@ static inline void atomic64_add(long i,
3981 static inline void atomic64_sub(long i, atomic64_t *v)
3983 - asm volatile(LOCK_PREFIX "subq %1,%0"
3984 + asm volatile(LOCK_PREFIX "subq %1,%0\n"
3986 +#ifdef CONFIG_PAX_REFCOUNT
3988 + LOCK_PREFIX "addq %1,%0\n"
3990 + _ASM_EXTABLE(0b, 0b)
3994 : "er" (i), "m" (v->counter));
3996 @@ -244,7 +366,16 @@ static inline int atomic64_sub_and_test(
4000 - asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
4001 + asm volatile(LOCK_PREFIX "subq %2,%0\n"
4003 +#ifdef CONFIG_PAX_REFCOUNT
4005 + LOCK_PREFIX "addq %2,%0\n"
4007 + _ASM_EXTABLE(0b, 0b)
4011 : "=m" (v->counter), "=qm" (c)
4012 : "er" (i), "m" (v->counter) : "memory");
4014 @@ -258,7 +389,19 @@ static inline int atomic64_sub_and_test(
4016 static inline void atomic64_inc(atomic64_t *v)
4018 - asm volatile(LOCK_PREFIX "incq %0"
4019 + asm volatile(LOCK_PREFIX "incq %0\n"
4021 +#ifdef CONFIG_PAX_REFCOUNT
4024 + ".pushsection .fixup,\"ax\"\n"
4026 + LOCK_PREFIX "decq %0\n"
4029 + _ASM_EXTABLE(0b, 1b)
4033 : "m" (v->counter));
4035 @@ -271,7 +414,19 @@ static inline void atomic64_inc(atomic64
4037 static inline void atomic64_dec(atomic64_t *v)
4039 - asm volatile(LOCK_PREFIX "decq %0"
4040 + asm volatile(LOCK_PREFIX "decq %0\n"
4042 +#ifdef CONFIG_PAX_REFCOUNT
4045 + ".pushsection .fixup,\"ax\"\n"
4047 + LOCK_PREFIX "incq %0\n"
4050 + _ASM_EXTABLE(0b, 1b)
4054 : "m" (v->counter));
4056 @@ -288,7 +443,20 @@ static inline int atomic64_dec_and_test(
4060 - asm volatile(LOCK_PREFIX "decq %0; sete %1"
4061 + asm volatile(LOCK_PREFIX "decq %0\n"
4063 +#ifdef CONFIG_PAX_REFCOUNT
4066 + ".pushsection .fixup,\"ax\"\n"
4068 + LOCK_PREFIX "incq %0\n"
4071 + _ASM_EXTABLE(0b, 1b)
4075 : "=m" (v->counter), "=qm" (c)
4076 : "m" (v->counter) : "memory");
4078 @@ -306,7 +474,20 @@ static inline int atomic64_inc_and_test(
4082 - asm volatile(LOCK_PREFIX "incq %0; sete %1"
4083 + asm volatile(LOCK_PREFIX "incq %0\n"
4085 +#ifdef CONFIG_PAX_REFCOUNT
4088 + ".pushsection .fixup,\"ax\"\n"
4090 + LOCK_PREFIX "decq %0\n"
4093 + _ASM_EXTABLE(0b, 1b)
4097 : "=m" (v->counter), "=qm" (c)
4098 : "m" (v->counter) : "memory");
4100 @@ -325,7 +506,16 @@ static inline int atomic64_add_negative(
4104 - asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
4105 + asm volatile(LOCK_PREFIX "addq %2,%0\n"
4107 +#ifdef CONFIG_PAX_REFCOUNT
4109 + LOCK_PREFIX "subq %2,%0\n"
4111 + _ASM_EXTABLE(0b, 0b)
4115 : "=m" (v->counter), "=qm" (c)
4116 : "er" (i), "m" (v->counter) : "memory");
4118 @@ -341,7 +531,15 @@ static inline int atomic64_add_negative(
4119 static inline long atomic64_add_return(long i, atomic64_t *v)
4122 - asm volatile(LOCK_PREFIX "xaddq %0, %1;"
4123 + asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
4125 +#ifdef CONFIG_PAX_REFCOUNT
4129 + _ASM_EXTABLE(0b, 0b)
4132 : "+r" (i), "+m" (v->counter)
4135 @@ -372,17 +570,29 @@ static inline long atomic64_sub_return(l
4137 static inline int atomic_add_unless(atomic_t *v, int a, int u)
4143 - if (unlikely(c == (u)))
4144 + if (unlikely(c == u))
4146 - old = atomic_cmpxchg((v), c, c + (a));
4148 + asm volatile("addl %2,%0\n"
4150 +#ifdef CONFIG_PAX_REFCOUNT
4153 + _ASM_EXTABLE(0b, 0b)
4157 + : "0" (c), "ir" (a));
4159 + old = atomic_cmpxchg(v, c, new);
4160 if (likely(old == c))
4168 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
4169 @@ -398,17 +608,29 @@ static inline int atomic_add_unless(atom
4171 static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
4175 c = atomic64_read(v);
4177 - if (unlikely(c == (u)))
4178 + if (unlikely(c == u))
4180 - old = atomic64_cmpxchg((v), c, c + (a));
4182 + asm volatile("addq %2,%0\n"
4184 +#ifdef CONFIG_PAX_REFCOUNT
4187 + _ASM_EXTABLE(0b, 0b)
4191 + : "0" (c), "er" (a));
4193 + old = atomic64_cmpxchg((v), c, new);
4194 if (likely(old == c))
4203 diff -urNp linux-2.6.29/arch/x86/include/asm/boot.h linux-2.6.29/arch/x86/include/asm/boot.h
4204 --- linux-2.6.29/arch/x86/include/asm/boot.h 2009-03-23 19:12:14.000000000 -0400
4205 +++ linux-2.6.29/arch/x86/include/asm/boot.h 2009-03-28 14:26:18.000000000 -0400
4209 /* Physical address where kernel should be loaded. */
4210 -#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
4211 +#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
4212 + (CONFIG_PHYSICAL_ALIGN - 1)) \
4213 & ~(CONFIG_PHYSICAL_ALIGN - 1))
4215 +#ifndef __ASSEMBLY__
4216 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
4217 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
4220 #ifdef CONFIG_KERNEL_BZIP2
4221 #define BOOT_HEAP_SIZE 0x400000
4222 #else /* !CONFIG_KERNEL_BZIP2 */
4223 diff -urNp linux-2.6.29/arch/x86/include/asm/cache.h linux-2.6.29/arch/x86/include/asm/cache.h
4224 --- linux-2.6.29/arch/x86/include/asm/cache.h 2009-03-23 19:12:14.000000000 -0400
4225 +++ linux-2.6.29/arch/x86/include/asm/cache.h 2009-03-28 14:26:18.000000000 -0400
4227 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
4229 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
4230 +#define __read_only __attribute__((__section__(".data.read_only")))
4232 #ifdef CONFIG_X86_VSMP
4233 /* vSMP Internode cacheline shift */
4234 diff -urNp linux-2.6.29/arch/x86/include/asm/checksum_32.h linux-2.6.29/arch/x86/include/asm/checksum_32.h
4235 --- linux-2.6.29/arch/x86/include/asm/checksum_32.h 2009-03-23 19:12:14.000000000 -0400
4236 +++ linux-2.6.29/arch/x86/include/asm/checksum_32.h 2009-03-28 14:26:18.000000000 -0400
4237 @@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
4238 int len, __wsum sum,
4239 int *src_err_ptr, int *dst_err_ptr);
4241 +asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
4242 + int len, __wsum sum,
4243 + int *src_err_ptr, int *dst_err_ptr);
4245 +asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
4246 + int len, __wsum sum,
4247 + int *src_err_ptr, int *dst_err_ptr);
4250 * Note: when you get a NULL pointer exception here this means someone
4251 * passed in an incorrect kernel address to one of these functions.
4252 @@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
4256 - return csum_partial_copy_generic((__force void *)src, dst,
4257 + return csum_partial_copy_generic_from_user((__force void *)src, dst,
4258 len, sum, err_ptr, NULL);
4261 @@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
4264 if (access_ok(VERIFY_WRITE, dst, len))
4265 - return csum_partial_copy_generic(src, (__force void *)dst,
4266 + return csum_partial_copy_generic_to_user(src, (__force void *)dst,
4267 len, sum, NULL, err_ptr);
4270 diff -urNp linux-2.6.29/arch/x86/include/asm/desc.h linux-2.6.29/arch/x86/include/asm/desc.h
4271 --- linux-2.6.29/arch/x86/include/asm/desc.h 2009-03-23 19:12:14.000000000 -0400
4272 +++ linux-2.6.29/arch/x86/include/asm/desc.h 2009-03-28 14:26:18.000000000 -0400
4273 @@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
4274 desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
4275 desc->type = (info->read_exec_only ^ 1) << 1;
4276 desc->type |= info->contents << 2;
4277 + desc->type |= info->seg_not_present ^ 1;
4280 desc->p = info->seg_not_present ^ 1;
4281 @@ -32,16 +33,12 @@ static inline void fill_ldt(struct desc_
4284 extern struct desc_ptr idt_descr;
4285 -extern gate_desc idt_table[];
4288 - struct desc_struct gdt[GDT_ENTRIES];
4289 -} __attribute__((aligned(PAGE_SIZE)));
4290 -DECLARE_PER_CPU(struct gdt_page, gdt_page);
4291 +extern gate_desc idt_table[256];
4293 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
4294 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
4296 - return per_cpu(gdt_page, cpu).gdt;
4297 + return cpu_gdt_table[cpu];
4300 #ifdef CONFIG_X86_64
4301 @@ -115,19 +112,48 @@ static inline void paravirt_free_ldt(str
4302 static inline void native_write_idt_entry(gate_desc *idt, int entry,
4303 const gate_desc *gate)
4306 +#ifdef CONFIG_PAX_KERNEXEC
4307 + unsigned long cr0;
4309 + pax_open_kernel(cr0);
4312 memcpy(&idt[entry], gate, sizeof(*gate));
4314 +#ifdef CONFIG_PAX_KERNEXEC
4315 + pax_close_kernel(cr0);
4320 static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
4324 +#ifdef CONFIG_PAX_KERNEXEC
4325 + unsigned long cr0;
4327 + pax_open_kernel(cr0);
4330 memcpy(&ldt[entry], desc, 8);
4332 +#ifdef CONFIG_PAX_KERNEXEC
4333 + pax_close_kernel(cr0);
4338 static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
4339 const void *desc, int type)
4343 +#ifdef CONFIG_PAX_KERNEXEC
4344 + unsigned long cr0;
4349 size = sizeof(tss_desc);
4350 @@ -139,7 +165,17 @@ static inline void native_write_gdt_entr
4351 size = sizeof(struct desc_struct);
4355 +#ifdef CONFIG_PAX_KERNEXEC
4356 + pax_open_kernel(cr0);
4359 memcpy(&gdt[entry], desc, size);
4361 +#ifdef CONFIG_PAX_KERNEXEC
4362 + pax_close_kernel(cr0);
4367 static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
4368 @@ -211,7 +247,19 @@ static inline void native_set_ldt(const
4370 static inline void native_load_tr_desc(void)
4373 +#ifdef CONFIG_PAX_KERNEXEC
4374 + unsigned long cr0;
4376 + pax_open_kernel(cr0);
4379 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
4381 +#ifdef CONFIG_PAX_KERNEXEC
4382 + pax_close_kernel(cr0);
4387 static inline void native_load_gdt(const struct desc_ptr *dtr)
4388 @@ -246,8 +294,19 @@ static inline void native_load_tls(struc
4390 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
4392 +#ifdef CONFIG_PAX_KERNEXEC
4393 + unsigned long cr0;
4395 + pax_open_kernel(cr0);
4398 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
4399 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
4401 +#ifdef CONFIG_PAX_KERNEXEC
4402 + pax_close_kernel(cr0);
4407 #define _LDT_empty(info) \
4408 @@ -379,6 +438,18 @@ static inline void set_system_intr_gate_
4409 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
4412 +#ifdef CONFIG_X86_32
4413 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
4415 + struct desc_struct d;
4417 + if (likely(limit))
4418 + limit = (limit - 1UL) >> PAGE_SHIFT;
4419 + pack_descriptor(&d, base, limit, 0xFB, 0xC);
4420 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
4426 * GET_DESC_BASE reads the descriptor base of the specified segment.
4427 diff -urNp linux-2.6.29/arch/x86/include/asm/e820.h linux-2.6.29/arch/x86/include/asm/e820.h
4428 --- linux-2.6.29/arch/x86/include/asm/e820.h 2009-03-23 19:12:14.000000000 -0400
4429 +++ linux-2.6.29/arch/x86/include/asm/e820.h 2009-03-28 14:26:18.000000000 -0400
4430 @@ -135,7 +135,7 @@ extern char *memory_setup(void);
4431 #define ISA_END_ADDRESS 0x100000
4432 #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
4434 -#define BIOS_BEGIN 0x000a0000
4435 +#define BIOS_BEGIN 0x000c0000
4436 #define BIOS_END 0x00100000
4439 diff -urNp linux-2.6.29/arch/x86/include/asm/elf.h linux-2.6.29/arch/x86/include/asm/elf.h
4440 --- linux-2.6.29/arch/x86/include/asm/elf.h 2009-03-23 19:12:14.000000000 -0400
4441 +++ linux-2.6.29/arch/x86/include/asm/elf.h 2009-03-28 14:26:18.000000000 -0400
4442 @@ -252,7 +252,25 @@ extern int force_personality32;
4443 the loader. We need to make sure that it is out of the way of the program
4444 that it will "exec", and that there is sufficient room for the brk. */
4446 +#ifdef CONFIG_PAX_SEGMEXEC
4447 +#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
4449 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
4452 +#ifdef CONFIG_PAX_ASLR
4453 +#ifdef CONFIG_X86_32
4454 +#define PAX_ELF_ET_DYN_BASE 0x10000000UL
4456 +#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
4457 +#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
4459 +#define PAX_ELF_ET_DYN_BASE 0x400000UL
4461 +#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
4462 +#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
4466 /* This yields a mask that user programs can use to figure out what
4467 instruction set this CPU supports. This could be done in user space,
4468 @@ -304,8 +322,7 @@ do { \
4469 #define ARCH_DLINFO \
4472 - NEW_AUX_ENT(AT_SYSINFO_EHDR, \
4473 - (unsigned long)current->mm->context.vdso); \
4474 + NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
4477 #define AT_SYSINFO 32
4478 @@ -316,7 +333,7 @@ do { \
4480 #endif /* !CONFIG_X86_32 */
4482 -#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
4483 +#define VDSO_CURRENT_BASE (current->mm->context.vdso)
4485 #define VDSO_ENTRY \
4486 ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
4487 @@ -330,7 +347,4 @@ extern int arch_setup_additional_pages(s
4488 extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
4489 #define compat_arch_setup_additional_pages syscall32_setup_pages
4491 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
4492 -#define arch_randomize_brk arch_randomize_brk
4494 #endif /* _ASM_X86_ELF_H */
4495 diff -urNp linux-2.6.29/arch/x86/include/asm/futex.h linux-2.6.29/arch/x86/include/asm/futex.h
4496 --- linux-2.6.29/arch/x86/include/asm/futex.h 2009-03-23 19:12:14.000000000 -0400
4497 +++ linux-2.6.29/arch/x86/include/asm/futex.h 2009-03-28 14:26:18.000000000 -0400
4499 #include <asm/processor.h>
4500 #include <asm/system.h>
4502 +#ifdef CONFIG_X86_32
4503 +#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
4505 + "movw\t%w6, %%ds\n" \
4506 + "1:\t" insn "\n" \
4507 + "2:\tpushl\t%%ss\n" \
4508 + "\tpopl\t%%ds\n" \
4509 + "\t.section .fixup,\"ax\"\n" \
4510 + "3:\tmov\t%3, %1\n" \
4513 + _ASM_EXTABLE(1b, 3b) \
4514 + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
4515 + : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
4517 +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
4518 + asm volatile("movw\t%w7, %%es\n" \
4519 + "1:\tmovl\t%%es:%2, %0\n" \
4520 + "\tmovl\t%0, %3\n" \
4522 + "2:\t" LOCK_PREFIX "cmpxchgl %3, %%es:%2\n"\
4524 + "3:\tpushl\t%%ss\n" \
4525 + "\tpopl\t%%es\n" \
4526 + "\t.section .fixup,\"ax\"\n" \
4527 + "4:\tmov\t%5, %1\n" \
4530 + _ASM_EXTABLE(1b, 4b) \
4531 + _ASM_EXTABLE(2b, 4b) \
4532 + : "=&a" (oldval), "=&r" (ret), \
4533 + "+m" (*uaddr), "=&r" (tem) \
4534 + : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
4536 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
4537 asm volatile("1:\t" insn "\n" \
4538 "2:\t.section .fixup,\"ax\"\n" \
4540 : "=&a" (oldval), "=&r" (ret), \
4541 "+m" (*uaddr), "=&r" (tem) \
4542 : "r" (oparg), "i" (-EFAULT), "1" (0))
4545 -static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
4546 +static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
4548 int op = (encoded_op >> 28) & 7;
4549 int cmp = (encoded_op >> 24) & 15;
4550 @@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
4554 +#ifdef CONFIG_X86_32
4555 + __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
4557 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
4561 +#ifdef CONFIG_X86_32
4562 + __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret, oldval,
4565 __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
4570 __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
4571 @@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
4575 -static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
4576 +static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
4580 @@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
4581 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
4584 - asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
4586 +#ifdef CONFIG_X86_32
4587 + "\tmovw %w5, %%ds\n"
4588 + "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
4589 + "2:\tpushl %%ss\n"
4591 + "\t.section .fixup, \"ax\"\n"
4593 + "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
4594 "2:\t.section .fixup, \"ax\"\n"
4599 _ASM_EXTABLE(1b, 3b)
4600 : "=a" (oldval), "+m" (*uaddr)
4601 +#ifdef CONFIG_X86_32
4602 + : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
4604 : "i" (-EFAULT), "r" (newval), "0" (oldval)
4609 diff -urNp linux-2.6.29/arch/x86/include/asm/i387.h linux-2.6.29/arch/x86/include/asm/i387.h
4610 --- linux-2.6.29/arch/x86/include/asm/i387.h 2009-03-23 19:12:14.000000000 -0400
4611 +++ linux-2.6.29/arch/x86/include/asm/i387.h 2009-03-28 14:26:18.000000000 -0400
4612 @@ -203,13 +203,8 @@ static inline void restore_fpu(struct ta
4615 /* We need a safe address that is cheap to find and that is already
4616 - in L1 during context switch. The best choices are unfortunately
4617 - different for UP and SMP */
4619 -#define safe_address (__per_cpu_offset[0])
4621 -#define safe_address (kstat_cpu(0).cpustat.user)
4623 + in L1 during context switch. */
4624 +#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
4627 * These must be called with preempt disabled
4628 diff -urNp linux-2.6.29/arch/x86/include/asm/io_64.h linux-2.6.29/arch/x86/include/asm/io_64.h
4629 --- linux-2.6.29/arch/x86/include/asm/io_64.h 2009-03-23 19:12:14.000000000 -0400
4630 +++ linux-2.6.29/arch/x86/include/asm/io_64.h 2009-03-28 14:26:18.000000000 -0400
4631 @@ -158,6 +158,17 @@ static inline void *phys_to_virt(unsigne
4635 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
4636 +static inline int valid_phys_addr_range (unsigned long addr, size_t count)
4638 + return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
4641 +static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
4643 + return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
4647 * Change "struct page" to physical address.
4649 diff -urNp linux-2.6.29/arch/x86/include/asm/irqflags.h linux-2.6.29/arch/x86/include/asm/irqflags.h
4650 --- linux-2.6.29/arch/x86/include/asm/irqflags.h 2009-03-23 19:12:14.000000000 -0400
4651 +++ linux-2.6.29/arch/x86/include/asm/irqflags.h 2009-03-28 14:26:18.000000000 -0400
4652 @@ -141,6 +141,8 @@ static inline unsigned long __raw_local_
4653 #define INTERRUPT_RETURN iret
4654 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
4655 #define GET_CR0_INTO_EAX movl %cr0, %eax
4656 +#define GET_CR0_INTO_EDX movl %cr0, %edx
4657 +#define SET_CR0_FROM_EDX movl %edx, %cr0
4661 diff -urNp linux-2.6.29/arch/x86/include/asm/kmap_types.h linux-2.6.29/arch/x86/include/asm/kmap_types.h
4662 --- linux-2.6.29/arch/x86/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
4663 +++ linux-2.6.29/arch/x86/include/asm/kmap_types.h 2009-03-28 14:26:18.000000000 -0400
4664 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
4669 +D(13) KM_CLEARPAGE,
4674 diff -urNp linux-2.6.29/arch/x86/include/asm/kvm_host.h linux-2.6.29/arch/x86/include/asm/kvm_host.h
4675 --- linux-2.6.29/arch/x86/include/asm/kvm_host.h 2009-03-23 19:12:14.000000000 -0400
4676 +++ linux-2.6.29/arch/x86/include/asm/kvm_host.h 2009-03-28 14:26:18.000000000 -0400
4677 @@ -494,7 +494,7 @@ struct kvm_x86_ops {
4678 int (*get_mt_mask_shift)(void);
4681 -extern struct kvm_x86_ops *kvm_x86_ops;
4682 +extern const struct kvm_x86_ops *kvm_x86_ops;
4684 int kvm_mmu_module_init(void);
4685 void kvm_mmu_module_exit(void);
4686 diff -urNp linux-2.6.29/arch/x86/include/asm/linkage.h linux-2.6.29/arch/x86/include/asm/linkage.h
4687 --- linux-2.6.29/arch/x86/include/asm/linkage.h 2009-03-23 19:12:14.000000000 -0400
4688 +++ linux-2.6.29/arch/x86/include/asm/linkage.h 2009-03-28 14:26:18.000000000 -0400
4690 #ifdef CONFIG_X86_64
4691 #define __ALIGN .p2align 4,,15
4692 #define __ALIGN_STR ".p2align 4,,15"
4694 +#ifdef CONFIG_X86_ALIGNMENT_16
4695 +#define __ALIGN .align 16,0x90
4696 +#define __ALIGN_STR ".align 16,0x90"
4700 #ifdef CONFIG_X86_32
4705 -#ifdef CONFIG_X86_ALIGNMENT_16
4706 -#define __ALIGN .align 16,0x90
4707 -#define __ALIGN_STR ".align 16,0x90"
4711 * to check ENTRY_X86/END_X86 and
4712 * KPROBE_ENTRY_X86/KPROBE_END_X86
4713 diff -urNp linux-2.6.29/arch/x86/include/asm/local.h linux-2.6.29/arch/x86/include/asm/local.h
4714 --- linux-2.6.29/arch/x86/include/asm/local.h 2009-03-23 19:12:14.000000000 -0400
4715 +++ linux-2.6.29/arch/x86/include/asm/local.h 2009-03-28 14:26:19.000000000 -0400
4716 @@ -18,26 +18,90 @@ typedef struct {
4718 static inline void local_inc(local_t *l)
4720 - asm volatile(_ASM_INC "%0"
4721 + asm volatile(_ASM_INC "%0\n"
4723 +#ifdef CONFIG_PAX_REFCOUNT
4724 +#ifdef CONFIG_X86_32
4730 + ".pushsection .fixup,\"ax\"\n"
4735 + _ASM_EXTABLE(0b, 1b)
4738 : "+m" (l->a.counter));
4741 static inline void local_dec(local_t *l)
4743 - asm volatile(_ASM_DEC "%0"
4744 + asm volatile(_ASM_DEC "%0\n"
4746 +#ifdef CONFIG_PAX_REFCOUNT
4747 +#ifdef CONFIG_X86_32
4753 + ".pushsection .fixup,\"ax\"\n"
4758 + _ASM_EXTABLE(0b, 1b)
4761 : "+m" (l->a.counter));
4764 static inline void local_add(long i, local_t *l)
4766 - asm volatile(_ASM_ADD "%1,%0"
4767 + asm volatile(_ASM_ADD "%1,%0\n"
4769 +#ifdef CONFIG_PAX_REFCOUNT
4770 +#ifdef CONFIG_X86_32
4776 + ".pushsection .fixup,\"ax\"\n"
4778 + _ASM_SUB "%1,%0\n"
4781 + _ASM_EXTABLE(0b, 1b)
4784 : "+m" (l->a.counter)
4788 static inline void local_sub(long i, local_t *l)
4790 - asm volatile(_ASM_SUB "%1,%0"
4791 + asm volatile(_ASM_SUB "%1,%0\n"
4793 +#ifdef CONFIG_PAX_REFCOUNT
4794 +#ifdef CONFIG_X86_32
4800 + ".pushsection .fixup,\"ax\"\n"
4802 + _ASM_ADD "%1,%0\n"
4805 + _ASM_EXTABLE(0b, 1b)
4808 : "+m" (l->a.counter)
4811 @@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
4815 - asm volatile(_ASM_SUB "%2,%0; sete %1"
4816 + asm volatile(_ASM_SUB "%2,%0\n"
4818 +#ifdef CONFIG_PAX_REFCOUNT
4819 +#ifdef CONFIG_X86_32
4825 + ".pushsection .fixup,\"ax\"\n"
4827 + _ASM_ADD "%2,%0\n"
4830 + _ASM_EXTABLE(0b, 1b)
4834 : "+m" (l->a.counter), "=qm" (c)
4835 : "ir" (i) : "memory");
4837 @@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
4841 - asm volatile(_ASM_DEC "%0; sete %1"
4842 + asm volatile(_ASM_DEC "%0\n"
4844 +#ifdef CONFIG_PAX_REFCOUNT
4845 +#ifdef CONFIG_X86_32
4851 + ".pushsection .fixup,\"ax\"\n"
4856 + _ASM_EXTABLE(0b, 1b)
4860 : "+m" (l->a.counter), "=qm" (c)
4863 @@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
4867 - asm volatile(_ASM_INC "%0; sete %1"
4868 + asm volatile(_ASM_INC "%0\n"
4870 +#ifdef CONFIG_PAX_REFCOUNT
4871 +#ifdef CONFIG_X86_32
4877 + ".pushsection .fixup,\"ax\"\n"
4882 + _ASM_EXTABLE(0b, 1b)
4886 : "+m" (l->a.counter), "=qm" (c)
4889 @@ -110,7 +225,24 @@ static inline int local_add_negative(lon
4893 - asm volatile(_ASM_ADD "%2,%0; sets %1"
4894 + asm volatile(_ASM_ADD "%2,%0\n"
4896 +#ifdef CONFIG_PAX_REFCOUNT
4897 +#ifdef CONFIG_X86_32
4903 + ".pushsection .fixup,\"ax\"\n"
4905 + _ASM_SUB "%2,%0\n"
4908 + _ASM_EXTABLE(0b, 1b)
4912 : "+m" (l->a.counter), "=qm" (c)
4913 : "ir" (i) : "memory");
4915 @@ -133,7 +265,23 @@ static inline long local_add_return(long
4917 /* Modern 486+ processor */
4919 - asm volatile(_ASM_XADD "%0, %1;"
4920 + asm volatile(_ASM_XADD "%0, %1\n"
4922 +#ifdef CONFIG_PAX_REFCOUNT
4923 +#ifdef CONFIG_X86_32
4929 + ".pushsection .fixup,\"ax\"\n"
4931 + _ASM_MOV "%0,%1\n"
4934 + _ASM_EXTABLE(0b, 1b)
4937 : "+r" (i), "+m" (l->a.counter)
4940 diff -urNp linux-2.6.29/arch/x86/include/asm/mach-default/apm.h linux-2.6.29/arch/x86/include/asm/mach-default/apm.h
4941 --- linux-2.6.29/arch/x86/include/asm/mach-default/apm.h 2009-03-23 19:12:14.000000000 -0400
4942 +++ linux-2.6.29/arch/x86/include/asm/mach-default/apm.h 2009-03-28 14:26:19.000000000 -0400
4943 @@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
4944 __asm__ __volatile__(APM_DO_ZERO_SEGS
4947 - "lcall *%%cs:apm_bios_entry\n\t"
4948 + "lcall *%%ss:apm_bios_entry\n\t"
4952 @@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
4953 __asm__ __volatile__(APM_DO_ZERO_SEGS
4956 - "lcall *%%cs:apm_bios_entry\n\t"
4957 + "lcall *%%ss:apm_bios_entry\n\t"
4961 diff -urNp linux-2.6.29/arch/x86/include/asm/mman.h linux-2.6.29/arch/x86/include/asm/mman.h
4962 --- linux-2.6.29/arch/x86/include/asm/mman.h 2009-03-23 19:12:14.000000000 -0400
4963 +++ linux-2.6.29/arch/x86/include/asm/mman.h 2009-03-28 14:26:19.000000000 -0400
4965 #define MCL_CURRENT 1 /* lock all current mappings */
4966 #define MCL_FUTURE 2 /* lock all future mappings */
4969 +#ifndef __ASSEMBLY__
4970 +#ifdef CONFIG_X86_32
4971 +#define arch_mmap_check i386_mmap_check
4972 +int i386_mmap_check(unsigned long addr, unsigned long len,
4973 + unsigned long flags);
4978 #endif /* _ASM_X86_MMAN_H */
4979 diff -urNp linux-2.6.29/arch/x86/include/asm/mmu_context_32.h linux-2.6.29/arch/x86/include/asm/mmu_context_32.h
4980 --- linux-2.6.29/arch/x86/include/asm/mmu_context_32.h 2009-03-23 19:12:14.000000000 -0400
4981 +++ linux-2.6.29/arch/x86/include/asm/mmu_context_32.h 2009-03-28 14:26:19.000000000 -0400
4982 @@ -32,6 +32,22 @@ static inline void switch_mm(struct mm_s
4984 if (unlikely(prev->context.ldt != next->context.ldt))
4985 load_LDT_nolock(&next->context);
4987 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
4988 + if (!nx_enabled) {
4989 + smp_mb__before_clear_bit();
4990 + cpu_clear(cpu, prev->context.cpu_user_cs_mask);
4991 + smp_mb__after_clear_bit();
4992 + cpu_set(cpu, next->context.cpu_user_cs_mask);
4996 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4997 + if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
4998 + prev->context.user_cs_limit != next->context.user_cs_limit))
4999 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
5005 @@ -44,6 +60,19 @@ static inline void switch_mm(struct mm_s
5007 load_cr3(next->pgd);
5008 load_LDT_nolock(&next->context);
5010 +#ifdef CONFIG_PAX_PAGEEXEC
5012 + cpu_set(cpu, next->context.cpu_user_cs_mask);
5015 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5016 +#ifdef CONFIG_PAX_PAGEEXEC
5017 + if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
5019 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
5025 diff -urNp linux-2.6.29/arch/x86/include/asm/mmu.h linux-2.6.29/arch/x86/include/asm/mmu.h
5026 --- linux-2.6.29/arch/x86/include/asm/mmu.h 2009-03-23 19:12:14.000000000 -0400
5027 +++ linux-2.6.29/arch/x86/include/asm/mmu.h 2009-03-28 14:26:19.000000000 -0400
5029 * we put the segment information here.
5033 + struct desc_struct *ldt;
5037 + unsigned long vdso;
5039 +#ifdef CONFIG_X86_32
5040 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5041 + unsigned long user_cs_base;
5042 + unsigned long user_cs_limit;
5044 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5045 + cpumask_t cpu_user_cs_mask;
5054 diff -urNp linux-2.6.29/arch/x86/include/asm/module.h linux-2.6.29/arch/x86/include/asm/module.h
5055 --- linux-2.6.29/arch/x86/include/asm/module.h 2009-03-23 19:12:14.000000000 -0400
5056 +++ linux-2.6.29/arch/x86/include/asm/module.h 2009-03-28 14:26:19.000000000 -0400
5057 @@ -74,7 +74,12 @@ struct mod_arch_specific {};
5059 # define MODULE_STACKSIZE ""
5061 -# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
5062 +# ifdef CONFIG_GRKERNSEC
5063 +# define MODULE_GRSEC "GRSECURITY "
5065 +# define MODULE_GRSEC ""
5067 +# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
5070 #endif /* _ASM_X86_MODULE_H */
5071 diff -urNp linux-2.6.29/arch/x86/include/asm/page_32.h linux-2.6.29/arch/x86/include/asm/page_32.h
5072 --- linux-2.6.29/arch/x86/include/asm/page_32.h 2009-03-23 19:12:14.000000000 -0400
5073 +++ linux-2.6.29/arch/x86/include/asm/page_32.h 2009-03-28 14:26:19.000000000 -0400
5076 #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
5078 +#ifdef CONFIG_PAX_KERNEXEC
5079 +#ifndef __ASSEMBLY__
5080 +extern unsigned char MODULES_VADDR[];
5081 +extern unsigned char MODULES_END[];
5082 +extern unsigned char KERNEL_TEXT_OFFSET[];
5083 +#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
5084 +#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
5087 +#define ktla_ktva(addr) (addr)
5088 +#define ktva_ktla(addr) (addr)
5091 +#ifdef CONFIG_PAX_PAGEEXEC
5092 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
5095 #ifdef CONFIG_4KSTACKS
5096 #define THREAD_ORDER 0
5098 diff -urNp linux-2.6.29/arch/x86/include/asm/page_64.h linux-2.6.29/arch/x86/include/asm/page_64.h
5099 --- linux-2.6.29/arch/x86/include/asm/page_64.h 2009-03-23 19:12:14.000000000 -0400
5100 +++ linux-2.6.29/arch/x86/include/asm/page_64.h 2009-03-28 14:26:19.000000000 -0400
5102 #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
5103 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
5105 +#define ktla_ktva(addr) (addr)
5106 +#define ktva_ktla(addr) (addr)
5108 /* See Documentation/x86_64/mm.txt for a description of the memory map. */
5109 #define __PHYSICAL_MASK_SHIFT 46
5110 #define __VIRTUAL_MASK_SHIFT 48
5111 @@ -101,5 +104,6 @@ extern void init_extra_mapping_wb(unsign
5112 #define pfn_valid(pfn) ((pfn) < max_pfn)
5115 +#define nx_enabled (1)
5117 #endif /* _ASM_X86_PAGE_64_H */
5118 diff -urNp linux-2.6.29/arch/x86/include/asm/paravirt.h linux-2.6.29/arch/x86/include/asm/paravirt.h
5119 --- linux-2.6.29/arch/x86/include/asm/paravirt.h 2009-03-23 19:12:14.000000000 -0400
5120 +++ linux-2.6.29/arch/x86/include/asm/paravirt.h 2009-03-28 14:26:19.000000000 -0400
5121 @@ -1558,7 +1558,7 @@ static inline unsigned long __raw_local_
5122 #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax
5123 #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
5124 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
5125 -#define PARA_INDIRECT(addr) *%cs:addr
5126 +#define PARA_INDIRECT(addr) *%ss:addr
5129 #define INTERRUPT_RETURN \
5130 diff -urNp linux-2.6.29/arch/x86/include/asm/pda.h linux-2.6.29/arch/x86/include/asm/pda.h
5131 --- linux-2.6.29/arch/x86/include/asm/pda.h 2009-03-23 19:12:14.000000000 -0400
5132 +++ linux-2.6.29/arch/x86/include/asm/pda.h 2009-03-28 14:26:19.000000000 -0400
5133 @@ -16,11 +16,9 @@ struct x8664_pda {
5134 unsigned long oldrsp; /* 24 user rsp for system call */
5135 int irqcount; /* 32 Irq nesting counter. Starts -1 */
5136 unsigned int cpunumber; /* 36 Logical CPU number */
5137 -#ifdef CONFIG_CC_STACKPROTECTOR
5138 unsigned long stack_canary; /* 40 stack canary value */
5139 /* gcc-ABI: this canary MUST be at
5143 short nodenumber; /* number of current node (32k max) */
5144 short in_bootmem; /* pda lives in bootmem */
5145 diff -urNp linux-2.6.29/arch/x86/include/asm/percpu.h linux-2.6.29/arch/x86/include/asm/percpu.h
5146 --- linux-2.6.29/arch/x86/include/asm/percpu.h 2009-03-23 19:12:14.000000000 -0400
5147 +++ linux-2.6.29/arch/x86/include/asm/percpu.h 2009-03-28 14:26:19.000000000 -0400
5148 @@ -93,6 +93,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
5150 #define __my_cpu_offset x86_read_percpu(this_cpu_off)
5152 +#include <asm-generic/sections.h>
5153 +#include <linux/threads.h>
5154 +#define __per_cpu_offset __per_cpu_offset
5155 +extern unsigned long __per_cpu_offset[NR_CPUS];
5156 +#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
5158 /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
5159 #define __percpu_seg "%%fs:"
5161 diff -urNp linux-2.6.29/arch/x86/include/asm/pgalloc.h linux-2.6.29/arch/x86/include/asm/pgalloc.h
5162 --- linux-2.6.29/arch/x86/include/asm/pgalloc.h 2009-03-23 19:12:14.000000000 -0400
5163 +++ linux-2.6.29/arch/x86/include/asm/pgalloc.h 2009-03-28 14:26:19.000000000 -0400
5164 @@ -52,7 +52,7 @@ static inline void pmd_populate_kernel(s
5165 pmd_t *pmd, pte_t *pte)
5167 paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
5168 - set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
5169 + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
5172 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
5173 diff -urNp linux-2.6.29/arch/x86/include/asm/pgtable-2level.h linux-2.6.29/arch/x86/include/asm/pgtable-2level.h
5174 --- linux-2.6.29/arch/x86/include/asm/pgtable-2level.h 2009-03-23 19:12:14.000000000 -0400
5175 +++ linux-2.6.29/arch/x86/include/asm/pgtable-2level.h 2009-03-28 14:26:19.000000000 -0400
5176 @@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
5178 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
5181 +#ifdef CONFIG_PAX_KERNEXEC
5182 + unsigned long cr0;
5184 + pax_open_kernel(cr0);
5189 +#ifdef CONFIG_PAX_KERNEXEC
5190 + pax_close_kernel(cr0);
5195 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
5196 diff -urNp linux-2.6.29/arch/x86/include/asm/pgtable_32.h linux-2.6.29/arch/x86/include/asm/pgtable_32.h
5197 --- linux-2.6.29/arch/x86/include/asm/pgtable_32.h 2009-03-23 19:12:14.000000000 -0400
5198 +++ linux-2.6.29/arch/x86/include/asm/pgtable_32.h 2009-03-28 14:26:19.000000000 -0400
5201 struct vm_area_struct;
5203 -extern pgd_t swapper_pg_dir[1024];
5205 static inline void pgtable_cache_init(void) { }
5206 static inline void check_pgt_cache(void) { }
5207 void paging_init(void);
5208 @@ -46,6 +44,11 @@ extern void set_pmd_pfn(unsigned long, u
5209 # include <asm/pgtable-2level-defs.h>
5212 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
5213 +#ifdef CONFIG_X86_PAE
5214 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
5217 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
5218 #define PGDIR_MASK (~(PGDIR_SIZE - 1))
5220 @@ -83,7 +86,7 @@ extern void set_pmd_pfn(unsigned long, u
5221 #undef TEST_ACCESS_OK
5223 /* The boot page tables (all created as a single array) */
5224 -extern unsigned long pg0[];
5225 +extern pte_t pg0[];
5227 #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
5229 @@ -166,6 +169,9 @@ do { \
5231 #endif /* !__ASSEMBLY__ */
5233 +#define HAVE_ARCH_UNMAPPED_AREA
5234 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
5237 * kern_addr_valid() is (1) for FLATMEM and (0) for
5238 * SPARSEMEM and DISCONTIGMEM
5239 diff -urNp linux-2.6.29/arch/x86/include/asm/pgtable-3level.h linux-2.6.29/arch/x86/include/asm/pgtable-3level.h
5240 --- linux-2.6.29/arch/x86/include/asm/pgtable-3level.h 2009-03-23 19:12:14.000000000 -0400
5241 +++ linux-2.6.29/arch/x86/include/asm/pgtable-3level.h 2009-03-28 14:26:19.000000000 -0400
5242 @@ -70,12 +70,36 @@ static inline void native_set_pte_atomic
5244 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
5247 +#ifdef CONFIG_PAX_KERNEXEC
5248 + unsigned long cr0;
5250 + pax_open_kernel(cr0);
5253 set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
5255 +#ifdef CONFIG_PAX_KERNEXEC
5256 + pax_close_kernel(cr0);
5261 static inline void native_set_pud(pud_t *pudp, pud_t pud)
5264 +#ifdef CONFIG_PAX_KERNEXEC
5265 + unsigned long cr0;
5267 + pax_open_kernel(cr0);
5270 set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
5272 +#ifdef CONFIG_PAX_KERNEXEC
5273 + pax_close_kernel(cr0);
5279 diff -urNp linux-2.6.29/arch/x86/include/asm/pgtable_64.h linux-2.6.29/arch/x86/include/asm/pgtable_64.h
5280 --- linux-2.6.29/arch/x86/include/asm/pgtable_64.h 2009-03-23 19:12:14.000000000 -0400
5281 +++ linux-2.6.29/arch/x86/include/asm/pgtable_64.h 2009-03-28 14:26:19.000000000 -0400
5284 extern pud_t level3_kernel_pgt[512];
5285 extern pud_t level3_ident_pgt[512];
5286 +extern pud_t level3_vmalloc_pgt[512];
5287 +extern pud_t level3_vmemmap_pgt[512];
5288 extern pmd_t level2_kernel_pgt[512];
5289 extern pmd_t level2_fixmap_pgt[512];
5290 -extern pmd_t level2_ident_pgt[512];
5291 +extern pmd_t level2_ident_pgt[512*4];
5292 +extern pte_t level1_fixmap_pgt[512];
5293 extern pgd_t init_level4_pgt[];
5295 #define swapper_pg_dir init_level4_pgt
5296 @@ -106,7 +109,19 @@ static inline pte_t native_ptep_get_and_
5298 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
5301 +#ifdef CONFIG_PAX_KERNEXEC
5302 + unsigned long cr0;
5304 + pax_open_kernel(cr0);
5309 +#ifdef CONFIG_PAX_KERNEXEC
5310 + pax_close_kernel(cr0);
5315 static inline void native_pmd_clear(pmd_t *pmd)
5316 @@ -158,17 +173,17 @@ static inline void native_pgd_clear(pgd_
5318 static inline int pgd_bad(pgd_t pgd)
5320 - return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
5321 + return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
5324 static inline int pud_bad(pud_t pud)
5326 - return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
5327 + return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
5330 static inline int pmd_bad(pmd_t pmd)
5332 - return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
5333 + return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
5336 #define pte_none(x) (!pte_val((x)))
5337 diff -urNp linux-2.6.29/arch/x86/include/asm/pgtable.h linux-2.6.29/arch/x86/include/asm/pgtable.h
5338 --- linux-2.6.29/arch/x86/include/asm/pgtable.h 2009-03-23 19:12:14.000000000 -0400
5339 +++ linux-2.6.29/arch/x86/include/asm/pgtable.h 2009-03-28 14:26:19.000000000 -0400
5341 #define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
5342 #define _PAGE_BIT_PAT 7 /* on 4KB pages */
5343 #define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
5344 -#define _PAGE_BIT_UNUSED1 9 /* available for programmer */
5345 +#define _PAGE_BIT_SPECIAL 9 /* special mappings, no associated struct page */
5346 #define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */
5347 #define _PAGE_BIT_UNUSED3 11
5348 #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
5349 -#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1
5350 -#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1
5351 +#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SPECIAL
5352 #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
5354 /* If _PAGE_BIT_PRESENT is clear, we use these: */
5356 #define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
5357 #define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
5358 #define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
5359 -#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
5360 #define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
5361 #define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
5362 #define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
5364 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
5365 #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
5367 -#define _PAGE_NX (_AT(pteval_t, 0))
5368 +#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
5371 #define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE)
5373 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
5376 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
5377 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
5379 #define __PAGE_KERNEL_EXEC \
5380 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
5381 #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
5383 #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
5384 #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
5385 #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
5386 -#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
5387 +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
5388 #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
5389 #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
5390 #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
5392 * bits are combined, this will alow user to access the high address mapped
5393 * VDSO in the presence of CONFIG_COMPAT_VDSO
5395 -#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
5396 +#define PTE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
5397 #define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
5398 #define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
5400 @@ -183,10 +184,17 @@ extern unsigned long empty_zero_page[PAG
5401 extern spinlock_t pgd_lock;
5402 extern struct list_head pgd_list;
5404 +extern pteval_t __supported_pte_mask;
5407 * The following only work if pte_present() is true.
5408 * Undefined behaviour if not..
5410 +static inline int pte_user(pte_t pte)
5412 + return pte_val(pte) & _PAGE_USER;
5415 static inline int pte_dirty(pte_t pte)
5417 return pte_flags(pte) & _PAGE_DIRTY;
5418 @@ -255,9 +263,29 @@ static inline pte_t pte_wrprotect(pte_t
5419 return __pte(pte_val(pte) & ~_PAGE_RW);
5422 +static inline pte_t pte_mkread(pte_t pte)
5424 + return __pte(pte_val(pte) | _PAGE_USER);
5427 static inline pte_t pte_mkexec(pte_t pte)
5429 - return __pte(pte_val(pte) & ~_PAGE_NX);
5430 +#ifdef CONFIG_X86_PAE
5431 + if (__supported_pte_mask & _PAGE_NX)
5432 + return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
5435 + return __pte(pte_val(pte) | _PAGE_USER);
5438 +static inline pte_t pte_exprotect(pte_t pte)
5440 +#ifdef CONFIG_X86_PAE
5441 + if (__supported_pte_mask & _PAGE_NX)
5442 + return __pte(pte_val(pte) | _PAGE_NX);
5445 + return __pte(pte_val(pte) & ~_PAGE_USER);
5448 static inline pte_t pte_mkdirty(pte_t pte)
5449 @@ -300,8 +328,6 @@ static inline pte_t pte_mkspecial(pte_t
5450 return __pte(pte_val(pte) | _PAGE_SPECIAL);
5453 -extern pteval_t __supported_pte_mask;
5456 * Mask out unsupported bits in a present pgprot. Non-present pgprots
5457 * can use those bits for other purposes, so leave them be.
5458 @@ -601,7 +627,19 @@ static inline void ptep_set_wrprotect(st
5460 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
5462 - memcpy(dst, src, count * sizeof(pgd_t));
5464 +#ifdef CONFIG_PAX_KERNEXEC
5465 + unsigned long cr0;
5467 + pax_open_kernel(cr0);
5470 + memcpy(dst, src, count * sizeof(pgd_t));
5472 +#ifdef CONFIG_PAX_KERNEXEC
5473 + pax_close_kernel(cr0);
5479 diff -urNp linux-2.6.29/arch/x86/include/asm/processor.h linux-2.6.29/arch/x86/include/asm/processor.h
5480 --- linux-2.6.29/arch/x86/include/asm/processor.h 2009-03-23 19:12:14.000000000 -0400
5481 +++ linux-2.6.29/arch/x86/include/asm/processor.h 2009-03-28 14:26:19.000000000 -0400
5482 @@ -275,7 +275,7 @@ struct tss_struct {
5484 } ____cacheline_aligned;
5486 -DECLARE_PER_CPU(struct tss_struct, init_tss);
5487 +extern struct tss_struct init_tss[NR_CPUS];
5490 * Save the original ist values for checking stack pointers during debugging
5491 @@ -839,11 +839,20 @@ static inline void spin_lock_prefetch(co
5492 * User space process size: 3GB (default).
5494 #define TASK_SIZE PAGE_OFFSET
5496 +#ifdef CONFIG_PAX_SEGMEXEC
5497 +#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
5500 +#ifdef CONFIG_PAX_SEGMEXEC
5501 +#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
5503 #define STACK_TOP TASK_SIZE
5504 -#define STACK_TOP_MAX STACK_TOP
5506 +#define STACK_TOP_MAX TASK_SIZE
5508 #define INIT_THREAD { \
5509 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
5510 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
5511 .vm86_info = NULL, \
5512 .sysenter_cs = __KERNEL_CS, \
5513 .io_bitmap_ptr = NULL, \
5514 @@ -858,7 +867,7 @@ static inline void spin_lock_prefetch(co
5516 #define INIT_TSS { \
5518 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
5519 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
5520 .ss0 = __KERNEL_DS, \
5521 .ss1 = __KERNEL_CS, \
5522 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
5523 @@ -869,11 +878,7 @@ static inline void spin_lock_prefetch(co
5524 extern unsigned long thread_saved_pc(struct task_struct *tsk);
5526 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
5527 -#define KSTK_TOP(info) \
5529 - unsigned long *__ptr = (unsigned long *)(info); \
5530 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
5532 +#define KSTK_TOP(info) ((info)->task.thread.sp0)
5535 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
5536 @@ -888,7 +893,7 @@ extern unsigned long thread_saved_pc(str
5537 #define task_pt_regs(task) \
5539 struct pt_regs *__regs__; \
5540 - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
5541 + __regs__ = (struct pt_regs *)((task)->thread.sp0); \
5545 @@ -904,7 +909,7 @@ extern unsigned long thread_saved_pc(str
5546 * space during mmap's.
5548 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
5549 - 0xc0000000 : 0xFFFFe000)
5550 + 0xc0000000 : 0xFFFFf000)
5552 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
5553 IA32_PAGE_OFFSET : TASK_SIZE64)
5554 @@ -941,6 +946,10 @@ extern void start_thread(struct pt_regs
5556 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
5558 +#ifdef CONFIG_PAX_SEGMEXEC
5559 +#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
5562 #define KSTK_EIP(task) (task_pt_regs(task)->ip)
5564 /* Get/set a process' ability to use the timestamp counter instruction */
5565 diff -urNp linux-2.6.29/arch/x86/include/asm/ptrace.h linux-2.6.29/arch/x86/include/asm/ptrace.h
5566 --- linux-2.6.29/arch/x86/include/asm/ptrace.h 2009-03-23 19:12:14.000000000 -0400
5567 +++ linux-2.6.29/arch/x86/include/asm/ptrace.h 2009-03-28 14:26:19.000000000 -0400
5568 @@ -151,28 +151,29 @@ static inline unsigned long regs_return_
5572 - * user_mode_vm(regs) determines whether a register set came from user mode.
5573 + * user_mode(regs) determines whether a register set came from user mode.
5574 * This is true if V8086 mode was enabled OR if the register set was from
5575 * protected mode with RPL-3 CS value. This tricky test checks that with
5576 * one comparison. Many places in the kernel can bypass this full check
5577 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
5578 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
5581 -static inline int user_mode(struct pt_regs *regs)
5582 +static inline int user_mode_novm(struct pt_regs *regs)
5584 #ifdef CONFIG_X86_32
5585 return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
5587 - return !!(regs->cs & 3);
5588 + return !!(regs->cs & SEGMENT_RPL_MASK);
5592 -static inline int user_mode_vm(struct pt_regs *regs)
5593 +static inline int user_mode(struct pt_regs *regs)
5595 #ifdef CONFIG_X86_32
5596 return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
5599 - return user_mode(regs);
5600 + return user_mode_novm(regs);
5604 diff -urNp linux-2.6.29/arch/x86/include/asm/reboot.h linux-2.6.29/arch/x86/include/asm/reboot.h
5605 --- linux-2.6.29/arch/x86/include/asm/reboot.h 2009-03-23 19:12:14.000000000 -0400
5606 +++ linux-2.6.29/arch/x86/include/asm/reboot.h 2009-03-28 14:26:19.000000000 -0400
5607 @@ -18,7 +18,7 @@ extern struct machine_ops machine_ops;
5609 void native_machine_crash_shutdown(struct pt_regs *regs);
5610 void native_machine_shutdown(void);
5611 -void machine_real_restart(const unsigned char *code, int length);
5612 +void machine_real_restart(const unsigned char *code, unsigned int length);
5614 typedef void (*nmi_shootdown_cb)(int, struct die_args*);
5615 void nmi_shootdown_cpus(nmi_shootdown_cb callback);
5616 diff -urNp linux-2.6.29/arch/x86/include/asm/rwsem.h linux-2.6.29/arch/x86/include/asm/rwsem.h
5617 --- linux-2.6.29/arch/x86/include/asm/rwsem.h 2009-03-23 19:12:14.000000000 -0400
5618 +++ linux-2.6.29/arch/x86/include/asm/rwsem.h 2009-03-28 14:26:19.000000000 -0400
5619 @@ -106,10 +106,26 @@ static inline void __down_read(struct rw
5621 asm volatile("# beginning down_read\n\t"
5622 LOCK_PREFIX " incl (%%eax)\n\t"
5624 +#ifdef CONFIG_PAX_REFCOUNT
5625 +#ifdef CONFIG_X86_32
5631 + ".pushsection .fixup,\"ax\"\n"
5633 + LOCK_PREFIX "decl (%%eax)\n"
5636 + _ASM_EXTABLE(0b, 1b)
5639 /* adds 0x00000001, returns the old value */
5642 " call call_rwsem_down_read_failed\n"
5645 "# ending down_read\n\t"
5648 @@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
5650 asm volatile("# beginning __down_read_trylock\n\t"
5658 +#ifdef CONFIG_PAX_REFCOUNT
5659 +#ifdef CONFIG_X86_32
5665 + ".pushsection .fixup,\"ax\"\n"
5670 + _ASM_EXTABLE(0b, 1b)
5674 LOCK_PREFIX " cmpxchgl %2,%0\n\t"
5679 "# ending __down_read_trylock\n\t"
5680 : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
5681 : "i" (RWSEM_ACTIVE_READ_BIAS)
5682 @@ -148,12 +180,28 @@ static inline void __down_write_nested(s
5683 tmp = RWSEM_ACTIVE_WRITE_BIAS;
5684 asm volatile("# beginning down_write\n\t"
5685 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
5687 +#ifdef CONFIG_PAX_REFCOUNT
5688 +#ifdef CONFIG_X86_32
5694 + ".pushsection .fixup,\"ax\"\n"
5696 + "movl %%edx,(%%eax)\n"
5699 + _ASM_EXTABLE(0b, 1b)
5702 /* subtract 0x0000ffff, returns the old value */
5703 " testl %%edx,%%edx\n\t"
5704 /* was the count 0 before? */
5707 " call call_rwsem_down_write_failed\n"
5710 "# ending down_write"
5711 : "+m" (sem->count), "=d" (tmp)
5712 : "a" (sem), "1" (tmp)
5713 @@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
5714 __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
5715 asm volatile("# beginning __up_read\n\t"
5716 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
5718 +#ifdef CONFIG_PAX_REFCOUNT
5719 +#ifdef CONFIG_X86_32
5725 + ".pushsection .fixup,\"ax\"\n"
5727 + "movl %%edx,(%%eax)\n"
5730 + _ASM_EXTABLE(0b, 1b)
5733 /* subtracts 1, returns the old value */
5736 " call call_rwsem_wake\n"
5739 "# ending __up_read\n"
5740 : "+m" (sem->count), "=d" (tmp)
5741 : "a" (sem), "1" (tmp)
5742 @@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
5743 asm volatile("# beginning __up_write\n\t"
5744 " movl %2,%%edx\n\t"
5745 LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
5747 +#ifdef CONFIG_PAX_REFCOUNT
5748 +#ifdef CONFIG_X86_32
5754 + ".pushsection .fixup,\"ax\"\n"
5756 + "movl %%edx,(%%eax)\n"
5759 + _ASM_EXTABLE(0b, 1b)
5762 /* tries to transition
5763 0xffff0001 -> 0x00000000 */
5766 " call call_rwsem_wake\n"
5769 "# ending __up_write\n"
5771 : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
5772 @@ -222,10 +302,26 @@ static inline void __downgrade_write(str
5774 asm volatile("# beginning __downgrade_write\n\t"
5775 LOCK_PREFIX " addl %2,(%%eax)\n\t"
5777 +#ifdef CONFIG_PAX_REFCOUNT
5778 +#ifdef CONFIG_X86_32
5784 + ".pushsection .fixup,\"ax\"\n"
5786 + LOCK_PREFIX "subl %2,(%%eax)\n"
5789 + _ASM_EXTABLE(0b, 1b)
5792 /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
5795 " call call_rwsem_downgrade_wake\n"
5798 "# ending __downgrade_write\n"
5800 : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
5801 @@ -237,7 +333,23 @@ static inline void __downgrade_write(str
5803 static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
5805 - asm volatile(LOCK_PREFIX "addl %1,%0"
5806 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
5808 +#ifdef CONFIG_PAX_REFCOUNT
5809 +#ifdef CONFIG_X86_32
5815 + ".pushsection .fixup,\"ax\"\n"
5817 + LOCK_PREFIX "subl %1,%0\n"
5820 + _ASM_EXTABLE(0b, 1b)
5826 @@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
5830 - asm volatile(LOCK_PREFIX "xadd %0,%1"
5831 + asm volatile(LOCK_PREFIX "xadd %0,%1\n"
5833 +#ifdef CONFIG_PAX_REFCOUNT
5834 +#ifdef CONFIG_X86_32
5840 + ".pushsection .fixup,\"ax\"\n"
5845 + _ASM_EXTABLE(0b, 1b)
5848 : "+r" (tmp), "+m" (sem->count)
5851 diff -urNp linux-2.6.29/arch/x86/include/asm/segment.h linux-2.6.29/arch/x86/include/asm/segment.h
5852 --- linux-2.6.29/arch/x86/include/asm/segment.h 2009-03-23 19:12:14.000000000 -0400
5853 +++ linux-2.6.29/arch/x86/include/asm/segment.h 2009-03-28 14:26:19.000000000 -0400
5855 #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
5856 #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
5858 -#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
5859 +#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
5861 #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
5863 #define __KERNEL_PERCPU 0
5866 +#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
5867 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
5869 +#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
5870 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
5872 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
5878 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
5879 -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
5880 +#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
5884 diff -urNp linux-2.6.29/arch/x86/include/asm/spinlock.h linux-2.6.29/arch/x86/include/asm/spinlock.h
5885 --- linux-2.6.29/arch/x86/include/asm/spinlock.h 2009-03-23 19:12:14.000000000 -0400
5886 +++ linux-2.6.29/arch/x86/include/asm/spinlock.h 2009-03-28 14:26:19.000000000 -0400
5887 @@ -311,18 +311,50 @@ static inline int __raw_write_can_lock(r
5888 static inline void __raw_read_lock(raw_rwlock_t *rw)
5890 asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
5892 - "call __read_lock_failed\n\t"
5894 +#ifdef CONFIG_PAX_REFCOUNT
5895 +#ifdef CONFIG_X86_32
5901 + ".pushsection .fixup,\"ax\"\n"
5903 + LOCK_PREFIX " addl $1,(%0)\n"
5906 + _ASM_EXTABLE(0b, 1b)
5910 + "call __read_lock_failed\n\t"
5912 ::LOCK_PTR_REG (rw) : "memory");
5915 static inline void __raw_write_lock(raw_rwlock_t *rw)
5917 asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
5919 - "call __write_lock_failed\n\t"
5921 +#ifdef CONFIG_PAX_REFCOUNT
5922 +#ifdef CONFIG_X86_32
5928 + ".pushsection .fixup,\"ax\"\n"
5930 + LOCK_PREFIX " addl %1,(%0)\n"
5933 + _ASM_EXTABLE(0b, 1b)
5937 + "call __write_lock_failed\n\t"
5939 ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
5942 @@ -349,12 +381,45 @@ static inline int __raw_write_trylock(ra
5944 static inline void __raw_read_unlock(raw_rwlock_t *rw)
5946 - asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
5947 + asm volatile(LOCK_PREFIX "incl %0\n"
5949 +#ifdef CONFIG_PAX_REFCOUNT
5950 +#ifdef CONFIG_X86_32
5956 + ".pushsection .fixup,\"ax\"\n"
5958 + LOCK_PREFIX "decl %0\n"
5961 + _ASM_EXTABLE(0b, 1b)
5964 + :"+m" (rw->lock) : : "memory");
5967 static inline void __raw_write_unlock(raw_rwlock_t *rw)
5969 - asm volatile(LOCK_PREFIX "addl %1, %0"
5970 + asm volatile(LOCK_PREFIX "addl %1, %0\n"
5972 +#ifdef CONFIG_PAX_REFCOUNT
5973 +#ifdef CONFIG_X86_32
5979 + ".pushsection .fixup,\"ax\"\n"
5981 + LOCK_PREFIX "subl %1,%0\n"
5984 + _ASM_EXTABLE(0b, 1b)
5987 : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
5990 diff -urNp linux-2.6.29/arch/x86/include/asm/system.h linux-2.6.29/arch/x86/include/asm/system.h
5991 --- linux-2.6.29/arch/x86/include/asm/system.h 2009-03-23 19:12:14.000000000 -0400
5992 +++ linux-2.6.29/arch/x86/include/asm/system.h 2009-03-28 14:26:19.000000000 -0400
5993 @@ -95,6 +95,8 @@ do { \
5994 ".globl thread_return\n" \
5995 "thread_return:\n\t" \
5996 "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
5997 + "movq %P[task_canary](%%rsi),%%r8\n\t" \
5998 + "movq %%r8,%%gs:%P[pda_canary]\n\t" \
5999 "movq %P[thread_info](%%rsi),%%r8\n\t" \
6000 LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
6001 "movq %%rax,%%rdi\n\t" \
6002 @@ -106,7 +108,9 @@ do { \
6003 [ti_flags] "i" (offsetof(struct thread_info, flags)), \
6004 [tif_fork] "i" (TIF_FORK), \
6005 [thread_info] "i" (offsetof(struct task_struct, stack)), \
6006 - [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
6007 + [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
6008 + [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
6009 + [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
6010 : "memory", "cc" __EXTRA_CLOBBER)
6013 @@ -169,7 +173,7 @@ static inline unsigned long get_limit(un
6015 unsigned long __limit;
6016 asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
6017 - return __limit + 1;
6021 static inline void native_clts(void)
6022 @@ -295,6 +299,21 @@ static inline void native_wbinvd(void)
6024 #define stts() write_cr0(read_cr0() | X86_CR0_TS)
6026 +#define pax_open_kernel(cr0) \
6028 + typecheck(unsigned long, cr0); \
6029 + preempt_disable(); \
6030 + cr0 = read_cr0(); \
6031 + write_cr0(cr0 & ~X86_CR0_WP); \
6034 +#define pax_close_kernel(cr0) \
6036 + typecheck(unsigned long, cr0); \
6038 + preempt_enable_no_resched(); \
6041 #endif /* __KERNEL__ */
6043 static inline void clflush(volatile void *__p)
6044 @@ -309,7 +328,7 @@ void enable_hlt(void);
6046 void cpu_idle_wait(void);
6048 -extern unsigned long arch_align_stack(unsigned long sp);
6049 +#define arch_align_stack(x) ((x) & ~0xfUL)
6050 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
6052 void default_idle(void);
6053 diff -urNp linux-2.6.29/arch/x86/include/asm/uaccess_64.h linux-2.6.29/arch/x86/include/asm/uaccess_64.h
6054 --- linux-2.6.29/arch/x86/include/asm/uaccess_64.h 2009-03-23 19:12:14.000000000 -0400
6055 +++ linux-2.6.29/arch/x86/include/asm/uaccess_64.h 2009-03-28 14:26:19.000000000 -0400
6057 #include <linux/lockdep.h>
6058 #include <asm/page.h>
6060 +#define set_fs(x) (current_thread_info()->addr_limit = (x))
6063 * Copy To/From Userspace
6065 diff -urNp linux-2.6.29/arch/x86/include/asm/uaccess.h linux-2.6.29/arch/x86/include/asm/uaccess.h
6066 --- linux-2.6.29/arch/x86/include/asm/uaccess.h 2009-03-23 19:12:14.000000000 -0400
6067 +++ linux-2.6.29/arch/x86/include/asm/uaccess.h 2009-03-28 14:26:19.000000000 -0400
6069 #include <linux/string.h>
6070 #include <asm/asm.h>
6071 #include <asm/page.h>
6072 +#include <asm/segment.h>
6074 #define VERIFY_READ 0
6075 #define VERIFY_WRITE 1
6078 #define get_ds() (KERNEL_DS)
6079 #define get_fs() (current_thread_info()->addr_limit)
6080 +#ifdef CONFIG_X86_32
6081 +void __set_fs(mm_segment_t x, int cpu);
6082 +void set_fs(mm_segment_t x);
6084 #define set_fs(x) (current_thread_info()->addr_limit = (x))
6087 #define segment_eq(a, b) ((a).seg == (b).seg)
6089 @@ -187,9 +193,12 @@ extern int __get_user_bad(void);
6091 #ifdef CONFIG_X86_32
6092 #define __put_user_u64(x, addr, err) \
6093 - asm volatile("1: movl %%eax,0(%2)\n" \
6094 - "2: movl %%edx,4(%2)\n" \
6095 + asm volatile(" movw %w5,%%ds\n" \
6096 + "1: movl %%eax,%%ds:0(%2)\n" \
6097 + "2: movl %%edx,%%ds:4(%2)\n" \
6101 ".section .fixup,\"ax\"\n" \
6104 @@ -197,7 +206,8 @@ extern int __get_user_bad(void);
6105 _ASM_EXTABLE(1b, 4b) \
6106 _ASM_EXTABLE(2b, 4b) \
6108 - : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
6109 + : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err), \
6112 #define __put_user_x8(x, ptr, __ret_pu) \
6113 asm volatile("call __put_user_8" : "=a" (__ret_pu) \
6114 @@ -338,6 +348,22 @@ do { \
6118 +#ifdef CONFIG_X86_32
6119 +#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
6120 + asm volatile(" movw %w5,%%ds\n" \
6121 + "1: mov"itype" %%ds:%2,%"rtype"1\n" \
6125 + ".section .fixup,\"ax\"\n" \
6126 + "3: movl %3,%0\n" \
6127 + " xor"itype" %"rtype"1,%"rtype"1\n" \
6130 + _ASM_EXTABLE(1b, 3b) \
6131 + : "=r" (err), ltype (x) \
6132 + : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
6134 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
6135 asm volatile("1: mov"itype" %2,%"rtype"1\n" \
6137 @@ -349,6 +375,7 @@ do { \
6138 _ASM_EXTABLE(1b, 3b) \
6139 : "=r" (err), ltype(x) \
6140 : "m" (__m(addr)), "i" (errret), "0" (err))
6143 #define __put_user_nocheck(x, ptr, size) \
6145 @@ -375,6 +402,22 @@ struct __large_struct { unsigned long bu
6146 * we do not write to any memory gcc knows about, so there are no
6149 +#ifdef CONFIG_X86_32
6150 +#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
6151 + asm volatile(" movw %w5,%%ds\n" \
6152 + "1: mov"itype" %"rtype"1,%%ds:%2\n" \
6156 + ".section .fixup,\"ax\"\n" \
6157 + "3: movl %3,%0\n" \
6160 + _ASM_EXTABLE(1b, 3b) \
6162 + : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
6165 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
6166 asm volatile("1: mov"itype" %"rtype"1,%2\n" \
6168 @@ -385,6 +428,7 @@ struct __large_struct { unsigned long bu
6169 _ASM_EXTABLE(1b, 3b) \
6171 : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
6174 * __get_user: - Get a simple variable from user space, with less checking.
6175 * @x: Variable to store result.
6176 @@ -445,6 +489,7 @@ extern struct movsl_mask {
6178 #define ARCH_HAS_NOCACHE_UACCESS 1
6180 +#define ARCH_HAS_SORT_EXTABLE
6181 #ifdef CONFIG_X86_32
6182 # include "uaccess_32.h"
6184 diff -urNp linux-2.6.29/arch/x86/Kconfig linux-2.6.29/arch/x86/Kconfig
6185 --- linux-2.6.29/arch/x86/Kconfig 2009-03-23 19:12:14.000000000 -0400
6186 +++ linux-2.6.29/arch/x86/Kconfig 2009-03-28 14:26:19.000000000 -0400
6187 @@ -993,7 +993,7 @@ config PAGE_OFFSET
6189 default 0xB0000000 if VMSPLIT_3G_OPT
6190 default 0x80000000 if VMSPLIT_2G
6191 - default 0x78000000 if VMSPLIT_2G_OPT
6192 + default 0x70000000 if VMSPLIT_2G_OPT
6193 default 0x40000000 if VMSPLIT_1G
6196 @@ -1408,8 +1408,7 @@ config KEXEC_JUMP
6197 config PHYSICAL_START
6198 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
6199 default "0x1000000" if X86_NUMAQ
6200 - default "0x200000" if X86_64
6201 - default "0x100000"
6202 + default "0x200000"
6204 This gives the physical address where the kernel is loaded.
6206 @@ -1501,9 +1500,9 @@ config HOTPLUG_CPU
6207 Say N if you want to disable CPU hotplug.
6212 prompt "Compat VDSO support"
6213 - depends on X86_32 || IA32_EMULATION
6214 + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
6216 Map the 32-bit VDSO to the predictable old-style address too.
6218 diff -urNp linux-2.6.29/arch/x86/Kconfig.cpu linux-2.6.29/arch/x86/Kconfig.cpu
6219 --- linux-2.6.29/arch/x86/Kconfig.cpu 2009-03-23 19:12:14.000000000 -0400
6220 +++ linux-2.6.29/arch/x86/Kconfig.cpu 2009-03-28 14:26:19.000000000 -0400
6221 @@ -333,7 +333,7 @@ config X86_PPRO_FENCE
6225 - depends on M586MMX || M586TSC || M586 || M486 || M386
6226 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
6228 config X86_WP_WORKS_OK
6230 @@ -353,7 +353,7 @@ config X86_POPAD_OK
6232 config X86_ALIGNMENT_16
6234 - depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
6235 + depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
6237 config X86_INTEL_USERCOPY
6239 @@ -399,7 +399,7 @@ config X86_CMPXCHG64
6243 - depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
6244 + depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
6246 config X86_MINIMUM_CPU_FAMILY
6248 diff -urNp linux-2.6.29/arch/x86/Kconfig.debug linux-2.6.29/arch/x86/Kconfig.debug
6249 --- linux-2.6.29/arch/x86/Kconfig.debug 2009-03-23 19:12:14.000000000 -0400
6250 +++ linux-2.6.29/arch/x86/Kconfig.debug 2009-03-28 14:26:19.000000000 -0400
6251 @@ -107,7 +107,7 @@ config X86_PTDUMP
6253 bool "Write protect kernel read-only data structures"
6255 - depends on DEBUG_KERNEL
6256 + depends on DEBUG_KERNEL && BROKEN
6258 Mark the kernel read-only data as write-protected in the pagetables,
6259 in order to catch accidental (and incorrect) writes to such const
6260 diff -urNp linux-2.6.29/arch/x86/kernel/acpi/boot.c linux-2.6.29/arch/x86/kernel/acpi/boot.c
6261 --- linux-2.6.29/arch/x86/kernel/acpi/boot.c 2009-03-23 19:12:14.000000000 -0400
6262 +++ linux-2.6.29/arch/x86/kernel/acpi/boot.c 2009-03-28 14:26:19.000000000 -0400
6263 @@ -1705,7 +1705,7 @@ static struct dmi_system_id __initdata a
6264 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
6268 + { NULL, NULL, {{0, {0}}}, NULL}
6272 diff -urNp linux-2.6.29/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.29/arch/x86/kernel/acpi/realmode/wakeup.S
6273 --- linux-2.6.29/arch/x86/kernel/acpi/realmode/wakeup.S 2009-03-23 19:12:14.000000000 -0400
6274 +++ linux-2.6.29/arch/x86/kernel/acpi/realmode/wakeup.S 2009-03-28 14:26:19.000000000 -0400
6275 @@ -104,7 +104,7 @@ _start:
6279 - movl $0xc0000080, %ecx
6280 + mov $MSR_EFER, %ecx
6284 diff -urNp linux-2.6.29/arch/x86/kernel/acpi/sleep.c linux-2.6.29/arch/x86/kernel/acpi/sleep.c
6285 --- linux-2.6.29/arch/x86/kernel/acpi/sleep.c 2009-03-23 19:12:14.000000000 -0400
6286 +++ linux-2.6.29/arch/x86/kernel/acpi/sleep.c 2009-03-28 14:26:19.000000000 -0400
6287 @@ -37,6 +37,10 @@ int acpi_save_state_mem(void)
6289 struct wakeup_header *header;
6291 +#if defined(CONFIG_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_PAX_KERNEXEC)
6292 + unsigned long cr0;
6295 if (!acpi_realmode) {
6296 printk(KERN_ERR "Could not allocate memory during boot, "
6298 @@ -99,8 +103,18 @@ int acpi_save_state_mem(void)
6299 header->trampoline_segment = setup_trampoline() >> 4;
6301 stack_start.sp = temp_stack + sizeof(temp_stack);
6303 +#ifdef CONFIG_PAX_KERNEXEC
6304 + pax_open_kernel(cr0);
6307 early_gdt_descr.address =
6308 (unsigned long)get_cpu_gdt_table(smp_processor_id());
6310 +#ifdef CONFIG_PAX_KERNEXEC
6311 + pax_close_kernel(cr0);
6315 initial_code = (unsigned long)wakeup_long64;
6316 saved_magic = 0x123456789abcdef0;
6317 diff -urNp linux-2.6.29/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.29/arch/x86/kernel/acpi/wakeup_32.S
6318 --- linux-2.6.29/arch/x86/kernel/acpi/wakeup_32.S 2009-03-23 19:12:14.000000000 -0400
6319 +++ linux-2.6.29/arch/x86/kernel/acpi/wakeup_32.S 2009-03-28 14:26:19.000000000 -0400
6320 @@ -30,13 +30,11 @@ wakeup_pmode_return:
6321 # and restore the stack ... but you need gdt for this to work
6322 movl saved_context_esp, %esp
6324 - movl %cs:saved_magic, %eax
6325 - cmpl $0x12345678, %eax
6326 + cmpl $0x12345678, saved_magic
6329 # jump to place where we left off
6330 - movl saved_eip, %eax
6336 diff -urNp linux-2.6.29/arch/x86/kernel/alternative.c linux-2.6.29/arch/x86/kernel/alternative.c
6337 --- linux-2.6.29/arch/x86/kernel/alternative.c 2009-03-23 19:12:14.000000000 -0400
6338 +++ linux-2.6.29/arch/x86/kernel/alternative.c 2009-03-28 14:26:19.000000000 -0400
6339 @@ -393,7 +393,7 @@ void apply_paravirt(struct paravirt_patc
6341 BUG_ON(p->len > MAX_PATCH_LEN);
6342 /* prep the buffer with the original instructions */
6343 - memcpy(insnbuf, p->instr, p->len);
6344 + memcpy(insnbuf, ktla_ktva(p->instr), p->len);
6345 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
6346 (unsigned long)p->instr, p->len);
6348 @@ -473,11 +473,26 @@ void __init alternative_instructions(voi
6349 * instructions. And on the local CPU you need to be protected again NMI or MCE
6350 * handlers seeing an inconsistent instruction while you patch.
6352 -void *text_poke_early(void *addr, const void *opcode, size_t len)
6353 +void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
6355 unsigned long flags;
6357 +#ifdef CONFIG_PAX_KERNEXEC
6358 + unsigned long cr0;
6361 local_irq_save(flags);
6362 - memcpy(addr, opcode, len);
6364 +#ifdef CONFIG_PAX_KERNEXEC
6365 + pax_open_kernel(cr0);
6368 + memcpy(ktla_ktva(addr), opcode, len);
6370 +#ifdef CONFIG_PAX_KERNEXEC
6371 + pax_close_kernel(cr0);
6374 local_irq_restore(flags);
6376 /* Could also do a CLFLUSH here to speed up CPU recovery; but
6377 @@ -498,33 +513,27 @@ void *text_poke_early(void *addr, const
6379 void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
6381 - unsigned long flags;
6384 + unsigned char *vaddr = ktla_ktva(addr);
6385 struct page *pages[2];
6389 + if (!core_kernel_text((unsigned long)addr)
6391 - if (!core_kernel_text((unsigned long)addr)) {
6392 - pages[0] = vmalloc_to_page(addr);
6393 - pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
6394 +#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
6395 + && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
6399 + pages[0] = vmalloc_to_page(vaddr);
6400 + pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
6402 - pages[0] = virt_to_page(addr);
6403 + pages[0] = virt_to_page(vaddr);
6404 WARN_ON(!PageReserved(pages[0]));
6405 - pages[1] = virt_to_page(addr + PAGE_SIZE);
6406 + pages[1] = virt_to_page(vaddr + PAGE_SIZE);
6411 - vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
6413 - local_irq_save(flags);
6414 - memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
6415 - local_irq_restore(flags);
6418 - /* Could also do a CLFLUSH here to speed up CPU recovery; but
6419 - that causes hangs on some VIA CPUs. */
6420 + text_poke_early(addr, opcode, len);
6421 for (i = 0; i < len; i++)
6422 - BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
6423 + BUG_ON((vaddr)[i] != ((unsigned char *)opcode)[i]);
6426 diff -urNp linux-2.6.29/arch/x86/kernel/apm_32.c linux-2.6.29/arch/x86/kernel/apm_32.c
6427 --- linux-2.6.29/arch/x86/kernel/apm_32.c 2009-03-23 19:12:14.000000000 -0400
6428 +++ linux-2.6.29/arch/x86/kernel/apm_32.c 2009-03-28 14:26:19.000000000 -0400
6429 @@ -403,7 +403,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
6430 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
6431 static struct apm_user *user_list;
6432 static DEFINE_SPINLOCK(user_list_lock);
6433 -static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
6434 +static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
6436 static const char driver_version[] = "1.16ac"; /* no spaces */
6438 @@ -598,19 +598,42 @@ static u8 apm_bios_call(u32 func, u32 eb
6439 struct desc_struct save_desc_40;
6440 struct desc_struct *gdt;
6442 +#ifdef CONFIG_PAX_KERNEXEC
6443 + unsigned long cr0;
6446 cpus = apm_save_cpus();
6449 gdt = get_cpu_gdt_table(cpu);
6450 save_desc_40 = gdt[0x40 / 8];
6452 +#ifdef CONFIG_PAX_KERNEXEC
6453 + pax_open_kernel(cr0);
6456 gdt[0x40 / 8] = bad_bios_desc;
6458 +#ifdef CONFIG_PAX_KERNEXEC
6459 + pax_close_kernel(cr0);
6462 apm_irq_save(flags);
6464 apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
6465 APM_DO_RESTORE_SEGS;
6466 apm_irq_restore(flags);
6468 +#ifdef CONFIG_PAX_KERNEXEC
6469 + pax_open_kernel(cr0);
6472 gdt[0x40 / 8] = save_desc_40;
6474 +#ifdef CONFIG_PAX_KERNEXEC
6475 + pax_close_kernel(cr0);
6479 apm_restore_cpus(cpus);
6481 @@ -641,19 +664,42 @@ static u8 apm_bios_call_simple(u32 func,
6482 struct desc_struct save_desc_40;
6483 struct desc_struct *gdt;
6485 +#ifdef CONFIG_PAX_KERNEXEC
6486 + unsigned long cr0;
6489 cpus = apm_save_cpus();
6492 gdt = get_cpu_gdt_table(cpu);
6493 save_desc_40 = gdt[0x40 / 8];
6495 +#ifdef CONFIG_PAX_KERNEXEC
6496 + pax_open_kernel(cr0);
6499 gdt[0x40 / 8] = bad_bios_desc;
6501 +#ifdef CONFIG_PAX_KERNEXEC
6502 + pax_close_kernel(cr0);
6505 apm_irq_save(flags);
6507 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
6508 APM_DO_RESTORE_SEGS;
6509 apm_irq_restore(flags);
6511 +#ifdef CONFIG_PAX_KERNEXEC
6512 + pax_open_kernel(cr0);
6515 gdt[0x40 / 8] = save_desc_40;
6517 +#ifdef CONFIG_PAX_KERNEXEC
6518 + pax_close_kernel(cr0);
6522 apm_restore_cpus(cpus);
6524 @@ -925,7 +971,7 @@ recalc:
6526 static void apm_power_off(void)
6528 - unsigned char po_bios_call[] = {
6529 + const unsigned char po_bios_call[] = {
6530 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
6531 0x8e, 0xd0, /* movw ax,ss */
6532 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
6533 @@ -1876,7 +1922,10 @@ static const struct file_operations apm_
6534 static struct miscdevice apm_device = {
6545 @@ -2197,7 +2246,7 @@ static struct dmi_system_id __initdata a
6546 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
6550 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
6554 @@ -2215,6 +2264,10 @@ static int __init apm_init(void)
6555 struct desc_struct *gdt;
6558 +#ifdef CONFIG_PAX_KERNEXEC
6559 + unsigned long cr0;
6562 dmi_check_system(apm_dmi_table);
6564 if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
6565 @@ -2288,9 +2341,18 @@ static int __init apm_init(void)
6566 * This is for buggy BIOS's that refer to (real mode) segment 0x40
6567 * even though they are called in protected mode.
6570 +#ifdef CONFIG_PAX_KERNEXEC
6571 + pax_open_kernel(cr0);
6574 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
6575 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
6577 +#ifdef CONFIG_PAX_KERNEXEC
6578 + pax_close_kernel(cr0);
6582 * Set up the long jump entry point to the APM BIOS, which is called
6583 * from inline assembly.
6584 @@ -2309,6 +2371,11 @@ static int __init apm_init(void)
6587 gdt = get_cpu_gdt_table(0);
6589 +#ifdef CONFIG_PAX_KERNEXEC
6590 + pax_open_kernel(cr0);
6593 set_base(gdt[APM_CS >> 3],
6594 __va((unsigned long)apm_info.bios.cseg << 4));
6595 set_base(gdt[APM_CS_16 >> 3],
6596 @@ -2316,6 +2383,10 @@ static int __init apm_init(void)
6597 set_base(gdt[APM_DS >> 3],
6598 __va((unsigned long)apm_info.bios.dseg << 4));
6600 +#ifdef CONFIG_PAX_KERNEXEC
6601 + pax_close_kernel(cr0);
6604 proc_create("apm", 0, NULL, &apm_file_ops);
6606 kapmd_task = kthread_create(apm, NULL, "kapmd");
6607 diff -urNp linux-2.6.29/arch/x86/kernel/asm-offsets_32.c linux-2.6.29/arch/x86/kernel/asm-offsets_32.c
6608 --- linux-2.6.29/arch/x86/kernel/asm-offsets_32.c 2009-03-23 19:12:14.000000000 -0400
6609 +++ linux-2.6.29/arch/x86/kernel/asm-offsets_32.c 2009-03-28 14:26:19.000000000 -0400
6610 @@ -100,6 +100,7 @@ void foo(void)
6611 DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
6612 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
6613 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
6614 + DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
6616 OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
6618 @@ -113,6 +114,7 @@ void foo(void)
6619 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
6620 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
6621 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
6622 + OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
6626 diff -urNp linux-2.6.29/arch/x86/kernel/asm-offsets_64.c linux-2.6.29/arch/x86/kernel/asm-offsets_64.c
6627 --- linux-2.6.29/arch/x86/kernel/asm-offsets_64.c 2009-03-23 19:12:14.000000000 -0400
6628 +++ linux-2.6.29/arch/x86/kernel/asm-offsets_64.c 2009-03-28 14:26:19.000000000 -0400
6629 @@ -124,6 +124,7 @@ int main(void)
6633 + DEFINE(TSS_size, sizeof(struct tss_struct));
6634 DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
6636 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
6637 diff -urNp linux-2.6.29/arch/x86/kernel/cpu/common.c linux-2.6.29/arch/x86/kernel/cpu/common.c
6638 --- linux-2.6.29/arch/x86/kernel/cpu/common.c 2009-03-23 19:12:14.000000000 -0400
6639 +++ linux-2.6.29/arch/x86/kernel/cpu/common.c 2009-03-28 14:26:19.000000000 -0400
6641 #include <linux/kernel.h>
6642 #include <linux/sched.h>
6643 #include <linux/string.h>
6644 -#include <linux/bootmem.h>
6645 #include <linux/bitops.h>
6646 #include <linux/module.h>
6647 #include <linux/kgdb.h>
6648 @@ -62,59 +61,6 @@ cpumask_t cpu_sibling_setup_map;
6650 static struct cpu_dev *this_cpu __cpuinitdata;
6652 -#ifdef CONFIG_X86_64
6653 -/* We need valid kernel segments for data and code in long mode too
6654 - * IRET will check the segment types kkeil 2000/10/28
6655 - * Also sysret mandates a special GDT layout
6657 -/* The TLS descriptors are currently at a different place compared to i386.
6658 - Hopefully nobody expects them at a fixed place (Wine?) */
6659 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
6660 - [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
6661 - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
6662 - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
6663 - [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
6664 - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
6665 - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
6668 -DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
6669 - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
6670 - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
6671 - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
6672 - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
6674 - * Segments used for calling PnP BIOS have byte granularity.
6675 - * They code segments and data segments have fixed 64k limits,
6676 - * the transfer segment sizes are set at run time.
6679 - [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
6681 - [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
6683 - [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
6685 - [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
6687 - [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
6689 - * The APM segments have byte granularity and their bases
6690 - * are set at run time. All have 64k limits.
6693 - [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
6695 - [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
6697 - [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
6699 - [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
6700 - [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
6703 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
6705 #ifdef CONFIG_X86_32
6706 static int cachesize_override __cpuinitdata = -1;
6707 static int disable_x86_serial_nr __cpuinitdata = 1;
6708 @@ -248,7 +194,7 @@ void switch_to_new_gdt(void)
6710 struct desc_ptr gdt_descr;
6712 - gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
6713 + gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
6714 gdt_descr.size = GDT_SIZE - 1;
6715 load_gdt(&gdt_descr);
6716 #ifdef CONFIG_X86_32
6717 @@ -708,6 +654,10 @@ static void __cpuinit identify_cpu(struc
6718 * we do "generic changes."
6721 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
6722 + setup_clear_cpu_cap(X86_FEATURE_SEP);
6725 /* If the model name is still unset, do table lookup. */
6726 if (!c->x86_model_id[0]) {
6728 @@ -880,7 +830,7 @@ __setup("clearcpuid=", setup_disablecpui
6729 struct x8664_pda **_cpu_pda __read_mostly;
6730 EXPORT_SYMBOL(_cpu_pda);
6732 -struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
6733 +struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
6735 static char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
6737 @@ -979,7 +929,7 @@ struct pt_regs * __cpuinit idle_regs(str
6738 void __cpuinit cpu_init(void)
6740 int cpu = stack_smp_processor_id();
6741 - struct tss_struct *t = &per_cpu(init_tss, cpu);
6742 + struct tss_struct *t = init_tss + cpu;
6743 struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
6745 char *estacks = NULL;
6746 @@ -1100,7 +1050,7 @@ void __cpuinit cpu_init(void)
6748 int cpu = smp_processor_id();
6749 struct task_struct *curr = current;
6750 - struct tss_struct *t = &per_cpu(init_tss, cpu);
6751 + struct tss_struct *t = init_tss + cpu;
6752 struct thread_struct *thread = &curr->thread;
6754 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
6755 diff -urNp linux-2.6.29/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.29/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
6756 --- linux-2.6.29/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-03-23 19:12:14.000000000 -0400
6757 +++ linux-2.6.29/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-03-28 14:26:19.000000000 -0400
6758 @@ -581,7 +581,7 @@ static const struct dmi_system_id sw_any
6759 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
6763 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
6767 diff -urNp linux-2.6.29/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.29/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
6768 --- linux-2.6.29/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-03-23 19:12:14.000000000 -0400
6769 +++ linux-2.6.29/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-03-28 14:26:19.000000000 -0400
6770 @@ -225,7 +225,7 @@ static struct cpu_model models[] =
6771 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
6772 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
6775 + { NULL, NULL, 0, NULL}
6779 diff -urNp linux-2.6.29/arch/x86/kernel/cpu/intel.c linux-2.6.29/arch/x86/kernel/cpu/intel.c
6780 --- linux-2.6.29/arch/x86/kernel/cpu/intel.c 2009-03-23 19:12:14.000000000 -0400
6781 +++ linux-2.6.29/arch/x86/kernel/cpu/intel.c 2009-03-28 14:26:19.000000000 -0400
6782 @@ -94,7 +94,7 @@ static void __cpuinit trap_init_f00f_bug
6783 * Update the IDT descriptor and reload the IDT so that
6784 * it uses the read-only mapped virtual address.
6786 - idt_descr.address = fix_to_virt(FIX_F00F_IDT);
6787 + idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
6788 load_idt(&idt_descr);
6791 diff -urNp linux-2.6.29/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.29/arch/x86/kernel/cpu/mcheck/mce_64.c
6792 --- linux-2.6.29/arch/x86/kernel/cpu/mcheck/mce_64.c 2009-03-23 19:12:14.000000000 -0400
6793 +++ linux-2.6.29/arch/x86/kernel/cpu/mcheck/mce_64.c 2009-03-28 14:26:19.000000000 -0400
6794 @@ -678,6 +678,7 @@ static struct miscdevice mce_log_device
6798 + {NULL, NULL}, NULL, NULL
6801 static unsigned long old_cr4 __initdata;
6802 diff -urNp linux-2.6.29/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.29/arch/x86/kernel/cpu/mtrr/generic.c
6803 --- linux-2.6.29/arch/x86/kernel/cpu/mtrr/generic.c 2009-03-23 19:12:14.000000000 -0400
6804 +++ linux-2.6.29/arch/x86/kernel/cpu/mtrr/generic.c 2009-03-28 14:26:19.000000000 -0400
6805 @@ -23,14 +23,14 @@ static struct fixed_range_block fixed_ra
6806 { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
6807 { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
6808 { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
6813 static unsigned long smp_changes_mask;
6814 static int mtrr_state_set;
6817 -struct mtrr_state_type mtrr_state = {};
6818 +struct mtrr_state_type mtrr_state;
6819 EXPORT_SYMBOL_GPL(mtrr_state);
6821 static int __initdata mtrr_show;
6822 diff -urNp linux-2.6.29/arch/x86/kernel/crash.c linux-2.6.29/arch/x86/kernel/crash.c
6823 --- linux-2.6.29/arch/x86/kernel/crash.c 2009-03-23 19:12:14.000000000 -0400
6824 +++ linux-2.6.29/arch/x86/kernel/crash.c 2009-03-28 14:26:19.000000000 -0400
6825 @@ -43,7 +43,7 @@ static void kdump_nmi_callback(int cpu,
6828 #ifdef CONFIG_X86_32
6829 - if (!user_mode_vm(regs)) {
6830 + if (!user_mode(regs)) {
6831 crash_fixup_ss_esp(&fixed_regs, regs);
6834 diff -urNp linux-2.6.29/arch/x86/kernel/doublefault_32.c linux-2.6.29/arch/x86/kernel/doublefault_32.c
6835 --- linux-2.6.29/arch/x86/kernel/doublefault_32.c 2009-03-23 19:12:14.000000000 -0400
6836 +++ linux-2.6.29/arch/x86/kernel/doublefault_32.c 2009-03-28 14:26:19.000000000 -0400
6839 #define DOUBLEFAULT_STACKSIZE (1024)
6840 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
6841 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
6842 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
6844 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
6846 @@ -21,7 +21,7 @@ static void doublefault_fn(void)
6847 unsigned long gdt, tss;
6849 store_gdt(&gdt_desc);
6850 - gdt = gdt_desc.address;
6851 + gdt = (unsigned long)gdt_desc.address;
6853 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
6855 @@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
6856 /* 0x2 bit is always set */
6857 .flags = X86_EFLAGS_SF | 0x2,
6860 + .es = __KERNEL_DS,
6864 + .ds = __KERNEL_DS,
6865 .fs = __KERNEL_PERCPU,
6867 .__cr3 = __pa_nodebug(swapper_pg_dir),
6868 diff -urNp linux-2.6.29/arch/x86/kernel/dumpstack_32.c linux-2.6.29/arch/x86/kernel/dumpstack_32.c
6869 --- linux-2.6.29/arch/x86/kernel/dumpstack_32.c 2009-03-23 19:12:14.000000000 -0400
6870 +++ linux-2.6.29/arch/x86/kernel/dumpstack_32.c 2009-03-28 14:26:19.000000000 -0400
6871 @@ -107,11 +107,12 @@ void show_registers(struct pt_regs *regs
6872 * When in-kernel, we also print out the stack and code at the
6873 * time of the fault..
6875 - if (!user_mode_vm(regs)) {
6876 + if (!user_mode(regs)) {
6877 unsigned int code_prologue = code_bytes * 43 / 64;
6878 unsigned int code_len = code_bytes;
6881 + unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
6883 printk(KERN_EMERG "Stack:\n");
6884 show_stack_log_lvl(NULL, regs, ®s->sp,
6885 @@ -119,10 +120,10 @@ void show_registers(struct pt_regs *regs
6887 printk(KERN_EMERG "Code: ");
6889 - ip = (u8 *)regs->ip - code_prologue;
6890 + ip = (u8 *)regs->ip - code_prologue + cs_base;
6891 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
6892 /* try starting at IP */
6893 - ip = (u8 *)regs->ip;
6894 + ip = (u8 *)regs->ip + cs_base;
6895 code_len = code_len - code_prologue + 1;
6897 for (i = 0; i < code_len; i++, ip++) {
6898 @@ -131,7 +132,7 @@ void show_registers(struct pt_regs *regs
6899 printk(" Bad EIP value.");
6902 - if (ip == (u8 *)regs->ip)
6903 + if (ip == (u8 *)regs->ip + cs_base)
6904 printk("<%02x> ", c);
6907 @@ -144,6 +145,7 @@ int is_valid_bugaddr(unsigned long ip)
6911 + ip = ktla_ktva(ip);
6912 if (ip < PAGE_OFFSET)
6914 if (probe_kernel_address((unsigned short *)ip, ud2))
6915 diff -urNp linux-2.6.29/arch/x86/kernel/dumpstack.c linux-2.6.29/arch/x86/kernel/dumpstack.c
6916 --- linux-2.6.29/arch/x86/kernel/dumpstack.c 2009-03-23 19:12:14.000000000 -0400
6917 +++ linux-2.6.29/arch/x86/kernel/dumpstack.c 2009-03-28 14:26:19.000000000 -0400
6918 @@ -288,7 +288,7 @@ void die(const char *str, struct pt_regs
6919 unsigned long flags = oops_begin();
6922 - if (!user_mode_vm(regs))
6923 + if (!user_mode(regs))
6924 report_bug(regs->ip, regs);
6926 if (__die(str, regs, err))
6927 diff -urNp linux-2.6.29/arch/x86/kernel/efi_32.c linux-2.6.29/arch/x86/kernel/efi_32.c
6928 --- linux-2.6.29/arch/x86/kernel/efi_32.c 2009-03-23 19:12:14.000000000 -0400
6929 +++ linux-2.6.29/arch/x86/kernel/efi_32.c 2009-03-28 14:26:19.000000000 -0400
6933 static unsigned long efi_rt_eflags;
6934 -static pgd_t efi_bak_pg_dir_pointer[2];
6935 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
6937 -void efi_call_phys_prelog(void)
6938 +void __init efi_call_phys_prelog(void)
6940 - unsigned long cr4;
6941 - unsigned long temp;
6942 struct desc_ptr gdt_descr;
6944 local_irq_save(efi_rt_eflags);
6947 - * If I don't have PAE, I should just duplicate two entries in page
6948 - * directory. If I have PAE, I just need to duplicate one entry in
6951 - cr4 = read_cr4_safe();
6953 - if (cr4 & X86_CR4_PAE) {
6954 - efi_bak_pg_dir_pointer[0].pgd =
6955 - swapper_pg_dir[pgd_index(0)].pgd;
6956 - swapper_pg_dir[0].pgd =
6957 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
6959 - efi_bak_pg_dir_pointer[0].pgd =
6960 - swapper_pg_dir[pgd_index(0)].pgd;
6961 - efi_bak_pg_dir_pointer[1].pgd =
6962 - swapper_pg_dir[pgd_index(0x400000)].pgd;
6963 - swapper_pg_dir[pgd_index(0)].pgd =
6964 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
6965 - temp = PAGE_OFFSET + 0x400000;
6966 - swapper_pg_dir[pgd_index(0x400000)].pgd =
6967 - swapper_pg_dir[pgd_index(temp)].pgd;
6969 + clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
6970 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6971 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
6974 * After the lock is released, the original page table is restored.
6978 - gdt_descr.address = __pa(get_cpu_gdt_table(0));
6979 + gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
6980 gdt_descr.size = GDT_SIZE - 1;
6981 load_gdt(&gdt_descr);
6984 -void efi_call_phys_epilog(void)
6985 +void __init efi_call_phys_epilog(void)
6987 - unsigned long cr4;
6988 struct desc_ptr gdt_descr;
6990 - gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
6991 + gdt_descr.address = get_cpu_gdt_table(0);
6992 gdt_descr.size = GDT_SIZE - 1;
6993 load_gdt(&gdt_descr);
6995 - cr4 = read_cr4_safe();
6997 - if (cr4 & X86_CR4_PAE) {
6998 - swapper_pg_dir[pgd_index(0)].pgd =
6999 - efi_bak_pg_dir_pointer[0].pgd;
7001 - swapper_pg_dir[pgd_index(0)].pgd =
7002 - efi_bak_pg_dir_pointer[0].pgd;
7003 - swapper_pg_dir[pgd_index(0x400000)].pgd =
7004 - efi_bak_pg_dir_pointer[1].pgd;
7006 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
7009 * After the lock is released, the original page table is restored.
7010 diff -urNp linux-2.6.29/arch/x86/kernel/efi_stub_32.S linux-2.6.29/arch/x86/kernel/efi_stub_32.S
7011 --- linux-2.6.29/arch/x86/kernel/efi_stub_32.S 2009-03-23 19:12:14.000000000 -0400
7012 +++ linux-2.6.29/arch/x86/kernel/efi_stub_32.S 2009-03-28 14:26:19.000000000 -0400
7016 #include <linux/linkage.h>
7017 +#include <linux/init.h>
7018 #include <asm/page.h>
7022 * service functions will comply with gcc calling convention, too.
7027 ENTRY(efi_call_phys)
7029 * 0. The function can only be called in Linux kernel. So CS has been
7030 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
7031 * The mapping of lower virtual memory has been created in prelog and
7035 - subl $__PAGE_OFFSET, %edx
7037 + jmp 1f-__PAGE_OFFSET
7041 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
7042 * parameter 2, ..., param n. To make things easy, we save the return
7043 * address of efi_call_phys in a global variable.
7046 - movl %edx, saved_return_addr
7047 - /* get the function pointer into ECX*/
7049 - movl %ecx, efi_rt_function_ptr
7051 - subl $__PAGE_OFFSET, %edx
7053 + popl (saved_return_addr)
7054 + popl (efi_rt_function_ptr)
7057 * 3. Clear PG bit in %CR0.
7058 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
7060 * 5. Call the physical function.
7063 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
7067 * 6. After EFI runtime service returns, control will return to
7068 * following instruction. We'd better readjust stack pointer first.
7069 @@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
7071 orl $0x80000000, %edx
7077 * 8. Now restore the virtual mode from flat mode by
7078 * adding EIP with PAGE_OFFSET.
7082 + jmp 1f+__PAGE_OFFSET
7086 * 9. Balance the stack. And because EAX contain the return value,
7087 * we'd better not clobber it.
7089 - leal efi_rt_function_ptr, %edx
7092 + pushl (efi_rt_function_ptr)
7095 - * 10. Push the saved return address onto the stack and return.
7096 + * 10. Return to the saved return address.
7098 - leal saved_return_addr, %edx
7102 + jmpl *(saved_return_addr)
7109 efi_rt_function_ptr:
7110 diff -urNp linux-2.6.29/arch/x86/kernel/entry_32.S linux-2.6.29/arch/x86/kernel/entry_32.S
7111 --- linux-2.6.29/arch/x86/kernel/entry_32.S 2009-03-23 19:12:14.000000000 -0400
7112 +++ linux-2.6.29/arch/x86/kernel/entry_32.S 2009-03-28 14:26:19.000000000 -0400
7114 #define resume_userspace_sig resume_userspace
7118 +#define __SAVE_ALL(_DS) \
7121 CFI_ADJUST_CFA_OFFSET 4;\
7122 @@ -133,12 +133,26 @@
7124 CFI_ADJUST_CFA_OFFSET 4;\
7125 CFI_REL_OFFSET ebx, 0;\
7126 - movl $(__USER_DS), %edx; \
7127 + movl $(_DS), %edx; \
7130 movl $(__KERNEL_PERCPU), %edx; \
7133 +#ifdef CONFIG_PAX_KERNEXEC
7135 + __SAVE_ALL(__KERNEL_DS); \
7136 + GET_CR0_INTO_EDX; \
7137 + movl %edx, %esi; \
7138 + orl $X86_CR0_WP, %edx; \
7139 + xorl %edx, %esi; \
7141 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
7142 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
7144 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
7147 #define RESTORE_INT_REGS \
7149 CFI_ADJUST_CFA_OFFSET -4;\
7150 @@ -229,6 +243,11 @@ ENTRY(ret_from_fork)
7151 CFI_ADJUST_CFA_OFFSET 4
7153 CFI_ADJUST_CFA_OFFSET -4
7155 +#ifdef CONFIG_PAX_KERNEXEC
7162 @@ -252,7 +271,17 @@ check_userspace:
7163 movb PT_CS(%esp), %al
7164 andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
7165 cmpl $USER_RPL, %eax
7167 +#ifdef CONFIG_PAX_KERNEXEC
7168 + jae resume_userspace
7175 jb resume_kernel # not returning to v8086 or userspace
7178 ENTRY(resume_userspace)
7180 @@ -314,10 +343,9 @@ sysenter_past_esp:
7181 /*CFI_REL_OFFSET cs, 0*/
7183 * Push current_thread_info()->sysenter_return to the stack.
7184 - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
7185 - * pushed above; +8 corresponds to copy_thread's esp0 setting.
7187 - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
7188 + GET_THREAD_INFO(%ebp)
7189 + pushl TI_sysenter_return(%ebp)
7190 CFI_ADJUST_CFA_OFFSET 4
7191 CFI_REL_OFFSET eip, 0
7193 @@ -330,9 +358,19 @@ sysenter_past_esp:
7194 * Load the potential sixth argument from user stack.
7195 * Careful about security.
7197 + movl PT_OLDESP(%esp),%ebp
7199 +#ifdef CONFIG_PAX_MEMORY_UDEREF
7200 + mov PT_OLDSS(%esp),%ds
7201 +1: movl %ds:(%ebp),%ebp
7205 cmpl $__PAGE_OFFSET-3,%ebp
7210 movl %ebp,PT_EBP(%esp)
7211 .section __ex_table,"a"
7213 @@ -356,12 +394,23 @@ sysenter_do_call:
7214 testw $_TIF_ALLWORK_MASK, %cx
7218 +#ifdef CONFIG_PAX_RANDKSTACK
7220 + CFI_ADJUST_CFA_OFFSET 4
7221 + call pax_randomize_kstack
7223 + CFI_ADJUST_CFA_OFFSET -4
7226 /* if something modifies registers it must also disable sysexit */
7227 movl PT_EIP(%esp), %edx
7228 movl PT_OLDESP(%esp), %ecx
7231 1: mov PT_FS(%esp), %fs
7232 +2: mov PT_DS(%esp), %ds
7233 +3: mov PT_ES(%esp), %es
7234 ENABLE_INTERRUPTS_SYSEXIT
7236 #ifdef CONFIG_AUDITSYSCALL
7237 @@ -404,11 +453,17 @@ sysexit_audit:
7240 .pushsection .fixup,"ax"
7241 -2: movl $0,PT_FS(%esp)
7242 +4: movl $0,PT_FS(%esp)
7244 +5: movl $0,PT_DS(%esp)
7246 +6: movl $0,PT_ES(%esp)
7248 .section __ex_table,"a"
7255 ENDPROC(ia32_sysenter_target)
7257 @@ -438,6 +493,10 @@ syscall_exit:
7258 testw $_TIF_ALLWORK_MASK, %cx # current->work
7259 jne syscall_exit_work
7261 +#ifdef CONFIG_PAX_RANDKSTACK
7262 + call pax_randomize_kstack
7266 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
7267 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
7268 @@ -531,25 +590,19 @@ work_resched:
7270 work_notifysig: # deal with pending signals and
7271 # notify-resume requests
7274 testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
7276 - jne work_notifysig_v86 # returning to kernel-space or
7277 + jz 1f # returning to kernel-space or
7280 - call do_notify_resume
7281 - jmp resume_userspace_sig
7284 -work_notifysig_v86:
7285 pushl %ecx # save ti_flags for do_notify_resume
7286 CFI_ADJUST_CFA_OFFSET 4
7287 call save_v86_state # %eax contains pt_regs pointer
7289 CFI_ADJUST_CFA_OFFSET -4
7296 call do_notify_resume
7297 @@ -584,6 +637,10 @@ END(syscall_exit_work)
7299 RING0_INT_FRAME # can't unwind into user space anyway
7301 +#ifdef CONFIG_PAX_MEMORY_UDEREF
7305 GET_THREAD_INFO(%ebp)
7306 movl $-EFAULT,PT_EAX(%esp)
7307 jmp resume_userspace
7308 @@ -595,17 +652,24 @@ syscall_badsys:
7312 -#define FIXUP_ESPFIX_STACK \
7313 - /* since we are on a wrong stack, we cant make it a C code :( */ \
7314 - PER_CPU(gdt_page, %ebx); \
7315 - GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
7316 - addl %esp, %eax; \
7317 - pushl $__KERNEL_DS; \
7318 - CFI_ADJUST_CFA_OFFSET 4; \
7320 - CFI_ADJUST_CFA_OFFSET 4; \
7321 - lss (%esp), %esp; \
7322 +.macro FIXUP_ESPFIX_STACK
7323 + /* since we are on a wrong stack, we cant make it a C code :( */
7325 + movl PER_CPU_VAR(cpu_number), %ebx;
7326 + shll $PAGE_SHIFT_asm, %ebx;
7327 + addl $cpu_gdt_table, %ebx;
7329 + movl $cpu_gdt_table, %ebx;
7331 + GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
7333 + pushl $__KERNEL_DS;
7334 + CFI_ADJUST_CFA_OFFSET 4;
7336 + CFI_ADJUST_CFA_OFFSET 4;
7338 CFI_ADJUST_CFA_OFFSET -8;
7340 #define UNWIND_ESPFIX_STACK \
7342 /* see if on espfix stack */ \
7343 @@ -1052,7 +1116,6 @@ return_to_handler:
7347 -.section .rodata,"a"
7348 #include "syscall_table_32.S"
7350 syscall_table_size=(.-sys_call_table)
7351 @@ -1106,12 +1169,21 @@ error_code:
7353 CFI_ADJUST_CFA_OFFSET -4
7354 /*CFI_REGISTER es, ecx*/
7356 +#ifdef CONFIG_PAX_KERNEXEC
7359 + orl $X86_CR0_WP, %edx
7364 movl PT_FS(%esp), %edi # get the function address
7365 movl PT_ORIG_EAX(%esp), %edx # get the error code
7366 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
7367 mov %ecx, PT_FS(%esp)
7368 /*CFI_REL_OFFSET fs, ES*/
7369 - movl $(__USER_DS), %ecx
7370 + movl $(__KERNEL_DS), %ecx
7374 @@ -1206,6 +1278,13 @@ nmi_stack_correct:
7375 xorl %edx,%edx # zero error code
7376 movl %esp,%eax # pt_regs pointer
7379 +#ifdef CONFIG_PAX_KERNEXEC
7385 jmp restore_nocheck_notrace
7388 @@ -1246,6 +1325,13 @@ nmi_espfix_stack:
7389 FIXUP_ESPFIX_STACK # %eax == %esp
7390 xorl %edx,%edx # zero error code
7393 +#ifdef CONFIG_PAX_KERNEXEC
7400 lss 12+4(%esp), %esp # back to espfix stack
7401 CFI_ADJUST_CFA_OFFSET -24
7402 diff -urNp linux-2.6.29/arch/x86/kernel/entry_64.S linux-2.6.29/arch/x86/kernel/entry_64.S
7403 --- linux-2.6.29/arch/x86/kernel/entry_64.S 2009-03-23 19:12:14.000000000 -0400
7404 +++ linux-2.6.29/arch/x86/kernel/entry_64.S 2009-03-28 14:26:19.000000000 -0400
7405 @@ -1073,10 +1073,11 @@ ENTRY(\sym)
7407 movq %rsp,%rdi /* pt_regs pointer */
7408 xorl %esi,%esi /* no error code */
7409 - movq %gs:pda_data_offset, %rbp
7410 - subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
7411 + imul $TSS_size, %gs:pda_cpunumber, %ebp
7412 + lea init_tss(%rbp), %rbp
7413 + subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
7415 - addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
7416 + addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
7417 jmp paranoid_exit /* %ebx: no swapgs flag */
7420 diff -urNp linux-2.6.29/arch/x86/kernel/ftrace.c linux-2.6.29/arch/x86/kernel/ftrace.c
7421 --- linux-2.6.29/arch/x86/kernel/ftrace.c 2009-03-23 19:12:14.000000000 -0400
7422 +++ linux-2.6.29/arch/x86/kernel/ftrace.c 2009-03-28 14:26:19.000000000 -0400
7423 @@ -250,9 +250,9 @@ int ftrace_update_ftrace_func(ftrace_fun
7424 unsigned char old[MCOUNT_INSN_SIZE], *new;
7427 - memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
7428 + memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
7429 new = ftrace_call_replace(ip, (unsigned long)func);
7430 - ret = ftrace_modify_code(ip, old, new);
7431 + ret = ftrace_modify_code(ktla_ktva(ip), old, new);
7435 diff -urNp linux-2.6.29/arch/x86/kernel/head32.c linux-2.6.29/arch/x86/kernel/head32.c
7436 --- linux-2.6.29/arch/x86/kernel/head32.c 2009-03-23 19:12:14.000000000 -0400
7437 +++ linux-2.6.29/arch/x86/kernel/head32.c 2009-03-28 14:26:19.000000000 -0400
7439 #include <asm/e820.h>
7440 #include <asm/bios_ebda.h>
7441 #include <asm/trampoline.h>
7442 +#include <asm/boot.h>
7444 void __init i386_start_kernel(void)
7446 reserve_trampoline_memory();
7448 - reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
7449 + reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&_end), "TEXT DATA BSS");
7451 #ifdef CONFIG_BLK_DEV_INITRD
7452 /* Reserve INITRD */
7453 diff -urNp linux-2.6.29/arch/x86/kernel/head_32.S linux-2.6.29/arch/x86/kernel/head_32.S
7454 --- linux-2.6.29/arch/x86/kernel/head_32.S 2009-03-23 19:12:14.000000000 -0400
7455 +++ linux-2.6.29/arch/x86/kernel/head_32.S 2009-03-28 14:26:19.000000000 -0400
7457 #include <asm/asm-offsets.h>
7458 #include <asm/setup.h>
7459 #include <asm/processor-flags.h>
7460 +#include <asm/msr-index.h>
7462 /* Physical address */
7463 #define pa(X) ((X) - __PAGE_OFFSET)
7464 @@ -64,17 +65,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
7465 LOW_PAGES = LOW_PAGES + 0x1000000
7468 -#if PTRS_PER_PMD > 1
7469 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
7471 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
7473 +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
7474 BOOTBITMAP_SIZE = LOW_PAGES / 8
7477 INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
7480 + * Real beginning of normal "text" segment
7485 +.section .text.startup,"ax",@progbits
7486 + ljmp $(__BOOT_CS),$phys_startup_32
7489 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
7490 * %esi points to the real-mode code as a 32-bit pointer.
7491 * CS and DS must be 4 GB flat segments, but we don't depend on
7492 @@ -82,6 +88,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
7495 .section .text.head,"ax",@progbits
7497 +#ifdef CONFIG_PAX_KERNEXEC
7498 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
7503 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
7504 us to not reload segments */
7505 @@ -99,6 +111,56 @@ ENTRY(startup_32)
7509 + movl $pa(cpu_gdt_table),%edi
7510 + movl $__per_cpu_start,%eax
7511 + movw %ax,__KERNEL_PERCPU + 2(%edi)
7513 + movb %al,__KERNEL_PERCPU + 4(%edi)
7514 + movb %ah,__KERNEL_PERCPU + 7(%edi)
7515 + movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
7516 + subl $__per_cpu_start,%eax
7517 + movw %ax,__KERNEL_PERCPU + 0(%edi)
7519 +#ifdef CONFIG_PAX_MEMORY_UDEREF
7520 + /* check for VMware */
7521 + movl $0x564d5868,%eax
7526 + cmpl $0x564d5868,%ebx
7529 + movl $NR_CPUS,%ecx
7530 + movl $pa(cpu_gdt_table),%edi
7532 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
7533 + addl $PAGE_SIZE_asm,%edi
7538 +#ifdef CONFIG_PAX_KERNEXEC
7539 + movl $pa(boot_gdt),%edi
7540 + movl $KERNEL_TEXT_OFFSET,%eax
7541 + movw %ax,__BOOT_CS + 2(%edi)
7543 + movb %al,__BOOT_CS + 4(%edi)
7544 + movb %ah,__BOOT_CS + 7(%edi)
7547 + movl $NR_CPUS,%ecx
7548 + movl $pa(cpu_gdt_table),%edi
7550 + movw %ax,__KERNEL_CS + 2(%edi)
7552 + movb %al,__KERNEL_CS + 4(%edi)
7553 + movb %ah,__KERNEL_CS + 7(%edi)
7555 + addl $PAGE_SIZE_asm,%edi
7560 * Clear BSS first so that there are no surprises...
7562 @@ -142,9 +204,7 @@ ENTRY(startup_32)
7563 cmpl $num_subarch_entries, %eax
7566 - movl pa(subarch_entries)(,%eax,4), %eax
7567 - subl $__PAGE_OFFSET, %eax
7569 + jmp *pa(subarch_entries)(,%eax,4)
7573 @@ -156,9 +216,9 @@ WEAK(xen_entry)
7577 - .long default_entry /* normal x86/PC */
7578 - .long lguest_entry /* lguest hypervisor */
7579 - .long xen_entry /* Xen hypervisor */
7580 + .long pa(default_entry) /* normal x86/PC */
7581 + .long pa(lguest_entry) /* lguest hypervisor */
7582 + .long pa(xen_entry) /* Xen hypervisor */
7583 num_subarch_entries = (. - subarch_entries) / 4
7585 #endif /* CONFIG_PARAVIRT */
7586 @@ -220,8 +280,7 @@ default_entry:
7587 movl %eax, pa(max_pfn_mapped)
7589 /* Do early initialization of the fixmap area */
7590 - movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
7591 - movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
7592 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
7595 page_pde_offset = (__PAGE_OFFSET >> 20);
7596 @@ -253,8 +312,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
7597 movl %eax, pa(max_pfn_mapped)
7599 /* Do early initialization of the fixmap area */
7600 - movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
7601 - movl %eax,pa(swapper_pg_dir+0xffc)
7602 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_dir+0xffc)
7606 @@ -318,13 +376,16 @@ ENTRY(startup_32_smp)
7609 /* Setup EFER (Extended Feature Enable Register) */
7610 - movl $0xc0000080, %ecx
7611 + movl $MSR_EFER, %ecx
7615 /* Make changes effective */
7618 + btsl $_PAGE_BIT_NX-32,pa(__supported_pte_mask+4)
7619 + movl $1,pa(nx_enabled)
7624 @@ -350,9 +411,7 @@ ENTRY(startup_32_smp)
7628 - jz 1f /* Initial CPU cleans BSS */
7631 + jnz checkCPUtype /* Initial CPU cleans BSS */
7632 #endif /* CONFIG_SMP */
7635 @@ -429,12 +488,12 @@ is386: movl $2,%ecx # set MP
7636 ljmp $(__KERNEL_CS),$1f
7637 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
7638 movl %eax,%ss # after changing gdt.
7639 - movl %eax,%fs # gets reset once there's real percpu
7641 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
7645 + movl $(__KERNEL_PERCPU), %eax
7646 + movl %eax,%fs # set this cpu's percpu
7648 xorl %eax,%eax # Clear GS and LDT
7651 @@ -444,12 +503,6 @@ is386: movl $2,%ecx # set MP
7655 - cmpb $0,%cl # the first CPU calls start_kernel
7657 - movl $(__KERNEL_PERCPU), %eax
7658 - movl %eax,%fs # set this cpu's percpu
7659 - movl (stack_start), %esp
7661 #endif /* CONFIG_SMP */
7664 @@ -535,15 +588,15 @@ early_page_fault:
7669 #ifdef CONFIG_PRINTK
7670 + cmpl $2,%ss:early_recursion_flag
7672 + incl %ss:early_recursion_flag
7675 movl $(__KERNEL_DS),%eax
7678 - cmpl $2,early_recursion_flag
7680 - incl early_recursion_flag
7683 pushl %edx /* trapno */
7684 @@ -553,8 +606,8 @@ early_fault:
7694 @@ -562,8 +615,11 @@ hlt_loop:
7695 /* This is the default interrupt "handler" :-) */
7699 #ifdef CONFIG_PRINTK
7700 + cmpl $2,%ss:early_recursion_flag
7702 + incl %ss:early_recursion_flag
7707 @@ -572,9 +628,6 @@ ignore_int:
7708 movl $(__KERNEL_DS),%eax
7711 - cmpl $2,early_recursion_flag
7713 - incl early_recursion_flag
7717 @@ -599,36 +652,41 @@ ignore_int:
7719 .long i386_start_kernel
7723 - * Real beginning of normal "text" segment
7731 -.section ".bss.page_aligned","wa"
7732 - .align PAGE_SIZE_asm
7733 #ifdef CONFIG_X86_PAE
7734 +.section .swapper_pg_pmd,"a",@progbits
7736 .fill 1024*KPMDS,4,0
7738 +.section .swapper_pg_dir,"a",@progbits
7739 ENTRY(swapper_pg_dir)
7745 +.section .empty_zero_page,"a",@progbits
7746 ENTRY(empty_zero_page)
7750 + * The IDT has to be page-aligned to simplify the Pentium
7751 + * F0 0F bug workaround.. We have a special link segment
7754 +.section .idt,"a",@progbits
7759 * This starts the data section.
7763 #ifdef CONFIG_X86_PAE
7764 -.section ".data.page_aligned","wa"
7765 - /* Page-aligned for the benefit of paravirt? */
7766 - .align PAGE_SIZE_asm
7767 +.section .swapper_pg_dir,"a",@progbits
7768 ENTRY(swapper_pg_dir)
7769 .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
7771 @@ -651,11 +709,12 @@ ENTRY(swapper_pg_dir)
7775 - .long init_thread_union+THREAD_SIZE
7776 + .long init_thread_union+THREAD_SIZE-8
7781 +.section .rodata,"a",@progbits
7782 early_recursion_flag:
7785 @@ -691,7 +750,7 @@ fault_msg:
7786 .word 0 # 32 bit align gdt_desc.address
7789 - .long boot_gdt - __PAGE_OFFSET
7790 + .long pa(boot_gdt)
7792 .word 0 # 32-bit align idt_desc.address
7794 @@ -702,7 +761,7 @@ idt_descr:
7795 .word 0 # 32 bit align gdt_desc.address
7796 ENTRY(early_gdt_descr)
7797 .word GDT_ENTRIES*8-1
7798 - .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
7799 + .long cpu_gdt_table /* Overwritten for secondary CPUs */
7802 * The boot_gdt must mirror the equivalent in setup.S and is
7803 @@ -711,5 +770,59 @@ ENTRY(early_gdt_descr)
7804 .align L1_CACHE_BYTES
7806 .fill GDT_ENTRY_BOOT_CS,8,0
7807 - .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
7808 - .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
7809 + .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
7810 + .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
7812 + .align PAGE_SIZE_asm
7813 +ENTRY(cpu_gdt_table)
7815 + .quad 0x0000000000000000 /* NULL descriptor */
7816 + .quad 0x0000000000000000 /* 0x0b reserved */
7817 + .quad 0x0000000000000000 /* 0x13 reserved */
7818 + .quad 0x0000000000000000 /* 0x1b reserved */
7819 + .quad 0x0000000000000000 /* 0x20 unused */
7820 + .quad 0x0000000000000000 /* 0x28 unused */
7821 + .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
7822 + .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
7823 + .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
7824 + .quad 0x0000000000000000 /* 0x4b reserved */
7825 + .quad 0x0000000000000000 /* 0x53 reserved */
7826 + .quad 0x0000000000000000 /* 0x5b reserved */
7828 + .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
7829 + .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
7830 + .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
7831 + .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
7833 + .quad 0x0000000000000000 /* 0x80 TSS descriptor */
7834 + .quad 0x0000000000000000 /* 0x88 LDT descriptor */
7837 + * Segments used for calling PnP BIOS have byte granularity.
7838 + * The code segments and data segments have fixed 64k limits,
7839 + * the transfer segment sizes are set at run time.
7841 + .quad 0x00409b000000ffff /* 0x90 32-bit code */
7842 + .quad 0x00009b000000ffff /* 0x98 16-bit code */
7843 + .quad 0x000093000000ffff /* 0xa0 16-bit data */
7844 + .quad 0x0000930000000000 /* 0xa8 16-bit data */
7845 + .quad 0x0000930000000000 /* 0xb0 16-bit data */
7848 + * The APM segments have byte granularity and their bases
7849 + * are set at run time. All have 64k limits.
7851 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
7852 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
7853 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
7855 + .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
7856 + .quad 0x0040930000000000 /* 0xd8 - PERCPU */
7857 + .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
7858 + .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
7859 + .quad 0x0000000000000000 /* 0xf0 - unused */
7860 + .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
7862 + /* Be sure this is zeroed to avoid false validations in Xen */
7863 + .fill PAGE_SIZE_asm - GDT_SIZE,1,0
7865 diff -urNp linux-2.6.29/arch/x86/kernel/head64.c linux-2.6.29/arch/x86/kernel/head64.c
7866 --- linux-2.6.29/arch/x86/kernel/head64.c 2009-03-23 19:12:14.000000000 -0400
7867 +++ linux-2.6.29/arch/x86/kernel/head64.c 2009-03-28 14:26:19.000000000 -0400
7868 @@ -94,6 +94,8 @@ void __init x86_64_start_kernel(char * r
7869 /* clear bss before set_intr_gate with early_idt_handler */
7872 + x86_64_init_pda();
7874 /* Make NULL pointers segfault */
7875 zap_identity_mappings();
7877 @@ -112,8 +114,6 @@ void __init x86_64_start_kernel(char * r
7878 if (console_loglevel == 10)
7879 early_printk("Kernel alive\n");
7881 - x86_64_init_pda();
7883 x86_64_start_reservations(real_mode_data);
7886 diff -urNp linux-2.6.29/arch/x86/kernel/head_64.S linux-2.6.29/arch/x86/kernel/head_64.S
7887 --- linux-2.6.29/arch/x86/kernel/head_64.S 2009-03-23 19:12:14.000000000 -0400
7888 +++ linux-2.6.29/arch/x86/kernel/head_64.S 2009-03-28 14:26:19.000000000 -0400
7889 @@ -38,6 +38,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
7890 L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
7891 L4_START_KERNEL = pgd_index(__START_KERNEL_map)
7892 L3_START_KERNEL = pud_index(__START_KERNEL_map)
7893 +L4_VMALLOC_START = pgd_index(VMALLOC_START)
7894 +L3_VMALLOC_START = pud_index(VMALLOC_START)
7895 +L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
7896 +L3_VMEMMAP_START = pud_index(VMEMMAP_START)
7900 @@ -85,35 +89,22 @@ startup_64:
7902 addq %rbp, init_level4_pgt + 0(%rip)
7903 addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
7904 + addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
7905 + addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
7906 addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
7908 addq %rbp, level3_ident_pgt + 0(%rip)
7909 + addq %rbp, level3_ident_pgt + 8(%rip)
7910 + addq %rbp, level3_ident_pgt + 16(%rip)
7911 + addq %rbp, level3_ident_pgt + 24(%rip)
7913 - addq %rbp, level3_kernel_pgt + (510*8)(%rip)
7914 - addq %rbp, level3_kernel_pgt + (511*8)(%rip)
7915 + addq %rbp, level3_vmemmap_pgt + (L3_VMEMMAP_START*8)(%rip)
7917 - addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
7918 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
7919 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
7921 - /* Add an Identity mapping if I am above 1G */
7922 - leaq _text(%rip), %rdi
7923 - andq $PMD_PAGE_MASK, %rdi
7926 - shrq $PUD_SHIFT, %rax
7927 - andq $(PTRS_PER_PUD - 1), %rax
7930 - leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
7931 - leaq level3_ident_pgt(%rip), %rbx
7932 - movq %rdx, 0(%rbx, %rax, 8)
7935 - shrq $PMD_SHIFT, %rax
7936 - andq $(PTRS_PER_PMD - 1), %rax
7937 - leaq __PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx
7938 - leaq level2_spare_pgt(%rip), %rbx
7939 - movq %rdx, 0(%rbx, %rax, 8)
7941 + addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
7942 + addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
7945 * Fixup the kernel text+data virtual addresses. Note that
7946 @@ -187,6 +178,10 @@ ENTRY(secondary_startup_64)
7947 btl $20,%edi /* No Execute supported? */
7949 btsl $_EFER_NX, %eax
7950 + leaq init_level4_pgt(%rip), %rdi
7951 + btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
7952 + btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
7953 + btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
7954 1: wrmsr /* Make changes effective */
7957 @@ -257,16 +252,16 @@ ENTRY(secondary_startup_64)
7960 .quad x86_64_start_kernel
7964 .quad init_thread_union+THREAD_SIZE-8
7971 - .section ".init.text","ax"
7973 #ifdef CONFIG_EARLY_PRINTK
7974 .globl early_idt_handlers
7976 @@ -311,18 +306,23 @@ ENTRY(early_idt_handler)
7977 #endif /* EARLY_PRINTK */
7982 #ifdef CONFIG_EARLY_PRINTK
7984 early_recursion_flag:
7988 + .section .rodata,"a",@progbits
7990 .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
7993 -#endif /* CONFIG_EARLY_PRINTK */
7995 +#endif /* CONFIG_EARLY_PRINTK */
7997 + .section .rodata,"a",@progbits
8000 #define NEXT_PAGE(name) \
8001 @@ -347,13 +347,27 @@ NEXT_PAGE(init_level4_pgt)
8002 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
8003 .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
8004 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
8005 + .org init_level4_pgt + L4_VMALLOC_START*8, 0
8006 + .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
8007 + .org init_level4_pgt + L4_VMEMMAP_START*8, 0
8008 + .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
8009 .org init_level4_pgt + L4_START_KERNEL*8, 0
8010 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
8011 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
8013 NEXT_PAGE(level3_ident_pgt)
8014 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
8016 + .quad level2_ident_pgt + PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
8017 + .quad level2_ident_pgt + 2*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
8018 + .quad level2_ident_pgt + 3*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
8021 +NEXT_PAGE(level3_vmalloc_pgt)
8024 +NEXT_PAGE(level3_vmemmap_pgt)
8025 + .fill L3_VMEMMAP_START,8,0
8026 + .quad level2_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
8028 NEXT_PAGE(level3_kernel_pgt)
8029 .fill L3_START_KERNEL,8,0
8030 @@ -361,20 +375,27 @@ NEXT_PAGE(level3_kernel_pgt)
8031 .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
8032 .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
8034 +NEXT_PAGE(level2_vmemmap_pgt)
8037 NEXT_PAGE(level2_fixmap_pgt)
8039 .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
8040 - /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
8042 + .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
8043 + /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
8046 NEXT_PAGE(level1_fixmap_pgt)
8049 -NEXT_PAGE(level2_ident_pgt)
8050 - /* Since I easily can, map the first 1G.
8051 +NEXT_PAGE(level1_vsyscall_pgt)
8054 + /* Since I easily can, map the first 4G.
8055 * Don't set NX because code runs from these pages.
8057 - PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
8058 +NEXT_PAGE(level2_ident_pgt)
8059 + PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, 4*PTRS_PER_PMD)
8061 NEXT_PAGE(level2_kernel_pgt)
8063 @@ -387,32 +408,48 @@ NEXT_PAGE(level2_kernel_pgt)
8064 * If you want to increase this then increase MODULES_VADDR
8067 - PMDS(0, __PAGE_KERNEL_LARGE_EXEC,
8068 - KERNEL_IMAGE_SIZE/PMD_SIZE)
8070 -NEXT_PAGE(level2_spare_pgt)
8072 + PMDS(0, __PAGE_KERNEL_LARGE_EXEC, KERNEL_IMAGE_SIZE/PMD_SIZE)
8079 +ENTRY(cpu_gdt_table)
8081 + .quad 0x0000000000000000 /* NULL descriptor */
8082 + .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
8083 + .quad 0x00af9b000000ffff /* __KERNEL_CS */
8084 + .quad 0x00cf93000000ffff /* __KERNEL_DS */
8085 + .quad 0x00cffb000000ffff /* __USER32_CS */
8086 + .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
8087 + .quad 0x00affb000000ffff /* __USER_CS */
8088 + .quad 0x0 /* unused */
8089 + .quad 0,0 /* TSS */
8090 + .quad 0,0 /* LDT */
8091 + .quad 0,0,0 /* three TLS descriptors */
8092 + .quad 0x0000f40000000000 /* node/CPU stored in limit */
8093 + /* asm/segment.h:GDT_ENTRIES must match this */
8095 + /* zero the remaining page */
8096 + .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
8100 .globl early_gdt_descr
8102 .word GDT_ENTRIES*8-1
8103 - .quad per_cpu__gdt_page
8104 + .quad cpu_gdt_table
8107 /* This must match the first entry in level2_kernel_pgt */
8108 .quad 0x0000000000000000
8110 #include "../../x86/xen/xen-head.S"
8112 - .section .bss, "aw", @nobits
8114 + .section .rodata,"a",@progbits
8115 .align L1_CACHE_BYTES
8120 .section .bss.page_aligned, "aw", @nobits
8122 diff -urNp linux-2.6.29/arch/x86/kernel/i386_ksyms_32.c linux-2.6.29/arch/x86/kernel/i386_ksyms_32.c
8123 --- linux-2.6.29/arch/x86/kernel/i386_ksyms_32.c 2009-03-23 19:12:14.000000000 -0400
8124 +++ linux-2.6.29/arch/x86/kernel/i386_ksyms_32.c 2009-03-28 14:26:19.000000000 -0400
8126 EXPORT_SYMBOL(mcount);
8129 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
8131 /* Networking helper routines. */
8132 EXPORT_SYMBOL(csum_partial_copy_generic);
8133 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
8134 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
8136 EXPORT_SYMBOL(__get_user_1);
8137 EXPORT_SYMBOL(__get_user_2);
8138 @@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr);
8140 EXPORT_SYMBOL(csum_partial);
8141 EXPORT_SYMBOL(empty_zero_page);
8143 +#ifdef CONFIG_PAX_KERNEXEC
8144 +EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
8146 diff -urNp linux-2.6.29/arch/x86/kernel/init_task.c linux-2.6.29/arch/x86/kernel/init_task.c
8147 --- linux-2.6.29/arch/x86/kernel/init_task.c 2009-03-23 19:12:14.000000000 -0400
8148 +++ linux-2.6.29/arch/x86/kernel/init_task.c 2009-03-28 14:26:19.000000000 -0400
8149 @@ -40,5 +40,5 @@ EXPORT_SYMBOL(init_task);
8150 * section. Since TSS's are completely CPU-local, we want them
8151 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
8153 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
8155 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
8156 +EXPORT_SYMBOL(init_tss);
8157 diff -urNp linux-2.6.29/arch/x86/kernel/ioport.c linux-2.6.29/arch/x86/kernel/ioport.c
8158 --- linux-2.6.29/arch/x86/kernel/ioport.c 2009-03-23 19:12:14.000000000 -0400
8159 +++ linux-2.6.29/arch/x86/kernel/ioport.c 2009-03-28 14:26:19.000000000 -0400
8161 #include <linux/sched.h>
8162 #include <linux/kernel.h>
8163 #include <linux/capability.h>
8164 +#include <linux/security.h>
8165 #include <linux/errno.h>
8166 #include <linux/types.h>
8167 #include <linux/ioport.h>
8168 @@ -41,6 +42,12 @@ asmlinkage long sys_ioperm(unsigned long
8170 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
8172 +#ifdef CONFIG_GRKERNSEC_IO
8174 + gr_handle_ioperm();
8178 if (turn_on && !capable(CAP_SYS_RAWIO))
8181 @@ -67,7 +74,7 @@ asmlinkage long sys_ioperm(unsigned long
8182 * because the ->io_bitmap_max value must match the bitmap
8185 - tss = &per_cpu(init_tss, get_cpu());
8186 + tss = init_tss + get_cpu();
8188 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
8190 @@ -122,8 +129,13 @@ static int do_iopl(unsigned int level, s
8192 /* Trying to gain more privileges? */
8194 +#ifdef CONFIG_GRKERNSEC_IO
8198 if (!capable(CAP_SYS_RAWIO))
8202 regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
8204 diff -urNp linux-2.6.29/arch/x86/kernel/irq_32.c linux-2.6.29/arch/x86/kernel/irq_32.c
8205 --- linux-2.6.29/arch/x86/kernel/irq_32.c 2009-03-23 19:12:14.000000000 -0400
8206 +++ linux-2.6.29/arch/x86/kernel/irq_32.c 2009-03-28 14:26:19.000000000 -0400
8207 @@ -93,7 +93,7 @@ execute_on_irq_stack(int overflow, struc
8210 /* build the stack frame on the IRQ stack */
8211 - isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
8212 + isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
8213 irqctx->tinfo.task = curctx->tinfo.task;
8214 irqctx->tinfo.previous_esp = current_stack_pointer;
8216 @@ -174,7 +174,7 @@ asmlinkage void do_softirq(void)
8217 irqctx->tinfo.previous_esp = current_stack_pointer;
8219 /* build the stack frame on the softirq stack */
8220 - isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
8221 + isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
8223 call_on_stack(__do_softirq, isp);
8225 diff -urNp linux-2.6.29/arch/x86/kernel/kprobes.c linux-2.6.29/arch/x86/kernel/kprobes.c
8226 --- linux-2.6.29/arch/x86/kernel/kprobes.c 2009-03-23 19:12:14.000000000 -0400
8227 +++ linux-2.6.29/arch/x86/kernel/kprobes.c 2009-03-28 14:26:19.000000000 -0400
8228 @@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
8231 } __attribute__((packed)) * jop;
8232 - jop = (struct __arch_jmp_op *)from;
8234 +#ifdef CONFIG_PAX_KERNEXEC
8235 + unsigned long cr0;
8238 + jop = (struct __arch_jmp_op *)(ktla_ktva(from));
8240 +#ifdef CONFIG_PAX_KERNEXEC
8241 + pax_open_kernel(cr0);
8244 jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
8245 jop->op = RELATIVEJUMP_INSTRUCTION;
8247 +#ifdef CONFIG_PAX_KERNEXEC
8248 + pax_close_kernel(cr0);
8254 @@ -345,16 +360,29 @@ static void __kprobes fix_riprel(struct
8256 static void __kprobes arch_copy_kprobe(struct kprobe *p)
8258 - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
8260 +#ifdef CONFIG_PAX_KERNEXEC
8261 + unsigned long cr0;
8264 +#ifdef CONFIG_PAX_KERNEXEC
8265 + pax_open_kernel(cr0);
8268 + memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
8270 +#ifdef CONFIG_PAX_KERNEXEC
8271 + pax_close_kernel(cr0);
8276 - if (can_boost(p->addr))
8277 + if (can_boost(ktla_ktva(p->addr)))
8278 p->ainsn.boostable = 0;
8280 p->ainsn.boostable = -1;
8282 - p->opcode = *p->addr;
8283 + p->opcode = *(ktla_ktva(p->addr));
8286 int __kprobes arch_prepare_kprobe(struct kprobe *p)
8287 @@ -432,7 +460,7 @@ static void __kprobes prepare_singlestep
8288 if (p->opcode == BREAKPOINT_INSTRUCTION)
8289 regs->ip = (unsigned long)p->addr;
8291 - regs->ip = (unsigned long)p->ainsn.insn;
8292 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
8295 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
8296 @@ -453,7 +481,7 @@ static void __kprobes setup_singlestep(s
8297 if (p->ainsn.boostable == 1 && !p->post_handler) {
8298 /* Boost up -- we can execute copied instructions directly */
8299 reset_current_kprobe();
8300 - regs->ip = (unsigned long)p->ainsn.insn;
8301 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
8302 preempt_enable_no_resched();
8305 @@ -523,7 +551,7 @@ static int __kprobes kprobe_handler(stru
8306 struct kprobe_ctlblk *kcb;
8308 addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
8309 - if (*addr != BREAKPOINT_INSTRUCTION) {
8310 + if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
8312 * The breakpoint instruction was removed right
8313 * after we hit it. Another cpu has removed
8314 @@ -774,7 +802,7 @@ static void __kprobes resume_execution(s
8315 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
8317 unsigned long *tos = stack_addr(regs);
8318 - unsigned long copy_ip = (unsigned long)p->ainsn.insn;
8319 + unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
8320 unsigned long orig_ip = (unsigned long)p->addr;
8321 kprobe_opcode_t *insn = p->ainsn.insn;
8323 @@ -957,7 +985,7 @@ int __kprobes kprobe_exceptions_notify(s
8324 struct die_args *args = data;
8325 int ret = NOTIFY_DONE;
8327 - if (args->regs && user_mode_vm(args->regs))
8328 + if (args->regs && user_mode(args->regs))
8332 diff -urNp linux-2.6.29/arch/x86/kernel/ldt.c linux-2.6.29/arch/x86/kernel/ldt.c
8333 --- linux-2.6.29/arch/x86/kernel/ldt.c 2009-03-23 19:12:14.000000000 -0400
8334 +++ linux-2.6.29/arch/x86/kernel/ldt.c 2009-03-28 14:26:19.000000000 -0400
8335 @@ -66,13 +66,13 @@ static int alloc_ldt(mm_context_t *pc, i
8340 + load_LDT_nolock(pc);
8341 if (!cpus_equal(current->mm->cpu_vm_mask,
8342 cpumask_of_cpu(smp_processor_id())))
8343 smp_call_function(flush_ldt, current->mm, 1);
8347 + load_LDT_nolock(pc);
8351 @@ -94,7 +94,7 @@ static inline int copy_ldt(mm_context_t
8354 for (i = 0; i < old->size; i++)
8355 - write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
8356 + write_ldt_entry(new->ldt, i, old->ldt + i);
8360 @@ -115,6 +115,24 @@ int init_new_context(struct task_struct
8361 retval = copy_ldt(&mm->context, &old_mm->context);
8362 mutex_unlock(&old_mm->context.lock);
8365 + if (tsk == current) {
8366 + mm->context.vdso = ~0UL;
8368 +#ifdef CONFIG_X86_32
8369 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8370 + mm->context.user_cs_base = 0UL;
8371 + mm->context.user_cs_limit = ~0UL;
8373 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
8374 + cpus_clear(mm->context.cpu_user_cs_mask);
8385 @@ -229,6 +247,13 @@ static int write_ldt(void __user *ptr, u
8389 +#ifdef CONFIG_PAX_SEGMEXEC
8390 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
8396 fill_ldt(&ldt, &ldt_info);
8399 diff -urNp linux-2.6.29/arch/x86/kernel/machine_kexec_32.c linux-2.6.29/arch/x86/kernel/machine_kexec_32.c
8400 --- linux-2.6.29/arch/x86/kernel/machine_kexec_32.c 2009-03-23 19:12:14.000000000 -0400
8401 +++ linux-2.6.29/arch/x86/kernel/machine_kexec_32.c 2009-03-28 14:26:19.000000000 -0400
8403 #include <asm/system.h>
8404 #include <asm/cacheflush.h>
8406 -static void set_idt(void *newidt, __u16 limit)
8407 +static void set_idt(struct desc_struct *newidt, __u16 limit)
8409 struct desc_ptr curidt;
8411 @@ -38,7 +38,7 @@ static void set_idt(void *newidt, __u16
8415 -static void set_gdt(void *newgdt, __u16 limit)
8416 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
8418 struct desc_ptr curgdt;
8420 @@ -216,7 +216,7 @@ void machine_kexec(struct kimage *image)
8423 control_page = page_address(image->control_code_page);
8424 - memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
8425 + memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
8427 relocate_kernel_ptr = control_page;
8428 page_list[PA_CONTROL_PAGE] = __pa(control_page);
8429 diff -urNp linux-2.6.29/arch/x86/kernel/module_32.c linux-2.6.29/arch/x86/kernel/module_32.c
8430 --- linux-2.6.29/arch/x86/kernel/module_32.c 2009-03-23 19:12:14.000000000 -0400
8431 +++ linux-2.6.29/arch/x86/kernel/module_32.c 2009-03-28 14:26:19.000000000 -0400
8433 #include <linux/kernel.h>
8434 #include <linux/bug.h>
8436 +#include <asm/desc.h>
8437 +#include <asm/pgtable.h>
8440 #define DEBUGP printk
8442 @@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
8447 +#ifdef CONFIG_PAX_KERNEXEC
8448 + return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
8450 return vmalloc_exec(size);
8455 +#ifdef CONFIG_PAX_KERNEXEC
8456 +void *module_alloc_exec(unsigned long size)
8458 + struct vm_struct *area;
8463 + area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
8465 + return area->addr;
8469 +EXPORT_SYMBOL(module_alloc_exec);
8472 /* Free memory returned from module_alloc */
8473 void module_free(struct module *mod, void *module_region)
8474 @@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
8478 +#ifdef CONFIG_PAX_KERNEXEC
8479 +void module_free_exec(struct module *mod, void *module_region)
8481 + struct vm_struct **p, *tmp;
8483 + if (!module_region)
8486 + if ((PAGE_SIZE-1) & (unsigned long)module_region) {
8487 + printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
8492 + write_lock(&vmlist_lock);
8493 + for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
8494 + if (tmp->addr == module_region)
8498 + unsigned long cr0;
8500 + pax_open_kernel(cr0);
8501 + memset(tmp->addr, 0xCC, tmp->size);
8502 + pax_close_kernel(cr0);
8507 + write_unlock(&vmlist_lock);
8510 + printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
8517 /* We don't need anything special. */
8518 int module_frob_arch_sections(Elf_Ehdr *hdr,
8520 @@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
8522 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
8524 - uint32_t *location;
8525 + uint32_t *plocation, location;
8527 +#ifdef CONFIG_PAX_KERNEXEC
8528 + unsigned long cr0;
8531 DEBUGP("Applying relocate section %u to %u\n", relsec,
8532 sechdrs[relsec].sh_info);
8533 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
8534 /* This is where to make the change */
8535 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
8536 - + rel[i].r_offset;
8537 + plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
8538 + location = (uint32_t)plocation;
8539 + if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
8540 + plocation = ktla_ktva((void *)plocation);
8541 /* This is the symbol it is referring to. Note that all
8542 undefined symbols have been resolved. */
8543 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
8544 @@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
8546 switch (ELF32_R_TYPE(rel[i].r_info)) {
8549 +#ifdef CONFIG_PAX_KERNEXEC
8550 + pax_open_kernel(cr0);
8553 /* We add the value into the location given */
8554 - *location += sym->st_value;
8555 + *plocation += sym->st_value;
8557 +#ifdef CONFIG_PAX_KERNEXEC
8558 + pax_close_kernel(cr0);
8564 +#ifdef CONFIG_PAX_KERNEXEC
8565 + pax_open_kernel(cr0);
8568 /* Add the value, subtract its postition */
8569 - *location += sym->st_value - (uint32_t)location;
8570 + *plocation += sym->st_value - location;
8572 +#ifdef CONFIG_PAX_KERNEXEC
8573 + pax_close_kernel(cr0);
8578 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
8579 diff -urNp linux-2.6.29/arch/x86/kernel/module_64.c linux-2.6.29/arch/x86/kernel/module_64.c
8580 --- linux-2.6.29/arch/x86/kernel/module_64.c 2009-03-23 19:12:14.000000000 -0400
8581 +++ linux-2.6.29/arch/x86/kernel/module_64.c 2009-03-28 14:26:19.000000000 -0400
8582 @@ -40,7 +40,7 @@ void module_free(struct module *mod, voi
8586 -void *module_alloc(unsigned long size)
8587 +static void *__module_alloc(unsigned long size, pgprot_t prot)
8589 struct vm_struct *area;
8591 @@ -54,8 +54,31 @@ void *module_alloc(unsigned long size)
8595 - return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
8596 + return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
8599 +#ifdef CONFIG_PAX_KERNEXEC
8600 +void *module_alloc(unsigned long size)
8602 + return __module_alloc(size, PAGE_KERNEL);
8605 +void module_free_exec(struct module *mod, void *module_region)
8607 + module_free(mod, module_region);
8610 +void *module_alloc_exec(unsigned long size)
8612 + return __module_alloc(size, PAGE_KERNEL_RX);
8615 +void *module_alloc(unsigned long size)
8617 + return __module_alloc(size, PAGE_KERNEL_EXEC);
8623 /* We don't need anything special. */
8624 @@ -77,7 +100,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
8625 Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
8631 +#ifdef CONFIG_PAX_KERNEXEC
8632 + unsigned long cr0;
8635 DEBUGP("Applying relocate section %u to %u\n", relsec,
8636 sechdrs[relsec].sh_info);
8637 @@ -101,21 +128,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
8642 +#ifdef CONFIG_PAX_KERNEXEC
8643 + pax_open_kernel(cr0);
8648 +#ifdef CONFIG_PAX_KERNEXEC
8649 + pax_close_kernel(cr0);
8655 +#ifdef CONFIG_PAX_KERNEXEC
8656 + pax_open_kernel(cr0);
8661 +#ifdef CONFIG_PAX_KERNEXEC
8662 + pax_close_kernel(cr0);
8665 if (val != *(u32 *)loc)
8670 +#ifdef CONFIG_PAX_KERNEXEC
8671 + pax_open_kernel(cr0);
8676 +#ifdef CONFIG_PAX_KERNEXEC
8677 + pax_close_kernel(cr0);
8680 if ((s64)val != *(s32 *)loc)
8686 +#ifdef CONFIG_PAX_KERNEXEC
8687 + pax_open_kernel(cr0);
8692 +#ifdef CONFIG_PAX_KERNEXEC
8693 + pax_close_kernel(cr0);
8697 if ((s64)val != *(s32 *)loc)
8699 diff -urNp linux-2.6.29/arch/x86/kernel/paravirt.c linux-2.6.29/arch/x86/kernel/paravirt.c
8700 --- linux-2.6.29/arch/x86/kernel/paravirt.c 2009-03-23 19:12:14.000000000 -0400
8701 +++ linux-2.6.29/arch/x86/kernel/paravirt.c 2009-03-28 14:26:19.000000000 -0400
8702 @@ -44,7 +44,7 @@ void _paravirt_nop(void)
8706 -static void __init default_banner(void)
8707 +static void default_banner(void)
8709 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
8711 @@ -164,7 +164,7 @@ unsigned paravirt_patch_insns(void *insn
8712 if (insn_len > len || start == NULL)
8715 - memcpy(insnbuf, start, insn_len);
8716 + memcpy(insnbuf, ktla_ktva(start), insn_len);
8720 @@ -294,21 +294,21 @@ void arch_flush_lazy_cpu_mode(void)
8724 -struct pv_info pv_info = {
8725 +struct pv_info pv_info __read_only = {
8726 .name = "bare hardware",
8727 .paravirt_enabled = 0,
8729 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
8732 -struct pv_init_ops pv_init_ops = {
8733 +struct pv_init_ops pv_init_ops __read_only = {
8734 .patch = native_patch,
8735 .banner = default_banner,
8736 .arch_setup = paravirt_nop,
8737 .memory_setup = machine_specific_memory_setup,
8740 -struct pv_time_ops pv_time_ops = {
8741 +struct pv_time_ops pv_time_ops __read_only = {
8742 .time_init = hpet_time_init,
8743 .get_wallclock = native_get_wallclock,
8744 .set_wallclock = native_set_wallclock,
8745 @@ -316,7 +316,7 @@ struct pv_time_ops pv_time_ops = {
8746 .get_tsc_khz = native_calibrate_tsc,
8749 -struct pv_irq_ops pv_irq_ops = {
8750 +struct pv_irq_ops pv_irq_ops __read_only = {
8751 .init_IRQ = native_init_IRQ,
8752 .save_fl = native_save_fl,
8753 .restore_fl = native_restore_fl,
8754 @@ -329,7 +329,7 @@ struct pv_irq_ops pv_irq_ops = {
8758 -struct pv_cpu_ops pv_cpu_ops = {
8759 +struct pv_cpu_ops pv_cpu_ops __read_only = {
8760 .cpuid = native_cpuid,
8761 .get_debugreg = native_get_debugreg,
8762 .set_debugreg = native_set_debugreg,
8763 @@ -391,7 +391,7 @@ struct pv_cpu_ops pv_cpu_ops = {
8767 -struct pv_apic_ops pv_apic_ops = {
8768 +struct pv_apic_ops pv_apic_ops __read_only = {
8769 #ifdef CONFIG_X86_LOCAL_APIC
8770 .setup_boot_clock = setup_boot_APIC_clock,
8771 .setup_secondary_clock = setup_secondary_APIC_clock,
8772 @@ -399,7 +399,7 @@ struct pv_apic_ops pv_apic_ops = {
8776 -struct pv_mmu_ops pv_mmu_ops = {
8777 +struct pv_mmu_ops pv_mmu_ops __read_only = {
8778 #ifndef CONFIG_X86_64
8779 .pagetable_setup_start = native_pagetable_setup_start,
8780 .pagetable_setup_done = native_pagetable_setup_done,
8781 diff -urNp linux-2.6.29/arch/x86/kernel/paravirt-spinlocks.c linux-2.6.29/arch/x86/kernel/paravirt-spinlocks.c
8782 --- linux-2.6.29/arch/x86/kernel/paravirt-spinlocks.c 2009-03-23 19:12:14.000000000 -0400
8783 +++ linux-2.6.29/arch/x86/kernel/paravirt-spinlocks.c 2009-03-28 14:26:19.000000000 -0400
8784 @@ -13,7 +13,7 @@ default_spin_lock_flags(raw_spinlock_t *
8785 __raw_spin_lock(lock);
8788 -struct pv_lock_ops pv_lock_ops = {
8789 +struct pv_lock_ops pv_lock_ops __read_only = {
8791 .spin_is_locked = __ticket_spin_is_locked,
8792 .spin_is_contended = __ticket_spin_is_contended,
8793 diff -urNp linux-2.6.29/arch/x86/kernel/process_32.c linux-2.6.29/arch/x86/kernel/process_32.c
8794 --- linux-2.6.29/arch/x86/kernel/process_32.c 2009-03-23 19:12:14.000000000 -0400
8795 +++ linux-2.6.29/arch/x86/kernel/process_32.c 2009-03-28 14:26:19.000000000 -0400
8796 @@ -66,8 +66,10 @@ asmlinkage void ret_from_fork(void) __as
8797 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
8798 EXPORT_PER_CPU_SYMBOL(current_task);
8801 DEFINE_PER_CPU(int, cpu_number);
8802 EXPORT_PER_CPU_SYMBOL(cpu_number);
8806 * Return saved PC of a blocked thread.
8807 @@ -75,6 +77,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
8808 unsigned long thread_saved_pc(struct task_struct *tsk)
8810 return ((unsigned long *)tsk->thread.sp)[3];
8811 +//XXX return tsk->thread.eip;
8815 @@ -129,7 +132,7 @@ void __show_regs(struct pt_regs *regs, i
8816 unsigned short ss, gs;
8819 - if (user_mode_vm(regs)) {
8820 + if (user_mode(regs)) {
8822 ss = regs->ss & 0xffff;
8823 savesegment(gs, gs);
8824 @@ -210,8 +213,8 @@ int kernel_thread(int (*fn)(void *), voi
8825 regs.bx = (unsigned long) fn;
8826 regs.dx = (unsigned long) arg;
8828 - regs.ds = __USER_DS;
8829 - regs.es = __USER_DS;
8830 + regs.ds = __KERNEL_DS;
8831 + regs.es = __KERNEL_DS;
8832 regs.fs = __KERNEL_PERCPU;
8834 regs.ip = (unsigned long) kernel_thread_helper;
8835 @@ -233,7 +236,7 @@ void exit_thread(void)
8836 struct task_struct *tsk = current;
8837 struct thread_struct *t = &tsk->thread;
8838 int cpu = get_cpu();
8839 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
8840 + struct tss_struct *tss = init_tss + cpu;
8842 kfree(t->io_bitmap_ptr);
8843 t->io_bitmap_ptr = NULL;
8844 @@ -256,6 +259,7 @@ void flush_thread(void)
8846 struct task_struct *tsk = current;
8848 + loadsegment(gs, 0);
8849 tsk->thread.debugreg0 = 0;
8850 tsk->thread.debugreg1 = 0;
8851 tsk->thread.debugreg2 = 0;
8852 @@ -295,7 +299,7 @@ int copy_thread(int nr, unsigned long cl
8853 struct task_struct *tsk;
8856 - childregs = task_pt_regs(p);
8857 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
8861 @@ -324,6 +328,7 @@ int copy_thread(int nr, unsigned long cl
8862 * Set a new TLS for the child thread?
8864 if (clone_flags & CLONE_SETTLS)
8865 +//XXX needs set_fs()?
8866 err = do_set_thread_area(p, -1,
8867 (struct user_desc __user *)childregs->si, 0);
8869 @@ -514,7 +519,7 @@ __switch_to(struct task_struct *prev_p,
8870 struct thread_struct *prev = &prev_p->thread,
8871 *next = &next_p->thread;
8872 int cpu = smp_processor_id();
8873 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
8874 + struct tss_struct *tss = init_tss + cpu;
8876 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
8878 @@ -542,6 +547,11 @@ __switch_to(struct task_struct *prev_p,
8880 savesegment(gs, prev->gs);
8882 +#ifdef CONFIG_PAX_MEMORY_UDEREF
8883 + if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
8884 + __set_fs(task_thread_info(next_p)->addr_limit, cpu);
8888 * Load the per-thread Thread-Local Storage descriptor.
8890 @@ -680,15 +690,27 @@ unsigned long get_wchan(struct task_stru
8894 -unsigned long arch_align_stack(unsigned long sp)
8895 +#ifdef CONFIG_PAX_RANDKSTACK
8896 +asmlinkage void pax_randomize_kstack(void)
8898 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8899 - sp -= get_random_int() % 8192;
8902 + struct thread_struct *thread = ¤t->thread;
8903 + unsigned long time;
8905 -unsigned long arch_randomize_brk(struct mm_struct *mm)
8907 - unsigned long range_end = mm->brk + 0x02000000;
8908 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
8909 + if (!randomize_va_space)
8914 + /* P4 seems to return a 0 LSB, ignore it */
8915 +#ifdef CONFIG_MPENTIUM4
8923 + thread->sp0 ^= time;
8924 + load_sp0(init_tss + smp_processor_id(), thread);
8927 diff -urNp linux-2.6.29/arch/x86/kernel/process_64.c linux-2.6.29/arch/x86/kernel/process_64.c
8928 --- linux-2.6.29/arch/x86/kernel/process_64.c 2009-03-23 19:12:14.000000000 -0400
8929 +++ linux-2.6.29/arch/x86/kernel/process_64.c 2009-03-28 14:26:19.000000000 -0400
8930 @@ -112,6 +112,8 @@ static inline void play_dead(void)
8933 current_thread_info()->status |= TS_POLLING;
8934 + current->stack_canary = pax_get_random_long();
8935 + write_pda(stack_canary, current->stack_canary);
8936 /* endless idle loop with no priority at all */
8938 tick_nohz_stop_sched_tick(1);
8939 @@ -230,7 +232,7 @@ void exit_thread(void)
8940 struct thread_struct *t = &me->thread;
8942 if (me->thread.io_bitmap_ptr) {
8943 - struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
8944 + struct tss_struct *tss = init_tss + get_cpu();
8946 kfree(t->io_bitmap_ptr);
8947 t->io_bitmap_ptr = NULL;
8948 @@ -537,7 +539,7 @@ __switch_to(struct task_struct *prev_p,
8949 struct thread_struct *prev = &prev_p->thread;
8950 struct thread_struct *next = &next_p->thread;
8951 int cpu = smp_processor_id();
8952 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
8953 + struct tss_struct *tss = init_tss + cpu;
8954 unsigned fsindex, gsindex;
8956 /* we're going to use this soon, after a few expensive things */
8957 @@ -626,7 +628,6 @@ __switch_to(struct task_struct *prev_p,
8958 (unsigned long)task_stack_page(next_p) +
8959 THREAD_SIZE - PDA_STACKOFFSET);
8960 #ifdef CONFIG_CC_STACKPROTECTOR
8961 - write_pda(stack_canary, next_p->stack_canary);
8963 * Build time only check to make sure the stack_canary is at
8964 * offset 40 in the pda; this is a gcc ABI requirement
8965 @@ -725,12 +726,11 @@ unsigned long get_wchan(struct task_stru
8966 if (!p || p == current || p->state == TASK_RUNNING)
8968 stack = (unsigned long)task_stack_page(p);
8969 - if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
8970 + if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
8972 fp = *(u64 *)(p->thread.sp);
8974 - if (fp < (unsigned long)stack ||
8975 - fp >= (unsigned long)stack+THREAD_SIZE)
8976 + if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
8978 ip = *(u64 *)(fp+8);
8979 if (!in_sched_functions(ip))
8980 @@ -839,16 +839,3 @@ long sys_arch_prctl(int code, unsigned l
8982 return do_arch_prctl(current, code, addr);
8985 -unsigned long arch_align_stack(unsigned long sp)
8987 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8988 - sp -= get_random_int() % 8192;
8992 -unsigned long arch_randomize_brk(struct mm_struct *mm)
8994 - unsigned long range_end = mm->brk + 0x02000000;
8995 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
8997 diff -urNp linux-2.6.29/arch/x86/kernel/ptrace.c linux-2.6.29/arch/x86/kernel/ptrace.c
8998 --- linux-2.6.29/arch/x86/kernel/ptrace.c 2009-03-23 19:12:14.000000000 -0400
8999 +++ linux-2.6.29/arch/x86/kernel/ptrace.c 2009-03-28 14:26:19.000000000 -0400
9000 @@ -1378,7 +1378,7 @@ void send_sigtrap(struct task_struct *ts
9001 info.si_code = si_code;
9004 - info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
9005 + info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
9007 /* Send us the fake SIGTRAP */
9008 force_sig_info(SIGTRAP, &info, tsk);
9009 diff -urNp linux-2.6.29/arch/x86/kernel/reboot.c linux-2.6.29/arch/x86/kernel/reboot.c
9010 --- linux-2.6.29/arch/x86/kernel/reboot.c 2009-03-23 19:12:14.000000000 -0400
9011 +++ linux-2.6.29/arch/x86/kernel/reboot.c 2009-03-28 14:26:19.000000000 -0400
9012 @@ -32,7 +32,7 @@ void (*pm_power_off)(void);
9013 EXPORT_SYMBOL(pm_power_off);
9015 static const struct desc_ptr no_idt = {};
9016 -static int reboot_mode;
9017 +static unsigned short reboot_mode;
9018 enum reboot_type reboot_type = BOOT_KBD;
9021 @@ -225,7 +225,7 @@ static struct dmi_system_id __initdata r
9022 DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"),
9026 + { NULL, NULL, {{0, {0}}}, NULL}
9029 static int __init reboot_init(void)
9030 @@ -241,12 +241,12 @@ core_initcall(reboot_init);
9031 controller to pulse the CPU reset line, which is more thorough, but
9032 doesn't work with at least one type of 486 motherboard. It is easy
9033 to stop this code working; hence the copious comments. */
9034 -static const unsigned long long
9035 -real_mode_gdt_entries [3] =
9036 +static struct desc_struct
9037 +real_mode_gdt_entries [3] __read_only =
9039 - 0x0000000000000000ULL, /* Null descriptor */
9040 - 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
9041 - 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
9042 + {{{0x00000000, 0x00000000}}}, /* Null descriptor */
9043 + {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
9044 + {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
9047 static const struct desc_ptr
9048 @@ -295,7 +295,7 @@ static const unsigned char jump_to_bios
9049 * specified by the code and length parameters.
9050 * We assume that length will aways be less that 100!
9052 -void machine_real_restart(const unsigned char *code, int length)
9053 +void machine_real_restart(const unsigned char *code, unsigned int length)
9055 local_irq_disable();
9057 @@ -315,8 +315,8 @@ void machine_real_restart(const unsigned
9058 /* Remap the kernel at virtual address zero, as well as offset zero
9059 from the kernel segment. This assumes the kernel segment starts at
9060 virtual address PAGE_OFFSET. */
9061 - memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
9062 - sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
9063 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
9064 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
9067 * Use `swapper_pg_dir' as our page directory.
9068 @@ -328,16 +328,15 @@ void machine_real_restart(const unsigned
9069 boot)". This seems like a fairly standard thing that gets set by
9070 REBOOT.COM programs, and the previous reset routine did this
9072 - *((unsigned short *)0x472) = reboot_mode;
9073 + *(unsigned short *)(__va(0x472)) = reboot_mode;
9075 /* For the switch to real mode, copy some code to low memory. It has
9076 to be in the first 64k because it is running in 16-bit mode, and it
9077 has to have the same physical and virtual address, because it turns
9078 off paging. Copy it near the end of the first page, out of the way
9079 of BIOS variables. */
9080 - memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
9081 - real_mode_switch, sizeof (real_mode_switch));
9082 - memcpy((void *)(0x1000 - 100), code, length);
9083 + memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
9084 + memcpy(__va(0x1000 - 100), code, length);
9086 /* Set up the IDT for real mode. */
9087 load_idt(&real_mode_idt);
9088 diff -urNp linux-2.6.29/arch/x86/kernel/setup.c linux-2.6.29/arch/x86/kernel/setup.c
9089 --- linux-2.6.29/arch/x86/kernel/setup.c 2009-03-23 19:12:14.000000000 -0400
9090 +++ linux-2.6.29/arch/x86/kernel/setup.c 2009-03-28 14:26:19.000000000 -0400
9091 @@ -712,8 +712,8 @@ void __init setup_arch(char **cmdline_p)
9093 if (!boot_params.hdr.root_flags)
9094 root_mountflags &= ~MS_RDONLY;
9095 - init_mm.start_code = (unsigned long) _text;
9096 - init_mm.end_code = (unsigned long) _etext;
9097 + init_mm.start_code = ktla_ktva((unsigned long) _text);
9098 + init_mm.end_code = ktla_ktva((unsigned long) _etext);
9099 init_mm.end_data = (unsigned long) _edata;
9100 #ifdef CONFIG_X86_32
9101 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
9102 @@ -721,9 +721,9 @@ void __init setup_arch(char **cmdline_p)
9103 init_mm.brk = (unsigned long) &_end;
9106 - code_resource.start = virt_to_phys(_text);
9107 - code_resource.end = virt_to_phys(_etext)-1;
9108 - data_resource.start = virt_to_phys(_etext);
9109 + code_resource.start = virt_to_phys(ktla_ktva(_text));
9110 + code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
9111 + data_resource.start = virt_to_phys(_data);
9112 data_resource.end = virt_to_phys(_edata)-1;
9113 bss_resource.start = virt_to_phys(&__bss_start);
9114 bss_resource.end = virt_to_phys(&__bss_stop)-1;
9115 diff -urNp linux-2.6.29/arch/x86/kernel/setup_percpu.c linux-2.6.29/arch/x86/kernel/setup_percpu.c
9116 --- linux-2.6.29/arch/x86/kernel/setup_percpu.c 2009-03-23 19:12:14.000000000 -0400
9117 +++ linux-2.6.29/arch/x86/kernel/setup_percpu.c 2009-03-28 14:26:19.000000000 -0400
9118 @@ -197,7 +197,11 @@ void __init setup_per_cpu_areas(void)
9119 cpu, node, __pa(ptr));
9122 +#ifdef CONFIG_X86_32
9123 + __per_cpu_offset[cpu] = ptr - __per_cpu_start;
9125 per_cpu_offset(cpu) = ptr - __per_cpu_start;
9127 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
9130 diff -urNp linux-2.6.29/arch/x86/kernel/signal.c linux-2.6.29/arch/x86/kernel/signal.c
9131 --- linux-2.6.29/arch/x86/kernel/signal.c 2009-03-23 19:12:14.000000000 -0400
9132 +++ linux-2.6.29/arch/x86/kernel/signal.c 2009-03-28 14:26:19.000000000 -0400
9133 @@ -287,9 +287,9 @@ __setup_frame(int sig, struct k_sigactio
9136 if (current->mm->context.vdso)
9137 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
9138 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
9140 - restorer = &frame->retcode;
9141 + restorer = (void __user *)&frame->retcode;
9142 if (ka->sa.sa_flags & SA_RESTORER)
9143 restorer = ka->sa.sa_restorer;
9145 @@ -360,7 +360,7 @@ static int __setup_rt_frame(int sig, str
9148 /* Set up to return from userspace. */
9149 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
9150 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
9151 if (ka->sa.sa_flags & SA_RESTORER)
9152 restorer = ka->sa.sa_restorer;
9153 err |= __put_user(restorer, &frame->pretcode);
9154 @@ -811,7 +811,7 @@ static void do_signal(struct pt_regs *re
9155 * X86_32: vm86 regs switched out by assembly code before reaching
9156 * here, so testing against kernel CS suffices.
9158 - if (!user_mode(regs))
9159 + if (!user_mode_novm(regs))
9162 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
9163 diff -urNp linux-2.6.29/arch/x86/kernel/smpboot.c linux-2.6.29/arch/x86/kernel/smpboot.c
9164 --- linux-2.6.29/arch/x86/kernel/smpboot.c 2009-03-23 19:12:14.000000000 -0400
9165 +++ linux-2.6.29/arch/x86/kernel/smpboot.c 2009-03-28 14:26:19.000000000 -0400
9166 @@ -806,6 +806,11 @@ static int __cpuinit do_boot_cpu(int api
9168 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
9171 +#ifdef CONFIG_PAX_KERNEXEC
9172 + unsigned long cr0;
9175 INIT_WORK(&c_idle.work, do_fork_idle);
9177 #ifdef CONFIG_X86_64
9178 @@ -856,7 +861,17 @@ do_rest:
9179 cpu_pda(cpu)->pcurrent = c_idle.idle;
9180 clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
9183 +#ifdef CONFIG_PAX_KERNEXEC
9184 + pax_open_kernel(cr0);
9187 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9189 +#ifdef CONFIG_PAX_KERNEXEC
9190 + pax_close_kernel(cr0);
9193 initial_code = (unsigned long)start_secondary;
9194 stack_start.sp = (void *) c_idle.idle->thread.sp;
9196 diff -urNp linux-2.6.29/arch/x86/kernel/smpcommon.c linux-2.6.29/arch/x86/kernel/smpcommon.c
9197 --- linux-2.6.29/arch/x86/kernel/smpcommon.c 2009-03-23 19:12:14.000000000 -0400
9198 +++ linux-2.6.29/arch/x86/kernel/smpcommon.c 2009-03-28 14:26:19.000000000 -0400
9201 #include <linux/module.h>
9202 #include <asm/smp.h>
9203 +#include <asm/sections.h>
9205 #ifdef CONFIG_X86_32
9206 -DEFINE_PER_CPU(unsigned long, this_cpu_off);
9207 +DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
9208 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
9211 @@ -15,16 +16,19 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
9213 __cpuinit void init_gdt(int cpu)
9215 - struct desc_struct gdt;
9216 + struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
9217 + unsigned long base, limit;
9219 - pack_descriptor(&gdt, __per_cpu_offset[cpu], 0xFFFFF,
9220 - 0x2 | DESCTYPE_S, 0x8);
9222 + base = per_cpu_offset(cpu);
9223 + limit = PERCPU_ENOUGH_ROOM - 1;
9224 + if (limit < 64*1024)
9225 + pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
9227 + pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
9229 - write_gdt_entry(get_cpu_gdt_table(cpu),
9230 - GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
9231 + write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
9233 - per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
9234 + per_cpu(this_cpu_off, cpu) = base;
9235 per_cpu(cpu_number, cpu) = cpu;
9238 diff -urNp linux-2.6.29/arch/x86/kernel/step.c linux-2.6.29/arch/x86/kernel/step.c
9239 --- linux-2.6.29/arch/x86/kernel/step.c 2009-03-23 19:12:14.000000000 -0400
9240 +++ linux-2.6.29/arch/x86/kernel/step.c 2009-03-28 14:26:19.000000000 -0400
9241 @@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
9242 * and APM bios ones we just ignore here.
9244 if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
9246 + struct desc_struct *desc;
9252 mutex_lock(&child->mm->context.lock);
9253 - if (unlikely((seg >> 3) >= child->mm->context.size))
9254 - addr = -1L; /* bogus selector, access would fault */
9255 + if (unlikely(seg >= child->mm->context.size))
9258 - desc = child->mm->context.ldt + seg;
9259 - base = ((desc[0] >> 16) |
9260 - ((desc[1] & 0xff) << 16) |
9261 - (desc[1] & 0xff000000));
9262 + desc = &child->mm->context.ldt[seg];
9263 + base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
9265 /* 16-bit code segment? */
9266 - if (!((desc[1] >> 22) & 1))
9267 + if (!((desc->b >> 22) & 1))
9271 @@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
9272 unsigned char opcode[15];
9273 unsigned long addr = convert_ip_to_linear(child, regs);
9275 + if (addr == -EINVAL)
9278 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
9279 for (i = 0; i < copied; i++) {
9280 switch (opcode[i]) {
9281 @@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
9283 #ifdef CONFIG_X86_64
9285 - if (regs->cs != __USER_CS)
9286 + if ((regs->cs & 0xffff) != __USER_CS)
9287 /* 32-bit mode: register increment */
9289 /* 64-bit mode: REX prefix */
9290 diff -urNp linux-2.6.29/arch/x86/kernel/syscall_table_32.S linux-2.6.29/arch/x86/kernel/syscall_table_32.S
9291 --- linux-2.6.29/arch/x86/kernel/syscall_table_32.S 2009-03-23 19:12:14.000000000 -0400
9292 +++ linux-2.6.29/arch/x86/kernel/syscall_table_32.S 2009-03-28 14:26:19.000000000 -0400
9294 +.section .rodata,"a",@progbits
9295 ENTRY(sys_call_table)
9296 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
9298 diff -urNp linux-2.6.29/arch/x86/kernel/sys_i386_32.c linux-2.6.29/arch/x86/kernel/sys_i386_32.c
9299 --- linux-2.6.29/arch/x86/kernel/sys_i386_32.c 2009-03-23 19:12:14.000000000 -0400
9300 +++ linux-2.6.29/arch/x86/kernel/sys_i386_32.c 2009-03-28 14:26:19.000000000 -0400
9303 #include <asm/syscalls.h>
9305 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
9307 + unsigned long pax_task_size = TASK_SIZE;
9309 +#ifdef CONFIG_PAX_SEGMEXEC
9310 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
9311 + pax_task_size = SEGMEXEC_TASK_SIZE;
9314 + if (len > pax_task_size || addr > pax_task_size - len)
9320 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
9321 unsigned long prot, unsigned long flags,
9322 unsigned long fd, unsigned long pgoff)
9323 @@ -83,6 +98,205 @@ out:
9328 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
9329 + unsigned long len, unsigned long pgoff, unsigned long flags)
9331 + struct mm_struct *mm = current->mm;
9332 + struct vm_area_struct *vma;
9333 + unsigned long start_addr, pax_task_size = TASK_SIZE;
9335 +#ifdef CONFIG_PAX_SEGMEXEC
9336 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
9337 + pax_task_size = SEGMEXEC_TASK_SIZE;
9340 + if (len > pax_task_size)
9343 + if (flags & MAP_FIXED)
9346 +#ifdef CONFIG_PAX_RANDMMAP
9347 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9351 + addr = PAGE_ALIGN(addr);
9352 + vma = find_vma(mm, addr);
9353 + if (pax_task_size - len >= addr &&
9354 + (!vma || addr + len <= vma->vm_start))
9357 + if (len > mm->cached_hole_size) {
9358 + start_addr = addr = mm->free_area_cache;
9360 + start_addr = addr = mm->mmap_base;
9361 + mm->cached_hole_size = 0;
9364 +#ifdef CONFIG_PAX_PAGEEXEC
9365 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
9366 + start_addr = 0x00110000UL;
9368 +#ifdef CONFIG_PAX_RANDMMAP
9369 + if (mm->pax_flags & MF_PAX_RANDMMAP)
9370 + start_addr += mm->delta_mmap & 0x03FFF000UL;
9373 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
9374 + start_addr = addr = mm->mmap_base;
9376 + addr = start_addr;
9381 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
9382 + /* At this point: (!vma || addr < vma->vm_end). */
9383 + if (pax_task_size - len < addr) {
9385 + * Start a new search - just in case we missed
9388 + if (start_addr != mm->mmap_base) {
9389 + start_addr = addr = mm->mmap_base;
9390 + mm->cached_hole_size = 0;
9395 + if (!vma || addr + len <= vma->vm_start) {
9397 + * Remember the place where we stopped the search:
9399 + mm->free_area_cache = addr + len;
9402 + if (addr + mm->cached_hole_size < vma->vm_start)
9403 + mm->cached_hole_size = vma->vm_start - addr;
9404 + addr = vma->vm_end;
9405 + if (mm->start_brk <= addr && addr < mm->mmap_base) {
9406 + start_addr = addr = mm->mmap_base;
9407 + mm->cached_hole_size = 0;
9414 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
9415 + const unsigned long len, const unsigned long pgoff,
9416 + const unsigned long flags)
9418 + struct vm_area_struct *vma;
9419 + struct mm_struct *mm = current->mm;
9420 + unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
9422 +#ifdef CONFIG_PAX_SEGMEXEC
9423 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
9424 + pax_task_size = SEGMEXEC_TASK_SIZE;
9427 + /* requested length too big for entire address space */
9428 + if (len > pax_task_size)
9431 + if (flags & MAP_FIXED)
9434 +#ifdef CONFIG_PAX_PAGEEXEC
9435 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
9439 +#ifdef CONFIG_PAX_RANDMMAP
9440 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9443 + /* requesting a specific address */
9445 + addr = PAGE_ALIGN(addr);
9446 + vma = find_vma(mm, addr);
9447 + if (pax_task_size - len >= addr &&
9448 + (!vma || addr + len <= vma->vm_start))
9452 + /* check if free_area_cache is useful for us */
9453 + if (len <= mm->cached_hole_size) {
9454 + mm->cached_hole_size = 0;
9455 + mm->free_area_cache = mm->mmap_base;
9458 + /* either no address requested or can't fit in requested address hole */
9459 + addr = mm->free_area_cache;
9461 + /* make sure it can fit in the remaining address space */
9463 + vma = find_vma(mm, addr-len);
9464 + if (!vma || addr <= vma->vm_start)
9465 + /* remember the address as a hint for next time */
9466 + return (mm->free_area_cache = addr-len);
9469 + if (mm->mmap_base < len)
9472 + addr = mm->mmap_base-len;
9476 + * Lookup failure means no vma is above this address,
9477 + * else if new region fits below vma->vm_start,
9478 + * return with success:
9480 + vma = find_vma(mm, addr);
9481 + if (!vma || addr+len <= vma->vm_start)
9482 + /* remember the address as a hint for next time */
9483 + return (mm->free_area_cache = addr);
9485 + /* remember the largest hole we saw so far */
9486 + if (addr + mm->cached_hole_size < vma->vm_start)
9487 + mm->cached_hole_size = vma->vm_start - addr;
9489 + /* try just below the current vma->vm_start */
9490 + addr = vma->vm_start-len;
9491 + } while (len < vma->vm_start);
9495 + * A failed mmap() very likely causes application failure,
9496 + * so fall back to the bottom-up function here. This scenario
9497 + * can happen with large stack limits and large mmap()
9501 +#ifdef CONFIG_PAX_SEGMEXEC
9502 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
9503 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
9507 + mm->mmap_base = TASK_UNMAPPED_BASE;
9509 +#ifdef CONFIG_PAX_RANDMMAP
9510 + if (mm->pax_flags & MF_PAX_RANDMMAP)
9511 + mm->mmap_base += mm->delta_mmap;
9514 + mm->free_area_cache = mm->mmap_base;
9515 + mm->cached_hole_size = ~0UL;
9516 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
9518 + * Restore the topdown base:
9520 + mm->mmap_base = base;
9521 + mm->free_area_cache = base;
9522 + mm->cached_hole_size = ~0UL;
9527 struct sel_arg_struct {
9529 diff -urNp linux-2.6.29/arch/x86/kernel/sys_x86_64.c linux-2.6.29/arch/x86/kernel/sys_x86_64.c
9530 --- linux-2.6.29/arch/x86/kernel/sys_x86_64.c 2009-03-23 19:12:14.000000000 -0400
9531 +++ linux-2.6.29/arch/x86/kernel/sys_x86_64.c 2009-03-28 14:26:19.000000000 -0400
9532 @@ -47,8 +47,8 @@ out:
9536 -static void find_start_end(unsigned long flags, unsigned long *begin,
9537 - unsigned long *end)
9538 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
9539 + unsigned long *begin, unsigned long *end)
9541 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
9542 unsigned long new_begin;
9543 @@ -67,7 +67,7 @@ static void find_start_end(unsigned long
9547 - *begin = TASK_UNMAPPED_BASE;
9548 + *begin = mm->mmap_base;
9552 @@ -84,11 +84,15 @@ arch_get_unmapped_area(struct file *filp
9553 if (flags & MAP_FIXED)
9556 - find_start_end(flags, &begin, &end);
9557 + find_start_end(mm, flags, &begin, &end);
9562 +#ifdef CONFIG_PAX_RANDMMAP
9563 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9567 addr = PAGE_ALIGN(addr);
9568 vma = find_vma(mm, addr);
9569 @@ -143,7 +147,7 @@ arch_get_unmapped_area_topdown(struct fi
9571 struct vm_area_struct *vma;
9572 struct mm_struct *mm = current->mm;
9573 - unsigned long addr = addr0;
9574 + unsigned long base = mm->mmap_base, addr = addr0;
9576 /* requested length too big for entire address space */
9577 if (len > TASK_SIZE)
9578 @@ -156,6 +160,10 @@ arch_get_unmapped_area_topdown(struct fi
9579 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
9582 +#ifdef CONFIG_PAX_RANDMMAP
9583 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9586 /* requesting a specific address */
9588 addr = PAGE_ALIGN(addr);
9589 @@ -213,13 +221,21 @@ bottomup:
9590 * can happen with large stack limits and large mmap()
9593 + mm->mmap_base = TASK_UNMAPPED_BASE;
9595 +#ifdef CONFIG_PAX_RANDMMAP
9596 + if (mm->pax_flags & MF_PAX_RANDMMAP)
9597 + mm->mmap_base += mm->delta_mmap;
9600 + mm->free_area_cache = mm->mmap_base;
9601 mm->cached_hole_size = ~0UL;
9602 - mm->free_area_cache = TASK_UNMAPPED_BASE;
9603 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
9605 * Restore the topdown base:
9607 - mm->free_area_cache = mm->mmap_base;
9608 + mm->mmap_base = base;
9609 + mm->free_area_cache = base;
9610 mm->cached_hole_size = ~0UL;
9613 diff -urNp linux-2.6.29/arch/x86/kernel/time_32.c linux-2.6.29/arch/x86/kernel/time_32.c
9614 --- linux-2.6.29/arch/x86/kernel/time_32.c 2009-03-23 19:12:14.000000000 -0400
9615 +++ linux-2.6.29/arch/x86/kernel/time_32.c 2009-03-28 14:26:19.000000000 -0400
9616 @@ -47,22 +47,32 @@ unsigned long profile_pc(struct pt_regs
9617 unsigned long pc = instruction_pointer(regs);
9620 - if (!user_mode_vm(regs) && in_lock_functions(pc)) {
9621 + if (!user_mode(regs) && in_lock_functions(pc)) {
9622 #ifdef CONFIG_FRAME_POINTER
9623 - return *(unsigned long *)(regs->bp + sizeof(long));
9624 + return ktla_ktva(*(unsigned long *)(regs->bp + sizeof(long)));
9626 unsigned long *sp = (unsigned long *)®s->sp;
9628 /* Return address is either directly at stack pointer
9629 or above a saved flags. Eflags has bits 22-31 zero,
9630 kernel addresses don't. */
9632 +#ifdef CONFIG_PAX_KERNEXEC
9633 + return ktla_ktva(sp[0]);
9645 + if (!user_mode(regs))
9646 + pc = ktla_ktva(pc);
9650 EXPORT_SYMBOL(profile_pc);
9651 diff -urNp linux-2.6.29/arch/x86/kernel/time_64.c linux-2.6.29/arch/x86/kernel/time_64.c
9652 --- linux-2.6.29/arch/x86/kernel/time_64.c 2009-03-23 19:12:14.000000000 -0400
9653 +++ linux-2.6.29/arch/x86/kernel/time_64.c 2009-03-28 14:26:19.000000000 -0400
9654 @@ -34,7 +34,7 @@ unsigned long profile_pc(struct pt_regs
9655 /* Assume the lock function has either no stack frame or a copy
9657 Eflags always has bits 22 and up cleared unlike kernel addresses. */
9658 - if (!user_mode_vm(regs) && in_lock_functions(pc)) {
9659 + if (!user_mode(regs) && in_lock_functions(pc)) {
9660 #ifdef CONFIG_FRAME_POINTER
9661 return *(unsigned long *)(regs->bp + sizeof(long));
9663 diff -urNp linux-2.6.29/arch/x86/kernel/tlb_32.c linux-2.6.29/arch/x86/kernel/tlb_32.c
9664 --- linux-2.6.29/arch/x86/kernel/tlb_32.c 2009-03-23 19:12:14.000000000 -0400
9665 +++ linux-2.6.29/arch/x86/kernel/tlb_32.c 2009-03-28 14:26:19.000000000 -0400
9667 #include <asm/tlbflush.h>
9669 DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
9670 - ____cacheline_aligned = { &init_mm, 0, };
9671 + ____cacheline_aligned = { &init_mm, 0, {0} };
9673 /* must come after the send_IPI functions above for inlining */
9674 #include <mach_ipi.h>
9675 diff -urNp linux-2.6.29/arch/x86/kernel/tls.c linux-2.6.29/arch/x86/kernel/tls.c
9676 --- linux-2.6.29/arch/x86/kernel/tls.c 2009-03-23 19:12:14.000000000 -0400
9677 +++ linux-2.6.29/arch/x86/kernel/tls.c 2009-03-28 14:26:19.000000000 -0400
9678 @@ -85,6 +85,11 @@ int do_set_thread_area(struct task_struc
9679 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
9682 +#ifdef CONFIG_PAX_SEGMEXEC
9683 + if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
9687 set_tls_desc(p, idx, &info, 1);
9690 diff -urNp linux-2.6.29/arch/x86/kernel/traps.c linux-2.6.29/arch/x86/kernel/traps.c
9691 --- linux-2.6.29/arch/x86/kernel/traps.c 2009-03-23 19:12:14.000000000 -0400
9692 +++ linux-2.6.29/arch/x86/kernel/traps.c 2009-03-28 14:26:19.000000000 -0400
9693 @@ -71,14 +71,6 @@ asmlinkage int system_call(void);
9695 /* Do we ignore FPU interrupts ? */
9696 char ignore_fpu_irq;
9699 - * The IDT has to be page-aligned to simplify the Pentium
9700 - * F0 0F bug workaround.. We have a special link segment
9703 -gate_desc idt_table[256]
9704 - __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
9707 DECLARE_BITMAP(used_vectors, NR_VECTORS);
9708 @@ -116,7 +108,7 @@ static inline void preempt_conditional_c
9710 die_if_kernel(const char *str, struct pt_regs *regs, long err)
9712 - if (!user_mode_vm(regs))
9713 + if (!user_mode(regs))
9714 die(str, regs, err);
9717 @@ -133,7 +125,7 @@ static int lazy_iobitmap_copy(void)
9721 - tss = &per_cpu(init_tss, cpu);
9722 + tss = init_tss + cpu;
9723 thread = ¤t->thread;
9725 if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
9726 @@ -169,7 +161,7 @@ do_trap(int trapnr, int signr, char *str
9727 struct task_struct *tsk = current;
9729 #ifdef CONFIG_X86_32
9730 - if (regs->flags & X86_VM_MASK) {
9731 + if (v8086_mode(regs)) {
9733 * traps 0, 1, 3, 4, and 5 should be forwarded to vm86.
9734 * On nmi (interrupt 2), do_trap should not be called.
9735 @@ -180,7 +172,7 @@ do_trap(int trapnr, int signr, char *str
9739 - if (!user_mode(regs))
9740 + if (!user_mode_novm(regs))
9743 #ifdef CONFIG_X86_32
9744 @@ -222,6 +214,12 @@ kernel_trap:
9745 tsk->thread.trap_no = trapnr;
9746 die(str, regs, error_code);
9749 +#ifdef CONFIG_PAX_REFCOUNT
9751 + pax_report_refcount_overflow(regs);
9756 #ifdef CONFIG_X86_32
9757 @@ -315,14 +313,30 @@ do_general_protection(struct pt_regs *re
9761 - if (regs->flags & X86_VM_MASK)
9762 + if (v8086_mode(regs))
9767 - if (!user_mode(regs))
9768 + if (!user_mode_novm(regs))
9771 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9772 + if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
9773 + struct mm_struct *mm = tsk->mm;
9774 + unsigned long limit;
9776 + down_write(&mm->mmap_sem);
9777 + limit = mm->context.user_cs_limit;
9778 + if (limit < TASK_SIZE) {
9779 + track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
9780 + up_write(&mm->mmap_sem);
9783 + up_write(&mm->mmap_sem);
9787 tsk->thread.error_code = error_code;
9788 tsk->thread.trap_no = 13;
9790 @@ -355,6 +369,13 @@ gp_in_kernel:
9791 if (notify_die(DIE_GPF, "general protection fault", regs,
9792 error_code, 13, SIGSEGV) == NOTIFY_STOP)
9795 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
9796 + if ((regs->cs & 0xFFFF) == __KERNEL_CS)
9797 + die("PAX: suspicious general protection fault", regs, error_code);
9801 die("general protection fault", regs, error_code);
9804 @@ -601,7 +622,7 @@ dotraplinkage void __kprobes do_debug(st
9807 #ifdef CONFIG_X86_32
9808 - if (regs->flags & X86_VM_MASK)
9809 + if (v8086_mode(regs))
9813 @@ -613,7 +634,7 @@ dotraplinkage void __kprobes do_debug(st
9814 * kernel space (but re-enable TF when returning to user mode).
9816 if (condition & DR_STEP) {
9817 - if (!user_mode(regs))
9818 + if (!user_mode_novm(regs))
9819 goto clear_TF_reenable;
9822 @@ -800,7 +821,7 @@ do_simd_coprocessor_error(struct pt_regs
9823 * Handle strange cache flush from user space exception
9824 * in all other cases. This is undocumented behaviour.
9826 - if (regs->flags & X86_VM_MASK) {
9827 + if (v8086_mode(regs)) {
9828 handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
9831 @@ -829,19 +850,14 @@ do_spurious_interrupt_bug(struct pt_regs
9832 #ifdef CONFIG_X86_32
9833 unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
9835 - struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
9836 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
9837 unsigned long new_kesp = kesp - base;
9838 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
9839 - __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
9840 + struct desc_struct ss;
9842 /* Set up base for espfix segment */
9843 - desc &= 0x00f0ff0000000000ULL;
9844 - desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
9845 - ((((__u64)base) << 32) & 0xff00000000000000ULL) |
9846 - ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
9847 - (lim_pages & 0xffff);
9848 - *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
9849 + pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
9850 + write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
9854 diff -urNp linux-2.6.29/arch/x86/kernel/tsc.c linux-2.6.29/arch/x86/kernel/tsc.c
9855 --- linux-2.6.29/arch/x86/kernel/tsc.c 2009-03-23 19:12:14.000000000 -0400
9856 +++ linux-2.6.29/arch/x86/kernel/tsc.c 2009-03-28 14:26:19.000000000 -0400
9857 @@ -765,7 +765,7 @@ static struct dmi_system_id __initdata b
9858 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
9862 + { NULL, NULL, {{0, {0}}}, NULL}
9865 static void __init check_system_tsc_reliable(void)
9866 diff -urNp linux-2.6.29/arch/x86/kernel/vm86_32.c linux-2.6.29/arch/x86/kernel/vm86_32.c
9867 --- linux-2.6.29/arch/x86/kernel/vm86_32.c 2009-03-23 19:12:14.000000000 -0400
9868 +++ linux-2.6.29/arch/x86/kernel/vm86_32.c 2009-03-28 14:26:19.000000000 -0400
9869 @@ -148,7 +148,7 @@ struct pt_regs *save_v86_state(struct ke
9873 - tss = &per_cpu(init_tss, get_cpu());
9874 + tss = init_tss + get_cpu();
9875 current->thread.sp0 = current->thread.saved_sp0;
9876 current->thread.sysenter_cs = __KERNEL_CS;
9877 load_sp0(tss, ¤t->thread);
9878 @@ -325,7 +325,7 @@ static void do_sys_vm86(struct kernel_vm
9879 tsk->thread.saved_fs = info->regs32->fs;
9880 savesegment(gs, tsk->thread.saved_gs);
9882 - tss = &per_cpu(init_tss, get_cpu());
9883 + tss = init_tss + get_cpu();
9884 tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
9886 tsk->thread.sysenter_cs = 0;
9887 diff -urNp linux-2.6.29/arch/x86/kernel/vmi_32.c linux-2.6.29/arch/x86/kernel/vmi_32.c
9888 --- linux-2.6.29/arch/x86/kernel/vmi_32.c 2009-03-23 19:12:14.000000000 -0400
9889 +++ linux-2.6.29/arch/x86/kernel/vmi_32.c 2009-03-28 14:26:19.000000000 -0400
9890 @@ -102,18 +102,43 @@ static unsigned patch_internal(int call,
9893 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
9895 +#ifdef CONFIG_PAX_KERNEXEC
9896 + unsigned long cr0;
9899 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
9901 case VMI_RELOCATION_CALL_REL:
9904 +#ifdef CONFIG_PAX_KERNEXEC
9905 + pax_open_kernel(cr0);
9908 *(char *)insnbuf = MNEM_CALL;
9909 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
9911 +#ifdef CONFIG_PAX_KERNEXEC
9912 + pax_close_kernel(cr0);
9917 case VMI_RELOCATION_JUMP_REL:
9920 +#ifdef CONFIG_PAX_KERNEXEC
9921 + pax_open_kernel(cr0);
9924 *(char *)insnbuf = MNEM_JMP;
9925 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
9927 +#ifdef CONFIG_PAX_KERNEXEC
9928 + pax_close_kernel(cr0);
9933 case VMI_RELOCATION_NOP:
9934 @@ -409,13 +434,13 @@ static void vmi_set_pud(pud_t *pudp, pud
9936 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
9938 - const pte_t pte = { .pte = 0 };
9939 + const pte_t pte = __pte(0ULL);
9940 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
9943 static void vmi_pmd_clear(pmd_t *pmd)
9945 - const pte_t pte = { .pte = 0 };
9946 + const pte_t pte = __pte(0ULL);
9947 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
9950 @@ -443,8 +468,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
9951 ap.ss = __KERNEL_DS;
9952 ap.esp = (unsigned long) start_esp;
9954 - ap.ds = __USER_DS;
9955 - ap.es = __USER_DS;
9956 + ap.ds = __KERNEL_DS;
9957 + ap.es = __KERNEL_DS;
9958 ap.fs = __KERNEL_PERCPU;
9961 @@ -639,12 +664,20 @@ static inline int __init activate_vmi(vo
9963 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
9965 +#ifdef CONFIG_PAX_KERNEXEC
9966 + unsigned long cr0;
9969 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
9970 printk(KERN_ERR "VMI ROM failed to initialize!");
9973 savesegment(cs, kernel_cs);
9975 +#ifdef CONFIG_PAX_KERNEXEC
9976 + pax_open_kernel(cr0);
9979 pv_info.paravirt_enabled = 1;
9980 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
9981 pv_info.name = "vmi";
9982 @@ -835,6 +868,10 @@ static inline int __init activate_vmi(vo
9984 para_fill(pv_irq_ops.safe_halt, Halt);
9986 +#ifdef CONFIG_PAX_KERNEXEC
9987 + pax_close_kernel(cr0);
9991 * Alternative instruction rewriting doesn't happen soon enough
9992 * to convert VMI_IRET to a call instead of a jump; so we have
9993 diff -urNp linux-2.6.29/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.29/arch/x86/kernel/vmlinux_32.lds.S
9994 --- linux-2.6.29/arch/x86/kernel/vmlinux_32.lds.S 2009-03-23 19:12:14.000000000 -0400
9995 +++ linux-2.6.29/arch/x86/kernel/vmlinux_32.lds.S 2009-03-28 14:26:19.000000000 -0400
9997 #include <asm/page.h>
9998 #include <asm/cache.h>
9999 #include <asm/boot.h>
10000 +#include <asm/segment.h>
10002 +#ifdef CONFIG_X86_PAE
10003 +#define PMD_SHIFT 21
10005 +#define PMD_SHIFT 22
10007 +#define PMD_SIZE (1 << PMD_SHIFT)
10009 +#ifdef CONFIG_PAX_KERNEXEC
10010 +#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
10012 +#define __KERNEL_TEXT_OFFSET 0
10015 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
10017 @@ -22,82 +36,23 @@ ENTRY(phys_startup_32)
10018 jiffies = jiffies_64;
10021 - text PT_LOAD FLAGS(5); /* R_E */
10022 - data PT_LOAD FLAGS(7); /* RWE */
10023 - note PT_NOTE FLAGS(0); /* ___ */
10024 + initdata PT_LOAD FLAGS(6); /* RW_ */
10025 + percpu PT_LOAD FLAGS(6); /* RW_ */
10026 + inittext PT_LOAD FLAGS(5); /* R_E */
10027 + text PT_LOAD FLAGS(5); /* R_E */
10028 + rodata PT_LOAD FLAGS(4); /* R__ */
10029 + data PT_LOAD FLAGS(6); /* RW_ */
10030 + note PT_NOTE FLAGS(0); /* ___ */
10034 - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
10035 - phys_startup_32 = startup_32 - LOAD_OFFSET;
10037 - .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
10038 - _text = .; /* Text and read-only data */
10043 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
10044 - . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
10045 - *(.text.page_aligned)
10053 - _etext = .; /* End of text section */
10056 - NOTES :text :note
10057 + . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
10059 - . = ALIGN(16); /* Exception table */
10060 - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
10061 - __start___ex_table = .;
10063 - __stop___ex_table = .;
10069 - . = ALIGN(PAGE_SIZE);
10070 - .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
10075 - . = ALIGN(PAGE_SIZE);
10076 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
10077 - __nosave_begin = .;
10079 - . = ALIGN(PAGE_SIZE);
10080 - __nosave_end = .;
10083 - . = ALIGN(PAGE_SIZE);
10084 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
10085 - *(.data.page_aligned)
10090 - .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
10091 - *(.data.cacheline_aligned)
10094 - /* rarely changed data like cpu maps */
10096 - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
10097 - *(.data.read_mostly)
10098 - _edata = .; /* End of data section */
10101 - . = ALIGN(THREAD_SIZE); /* init_task */
10102 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
10103 - *(.data.init_task)
10105 + .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
10106 + __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
10107 + phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
10111 /* might get freed after init */
10112 . = ALIGN(PAGE_SIZE);
10113 @@ -115,14 +70,8 @@ SECTIONS
10114 . = ALIGN(PAGE_SIZE);
10116 /* will be freed after init */
10117 - . = ALIGN(PAGE_SIZE); /* Init code and data */
10118 - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
10119 - __init_begin = .;
10124 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
10125 + __init_begin = .;
10129 @@ -162,11 +111,6 @@ SECTIONS
10130 *(.parainstructions)
10131 __parainstructions_end = .;
10133 - /* .exit.text is discard at runtime, not link time, to deal with references
10134 - from .altinstructions and .eh_frame */
10135 - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
10138 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
10141 @@ -179,18 +123,139 @@ SECTIONS
10144 . = ALIGN(PAGE_SIZE);
10145 - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
10146 - __per_cpu_start = .;
10147 - *(.data.percpu.page_aligned)
10148 + per_cpu_start = .;
10149 + .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
10150 + __per_cpu_start = . + per_cpu_start;
10153 *(.data.percpu.shared_aligned)
10154 - __per_cpu_end = .;
10156 + . = ALIGN(PAGE_SIZE);
10157 + *(.data.percpu.page_aligned)
10158 + __per_cpu_end = . + per_cpu_start;
10160 + . += per_cpu_start;
10161 . = ALIGN(PAGE_SIZE);
10162 /* freed after init ends here */
10164 + . = ALIGN(PAGE_SIZE); /* Init code and data */
10165 + .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10171 + /* .exit.text is discard at runtime, not link time, to deal with references
10172 + from .altinstructions and .eh_frame */
10173 + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10177 + .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10179 + . = ALIGN(2*PMD_SIZE) - 1;
10182 + /* freed after init ends here */
10184 + .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10185 + __init_end = . + __KERNEL_TEXT_OFFSET;
10186 + KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
10187 + _text = .; /* Text and read-only data */
10192 + .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10193 + . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
10194 + *(.text.page_aligned)
10202 + _etext = .; /* End of text section */
10205 + . += __KERNEL_TEXT_OFFSET;
10208 + NOTES :rodata :note
10210 + . = ALIGN(16); /* Exception table */
10211 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
10212 + __start___ex_table = .;
10214 + __stop___ex_table = .;
10217 + RO_DATA(PAGE_SIZE)
10219 + . = ALIGN(PAGE_SIZE);
10220 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
10222 + . = ALIGN(PAGE_SIZE);
10223 + *(.empty_zero_page)
10224 + *(.swapper_pg_pmd)
10225 + *(.swapper_pg_dir)
10227 +#if defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_MODULES)
10228 + . = ALIGN(PMD_SIZE);
10233 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
10234 + . = ALIGN(PAGE_SIZE);
10235 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
10236 + MODULES_VADDR = .;
10238 + . += (6 * 1024 * 1024);
10239 + . = ALIGN(PMD_SIZE);
10240 + MODULES_END = . - 1;
10245 + . = ALIGN(PAGE_SIZE);
10246 + .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
10252 + . = ALIGN(PAGE_SIZE);
10253 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
10254 + __nosave_begin = .;
10256 + . = ALIGN(PAGE_SIZE);
10257 + __nosave_end = .;
10260 + . = ALIGN(PAGE_SIZE);
10261 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
10262 + *(.data.page_aligned)
10266 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
10267 + *(.data.cacheline_aligned)
10270 + /* rarely changed data like cpu maps */
10272 + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
10273 + *(.data.read_mostly)
10274 + _edata = .; /* End of data section */
10277 + . = ALIGN(THREAD_SIZE); /* init_task */
10278 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
10279 + *(.data.init_task)
10282 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
10284 __bss_start = .; /* BSS */
10285 *(.bss.page_aligned)
10287 diff -urNp linux-2.6.29/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.29/arch/x86/kernel/vmlinux_64.lds.S
10288 --- linux-2.6.29/arch/x86/kernel/vmlinux_64.lds.S 2009-03-23 19:12:14.000000000 -0400
10289 +++ linux-2.6.29/arch/x86/kernel/vmlinux_64.lds.S 2009-03-28 14:26:19.000000000 -0400
10290 @@ -16,7 +16,7 @@ jiffies_64 = jiffies;
10293 text PT_LOAD FLAGS(5); /* R_E */
10294 - data PT_LOAD FLAGS(7); /* RWE */
10295 + data PT_LOAD FLAGS(6); /* RW_ */
10296 user PT_LOAD FLAGS(7); /* RWE */
10297 data.init PT_LOAD FLAGS(7); /* RWE */
10298 note PT_NOTE FLAGS(0); /* ___ */
10299 @@ -50,17 +50,20 @@ SECTIONS
10300 __stop___ex_table = .;
10304 + RO_DATA(PAGE_SIZE)
10306 +#ifdef CONFIG_PAX_KERNEXEC
10307 + . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
10309 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
10313 .data : AT(ADDR(.data) - LOAD_OFFSET) {
10318 - _edata = .; /* End of data section */
10320 . = ALIGN(PAGE_SIZE);
10321 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
10322 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
10323 @@ -71,9 +74,27 @@ SECTIONS
10324 *(.data.read_mostly)
10327 + . = ALIGN(THREAD_SIZE); /* init_task */
10328 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
10329 + *(.data.init_task)
10332 + . = ALIGN(PAGE_SIZE);
10333 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
10334 + *(.data.page_aligned)
10337 + . = ALIGN(PAGE_SIZE);
10338 + __nosave_begin = .;
10339 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
10340 + . = ALIGN(PAGE_SIZE);
10341 + __nosave_end = .;
10343 + _edata = .; /* End of data section */
10345 #define VSYSCALL_ADDR (-10*1024*1024)
10346 -#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
10347 -#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
10348 +#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
10349 +#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
10351 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
10352 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
10353 @@ -121,23 +142,13 @@ SECTIONS
10354 #undef VVIRT_OFFSET
10357 - . = ALIGN(THREAD_SIZE); /* init_task */
10358 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
10359 - *(.data.init_task)
10362 - . = ALIGN(PAGE_SIZE);
10363 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
10364 - *(.data.page_aligned)
10367 /* might get freed after init */
10368 . = ALIGN(PAGE_SIZE);
10369 __smp_alt_begin = .;
10371 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
10375 __smp_locks_end = .;
10376 . = ALIGN(PAGE_SIZE);
10378 @@ -213,16 +224,11 @@ SECTIONS
10379 . = ALIGN(PAGE_SIZE);
10382 - . = ALIGN(PAGE_SIZE);
10383 - __nosave_begin = .;
10384 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
10385 - . = ALIGN(PAGE_SIZE);
10386 - __nosave_end = .;
10388 __bss_start = .; /* BSS */
10389 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
10390 *(.bss.page_aligned)
10392 + . = ALIGN(2*1024*1024);
10396 diff -urNp linux-2.6.29/arch/x86/kernel/vsyscall_64.c linux-2.6.29/arch/x86/kernel/vsyscall_64.c
10397 --- linux-2.6.29/arch/x86/kernel/vsyscall_64.c 2009-03-23 19:12:14.000000000 -0400
10398 +++ linux-2.6.29/arch/x86/kernel/vsyscall_64.c 2009-03-28 14:26:19.000000000 -0400
10399 @@ -248,13 +248,13 @@ static ctl_table kernel_table2[] = {
10400 .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
10402 .proc_handler = vsyscall_sysctl_change },
10404 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
10407 static ctl_table kernel_root_table2[] = {
10408 { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
10409 .child = kernel_table2 },
10411 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
10415 diff -urNp linux-2.6.29/arch/x86/kvm/svm.c linux-2.6.29/arch/x86/kvm/svm.c
10416 --- linux-2.6.29/arch/x86/kvm/svm.c 2009-03-23 19:12:14.000000000 -0400
10417 +++ linux-2.6.29/arch/x86/kvm/svm.c 2009-03-28 14:26:19.000000000 -0400
10418 @@ -1509,7 +1509,19 @@ static void reload_tss(struct kvm_vcpu *
10419 int cpu = raw_smp_processor_id();
10421 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
10423 +#ifdef CONFIG_PAX_KERNEXEC
10424 + unsigned long cr0;
10426 + pax_open_kernel(cr0);
10429 svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
10431 +#ifdef CONFIG_PAX_KERNEXEC
10432 + pax_close_kernel(cr0);
10438 @@ -1920,7 +1932,7 @@ static int svm_get_mt_mask_shift(void)
10442 -static struct kvm_x86_ops svm_x86_ops = {
10443 +static const struct kvm_x86_ops svm_x86_ops = {
10444 .cpu_has_kvm_support = has_svm,
10445 .disabled_by_bios = is_disabled,
10446 .hardware_setup = svm_hardware_setup,
10447 diff -urNp linux-2.6.29/arch/x86/kvm/vmx.c linux-2.6.29/arch/x86/kvm/vmx.c
10448 --- linux-2.6.29/arch/x86/kvm/vmx.c 2009-03-23 19:12:14.000000000 -0400
10449 +++ linux-2.6.29/arch/x86/kvm/vmx.c 2009-03-28 14:26:19.000000000 -0400
10450 @@ -497,9 +497,23 @@ static void reload_tss(void)
10451 struct descriptor_table gdt;
10452 struct desc_struct *descs;
10454 +#ifdef CONFIG_PAX_KERNEXEC
10455 + unsigned long cr0;
10459 descs = (void *)gdt.base;
10461 +#ifdef CONFIG_PAX_KERNEXEC
10462 + pax_open_kernel(cr0);
10465 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
10467 +#ifdef CONFIG_PAX_KERNEXEC
10468 + pax_close_kernel(cr0);
10474 @@ -2188,7 +2202,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
10475 vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */
10477 asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return));
10478 - vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */
10479 + vmcs_writel(HOST_RIP, ktla_ktva(kvm_vmx_return)); /* 22.2.5 */
10480 vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0);
10481 vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0);
10482 vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0);
10483 @@ -3385,6 +3399,12 @@ static void vmx_vcpu_run(struct kvm_vcpu
10484 "jmp .Lkvm_vmx_return \n\t"
10485 ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
10486 ".Lkvm_vmx_return: "
10488 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
10489 + "ljmp %[cs],$.Lkvm_vmx_return2\n\t"
10490 + ".Lkvm_vmx_return2: "
10493 /* Save guest registers, load host registers, keep flags */
10494 "xchg %0, (%%"R"sp) \n\t"
10495 "mov %%"R"ax, %c[rax](%0) \n\t"
10496 @@ -3431,6 +3451,11 @@ static void vmx_vcpu_run(struct kvm_vcpu
10497 [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
10499 [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
10501 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
10502 + ,[cs]"i"(__KERNEL_CS)
10506 , R"bx", R"di", R"si"
10507 #ifdef CONFIG_X86_64
10508 @@ -3447,7 +3472,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
10510 vmx_update_window_states(vcpu);
10512 - asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
10513 + asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
10516 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
10517 @@ -3576,7 +3601,7 @@ static int vmx_get_mt_mask_shift(void)
10518 return VMX_EPT_MT_EPTE_SHIFT;
10521 -static struct kvm_x86_ops vmx_x86_ops = {
10522 +static const struct kvm_x86_ops vmx_x86_ops = {
10523 .cpu_has_kvm_support = cpu_has_kvm_support,
10524 .disabled_by_bios = vmx_disabled_by_bios,
10525 .hardware_setup = hardware_setup,
10526 diff -urNp linux-2.6.29/arch/x86/kvm/x86.c linux-2.6.29/arch/x86/kvm/x86.c
10527 --- linux-2.6.29/arch/x86/kvm/x86.c 2009-03-23 19:12:14.000000000 -0400
10528 +++ linux-2.6.29/arch/x86/kvm/x86.c 2009-03-28 14:26:19.000000000 -0400
10529 @@ -70,44 +70,44 @@ static u64 __read_mostly efer_reserved_b
10530 static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
10531 struct kvm_cpuid_entry2 __user *entries);
10533 -struct kvm_x86_ops *kvm_x86_ops;
10534 +const struct kvm_x86_ops *kvm_x86_ops;
10535 EXPORT_SYMBOL_GPL(kvm_x86_ops);
10537 struct kvm_stats_debugfs_item debugfs_entries[] = {
10538 - { "pf_fixed", VCPU_STAT(pf_fixed) },
10539 - { "pf_guest", VCPU_STAT(pf_guest) },
10540 - { "tlb_flush", VCPU_STAT(tlb_flush) },
10541 - { "invlpg", VCPU_STAT(invlpg) },
10542 - { "exits", VCPU_STAT(exits) },
10543 - { "io_exits", VCPU_STAT(io_exits) },
10544 - { "mmio_exits", VCPU_STAT(mmio_exits) },
10545 - { "signal_exits", VCPU_STAT(signal_exits) },
10546 - { "irq_window", VCPU_STAT(irq_window_exits) },
10547 - { "nmi_window", VCPU_STAT(nmi_window_exits) },
10548 - { "halt_exits", VCPU_STAT(halt_exits) },
10549 - { "halt_wakeup", VCPU_STAT(halt_wakeup) },
10550 - { "hypercalls", VCPU_STAT(hypercalls) },
10551 - { "request_irq", VCPU_STAT(request_irq_exits) },
10552 - { "request_nmi", VCPU_STAT(request_nmi_exits) },
10553 - { "irq_exits", VCPU_STAT(irq_exits) },
10554 - { "host_state_reload", VCPU_STAT(host_state_reload) },
10555 - { "efer_reload", VCPU_STAT(efer_reload) },
10556 - { "fpu_reload", VCPU_STAT(fpu_reload) },
10557 - { "insn_emulation", VCPU_STAT(insn_emulation) },
10558 - { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
10559 - { "irq_injections", VCPU_STAT(irq_injections) },
10560 - { "nmi_injections", VCPU_STAT(nmi_injections) },
10561 - { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
10562 - { "mmu_pte_write", VM_STAT(mmu_pte_write) },
10563 - { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
10564 - { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
10565 - { "mmu_flooded", VM_STAT(mmu_flooded) },
10566 - { "mmu_recycled", VM_STAT(mmu_recycled) },
10567 - { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
10568 - { "mmu_unsync", VM_STAT(mmu_unsync) },
10569 - { "mmu_unsync_global", VM_STAT(mmu_unsync_global) },
10570 - { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
10571 - { "largepages", VM_STAT(lpages) },
10572 + { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
10573 + { "pf_guest", VCPU_STAT(pf_guest), NULL },
10574 + { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
10575 + { "invlpg", VCPU_STAT(invlpg), NULL },
10576 + { "exits", VCPU_STAT(exits), NULL },
10577 + { "io_exits", VCPU_STAT(io_exits), NULL },
10578 + { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
10579 + { "signal_exits", VCPU_STAT(signal_exits), NULL },
10580 + { "irq_window", VCPU_STAT(irq_window_exits), NULL },
10581 + { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
10582 + { "halt_exits", VCPU_STAT(halt_exits), NULL },
10583 + { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
10584 + { "hypercalls", VCPU_STAT(hypercalls), NULL },
10585 + { "request_irq", VCPU_STAT(request_irq_exits), NULL },
10586 + { "request_nmi", VCPU_STAT(request_nmi_exits), NULL },
10587 + { "irq_exits", VCPU_STAT(irq_exits), NULL },
10588 + { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
10589 + { "efer_reload", VCPU_STAT(efer_reload), NULL },
10590 + { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
10591 + { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
10592 + { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
10593 + { "irq_injections", VCPU_STAT(irq_injections), NULL },
10594 + { "nmi_injections", VCPU_STAT(nmi_injections), NULL },
10595 + { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
10596 + { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
10597 + { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
10598 + { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
10599 + { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
10600 + { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
10601 + { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
10602 + { "mmu_unsync", VM_STAT(mmu_unsync), NULL },
10603 + { "mmu_unsync_global", VM_STAT(mmu_unsync_global), NULL },
10604 + { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
10605 + { "largepages", VM_STAT(lpages), NULL },
10609 @@ -1368,7 +1368,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
10610 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
10611 struct kvm_interrupt *irq)
10613 - if (irq->irq < 0 || irq->irq >= 256)
10614 + if (irq->irq >= 256)
10616 if (irqchip_in_kernel(vcpu->kvm))
10618 @@ -2587,10 +2587,10 @@ int kvm_emulate_pio_string(struct kvm_vc
10620 EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
10622 -int kvm_arch_init(void *opaque)
10623 +int kvm_arch_init(const void *opaque)
10626 - struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
10627 + const struct kvm_x86_ops *ops = (const struct kvm_x86_ops *)opaque;
10630 printk(KERN_ERR "kvm: already loaded the other module\n");
10631 diff -urNp linux-2.6.29/arch/x86/lib/checksum_32.S linux-2.6.29/arch/x86/lib/checksum_32.S
10632 --- linux-2.6.29/arch/x86/lib/checksum_32.S 2009-03-23 19:12:14.000000000 -0400
10633 +++ linux-2.6.29/arch/x86/lib/checksum_32.S 2009-03-28 14:26:19.000000000 -0400
10635 #include <linux/linkage.h>
10636 #include <asm/dwarf2.h>
10637 #include <asm/errno.h>
10639 +#include <asm/segment.h>
10642 * computes a partial checksum, e.g. for TCP/UDP fragments
10644 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
10649 -ENTRY(csum_partial_copy_generic)
10651 +ENTRY(csum_partial_copy_generic_to_user)
10653 + pushl $(__USER_DS)
10654 + CFI_ADJUST_CFA_OFFSET 4
10656 + CFI_ADJUST_CFA_OFFSET -4
10657 + jmp csum_partial_copy_generic
10659 +ENTRY(csum_partial_copy_generic_from_user)
10660 + pushl $(__USER_DS)
10661 + CFI_ADJUST_CFA_OFFSET 4
10663 + CFI_ADJUST_CFA_OFFSET -4
10665 +ENTRY(csum_partial_copy_generic)
10667 CFI_ADJUST_CFA_OFFSET 4
10669 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
10671 SRC(1: movw (%esi), %bx )
10673 -DST( movw %bx, (%edi) )
10674 +DST( movw %bx, %es:(%edi) )
10678 @@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
10679 SRC(1: movl (%esi), %ebx )
10680 SRC( movl 4(%esi), %edx )
10682 -DST( movl %ebx, (%edi) )
10683 +DST( movl %ebx, %es:(%edi) )
10685 -DST( movl %edx, 4(%edi) )
10686 +DST( movl %edx, %es:4(%edi) )
10688 SRC( movl 8(%esi), %ebx )
10689 SRC( movl 12(%esi), %edx )
10691 -DST( movl %ebx, 8(%edi) )
10692 +DST( movl %ebx, %es:8(%edi) )
10694 -DST( movl %edx, 12(%edi) )
10695 +DST( movl %edx, %es:12(%edi) )
10697 SRC( movl 16(%esi), %ebx )
10698 SRC( movl 20(%esi), %edx )
10700 -DST( movl %ebx, 16(%edi) )
10701 +DST( movl %ebx, %es:16(%edi) )
10703 -DST( movl %edx, 20(%edi) )
10704 +DST( movl %edx, %es:20(%edi) )
10706 SRC( movl 24(%esi), %ebx )
10707 SRC( movl 28(%esi), %edx )
10709 -DST( movl %ebx, 24(%edi) )
10710 +DST( movl %ebx, %es:24(%edi) )
10712 -DST( movl %edx, 28(%edi) )
10713 +DST( movl %edx, %es:28(%edi) )
10717 @@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
10718 shrl $2, %edx # This clears CF
10719 SRC(3: movl (%esi), %ebx )
10721 -DST( movl %ebx, (%edi) )
10722 +DST( movl %ebx, %es:(%edi) )
10726 @@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
10728 SRC( movw (%esi), %cx )
10730 -DST( movw %cx, (%edi) )
10731 +DST( movw %cx, %es:(%edi) )
10735 SRC(5: movb (%esi), %cl )
10736 -DST( movb %cl, (%edi) )
10737 +DST( movb %cl, %es:(%edi) )
10741 @@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
10744 movl ARGBASE+20(%esp), %ebx # src_err_ptr
10745 - movl $-EFAULT, (%ebx)
10746 + movl $-EFAULT, %ss:(%ebx)
10748 # zero the complete destination - computing the rest
10750 @@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
10753 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10754 - movl $-EFAULT,(%ebx)
10755 + movl $-EFAULT,%ss:(%ebx)
10761 + CFI_ADJUST_CFA_OFFSET 4
10763 + CFI_ADJUST_CFA_OFFSET -4
10765 + CFI_ADJUST_CFA_OFFSET 4
10767 + CFI_ADJUST_CFA_OFFSET -4
10769 CFI_ADJUST_CFA_OFFSET -4
10771 @@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
10772 CFI_ADJUST_CFA_OFFSET -4
10775 -ENDPROC(csum_partial_copy_generic)
10776 +ENDPROC(csum_partial_copy_generic_to_user)
10780 /* Version for PentiumII/PPro */
10782 #define ROUND1(x) \
10784 SRC(movl x(%esi), %ebx ) ; \
10785 addl %ebx, %eax ; \
10786 - DST(movl %ebx, x(%edi) ) ;
10787 + DST(movl %ebx, %es:x(%edi)) ;
10791 SRC(movl x(%esi), %ebx ) ; \
10792 adcl %ebx, %eax ; \
10793 - DST(movl %ebx, x(%edi) ) ;
10794 + DST(movl %ebx, %es:x(%edi)) ;
10798 -ENTRY(csum_partial_copy_generic)
10800 +ENTRY(csum_partial_copy_generic_to_user)
10802 + pushl $(__USER_DS)
10803 + CFI_ADJUST_CFA_OFFSET 4
10805 + CFI_ADJUST_CFA_OFFSET -4
10806 + jmp csum_partial_copy_generic
10808 +ENTRY(csum_partial_copy_generic_from_user)
10809 + pushl $(__USER_DS)
10810 + CFI_ADJUST_CFA_OFFSET 4
10812 + CFI_ADJUST_CFA_OFFSET -4
10814 +ENTRY(csum_partial_copy_generic)
10816 CFI_ADJUST_CFA_OFFSET 4
10817 CFI_REL_OFFSET ebx, 0
10818 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
10822 - lea 3f(%ebx,%ebx), %ebx
10823 + lea 3f(%ebx,%ebx,2), %ebx
10827 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
10829 SRC( movw (%esi), %dx )
10831 -DST( movw %dx, (%edi) )
10832 +DST( movw %dx, %es:(%edi) )
10837 SRC( movb (%esi), %dl )
10838 -DST( movb %dl, (%edi) )
10839 +DST( movb %dl, %es:(%edi) )
10843 .section .fixup, "ax"
10844 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
10845 - movl $-EFAULT, (%ebx)
10846 + movl $-EFAULT, %ss:(%ebx)
10847 # zero the complete destination (computing the rest is too much work)
10848 movl ARGBASE+8(%esp),%edi # dst
10849 movl ARGBASE+12(%esp),%ecx # len
10850 @@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
10853 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10854 - movl $-EFAULT, (%ebx)
10855 + movl $-EFAULT, %ss:(%ebx)
10860 + CFI_ADJUST_CFA_OFFSET 4
10862 + CFI_ADJUST_CFA_OFFSET -4
10864 + CFI_ADJUST_CFA_OFFSET 4
10866 + CFI_ADJUST_CFA_OFFSET -4
10868 CFI_ADJUST_CFA_OFFSET -4
10870 @@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
10874 -ENDPROC(csum_partial_copy_generic)
10875 +ENDPROC(csum_partial_copy_generic_to_user)
10879 diff -urNp linux-2.6.29/arch/x86/lib/clear_page_64.S linux-2.6.29/arch/x86/lib/clear_page_64.S
10880 --- linux-2.6.29/arch/x86/lib/clear_page_64.S 2009-03-23 19:12:14.000000000 -0400
10881 +++ linux-2.6.29/arch/x86/lib/clear_page_64.S 2009-03-28 14:26:19.000000000 -0400
10882 @@ -44,7 +44,7 @@ ENDPROC(clear_page)
10884 #include <asm/cpufeature.h>
10886 - .section .altinstr_replacement,"ax"
10887 + .section .altinstr_replacement,"a"
10888 1: .byte 0xeb /* jmp <disp8> */
10889 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
10891 diff -urNp linux-2.6.29/arch/x86/lib/copy_page_64.S linux-2.6.29/arch/x86/lib/copy_page_64.S
10892 --- linux-2.6.29/arch/x86/lib/copy_page_64.S 2009-03-23 19:12:14.000000000 -0400
10893 +++ linux-2.6.29/arch/x86/lib/copy_page_64.S 2009-03-28 14:26:19.000000000 -0400
10894 @@ -104,7 +104,7 @@ ENDPROC(copy_page)
10896 #include <asm/cpufeature.h>
10898 - .section .altinstr_replacement,"ax"
10899 + .section .altinstr_replacement,"a"
10900 1: .byte 0xeb /* jmp <disp8> */
10901 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
10903 diff -urNp linux-2.6.29/arch/x86/lib/copy_user_64.S linux-2.6.29/arch/x86/lib/copy_user_64.S
10904 --- linux-2.6.29/arch/x86/lib/copy_user_64.S 2009-03-23 19:12:14.000000000 -0400
10905 +++ linux-2.6.29/arch/x86/lib/copy_user_64.S 2009-03-28 14:26:19.000000000 -0400
10907 .byte 0xe9 /* 32bit jump */
10908 .long \orig-1f /* by default jump to orig */
10910 - .section .altinstr_replacement,"ax"
10911 + .section .altinstr_replacement,"a"
10912 2: .byte 0xe9 /* near jump with 32bit immediate */
10913 .long \alt-1b /* offset */ /* or alternatively to alt */
10915 @@ -106,6 +106,8 @@ ENDPROC(__copy_from_user_inatomic)
10916 ENTRY(bad_from_user)
10924 diff -urNp linux-2.6.29/arch/x86/lib/getuser.S linux-2.6.29/arch/x86/lib/getuser.S
10925 --- linux-2.6.29/arch/x86/lib/getuser.S 2009-03-23 19:12:14.000000000 -0400
10926 +++ linux-2.6.29/arch/x86/lib/getuser.S 2009-03-28 14:26:19.000000000 -0400
10928 #include <asm/asm-offsets.h>
10929 #include <asm/thread_info.h>
10930 #include <asm/asm.h>
10931 +#include <asm/segment.h>
10934 ENTRY(__get_user_1)
10935 @@ -40,7 +41,19 @@ ENTRY(__get_user_1)
10936 GET_THREAD_INFO(%_ASM_DX)
10937 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
10940 +#ifdef CONFIG_X86_32
10941 + pushl $(__USER_DS)
10945 1: movzb (%_ASM_AX),%edx
10947 +#ifdef CONFIG_X86_32
10955 @@ -53,7 +66,19 @@ ENTRY(__get_user_2)
10956 GET_THREAD_INFO(%_ASM_DX)
10957 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
10960 +#ifdef CONFIG_X86_32
10961 + pushl $(__USER_DS)
10965 2: movzwl -1(%_ASM_AX),%edx
10967 +#ifdef CONFIG_X86_32
10975 @@ -66,7 +91,19 @@ ENTRY(__get_user_4)
10976 GET_THREAD_INFO(%_ASM_DX)
10977 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
10980 +#ifdef CONFIG_X86_32
10981 + pushl $(__USER_DS)
10985 3: mov -3(%_ASM_AX),%edx
10987 +#ifdef CONFIG_X86_32
10995 @@ -89,6 +126,12 @@ ENDPROC(__get_user_8)
11000 +#ifdef CONFIG_X86_32
11006 mov $(-EFAULT),%_ASM_AX
11008 diff -urNp linux-2.6.29/arch/x86/lib/memcpy_64.S linux-2.6.29/arch/x86/lib/memcpy_64.S
11009 --- linux-2.6.29/arch/x86/lib/memcpy_64.S 2009-03-23 19:12:14.000000000 -0400
11010 +++ linux-2.6.29/arch/x86/lib/memcpy_64.S 2009-03-28 14:26:19.000000000 -0400
11011 @@ -114,7 +114,7 @@ ENDPROC(__memcpy)
11012 /* Some CPUs run faster using the string copy instructions.
11013 It is also a lot simpler. Use this when possible */
11015 - .section .altinstr_replacement,"ax"
11016 + .section .altinstr_replacement,"a"
11017 1: .byte 0xeb /* jmp <disp8> */
11018 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
11020 diff -urNp linux-2.6.29/arch/x86/lib/memset_64.S linux-2.6.29/arch/x86/lib/memset_64.S
11021 --- linux-2.6.29/arch/x86/lib/memset_64.S 2009-03-23 19:12:14.000000000 -0400
11022 +++ linux-2.6.29/arch/x86/lib/memset_64.S 2009-03-28 14:26:19.000000000 -0400
11023 @@ -118,7 +118,7 @@ ENDPROC(__memset)
11025 #include <asm/cpufeature.h>
11027 - .section .altinstr_replacement,"ax"
11028 + .section .altinstr_replacement,"a"
11029 1: .byte 0xeb /* jmp <disp8> */
11030 .byte (memset_c - memset) - (2f - 1b) /* offset */
11032 diff -urNp linux-2.6.29/arch/x86/lib/mmx_32.c linux-2.6.29/arch/x86/lib/mmx_32.c
11033 --- linux-2.6.29/arch/x86/lib/mmx_32.c 2009-03-23 19:12:14.000000000 -0400
11034 +++ linux-2.6.29/arch/x86/lib/mmx_32.c 2009-03-28 14:26:19.000000000 -0400
11035 @@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
11039 + unsigned long cr0;
11041 if (unlikely(in_interrupt()))
11042 return __memcpy(to, from, len);
11043 @@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
11044 kernel_fpu_begin();
11046 __asm__ __volatile__ (
11047 - "1: prefetch (%0)\n" /* This set is 28 bytes */
11048 - " prefetch 64(%0)\n"
11049 - " prefetch 128(%0)\n"
11050 - " prefetch 192(%0)\n"
11051 - " prefetch 256(%0)\n"
11052 + "1: prefetch (%1)\n" /* This set is 28 bytes */
11053 + " prefetch 64(%1)\n"
11054 + " prefetch 128(%1)\n"
11055 + " prefetch 192(%1)\n"
11056 + " prefetch 256(%1)\n"
11058 ".section .fixup, \"ax\"\n"
11059 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11062 +#ifdef CONFIG_PAX_KERNEXEC
11063 + " movl %%cr0, %0\n"
11064 + " movl %0, %%eax\n"
11065 + " andl $0xFFFEFFFF, %%eax\n"
11066 + " movl %%eax, %%cr0\n"
11069 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11071 +#ifdef CONFIG_PAX_KERNEXEC
11072 + " movl %0, %%cr0\n"
11077 _ASM_EXTABLE(1b, 3b)
11079 + : "=&r" (cr0) : "r" (from) : "ax");
11081 for ( ; i > 5; i--) {
11082 __asm__ __volatile__ (
11083 - "1: prefetch 320(%0)\n"
11084 - "2: movq (%0), %%mm0\n"
11085 - " movq 8(%0), %%mm1\n"
11086 - " movq 16(%0), %%mm2\n"
11087 - " movq 24(%0), %%mm3\n"
11088 - " movq %%mm0, (%1)\n"
11089 - " movq %%mm1, 8(%1)\n"
11090 - " movq %%mm2, 16(%1)\n"
11091 - " movq %%mm3, 24(%1)\n"
11092 - " movq 32(%0), %%mm0\n"
11093 - " movq 40(%0), %%mm1\n"
11094 - " movq 48(%0), %%mm2\n"
11095 - " movq 56(%0), %%mm3\n"
11096 - " movq %%mm0, 32(%1)\n"
11097 - " movq %%mm1, 40(%1)\n"
11098 - " movq %%mm2, 48(%1)\n"
11099 - " movq %%mm3, 56(%1)\n"
11100 + "1: prefetch 320(%1)\n"
11101 + "2: movq (%1), %%mm0\n"
11102 + " movq 8(%1), %%mm1\n"
11103 + " movq 16(%1), %%mm2\n"
11104 + " movq 24(%1), %%mm3\n"
11105 + " movq %%mm0, (%2)\n"
11106 + " movq %%mm1, 8(%2)\n"
11107 + " movq %%mm2, 16(%2)\n"
11108 + " movq %%mm3, 24(%2)\n"
11109 + " movq 32(%1), %%mm0\n"
11110 + " movq 40(%1), %%mm1\n"
11111 + " movq 48(%1), %%mm2\n"
11112 + " movq 56(%1), %%mm3\n"
11113 + " movq %%mm0, 32(%2)\n"
11114 + " movq %%mm1, 40(%2)\n"
11115 + " movq %%mm2, 48(%2)\n"
11116 + " movq %%mm3, 56(%2)\n"
11117 ".section .fixup, \"ax\"\n"
11118 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11121 +#ifdef CONFIG_PAX_KERNEXEC
11122 + " movl %%cr0, %0\n"
11123 + " movl %0, %%eax\n"
11124 + " andl $0xFFFEFFFF, %%eax\n"
11125 + " movl %%eax, %%cr0\n"
11128 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11130 +#ifdef CONFIG_PAX_KERNEXEC
11131 + " movl %0, %%cr0\n"
11136 _ASM_EXTABLE(1b, 3b)
11137 - : : "r" (from), "r" (to) : "memory");
11138 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
11142 @@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
11143 static void fast_copy_page(void *to, void *from)
11146 + unsigned long cr0;
11148 kernel_fpu_begin();
11150 @@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
11151 * but that is for later. -AV
11153 __asm__ __volatile__(
11154 - "1: prefetch (%0)\n"
11155 - " prefetch 64(%0)\n"
11156 - " prefetch 128(%0)\n"
11157 - " prefetch 192(%0)\n"
11158 - " prefetch 256(%0)\n"
11159 + "1: prefetch (%1)\n"
11160 + " prefetch 64(%1)\n"
11161 + " prefetch 128(%1)\n"
11162 + " prefetch 192(%1)\n"
11163 + " prefetch 256(%1)\n"
11165 ".section .fixup, \"ax\"\n"
11166 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11169 +#ifdef CONFIG_PAX_KERNEXEC
11170 + " movl %%cr0, %0\n"
11171 + " movl %0, %%eax\n"
11172 + " andl $0xFFFEFFFF, %%eax\n"
11173 + " movl %%eax, %%cr0\n"
11176 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11178 +#ifdef CONFIG_PAX_KERNEXEC
11179 + " movl %0, %%cr0\n"
11184 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
11185 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
11187 for (i = 0; i < (4096-320)/64; i++) {
11188 __asm__ __volatile__ (
11189 - "1: prefetch 320(%0)\n"
11190 - "2: movq (%0), %%mm0\n"
11191 - " movntq %%mm0, (%1)\n"
11192 - " movq 8(%0), %%mm1\n"
11193 - " movntq %%mm1, 8(%1)\n"
11194 - " movq 16(%0), %%mm2\n"
11195 - " movntq %%mm2, 16(%1)\n"
11196 - " movq 24(%0), %%mm3\n"
11197 - " movntq %%mm3, 24(%1)\n"
11198 - " movq 32(%0), %%mm4\n"
11199 - " movntq %%mm4, 32(%1)\n"
11200 - " movq 40(%0), %%mm5\n"
11201 - " movntq %%mm5, 40(%1)\n"
11202 - " movq 48(%0), %%mm6\n"
11203 - " movntq %%mm6, 48(%1)\n"
11204 - " movq 56(%0), %%mm7\n"
11205 - " movntq %%mm7, 56(%1)\n"
11206 + "1: prefetch 320(%1)\n"
11207 + "2: movq (%1), %%mm0\n"
11208 + " movntq %%mm0, (%2)\n"
11209 + " movq 8(%1), %%mm1\n"
11210 + " movntq %%mm1, 8(%2)\n"
11211 + " movq 16(%1), %%mm2\n"
11212 + " movntq %%mm2, 16(%2)\n"
11213 + " movq 24(%1), %%mm3\n"
11214 + " movntq %%mm3, 24(%2)\n"
11215 + " movq 32(%1), %%mm4\n"
11216 + " movntq %%mm4, 32(%2)\n"
11217 + " movq 40(%1), %%mm5\n"
11218 + " movntq %%mm5, 40(%2)\n"
11219 + " movq 48(%1), %%mm6\n"
11220 + " movntq %%mm6, 48(%2)\n"
11221 + " movq 56(%1), %%mm7\n"
11222 + " movntq %%mm7, 56(%2)\n"
11223 ".section .fixup, \"ax\"\n"
11224 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11227 +#ifdef CONFIG_PAX_KERNEXEC
11228 + " movl %%cr0, %0\n"
11229 + " movl %0, %%eax\n"
11230 + " andl $0xFFFEFFFF, %%eax\n"
11231 + " movl %%eax, %%cr0\n"
11234 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11236 +#ifdef CONFIG_PAX_KERNEXEC
11237 + " movl %0, %%cr0\n"
11242 - _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
11243 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
11247 @@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
11248 static void fast_copy_page(void *to, void *from)
11251 + unsigned long cr0;
11253 kernel_fpu_begin();
11255 __asm__ __volatile__ (
11256 - "1: prefetch (%0)\n"
11257 - " prefetch 64(%0)\n"
11258 - " prefetch 128(%0)\n"
11259 - " prefetch 192(%0)\n"
11260 - " prefetch 256(%0)\n"
11261 + "1: prefetch (%1)\n"
11262 + " prefetch 64(%1)\n"
11263 + " prefetch 128(%1)\n"
11264 + " prefetch 192(%1)\n"
11265 + " prefetch 256(%1)\n"
11267 ".section .fixup, \"ax\"\n"
11268 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11271 +#ifdef CONFIG_PAX_KERNEXEC
11272 + " movl %%cr0, %0\n"
11273 + " movl %0, %%eax\n"
11274 + " andl $0xFFFEFFFF, %%eax\n"
11275 + " movl %%eax, %%cr0\n"
11278 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11280 +#ifdef CONFIG_PAX_KERNEXEC
11281 + " movl %0, %%cr0\n"
11286 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
11287 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
11289 for (i = 0; i < 4096/64; i++) {
11290 __asm__ __volatile__ (
11291 - "1: prefetch 320(%0)\n"
11292 - "2: movq (%0), %%mm0\n"
11293 - " movq 8(%0), %%mm1\n"
11294 - " movq 16(%0), %%mm2\n"
11295 - " movq 24(%0), %%mm3\n"
11296 - " movq %%mm0, (%1)\n"
11297 - " movq %%mm1, 8(%1)\n"
11298 - " movq %%mm2, 16(%1)\n"
11299 - " movq %%mm3, 24(%1)\n"
11300 - " movq 32(%0), %%mm0\n"
11301 - " movq 40(%0), %%mm1\n"
11302 - " movq 48(%0), %%mm2\n"
11303 - " movq 56(%0), %%mm3\n"
11304 - " movq %%mm0, 32(%1)\n"
11305 - " movq %%mm1, 40(%1)\n"
11306 - " movq %%mm2, 48(%1)\n"
11307 - " movq %%mm3, 56(%1)\n"
11308 + "1: prefetch 320(%1)\n"
11309 + "2: movq (%1), %%mm0\n"
11310 + " movq 8(%1), %%mm1\n"
11311 + " movq 16(%1), %%mm2\n"
11312 + " movq 24(%1), %%mm3\n"
11313 + " movq %%mm0, (%2)\n"
11314 + " movq %%mm1, 8(%2)\n"
11315 + " movq %%mm2, 16(%2)\n"
11316 + " movq %%mm3, 24(%2)\n"
11317 + " movq 32(%1), %%mm0\n"
11318 + " movq 40(%1), %%mm1\n"
11319 + " movq 48(%1), %%mm2\n"
11320 + " movq 56(%1), %%mm3\n"
11321 + " movq %%mm0, 32(%2)\n"
11322 + " movq %%mm1, 40(%2)\n"
11323 + " movq %%mm2, 48(%2)\n"
11324 + " movq %%mm3, 56(%2)\n"
11325 ".section .fixup, \"ax\"\n"
11326 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11329 +#ifdef CONFIG_PAX_KERNEXEC
11330 + " movl %%cr0, %0\n"
11331 + " movl %0, %%eax\n"
11332 + " andl $0xFFFEFFFF, %%eax\n"
11333 + " movl %%eax, %%cr0\n"
11336 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11338 +#ifdef CONFIG_PAX_KERNEXEC
11339 + " movl %0, %%cr0\n"
11344 _ASM_EXTABLE(1b, 3b)
11345 - : : "r" (from), "r" (to) : "memory");
11346 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
11350 diff -urNp linux-2.6.29/arch/x86/lib/putuser.S linux-2.6.29/arch/x86/lib/putuser.S
11351 --- linux-2.6.29/arch/x86/lib/putuser.S 2009-03-23 19:12:14.000000000 -0400
11352 +++ linux-2.6.29/arch/x86/lib/putuser.S 2009-03-28 14:26:19.000000000 -0400
11354 #include <asm/thread_info.h>
11355 #include <asm/errno.h>
11356 #include <asm/asm.h>
11357 +#include <asm/segment.h>
11361 @@ -39,7 +40,19 @@ ENTRY(__put_user_1)
11363 cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
11366 +#ifdef CONFIG_X86_32
11367 + pushl $(__USER_DS)
11371 1: movb %al,(%_ASM_CX)
11373 +#ifdef CONFIG_X86_32
11380 ENDPROC(__put_user_1)
11381 @@ -50,7 +63,19 @@ ENTRY(__put_user_2)
11383 cmp %_ASM_BX,%_ASM_CX
11386 +#ifdef CONFIG_X86_32
11387 + pushl $(__USER_DS)
11391 2: movw %ax,(%_ASM_CX)
11393 +#ifdef CONFIG_X86_32
11400 ENDPROC(__put_user_2)
11401 @@ -61,7 +86,19 @@ ENTRY(__put_user_4)
11403 cmp %_ASM_BX,%_ASM_CX
11406 +#ifdef CONFIG_X86_32
11407 + pushl $(__USER_DS)
11411 3: movl %eax,(%_ASM_CX)
11413 +#ifdef CONFIG_X86_32
11420 ENDPROC(__put_user_4)
11421 @@ -72,16 +109,34 @@ ENTRY(__put_user_8)
11423 cmp %_ASM_BX,%_ASM_CX
11426 +#ifdef CONFIG_X86_32
11427 + pushl $(__USER_DS)
11431 4: mov %_ASM_AX,(%_ASM_CX)
11432 #ifdef CONFIG_X86_32
11433 5: movl %edx,4(%_ASM_CX)
11436 +#ifdef CONFIG_X86_32
11443 ENDPROC(__put_user_8)
11448 +#ifdef CONFIG_X86_32
11456 diff -urNp linux-2.6.29/arch/x86/lib/usercopy_32.c linux-2.6.29/arch/x86/lib/usercopy_32.c
11457 --- linux-2.6.29/arch/x86/lib/usercopy_32.c 2009-03-23 19:12:14.000000000 -0400
11458 +++ linux-2.6.29/arch/x86/lib/usercopy_32.c 2009-03-28 14:26:19.000000000 -0400
11459 @@ -36,31 +36,38 @@ static inline int __movsl_is_ok(unsigned
11460 * Copy a null terminated string from userspace.
11463 -#define __do_strncpy_from_user(dst, src, count, res) \
11465 - int __d0, __d1, __d2; \
11467 - __asm__ __volatile__( \
11468 - " testl %1,%1\n" \
11472 - " testb %%al,%%al\n" \
11476 - "1: subl %1,%0\n" \
11478 - ".section .fixup,\"ax\"\n" \
11479 - "3: movl %5,%0\n" \
11482 - _ASM_EXTABLE(0b,3b) \
11483 - : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \
11485 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
11488 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
11490 + int __d0, __d1, __d2;
11491 + long res = -EFAULT;
11494 + __asm__ __volatile__(
11495 + " movw %w10,%%ds\n"
11500 + " testb %%al,%%al\n"
11504 + "1: subl %1,%0\n"
11508 + ".section .fixup,\"ax\"\n"
11509 + "3: movl %5,%0\n"
11512 + _ASM_EXTABLE(0b,3b)
11513 + : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),
11515 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
11522 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
11523 @@ -85,9 +92,7 @@ do { \
11525 __strncpy_from_user(char *dst, const char __user *src, long count)
11528 - __do_strncpy_from_user(dst, src, count, res);
11530 + return __do_strncpy_from_user(dst, src, count);
11532 EXPORT_SYMBOL(__strncpy_from_user);
11534 @@ -114,7 +119,7 @@ strncpy_from_user(char *dst, const char
11536 long res = -EFAULT;
11537 if (access_ok(VERIFY_READ, src, 1))
11538 - __do_strncpy_from_user(dst, src, count, res);
11539 + res = __do_strncpy_from_user(dst, src, count);
11542 EXPORT_SYMBOL(strncpy_from_user);
11543 @@ -123,24 +128,30 @@ EXPORT_SYMBOL(strncpy_from_user);
11547 -#define __do_clear_user(addr,size) \
11551 - __asm__ __volatile__( \
11552 - "0: rep; stosl\n" \
11553 - " movl %2,%0\n" \
11554 - "1: rep; stosb\n" \
11556 - ".section .fixup,\"ax\"\n" \
11557 - "3: lea 0(%2,%0,4),%0\n" \
11560 - _ASM_EXTABLE(0b,3b) \
11561 - _ASM_EXTABLE(1b,2b) \
11562 - : "=&c"(size), "=&D" (__d0) \
11563 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
11565 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
11570 + __asm__ __volatile__(
11571 + " movw %w6,%%es\n"
11572 + "0: rep; stosl\n"
11574 + "1: rep; stosb\n"
11578 + ".section .fixup,\"ax\"\n"
11579 + "3: lea 0(%2,%0,4),%0\n"
11582 + _ASM_EXTABLE(0b,3b)
11583 + _ASM_EXTABLE(1b,2b)
11584 + : "=&c"(size), "=&D" (__d0)
11585 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
11591 * clear_user: - Zero a block of memory in user space.
11592 @@ -157,7 +168,7 @@ clear_user(void __user *to, unsigned lon
11595 if (access_ok(VERIFY_WRITE, to, n))
11596 - __do_clear_user(to, n);
11597 + n = __do_clear_user(to, n);
11600 EXPORT_SYMBOL(clear_user);
11601 @@ -176,8 +187,7 @@ EXPORT_SYMBOL(clear_user);
11603 __clear_user(void __user *to, unsigned long n)
11605 - __do_clear_user(to, n);
11607 + return __do_clear_user(to, n);
11609 EXPORT_SYMBOL(__clear_user);
11611 @@ -200,14 +210,17 @@ long strnlen_user(const char __user *s,
11614 __asm__ __volatile__(
11615 + " movw %w8,%%es\n"
11618 - " andl %0,%%ecx\n"
11619 + " movl %0,%%ecx\n"
11620 "0: repne; scasb\n"
11627 ".section .fixup,\"ax\"\n"
11628 "2: xorl %%eax,%%eax\n"
11630 @@ -219,7 +232,7 @@ long strnlen_user(const char __user *s,
11633 :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp)
11634 - :"0" (n), "1" (s), "2" (0), "3" (mask)
11635 + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
11639 @@ -227,10 +240,11 @@ EXPORT_SYMBOL(strnlen_user);
11641 #ifdef CONFIG_X86_INTEL_USERCOPY
11642 static unsigned long
11643 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
11644 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
11647 __asm__ __volatile__(
11648 + " movw %w6, %%es\n"
11650 "1: movl 32(%4), %%eax\n"
11652 @@ -239,36 +253,36 @@ __copy_user_intel(void __user *to, const
11654 "3: movl 0(%4), %%eax\n"
11655 "4: movl 4(%4), %%edx\n"
11656 - "5: movl %%eax, 0(%3)\n"
11657 - "6: movl %%edx, 4(%3)\n"
11658 + "5: movl %%eax, %%es:0(%3)\n"
11659 + "6: movl %%edx, %%es:4(%3)\n"
11660 "7: movl 8(%4), %%eax\n"
11661 "8: movl 12(%4),%%edx\n"
11662 - "9: movl %%eax, 8(%3)\n"
11663 - "10: movl %%edx, 12(%3)\n"
11664 + "9: movl %%eax, %%es:8(%3)\n"
11665 + "10: movl %%edx, %%es:12(%3)\n"
11666 "11: movl 16(%4), %%eax\n"
11667 "12: movl 20(%4), %%edx\n"
11668 - "13: movl %%eax, 16(%3)\n"
11669 - "14: movl %%edx, 20(%3)\n"
11670 + "13: movl %%eax, %%es:16(%3)\n"
11671 + "14: movl %%edx, %%es:20(%3)\n"
11672 "15: movl 24(%4), %%eax\n"
11673 "16: movl 28(%4), %%edx\n"
11674 - "17: movl %%eax, 24(%3)\n"
11675 - "18: movl %%edx, 28(%3)\n"
11676 + "17: movl %%eax, %%es:24(%3)\n"
11677 + "18: movl %%edx, %%es:28(%3)\n"
11678 "19: movl 32(%4), %%eax\n"
11679 "20: movl 36(%4), %%edx\n"
11680 - "21: movl %%eax, 32(%3)\n"
11681 - "22: movl %%edx, 36(%3)\n"
11682 + "21: movl %%eax, %%es:32(%3)\n"
11683 + "22: movl %%edx, %%es:36(%3)\n"
11684 "23: movl 40(%4), %%eax\n"
11685 "24: movl 44(%4), %%edx\n"
11686 - "25: movl %%eax, 40(%3)\n"
11687 - "26: movl %%edx, 44(%3)\n"
11688 + "25: movl %%eax, %%es:40(%3)\n"
11689 + "26: movl %%edx, %%es:44(%3)\n"
11690 "27: movl 48(%4), %%eax\n"
11691 "28: movl 52(%4), %%edx\n"
11692 - "29: movl %%eax, 48(%3)\n"
11693 - "30: movl %%edx, 52(%3)\n"
11694 + "29: movl %%eax, %%es:48(%3)\n"
11695 + "30: movl %%edx, %%es:52(%3)\n"
11696 "31: movl 56(%4), %%eax\n"
11697 "32: movl 60(%4), %%edx\n"
11698 - "33: movl %%eax, 56(%3)\n"
11699 - "34: movl %%edx, 60(%3)\n"
11700 + "33: movl %%eax, %%es:56(%3)\n"
11701 + "34: movl %%edx, %%es:60(%3)\n"
11705 @@ -282,6 +296,8 @@ __copy_user_intel(void __user *to, const
11706 "36: movl %%eax, %0\n"
11711 ".section .fixup,\"ax\"\n"
11712 "101: lea 0(%%eax,%0,4),%0\n"
11714 @@ -328,7 +344,117 @@ __copy_user_intel(void __user *to, const
11715 " .long 99b,101b\n"
11717 : "=&c"(size), "=&D" (d0), "=&S" (d1)
11718 - : "1"(to), "2"(from), "0"(size)
11719 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11720 + : "eax", "edx", "memory");
11724 +static unsigned long
11725 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
11728 + __asm__ __volatile__(
11729 + " movw %w6, %%ds\n"
11730 + " .align 2,0x90\n"
11731 + "1: movl 32(%4), %%eax\n"
11732 + " cmpl $67, %0\n"
11734 + "2: movl 64(%4), %%eax\n"
11735 + " .align 2,0x90\n"
11736 + "3: movl 0(%4), %%eax\n"
11737 + "4: movl 4(%4), %%edx\n"
11738 + "5: movl %%eax, %%es:0(%3)\n"
11739 + "6: movl %%edx, %%es:4(%3)\n"
11740 + "7: movl 8(%4), %%eax\n"
11741 + "8: movl 12(%4),%%edx\n"
11742 + "9: movl %%eax, %%es:8(%3)\n"
11743 + "10: movl %%edx, %%es:12(%3)\n"
11744 + "11: movl 16(%4), %%eax\n"
11745 + "12: movl 20(%4), %%edx\n"
11746 + "13: movl %%eax, %%es:16(%3)\n"
11747 + "14: movl %%edx, %%es:20(%3)\n"
11748 + "15: movl 24(%4), %%eax\n"
11749 + "16: movl 28(%4), %%edx\n"
11750 + "17: movl %%eax, %%es:24(%3)\n"
11751 + "18: movl %%edx, %%es:28(%3)\n"
11752 + "19: movl 32(%4), %%eax\n"
11753 + "20: movl 36(%4), %%edx\n"
11754 + "21: movl %%eax, %%es:32(%3)\n"
11755 + "22: movl %%edx, %%es:36(%3)\n"
11756 + "23: movl 40(%4), %%eax\n"
11757 + "24: movl 44(%4), %%edx\n"
11758 + "25: movl %%eax, %%es:40(%3)\n"
11759 + "26: movl %%edx, %%es:44(%3)\n"
11760 + "27: movl 48(%4), %%eax\n"
11761 + "28: movl 52(%4), %%edx\n"
11762 + "29: movl %%eax, %%es:48(%3)\n"
11763 + "30: movl %%edx, %%es:52(%3)\n"
11764 + "31: movl 56(%4), %%eax\n"
11765 + "32: movl 60(%4), %%edx\n"
11766 + "33: movl %%eax, %%es:56(%3)\n"
11767 + "34: movl %%edx, %%es:60(%3)\n"
11768 + " addl $-64, %0\n"
11769 + " addl $64, %4\n"
11770 + " addl $64, %3\n"
11771 + " cmpl $63, %0\n"
11773 + "35: movl %0, %%eax\n"
11775 + " andl $3, %%eax\n"
11777 + "99: rep; movsl\n"
11778 + "36: movl %%eax, %0\n"
11779 + "37: rep; movsb\n"
11783 + ".section .fixup,\"ax\"\n"
11784 + "101: lea 0(%%eax,%0,4),%0\n"
11787 + ".section __ex_table,\"a\"\n"
11789 + " .long 1b,100b\n"
11790 + " .long 2b,100b\n"
11791 + " .long 3b,100b\n"
11792 + " .long 4b,100b\n"
11793 + " .long 5b,100b\n"
11794 + " .long 6b,100b\n"
11795 + " .long 7b,100b\n"
11796 + " .long 8b,100b\n"
11797 + " .long 9b,100b\n"
11798 + " .long 10b,100b\n"
11799 + " .long 11b,100b\n"
11800 + " .long 12b,100b\n"
11801 + " .long 13b,100b\n"
11802 + " .long 14b,100b\n"
11803 + " .long 15b,100b\n"
11804 + " .long 16b,100b\n"
11805 + " .long 17b,100b\n"
11806 + " .long 18b,100b\n"
11807 + " .long 19b,100b\n"
11808 + " .long 20b,100b\n"
11809 + " .long 21b,100b\n"
11810 + " .long 22b,100b\n"
11811 + " .long 23b,100b\n"
11812 + " .long 24b,100b\n"
11813 + " .long 25b,100b\n"
11814 + " .long 26b,100b\n"
11815 + " .long 27b,100b\n"
11816 + " .long 28b,100b\n"
11817 + " .long 29b,100b\n"
11818 + " .long 30b,100b\n"
11819 + " .long 31b,100b\n"
11820 + " .long 32b,100b\n"
11821 + " .long 33b,100b\n"
11822 + " .long 34b,100b\n"
11823 + " .long 35b,100b\n"
11824 + " .long 36b,100b\n"
11825 + " .long 37b,100b\n"
11826 + " .long 99b,101b\n"
11828 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11829 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11830 : "eax", "edx", "memory");
11833 @@ -338,6 +464,7 @@ __copy_user_zeroing_intel(void *to, cons
11836 __asm__ __volatile__(
11837 + " movw %w6, %%ds\n"
11839 "0: movl 32(%4), %%eax\n"
11841 @@ -346,36 +473,36 @@ __copy_user_zeroing_intel(void *to, cons
11843 "2: movl 0(%4), %%eax\n"
11844 "21: movl 4(%4), %%edx\n"
11845 - " movl %%eax, 0(%3)\n"
11846 - " movl %%edx, 4(%3)\n"
11847 + " movl %%eax, %%es:0(%3)\n"
11848 + " movl %%edx, %%es:4(%3)\n"
11849 "3: movl 8(%4), %%eax\n"
11850 "31: movl 12(%4),%%edx\n"
11851 - " movl %%eax, 8(%3)\n"
11852 - " movl %%edx, 12(%3)\n"
11853 + " movl %%eax, %%es:8(%3)\n"
11854 + " movl %%edx, %%es:12(%3)\n"
11855 "4: movl 16(%4), %%eax\n"
11856 "41: movl 20(%4), %%edx\n"
11857 - " movl %%eax, 16(%3)\n"
11858 - " movl %%edx, 20(%3)\n"
11859 + " movl %%eax, %%es:16(%3)\n"
11860 + " movl %%edx, %%es:20(%3)\n"
11861 "10: movl 24(%4), %%eax\n"
11862 "51: movl 28(%4), %%edx\n"
11863 - " movl %%eax, 24(%3)\n"
11864 - " movl %%edx, 28(%3)\n"
11865 + " movl %%eax, %%es:24(%3)\n"
11866 + " movl %%edx, %%es:28(%3)\n"
11867 "11: movl 32(%4), %%eax\n"
11868 "61: movl 36(%4), %%edx\n"
11869 - " movl %%eax, 32(%3)\n"
11870 - " movl %%edx, 36(%3)\n"
11871 + " movl %%eax, %%es:32(%3)\n"
11872 + " movl %%edx, %%es:36(%3)\n"
11873 "12: movl 40(%4), %%eax\n"
11874 "71: movl 44(%4), %%edx\n"
11875 - " movl %%eax, 40(%3)\n"
11876 - " movl %%edx, 44(%3)\n"
11877 + " movl %%eax, %%es:40(%3)\n"
11878 + " movl %%edx, %%es:44(%3)\n"
11879 "13: movl 48(%4), %%eax\n"
11880 "81: movl 52(%4), %%edx\n"
11881 - " movl %%eax, 48(%3)\n"
11882 - " movl %%edx, 52(%3)\n"
11883 + " movl %%eax, %%es:48(%3)\n"
11884 + " movl %%edx, %%es:52(%3)\n"
11885 "14: movl 56(%4), %%eax\n"
11886 "91: movl 60(%4), %%edx\n"
11887 - " movl %%eax, 56(%3)\n"
11888 - " movl %%edx, 60(%3)\n"
11889 + " movl %%eax, %%es:56(%3)\n"
11890 + " movl %%edx, %%es:60(%3)\n"
11894 @@ -389,6 +516,8 @@ __copy_user_zeroing_intel(void *to, cons
11900 ".section .fixup,\"ax\"\n"
11901 "9: lea 0(%%eax,%0,4),%0\n"
11903 @@ -423,7 +552,7 @@ __copy_user_zeroing_intel(void *to, cons
11906 : "=&c"(size), "=&D" (d0), "=&S" (d1)
11907 - : "1"(to), "2"(from), "0"(size)
11908 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11909 : "eax", "edx", "memory");
11912 @@ -439,6 +568,7 @@ static unsigned long __copy_user_zeroing
11915 __asm__ __volatile__(
11916 + " movw %w6, %%ds\n"
11918 "0: movl 32(%4), %%eax\n"
11920 @@ -447,36 +577,36 @@ static unsigned long __copy_user_zeroing
11922 "2: movl 0(%4), %%eax\n"
11923 "21: movl 4(%4), %%edx\n"
11924 - " movnti %%eax, 0(%3)\n"
11925 - " movnti %%edx, 4(%3)\n"
11926 + " movnti %%eax, %%es:0(%3)\n"
11927 + " movnti %%edx, %%es:4(%3)\n"
11928 "3: movl 8(%4), %%eax\n"
11929 "31: movl 12(%4),%%edx\n"
11930 - " movnti %%eax, 8(%3)\n"
11931 - " movnti %%edx, 12(%3)\n"
11932 + " movnti %%eax, %%es:8(%3)\n"
11933 + " movnti %%edx, %%es:12(%3)\n"
11934 "4: movl 16(%4), %%eax\n"
11935 "41: movl 20(%4), %%edx\n"
11936 - " movnti %%eax, 16(%3)\n"
11937 - " movnti %%edx, 20(%3)\n"
11938 + " movnti %%eax, %%es:16(%3)\n"
11939 + " movnti %%edx, %%es:20(%3)\n"
11940 "10: movl 24(%4), %%eax\n"
11941 "51: movl 28(%4), %%edx\n"
11942 - " movnti %%eax, 24(%3)\n"
11943 - " movnti %%edx, 28(%3)\n"
11944 + " movnti %%eax, %%es:24(%3)\n"
11945 + " movnti %%edx, %%es:28(%3)\n"
11946 "11: movl 32(%4), %%eax\n"
11947 "61: movl 36(%4), %%edx\n"
11948 - " movnti %%eax, 32(%3)\n"
11949 - " movnti %%edx, 36(%3)\n"
11950 + " movnti %%eax, %%es:32(%3)\n"
11951 + " movnti %%edx, %%es:36(%3)\n"
11952 "12: movl 40(%4), %%eax\n"
11953 "71: movl 44(%4), %%edx\n"
11954 - " movnti %%eax, 40(%3)\n"
11955 - " movnti %%edx, 44(%3)\n"
11956 + " movnti %%eax, %%es:40(%3)\n"
11957 + " movnti %%edx, %%es:44(%3)\n"
11958 "13: movl 48(%4), %%eax\n"
11959 "81: movl 52(%4), %%edx\n"
11960 - " movnti %%eax, 48(%3)\n"
11961 - " movnti %%edx, 52(%3)\n"
11962 + " movnti %%eax, %%es:48(%3)\n"
11963 + " movnti %%edx, %%es:52(%3)\n"
11964 "14: movl 56(%4), %%eax\n"
11965 "91: movl 60(%4), %%edx\n"
11966 - " movnti %%eax, 56(%3)\n"
11967 - " movnti %%edx, 60(%3)\n"
11968 + " movnti %%eax, %%es:56(%3)\n"
11969 + " movnti %%edx, %%es:60(%3)\n"
11973 @@ -491,6 +621,8 @@ static unsigned long __copy_user_zeroing
11979 ".section .fixup,\"ax\"\n"
11980 "9: lea 0(%%eax,%0,4),%0\n"
11982 @@ -525,7 +657,7 @@ static unsigned long __copy_user_zeroing
11985 : "=&c"(size), "=&D" (d0), "=&S" (d1)
11986 - : "1"(to), "2"(from), "0"(size)
11987 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11988 : "eax", "edx", "memory");
11991 @@ -536,6 +668,7 @@ static unsigned long __copy_user_intel_n
11994 __asm__ __volatile__(
11995 + " movw %w6, %%ds\n"
11997 "0: movl 32(%4), %%eax\n"
11999 @@ -544,36 +677,36 @@ static unsigned long __copy_user_intel_n
12001 "2: movl 0(%4), %%eax\n"
12002 "21: movl 4(%4), %%edx\n"
12003 - " movnti %%eax, 0(%3)\n"
12004 - " movnti %%edx, 4(%3)\n"
12005 + " movnti %%eax, %%es:0(%3)\n"
12006 + " movnti %%edx, %%es:4(%3)\n"
12007 "3: movl 8(%4), %%eax\n"
12008 "31: movl 12(%4),%%edx\n"
12009 - " movnti %%eax, 8(%3)\n"
12010 - " movnti %%edx, 12(%3)\n"
12011 + " movnti %%eax, %%es:8(%3)\n"
12012 + " movnti %%edx, %%es:12(%3)\n"
12013 "4: movl 16(%4), %%eax\n"
12014 "41: movl 20(%4), %%edx\n"
12015 - " movnti %%eax, 16(%3)\n"
12016 - " movnti %%edx, 20(%3)\n"
12017 + " movnti %%eax, %%es:16(%3)\n"
12018 + " movnti %%edx, %%es:20(%3)\n"
12019 "10: movl 24(%4), %%eax\n"
12020 "51: movl 28(%4), %%edx\n"
12021 - " movnti %%eax, 24(%3)\n"
12022 - " movnti %%edx, 28(%3)\n"
12023 + " movnti %%eax, %%es:24(%3)\n"
12024 + " movnti %%edx, %%es:28(%3)\n"
12025 "11: movl 32(%4), %%eax\n"
12026 "61: movl 36(%4), %%edx\n"
12027 - " movnti %%eax, 32(%3)\n"
12028 - " movnti %%edx, 36(%3)\n"
12029 + " movnti %%eax, %%es:32(%3)\n"
12030 + " movnti %%edx, %%es:36(%3)\n"
12031 "12: movl 40(%4), %%eax\n"
12032 "71: movl 44(%4), %%edx\n"
12033 - " movnti %%eax, 40(%3)\n"
12034 - " movnti %%edx, 44(%3)\n"
12035 + " movnti %%eax, %%es:40(%3)\n"
12036 + " movnti %%edx, %%es:44(%3)\n"
12037 "13: movl 48(%4), %%eax\n"
12038 "81: movl 52(%4), %%edx\n"
12039 - " movnti %%eax, 48(%3)\n"
12040 - " movnti %%edx, 52(%3)\n"
12041 + " movnti %%eax, %%es:48(%3)\n"
12042 + " movnti %%edx, %%es:52(%3)\n"
12043 "14: movl 56(%4), %%eax\n"
12044 "91: movl 60(%4), %%edx\n"
12045 - " movnti %%eax, 56(%3)\n"
12046 - " movnti %%edx, 60(%3)\n"
12047 + " movnti %%eax, %%es:56(%3)\n"
12048 + " movnti %%edx, %%es:60(%3)\n"
12052 @@ -588,6 +721,8 @@ static unsigned long __copy_user_intel_n
12058 ".section .fixup,\"ax\"\n"
12059 "9: lea 0(%%eax,%0,4),%0\n"
12061 @@ -616,7 +751,7 @@ static unsigned long __copy_user_intel_n
12064 : "=&c"(size), "=&D" (d0), "=&S" (d1)
12065 - : "1"(to), "2"(from), "0"(size)
12066 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
12067 : "eax", "edx", "memory");
12070 @@ -629,90 +764,146 @@ static unsigned long __copy_user_intel_n
12072 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
12073 unsigned long size);
12074 -unsigned long __copy_user_intel(void __user *to, const void *from,
12075 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
12076 + unsigned long size);
12077 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
12078 unsigned long size);
12079 unsigned long __copy_user_zeroing_intel_nocache(void *to,
12080 const void __user *from, unsigned long size);
12081 #endif /* CONFIG_X86_INTEL_USERCOPY */
12083 /* Generic arbitrary sized copy. */
12084 -#define __copy_user(to, from, size) \
12086 - int __d0, __d1, __d2; \
12087 - __asm__ __volatile__( \
12090 - " movl %1,%0\n" \
12092 - " andl $7,%0\n" \
12093 - " subl %0,%3\n" \
12094 - "4: rep; movsb\n" \
12095 - " movl %3,%0\n" \
12096 - " shrl $2,%0\n" \
12097 - " andl $3,%3\n" \
12098 - " .align 2,0x90\n" \
12099 - "0: rep; movsl\n" \
12100 - " movl %3,%0\n" \
12101 - "1: rep; movsb\n" \
12103 - ".section .fixup,\"ax\"\n" \
12104 - "5: addl %3,%0\n" \
12106 - "3: lea 0(%3,%0,4),%0\n" \
12109 - ".section __ex_table,\"a\"\n" \
12111 - " .long 4b,5b\n" \
12112 - " .long 0b,3b\n" \
12113 - " .long 1b,2b\n" \
12115 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
12116 - : "3"(size), "0"(size), "1"(to), "2"(from) \
12120 -#define __copy_user_zeroing(to, from, size) \
12122 - int __d0, __d1, __d2; \
12123 - __asm__ __volatile__( \
12126 - " movl %1,%0\n" \
12128 - " andl $7,%0\n" \
12129 - " subl %0,%3\n" \
12130 - "4: rep; movsb\n" \
12131 - " movl %3,%0\n" \
12132 - " shrl $2,%0\n" \
12133 - " andl $3,%3\n" \
12134 - " .align 2,0x90\n" \
12135 - "0: rep; movsl\n" \
12136 - " movl %3,%0\n" \
12137 - "1: rep; movsb\n" \
12139 - ".section .fixup,\"ax\"\n" \
12140 - "5: addl %3,%0\n" \
12142 - "3: lea 0(%3,%0,4),%0\n" \
12143 - "6: pushl %0\n" \
12144 - " pushl %%eax\n" \
12145 - " xorl %%eax,%%eax\n" \
12146 - " rep; stosb\n" \
12147 - " popl %%eax\n" \
12151 - ".section __ex_table,\"a\"\n" \
12153 - " .long 4b,5b\n" \
12154 - " .long 0b,3b\n" \
12155 - " .long 1b,6b\n" \
12157 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
12158 - : "3"(size), "0"(size), "1"(to), "2"(from) \
12161 +static unsigned long
12162 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
12164 + int __d0, __d1, __d2;
12166 + __asm__ __volatile__(
12167 + " movw %w8,%%es\n"
12174 + "4: rep; movsb\n"
12178 + " .align 2,0x90\n"
12179 + "0: rep; movsl\n"
12181 + "1: rep; movsb\n"
12185 + ".section .fixup,\"ax\"\n"
12186 + "5: addl %3,%0\n"
12188 + "3: lea 0(%3,%0,4),%0\n"
12191 + ".section __ex_table,\"a\"\n"
12197 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
12198 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
12203 +static unsigned long
12204 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
12206 + int __d0, __d1, __d2;
12208 + __asm__ __volatile__(
12209 + " movw %w8,%%ds\n"
12216 + "4: rep; movsb\n"
12220 + " .align 2,0x90\n"
12221 + "0: rep; movsl\n"
12223 + "1: rep; movsb\n"
12227 + ".section .fixup,\"ax\"\n"
12228 + "5: addl %3,%0\n"
12230 + "3: lea 0(%3,%0,4),%0\n"
12233 + ".section __ex_table,\"a\"\n"
12239 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
12240 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
12245 +static unsigned long
12246 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
12248 + int __d0, __d1, __d2;
12250 + __asm__ __volatile__(
12251 + " movw %w8,%%ds\n"
12258 + "4: rep; movsb\n"
12262 + " .align 2,0x90\n"
12263 + "0: rep; movsl\n"
12265 + "1: rep; movsb\n"
12269 + ".section .fixup,\"ax\"\n"
12270 + "5: addl %3,%0\n"
12272 + "3: lea 0(%3,%0,4),%0\n"
12275 + " xorl %%eax,%%eax\n"
12281 + ".section __ex_table,\"a\"\n"
12287 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
12288 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
12293 unsigned long __copy_to_user_ll(void __user *to, const void *from,
12295 @@ -775,9 +966,9 @@ survive:
12298 if (movsl_is_ok(to, from, n))
12299 - __copy_user(to, from, n);
12300 + n = __generic_copy_to_user(to, from, n);
12302 - n = __copy_user_intel(to, from, n);
12303 + n = __generic_copy_to_user_intel(to, from, n);
12306 EXPORT_SYMBOL(__copy_to_user_ll);
12307 @@ -786,7 +977,7 @@ unsigned long __copy_from_user_ll(void *
12310 if (movsl_is_ok(to, from, n))
12311 - __copy_user_zeroing(to, from, n);
12312 + n = __copy_user_zeroing(to, from, n);
12314 n = __copy_user_zeroing_intel(to, from, n);
12316 @@ -797,10 +988,9 @@ unsigned long __copy_from_user_ll_nozero
12319 if (movsl_is_ok(to, from, n))
12320 - __copy_user(to, from, n);
12321 + n = __generic_copy_from_user(to, from, n);
12323 - n = __copy_user_intel((void __user *)to,
12324 - (const void *)from, n);
12325 + n = __generic_copy_from_user_intel(to, from, n);
12328 EXPORT_SYMBOL(__copy_from_user_ll_nozero);
12329 @@ -812,9 +1002,9 @@ unsigned long __copy_from_user_ll_nocach
12330 if (n > 64 && cpu_has_xmm2)
12331 n = __copy_user_zeroing_intel_nocache(to, from, n);
12333 - __copy_user_zeroing(to, from, n);
12334 + n = __copy_user_zeroing(to, from, n);
12336 - __copy_user_zeroing(to, from, n);
12337 + n = __copy_user_zeroing(to, from, n);
12341 @@ -827,9 +1017,9 @@ unsigned long __copy_from_user_ll_nocach
12342 if (n > 64 && cpu_has_xmm2)
12343 n = __copy_user_intel_nocache(to, from, n);
12345 - __copy_user(to, from, n);
12346 + n = __generic_copy_from_user(to, from, n);
12348 - __copy_user(to, from, n);
12349 + n = __generic_copy_from_user(to, from, n);
12353 @@ -878,8 +1068,35 @@ copy_from_user(void *to, const void __us
12355 if (access_ok(VERIFY_READ, from, n))
12356 n = __copy_from_user(to, from, n);
12358 + else if ((long)n > 0)
12362 EXPORT_SYMBOL(copy_from_user);
12364 +#ifdef CONFIG_PAX_MEMORY_UDEREF
12365 +void __set_fs(mm_segment_t x, int cpu)
12367 + unsigned long limit = x.seg;
12368 + struct desc_struct d;
12370 + current_thread_info()->addr_limit = x;
12371 + if (likely(limit))
12372 + limit = (limit - 1UL) >> PAGE_SHIFT;
12373 + pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
12374 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
12377 +void set_fs(mm_segment_t x)
12379 + __set_fs(x, get_cpu());
12380 + put_cpu_no_resched();
12383 +void set_fs(mm_segment_t x)
12385 + current_thread_info()->addr_limit = x;
12389 +EXPORT_SYMBOL(set_fs);
12390 diff -urNp linux-2.6.29/arch/x86/mach-voyager/voyager_basic.c linux-2.6.29/arch/x86/mach-voyager/voyager_basic.c
12391 --- linux-2.6.29/arch/x86/mach-voyager/voyager_basic.c 2009-03-23 19:12:14.000000000 -0400
12392 +++ linux-2.6.29/arch/x86/mach-voyager/voyager_basic.c 2009-03-28 14:26:19.000000000 -0400
12393 @@ -123,7 +123,7 @@ int __init voyager_memory_detect(int reg
12396 unsigned long map_addr;
12397 - unsigned long old;
12400 if (region >= CLICK_ENTRIES) {
12401 printk("Voyager: Illegal ClickMap region %d\n", region);
12402 @@ -138,7 +138,7 @@ int __init voyager_memory_detect(int reg
12404 /* steal page 0 for this */
12406 - pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
12407 + pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
12409 /* now clear everything out but page 0 */
12410 map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
12411 diff -urNp linux-2.6.29/arch/x86/mach-voyager/voyager_smp.c linux-2.6.29/arch/x86/mach-voyager/voyager_smp.c
12412 --- linux-2.6.29/arch/x86/mach-voyager/voyager_smp.c 2009-03-23 19:12:14.000000000 -0400
12413 +++ linux-2.6.29/arch/x86/mach-voyager/voyager_smp.c 2009-03-28 14:26:19.000000000 -0400
12414 @@ -511,6 +511,10 @@ static void __init do_boot_cpu(__u8 cpu)
12415 __u32 *hijack_vector;
12416 __u32 start_phys_address = setup_trampoline();
12418 +#ifdef CONFIG_PAX_KERNEXEC
12419 + unsigned long cr0;
12422 /* There's a clever trick to this: The linux trampoline is
12423 * compiled to begin at absolute location zero, so make the
12424 * address zero but have the data segment selector compensate
12425 @@ -530,7 +534,17 @@ static void __init do_boot_cpu(__u8 cpu)
12428 per_cpu(current_task, cpu) = idle;
12429 - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
12431 +#ifdef CONFIG_PAX_KERNEXEC
12432 + pax_open_kernel(cr0);
12435 + early_gdt_descr.address = get_cpu_gdt_table(cpu);
12437 +#ifdef CONFIG_PAX_KERNEXEC
12438 + pax_close_kernel(cr0);
12443 /* Note: Don't modify initial ss override */
12444 @@ -1144,7 +1158,7 @@ void smp_local_timer_interrupt(void)
12445 per_cpu(prof_counter, cpu);
12448 - update_process_times(user_mode_vm(get_irq_regs()));
12449 + update_process_times(user_mode(get_irq_regs()));
12452 if (((1 << cpu) & voyager_extended_vic_processors) == 0)
12453 diff -urNp linux-2.6.29/arch/x86/Makefile linux-2.6.29/arch/x86/Makefile
12454 --- linux-2.6.29/arch/x86/Makefile 2009-03-23 19:12:14.000000000 -0400
12455 +++ linux-2.6.29/arch/x86/Makefile 2009-03-28 14:26:19.000000000 -0400
12456 @@ -232,3 +232,12 @@ endef
12457 CLEAN_FILES += arch/x86/boot/fdimage \
12458 arch/x86/boot/image.iso \
12459 arch/x86/boot/mtools.conf
12463 +*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
12464 +*** Please upgrade your binutils to 2.18 or newer
12468 + $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
12469 diff -urNp linux-2.6.29/arch/x86/mm/extable.c linux-2.6.29/arch/x86/mm/extable.c
12470 --- linux-2.6.29/arch/x86/mm/extable.c 2009-03-23 19:12:14.000000000 -0400
12471 +++ linux-2.6.29/arch/x86/mm/extable.c 2009-03-28 14:26:19.000000000 -0400
12473 #include <linux/module.h>
12474 #include <linux/spinlock.h>
12475 +#include <linux/sort.h>
12476 #include <asm/uaccess.h>
12479 + * The exception table needs to be sorted so that the binary
12480 + * search that we use to find entries in it works properly.
12481 + * This is used both for the kernel exception table and for
12482 + * the exception tables of modules that get loaded.
12484 +static int cmp_ex(const void *a, const void *b)
12486 + const struct exception_table_entry *x = a, *y = b;
12488 + /* avoid overflow */
12489 + if (x->insn > y->insn)
12491 + if (x->insn < y->insn)
12496 +static void swap_ex(void *a, void *b, int size)
12498 + struct exception_table_entry t, *x = a, *y = b;
12500 +#ifdef CONFIG_PAX_KERNEXEC
12501 + unsigned long cr0;
12506 +#ifdef CONFIG_PAX_KERNEXEC
12507 + pax_open_kernel(cr0);
12513 +#ifdef CONFIG_PAX_KERNEXEC
12514 + pax_close_kernel(cr0);
12519 +void sort_extable(struct exception_table_entry *start,
12520 + struct exception_table_entry *finish)
12522 + sort(start, finish - start, sizeof(struct exception_table_entry),
12523 + cmp_ex, swap_ex);
12526 int fixup_exception(struct pt_regs *regs)
12528 const struct exception_table_entry *fixup;
12530 #ifdef CONFIG_PNPBIOS
12531 - if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
12532 + if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
12533 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
12534 extern u32 pnp_bios_is_utter_crap;
12535 pnp_bios_is_utter_crap = 1;
12536 diff -urNp linux-2.6.29/arch/x86/mm/fault.c linux-2.6.29/arch/x86/mm/fault.c
12537 --- linux-2.6.29/arch/x86/mm/fault.c 2009-03-23 19:12:14.000000000 -0400
12538 +++ linux-2.6.29/arch/x86/mm/fault.c 2009-03-28 14:26:19.000000000 -0400
12540 #include <linux/kprobes.h>
12541 #include <linux/uaccess.h>
12542 #include <linux/kdebug.h>
12543 +#include <linux/unistd.h>
12544 +#include <linux/compiler.h>
12546 #include <asm/system.h>
12547 #include <asm/desc.h>
12548 @@ -67,7 +69,7 @@ static inline int notify_page_fault(stru
12551 /* kprobe_running() needs smp_processor_id() */
12552 - if (!user_mode_vm(regs)) {
12553 + if (!user_mode(regs)) {
12555 if (kprobe_running() && kprobe_fault_handler(regs, 14))
12557 @@ -265,6 +267,30 @@ bad:
12561 +#ifdef CONFIG_PAX_EMUTRAMP
12562 +static int pax_handle_fetch_fault(struct pt_regs *regs);
12565 +#ifdef CONFIG_PAX_PAGEEXEC
12566 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
12572 + pgd = pgd_offset(mm, address);
12573 + if (!pgd_present(*pgd))
12575 + pud = pud_offset(pgd, address);
12576 + if (!pud_present(*pud))
12578 + pmd = pmd_offset(pud, address);
12579 + if (!pmd_present(*pmd))
12585 #ifdef CONFIG_X86_32
12586 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
12588 @@ -351,7 +377,7 @@ static int is_errata93(struct pt_regs *r
12589 static int is_errata100(struct pt_regs *regs, unsigned long address)
12591 #ifdef CONFIG_X86_64
12592 - if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
12593 + if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
12597 @@ -386,14 +412,31 @@ static void show_fault_oops(struct pt_re
12600 #ifdef CONFIG_X86_PAE
12601 - if (error_code & PF_INSTR) {
12602 + if (nx_enabled && (error_code & PF_INSTR)) {
12603 unsigned int level;
12604 pte_t *pte = lookup_address(address, &level);
12606 if (pte && pte_present(*pte) && !pte_exec(*pte))
12607 printk(KERN_CRIT "kernel tried to execute "
12608 "NX-protected page - exploit attempt? "
12609 - "(uid: %d)\n", current_uid());
12610 + "(uid: %d, task: %s, pid: %d)\n",
12611 + current_uid(), current->comm, task_pid_nr(current));
12615 +#ifdef CONFIG_PAX_KERNEXEC
12616 +#ifdef CONFIG_MODULES
12617 + if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
12619 + if (init_mm.start_code <= address && address < init_mm.end_code)
12622 + if (current->signal->curr_ip)
12623 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
12624 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current_uid(), current_euid());
12626 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
12627 + current->comm, task_pid_nr(current), current_uid(), current_euid());
12631 @@ -586,7 +629,6 @@ void __kprobes do_page_fault(struct pt_r
12632 struct task_struct *tsk;
12633 struct mm_struct *mm;
12634 struct vm_area_struct *vma;
12635 - unsigned long address;
12636 int write, si_code;
12638 #ifdef CONFIG_X86_64
12639 @@ -594,13 +636,20 @@ void __kprobes do_page_fault(struct pt_r
12643 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
12647 + unsigned char pte_mask;
12650 + /* get the address */
12651 + const unsigned long address = read_cr2();
12655 prefetchw(&mm->mmap_sem);
12657 - /* get the address */
12658 - address = read_cr2();
12660 si_code = SEGV_MAPERR;
12662 if (unlikely(kmmio_fault(regs, address)))
12663 @@ -653,7 +702,7 @@ void __kprobes do_page_fault(struct pt_r
12664 * User-mode registers count as a user access even for any
12665 * potential system fault or CPU buglet.
12667 - if (user_mode_vm(regs)) {
12668 + if (user_mode(regs)) {
12669 local_irq_enable();
12670 error_code |= PF_USER;
12671 } else if (regs->flags & X86_EFLAGS_IF)
12672 @@ -669,7 +718,7 @@ void __kprobes do_page_fault(struct pt_r
12673 * atomic region then we must not take the fault.
12675 if (unlikely(in_atomic() || !mm))
12676 - goto bad_area_nosemaphore;
12677 + goto bad_area_nopax;
12680 * When running in the kernel we expect faults to occur only to
12681 @@ -690,10 +739,104 @@ void __kprobes do_page_fault(struct pt_r
12682 if (!down_read_trylock(&mm->mmap_sem)) {
12683 if ((error_code & PF_USER) == 0 &&
12684 !search_exception_tables(regs->ip))
12685 - goto bad_area_nosemaphore;
12686 + goto bad_area_nopax;
12687 down_read(&mm->mmap_sem);
12690 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
12691 + if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
12692 + !(mm->pax_flags & MF_PAX_PAGEEXEC))
12693 + goto not_pax_fault;
12695 + /* PaX: it's our fault, let's handle it if we can */
12697 + /* PaX: take a look at read faults before acquiring any locks */
12698 + if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
12699 + /* instruction fetch attempt from a protected page in user mode */
12700 + up_read(&mm->mmap_sem);
12702 +#ifdef CONFIG_PAX_EMUTRAMP
12703 + switch (pax_handle_fetch_fault(regs)) {
12709 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12710 + do_group_exit(SIGKILL);
12713 + pmd = pax_get_pmd(mm, address);
12714 + if (unlikely(!pmd))
12715 + goto not_pax_fault;
12717 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
12718 + if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
12719 + pte_unmap_unlock(pte, ptl);
12720 + goto not_pax_fault;
12723 + if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
12724 + /* write attempt to a protected page in user mode */
12725 + pte_unmap_unlock(pte, ptl);
12726 + goto not_pax_fault;
12730 + if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
12732 + if (likely(address > get_limit(regs->cs)))
12735 + set_pte(pte, pte_mkread(*pte));
12736 + __flush_tlb_one(address);
12737 + pte_unmap_unlock(pte, ptl);
12738 + up_read(&mm->mmap_sem);
12742 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
12745 + * PaX: fill DTLB with user rights and retry
12747 + __asm__ __volatile__ (
12748 +#ifdef CONFIG_PAX_MEMORY_UDEREF
12749 + "movw %w4,%%es\n"
12752 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
12754 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
12755 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
12756 + * page fault when examined during a TLB load attempt. this is true not only
12757 + * for PTEs holding a non-present entry but also present entries that will
12758 + * raise a page fault (such as those set up by PaX, or the copy-on-write
12759 + * mechanism). in effect it means that we do *not* need to flush the TLBs
12760 + * for our target pages since their PTEs are simply not in the TLBs at all.
12762 + * the best thing in omitting it is that we gain around 15-20% speed in the
12763 + * fast path of the page fault handler and can get rid of tracing since we
12764 + * can no longer flush unintended entries.
12768 + "testb $0,%%es:(%0)\n"
12770 +#ifdef CONFIG_PAX_MEMORY_UDEREF
12775 + : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
12776 + : "memory", "cc");
12777 + pte_unmap_unlock(pte, ptl);
12778 + up_read(&mm->mmap_sem);
12784 vma = find_vma(mm, address);
12787 @@ -701,16 +844,20 @@ void __kprobes do_page_fault(struct pt_r
12789 if (!(vma->vm_flags & VM_GROWSDOWN))
12791 - if (error_code & PF_USER) {
12793 - * Accessing the stack below %sp is always a bug.
12794 - * The large cushion allows instructions like enter
12795 - * and pusha to work. ("enter $65535,$31" pushes
12796 - * 32 pointers and then decrements %sp by 65535.)
12798 - if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
12802 + * Accessing the stack below %sp is always a bug.
12803 + * The large cushion allows instructions like enter
12804 + * and pusha to work. ("enter $65535,$31" pushes
12805 + * 32 pointers and then decrements %sp by 65535.)
12807 + if (address + 65536 + 32 * sizeof(unsigned long) < task_pt_regs(tsk)->sp)
12810 +#ifdef CONFIG_PAX_SEGMEXEC
12811 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
12815 if (expand_stack(vma, address))
12818 @@ -720,6 +867,8 @@ void __kprobes do_page_fault(struct pt_r
12820 si_code = SEGV_ACCERR;
12822 + if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
12824 switch (error_code & (PF_PROT|PF_WRITE)) {
12825 default: /* 3: write, present */
12827 @@ -774,6 +923,54 @@ bad_area:
12828 up_read(&mm->mmap_sem);
12830 bad_area_nosemaphore:
12832 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12833 + if (mm && (error_code & PF_USER)) {
12834 + unsigned long ip = regs->ip;
12836 + if (v8086_mode(regs))
12837 + ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
12840 + * It's possible to have interrupts off here.
12842 + local_irq_enable();
12844 +#ifdef CONFIG_PAX_PAGEEXEC
12845 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
12846 + ((nx_enabled && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && regs->ip == address))) {
12848 +#ifdef CONFIG_PAX_EMUTRAMP
12849 + switch (pax_handle_fetch_fault(regs)) {
12855 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12856 + do_group_exit(SIGKILL);
12860 +#ifdef CONFIG_PAX_SEGMEXEC
12861 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
12863 +#ifdef CONFIG_PAX_EMUTRAMP
12864 + switch (pax_handle_fetch_fault(regs)) {
12870 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12871 + do_group_exit(SIGKILL);
12879 /* User mode accesses just cause a SIGSEGV */
12880 if (error_code & PF_USER) {
12882 @@ -852,7 +1049,7 @@ no_context:
12883 #ifdef CONFIG_X86_32
12884 die("Oops", regs, error_code);
12886 - do_exit(SIGKILL);
12887 + do_group_exit(SIGKILL);
12890 if (__die("Oops", regs, error_code))
12891 @@ -935,3 +1132,174 @@ void vmalloc_sync_all(void)
12896 +#ifdef CONFIG_PAX_EMUTRAMP
12897 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
12901 + do { /* PaX: gcc trampoline emulation #1 */
12902 + unsigned char mov1, mov2;
12903 + unsigned short jmp;
12904 + unsigned int addr1, addr2;
12906 +#ifdef CONFIG_X86_64
12907 + if ((regs->ip + 11) >> 32)
12911 + err = get_user(mov1, (unsigned char __user *)regs->ip);
12912 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
12913 + err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
12914 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
12915 + err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
12920 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
12921 + regs->cx = addr1;
12922 + regs->ax = addr2;
12923 + regs->ip = addr2;
12928 + do { /* PaX: gcc trampoline emulation #2 */
12929 + unsigned char mov, jmp;
12930 + unsigned int addr1, addr2;
12932 +#ifdef CONFIG_X86_64
12933 + if ((regs->ip + 9) >> 32)
12937 + err = get_user(mov, (unsigned char __user *)regs->ip);
12938 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
12939 + err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
12940 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
12945 + if (mov == 0xB9 && jmp == 0xE9) {
12946 + regs->cx = addr1;
12947 + regs->ip = (unsigned int)(regs->ip + addr2 + 10);
12952 + return 1; /* PaX in action */
12955 +#ifdef CONFIG_X86_64
12956 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
12960 + do { /* PaX: gcc trampoline emulation #1 */
12961 + unsigned short mov1, mov2, jmp1;
12962 + unsigned char jmp2;
12963 + unsigned int addr1;
12964 + unsigned long addr2;
12966 + err = get_user(mov1, (unsigned short __user *)regs->ip);
12967 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
12968 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
12969 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
12970 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
12971 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
12976 + if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
12977 + regs->r11 = addr1;
12978 + regs->r10 = addr2;
12979 + regs->ip = addr1;
12984 + do { /* PaX: gcc trampoline emulation #2 */
12985 + unsigned short mov1, mov2, jmp1;
12986 + unsigned char jmp2;
12987 + unsigned long addr1, addr2;
12989 + err = get_user(mov1, (unsigned short __user *)regs->ip);
12990 + err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
12991 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
12992 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
12993 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
12994 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
12999 + if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
13000 + regs->r11 = addr1;
13001 + regs->r10 = addr2;
13002 + regs->ip = addr1;
13007 + return 1; /* PaX in action */
13012 + * PaX: decide what to do with offenders (regs->ip = fault address)
13014 + * returns 1 when task should be killed
13015 + * 2 when gcc trampoline was detected
13017 +static int pax_handle_fetch_fault(struct pt_regs *regs)
13019 + if (v8086_mode(regs))
13022 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
13025 +#ifdef CONFIG_X86_32
13026 + return pax_handle_fetch_fault_32(regs);
13028 + if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
13029 + return pax_handle_fetch_fault_32(regs);
13031 + return pax_handle_fetch_fault_64(regs);
13036 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13037 +void pax_report_insns(void *pc, void *sp)
13041 + printk(KERN_ERR "PAX: bytes at PC: ");
13042 + for (i = 0; i < 20; i++) {
13044 + if (get_user(c, (unsigned char __user *)pc+i))
13045 + printk(KERN_CONT "?? ");
13047 + printk(KERN_CONT "%02x ", c);
13051 + printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
13052 + for (i = -1; i < 80 / sizeof(long); i++) {
13054 + if (get_user(c, (unsigned long __user *)sp+i))
13055 +#ifdef CONFIG_X86_32
13056 + printk(KERN_CONT "???????? ");
13058 + printk(KERN_CONT "???????????????? ");
13061 + printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
13066 diff -urNp linux-2.6.29/arch/x86/mm/highmem_32.c linux-2.6.29/arch/x86/mm/highmem_32.c
13067 --- linux-2.6.29/arch/x86/mm/highmem_32.c 2009-03-23 19:12:14.000000000 -0400
13068 +++ linux-2.6.29/arch/x86/mm/highmem_32.c 2009-03-28 14:26:19.000000000 -0400
13069 @@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
13070 enum fixed_addresses idx;
13071 unsigned long vaddr;
13073 +#ifdef CONFIG_PAX_KERNEXEC
13074 + unsigned long cr0;
13077 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
13078 pagefault_disable();
13080 @@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
13081 idx = type + KM_TYPE_NR*smp_processor_id();
13082 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
13083 BUG_ON(!pte_none(*(kmap_pte-idx)));
13085 +#ifdef CONFIG_PAX_KERNEXEC
13086 + pax_open_kernel(cr0);
13089 set_pte(kmap_pte-idx, mk_pte(page, prot));
13091 +#ifdef CONFIG_PAX_KERNEXEC
13092 + pax_close_kernel(cr0);
13095 arch_flush_lazy_mmu_mode();
13097 return (void *)vaddr;
13098 @@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
13099 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
13100 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
13102 +#ifdef CONFIG_PAX_KERNEXEC
13103 + unsigned long cr0;
13107 * Force other mappings to Oops if they'll try to access this pte
13108 * without first remap it. Keeping stale mappings around is a bad idea
13109 * also, in case the page changes cacheability attributes or becomes
13110 * a protected page in a hypervisor.
13112 - if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
13113 + if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
13115 +#ifdef CONFIG_PAX_KERNEXEC
13116 + pax_open_kernel(cr0);
13119 kpte_clear_flush(kmap_pte-idx, vaddr);
13122 +#ifdef CONFIG_PAX_KERNEXEC
13123 + pax_close_kernel(cr0);
13127 #ifdef CONFIG_DEBUG_HIGHMEM
13128 BUG_ON(vaddr < PAGE_OFFSET);
13129 BUG_ON(vaddr >= (unsigned long)high_memory);
13130 @@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
13131 enum fixed_addresses idx;
13132 unsigned long vaddr;
13134 +#ifdef CONFIG_PAX_KERNEXEC
13135 + unsigned long cr0;
13138 pagefault_disable();
13140 idx = type + KM_TYPE_NR*smp_processor_id();
13141 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
13143 +#ifdef CONFIG_PAX_KERNEXEC
13144 + pax_open_kernel(cr0);
13147 set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
13149 +#ifdef CONFIG_PAX_KERNEXEC
13150 + pax_close_kernel(cr0);
13153 arch_flush_lazy_mmu_mode();
13155 return (void*) vaddr;
13156 diff -urNp linux-2.6.29/arch/x86/mm/hugetlbpage.c linux-2.6.29/arch/x86/mm/hugetlbpage.c
13157 --- linux-2.6.29/arch/x86/mm/hugetlbpage.c 2009-03-23 19:12:14.000000000 -0400
13158 +++ linux-2.6.29/arch/x86/mm/hugetlbpage.c 2009-03-28 14:26:19.000000000 -0400
13159 @@ -263,13 +263,18 @@ static unsigned long hugetlb_get_unmappe
13160 struct hstate *h = hstate_file(file);
13161 struct mm_struct *mm = current->mm;
13162 struct vm_area_struct *vma;
13163 - unsigned long start_addr;
13164 + unsigned long start_addr, pax_task_size = TASK_SIZE;
13166 +#ifdef CONFIG_PAX_SEGMEXEC
13167 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
13168 + pax_task_size = SEGMEXEC_TASK_SIZE;
13171 if (len > mm->cached_hole_size) {
13172 - start_addr = mm->free_area_cache;
13173 + start_addr = mm->free_area_cache;
13175 - start_addr = TASK_UNMAPPED_BASE;
13176 - mm->cached_hole_size = 0;
13177 + start_addr = mm->mmap_base;
13178 + mm->cached_hole_size = 0;
13182 @@ -277,13 +282,13 @@ full_search:
13184 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
13185 /* At this point: (!vma || addr < vma->vm_end). */
13186 - if (TASK_SIZE - len < addr) {
13187 + if (pax_task_size - len < addr) {
13189 * Start a new search - just in case we missed
13192 - if (start_addr != TASK_UNMAPPED_BASE) {
13193 - start_addr = TASK_UNMAPPED_BASE;
13194 + if (start_addr != mm->mmap_base) {
13195 + start_addr = mm->mmap_base;
13196 mm->cached_hole_size = 0;
13199 @@ -306,9 +311,8 @@ static unsigned long hugetlb_get_unmappe
13200 struct hstate *h = hstate_file(file);
13201 struct mm_struct *mm = current->mm;
13202 struct vm_area_struct *vma, *prev_vma;
13203 - unsigned long base = mm->mmap_base, addr = addr0;
13204 + unsigned long base = mm->mmap_base, addr;
13205 unsigned long largest_hole = mm->cached_hole_size;
13206 - int first_time = 1;
13208 /* don't allow allocations above current base */
13209 if (mm->free_area_cache > base)
13210 @@ -318,7 +322,7 @@ static unsigned long hugetlb_get_unmappe
13212 mm->free_area_cache = base;
13216 /* make sure it can fit in the remaining address space */
13217 if (mm->free_area_cache < len)
13219 @@ -360,22 +364,26 @@ try_again:
13223 - * if hint left us with no space for the requested
13224 - * mapping then try again:
13226 - if (first_time) {
13227 - mm->free_area_cache = base;
13228 - largest_hole = 0;
13233 * A failed mmap() very likely causes application failure,
13234 * so fall back to the bottom-up function here. This scenario
13235 * can happen with large stack limits and large mmap()
13238 - mm->free_area_cache = TASK_UNMAPPED_BASE;
13240 +#ifdef CONFIG_PAX_SEGMEXEC
13241 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
13242 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
13246 + mm->mmap_base = TASK_UNMAPPED_BASE;
13248 +#ifdef CONFIG_PAX_RANDMMAP
13249 + if (mm->pax_flags & MF_PAX_RANDMMAP)
13250 + mm->mmap_base += mm->delta_mmap;
13253 + mm->free_area_cache = mm->mmap_base;
13254 mm->cached_hole_size = ~0UL;
13255 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
13256 len, pgoff, flags);
13257 @@ -383,6 +391,7 @@ fail:
13259 * Restore the topdown base:
13261 + mm->mmap_base = base;
13262 mm->free_area_cache = base;
13263 mm->cached_hole_size = ~0UL;
13265 @@ -396,10 +405,17 @@ hugetlb_get_unmapped_area(struct file *f
13266 struct hstate *h = hstate_file(file);
13267 struct mm_struct *mm = current->mm;
13268 struct vm_area_struct *vma;
13269 + unsigned long pax_task_size = TASK_SIZE;
13271 if (len & ~huge_page_mask(h))
13273 - if (len > TASK_SIZE)
13275 +#ifdef CONFIG_PAX_SEGMEXEC
13276 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
13277 + pax_task_size = SEGMEXEC_TASK_SIZE;
13280 + if (len > pax_task_size)
13283 if (flags & MAP_FIXED) {
13284 @@ -411,7 +427,7 @@ hugetlb_get_unmapped_area(struct file *f
13286 addr = ALIGN(addr, huge_page_size(h));
13287 vma = find_vma(mm, addr);
13288 - if (TASK_SIZE - len >= addr &&
13289 + if (pax_task_size - len >= addr &&
13290 (!vma || addr + len <= vma->vm_start))
13293 diff -urNp linux-2.6.29/arch/x86/mm/init_32.c linux-2.6.29/arch/x86/mm/init_32.c
13294 --- linux-2.6.29/arch/x86/mm/init_32.c 2009-03-23 19:12:14.000000000 -0400
13295 +++ linux-2.6.29/arch/x86/mm/init_32.c 2009-03-28 14:26:19.000000000 -0400
13297 #include <asm/setup.h>
13298 #include <asm/cacheflush.h>
13299 #include <asm/smp.h>
13300 +#include <asm/desc.h>
13302 unsigned int __VMALLOC_RESERVE = 128 << 20;
13304 @@ -82,36 +83,6 @@ static __init void *alloc_low_page(void)
13308 - * Creates a middle page table and puts a pointer to it in the
13309 - * given global directory entry. This only returns the gd entry
13310 - * in non-PAE compilation mode, since the middle layer is folded.
13312 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
13315 - pmd_t *pmd_table;
13317 -#ifdef CONFIG_X86_PAE
13318 - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
13319 - if (after_init_bootmem)
13320 - pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
13322 - pmd_table = (pmd_t *)alloc_low_page();
13323 - paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
13324 - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
13325 - pud = pud_offset(pgd, 0);
13326 - BUG_ON(pmd_table != pmd_offset(pud, 0));
13328 - return pmd_table;
13331 - pud = pud_offset(pgd, 0);
13332 - pmd_table = pmd_offset(pud, 0);
13334 - return pmd_table;
13338 * Create a page table and place a pointer to it in a middle page
13341 @@ -131,7 +102,11 @@ static pte_t * __init one_page_table_ini
13342 page_table = (pte_t *)alloc_low_page();
13344 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
13345 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13346 + set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
13348 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
13350 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
13353 @@ -194,6 +169,7 @@ page_table_range_init(unsigned long star
13354 int pgd_idx, pmd_idx;
13355 unsigned long vaddr;
13361 @@ -203,8 +179,13 @@ page_table_range_init(unsigned long star
13362 pgd = pgd_base + pgd_idx;
13364 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
13365 - pmd = one_md_table_init(pgd);
13366 - pmd = pmd + pmd_index(vaddr);
13367 + pud = pud_offset(pgd, vaddr);
13368 + pmd = pmd_offset(pud, vaddr);
13370 +#ifdef CONFIG_X86_PAE
13371 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
13374 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
13375 pmd++, pmd_idx++) {
13376 pte = page_table_kmap_check(one_page_table_init(pmd),
13377 @@ -216,11 +197,23 @@ page_table_range_init(unsigned long star
13381 -static inline int is_kernel_text(unsigned long addr)
13382 +static inline int is_kernel_text(unsigned long start, unsigned long end)
13384 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
13387 + unsigned long etext;
13389 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13390 + etext = ktva_ktla((unsigned long)&MODULES_END);
13392 + etext = (unsigned long)&_etext;
13395 + if ((start > ktla_ktva(etext) ||
13396 + end <= ktla_ktva((unsigned long)_stext)) &&
13397 + (start > ktla_ktva((unsigned long)_einittext) ||
13398 + end <= ktla_ktva((unsigned long)_sinittext)) &&
13399 + (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
13405 @@ -233,9 +226,10 @@ static void __init kernel_physical_mappi
13406 unsigned long end_pfn,
13409 - int pgd_idx, pmd_idx, pte_ofs;
13410 + unsigned int pgd_idx, pmd_idx, pte_ofs;
13416 unsigned pages_2m, pages_4k;
13417 @@ -265,8 +259,13 @@ repeat:
13419 pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
13420 pgd = pgd_base + pgd_idx;
13421 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
13422 - pmd = one_md_table_init(pgd);
13423 + for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
13424 + pud = pud_offset(pgd, 0);
13425 + pmd = pmd_offset(pud, 0);
13427 +#ifdef CONFIG_X86_PAE
13428 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
13431 if (pfn >= end_pfn)
13433 @@ -278,14 +277,13 @@ repeat:
13435 for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
13436 pmd++, pmd_idx++) {
13437 - unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
13438 + unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
13441 * Map with big pages if possible, otherwise
13442 * create normal page tables:
13445 - unsigned int addr2;
13446 pgprot_t prot = PAGE_KERNEL_LARGE;
13448 * first pass will use the same initial
13449 @@ -295,11 +293,7 @@ repeat:
13450 __pgprot(PTE_IDENT_ATTR |
13453 - addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
13454 - PAGE_OFFSET + PAGE_SIZE-1;
13456 - if (is_kernel_text(addr) ||
13457 - is_kernel_text(addr2))
13458 + if (is_kernel_text(address, address + PMD_SIZE))
13459 prot = PAGE_KERNEL_LARGE_EXEC;
13462 @@ -316,7 +310,7 @@ repeat:
13463 pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
13465 for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
13466 - pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
13467 + pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
13468 pgprot_t prot = PAGE_KERNEL;
13470 * first pass will use the same initial
13471 @@ -324,7 +318,7 @@ repeat:
13473 pgprot_t init_prot = __pgprot(PTE_IDENT_ATTR);
13475 - if (is_kernel_text(addr))
13476 + if (is_kernel_text(address, address + PAGE_SIZE))
13477 prot = PAGE_KERNEL_EXEC;
13480 @@ -369,7 +363,9 @@ repeat:
13482 int devmem_is_allowed(unsigned long pagenr)
13484 - if (pagenr <= 256)
13487 + if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13489 if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
13491 @@ -508,7 +504,7 @@ void __init native_pagetable_setup_start
13493 pud = pud_offset(pgd, va);
13494 pmd = pmd_offset(pud, va);
13495 - if (!pmd_present(*pmd))
13496 + if (!pmd_present(*pmd) || pmd_huge(*pmd))
13499 pte = pte_offset_kernel(pmd, va);
13500 @@ -559,9 +555,7 @@ static void __init early_ioremap_page_ta
13502 static void __init pagetable_init(void)
13504 - pgd_t *pgd_base = swapper_pg_dir;
13506 - permanent_kmaps_init(pgd_base);
13507 + permanent_kmaps_init(swapper_pg_dir);
13510 #ifdef CONFIG_ACPI_SLEEP
13511 @@ -569,12 +563,12 @@ static void __init pagetable_init(void)
13512 * ACPI suspend needs this for resume, because things like the intel-agp
13513 * driver might have split up a kernel 4MB mapping.
13515 -char swsusp_pg_dir[PAGE_SIZE]
13516 +pgd_t swsusp_pg_dir[PTRS_PER_PGD]
13517 __attribute__ ((aligned(PAGE_SIZE)));
13519 static inline void save_pg_dir(void)
13521 - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
13522 + clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
13524 #else /* !CONFIG_ACPI_SLEEP */
13525 static inline void save_pg_dir(void)
13526 @@ -604,13 +598,11 @@ void zap_low_mappings(void)
13530 -pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
13531 +pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
13532 EXPORT_SYMBOL_GPL(__supported_pte_mask);
13534 #ifdef CONFIG_X86_PAE
13536 -static int disable_nx __initdata;
13541 @@ -619,40 +611,33 @@ static int disable_nx __initdata;
13545 +#if !defined(CONFIG_PAX_PAGEEXEC)
13546 static int __init noexec_setup(char *str)
13548 if (!str || !strcmp(str, "on")) {
13549 - if (cpu_has_nx) {
13550 - __supported_pte_mask |= _PAGE_NX;
13556 - if (!strcmp(str, "off")) {
13558 - __supported_pte_mask &= ~_PAGE_NX;
13560 + if (!strcmp(str, "off"))
13569 early_param("noexec", noexec_setup);
13572 static void __init set_nx(void)
13574 - unsigned int v[4], l, h;
13576 - if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
13577 - cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
13578 + if (!nx_enabled && cpu_has_nx) {
13581 - if ((v[3] & (1 << 20)) && !disable_nx) {
13582 - rdmsr(MSR_EFER, l, h);
13584 - wrmsr(MSR_EFER, l, h);
13586 - __supported_pte_mask |= _PAGE_NX;
13588 + __supported_pte_mask &= ~_PAGE_NX;
13589 + rdmsr(MSR_EFER, l, h);
13591 + wrmsr(MSR_EFER, l, h);
13595 @@ -1035,7 +1020,7 @@ void __init mem_init(void)
13596 set_highmem_pages_init();
13598 codesize = (unsigned long) &_etext - (unsigned long) &_text;
13599 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
13600 + datasize = (unsigned long) &_edata - (unsigned long) &_data;
13601 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
13603 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
13604 @@ -1081,10 +1066,10 @@ void __init mem_init(void)
13605 ((unsigned long)&__init_end -
13606 (unsigned long)&__init_begin) >> 10,
13608 - (unsigned long)&_etext, (unsigned long)&_edata,
13609 - ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
13610 + (unsigned long)&_data, (unsigned long)&_edata,
13611 + ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
13613 - (unsigned long)&_text, (unsigned long)&_etext,
13614 + ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
13615 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
13618 @@ -1227,6 +1212,46 @@ void free_init_pages(char *what, unsigne
13620 void free_initmem(void)
13623 +#ifdef CONFIG_PAX_KERNEXEC
13624 + /* PaX: limit KERNEL_CS to actual size */
13625 + unsigned long addr, limit;
13626 + struct desc_struct d;
13632 +#ifdef CONFIG_MODULES
13633 + limit = ktva_ktla((unsigned long)&MODULES_END);
13635 + limit = (unsigned long)&_etext;
13637 + limit = (limit - 1UL) >> PAGE_SHIFT;
13639 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
13640 + pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
13641 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
13644 + /* PaX: make KERNEL_CS read-only */
13645 + for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
13646 + pgd = pgd_offset_k(addr);
13647 + pud = pud_offset(pgd, addr);
13648 + pmd = pmd_offset(pud, addr);
13649 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13651 +#ifdef CONFIG_X86_PAE
13652 + for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
13653 + pgd = pgd_offset_k(addr);
13654 + pud = pud_offset(pgd, addr);
13655 + pmd = pmd_offset(pud, addr);
13656 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13662 free_init_pages("unused kernel memory",
13663 (unsigned long)(&__init_begin),
13664 (unsigned long)(&__init_end));
13665 diff -urNp linux-2.6.29/arch/x86/mm/init_64.c linux-2.6.29/arch/x86/mm/init_64.c
13666 --- linux-2.6.29/arch/x86/mm/init_64.c 2009-03-23 19:12:14.000000000 -0400
13667 +++ linux-2.6.29/arch/x86/mm/init_64.c 2009-03-28 14:26:19.000000000 -0400
13668 @@ -175,6 +175,10 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
13672 +#ifdef CONFIG_PAX_KERNEXEC
13673 + unsigned long cr0;
13676 pud = pud_page + pud_index(vaddr);
13677 if (pud_none(*pud)) {
13678 pmd = (pmd_t *) spp_getpage();
13679 @@ -196,8 +200,17 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
13682 pte = pte_offset_kernel(pmd, vaddr);
13684 +#ifdef CONFIG_PAX_KERNEXEC
13685 + pax_open_kernel(cr0);
13688 set_pte(pte, new_pte);
13690 +#ifdef CONFIG_PAX_KERNEXEC
13691 + pax_close_kernel(cr0);
13695 * It's enough to flush this one mapping.
13696 * (PGE mappings get flushed as well)
13697 @@ -238,14 +251,12 @@ static void __init __init_extra_mapping(
13698 pgd = pgd_offset_k((unsigned long)__va(phys));
13699 if (pgd_none(*pgd)) {
13700 pud = (pud_t *) spp_getpage();
13701 - set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
13703 + set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
13705 pud = pud_offset(pgd, (unsigned long)__va(phys));
13706 if (pud_none(*pud)) {
13707 pmd = (pmd_t *) spp_getpage();
13708 - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
13710 + set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
13712 pmd = pmd_offset(pud, phys);
13713 BUG_ON(!pmd_none(*pmd));
13714 @@ -888,7 +899,9 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
13716 int devmem_is_allowed(unsigned long pagenr)
13718 - if (pagenr <= 256)
13721 + if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13723 if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
13725 @@ -979,6 +992,39 @@ void free_init_pages(char *what, unsigne
13727 void free_initmem(void)
13730 +#ifdef CONFIG_PAX_KERNEXEC
13731 + unsigned long addr, end;
13736 + /* PaX: make kernel code/rodata read-only, rest non-executable */
13737 + for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
13738 + pgd = pgd_offset_k(addr);
13739 + pud = pud_offset(pgd, addr);
13740 + pmd = pmd_offset(pud, addr);
13741 + if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
13742 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13744 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13747 + addr = (unsigned long)__va(__pa(__START_KERNEL_map));
13748 + end = addr + KERNEL_IMAGE_SIZE;
13749 + for (; addr < end; addr += PMD_SIZE) {
13750 + pgd = pgd_offset_k(addr);
13751 + pud = pud_offset(pgd, addr);
13752 + pmd = pmd_offset(pud, addr);
13753 + if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
13754 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13756 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13762 free_init_pages("unused kernel memory",
13763 (unsigned long)(&__init_begin),
13764 (unsigned long)(&__init_end));
13765 @@ -1151,7 +1197,7 @@ int in_gate_area_no_task(unsigned long a
13767 const char *arch_vma_name(struct vm_area_struct *vma)
13769 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
13770 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
13772 if (vma == &gate_vma)
13773 return "[vsyscall]";
13774 diff -urNp linux-2.6.29/arch/x86/mm/ioremap.c linux-2.6.29/arch/x86/mm/ioremap.c
13775 --- linux-2.6.29/arch/x86/mm/ioremap.c 2009-03-23 19:12:14.000000000 -0400
13776 +++ linux-2.6.29/arch/x86/mm/ioremap.c 2009-03-28 14:26:19.000000000 -0400
13777 @@ -114,8 +114,8 @@ int page_is_ram(unsigned long pagenr)
13778 * Second special case: Some BIOSen report the PC BIOS
13779 * area (640->1Mb) as ram even though it is not.
13781 - if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
13782 - pagenr < (BIOS_END >> PAGE_SHIFT))
13783 + if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
13784 + pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13787 for (i = 0; i < e820.nr_map; i++) {
13788 @@ -275,6 +275,8 @@ static void __iomem *__ioremap_caller(re
13792 + prot = canon_pgprot(prot);
13797 @@ -490,7 +492,7 @@ static int __init early_ioremap_debug_se
13798 early_param("early_ioremap_debug", early_ioremap_debug_setup);
13800 static __initdata int after_paging_init;
13801 -static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
13802 +static __read_only pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __aligned(PAGE_SIZE);
13804 static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
13806 @@ -505,7 +507,11 @@ static inline pmd_t * __init early_iorem
13808 static inline pte_t * __init early_ioremap_pte(unsigned long addr)
13810 +#ifdef CONFIG_X86_32
13811 return &bm_pte[pte_index(addr)];
13813 + return &level1_fixmap_pgt[pte_index(addr)];
13817 void __init early_ioremap_init(void)
13818 @@ -516,8 +522,10 @@ void __init early_ioremap_init(void)
13819 printk(KERN_INFO "early_ioremap_init()\n");
13821 pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
13822 +#ifdef CONFIG_X86_32
13823 memset(bm_pte, 0, sizeof(bm_pte));
13824 pmd_populate_kernel(&init_mm, pmd, bm_pte);
13828 * The boot-ioremap range spans multiple pmds, for which
13829 diff -urNp linux-2.6.29/arch/x86/mm/mmap.c linux-2.6.29/arch/x86/mm/mmap.c
13830 --- linux-2.6.29/arch/x86/mm/mmap.c 2009-03-23 19:12:14.000000000 -0400
13831 +++ linux-2.6.29/arch/x86/mm/mmap.c 2009-03-28 14:26:19.000000000 -0400
13833 * Leave an at least ~128 MB hole.
13835 #define MIN_GAP (128*1024*1024)
13836 -#define MAX_GAP (TASK_SIZE/6*5)
13837 +#define MAX_GAP (pax_task_size/6*5)
13840 * True on X86_32 or when emulating IA32 on X86_64
13841 @@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
13842 return rnd << PAGE_SHIFT;
13845 -static unsigned long mmap_base(void)
13846 +static unsigned long mmap_base(struct mm_struct *mm)
13848 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
13849 + unsigned long pax_task_size = TASK_SIZE;
13851 +#ifdef CONFIG_PAX_SEGMEXEC
13852 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
13853 + pax_task_size = SEGMEXEC_TASK_SIZE;
13858 else if (gap > MAX_GAP)
13861 - return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
13862 + return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
13866 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
13867 * does, but not when emulating X86_32
13869 -static unsigned long mmap_legacy_base(void)
13870 +static unsigned long mmap_legacy_base(struct mm_struct *mm)
13872 - if (mmap_is_ia32())
13873 + if (mmap_is_ia32()) {
13875 +#ifdef CONFIG_PAX_SEGMEXEC
13876 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
13877 + return SEGMEXEC_TASK_UNMAPPED_BASE;
13881 return TASK_UNMAPPED_BASE;
13884 return TASK_UNMAPPED_BASE + mmap_rnd();
13887 @@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
13888 void arch_pick_mmap_layout(struct mm_struct *mm)
13890 if (mmap_is_legacy()) {
13891 - mm->mmap_base = mmap_legacy_base();
13892 + mm->mmap_base = mmap_legacy_base(mm);
13894 +#ifdef CONFIG_PAX_RANDMMAP
13895 + if (mm->pax_flags & MF_PAX_RANDMMAP)
13896 + mm->mmap_base += mm->delta_mmap;
13899 mm->get_unmapped_area = arch_get_unmapped_area;
13900 mm->unmap_area = arch_unmap_area;
13902 - mm->mmap_base = mmap_base();
13903 + mm->mmap_base = mmap_base(mm);
13905 +#ifdef CONFIG_PAX_RANDMMAP
13906 + if (mm->pax_flags & MF_PAX_RANDMMAP)
13907 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
13910 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
13911 mm->unmap_area = arch_unmap_area_topdown;
13913 diff -urNp linux-2.6.29/arch/x86/mm/numa_32.c linux-2.6.29/arch/x86/mm/numa_32.c
13914 --- linux-2.6.29/arch/x86/mm/numa_32.c 2009-03-23 19:12:14.000000000 -0400
13915 +++ linux-2.6.29/arch/x86/mm/numa_32.c 2009-03-28 14:26:19.000000000 -0400
13916 @@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
13920 -extern unsigned long find_max_low_pfn(void);
13921 extern unsigned long highend_pfn, highstart_pfn;
13923 #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
13924 diff -urNp linux-2.6.29/arch/x86/mm/pageattr.c linux-2.6.29/arch/x86/mm/pageattr.c
13925 --- linux-2.6.29/arch/x86/mm/pageattr.c 2009-03-23 19:12:14.000000000 -0400
13926 +++ linux-2.6.29/arch/x86/mm/pageattr.c 2009-03-28 14:26:19.000000000 -0400
13928 #include <asm/pgalloc.h>
13929 #include <asm/proto.h>
13930 #include <asm/pat.h>
13931 +#include <asm/desc.h>
13934 * The current flushing context - we pass it instead of 5 arguments:
13935 @@ -259,7 +260,7 @@ static inline pgprot_t static_protection
13936 * Does not cover __inittext since that is gone later on. On
13937 * 64bit we do not enforce !NX on the low mapping
13939 - if (within(address, (unsigned long)_text, (unsigned long)_etext))
13940 + if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
13941 pgprot_val(forbidden) |= _PAGE_NX;
13944 @@ -321,8 +322,20 @@ EXPORT_SYMBOL_GPL(lookup_address);
13946 static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
13949 +#ifdef CONFIG_PAX_KERNEXEC
13950 + unsigned long cr0;
13952 + pax_open_kernel(cr0);
13955 /* change init_mm */
13956 set_pte_atomic(kpte, pte);
13958 +#ifdef CONFIG_PAX_KERNEXEC
13959 + pax_close_kernel(cr0);
13962 #ifdef CONFIG_X86_32
13963 if (!SHARED_KERNEL_PMD) {
13965 diff -urNp linux-2.6.29/arch/x86/mm/pageattr-test.c linux-2.6.29/arch/x86/mm/pageattr-test.c
13966 --- linux-2.6.29/arch/x86/mm/pageattr-test.c 2009-03-23 19:12:14.000000000 -0400
13967 +++ linux-2.6.29/arch/x86/mm/pageattr-test.c 2009-03-28 14:26:19.000000000 -0400
13968 @@ -36,7 +36,7 @@ enum {
13970 static int pte_testbit(pte_t pte)
13972 - return pte_flags(pte) & _PAGE_UNUSED1;
13973 + return pte_flags(pte) & _PAGE_CPA_TEST;
13976 struct split_state {
13977 diff -urNp linux-2.6.29/arch/x86/mm/pat.c linux-2.6.29/arch/x86/mm/pat.c
13978 --- linux-2.6.29/arch/x86/mm/pat.c 2009-03-23 19:12:14.000000000 -0400
13979 +++ linux-2.6.29/arch/x86/mm/pat.c 2009-03-28 14:26:19.000000000 -0400
13980 @@ -503,7 +503,7 @@ pgprot_t phys_mem_access_prot(struct fil
13984 -#ifdef CONFIG_STRICT_DEVMEM
13985 +#ifndef CONFIG_STRICT_DEVMEM
13986 /* This check is done in drivers/char/mem.c in case of STRICT_DEVMEM*/
13987 static inline int range_is_allowed(unsigned long pfn, unsigned long size)
13989 diff -urNp linux-2.6.29/arch/x86/mm/pgtable_32.c linux-2.6.29/arch/x86/mm/pgtable_32.c
13990 --- linux-2.6.29/arch/x86/mm/pgtable_32.c 2009-03-23 19:12:14.000000000 -0400
13991 +++ linux-2.6.29/arch/x86/mm/pgtable_32.c 2009-03-28 14:26:19.000000000 -0400
13992 @@ -31,6 +31,10 @@ void set_pte_vaddr(unsigned long vaddr,
13996 +#ifdef CONFIG_PAX_KERNEXEC
13997 + unsigned long cr0;
14000 pgd = swapper_pg_dir + pgd_index(vaddr);
14001 if (pgd_none(*pgd)) {
14003 @@ -47,11 +51,20 @@ void set_pte_vaddr(unsigned long vaddr,
14006 pte = pte_offset_kernel(pmd, vaddr);
14008 +#ifdef CONFIG_PAX_KERNEXEC
14009 + pax_open_kernel(cr0);
14012 if (pte_val(pteval))
14013 set_pte_present(&init_mm, vaddr, pte, pteval);
14015 pte_clear(&init_mm, vaddr, pte);
14017 +#ifdef CONFIG_PAX_KERNEXEC
14018 + pax_close_kernel(cr0);
14022 * It's enough to flush this one mapping.
14023 * (PGE mappings get flushed as well)
14024 diff -urNp linux-2.6.29/arch/x86/oprofile/backtrace.c linux-2.6.29/arch/x86/oprofile/backtrace.c
14025 --- linux-2.6.29/arch/x86/oprofile/backtrace.c 2009-03-23 19:12:14.000000000 -0400
14026 +++ linux-2.6.29/arch/x86/oprofile/backtrace.c 2009-03-28 14:26:19.000000000 -0400
14027 @@ -37,7 +37,7 @@ static void backtrace_address(void *data
14028 unsigned int *depth = data;
14031 - oprofile_add_trace(addr);
14032 + oprofile_add_trace(ktla_ktva(addr));
14035 static struct stacktrace_ops backtrace_ops = {
14036 @@ -78,7 +78,7 @@ x86_backtrace(struct pt_regs * const reg
14037 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
14038 unsigned long stack = kernel_trap_sp(regs);
14040 - if (!user_mode_vm(regs)) {
14041 + if (!user_mode(regs)) {
14043 dump_trace(NULL, regs, (unsigned long *)stack, 0,
14044 &backtrace_ops, &depth);
14045 diff -urNp linux-2.6.29/arch/x86/oprofile/op_model_p4.c linux-2.6.29/arch/x86/oprofile/op_model_p4.c
14046 --- linux-2.6.29/arch/x86/oprofile/op_model_p4.c 2009-03-23 19:12:14.000000000 -0400
14047 +++ linux-2.6.29/arch/x86/oprofile/op_model_p4.c 2009-03-28 14:26:19.000000000 -0400
14048 @@ -48,7 +48,7 @@ static inline void setup_num_counters(vo
14052 -static int inline addr_increment(void)
14053 +static inline int addr_increment(void)
14056 return smp_num_siblings == 2 ? 2 : 1;
14057 diff -urNp linux-2.6.29/arch/x86/pci/common.c linux-2.6.29/arch/x86/pci/common.c
14058 --- linux-2.6.29/arch/x86/pci/common.c 2009-03-23 19:12:14.000000000 -0400
14059 +++ linux-2.6.29/arch/x86/pci/common.c 2009-03-28 14:26:19.000000000 -0400
14060 @@ -367,7 +367,7 @@ static struct dmi_system_id __devinitdat
14061 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
14065 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
14068 void __init dmi_check_pciprobe(void)
14069 diff -urNp linux-2.6.29/arch/x86/pci/fixup.c linux-2.6.29/arch/x86/pci/fixup.c
14070 --- linux-2.6.29/arch/x86/pci/fixup.c 2009-03-23 19:12:14.000000000 -0400
14071 +++ linux-2.6.29/arch/x86/pci/fixup.c 2009-03-28 14:26:19.000000000 -0400
14072 @@ -364,7 +364,7 @@ static struct dmi_system_id __devinitdat
14073 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
14077 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
14081 @@ -435,7 +435,7 @@ static struct dmi_system_id __devinitdat
14082 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
14086 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
14089 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
14090 diff -urNp linux-2.6.29/arch/x86/pci/irq.c linux-2.6.29/arch/x86/pci/irq.c
14091 --- linux-2.6.29/arch/x86/pci/irq.c 2009-03-23 19:12:14.000000000 -0400
14092 +++ linux-2.6.29/arch/x86/pci/irq.c 2009-03-28 14:26:19.000000000 -0400
14093 @@ -543,7 +543,7 @@ static __init int intel_router_probe(str
14094 static struct pci_device_id __initdata pirq_440gx[] = {
14095 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
14096 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
14098 + { PCI_DEVICE(0, 0) }
14101 /* 440GX has a proprietary PIRQ router -- don't use it */
14102 @@ -1145,7 +1145,7 @@ static struct dmi_system_id __initdata p
14103 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
14107 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
14110 int __init pcibios_irq_init(void)
14111 diff -urNp linux-2.6.29/arch/x86/pci/pcbios.c linux-2.6.29/arch/x86/pci/pcbios.c
14112 --- linux-2.6.29/arch/x86/pci/pcbios.c 2009-03-23 19:12:14.000000000 -0400
14113 +++ linux-2.6.29/arch/x86/pci/pcbios.c 2009-03-28 14:26:19.000000000 -0400
14114 @@ -56,50 +56,120 @@ union bios32 {
14116 unsigned long address;
14117 unsigned short segment;
14118 -} bios32_indirect = { 0, __KERNEL_CS };
14119 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
14122 * Returns the entry point for the given service, NULL on error
14125 -static unsigned long bios32_service(unsigned long service)
14126 +static unsigned long __devinit bios32_service(unsigned long service)
14128 unsigned char return_code; /* %al */
14129 unsigned long address; /* %ebx */
14130 unsigned long length; /* %ecx */
14131 unsigned long entry; /* %edx */
14132 unsigned long flags;
14133 + struct desc_struct d, *gdt;
14135 +#ifdef CONFIG_PAX_KERNEXEC
14136 + unsigned long cr0;
14139 local_irq_save(flags);
14140 - __asm__("lcall *(%%edi); cld"
14142 + gdt = get_cpu_gdt_table(smp_processor_id());
14144 +#ifdef CONFIG_PAX_KERNEXEC
14145 + pax_open_kernel(cr0);
14148 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
14149 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
14150 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
14151 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
14153 +#ifdef CONFIG_PAX_KERNEXEC
14154 + pax_close_kernel(cr0);
14157 + __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
14158 : "=a" (return_code),
14164 - "D" (&bios32_indirect));
14165 + "D" (&bios32_indirect),
14166 + "r"(__PCIBIOS_DS)
14169 +#ifdef CONFIG_PAX_KERNEXEC
14170 + pax_open_kernel(cr0);
14173 + gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
14174 + gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
14175 + gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
14176 + gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
14178 +#ifdef CONFIG_PAX_KERNEXEC
14179 + pax_close_kernel(cr0);
14182 local_irq_restore(flags);
14184 switch (return_code) {
14186 - return address + entry;
14187 - case 0x80: /* Not present */
14188 - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
14190 - default: /* Shouldn't happen */
14191 - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
14192 - service, return_code);
14195 + unsigned char flags;
14197 + printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
14198 + if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
14199 + printk(KERN_WARNING "bios32_service: not valid\n");
14202 + address = address + PAGE_OFFSET;
14203 + length += 16UL; /* some BIOSs underreport this... */
14205 + if (length >= 64*1024*1024) {
14206 + length >>= PAGE_SHIFT;
14210 +#ifdef CONFIG_PAX_KERNEXEC
14211 + pax_open_kernel(cr0);
14214 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
14215 + gdt = get_cpu_gdt_table(cpu);
14216 + pack_descriptor(&d, address, length, 0x9b, flags);
14217 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
14218 + pack_descriptor(&d, address, length, 0x93, flags);
14219 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
14222 +#ifdef CONFIG_PAX_KERNEXEC
14223 + pax_close_kernel(cr0);
14228 + case 0x80: /* Not present */
14229 + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
14231 + default: /* Shouldn't happen */
14232 + printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
14233 + service, return_code);
14239 unsigned long address;
14240 unsigned short segment;
14241 -} pci_indirect = { 0, __KERNEL_CS };
14242 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
14244 -static int pci_bios_present;
14245 +static int pci_bios_present __read_only;
14247 static int __devinit check_pcibios(void)
14249 @@ -108,11 +178,13 @@ static int __devinit check_pcibios(void)
14250 unsigned long flags, pcibios_entry;
14252 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
14253 - pci_indirect.address = pcibios_entry + PAGE_OFFSET;
14254 + pci_indirect.address = pcibios_entry;
14256 local_irq_save(flags);
14258 - "lcall *(%%edi); cld\n\t"
14259 + __asm__("movw %w6, %%ds\n\t"
14260 + "lcall *%%ss:(%%edi); cld\n\t"
14266 @@ -121,7 +193,8 @@ static int __devinit check_pcibios(void)
14269 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
14270 - "D" (&pci_indirect)
14271 + "D" (&pci_indirect),
14272 + "r" (__PCIBIOS_DS)
14274 local_irq_restore(flags);
14276 @@ -165,7 +238,10 @@ static int pci_bios_read(unsigned int se
14280 - __asm__("lcall *(%%esi); cld\n\t"
14281 + __asm__("movw %w6, %%ds\n\t"
14282 + "lcall *%%ss:(%%esi); cld\n\t"
14288 @@ -174,7 +250,8 @@ static int pci_bios_read(unsigned int se
14289 : "1" (PCIBIOS_READ_CONFIG_BYTE),
14292 - "S" (&pci_indirect));
14293 + "S" (&pci_indirect),
14294 + "r" (__PCIBIOS_DS));
14296 * Zero-extend the result beyond 8 bits, do not trust the
14297 * BIOS having done it:
14298 @@ -182,7 +259,10 @@ static int pci_bios_read(unsigned int se
14302 - __asm__("lcall *(%%esi); cld\n\t"
14303 + __asm__("movw %w6, %%ds\n\t"
14304 + "lcall *%%ss:(%%esi); cld\n\t"
14310 @@ -191,7 +271,8 @@ static int pci_bios_read(unsigned int se
14311 : "1" (PCIBIOS_READ_CONFIG_WORD),
14314 - "S" (&pci_indirect));
14315 + "S" (&pci_indirect),
14316 + "r" (__PCIBIOS_DS));
14318 * Zero-extend the result beyond 16 bits, do not trust the
14319 * BIOS having done it:
14320 @@ -199,7 +280,10 @@ static int pci_bios_read(unsigned int se
14324 - __asm__("lcall *(%%esi); cld\n\t"
14325 + __asm__("movw %w6, %%ds\n\t"
14326 + "lcall *%%ss:(%%esi); cld\n\t"
14332 @@ -208,7 +292,8 @@ static int pci_bios_read(unsigned int se
14333 : "1" (PCIBIOS_READ_CONFIG_DWORD),
14336 - "S" (&pci_indirect));
14337 + "S" (&pci_indirect),
14338 + "r" (__PCIBIOS_DS));
14342 @@ -231,7 +316,10 @@ static int pci_bios_write(unsigned int s
14346 - __asm__("lcall *(%%esi); cld\n\t"
14347 + __asm__("movw %w6, %%ds\n\t"
14348 + "lcall *%%ss:(%%esi); cld\n\t"
14354 @@ -240,10 +328,14 @@ static int pci_bios_write(unsigned int s
14358 - "S" (&pci_indirect));
14359 + "S" (&pci_indirect),
14360 + "r" (__PCIBIOS_DS));
14363 - __asm__("lcall *(%%esi); cld\n\t"
14364 + __asm__("movw %w6, %%ds\n\t"
14365 + "lcall *%%ss:(%%esi); cld\n\t"
14371 @@ -252,10 +344,14 @@ static int pci_bios_write(unsigned int s
14375 - "S" (&pci_indirect));
14376 + "S" (&pci_indirect),
14377 + "r" (__PCIBIOS_DS));
14380 - __asm__("lcall *(%%esi); cld\n\t"
14381 + __asm__("movw %w6, %%ds\n\t"
14382 + "lcall *%%ss:(%%esi); cld\n\t"
14388 @@ -264,7 +360,8 @@ static int pci_bios_write(unsigned int s
14392 - "S" (&pci_indirect));
14393 + "S" (&pci_indirect),
14394 + "r" (__PCIBIOS_DS));
14398 @@ -368,10 +465,13 @@ struct irq_routing_table * pcibios_get_i
14400 DBG("PCI: Fetching IRQ routing table... ");
14401 __asm__("push %%es\n\t"
14402 + "movw %w8, %%ds\n\t"
14405 - "lcall *(%%esi); cld\n\t"
14406 + "lcall *%%ss:(%%esi); cld\n\t"
14413 @@ -382,7 +482,8 @@ struct irq_routing_table * pcibios_get_i
14416 "S" (&pci_indirect),
14419 + "r" (__PCIBIOS_DS)
14421 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
14423 @@ -406,7 +507,10 @@ int pcibios_set_irq_routing(struct pci_d
14427 - __asm__("lcall *(%%esi); cld\n\t"
14428 + __asm__("movw %w5, %%ds\n\t"
14429 + "lcall *%%ss:(%%esi); cld\n\t"
14435 @@ -414,7 +518,8 @@ int pcibios_set_irq_routing(struct pci_d
14436 : "0" (PCIBIOS_SET_PCI_HW_INT),
14437 "b" ((dev->bus->number << 8) | dev->devfn),
14438 "c" ((irq << 8) | (pin + 10)),
14439 - "S" (&pci_indirect));
14440 + "S" (&pci_indirect),
14441 + "r" (__PCIBIOS_DS));
14442 return !(ret & 0xff00);
14444 EXPORT_SYMBOL(pcibios_set_irq_routing);
14445 diff -urNp linux-2.6.29/arch/x86/power/cpu_32.c linux-2.6.29/arch/x86/power/cpu_32.c
14446 --- linux-2.6.29/arch/x86/power/cpu_32.c 2009-03-23 19:12:14.000000000 -0400
14447 +++ linux-2.6.29/arch/x86/power/cpu_32.c 2009-03-28 14:26:19.000000000 -0400
14448 @@ -67,7 +67,7 @@ static void do_fpu_end(void)
14449 static void fix_processor_context(void)
14451 int cpu = smp_processor_id();
14452 - struct tss_struct *t = &per_cpu(init_tss, cpu);
14453 + struct tss_struct *t = init_tss + cpu;
14455 set_tss_desc(cpu, t); /*
14456 * This just modifies memory; should not be
14457 diff -urNp linux-2.6.29/arch/x86/power/cpu_64.c linux-2.6.29/arch/x86/power/cpu_64.c
14458 --- linux-2.6.29/arch/x86/power/cpu_64.c 2009-03-23 19:12:14.000000000 -0400
14459 +++ linux-2.6.29/arch/x86/power/cpu_64.c 2009-03-28 14:26:19.000000000 -0400
14460 @@ -143,7 +143,11 @@ void restore_processor_state(void)
14461 static void fix_processor_context(void)
14463 int cpu = smp_processor_id();
14464 - struct tss_struct *t = &per_cpu(init_tss, cpu);
14465 + struct tss_struct *t = init_tss + cpu;
14467 +#ifdef CONFIG_PAX_KERNEXEC
14468 + unsigned long cr0;
14472 * This just modifies memory; should not be necessary. But... This
14473 @@ -152,8 +156,16 @@ static void fix_processor_context(void)
14475 set_tss_desc(cpu, t);
14477 +#ifdef CONFIG_PAX_KERNEXEC
14478 + pax_open_kernel(cr0);
14481 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
14483 +#ifdef CONFIG_PAX_KERNEXEC
14484 + pax_close_kernel(cr0);
14487 syscall_init(); /* This sets MSR_*STAR and related */
14488 load_TR_desc(); /* This does ltr */
14489 load_LDT(¤t->active_mm->context); /* This does lldt */
14490 diff -urNp linux-2.6.29/arch/x86/vdso/vdso32-setup.c linux-2.6.29/arch/x86/vdso/vdso32-setup.c
14491 --- linux-2.6.29/arch/x86/vdso/vdso32-setup.c 2009-03-23 19:12:14.000000000 -0400
14492 +++ linux-2.6.29/arch/x86/vdso/vdso32-setup.c 2009-03-28 14:26:19.000000000 -0400
14493 @@ -226,7 +226,7 @@ static inline void map_compat_vdso(int m
14494 void enable_sep_cpu(void)
14496 int cpu = get_cpu();
14497 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
14498 + struct tss_struct *tss = init_tss + cpu;
14500 if (!boot_cpu_has(X86_FEATURE_SEP)) {
14502 @@ -249,7 +249,7 @@ static int __init gate_vma_init(void)
14503 gate_vma.vm_start = FIXADDR_USER_START;
14504 gate_vma.vm_end = FIXADDR_USER_END;
14505 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
14506 - gate_vma.vm_page_prot = __P101;
14507 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
14509 * Make sure the vDSO gets into every core dump.
14510 * Dumping its contents makes post-mortem fully interpretable later
14511 @@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct l
14513 addr = VDSO_HIGH_BASE;
14515 - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
14516 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
14517 if (IS_ERR_VALUE(addr)) {
14520 @@ -358,7 +358,7 @@ int arch_setup_additional_pages(struct l
14524 - current->mm->context.vdso = (void *)addr;
14525 + current->mm->context.vdso = addr;
14526 current_thread_info()->sysenter_return =
14527 VDSO32_SYMBOL(addr, SYSENTER_RETURN);
14529 @@ -384,7 +384,7 @@ static ctl_table abi_table2[] = {
14531 .proc_handler = proc_dointvec
14534 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
14537 static ctl_table abi_root_table2[] = {
14538 @@ -394,7 +394,7 @@ static ctl_table abi_root_table2[] = {
14540 .child = abi_table2
14543 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
14546 static __init int ia32_binfmt_init(void)
14547 @@ -409,8 +409,14 @@ __initcall(ia32_binfmt_init);
14549 const char *arch_vma_name(struct vm_area_struct *vma)
14551 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
14552 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
14555 +#ifdef CONFIG_PAX_SEGMEXEC
14556 + if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
14563 @@ -419,7 +425,7 @@ struct vm_area_struct *get_gate_vma(stru
14564 struct mm_struct *mm = tsk->mm;
14566 /* Check to see if this task was created in compat vdso mode */
14567 - if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
14568 + if (mm && mm->context.vdso == VDSO_HIGH_BASE)
14572 diff -urNp linux-2.6.29/arch/x86/vdso/vma.c linux-2.6.29/arch/x86/vdso/vma.c
14573 --- linux-2.6.29/arch/x86/vdso/vma.c 2009-03-23 19:12:14.000000000 -0400
14574 +++ linux-2.6.29/arch/x86/vdso/vma.c 2009-03-28 14:26:19.000000000 -0400
14575 @@ -123,7 +123,7 @@ int arch_setup_additional_pages(struct l
14579 - current->mm->context.vdso = (void *)addr;
14580 + current->mm->context.vdso = addr;
14582 up_write(&mm->mmap_sem);
14584 diff -urNp linux-2.6.29/arch/x86/xen/enlighten.c linux-2.6.29/arch/x86/xen/enlighten.c
14585 --- linux-2.6.29/arch/x86/xen/enlighten.c 2009-03-23 19:12:14.000000000 -0400
14586 +++ linux-2.6.29/arch/x86/xen/enlighten.c 2009-03-28 14:26:19.000000000 -0400
14587 @@ -319,7 +319,7 @@ static void xen_set_ldt(const void *addr
14588 static void xen_load_gdt(const struct desc_ptr *dtr)
14590 unsigned long *frames;
14591 - unsigned long va = dtr->address;
14592 + unsigned long va = (unsigned long)dtr->address;
14593 unsigned int size = dtr->size + 1;
14594 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
14596 @@ -334,7 +334,7 @@ static void xen_load_gdt(const struct de
14597 mcs = xen_mc_entry(sizeof(*frames) * pages);
14600 - for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
14601 + for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
14602 frames[f] = virt_to_mfn(va);
14603 make_lowmem_page_readonly((void *)va);
14605 @@ -442,7 +442,7 @@ static void xen_write_idt_entry(gate_des
14609 - start = __get_cpu_var(idt_desc).address;
14610 + start = (unsigned long)__get_cpu_var(idt_desc).address;
14611 end = start + __get_cpu_var(idt_desc).size + 1;
14614 @@ -1528,6 +1528,8 @@ static __init pgd_t *xen_setup_kernel_pa
14615 convert_pfn_mfn(init_level4_pgt);
14616 convert_pfn_mfn(level3_ident_pgt);
14617 convert_pfn_mfn(level3_kernel_pgt);
14618 + convert_pfn_mfn(level3_vmalloc_pgt);
14619 + convert_pfn_mfn(level3_vmemmap_pgt);
14621 l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
14622 l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
14623 @@ -1546,9 +1548,12 @@ static __init pgd_t *xen_setup_kernel_pa
14624 set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
14625 set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
14626 set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
14627 + set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
14628 + set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
14629 set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
14630 set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
14631 set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
14632 + set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
14634 /* Pin down new L4 */
14635 pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
14636 diff -urNp linux-2.6.29/arch/x86/xen/smp.c linux-2.6.29/arch/x86/xen/smp.c
14637 --- linux-2.6.29/arch/x86/xen/smp.c 2009-03-23 19:12:14.000000000 -0400
14638 +++ linux-2.6.29/arch/x86/xen/smp.c 2009-03-28 14:26:19.000000000 -0400
14639 @@ -171,11 +171,6 @@ static void __init xen_smp_prepare_boot_
14641 BUG_ON(smp_processor_id() != 0);
14642 native_smp_prepare_boot_cpu();
14644 - /* We've switched to the "real" per-cpu gdt, so make sure the
14645 - old memory can be recycled */
14646 - make_lowmem_page_readwrite(&per_cpu_var(gdt_page));
14648 xen_setup_vcpu_info_placement();
14651 @@ -234,8 +229,8 @@ cpu_initialize_context(unsigned int cpu,
14652 gdt = get_cpu_gdt_table(cpu);
14654 ctxt->flags = VGCF_IN_KERNEL;
14655 - ctxt->user_regs.ds = __USER_DS;
14656 - ctxt->user_regs.es = __USER_DS;
14657 + ctxt->user_regs.ds = __KERNEL_DS;
14658 + ctxt->user_regs.es = __KERNEL_DS;
14659 ctxt->user_regs.ss = __KERNEL_DS;
14660 #ifdef CONFIG_X86_32
14661 ctxt->user_regs.fs = __KERNEL_PERCPU;
14662 diff -urNp linux-2.6.29/arch/xtensa/include/asm/kmap_types.h linux-2.6.29/arch/xtensa/include/asm/kmap_types.h
14663 --- linux-2.6.29/arch/xtensa/include/asm/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
14664 +++ linux-2.6.29/arch/xtensa/include/asm/kmap_types.h 2009-03-28 14:26:19.000000000 -0400
14665 @@ -25,6 +25,7 @@ enum km_type {
14673 diff -urNp linux-2.6.29/crypto/lrw.c linux-2.6.29/crypto/lrw.c
14674 --- linux-2.6.29/crypto/lrw.c 2009-03-23 19:12:14.000000000 -0400
14675 +++ linux-2.6.29/crypto/lrw.c 2009-03-28 14:26:19.000000000 -0400
14676 @@ -60,7 +60,7 @@ static int setkey(struct crypto_tfm *par
14677 struct priv *ctx = crypto_tfm_ctx(parent);
14678 struct crypto_cipher *child = ctx->child;
14680 - be128 tmp = { 0 };
14681 + be128 tmp = { 0, 0 };
14682 int bsize = crypto_cipher_blocksize(child);
14684 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
14685 diff -urNp linux-2.6.29/Documentation/dontdiff linux-2.6.29/Documentation/dontdiff
14686 --- linux-2.6.29/Documentation/dontdiff 2009-03-23 19:12:14.000000000 -0400
14687 +++ linux-2.6.29/Documentation/dontdiff 2009-03-28 14:26:19.000000000 -0400
14707 @@ -62,7 +67,6 @@ aic7*reg_print.c*
14715 @@ -77,6 +81,7 @@ btfixupprep
14723 @@ -188,12 +193,15 @@ version.h*
14739 diff -urNp linux-2.6.29/drivers/acpi/blacklist.c linux-2.6.29/drivers/acpi/blacklist.c
14740 --- linux-2.6.29/drivers/acpi/blacklist.c 2009-03-23 19:12:14.000000000 -0400
14741 +++ linux-2.6.29/drivers/acpi/blacklist.c 2009-03-28 14:26:19.000000000 -0400
14742 @@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
14743 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
14744 "Incorrect _ADR", 1},
14747 + {"", "", 0, 0, 0, all_versions, 0}
14750 #if CONFIG_ACPI_BLACKLIST_YEAR
14751 diff -urNp linux-2.6.29/drivers/acpi/osl.c linux-2.6.29/drivers/acpi/osl.c
14752 --- linux-2.6.29/drivers/acpi/osl.c 2009-03-23 19:12:14.000000000 -0400
14753 +++ linux-2.6.29/drivers/acpi/osl.c 2009-03-28 14:26:19.000000000 -0400
14754 @@ -483,6 +483,8 @@ acpi_os_read_memory(acpi_physical_addres
14755 void __iomem *virt_addr;
14757 virt_addr = ioremap(phys_addr, width);
14759 + return AE_NO_MEMORY;
14763 @@ -511,6 +513,8 @@ acpi_os_write_memory(acpi_physical_addre
14764 void __iomem *virt_addr;
14766 virt_addr = ioremap(phys_addr, width);
14768 + return AE_NO_MEMORY;
14772 diff -urNp linux-2.6.29/drivers/acpi/processor_core.c linux-2.6.29/drivers/acpi/processor_core.c
14773 --- linux-2.6.29/drivers/acpi/processor_core.c 2009-03-23 19:12:14.000000000 -0400
14774 +++ linux-2.6.29/drivers/acpi/processor_core.c 2009-03-28 14:26:19.000000000 -0400
14775 @@ -678,7 +678,7 @@ static int __cpuinit acpi_processor_star
14779 - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
14780 + BUG_ON(pr->id >= nr_cpu_ids);
14784 diff -urNp linux-2.6.29/drivers/acpi/processor_idle.c linux-2.6.29/drivers/acpi/processor_idle.c
14785 --- linux-2.6.29/drivers/acpi/processor_idle.c 2009-03-23 19:12:14.000000000 -0400
14786 +++ linux-2.6.29/drivers/acpi/processor_idle.c 2009-03-28 14:26:19.000000000 -0400
14787 @@ -156,7 +156,7 @@ static struct dmi_system_id __cpuinitdat
14788 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
14789 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
14792 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL},
14795 static inline u32 ticks_elapsed(u32 t1, u32 t2)
14796 diff -urNp linux-2.6.29/drivers/ata/ahci.c linux-2.6.29/drivers/ata/ahci.c
14797 --- linux-2.6.29/drivers/ata/ahci.c 2009-03-23 19:12:14.000000000 -0400
14798 +++ linux-2.6.29/drivers/ata/ahci.c 2009-03-28 14:26:19.000000000 -0400
14799 @@ -611,7 +611,7 @@ static const struct pci_device_id ahci_p
14800 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
14801 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
14803 - { } /* terminate list */
14804 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
14808 diff -urNp linux-2.6.29/drivers/ata/ata_piix.c linux-2.6.29/drivers/ata/ata_piix.c
14809 --- linux-2.6.29/drivers/ata/ata_piix.c 2009-03-23 19:12:14.000000000 -0400
14810 +++ linux-2.6.29/drivers/ata/ata_piix.c 2009-03-28 14:26:19.000000000 -0400
14811 @@ -291,7 +291,7 @@ static const struct pci_device_id piix_p
14812 { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
14813 /* SATA Controller IDE (PCH) */
14814 { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
14815 - { } /* terminate list */
14816 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
14819 static struct pci_driver piix_pci_driver = {
14820 @@ -595,7 +595,7 @@ static const struct ich_laptop ich_lapto
14821 { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
14822 { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
14829 @@ -1054,7 +1054,7 @@ static int piix_broken_suspend(void)
14833 - { } /* terminate list */
14834 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } /* terminate list */
14836 static const char *oemstrs[] = {
14838 diff -urNp linux-2.6.29/drivers/ata/libata-core.c linux-2.6.29/drivers/ata/libata-core.c
14839 --- linux-2.6.29/drivers/ata/libata-core.c 2009-03-23 19:12:14.000000000 -0400
14840 +++ linux-2.6.29/drivers/ata/libata-core.c 2009-03-28 14:26:19.000000000 -0400
14841 @@ -889,7 +889,7 @@ static const struct ata_xfer_ent {
14842 { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
14843 { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
14844 { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
14850 @@ -3105,7 +3105,7 @@ static const struct ata_timing ata_timin
14851 { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 },
14852 { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 },
14855 + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
14858 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
14859 @@ -4267,7 +4267,7 @@ static const struct ata_blacklist_entry
14860 { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, },
14864 + { NULL, NULL, 0 }
14867 static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
14868 diff -urNp linux-2.6.29/drivers/char/agp/frontend.c linux-2.6.29/drivers/char/agp/frontend.c
14869 --- linux-2.6.29/drivers/char/agp/frontend.c 2009-03-23 19:12:14.000000000 -0400
14870 +++ linux-2.6.29/drivers/char/agp/frontend.c 2009-03-28 14:26:19.000000000 -0400
14871 @@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag
14872 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
14875 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
14876 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
14879 client = agp_find_client_by_pid(reserve.pid);
14880 diff -urNp linux-2.6.29/drivers/char/agp/intel-agp.c linux-2.6.29/drivers/char/agp/intel-agp.c
14881 --- linux-2.6.29/drivers/char/agp/intel-agp.c 2009-03-23 19:12:14.000000000 -0400
14882 +++ linux-2.6.29/drivers/char/agp/intel-agp.c 2009-03-28 14:26:19.000000000 -0400
14883 @@ -2369,7 +2369,7 @@ static struct pci_device_id agp_intel_pc
14884 ID(PCI_DEVICE_ID_INTEL_Q45_HB),
14885 ID(PCI_DEVICE_ID_INTEL_G45_HB),
14886 ID(PCI_DEVICE_ID_INTEL_G41_HB),
14888 + { 0, 0, 0, 0, 0, 0, 0 }
14891 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
14892 diff -urNp linux-2.6.29/drivers/char/hpet.c linux-2.6.29/drivers/char/hpet.c
14893 --- linux-2.6.29/drivers/char/hpet.c 2009-03-23 19:12:14.000000000 -0400
14894 +++ linux-2.6.29/drivers/char/hpet.c 2009-03-28 14:26:19.000000000 -0400
14895 @@ -975,7 +975,7 @@ static struct acpi_driver hpet_acpi_driv
14899 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
14900 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
14902 static int __init hpet_init(void)
14904 diff -urNp linux-2.6.29/drivers/char/keyboard.c linux-2.6.29/drivers/char/keyboard.c
14905 --- linux-2.6.29/drivers/char/keyboard.c 2009-03-23 19:12:14.000000000 -0400
14906 +++ linux-2.6.29/drivers/char/keyboard.c 2009-03-28 14:26:19.000000000 -0400
14907 @@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u
14908 kbd->kbdmode == VC_MEDIUMRAW) &&
14909 value != KVAL(K_SAK))
14910 return; /* SAK is allowed even in raw mode */
14912 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
14914 + void *func = fn_handler[value];
14915 + if (func == fn_show_state || func == fn_show_ptregs ||
14916 + func == fn_show_mem)
14921 fn_handler[value](vc);
14924 @@ -1388,7 +1398,7 @@ static const struct input_device_id kbd_
14925 .evbit = { BIT_MASK(EV_SND) },
14928 - { }, /* Terminating entry */
14929 + { 0 }, /* Terminating entry */
14932 MODULE_DEVICE_TABLE(input, kbd_ids);
14933 diff -urNp linux-2.6.29/drivers/char/mem.c linux-2.6.29/drivers/char/mem.c
14934 --- linux-2.6.29/drivers/char/mem.c 2009-03-23 19:12:14.000000000 -0400
14935 +++ linux-2.6.29/drivers/char/mem.c 2009-03-28 14:26:19.000000000 -0400
14937 #include <linux/raw.h>
14938 #include <linux/tty.h>
14939 #include <linux/capability.h>
14940 +#include <linux/security.h>
14941 #include <linux/ptrace.h>
14942 #include <linux/device.h>
14943 #include <linux/highmem.h>
14945 # include <linux/efi.h>
14948 +#ifdef CONFIG_GRKERNSEC
14949 +extern struct file_operations grsec_fops;
14953 * Architectures vary in how they handle caching for addresses
14954 * outside of main memory.
14955 @@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f
14956 if (!valid_phys_addr_range(p, count))
14959 +#ifdef CONFIG_GRKERNSEC_KMEM
14960 + gr_handle_mem_write();
14966 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
14967 @@ -350,6 +360,11 @@ static int mmap_mem(struct file * file,
14968 &vma->vm_page_prot))
14971 +#ifdef CONFIG_GRKERNSEC_KMEM
14972 + if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
14976 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
14978 vma->vm_page_prot);
14979 @@ -585,6 +600,11 @@ static ssize_t write_kmem(struct file *
14981 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
14983 +#ifdef CONFIG_GRKERNSEC_KMEM
14984 + gr_handle_kmem_write();
14988 if (p < (unsigned long) high_memory) {
14991 @@ -788,6 +808,16 @@ static loff_t memory_lseek(struct file *
14993 static int open_port(struct inode * inode, struct file * filp)
14995 +#ifdef CONFIG_GRKERNSEC_KMEM
14996 + gr_handle_open_port();
15000 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
15003 +static int open_mem(struct inode * inode, struct file * filp)
15005 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
15008 @@ -795,7 +825,6 @@ static int open_port(struct inode * inod
15009 #define full_lseek null_lseek
15010 #define write_zero write_null
15011 #define read_full read_zero
15012 -#define open_mem open_port
15013 #define open_kmem open_mem
15014 #define open_oldmem open_mem
15016 @@ -935,6 +964,11 @@ static int memory_open(struct inode * in
15017 filp->f_op = &oldmem_fops;
15020 +#ifdef CONFIG_GRKERNSEC
15022 + filp->f_op = &grsec_fops;
15028 @@ -971,6 +1005,9 @@ static const struct {
15029 #ifdef CONFIG_CRASH_DUMP
15030 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
15032 +#ifdef CONFIG_GRKERNSEC
15033 + {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
15037 static struct class *mem_class;
15038 diff -urNp linux-2.6.29/drivers/char/nvram.c linux-2.6.29/drivers/char/nvram.c
15039 --- linux-2.6.29/drivers/char/nvram.c 2009-03-23 19:12:14.000000000 -0400
15040 +++ linux-2.6.29/drivers/char/nvram.c 2009-03-28 14:26:19.000000000 -0400
15041 @@ -429,7 +429,10 @@ static const struct file_operations nvra
15042 static struct miscdevice nvram_dev = {
15052 static int __init nvram_init(void)
15053 diff -urNp linux-2.6.29/drivers/char/random.c linux-2.6.29/drivers/char/random.c
15054 --- linux-2.6.29/drivers/char/random.c 2009-03-23 19:12:14.000000000 -0400
15055 +++ linux-2.6.29/drivers/char/random.c 2009-03-28 14:26:19.000000000 -0400
15056 @@ -249,8 +249,13 @@
15058 * Configuration information
15060 +#ifdef CONFIG_GRKERNSEC_RANDNET
15061 +#define INPUT_POOL_WORDS 512
15062 +#define OUTPUT_POOL_WORDS 128
15064 #define INPUT_POOL_WORDS 128
15065 #define OUTPUT_POOL_WORDS 32
15067 #define SEC_XFER_SIZE 512
15070 @@ -287,10 +292,17 @@ static struct poolinfo {
15072 int tap1, tap2, tap3, tap4, tap5;
15073 } poolinfo_table[] = {
15074 +#ifdef CONFIG_GRKERNSEC_RANDNET
15075 + /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
15076 + { 512, 411, 308, 208, 104, 1 },
15077 + /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
15078 + { 128, 103, 76, 51, 25, 1 },
15080 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
15081 { 128, 103, 76, 51, 25, 1 },
15082 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
15083 { 32, 26, 20, 14, 7, 1 },
15086 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
15087 { 2048, 1638, 1231, 819, 411, 1 },
15088 @@ -1200,7 +1212,7 @@ EXPORT_SYMBOL(generate_random_uuid);
15089 #include <linux/sysctl.h>
15091 static int min_read_thresh = 8, min_write_thresh;
15092 -static int max_read_thresh = INPUT_POOL_WORDS * 32;
15093 +static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
15094 static int max_write_thresh = INPUT_POOL_WORDS * 32;
15095 static char sysctl_bootid[16];
15097 diff -urNp linux-2.6.29/drivers/char/tty_ldisc.c linux-2.6.29/drivers/char/tty_ldisc.c
15098 --- linux-2.6.29/drivers/char/tty_ldisc.c 2009-03-23 19:12:14.000000000 -0400
15099 +++ linux-2.6.29/drivers/char/tty_ldisc.c 2009-03-28 14:26:19.000000000 -0400
15100 @@ -74,7 +74,7 @@ int tty_register_ldisc(int disc, struct
15101 spin_lock_irqsave(&tty_ldisc_lock, flags);
15102 tty_ldiscs[disc] = new_ldisc;
15103 new_ldisc->num = disc;
15104 - new_ldisc->refcount = 0;
15105 + atomic_set(&new_ldisc->refcount, 0);
15106 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
15109 @@ -102,7 +102,7 @@ int tty_unregister_ldisc(int disc)
15112 spin_lock_irqsave(&tty_ldisc_lock, flags);
15113 - if (tty_ldiscs[disc]->refcount)
15114 + if (atomic_read(&tty_ldiscs[disc]->refcount))
15117 tty_ldiscs[disc] = NULL;
15118 @@ -139,7 +139,7 @@ static int tty_ldisc_try_get(int disc, s
15122 - ldops->refcount++;
15123 + atomic_inc(&ldops->refcount);
15127 @@ -196,8 +196,8 @@ static void tty_ldisc_put(struct tty_ldi
15129 spin_lock_irqsave(&tty_ldisc_lock, flags);
15130 ld = tty_ldiscs[disc];
15131 - BUG_ON(ld->refcount == 0);
15133 + BUG_ON(atomic_read(&ld->refcount) == 0);
15134 + atomic_dec(&ld->refcount);
15135 module_put(ld->owner);
15136 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
15138 @@ -264,7 +264,7 @@ const struct file_operations tty_ldiscs_
15140 static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
15142 - ld->refcount = 0;
15143 + atomic_set(&ld->refcount, 0);
15147 @@ -289,7 +289,7 @@ static int tty_ldisc_try(struct tty_stru
15148 spin_lock_irqsave(&tty_ldisc_lock, flags);
15150 if (test_bit(TTY_LDISC, &tty->flags)) {
15152 + atomic_inc(&ld->refcount);
15155 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
15156 @@ -316,7 +316,7 @@ struct tty_ldisc *tty_ldisc_ref_wait(str
15158 /* wait_event is a macro */
15159 wait_event(tty_ldisc_wait, tty_ldisc_try(tty));
15160 - WARN_ON(tty->ldisc.refcount == 0);
15161 + WARN_ON(atomic_read(&tty->ldisc.refcount) == 0);
15162 return &tty->ldisc;
15165 @@ -359,11 +359,9 @@ void tty_ldisc_deref(struct tty_ldisc *l
15166 BUG_ON(ld == NULL);
15168 spin_lock_irqsave(&tty_ldisc_lock, flags);
15169 - if (ld->refcount == 0)
15170 + if (!atomic_add_unless(&ld->refcount, -1, 0))
15171 printk(KERN_ERR "tty_ldisc_deref: no references.\n");
15174 - if (ld->refcount == 0)
15175 + if (atomic_read(&ld->refcount) == 0)
15176 wake_up(&tty_ldisc_wait);
15177 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
15179 @@ -507,8 +505,8 @@ restart:
15180 clear_bit(TTY_LDISC, &o_tty->flags);
15182 spin_lock_irqsave(&tty_ldisc_lock, flags);
15183 - if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
15184 - if (tty->ldisc.refcount) {
15185 + if (atomic_read(&tty->ldisc.refcount) || (o_tty && atomic_read(&o_tty->ldisc.refcount))) {
15186 + if (atomic_read(&tty->ldisc.refcount)) {
15187 /* Free the new ldisc we grabbed. Must drop the lock
15189 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
15190 @@ -520,14 +518,14 @@ restart:
15191 * and retries if we made tty_ldisc_wait() smarter.
15192 * That is up for discussion.
15194 - if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
15195 + if (wait_event_interruptible(tty_ldisc_wait, atomic_read(&tty->ldisc.refcount) == 0) < 0)
15196 return -ERESTARTSYS;
15199 - if (o_tty && o_tty->ldisc.refcount) {
15200 + if (o_tty && atomic_read(&o_tty->ldisc.refcount)) {
15201 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
15202 tty_ldisc_put(o_tty->ldisc.ops);
15203 - if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
15204 + if (wait_event_interruptible(tty_ldisc_wait, atomic_read(&o_tty->ldisc.refcount) == 0) < 0)
15205 return -ERESTARTSYS;
15208 @@ -670,9 +668,9 @@ void tty_ldisc_release(struct tty_struct
15211 spin_lock_irqsave(&tty_ldisc_lock, flags);
15212 - while (tty->ldisc.refcount) {
15213 + while (atomic_read(&tty->ldisc.refcount)) {
15214 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
15215 - wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0);
15216 + wait_event(tty_ldisc_wait, atomic_read(&tty->ldisc.refcount) == 0);
15217 spin_lock_irqsave(&tty_ldisc_lock, flags);
15219 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
15220 diff -urNp linux-2.6.29/drivers/char/vt_ioctl.c linux-2.6.29/drivers/char/vt_ioctl.c
15221 --- linux-2.6.29/drivers/char/vt_ioctl.c 2009-03-23 19:12:14.000000000 -0400
15222 +++ linux-2.6.29/drivers/char/vt_ioctl.c 2009-03-28 14:26:19.000000000 -0400
15223 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
15228 +#ifdef CONFIG_GRKERNSEC
15229 + if (!capable(CAP_SYS_TTY_CONFIG))
15233 if (!i && v == K_NOSUCHMAP) {
15234 /* deallocate map */
15235 key_map = key_maps[s];
15236 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
15240 +#ifdef CONFIG_GRKERNSEC
15241 + if (!capable(CAP_SYS_TTY_CONFIG)) {
15248 first_free = funcbufptr + (funcbufsize - funcbufleft);
15249 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
15250 diff -urNp linux-2.6.29/drivers/edac/edac_core.h linux-2.6.29/drivers/edac/edac_core.h
15251 --- linux-2.6.29/drivers/edac/edac_core.h 2009-03-23 19:12:14.000000000 -0400
15252 +++ linux-2.6.29/drivers/edac/edac_core.h 2009-03-28 14:26:19.000000000 -0400
15253 @@ -85,11 +85,11 @@ extern int edac_debug_level;
15255 #else /* !CONFIG_EDAC_DEBUG */
15257 -#define debugf0( ... )
15258 -#define debugf1( ... )
15259 -#define debugf2( ... )
15260 -#define debugf3( ... )
15261 -#define debugf4( ... )
15262 +#define debugf0( ... ) do {} while (0)
15263 +#define debugf1( ... ) do {} while (0)
15264 +#define debugf2( ... ) do {} while (0)
15265 +#define debugf3( ... ) do {} while (0)
15266 +#define debugf4( ... ) do {} while (0)
15268 #endif /* !CONFIG_EDAC_DEBUG */
15270 diff -urNp linux-2.6.29/drivers/firmware/dmi_scan.c linux-2.6.29/drivers/firmware/dmi_scan.c
15271 --- linux-2.6.29/drivers/firmware/dmi_scan.c 2009-03-23 19:12:14.000000000 -0400
15272 +++ linux-2.6.29/drivers/firmware/dmi_scan.c 2009-03-28 14:26:19.000000000 -0400
15273 @@ -389,11 +389,6 @@ void __init dmi_scan_machine(void)
15278 - * no iounmap() for that ioremap(); it would be a no-op, but
15279 - * it's so early in setup that sucker gets confused into doing
15280 - * what it shouldn't if we actually call it.
15282 p = dmi_ioremap(0xF0000, 0x10000);
15285 diff -urNp linux-2.6.29/drivers/hwmon/fscpos.c linux-2.6.29/drivers/hwmon/fscpos.c
15286 --- linux-2.6.29/drivers/hwmon/fscpos.c 2009-03-23 19:12:14.000000000 -0400
15287 +++ linux-2.6.29/drivers/hwmon/fscpos.c 2009-03-28 14:26:19.000000000 -0400
15288 @@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client
15289 unsigned long v = simple_strtoul(buf, NULL, 10);
15291 /* Range: 0..255 */
15292 - if (v < 0) v = 0;
15293 if (v > 255) v = 255;
15295 mutex_lock(&data->update_lock);
15296 diff -urNp linux-2.6.29/drivers/hwmon/k8temp.c linux-2.6.29/drivers/hwmon/k8temp.c
15297 --- linux-2.6.29/drivers/hwmon/k8temp.c 2009-03-23 19:12:14.000000000 -0400
15298 +++ linux-2.6.29/drivers/hwmon/k8temp.c 2009-03-28 14:26:19.000000000 -0400
15299 @@ -138,7 +138,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
15301 static struct pci_device_id k8temp_ids[] = {
15302 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
15304 + { 0, 0, 0, 0, 0, 0, 0 },
15307 MODULE_DEVICE_TABLE(pci, k8temp_ids);
15308 diff -urNp linux-2.6.29/drivers/hwmon/sis5595.c linux-2.6.29/drivers/hwmon/sis5595.c
15309 --- linux-2.6.29/drivers/hwmon/sis5595.c 2009-03-23 19:12:14.000000000 -0400
15310 +++ linux-2.6.29/drivers/hwmon/sis5595.c 2009-03-28 14:26:19.000000000 -0400
15311 @@ -699,7 +699,7 @@ static struct sis5595_data *sis5595_upda
15313 static struct pci_device_id sis5595_pci_ids[] = {
15314 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
15316 + { 0, 0, 0, 0, 0, 0, 0 }
15319 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
15320 diff -urNp linux-2.6.29/drivers/hwmon/via686a.c linux-2.6.29/drivers/hwmon/via686a.c
15321 --- linux-2.6.29/drivers/hwmon/via686a.c 2009-03-23 19:12:14.000000000 -0400
15322 +++ linux-2.6.29/drivers/hwmon/via686a.c 2009-03-28 14:26:19.000000000 -0400
15323 @@ -769,7 +769,7 @@ static struct via686a_data *via686a_upda
15325 static struct pci_device_id via686a_pci_ids[] = {
15326 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
15328 + { 0, 0, 0, 0, 0, 0, 0 }
15331 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
15332 diff -urNp linux-2.6.29/drivers/hwmon/vt8231.c linux-2.6.29/drivers/hwmon/vt8231.c
15333 --- linux-2.6.29/drivers/hwmon/vt8231.c 2009-03-23 19:12:14.000000000 -0400
15334 +++ linux-2.6.29/drivers/hwmon/vt8231.c 2009-03-28 14:26:19.000000000 -0400
15335 @@ -699,7 +699,7 @@ static struct platform_driver vt8231_dri
15337 static struct pci_device_id vt8231_pci_ids[] = {
15338 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
15340 + { 0, 0, 0, 0, 0, 0, 0 }
15343 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
15344 diff -urNp linux-2.6.29/drivers/hwmon/w83791d.c linux-2.6.29/drivers/hwmon/w83791d.c
15345 --- linux-2.6.29/drivers/hwmon/w83791d.c 2009-03-23 19:12:14.000000000 -0400
15346 +++ linux-2.6.29/drivers/hwmon/w83791d.c 2009-03-28 14:26:19.000000000 -0400
15347 @@ -330,8 +330,8 @@ static int w83791d_detect(struct i2c_cli
15348 struct i2c_board_info *info);
15349 static int w83791d_remove(struct i2c_client *client);
15351 -static int w83791d_read(struct i2c_client *client, u8 register);
15352 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
15353 +static int w83791d_read(struct i2c_client *client, u8 reg);
15354 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
15355 static struct w83791d_data *w83791d_update_device(struct device *dev);
15358 diff -urNp linux-2.6.29/drivers/i2c/busses/i2c-i801.c linux-2.6.29/drivers/i2c/busses/i2c-i801.c
15359 --- linux-2.6.29/drivers/i2c/busses/i2c-i801.c 2009-03-23 19:12:14.000000000 -0400
15360 +++ linux-2.6.29/drivers/i2c/busses/i2c-i801.c 2009-03-28 14:26:19.000000000 -0400
15361 @@ -577,7 +577,7 @@ static struct pci_device_id i801_ids[] =
15362 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
15363 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
15364 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_SMBUS) },
15366 + { 0, 0, 0, 0, 0, 0, 0 }
15369 MODULE_DEVICE_TABLE (pci, i801_ids);
15370 diff -urNp linux-2.6.29/drivers/i2c/busses/i2c-piix4.c linux-2.6.29/drivers/i2c/busses/i2c-piix4.c
15371 --- linux-2.6.29/drivers/i2c/busses/i2c-piix4.c 2009-03-23 19:12:14.000000000 -0400
15372 +++ linux-2.6.29/drivers/i2c/busses/i2c-piix4.c 2009-03-28 14:26:19.000000000 -0400
15373 @@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat
15375 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
15378 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
15381 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
15382 @@ -423,7 +423,7 @@ static struct pci_device_id piix4_ids[]
15383 PCI_DEVICE_ID_SERVERWORKS_CSB6) },
15384 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
15385 PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
15387 + { 0, 0, 0, 0, 0, 0, 0 }
15390 MODULE_DEVICE_TABLE (pci, piix4_ids);
15391 diff -urNp linux-2.6.29/drivers/i2c/busses/i2c-sis630.c linux-2.6.29/drivers/i2c/busses/i2c-sis630.c
15392 --- linux-2.6.29/drivers/i2c/busses/i2c-sis630.c 2009-03-23 19:12:14.000000000 -0400
15393 +++ linux-2.6.29/drivers/i2c/busses/i2c-sis630.c 2009-03-28 14:26:19.000000000 -0400
15394 @@ -471,7 +471,7 @@ static struct i2c_adapter sis630_adapter
15395 static struct pci_device_id sis630_ids[] __devinitdata = {
15396 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
15397 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
15399 + { 0, 0, 0, 0, 0, 0, 0 }
15402 MODULE_DEVICE_TABLE (pci, sis630_ids);
15403 diff -urNp linux-2.6.29/drivers/i2c/busses/i2c-sis96x.c linux-2.6.29/drivers/i2c/busses/i2c-sis96x.c
15404 --- linux-2.6.29/drivers/i2c/busses/i2c-sis96x.c 2009-03-23 19:12:14.000000000 -0400
15405 +++ linux-2.6.29/drivers/i2c/busses/i2c-sis96x.c 2009-03-28 14:26:19.000000000 -0400
15406 @@ -247,7 +247,7 @@ static struct i2c_adapter sis96x_adapter
15408 static struct pci_device_id sis96x_ids[] = {
15409 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
15411 + { 0, 0, 0, 0, 0, 0, 0 }
15414 MODULE_DEVICE_TABLE (pci, sis96x_ids);
15415 diff -urNp linux-2.6.29/drivers/ieee1394/dv1394.c linux-2.6.29/drivers/ieee1394/dv1394.c
15416 --- linux-2.6.29/drivers/ieee1394/dv1394.c 2009-03-23 19:12:14.000000000 -0400
15417 +++ linux-2.6.29/drivers/ieee1394/dv1394.c 2009-03-28 14:26:19.000000000 -0400
15418 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
15419 based upon DIF section and sequence
15422 -static void inline
15423 +static inline void
15424 frame_put_packet (struct frame *f, struct packet *p)
15426 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
15427 @@ -2181,7 +2181,7 @@ static struct ieee1394_device_id dv1394_
15428 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
15429 .version = AVC_SW_VERSION_ENTRY & 0xffffff
15432 + { 0, 0, 0, 0, 0, 0 }
15435 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
15436 diff -urNp linux-2.6.29/drivers/ieee1394/eth1394.c linux-2.6.29/drivers/ieee1394/eth1394.c
15437 --- linux-2.6.29/drivers/ieee1394/eth1394.c 2009-03-23 19:12:14.000000000 -0400
15438 +++ linux-2.6.29/drivers/ieee1394/eth1394.c 2009-03-28 14:26:19.000000000 -0400
15439 @@ -445,7 +445,7 @@ static struct ieee1394_device_id eth1394
15440 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
15441 .version = ETHER1394_GASP_VERSION,
15444 + { 0, 0, 0, 0, 0, 0 }
15447 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
15448 diff -urNp linux-2.6.29/drivers/ieee1394/hosts.c linux-2.6.29/drivers/ieee1394/hosts.c
15449 --- linux-2.6.29/drivers/ieee1394/hosts.c 2009-03-23 19:12:14.000000000 -0400
15450 +++ linux-2.6.29/drivers/ieee1394/hosts.c 2009-03-28 14:26:19.000000000 -0400
15451 @@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
15454 static struct hpsb_host_driver dummy_driver = {
15456 .transmit_packet = dummy_transmit_packet,
15457 .devctl = dummy_devctl,
15458 .isoctl = dummy_isoctl
15459 diff -urNp linux-2.6.29/drivers/ieee1394/ohci1394.c linux-2.6.29/drivers/ieee1394/ohci1394.c
15460 --- linux-2.6.29/drivers/ieee1394/ohci1394.c 2009-03-23 19:12:14.000000000 -0400
15461 +++ linux-2.6.29/drivers/ieee1394/ohci1394.c 2009-03-28 14:26:19.000000000 -0400
15462 @@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
15463 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
15465 /* Module Parameters */
15466 -static int phys_dma = 1;
15467 +static int phys_dma;
15468 module_param(phys_dma, int, 0444);
15469 -MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
15470 +MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
15472 static void dma_trm_tasklet(unsigned long data);
15473 static void dma_trm_reset(struct dma_trm_ctx *d);
15474 @@ -3449,7 +3449,7 @@ static struct pci_device_id ohci1394_pci
15475 .subvendor = PCI_ANY_ID,
15476 .subdevice = PCI_ANY_ID,
15479 + { 0, 0, 0, 0, 0, 0, 0 },
15482 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
15483 diff -urNp linux-2.6.29/drivers/ieee1394/raw1394.c linux-2.6.29/drivers/ieee1394/raw1394.c
15484 --- linux-2.6.29/drivers/ieee1394/raw1394.c 2009-03-23 19:12:14.000000000 -0400
15485 +++ linux-2.6.29/drivers/ieee1394/raw1394.c 2009-03-28 14:26:19.000000000 -0400
15486 @@ -2995,7 +2995,7 @@ static struct ieee1394_device_id raw1394
15487 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
15488 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
15489 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
15491 + { 0, 0, 0, 0, 0, 0 }
15494 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
15495 diff -urNp linux-2.6.29/drivers/ieee1394/sbp2.c linux-2.6.29/drivers/ieee1394/sbp2.c
15496 --- linux-2.6.29/drivers/ieee1394/sbp2.c 2009-03-23 19:12:14.000000000 -0400
15497 +++ linux-2.6.29/drivers/ieee1394/sbp2.c 2009-03-28 14:26:19.000000000 -0400
15498 @@ -290,7 +290,7 @@ static struct ieee1394_device_id sbp2_id
15499 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
15500 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
15501 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
15503 + { 0, 0, 0, 0, 0, 0 }
15505 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
15507 @@ -2112,7 +2112,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
15508 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
15509 MODULE_LICENSE("GPL");
15511 -static int sbp2_module_init(void)
15512 +static int __init sbp2_module_init(void)
15516 diff -urNp linux-2.6.29/drivers/ieee1394/video1394.c linux-2.6.29/drivers/ieee1394/video1394.c
15517 --- linux-2.6.29/drivers/ieee1394/video1394.c 2009-03-23 19:12:14.000000000 -0400
15518 +++ linux-2.6.29/drivers/ieee1394/video1394.c 2009-03-28 14:26:19.000000000 -0400
15519 @@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
15520 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
15521 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
15524 + { 0, 0, 0, 0, 0, 0 }
15527 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
15528 diff -urNp linux-2.6.29/drivers/input/keyboard/atkbd.c linux-2.6.29/drivers/input/keyboard/atkbd.c
15529 --- linux-2.6.29/drivers/input/keyboard/atkbd.c 2009-03-23 19:12:14.000000000 -0400
15530 +++ linux-2.6.29/drivers/input/keyboard/atkbd.c 2009-03-28 14:26:19.000000000 -0400
15531 @@ -1181,7 +1181,7 @@ static struct serio_device_id atkbd_seri
15533 .extra = SERIO_ANY,
15539 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
15540 diff -urNp linux-2.6.29/drivers/input/mouse/lifebook.c linux-2.6.29/drivers/input/mouse/lifebook.c
15541 --- linux-2.6.29/drivers/input/mouse/lifebook.c 2009-03-23 19:12:14.000000000 -0400
15542 +++ linux-2.6.29/drivers/input/mouse/lifebook.c 2009-03-28 14:26:19.000000000 -0400
15543 @@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
15544 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
15548 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
15551 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
15552 diff -urNp linux-2.6.29/drivers/input/mouse/psmouse-base.c linux-2.6.29/drivers/input/mouse/psmouse-base.c
15553 --- linux-2.6.29/drivers/input/mouse/psmouse-base.c 2009-03-23 19:12:14.000000000 -0400
15554 +++ linux-2.6.29/drivers/input/mouse/psmouse-base.c 2009-03-28 14:26:19.000000000 -0400
15555 @@ -1378,7 +1378,7 @@ static struct serio_device_id psmouse_se
15557 .extra = SERIO_ANY,
15563 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
15564 diff -urNp linux-2.6.29/drivers/input/mouse/synaptics.c linux-2.6.29/drivers/input/mouse/synaptics.c
15565 --- linux-2.6.29/drivers/input/mouse/synaptics.c 2009-03-23 19:12:14.000000000 -0400
15566 +++ linux-2.6.29/drivers/input/mouse/synaptics.c 2009-03-28 14:26:19.000000000 -0400
15567 @@ -412,7 +412,7 @@ static void synaptics_process_packet(str
15570 if (SYN_MODEL_PEN(priv->model_id))
15571 - ; /* Nothing, treat a pen as a single finger */
15572 + break; /* Nothing, treat a pen as a single finger */
15575 if (SYN_CAP_PALMDETECT(priv->capabilities))
15576 @@ -625,7 +625,7 @@ static const struct dmi_system_id toshib
15577 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
15581 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15585 diff -urNp linux-2.6.29/drivers/input/mousedev.c linux-2.6.29/drivers/input/mousedev.c
15586 --- linux-2.6.29/drivers/input/mousedev.c 2009-03-23 19:12:14.000000000 -0400
15587 +++ linux-2.6.29/drivers/input/mousedev.c 2009-03-28 14:26:19.000000000 -0400
15588 @@ -1062,7 +1062,7 @@ static struct input_handler mousedev_han
15590 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
15591 static struct miscdevice psaux_mouse = {
15592 - PSMOUSE_MINOR, "psaux", &mousedev_fops
15593 + PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
15595 static int psaux_registered;
15597 diff -urNp linux-2.6.29/drivers/input/serio/i8042-x86ia64io.h linux-2.6.29/drivers/input/serio/i8042-x86ia64io.h
15598 --- linux-2.6.29/drivers/input/serio/i8042-x86ia64io.h 2009-03-23 19:12:14.000000000 -0400
15599 +++ linux-2.6.29/drivers/input/serio/i8042-x86ia64io.h 2009-03-28 14:26:19.000000000 -0400
15600 @@ -151,7 +151,7 @@ static struct dmi_system_id __initdata i
15601 DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
15605 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15609 @@ -366,7 +366,7 @@ static struct dmi_system_id __initdata i
15610 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
15614 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15618 @@ -378,7 +378,7 @@ static struct dmi_system_id __initdata i
15619 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
15623 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15627 @@ -445,7 +445,7 @@ static struct dmi_system_id __initdata i
15628 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
15632 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15635 #endif /* CONFIG_X86 */
15636 diff -urNp linux-2.6.29/drivers/input/serio/serio_raw.c linux-2.6.29/drivers/input/serio/serio_raw.c
15637 --- linux-2.6.29/drivers/input/serio/serio_raw.c 2009-03-23 19:12:14.000000000 -0400
15638 +++ linux-2.6.29/drivers/input/serio/serio_raw.c 2009-03-28 14:26:19.000000000 -0400
15639 @@ -378,7 +378,7 @@ static struct serio_device_id serio_raw_
15641 .extra = SERIO_ANY,
15647 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
15648 diff -urNp linux-2.6.29/drivers/lguest/core.c linux-2.6.29/drivers/lguest/core.c
15649 --- linux-2.6.29/drivers/lguest/core.c 2009-03-23 19:12:14.000000000 -0400
15650 +++ linux-2.6.29/drivers/lguest/core.c 2009-03-28 14:26:19.000000000 -0400
15651 @@ -80,9 +80,17 @@ static __init int map_switcher(void)
15652 * (SWITCHER_ADDR). We might not get it in theory, but in practice
15653 * it's worked so far. The end address needs +1 because __get_vm_area
15654 * allocates an extra guard page, so we need space for that. */
15656 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
15657 + switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
15658 + VM_ALLOC | VM_KERNEXEC, SWITCHER_ADDR, SWITCHER_ADDR
15659 + + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
15661 switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
15662 VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR
15663 + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
15666 if (!switcher_vma) {
15668 printk("lguest: could not map switcher pages high\n");
15669 diff -urNp linux-2.6.29/drivers/md/bitmap.c linux-2.6.29/drivers/md/bitmap.c
15670 --- linux-2.6.29/drivers/md/bitmap.c 2009-03-23 19:12:14.000000000 -0400
15671 +++ linux-2.6.29/drivers/md/bitmap.c 2009-03-28 14:26:19.000000000 -0400
15674 # define PRINTK(x...) printk(KERN_DEBUG x)
15676 -# define PRINTK(x...)
15677 +# define PRINTK(x...) do {} while (0)
15681 diff -urNp linux-2.6.29/drivers/md/md.c linux-2.6.29/drivers/md/md.c
15682 --- linux-2.6.29/drivers/md/md.c 2009-03-23 19:12:14.000000000 -0400
15683 +++ linux-2.6.29/drivers/md/md.c 2009-03-28 14:26:19.000000000 -0400
15684 @@ -5640,7 +5640,7 @@ static int md_seq_show(struct seq_file *
15685 chunk_kb ? "KB" : "B");
15686 if (bitmap->file) {
15687 seq_printf(seq, ", file: ");
15688 - seq_path(seq, &bitmap->file->f_path, " \t\n");
15689 + seq_path(seq, &bitmap->file->f_path, " \t\n\\");
15692 seq_printf(seq, "\n");
15693 diff -urNp linux-2.6.29/drivers/mtd/devices/doc2000.c linux-2.6.29/drivers/mtd/devices/doc2000.c
15694 --- linux-2.6.29/drivers/mtd/devices/doc2000.c 2009-03-23 19:12:14.000000000 -0400
15695 +++ linux-2.6.29/drivers/mtd/devices/doc2000.c 2009-03-28 14:26:19.000000000 -0400
15696 @@ -777,7 +777,7 @@ static int doc_write(struct mtd_info *mt
15698 /* The ECC will not be calculated correctly if less than 512 is written */
15700 - if (len != 0x200 && eccbuf)
15701 + if (len != 0x200)
15702 printk(KERN_WARNING
15703 "ECC needs a full sector write (adr: %lx size %lx)\n",
15704 (long) to, (long) len);
15705 diff -urNp linux-2.6.29/drivers/mtd/devices/doc2001.c linux-2.6.29/drivers/mtd/devices/doc2001.c
15706 --- linux-2.6.29/drivers/mtd/devices/doc2001.c 2009-03-23 19:12:14.000000000 -0400
15707 +++ linux-2.6.29/drivers/mtd/devices/doc2001.c 2009-03-28 14:26:19.000000000 -0400
15708 @@ -396,6 +396,8 @@ static int doc_read (struct mtd_info *mt
15709 /* Don't allow read past end of device */
15710 if (from >= this->totlen)
15715 /* Don't allow a single read to cross a 512-byte block boundary */
15716 if (from + len > ((from | 0x1ff) + 1))
15717 diff -urNp linux-2.6.29/drivers/mtd/ubi/build.c linux-2.6.29/drivers/mtd/ubi/build.c
15718 --- linux-2.6.29/drivers/mtd/ubi/build.c 2009-03-23 19:12:14.000000000 -0400
15719 +++ linux-2.6.29/drivers/mtd/ubi/build.c 2009-03-28 14:26:19.000000000 -0400
15720 @@ -1112,7 +1112,7 @@ static int __init bytes_str_to_int(const
15721 unsigned long result;
15723 result = simple_strtoul(str, &endp, 0);
15724 - if (str == endp || result < 0) {
15725 + if (str == endp) {
15726 printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
15729 diff -urNp linux-2.6.29/drivers/net/irda/vlsi_ir.c linux-2.6.29/drivers/net/irda/vlsi_ir.c
15730 --- linux-2.6.29/drivers/net/irda/vlsi_ir.c 2009-03-23 19:12:14.000000000 -0400
15731 +++ linux-2.6.29/drivers/net/irda/vlsi_ir.c 2009-03-28 14:26:19.000000000 -0400
15732 @@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
15733 /* no race - tx-ring already empty */
15734 vlsi_set_baud(idev, iobase);
15735 netif_wake_queue(ndev);
15740 /* keep the speed change pending like it would
15741 * for any len>0 packet. tx completion interrupt
15742 * will apply it when the tx ring becomes empty.
15745 spin_unlock_irqrestore(&idev->lock, flags);
15746 dev_kfree_skb_any(skb);
15748 diff -urNp linux-2.6.29/drivers/net/pcnet32.c linux-2.6.29/drivers/net/pcnet32.c
15749 --- linux-2.6.29/drivers/net/pcnet32.c 2009-03-23 19:12:14.000000000 -0400
15750 +++ linux-2.6.29/drivers/net/pcnet32.c 2009-03-28 14:26:19.000000000 -0400
15751 @@ -78,7 +78,7 @@ static int cards_found;
15753 * VLB I/O addresses
15755 -static unsigned int pcnet32_portlist[] __initdata =
15756 +static unsigned int pcnet32_portlist[] __devinitdata =
15757 { 0x300, 0x320, 0x340, 0x360, 0 };
15759 static int pcnet32_debug = 0;
15760 diff -urNp linux-2.6.29/drivers/net/tg3.h linux-2.6.29/drivers/net/tg3.h
15761 --- linux-2.6.29/drivers/net/tg3.h 2009-03-23 19:12:14.000000000 -0400
15762 +++ linux-2.6.29/drivers/net/tg3.h 2009-03-28 14:26:20.000000000 -0400
15764 #define CHIPREV_ID_5750_A0 0x4000
15765 #define CHIPREV_ID_5750_A1 0x4001
15766 #define CHIPREV_ID_5750_A3 0x4003
15767 +#define CHIPREV_ID_5750_C1 0x4201
15768 #define CHIPREV_ID_5750_C2 0x4202
15769 #define CHIPREV_ID_5752_A0_HW 0x5000
15770 #define CHIPREV_ID_5752_A0 0x6000
15771 diff -urNp linux-2.6.29/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.29/drivers/pci/hotplug/cpqphp_nvram.c
15772 --- linux-2.6.29/drivers/pci/hotplug/cpqphp_nvram.c 2009-03-23 19:12:14.000000000 -0400
15773 +++ linux-2.6.29/drivers/pci/hotplug/cpqphp_nvram.c 2009-03-28 14:26:20.000000000 -0400
15774 @@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
15776 void compaq_nvram_init (void __iomem *rom_start)
15779 +#ifndef CONFIG_PAX_KERNEXEC
15781 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
15785 dbg("int15 entry = %p\n", compaq_int15_entry_point);
15787 /* initialize our int15 lock */
15788 diff -urNp linux-2.6.29/drivers/pci/pcie/aer/aerdrv.c linux-2.6.29/drivers/pci/pcie/aer/aerdrv.c
15789 --- linux-2.6.29/drivers/pci/pcie/aer/aerdrv.c 2009-03-23 19:12:14.000000000 -0400
15790 +++ linux-2.6.29/drivers/pci/pcie/aer/aerdrv.c 2009-03-28 14:26:20.000000000 -0400
15791 @@ -59,7 +59,7 @@ static struct pcie_port_service_id aer_i
15792 .port_type = PCIE_RC_PORT,
15793 .service_type = PCIE_PORT_SERVICE_AER,
15795 - { /* end: all zeroes */ }
15796 + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
15799 static struct pci_error_handlers aer_error_handlers = {
15800 diff -urNp linux-2.6.29/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.29/drivers/pci/pcie/aer/aerdrv_core.c
15801 --- linux-2.6.29/drivers/pci/pcie/aer/aerdrv_core.c 2009-03-23 19:12:14.000000000 -0400
15802 +++ linux-2.6.29/drivers/pci/pcie/aer/aerdrv_core.c 2009-03-28 14:26:20.000000000 -0400
15803 @@ -670,7 +670,7 @@ static void aer_isr_one_error(struct pci
15804 struct aer_err_source *e_src)
15806 struct device *s_device;
15807 - struct aer_err_info e_info = {0, 0, 0,};
15808 + struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
15812 diff -urNp linux-2.6.29/drivers/pci/pcie/portdrv_pci.c linux-2.6.29/drivers/pci/pcie/portdrv_pci.c
15813 --- linux-2.6.29/drivers/pci/pcie/portdrv_pci.c 2009-03-23 19:12:14.000000000 -0400
15814 +++ linux-2.6.29/drivers/pci/pcie/portdrv_pci.c 2009-03-28 14:26:20.000000000 -0400
15815 @@ -260,7 +260,7 @@ static void pcie_portdrv_err_resume(stru
15816 static const struct pci_device_id port_pci_ids[] = { {
15817 /* handle any PCI-Express port */
15818 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
15819 - }, { /* end: all zeroes */ }
15820 + }, { 0, 0, 0, 0, 0, 0, 0 }
15822 MODULE_DEVICE_TABLE(pci, port_pci_ids);
15824 diff -urNp linux-2.6.29/drivers/pci/proc.c linux-2.6.29/drivers/pci/proc.c
15825 --- linux-2.6.29/drivers/pci/proc.c 2009-03-23 19:12:14.000000000 -0400
15826 +++ linux-2.6.29/drivers/pci/proc.c 2009-03-28 14:26:20.000000000 -0400
15827 @@ -480,7 +480,16 @@ static const struct file_operations proc
15828 static int __init pci_proc_init(void)
15830 struct pci_dev *dev = NULL;
15832 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
15833 +#ifdef CONFIG_GRKERNSEC_PROC_USER
15834 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
15835 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
15836 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
15839 proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
15841 proc_create("devices", 0, proc_bus_pci_dir,
15842 &proc_bus_pci_dev_operations);
15843 proc_initialized = 1;
15844 diff -urNp linux-2.6.29/drivers/pcmcia/ti113x.h linux-2.6.29/drivers/pcmcia/ti113x.h
15845 --- linux-2.6.29/drivers/pcmcia/ti113x.h 2009-03-23 19:12:14.000000000 -0400
15846 +++ linux-2.6.29/drivers/pcmcia/ti113x.h 2009-03-28 14:26:20.000000000 -0400
15847 @@ -903,7 +903,7 @@ static struct pci_device_id ene_tune_tbl
15848 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
15849 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
15852 + { 0, 0, 0, 0, 0, 0, 0 }
15855 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
15856 diff -urNp linux-2.6.29/drivers/pcmcia/yenta_socket.c linux-2.6.29/drivers/pcmcia/yenta_socket.c
15857 --- linux-2.6.29/drivers/pcmcia/yenta_socket.c 2009-03-23 19:12:14.000000000 -0400
15858 +++ linux-2.6.29/drivers/pcmcia/yenta_socket.c 2009-03-28 14:26:20.000000000 -0400
15859 @@ -1366,7 +1366,7 @@ static struct pci_device_id yenta_table
15861 /* match any cardbus bridge */
15862 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
15863 - { /* all zeroes */ }
15864 + { 0, 0, 0, 0, 0, 0, 0 }
15866 MODULE_DEVICE_TABLE(pci, yenta_table);
15868 diff -urNp linux-2.6.29/drivers/pnp/pnpbios/bioscalls.c linux-2.6.29/drivers/pnp/pnpbios/bioscalls.c
15869 --- linux-2.6.29/drivers/pnp/pnpbios/bioscalls.c 2009-03-23 19:12:14.000000000 -0400
15870 +++ linux-2.6.29/drivers/pnp/pnpbios/bioscalls.c 2009-03-28 14:26:20.000000000 -0400
15871 @@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
15872 set_limit(gdt[(selname) >> 3], size); \
15875 -static struct desc_struct bad_bios_desc;
15876 +static struct desc_struct bad_bios_desc __read_only;
15879 * At some point we want to use this stack frame pointer to unwind
15880 @@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
15881 struct desc_struct save_desc_40;
15884 +#ifdef CONFIG_PAX_KERNEXEC
15885 + unsigned long cr0;
15889 * PnP BIOSes are generally not terribly re-entrant.
15890 * Also, don't rely on them to save everything correctly.
15891 @@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
15894 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
15896 +#ifdef CONFIG_PAX_KERNEXEC
15897 + pax_open_kernel(cr0);
15900 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
15902 +#ifdef CONFIG_PAX_KERNEXEC
15903 + pax_close_kernel(cr0);
15906 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
15907 spin_lock_irqsave(&pnp_bios_lock, flags);
15909 @@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
15911 spin_unlock_irqrestore(&pnp_bios_lock, flags);
15913 +#ifdef CONFIG_PAX_KERNEXEC
15914 + pax_open_kernel(cr0);
15917 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
15919 +#ifdef CONFIG_PAX_KERNEXEC
15920 + pax_close_kernel(cr0);
15925 /* If we get here and this is set then the PnP BIOS faulted on us. */
15926 @@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
15930 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
15931 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
15935 +#ifdef CONFIG_PAX_KERNEXEC
15936 + unsigned long cr0;
15939 spin_lock_init(&pnp_bios_lock);
15940 pnp_bios_callpoint.offset = header->fields.pm16offset;
15941 pnp_bios_callpoint.segment = PNP_CS16;
15943 +#ifdef CONFIG_PAX_KERNEXEC
15944 + pax_open_kernel(cr0);
15947 bad_bios_desc.a = 0;
15948 - bad_bios_desc.b = 0x00409200;
15949 + bad_bios_desc.b = 0x00409300;
15951 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
15952 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
15953 @@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
15954 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
15955 __va(header->fields.pm16dseg));
15958 +#ifdef CONFIG_PAX_KERNEXEC
15959 + pax_close_kernel(cr0);
15963 diff -urNp linux-2.6.29/drivers/pnp/quirks.c linux-2.6.29/drivers/pnp/quirks.c
15964 --- linux-2.6.29/drivers/pnp/quirks.c 2009-03-23 19:12:14.000000000 -0400
15965 +++ linux-2.6.29/drivers/pnp/quirks.c 2009-03-28 14:26:20.000000000 -0400
15966 @@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = {
15967 /* PnP resources that might overlap PCI BARs */
15968 {"PNP0c01", quirk_system_pci_resources},
15969 {"PNP0c02", quirk_system_pci_resources},
15974 void pnp_fixup_device(struct pnp_dev *dev)
15975 diff -urNp linux-2.6.29/drivers/pnp/resource.c linux-2.6.29/drivers/pnp/resource.c
15976 --- linux-2.6.29/drivers/pnp/resource.c 2009-03-23 19:12:14.000000000 -0400
15977 +++ linux-2.6.29/drivers/pnp/resource.c 2009-03-28 14:26:20.000000000 -0400
15978 @@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
15981 /* check if the resource is valid */
15982 - if (*irq < 0 || *irq > 15)
15986 /* check if the resource is reserved */
15987 @@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
15990 /* check if the resource is valid */
15991 - if (*dma < 0 || *dma == 4 || *dma > 7)
15992 + if (*dma == 4 || *dma > 7)
15995 /* check if the resource is reserved */
15996 diff -urNp linux-2.6.29/drivers/scsi/scsi_logging.h linux-2.6.29/drivers/scsi/scsi_logging.h
15997 --- linux-2.6.29/drivers/scsi/scsi_logging.h 2009-03-23 19:12:14.000000000 -0400
15998 +++ linux-2.6.29/drivers/scsi/scsi_logging.h 2009-03-28 14:26:20.000000000 -0400
15999 @@ -51,7 +51,7 @@ do { \
16003 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
16004 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
16005 #endif /* CONFIG_SCSI_LOGGING */
16008 diff -urNp linux-2.6.29/drivers/serial/8250_pci.c linux-2.6.29/drivers/serial/8250_pci.c
16009 --- linux-2.6.29/drivers/serial/8250_pci.c 2009-03-23 19:12:14.000000000 -0400
16010 +++ linux-2.6.29/drivers/serial/8250_pci.c 2009-03-28 14:26:20.000000000 -0400
16011 @@ -3162,7 +3162,7 @@ static struct pci_device_id serial_pci_t
16012 PCI_ANY_ID, PCI_ANY_ID,
16013 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
16014 0xffff00, pbn_default },
16016 + { 0, 0, 0, 0, 0, 0, 0 }
16019 static struct pci_driver serial_pci_driver = {
16020 diff -urNp linux-2.6.29/drivers/usb/class/cdc-acm.c linux-2.6.29/drivers/usb/class/cdc-acm.c
16021 --- linux-2.6.29/drivers/usb/class/cdc-acm.c 2009-03-23 19:12:14.000000000 -0400
16022 +++ linux-2.6.29/drivers/usb/class/cdc-acm.c 2009-03-28 14:26:20.000000000 -0400
16023 @@ -1401,7 +1401,7 @@ static struct usb_device_id acm_ids[] =
16024 USB_CDC_ACM_PROTO_AT_CDMA) },
16026 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
16028 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
16031 MODULE_DEVICE_TABLE (usb, acm_ids);
16032 diff -urNp linux-2.6.29/drivers/usb/class/usblp.c linux-2.6.29/drivers/usb/class/usblp.c
16033 --- linux-2.6.29/drivers/usb/class/usblp.c 2009-03-23 19:12:14.000000000 -0400
16034 +++ linux-2.6.29/drivers/usb/class/usblp.c 2009-03-28 14:26:20.000000000 -0400
16035 @@ -228,7 +228,7 @@ static const struct quirk_printer_struct
16036 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
16037 { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */
16038 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
16043 static int usblp_wwait(struct usblp *usblp, int nonblock);
16044 @@ -1403,7 +1403,7 @@ static struct usb_device_id usblp_ids []
16045 { USB_INTERFACE_INFO(7, 1, 2) },
16046 { USB_INTERFACE_INFO(7, 1, 3) },
16047 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
16048 - { } /* Terminating entry */
16049 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
16052 MODULE_DEVICE_TABLE (usb, usblp_ids);
16053 diff -urNp linux-2.6.29/drivers/usb/core/hub.c linux-2.6.29/drivers/usb/core/hub.c
16054 --- linux-2.6.29/drivers/usb/core/hub.c 2009-03-23 19:12:14.000000000 -0400
16055 +++ linux-2.6.29/drivers/usb/core/hub.c 2009-03-28 14:26:20.000000000 -0400
16056 @@ -3193,7 +3193,7 @@ static struct usb_device_id hub_id_table
16057 .bDeviceClass = USB_CLASS_HUB},
16058 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
16059 .bInterfaceClass = USB_CLASS_HUB},
16060 - { } /* Terminating entry */
16061 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
16064 MODULE_DEVICE_TABLE (usb, hub_id_table);
16065 diff -urNp linux-2.6.29/drivers/usb/host/ehci-pci.c linux-2.6.29/drivers/usb/host/ehci-pci.c
16066 --- linux-2.6.29/drivers/usb/host/ehci-pci.c 2009-03-23 19:12:14.000000000 -0400
16067 +++ linux-2.6.29/drivers/usb/host/ehci-pci.c 2009-03-28 14:26:20.000000000 -0400
16068 @@ -418,7 +418,7 @@ static const struct pci_device_id pci_id
16069 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
16070 .driver_data = (unsigned long) &ehci_pci_hc_driver,
16072 - { /* end: all zeroes */ }
16073 + { 0, 0, 0, 0, 0, 0, 0 }
16075 MODULE_DEVICE_TABLE(pci, pci_ids);
16077 diff -urNp linux-2.6.29/drivers/usb/host/uhci-hcd.c linux-2.6.29/drivers/usb/host/uhci-hcd.c
16078 --- linux-2.6.29/drivers/usb/host/uhci-hcd.c 2009-03-23 19:12:14.000000000 -0400
16079 +++ linux-2.6.29/drivers/usb/host/uhci-hcd.c 2009-03-28 14:26:20.000000000 -0400
16080 @@ -927,7 +927,7 @@ static const struct pci_device_id uhci_p
16081 /* handle any USB UHCI controller */
16082 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
16083 .driver_data = (unsigned long) &uhci_driver,
16084 - }, { /* end: all zeroes */ }
16085 + }, { 0, 0, 0, 0, 0, 0, 0 }
16088 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
16089 diff -urNp linux-2.6.29/drivers/usb/storage/debug.h linux-2.6.29/drivers/usb/storage/debug.h
16090 --- linux-2.6.29/drivers/usb/storage/debug.h 2009-03-23 19:12:14.000000000 -0400
16091 +++ linux-2.6.29/drivers/usb/storage/debug.h 2009-03-28 14:26:20.000000000 -0400
16092 @@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
16093 #define US_DEBUGPX(x...) printk( x )
16094 #define US_DEBUG(x) x
16096 -#define US_DEBUGP(x...)
16097 -#define US_DEBUGPX(x...)
16098 -#define US_DEBUG(x)
16099 +#define US_DEBUGP(x...) do {} while (0)
16100 +#define US_DEBUGPX(x...) do {} while (0)
16101 +#define US_DEBUG(x) do {} while (0)
16105 diff -urNp linux-2.6.29/drivers/usb/storage/usb.c linux-2.6.29/drivers/usb/storage/usb.c
16106 --- linux-2.6.29/drivers/usb/storage/usb.c 2009-03-23 19:12:14.000000000 -0400
16107 +++ linux-2.6.29/drivers/usb/storage/usb.c 2009-03-28 14:26:20.000000000 -0400
16108 @@ -141,7 +141,7 @@ static struct usb_device_id storage_usb_
16109 #undef COMPLIANT_DEV
16111 /* Terminating entry */
16113 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
16116 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
16117 @@ -184,7 +184,7 @@ static struct us_unusual_dev us_unusual_
16120 /* Terminating entry */
16122 + { NULL, NULL, 0, 0, NULL }
16126 diff -urNp linux-2.6.29/drivers/uwb/wlp/messages.c linux-2.6.29/drivers/uwb/wlp/messages.c
16127 --- linux-2.6.29/drivers/uwb/wlp/messages.c 2009-03-23 19:12:14.000000000 -0400
16128 +++ linux-2.6.29/drivers/uwb/wlp/messages.c 2009-03-28 14:26:20.000000000 -0400
16129 @@ -903,7 +903,7 @@ int wlp_parse_f0(struct wlp *wlp, struct
16130 size_t len = skb->len;
16133 - struct wlp_nonce enonce, rnonce;
16134 + struct wlp_nonce enonce = {{0}}, rnonce = {{0}};
16135 enum wlp_assc_error assc_err;
16136 char enonce_buf[WLP_WSS_NONCE_STRSIZE];
16137 char rnonce_buf[WLP_WSS_NONCE_STRSIZE];
16138 diff -urNp linux-2.6.29/drivers/video/fbmem.c linux-2.6.29/drivers/video/fbmem.c
16139 --- linux-2.6.29/drivers/video/fbmem.c 2009-03-23 19:12:14.000000000 -0400
16140 +++ linux-2.6.29/drivers/video/fbmem.c 2009-03-28 14:26:20.000000000 -0400
16141 @@ -393,7 +393,7 @@ static void fb_do_show_logo(struct fb_in
16142 image->dx += image->width + 8;
16144 } else if (rotate == FB_ROTATE_UD) {
16145 - for (x = 0; x < num && image->dx >= 0; x++) {
16146 + for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
16147 info->fbops->fb_imageblit(info, image);
16148 image->dx -= image->width + 8;
16150 @@ -405,7 +405,7 @@ static void fb_do_show_logo(struct fb_in
16151 image->dy += image->height + 8;
16153 } else if (rotate == FB_ROTATE_CCW) {
16154 - for (x = 0; x < num && image->dy >= 0; x++) {
16155 + for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
16156 info->fbops->fb_imageblit(info, image);
16157 image->dy -= image->height + 8;
16159 @@ -1100,7 +1100,7 @@ static long do_fb_ioctl(struct fb_info *
16161 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
16163 - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
16164 + if (con2fb.framebuffer >= FB_MAX)
16166 if (!registered_fb[con2fb.framebuffer])
16167 request_module("fb%d", con2fb.framebuffer);
16168 diff -urNp linux-2.6.29/drivers/video/fbmon.c linux-2.6.29/drivers/video/fbmon.c
16169 --- linux-2.6.29/drivers/video/fbmon.c 2009-03-23 19:12:14.000000000 -0400
16170 +++ linux-2.6.29/drivers/video/fbmon.c 2009-03-28 14:26:20.000000000 -0400
16173 #define DPRINTK(fmt, args...) printk(fmt,## args)
16175 -#define DPRINTK(fmt, args...)
16176 +#define DPRINTK(fmt, args...) do {} while (0)
16179 #define FBMON_FIX_HEADER 1
16180 diff -urNp linux-2.6.29/drivers/video/i810/i810_accel.c linux-2.6.29/drivers/video/i810/i810_accel.c
16181 --- linux-2.6.29/drivers/video/i810/i810_accel.c 2009-03-23 19:12:14.000000000 -0400
16182 +++ linux-2.6.29/drivers/video/i810/i810_accel.c 2009-03-28 14:26:20.000000000 -0400
16183 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct
16186 printk("ringbuffer lockup!!!\n");
16187 + printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
16188 i810_report_error(mmio);
16189 par->dev_flags |= LOCKUP;
16190 info->pixmap.scan_align = 1;
16191 diff -urNp linux-2.6.29/drivers/video/i810/i810_main.c linux-2.6.29/drivers/video/i810/i810_main.c
16192 --- linux-2.6.29/drivers/video/i810/i810_main.c 2009-03-23 19:12:14.000000000 -0400
16193 +++ linux-2.6.29/drivers/video/i810/i810_main.c 2009-03-28 14:26:20.000000000 -0400
16194 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
16195 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
16196 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
16197 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
16199 + { 0, 0, 0, 0, 0, 0, 0 },
16202 static struct pci_driver i810fb_driver = {
16203 diff -urNp linux-2.6.29/drivers/video/modedb.c linux-2.6.29/drivers/video/modedb.c
16204 --- linux-2.6.29/drivers/video/modedb.c 2009-03-23 19:12:14.000000000 -0400
16205 +++ linux-2.6.29/drivers/video/modedb.c 2009-03-28 14:26:20.000000000 -0400
16206 @@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
16208 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
16209 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
16210 - 0, FB_VMODE_NONINTERLACED
16211 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16213 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
16214 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
16215 - 0, FB_VMODE_NONINTERLACED
16216 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16218 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
16219 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
16220 - 0, FB_VMODE_NONINTERLACED
16221 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16223 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
16224 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
16225 - 0, FB_VMODE_INTERLACED
16226 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
16228 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
16229 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
16230 - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16231 + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16233 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
16234 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
16235 - 0, FB_VMODE_NONINTERLACED
16236 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16238 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
16239 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
16240 - 0, FB_VMODE_NONINTERLACED
16241 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16243 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
16244 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
16245 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16246 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16248 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
16249 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
16250 - 0, FB_VMODE_NONINTERLACED
16251 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16253 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
16254 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
16255 - 0, FB_VMODE_INTERLACED
16256 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
16258 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
16259 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
16260 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16261 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16263 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
16264 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
16265 - 0, FB_VMODE_NONINTERLACED
16266 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16268 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
16269 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
16270 - 0, FB_VMODE_NONINTERLACED
16271 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16273 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
16274 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
16275 - 0, FB_VMODE_NONINTERLACED
16276 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16278 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
16279 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
16280 - 0, FB_VMODE_NONINTERLACED
16281 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16283 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
16284 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
16285 - 0, FB_VMODE_NONINTERLACED
16286 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16288 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
16289 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
16290 - 0, FB_VMODE_INTERLACED
16291 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
16293 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
16294 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
16295 - 0, FB_VMODE_NONINTERLACED
16296 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16298 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
16299 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
16300 - 0, FB_VMODE_NONINTERLACED
16301 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16303 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
16304 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
16305 - 0, FB_VMODE_NONINTERLACED
16306 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16308 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
16309 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
16310 - 0, FB_VMODE_NONINTERLACED
16311 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16313 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
16314 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
16315 - 0, FB_VMODE_NONINTERLACED
16316 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16318 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
16319 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
16320 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16321 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16323 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
16324 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
16325 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16326 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16328 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
16329 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
16330 - 0, FB_VMODE_NONINTERLACED
16331 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16333 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
16334 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
16335 - 0, FB_VMODE_NONINTERLACED
16336 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16338 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
16339 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
16340 - 0, FB_VMODE_NONINTERLACED
16341 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16343 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
16344 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
16345 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16346 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16348 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
16349 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
16350 - 0, FB_VMODE_NONINTERLACED
16351 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16353 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
16354 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
16355 - 0, FB_VMODE_NONINTERLACED
16356 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16358 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
16359 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
16360 - 0, FB_VMODE_NONINTERLACED
16361 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16363 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
16364 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
16365 - 0, FB_VMODE_NONINTERLACED
16366 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16368 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
16369 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
16370 - 0, FB_VMODE_NONINTERLACED
16371 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16373 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
16374 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
16375 - 0, FB_VMODE_NONINTERLACED
16376 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16378 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
16379 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
16380 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16381 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16383 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
16384 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
16385 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16386 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16388 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
16389 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
16390 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16391 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16393 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
16394 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
16395 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16396 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16398 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
16399 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
16400 - 0, FB_VMODE_NONINTERLACED
16401 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16403 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
16404 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
16405 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16406 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16408 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
16409 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
16410 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16411 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16413 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
16414 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
16415 - 0, FB_VMODE_NONINTERLACED
16416 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16418 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
16419 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
16420 - 0, FB_VMODE_NONINTERLACED
16421 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16423 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
16424 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
16425 - 0, FB_VMODE_DOUBLE
16426 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16428 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
16429 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
16430 - 0, FB_VMODE_DOUBLE
16431 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16433 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
16434 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
16435 - 0, FB_VMODE_DOUBLE
16436 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16438 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
16439 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
16440 - 0, FB_VMODE_DOUBLE
16441 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16443 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
16444 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
16445 - 0, FB_VMODE_DOUBLE
16446 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16448 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
16449 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
16450 - 0, FB_VMODE_DOUBLE
16451 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16453 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
16454 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
16455 - 0, FB_VMODE_DOUBLE
16456 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16458 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
16459 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
16460 - 0, FB_VMODE_DOUBLE
16461 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16463 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
16464 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
16465 - 0, FB_VMODE_DOUBLE
16466 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16468 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
16469 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
16470 - 0, FB_VMODE_DOUBLE
16471 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16473 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
16474 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
16475 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
16476 - FB_VMODE_NONINTERLACED
16477 + FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16479 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
16480 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
16481 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16482 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16484 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
16485 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
16486 - 0, FB_VMODE_NONINTERLACED
16487 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16489 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
16490 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
16491 - 0, FB_VMODE_NONINTERLACED
16492 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16496 diff -urNp linux-2.6.29/drivers/video/uvesafb.c linux-2.6.29/drivers/video/uvesafb.c
16497 --- linux-2.6.29/drivers/video/uvesafb.c 2009-03-23 19:12:14.000000000 -0400
16498 +++ linux-2.6.29/drivers/video/uvesafb.c 2009-03-28 14:26:20.000000000 -0400
16500 #include <linux/fb.h>
16501 #include <linux/io.h>
16502 #include <linux/mutex.h>
16503 +#include <linux/moduleloader.h>
16504 #include <video/edid.h>
16505 #include <video/uvesafb.h>
16507 @@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
16511 - return call_usermodehelper(v86d_path, argv, envp, 1);
16512 + return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
16516 @@ -574,10 +575,34 @@ static int __devinit uvesafb_vbe_getpmi(
16517 if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
16518 par->pmi_setpal = par->ypan = 0;
16521 +#ifdef CONFIG_PAX_KERNEXEC
16522 +#ifdef CONFIG_MODULES
16523 + unsigned long cr0;
16525 + par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
16527 + if (!par->pmi_code) {
16528 + par->pmi_setpal = par->ypan = 0;
16533 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
16534 + task->t.regs.edi);
16536 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16537 + pax_open_kernel(cr0);
16538 + memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
16539 + pax_close_kernel(cr0);
16541 + par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
16542 + par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
16544 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
16545 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
16548 printk(KERN_INFO "uvesafb: protected mode interface info at "
16550 (u16)task->t.regs.es, (u16)task->t.regs.edi);
16551 @@ -1832,6 +1857,11 @@ out:
16552 if (par->vbe_modes)
16553 kfree(par->vbe_modes);
16555 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16556 + if (par->pmi_code)
16557 + module_free_exec(NULL, par->pmi_code);
16560 framebuffer_release(info);
16563 @@ -1858,6 +1888,12 @@ static int uvesafb_remove(struct platfor
16564 kfree(par->vbe_state_orig);
16565 if (par->vbe_state_saved)
16566 kfree(par->vbe_state_saved);
16568 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16569 + if (par->pmi_code)
16570 + module_free_exec(NULL, par->pmi_code);
16575 framebuffer_release(info);
16576 diff -urNp linux-2.6.29/drivers/video/vesafb.c linux-2.6.29/drivers/video/vesafb.c
16577 --- linux-2.6.29/drivers/video/vesafb.c 2009-03-23 19:12:14.000000000 -0400
16578 +++ linux-2.6.29/drivers/video/vesafb.c 2009-03-28 14:26:20.000000000 -0400
16582 #include <linux/module.h>
16583 +#include <linux/moduleloader.h>
16584 #include <linux/kernel.h>
16585 #include <linux/errno.h>
16586 #include <linux/string.h>
16587 @@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
16588 static int vram_total __initdata; /* Set total amount of memory */
16589 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
16590 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
16591 -static void (*pmi_start)(void) __read_mostly;
16592 -static void (*pmi_pal) (void) __read_mostly;
16593 +static void (*pmi_start)(void) __read_only;
16594 +static void (*pmi_pal) (void) __read_only;
16595 static int depth __read_mostly;
16596 static int vga_compat __read_mostly;
16597 /* --------------------------------------------------------------------- */
16598 @@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
16599 unsigned int size_vmode;
16600 unsigned int size_remap;
16601 unsigned int size_total;
16602 + void *pmi_code = NULL;
16604 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
16606 @@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
16607 size_remap = size_total;
16608 vesafb_fix.smem_len = size_remap;
16611 - screen_info.vesapm_seg = 0;
16614 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
16615 printk(KERN_WARNING
16616 "vesafb: cannot reserve video memory at 0x%lx\n",
16617 @@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
16618 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
16619 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
16623 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16624 + pmi_code = module_alloc_exec(screen_info.vesapm_size);
16626 +#elif !defined(CONFIG_PAX_KERNEXEC)
16631 + screen_info.vesapm_seg = 0;
16633 if (screen_info.vesapm_seg) {
16634 - printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
16635 - screen_info.vesapm_seg,screen_info.vesapm_off);
16636 + printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
16637 + screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
16640 if (screen_info.vesapm_seg < 0xc000)
16641 @@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
16643 if (ypan || pmi_setpal) {
16644 unsigned short *pmi_base;
16645 - pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
16646 - pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
16647 - pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
16649 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16650 + unsigned long cr0;
16653 + pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
16655 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16656 + pax_open_kernel(cr0);
16657 + memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
16659 + pmi_code = pmi_base;
16662 + pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
16663 + pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
16665 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16666 + pmi_start = ktva_ktla(pmi_start);
16667 + pmi_pal = ktva_ktla(pmi_pal);
16668 + pax_close_kernel(cr0);
16671 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
16673 printk(KERN_INFO "vesafb: pmi: ports = ");
16674 @@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
16675 info->node, info->fix.id);
16679 +#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16680 + module_free_exec(NULL, pmi_code);
16683 if (info->screen_base)
16684 iounmap(info->screen_base);
16685 framebuffer_release(info);
16686 diff -urNp linux-2.6.29/fs/9p/vfs_inode.c linux-2.6.29/fs/9p/vfs_inode.c
16687 --- linux-2.6.29/fs/9p/vfs_inode.c 2009-03-23 19:12:14.000000000 -0400
16688 +++ linux-2.6.29/fs/9p/vfs_inode.c 2009-03-28 14:26:20.000000000 -0400
16689 @@ -1021,7 +1021,7 @@ static void *v9fs_vfs_follow_link(struct
16691 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
16693 - char *s = nd_get_link(nd);
16694 + const char *s = nd_get_link(nd);
16696 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name,
16697 IS_ERR(s) ? "<error>" : s);
16698 diff -urNp linux-2.6.29/fs/aio.c linux-2.6.29/fs/aio.c
16699 --- linux-2.6.29/fs/aio.c 2009-03-23 19:12:14.000000000 -0400
16700 +++ linux-2.6.29/fs/aio.c 2009-03-28 14:26:20.000000000 -0400
16701 @@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
16702 size += sizeof(struct io_event) * nr_events;
16703 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
16705 - if (nr_pages < 0)
16706 + if (nr_pages <= 0)
16709 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
16710 diff -urNp linux-2.6.29/fs/autofs4/symlink.c linux-2.6.29/fs/autofs4/symlink.c
16711 --- linux-2.6.29/fs/autofs4/symlink.c 2009-03-23 19:12:14.000000000 -0400
16712 +++ linux-2.6.29/fs/autofs4/symlink.c 2009-03-28 14:26:20.000000000 -0400
16714 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
16716 struct autofs_info *ino = autofs4_dentry_ino(dentry);
16717 - nd_set_link(nd, (char *)ino->u.symlink);
16718 + nd_set_link(nd, ino->u.symlink);
16722 diff -urNp linux-2.6.29/fs/befs/linuxvfs.c linux-2.6.29/fs/befs/linuxvfs.c
16723 --- linux-2.6.29/fs/befs/linuxvfs.c 2009-03-23 19:12:14.000000000 -0400
16724 +++ linux-2.6.29/fs/befs/linuxvfs.c 2009-03-28 14:26:20.000000000 -0400
16725 @@ -493,7 +493,7 @@ static void befs_put_link(struct dentry
16727 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
16728 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
16729 - char *link = nd_get_link(nd);
16730 + const char *link = nd_get_link(nd);
16734 diff -urNp linux-2.6.29/fs/binfmt_aout.c linux-2.6.29/fs/binfmt_aout.c
16735 --- linux-2.6.29/fs/binfmt_aout.c 2009-03-23 19:12:14.000000000 -0400
16736 +++ linux-2.6.29/fs/binfmt_aout.c 2009-03-28 14:26:20.000000000 -0400
16738 #include <linux/string.h>
16739 #include <linux/fs.h>
16740 #include <linux/file.h>
16741 +#include <linux/security.h>
16742 #include <linux/stat.h>
16743 #include <linux/fcntl.h>
16744 #include <linux/ptrace.h>
16745 @@ -113,10 +114,12 @@ static int aout_core_dump(long signr, st
16747 /* If the size of the dump file exceeds the rlimit, then see what would happen
16748 if we wrote the stack, but not the data area. */
16749 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
16750 if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
16753 /* Make sure we have enough room to write the stack and data areas. */
16754 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
16755 if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
16758 @@ -249,6 +252,8 @@ static int load_aout_binary(struct linux
16759 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
16760 if (rlim >= RLIM_INFINITY)
16763 + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
16764 if (ex.a_data + ex.a_bss > rlim)
16767 @@ -276,6 +281,27 @@ static int load_aout_binary(struct linux
16768 install_exec_creds(bprm);
16769 current->flags &= ~PF_FORKNOEXEC;
16771 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16772 + current->mm->pax_flags = 0UL;
16775 +#ifdef CONFIG_PAX_PAGEEXEC
16776 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
16777 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
16779 +#ifdef CONFIG_PAX_EMUTRAMP
16780 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
16781 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
16784 +#ifdef CONFIG_PAX_MPROTECT
16785 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
16786 + current->mm->pax_flags |= MF_PAX_MPROTECT;
16792 if (N_MAGIC(ex) == OMAGIC) {
16793 unsigned long text_addr, map_size;
16795 @@ -348,7 +374,7 @@ static int load_aout_binary(struct linux
16797 down_write(¤t->mm->mmap_sem);
16798 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
16799 - PROT_READ | PROT_WRITE | PROT_EXEC,
16800 + PROT_READ | PROT_WRITE,
16801 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
16802 fd_offset + ex.a_text);
16803 up_write(¤t->mm->mmap_sem);
16804 diff -urNp linux-2.6.29/fs/binfmt_elf.c linux-2.6.29/fs/binfmt_elf.c
16805 --- linux-2.6.29/fs/binfmt_elf.c 2009-03-23 19:12:14.000000000 -0400
16806 +++ linux-2.6.29/fs/binfmt_elf.c 2009-03-28 14:26:20.000000000 -0400
16808 #include <asm/param.h>
16809 #include <asm/page.h>
16811 +#ifdef CONFIG_PAX_SEGMEXEC
16812 +#include <asm/desc.h>
16815 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
16816 static int load_elf_library(struct file *);
16817 static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
16818 @@ -57,6 +61,10 @@ static int elf_core_dump(long signr, str
16819 #define elf_core_dump NULL
16822 +#ifdef CONFIG_PAX_MPROTECT
16823 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags);
16826 #if ELF_EXEC_PAGESIZE > PAGE_SIZE
16827 #define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE
16829 @@ -76,6 +84,11 @@ static struct linux_binfmt elf_format =
16830 .load_binary = load_elf_binary,
16831 .load_shlib = load_elf_library,
16832 .core_dump = elf_core_dump,
16834 +#ifdef CONFIG_PAX_MPROTECT
16835 + .handle_mprotect= elf_handle_mprotect,
16838 .min_coredump = ELF_EXEC_PAGESIZE,
16841 @@ -84,6 +97,8 @@ static struct linux_binfmt elf_format =
16843 static int set_brk(unsigned long start, unsigned long end)
16845 + unsigned long e = end;
16847 start = ELF_PAGEALIGN(start);
16848 end = ELF_PAGEALIGN(end);
16850 @@ -94,7 +109,7 @@ static int set_brk(unsigned long start,
16851 if (BAD_ADDR(addr))
16854 - current->mm->start_brk = current->mm->brk = end;
16855 + current->mm->start_brk = current->mm->brk = e;
16859 @@ -392,10 +407,10 @@ static unsigned long load_elf_interp(str
16861 struct elf_phdr *elf_phdata;
16862 struct elf_phdr *eppnt;
16863 - unsigned long load_addr = 0;
16864 + unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
16865 int load_addr_set = 0;
16866 unsigned long last_bss = 0, elf_bss = 0;
16867 - unsigned long error = ~0UL;
16868 + unsigned long error = -EINVAL;
16869 unsigned long total_size;
16870 int retval, i, size;
16872 @@ -441,6 +456,11 @@ static unsigned long load_elf_interp(str
16876 +#ifdef CONFIG_PAX_SEGMEXEC
16877 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
16878 + pax_task_size = SEGMEXEC_TASK_SIZE;
16881 eppnt = elf_phdata;
16882 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
16883 if (eppnt->p_type == PT_LOAD) {
16884 @@ -484,8 +504,8 @@ static unsigned long load_elf_interp(str
16885 k = load_addr + eppnt->p_vaddr;
16887 eppnt->p_filesz > eppnt->p_memsz ||
16888 - eppnt->p_memsz > TASK_SIZE ||
16889 - TASK_SIZE - eppnt->p_memsz < k) {
16890 + eppnt->p_memsz > pax_task_size ||
16891 + pax_task_size - eppnt->p_memsz < k) {
16895 @@ -539,6 +559,177 @@ out:
16899 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
16900 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
16902 + unsigned long pax_flags = 0UL;
16904 +#ifdef CONFIG_PAX_PAGEEXEC
16905 + if (elf_phdata->p_flags & PF_PAGEEXEC)
16906 + pax_flags |= MF_PAX_PAGEEXEC;
16909 +#ifdef CONFIG_PAX_SEGMEXEC
16910 + if (elf_phdata->p_flags & PF_SEGMEXEC)
16911 + pax_flags |= MF_PAX_SEGMEXEC;
16914 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
16915 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16917 + pax_flags &= ~MF_PAX_SEGMEXEC;
16919 + pax_flags &= ~MF_PAX_PAGEEXEC;
16923 +#ifdef CONFIG_PAX_EMUTRAMP
16924 + if (elf_phdata->p_flags & PF_EMUTRAMP)
16925 + pax_flags |= MF_PAX_EMUTRAMP;
16928 +#ifdef CONFIG_PAX_MPROTECT
16929 + if (elf_phdata->p_flags & PF_MPROTECT)
16930 + pax_flags |= MF_PAX_MPROTECT;
16933 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
16934 + if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
16935 + pax_flags |= MF_PAX_RANDMMAP;
16938 + return pax_flags;
16942 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
16943 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
16945 + unsigned long pax_flags = 0UL;
16947 +#ifdef CONFIG_PAX_PAGEEXEC
16948 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
16949 + pax_flags |= MF_PAX_PAGEEXEC;
16952 +#ifdef CONFIG_PAX_SEGMEXEC
16953 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
16954 + pax_flags |= MF_PAX_SEGMEXEC;
16957 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
16958 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16960 + pax_flags &= ~MF_PAX_SEGMEXEC;
16962 + pax_flags &= ~MF_PAX_PAGEEXEC;
16966 +#ifdef CONFIG_PAX_EMUTRAMP
16967 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
16968 + pax_flags |= MF_PAX_EMUTRAMP;
16971 +#ifdef CONFIG_PAX_MPROTECT
16972 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
16973 + pax_flags |= MF_PAX_MPROTECT;
16976 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
16977 + if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
16978 + pax_flags |= MF_PAX_RANDMMAP;
16981 + return pax_flags;
16985 +#ifdef CONFIG_PAX_EI_PAX
16986 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
16988 + unsigned long pax_flags = 0UL;
16990 +#ifdef CONFIG_PAX_PAGEEXEC
16991 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
16992 + pax_flags |= MF_PAX_PAGEEXEC;
16995 +#ifdef CONFIG_PAX_SEGMEXEC
16996 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
16997 + pax_flags |= MF_PAX_SEGMEXEC;
17000 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
17001 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17003 + pax_flags &= ~MF_PAX_SEGMEXEC;
17005 + pax_flags &= ~MF_PAX_PAGEEXEC;
17009 +#ifdef CONFIG_PAX_EMUTRAMP
17010 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
17011 + pax_flags |= MF_PAX_EMUTRAMP;
17014 +#ifdef CONFIG_PAX_MPROTECT
17015 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
17016 + pax_flags |= MF_PAX_MPROTECT;
17019 +#ifdef CONFIG_PAX_ASLR
17020 + if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
17021 + pax_flags |= MF_PAX_RANDMMAP;
17024 + return pax_flags;
17028 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
17029 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
17031 + unsigned long pax_flags = 0UL;
17033 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
17037 +#ifdef CONFIG_PAX_EI_PAX
17038 + pax_flags = pax_parse_ei_pax(elf_ex);
17041 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
17042 + for (i = 0UL; i < elf_ex->e_phnum; i++)
17043 + if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
17044 + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
17045 + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
17046 + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
17047 + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
17048 + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
17051 +#ifdef CONFIG_PAX_SOFTMODE
17052 + if (pax_softmode)
17053 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
17057 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
17062 + if (0 > pax_check_flags(&pax_flags))
17065 + current->mm->pax_flags = pax_flags;
17071 * These are the functions used to load ELF style executables and shared
17072 * libraries. There is no binary dependent code anywhere else.
17073 @@ -555,6 +746,11 @@ static unsigned long randomize_stack_top
17075 unsigned int random_variable = 0;
17077 +#ifdef CONFIG_PAX_RANDUSTACK
17078 + if (randomize_va_space)
17079 + return stack_top - current->mm->delta_stack;
17082 if ((current->flags & PF_RANDOMIZE) &&
17083 !(current->personality & ADDR_NO_RANDOMIZE)) {
17084 random_variable = get_random_int() & STACK_RND_MASK;
17085 @@ -573,7 +769,7 @@ static int load_elf_binary(struct linux_
17086 unsigned long load_addr = 0, load_bias = 0;
17087 int load_addr_set = 0;
17088 char * elf_interpreter = NULL;
17089 - unsigned long error;
17090 + unsigned long error = 0;
17091 struct elf_phdr *elf_ppnt, *elf_phdata;
17092 unsigned long elf_bss, elf_brk;
17093 int elf_exec_fileno;
17094 @@ -584,11 +780,11 @@ static int load_elf_binary(struct linux_
17095 unsigned long start_code, end_code, start_data, end_data;
17096 unsigned long reloc_func_desc = 0;
17097 int executable_stack = EXSTACK_DEFAULT;
17098 - unsigned long def_flags = 0;
17100 struct elfhdr elf_ex;
17101 struct elfhdr interp_elf_ex;
17103 + unsigned long pax_task_size = TASK_SIZE;
17105 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
17107 @@ -756,11 +952,80 @@ static int load_elf_binary(struct linux_
17109 /* OK, This is the point of no return */
17110 current->flags &= ~PF_FORKNOEXEC;
17111 - current->mm->def_flags = def_flags;
17113 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
17114 + current->mm->pax_flags = 0UL;
17117 +#ifdef CONFIG_PAX_DLRESOLVE
17118 + current->mm->call_dl_resolve = 0UL;
17121 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
17122 + current->mm->call_syscall = 0UL;
17125 +#ifdef CONFIG_PAX_ASLR
17126 + current->mm->delta_mmap = 0UL;
17127 + current->mm->delta_stack = 0UL;
17130 + current->mm->def_flags = 0;
17132 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
17133 + if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
17134 + send_sig(SIGKILL, current, 0);
17135 + goto out_free_dentry;
17139 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
17140 + pax_set_initial_flags(bprm);
17141 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
17142 + if (pax_set_initial_flags_func)
17143 + (pax_set_initial_flags_func)(bprm);
17146 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
17147 + if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
17148 + current->mm->context.user_cs_limit = PAGE_SIZE;
17149 + current->mm->def_flags |= VM_PAGEEXEC;
17153 +#ifdef CONFIG_PAX_SEGMEXEC
17154 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
17155 + current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
17156 + current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
17157 + pax_task_size = SEGMEXEC_TASK_SIZE;
17161 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
17162 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17163 + set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
17164 + put_cpu_no_resched();
17168 +#ifdef CONFIG_PAX_ASLR
17169 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
17170 + current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
17171 + current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
17175 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
17176 may depend on the personality. */
17177 SET_PERSONALITY(loc->elf_ex);
17179 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17180 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17181 + executable_stack = EXSTACK_DISABLE_X;
17182 + current->personality &= ~READ_IMPLIES_EXEC;
17186 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
17187 current->personality |= READ_IMPLIES_EXEC;
17189 @@ -841,6 +1106,20 @@ static int load_elf_binary(struct linux_
17191 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
17194 +#ifdef CONFIG_PAX_RANDMMAP
17195 + /* PaX: randomize base address at the default exe base if requested */
17196 + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
17197 +#ifdef CONFIG_SPARC64
17198 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
17200 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
17202 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
17203 + elf_flags |= MAP_FIXED;
17209 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
17210 @@ -873,9 +1152,9 @@ static int load_elf_binary(struct linux_
17211 * allowed task size. Note that p_filesz must always be
17212 * <= p_memsz so it is only necessary to check p_memsz.
17214 - if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
17215 - elf_ppnt->p_memsz > TASK_SIZE ||
17216 - TASK_SIZE - elf_ppnt->p_memsz < k) {
17217 + if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
17218 + elf_ppnt->p_memsz > pax_task_size ||
17219 + pax_task_size - elf_ppnt->p_memsz < k) {
17220 /* set_brk can never work. Avoid overflows. */
17221 send_sig(SIGKILL, current, 0);
17223 @@ -903,6 +1182,11 @@ static int load_elf_binary(struct linux_
17224 start_data += load_bias;
17225 end_data += load_bias;
17227 +#ifdef CONFIG_PAX_RANDMMAP
17228 + if (current->mm->pax_flags & MF_PAX_RANDMMAP)
17229 + elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
17232 /* Calling set_brk effectively mmaps the pages that we need
17233 * for the bss and break sections. We must do this before
17234 * mapping in the interpreter, to make sure it doesn't wind
17235 @@ -914,9 +1198,11 @@ static int load_elf_binary(struct linux_
17236 goto out_free_dentry;
17238 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
17239 - send_sig(SIGSEGV, current, 0);
17240 - retval = -EFAULT; /* Nobody gets to see this, but.. */
17241 - goto out_free_dentry;
17243 + * This bss-zeroing can fail if the ELF
17244 + * file specifies odd protections. So
17245 + * we don't check the return value
17249 if (elf_interpreter) {
17250 @@ -1153,8 +1439,10 @@ static int dump_seek(struct file *file,
17251 unsigned long n = off;
17254 - if (!dump_write(file, buf, n))
17255 + if (!dump_write(file, buf, n)) {
17256 + free_page((unsigned long)buf);
17261 free_page((unsigned long)buf);
17262 @@ -1166,7 +1454,7 @@ static int dump_seek(struct file *file,
17263 * Decide what to dump of a segment, part, all or none.
17265 static unsigned long vma_dump_size(struct vm_area_struct *vma,
17266 - unsigned long mm_flags)
17267 + unsigned long mm_flags, long signr)
17269 #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
17271 @@ -1200,7 +1488,7 @@ static unsigned long vma_dump_size(struc
17272 if (vma->vm_file == NULL)
17275 - if (FILTER(MAPPED_PRIVATE))
17276 + if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
17280 @@ -1296,8 +1584,11 @@ static int writenote(struct memelfnote *
17283 #define DUMP_WRITE(addr, nr) \
17285 + gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
17286 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
17287 - goto end_coredump;
17288 + goto end_coredump; \
17290 #define DUMP_SEEK(off) \
17291 if (!dump_seek(file, (off))) \
17293 @@ -2002,7 +2293,7 @@ static int elf_core_dump(long signr, str
17294 phdr.p_offset = offset;
17295 phdr.p_vaddr = vma->vm_start;
17297 - phdr.p_filesz = vma_dump_size(vma, mm_flags);
17298 + phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
17299 phdr.p_memsz = vma->vm_end - vma->vm_start;
17300 offset += phdr.p_filesz;
17301 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
17302 @@ -2034,7 +2325,7 @@ static int elf_core_dump(long signr, str
17303 unsigned long addr;
17306 - end = vma->vm_start + vma_dump_size(vma, mm_flags);
17307 + end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
17309 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
17311 @@ -2054,6 +2345,7 @@ static int elf_core_dump(long signr, str
17312 flush_cache_page(tmp_vma, addr,
17313 page_to_pfn(page));
17314 kaddr = kmap(page);
17315 + gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
17316 if ((size += PAGE_SIZE) > limit ||
17317 !dump_write(file, kaddr,
17319 @@ -2084,6 +2376,99 @@ out:
17321 #endif /* USE_ELF_CORE_DUMP */
17323 +#ifdef CONFIG_PAX_MPROTECT
17324 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
17325 + * therefore we'll grant them VM_MAYWRITE once during their life. Similarly
17326 + * we'll remove VM_MAYWRITE for good on RELRO segments.
17328 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
17329 + * basis because we want to allow the common case and not the special ones.
17331 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags)
17333 + struct elfhdr elf_h;
17334 + struct elf_phdr elf_p;
17336 + unsigned long oldflags;
17337 + bool is_textrel_rw, is_textrel_rx, is_relro;
17339 + if (!(vma->vm_mm->pax_flags & MF_PAX_MPROTECT))
17342 + oldflags = vma->vm_flags & (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ);
17343 + newflags &= VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ;
17345 +#ifdef CONFIG_PAX_NOELFRELOCS
17346 + is_textrel_rw = false;
17347 + is_textrel_rx = false;
17349 + /* possible TEXTREL */
17350 + is_textrel_rw = vma->vm_file && !vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYREAD | VM_EXEC | VM_READ) && newflags == (VM_WRITE | VM_READ);
17351 + is_textrel_rx = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_WRITE | VM_READ) && newflags == (VM_EXEC | VM_READ);
17354 + /* possible RELRO */
17355 + is_relro = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ) && newflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ);
17357 + if (!is_textrel_rw && !is_textrel_rx && !is_relro)
17360 + if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
17361 + memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
17363 +#ifdef CONFIG_PAX_ETEXECRELOCS
17364 + ((is_textrel_rw || is_textrel_rx) && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
17366 + ((is_textrel_rw || is_textrel_rx) && elf_h.e_type != ET_DYN) ||
17369 + (is_relro && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
17370 + !elf_check_arch(&elf_h) ||
17371 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
17372 + elf_h.e_phnum > 65536UL / sizeof(struct elf_phdr))
17375 + for (i = 0UL; i < elf_h.e_phnum; i++) {
17376 + if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
17378 + switch (elf_p.p_type) {
17379 + case PT_DYNAMIC: {
17380 + elf_addr_t dyn_offset = 0UL;
17383 + if (!is_textrel_rw && !is_textrel_rx)
17385 + dyn_offset = elf_p.p_offset;
17388 + if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
17390 + if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
17391 + gr_log_textrel(vma);
17392 + if (is_textrel_rw)
17393 + vma->vm_flags |= VM_MAYWRITE;
17395 + /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
17396 + vma->vm_flags &= ~VM_MAYWRITE;
17400 + } while (dyn.d_tag != DT_NULL);
17404 + case PT_GNU_RELRO:
17407 + if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start) {
17408 + vma->vm_flags &= ~VM_MAYWRITE;
17416 static int __init init_elf_binfmt(void)
17418 return register_binfmt(&elf_format);
17419 diff -urNp linux-2.6.29/fs/binfmt_flat.c linux-2.6.29/fs/binfmt_flat.c
17420 --- linux-2.6.29/fs/binfmt_flat.c 2009-03-23 19:12:14.000000000 -0400
17421 +++ linux-2.6.29/fs/binfmt_flat.c 2009-03-28 14:26:20.000000000 -0400
17422 @@ -554,7 +554,9 @@ static int load_flat_file(struct linux_b
17423 realdatastart = (unsigned long) -ENOMEM;
17424 printk("Unable to allocate RAM for process data, errno %d\n",
17425 (int)-realdatastart);
17426 + down_write(¤t->mm->mmap_sem);
17427 do_munmap(current->mm, textpos, text_len);
17428 + up_write(¤t->mm->mmap_sem);
17429 ret = realdatastart;
17432 @@ -576,8 +578,10 @@ static int load_flat_file(struct linux_b
17434 if (result >= (unsigned long)-4096) {
17435 printk("Unable to read data+bss, errno %d\n", (int)-result);
17436 + down_write(¤t->mm->mmap_sem);
17437 do_munmap(current->mm, textpos, text_len);
17438 do_munmap(current->mm, realdatastart, data_len + extra);
17439 + up_write(¤t->mm->mmap_sem);
17443 @@ -643,8 +647,10 @@ static int load_flat_file(struct linux_b
17445 if (result >= (unsigned long)-4096) {
17446 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
17447 + down_write(¤t->mm->mmap_sem);
17448 do_munmap(current->mm, textpos, text_len + data_len + extra +
17449 MAX_SHARED_LIBS * sizeof(unsigned long));
17450 + up_write(¤t->mm->mmap_sem);
17454 diff -urNp linux-2.6.29/fs/binfmt_misc.c linux-2.6.29/fs/binfmt_misc.c
17455 --- linux-2.6.29/fs/binfmt_misc.c 2009-03-23 19:12:14.000000000 -0400
17456 +++ linux-2.6.29/fs/binfmt_misc.c 2009-03-28 14:26:20.000000000 -0400
17457 @@ -693,7 +693,7 @@ static int bm_fill_super(struct super_bl
17458 static struct tree_descr bm_files[] = {
17459 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
17460 [3] = {"register", &bm_register_operations, S_IWUSR},
17461 - /* last one */ {""}
17462 + /* last one */ {"", NULL, 0}
17464 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
17466 diff -urNp linux-2.6.29/fs/bio.c linux-2.6.29/fs/bio.c
17467 --- linux-2.6.29/fs/bio.c 2009-03-23 19:12:14.000000000 -0400
17468 +++ linux-2.6.29/fs/bio.c 2009-03-28 14:26:20.000000000 -0400
17469 @@ -710,7 +710,7 @@ static int __bio_copy_iov(struct bio *bi
17471 while (bv_len && iov_idx < iov_count) {
17472 unsigned int bytes;
17474 + char __user *iov_addr;
17476 bytes = min_t(unsigned int,
17477 iov[iov_idx].iov_len - iov_off, bv_len);
17478 diff -urNp linux-2.6.29/fs/buffer.c linux-2.6.29/fs/buffer.c
17479 --- linux-2.6.29/fs/buffer.c 2009-03-23 19:12:14.000000000 -0400
17480 +++ linux-2.6.29/fs/buffer.c 2009-03-28 14:26:20.000000000 -0400
17482 #include <linux/percpu.h>
17483 #include <linux/slab.h>
17484 #include <linux/capability.h>
17485 +#include <linux/security.h>
17486 #include <linux/blkdev.h>
17487 #include <linux/file.h>
17488 #include <linux/quotaops.h>
17489 @@ -2312,6 +2313,7 @@ int generic_cont_expand_simple(struct in
17492 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
17493 + gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
17494 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
17495 send_sig(SIGXFSZ, current, 0);
17497 diff -urNp linux-2.6.29/fs/cifs/cifs_uniupr.h linux-2.6.29/fs/cifs/cifs_uniupr.h
17498 --- linux-2.6.29/fs/cifs/cifs_uniupr.h 2009-03-23 19:12:14.000000000 -0400
17499 +++ linux-2.6.29/fs/cifs/cifs_uniupr.h 2009-03-28 14:26:20.000000000 -0400
17500 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
17501 {0x0490, 0x04cc, UniCaseRangeU0490},
17502 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
17503 {0xff40, 0xff5a, UniCaseRangeUff40},
17509 diff -urNp linux-2.6.29/fs/cifs/link.c linux-2.6.29/fs/cifs/link.c
17510 --- linux-2.6.29/fs/cifs/link.c 2009-03-23 19:12:14.000000000 -0400
17511 +++ linux-2.6.29/fs/cifs/link.c 2009-03-28 14:26:20.000000000 -0400
17512 @@ -318,7 +318,7 @@ cifs_readlink(struct dentry *direntry, c
17514 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
17516 - char *p = nd_get_link(nd);
17517 + const char *p = nd_get_link(nd);
17521 diff -urNp linux-2.6.29/fs/compat.c linux-2.6.29/fs/compat.c
17522 --- linux-2.6.29/fs/compat.c 2009-03-23 19:12:14.000000000 -0400
17523 +++ linux-2.6.29/fs/compat.c 2009-03-28 15:22:21.000000000 -0400
17524 @@ -1337,14 +1337,12 @@ static int compat_copy_strings(int argc,
17525 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
17528 -#ifdef CONFIG_STACK_GROWSUP
17529 ret = expand_stack_downwards(bprm->vma, pos);
17531 /* We've exceed the stack rlimit. */
17536 ret = get_user_pages(current, bprm->mm, pos,
17537 1, 1, 1, &page, NULL);
17539 @@ -1390,6 +1388,11 @@ int compat_do_execve(char * filename,
17540 compat_uptr_t __user *envp,
17541 struct pt_regs * regs)
17543 +#ifdef CONFIG_GRKERNSEC
17544 + struct file *old_exec_file;
17545 + struct acl_subject_label *old_acl;
17546 + struct rlimit old_rlim[RLIM_NLIMITS];
17548 struct linux_binprm *bprm;
17551 @@ -1420,6 +1423,14 @@ int compat_do_execve(char * filename,
17552 bprm->filename = filename;
17553 bprm->interp = filename;
17555 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->cred->user->processes), 1);
17556 + retval = -EAGAIN;
17557 + if (gr_handle_nproc())
17559 + retval = -EACCES;
17560 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
17563 retval = bprm_mm_init(bprm);
17566 @@ -1449,9 +1460,39 @@ int compat_do_execve(char * filename,
17570 + if (!gr_tpe_allow(file)) {
17571 + retval = -EACCES;
17575 + if (gr_check_crash_exec(file)) {
17576 + retval = -EACCES;
17580 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
17582 + gr_handle_exec_args(bprm, (char __user * __user *)argv);
17584 +#ifdef CONFIG_GRKERNSEC
17585 + old_acl = current->acl;
17586 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
17587 + old_exec_file = current->exec_file;
17589 + current->exec_file = file;
17592 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
17596 retval = search_binary_handler(bprm, regs);
17600 +#ifdef CONFIG_GRKERNSEC
17601 + if (old_exec_file)
17602 + fput(old_exec_file);
17605 /* execve succeeded */
17606 mutex_unlock(¤t->cred_exec_mutex);
17607 @@ -1459,6 +1500,14 @@ int compat_do_execve(char * filename,
17612 +#ifdef CONFIG_GRKERNSEC
17613 + current->acl = old_acl;
17614 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
17615 + fput(current->exec_file);
17616 + current->exec_file = old_exec_file;
17622 diff -urNp linux-2.6.29/fs/compat_ioctl.c linux-2.6.29/fs/compat_ioctl.c
17623 --- linux-2.6.29/fs/compat_ioctl.c 2009-03-23 19:12:14.000000000 -0400
17624 +++ linux-2.6.29/fs/compat_ioctl.c 2009-03-28 14:26:20.000000000 -0400
17625 @@ -1832,15 +1832,15 @@ struct ioctl_trans {
17628 #define HANDLE_IOCTL(cmd,handler) \
17629 - { (cmd), (ioctl_trans_handler_t)(handler) },
17630 + { (cmd), (ioctl_trans_handler_t)(handler), NULL },
17632 /* pointer to compatible structure or no argument */
17633 #define COMPATIBLE_IOCTL(cmd) \
17634 - { (cmd), do_ioctl32_pointer },
17635 + { (cmd), do_ioctl32_pointer, NULL },
17637 /* argument is an unsigned long integer, not a pointer */
17638 #define ULONG_IOCTL(cmd) \
17639 - { (cmd), (ioctl_trans_handler_t)sys_ioctl },
17640 + { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
17642 /* ioctl should not be warned about even if it's not implemented.
17643 Valid reasons to use this:
17644 diff -urNp linux-2.6.29/fs/debugfs/inode.c linux-2.6.29/fs/debugfs/inode.c
17645 --- linux-2.6.29/fs/debugfs/inode.c 2009-03-23 19:12:14.000000000 -0400
17646 +++ linux-2.6.29/fs/debugfs/inode.c 2009-03-28 14:26:20.000000000 -0400
17647 @@ -117,7 +117,7 @@ static inline int debugfs_positive(struc
17649 static int debug_fill_super(struct super_block *sb, void *data, int silent)
17651 - static struct tree_descr debug_files[] = {{""}};
17652 + static struct tree_descr debug_files[] = {{"", NULL, 0}};
17654 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
17656 diff -urNp linux-2.6.29/fs/exec.c linux-2.6.29/fs/exec.c
17657 --- linux-2.6.29/fs/exec.c 2009-03-23 19:12:14.000000000 -0400
17658 +++ linux-2.6.29/fs/exec.c 2009-03-28 14:26:20.000000000 -0400
17659 @@ -52,12 +52,24 @@
17660 #include <linux/tracehook.h>
17661 #include <linux/kmod.h>
17662 #include <linux/fsnotify.h>
17663 +#include <linux/random.h>
17664 +#include <linux/seq_file.h>
17666 +#ifdef CONFIG_PAX_REFCOUNT
17667 +#include <linux/kallsyms.h>
17668 +#include <linux/kdebug.h>
17671 #include <asm/uaccess.h>
17672 #include <asm/mmu_context.h>
17673 #include <asm/tlb.h>
17674 #include "internal.h"
17676 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
17677 +void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
17678 +EXPORT_SYMBOL(pax_set_initial_flags_func);
17682 char core_pattern[CORENAME_MAX_SIZE] = "core";
17683 int suid_dumpable = 0;
17684 @@ -169,18 +181,10 @@ static struct page *get_arg_page(struct
17690 -#ifdef CONFIG_STACK_GROWSUP
17692 - ret = expand_stack_downwards(bprm->vma, pos);
17697 - ret = get_user_pages(current, bprm->mm, pos,
17698 - 1, write, 1, &page, NULL);
17700 + if (0 > expand_stack_downwards(bprm->vma, pos))
17702 + if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
17706 @@ -252,6 +256,11 @@ static int __bprm_mm_init(struct linux_b
17707 vma->vm_end = STACK_TOP_MAX;
17708 vma->vm_start = vma->vm_end - PAGE_SIZE;
17709 vma->vm_flags = VM_STACK_FLAGS;
17711 +#ifdef CONFIG_PAX_SEGMEXEC
17712 + vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
17715 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
17716 err = insert_vm_struct(mm, vma);
17718 @@ -260,6 +269,12 @@ static int __bprm_mm_init(struct linux_b
17719 mm->stack_vm = mm->total_vm = 1;
17720 up_write(&mm->mmap_sem);
17721 bprm->p = vma->vm_end - sizeof(void *);
17723 +#ifdef CONFIG_PAX_RANDUSTACK
17724 + if (randomize_va_space)
17725 + bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
17730 up_write(&mm->mmap_sem);
17731 @@ -520,6 +535,10 @@ static int shift_arg_pages(struct vm_are
17732 if (vma != find_vma(mm, new_start))
17735 +#ifdef CONFIG_PAX_SEGMEXEC
17736 + BUG_ON(pax_find_mirror_vma(vma));
17740 * cover the whole range: [new_start, old_end)
17742 @@ -608,6 +627,14 @@ int setup_arg_pages(struct linux_binprm
17743 bprm->exec -= stack_shift;
17745 down_write(&mm->mmap_sem);
17747 + /* Move stack pages down in memory. */
17748 + if (stack_shift) {
17749 + ret = shift_arg_pages(vma, stack_shift);
17754 vm_flags = VM_STACK_FLAGS;
17757 @@ -621,21 +648,24 @@ int setup_arg_pages(struct linux_binprm
17758 vm_flags &= ~VM_EXEC;
17759 vm_flags |= mm->def_flags;
17761 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17762 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17763 + vm_flags &= ~VM_EXEC;
17765 +#ifdef CONFIG_PAX_MPROTECT
17766 + if (mm->pax_flags & MF_PAX_MPROTECT)
17767 + vm_flags &= ~VM_MAYEXEC;
17773 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
17777 BUG_ON(prev != vma);
17779 - /* Move stack pages down in memory. */
17780 - if (stack_shift) {
17781 - ret = shift_arg_pages(vma, stack_shift);
17783 - up_write(&mm->mmap_sem);
17788 #ifdef CONFIG_STACK_GROWSUP
17789 stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
17791 @@ -647,7 +677,7 @@ int setup_arg_pages(struct linux_binprm
17794 up_write(&mm->mmap_sem);
17798 EXPORT_SYMBOL(setup_arg_pages);
17800 @@ -1267,6 +1297,11 @@ int do_execve(char * filename,
17801 char __user *__user *envp,
17802 struct pt_regs * regs)
17804 +#ifdef CONFIG_GRKERNSEC
17805 + struct file *old_exec_file;
17806 + struct acl_subject_label *old_acl;
17807 + struct rlimit old_rlim[RLIM_NLIMITS];
17809 struct linux_binprm *bprm;
17811 struct files_struct *displaced;
17812 @@ -1296,6 +1331,20 @@ int do_execve(char * filename,
17816 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->cred->user->processes), 1);
17818 + if (gr_handle_nproc()) {
17819 + allow_write_access(file);
17824 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
17825 + allow_write_access(file);
17833 @@ -1331,10 +1380,40 @@ int do_execve(char * filename,
17837 + if (!gr_tpe_allow(file)) {
17838 + retval = -EACCES;
17842 + if (gr_check_crash_exec(file)) {
17843 + retval = -EACCES;
17847 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
17849 + gr_handle_exec_args(bprm, argv);
17851 +#ifdef CONFIG_GRKERNSEC
17852 + old_acl = current->acl;
17853 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
17854 + old_exec_file = current->exec_file;
17856 + current->exec_file = file;
17859 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
17863 current->flags &= ~PF_KTHREAD;
17864 retval = search_binary_handler(bprm,regs);
17868 +#ifdef CONFIG_GRKERNSEC
17869 + if (old_exec_file)
17870 + fput(old_exec_file);
17873 /* execve succeeded */
17874 mutex_unlock(¤t->cred_exec_mutex);
17875 @@ -1344,6 +1423,14 @@ int do_execve(char * filename,
17876 put_files_struct(displaced);
17880 +#ifdef CONFIG_GRKERNSEC
17881 + current->acl = old_acl;
17882 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
17883 + fput(current->exec_file);
17884 + current->exec_file = old_exec_file;
17890 @@ -1507,6 +1594,137 @@ out:
17894 +int pax_check_flags(unsigned long *flags)
17898 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
17899 + if (*flags & MF_PAX_SEGMEXEC)
17901 + *flags &= ~MF_PAX_SEGMEXEC;
17902 + retval = -EINVAL;
17906 + if ((*flags & MF_PAX_PAGEEXEC)
17908 +#ifdef CONFIG_PAX_PAGEEXEC
17909 + && (*flags & MF_PAX_SEGMEXEC)
17914 + *flags &= ~MF_PAX_PAGEEXEC;
17915 + retval = -EINVAL;
17918 + if ((*flags & MF_PAX_MPROTECT)
17920 +#ifdef CONFIG_PAX_MPROTECT
17921 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
17926 + *flags &= ~MF_PAX_MPROTECT;
17927 + retval = -EINVAL;
17930 + if ((*flags & MF_PAX_EMUTRAMP)
17932 +#ifdef CONFIG_PAX_EMUTRAMP
17933 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
17938 + *flags &= ~MF_PAX_EMUTRAMP;
17939 + retval = -EINVAL;
17945 +EXPORT_SYMBOL(pax_check_flags);
17947 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17948 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
17950 + struct task_struct *tsk = current;
17951 + struct mm_struct *mm = current->mm;
17952 + char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
17953 + char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
17954 + char *path_exec = NULL;
17955 + char *path_fault = NULL;
17956 + unsigned long start = 0UL, end = 0UL, offset = 0UL;
17958 + if (buffer_exec && buffer_fault) {
17959 + struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
17961 + down_read(&mm->mmap_sem);
17963 + while (vma && (!vma_exec || !vma_fault)) {
17964 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
17966 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
17968 + vma = vma->vm_next;
17971 + path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
17972 + if (IS_ERR(path_exec))
17973 + path_exec = "<path too long>";
17975 + mangle_path(buffer_exec, path_exec, "\t\n\\");
17976 + path_exec = buffer_exec;
17980 + start = vma_fault->vm_start;
17981 + end = vma_fault->vm_end;
17982 + offset = vma_fault->vm_pgoff << PAGE_SHIFT;
17983 + if (vma_fault->vm_file) {
17984 + path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
17985 + if (IS_ERR(path_fault))
17986 + path_fault = "<path too long>";
17988 + mangle_path(buffer_fault, path_fault, "\t\n\\");
17989 + path_fault = buffer_fault;
17992 + path_fault = "<anonymous mapping>";
17994 + up_read(&mm->mmap_sem);
17996 + if (tsk->signal->curr_ip)
17997 + 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);
17999 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
18000 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
18001 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
18002 + task_uid(tsk), task_euid(tsk), pc, sp);
18003 + free_page((unsigned long)buffer_exec);
18004 + free_page((unsigned long)buffer_fault);
18005 + pax_report_insns(pc, sp);
18006 + do_coredump(SIGKILL, SIGKILL, regs);
18010 +#ifdef CONFIG_PAX_REFCOUNT
18011 +void pax_report_refcount_overflow(struct pt_regs *regs)
18013 + if (current->signal->curr_ip)
18014 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
18015 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current_uid(), current_euid());
18017 + printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
18018 + current->comm, task_pid_nr(current), current_uid(), current_euid());
18019 + print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
18020 + show_registers(regs);
18021 + force_sig_specific(SIGKILL, current);
18025 static int zap_process(struct task_struct *start)
18027 struct task_struct *t;
18028 @@ -1766,6 +1984,10 @@ void do_coredump(long signr, int exit_co
18030 clear_thread_flag(TIF_SIGPENDING);
18032 + if (signr == SIGKILL || signr == SIGILL)
18033 + gr_handle_brute_attach(current);
18034 + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
18037 * lock_kernel() because format_corename() is controlled by sysctl, which
18038 * uses lock_kernel()
18039 diff -urNp linux-2.6.29/fs/ext2/balloc.c linux-2.6.29/fs/ext2/balloc.c
18040 --- linux-2.6.29/fs/ext2/balloc.c 2009-03-23 19:12:14.000000000 -0400
18041 +++ linux-2.6.29/fs/ext2/balloc.c 2009-03-28 14:26:20.000000000 -0400
18042 @@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
18044 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
18045 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
18046 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
18047 + if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
18048 sbi->s_resuid != current_fsuid() &&
18049 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
18051 diff -urNp linux-2.6.29/fs/ext3/balloc.c linux-2.6.29/fs/ext3/balloc.c
18052 --- linux-2.6.29/fs/ext3/balloc.c 2009-03-23 19:12:14.000000000 -0400
18053 +++ linux-2.6.29/fs/ext3/balloc.c 2009-03-28 14:26:20.000000000 -0400
18054 @@ -1435,7 +1435,7 @@ static int ext3_has_free_blocks(struct s
18055 DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
18057 cond = (free_blocks < root_blocks + 1 &&
18058 - !capable(CAP_SYS_RESOURCE) &&
18059 + !capable_nolog(CAP_SYS_RESOURCE) &&
18060 sbi->s_resuid != current_fsuid() &&
18061 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
18063 diff -urNp linux-2.6.29/fs/ext3/namei.c linux-2.6.29/fs/ext3/namei.c
18064 --- linux-2.6.29/fs/ext3/namei.c 2009-03-23 19:12:14.000000000 -0400
18065 +++ linux-2.6.29/fs/ext3/namei.c 2009-03-28 14:26:20.000000000 -0400
18066 @@ -1159,7 +1159,7 @@ static struct ext3_dir_entry_2 *do_split
18067 char *data1 = (*bh)->b_data, *data2;
18068 unsigned split, move, size;
18069 struct ext3_dir_entry_2 *de = NULL, *de2;
18073 bh2 = ext3_append (handle, dir, &newblock, &err);
18075 diff -urNp linux-2.6.29/fs/ext3/xattr.c linux-2.6.29/fs/ext3/xattr.c
18076 --- linux-2.6.29/fs/ext3/xattr.c 2009-03-23 19:12:14.000000000 -0400
18077 +++ linux-2.6.29/fs/ext3/xattr.c 2009-03-28 14:26:20.000000000 -0400
18082 -# define ea_idebug(f...)
18083 -# define ea_bdebug(f...)
18084 +# define ea_idebug(f...) do {} while (0)
18085 +# define ea_bdebug(f...) do {} while (0)
18088 static void ext3_xattr_cache_insert(struct buffer_head *);
18089 diff -urNp linux-2.6.29/fs/ext4/balloc.c linux-2.6.29/fs/ext4/balloc.c
18090 --- linux-2.6.29/fs/ext4/balloc.c 2009-03-23 19:12:14.000000000 -0400
18091 +++ linux-2.6.29/fs/ext4/balloc.c 2009-03-28 14:26:20.000000000 -0400
18092 @@ -577,7 +577,7 @@ int ext4_has_free_blocks(struct ext4_sb_
18093 /* Hm, nope. Are (enough) root reserved blocks available? */
18094 if (sbi->s_resuid == current_fsuid() ||
18095 ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
18096 - capable(CAP_SYS_RESOURCE)) {
18097 + capable_nolog(CAP_SYS_RESOURCE)) {
18098 if (free_blocks >= (nblocks + dirty_blocks))
18101 diff -urNp linux-2.6.29/fs/ext4/namei.c linux-2.6.29/fs/ext4/namei.c
18102 --- linux-2.6.29/fs/ext4/namei.c 2009-03-23 19:12:14.000000000 -0400
18103 +++ linux-2.6.29/fs/ext4/namei.c 2009-03-28 14:26:20.000000000 -0400
18104 @@ -1169,7 +1169,7 @@ static struct ext4_dir_entry_2 *do_split
18105 char *data1 = (*bh)->b_data, *data2;
18106 unsigned split, move, size;
18107 struct ext4_dir_entry_2 *de = NULL, *de2;
18111 bh2 = ext4_append (handle, dir, &newblock, &err);
18113 diff -urNp linux-2.6.29/fs/fcntl.c linux-2.6.29/fs/fcntl.c
18114 --- linux-2.6.29/fs/fcntl.c 2009-03-23 19:12:14.000000000 -0400
18115 +++ linux-2.6.29/fs/fcntl.c 2009-03-28 14:26:20.000000000 -0400
18116 @@ -267,6 +267,7 @@ static long do_fcntl(int fd, unsigned in
18119 case F_DUPFD_CLOEXEC:
18120 + gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
18121 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
18123 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
18124 @@ -417,7 +418,8 @@ static inline int sigio_perm(struct task
18125 ret = ((fown->euid == 0 ||
18126 fown->euid == cred->suid || fown->euid == cred->uid ||
18127 fown->uid == cred->suid || fown->uid == cred->uid) &&
18128 - !security_file_send_sigiotask(p, fown, sig));
18129 + !security_file_send_sigiotask(p, fown, sig) &&
18130 + !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
18134 diff -urNp linux-2.6.29/fs/file.c linux-2.6.29/fs/file.c
18135 --- linux-2.6.29/fs/file.c 2009-03-23 19:12:14.000000000 -0400
18136 +++ linux-2.6.29/fs/file.c 2009-03-28 14:26:20.000000000 -0400
18138 #include <linux/slab.h>
18139 #include <linux/vmalloc.h>
18140 #include <linux/file.h>
18141 +#include <linux/security.h>
18142 #include <linux/fdtable.h>
18143 #include <linux/bitops.h>
18144 #include <linux/interrupt.h>
18145 @@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi
18146 * N.B. For clone tasks sharing a files structure, this test
18147 * will limit the total number of files that can be opened.
18150 + gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
18151 if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
18154 diff -urNp linux-2.6.29/fs/fuse/control.c linux-2.6.29/fs/fuse/control.c
18155 --- linux-2.6.29/fs/fuse/control.c 2009-03-23 19:12:14.000000000 -0400
18156 +++ linux-2.6.29/fs/fuse/control.c 2009-03-28 14:26:20.000000000 -0400
18157 @@ -161,7 +161,7 @@ void fuse_ctl_remove_conn(struct fuse_co
18159 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
18161 - struct tree_descr empty_descr = {""};
18162 + struct tree_descr empty_descr = {"", NULL, 0};
18163 struct fuse_conn *fc;
18166 diff -urNp linux-2.6.29/fs/fuse/dir.c linux-2.6.29/fs/fuse/dir.c
18167 --- linux-2.6.29/fs/fuse/dir.c 2009-03-23 19:12:14.000000000 -0400
18168 +++ linux-2.6.29/fs/fuse/dir.c 2009-03-28 14:26:20.000000000 -0400
18169 @@ -1081,7 +1081,7 @@ static char *read_link(struct dentry *de
18173 -static void free_link(char *link)
18174 +static void free_link(const char *link)
18177 free_page((unsigned long) link);
18178 diff -urNp linux-2.6.29/fs/hfs/inode.c linux-2.6.29/fs/hfs/inode.c
18179 --- linux-2.6.29/fs/hfs/inode.c 2009-03-23 19:12:14.000000000 -0400
18180 +++ linux-2.6.29/fs/hfs/inode.c 2009-03-28 14:26:20.000000000 -0400
18181 @@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
18183 if (S_ISDIR(main_inode->i_mode)) {
18184 if (fd.entrylength < sizeof(struct hfs_cat_dir))
18187 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
18188 sizeof(struct hfs_cat_dir));
18189 if (rec.type != HFS_CDR_DIR ||
18190 @@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
18191 sizeof(struct hfs_cat_file));
18193 if (fd.entrylength < sizeof(struct hfs_cat_file))
18196 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
18197 sizeof(struct hfs_cat_file));
18198 if (rec.type != HFS_CDR_FIL ||
18199 diff -urNp linux-2.6.29/fs/hfsplus/inode.c linux-2.6.29/fs/hfsplus/inode.c
18200 --- linux-2.6.29/fs/hfsplus/inode.c 2009-03-23 19:12:14.000000000 -0400
18201 +++ linux-2.6.29/fs/hfsplus/inode.c 2009-03-28 14:26:20.000000000 -0400
18202 @@ -406,7 +406,7 @@ int hfsplus_cat_read_inode(struct inode
18203 struct hfsplus_cat_folder *folder = &entry.folder;
18205 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
18208 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
18209 sizeof(struct hfsplus_cat_folder));
18210 hfsplus_get_perms(inode, &folder->permissions, 1);
18211 @@ -423,7 +423,7 @@ int hfsplus_cat_read_inode(struct inode
18212 struct hfsplus_cat_file *file = &entry.file;
18214 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
18217 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
18218 sizeof(struct hfsplus_cat_file));
18220 @@ -479,7 +479,7 @@ int hfsplus_cat_write_inode(struct inode
18221 struct hfsplus_cat_folder *folder = &entry.folder;
18223 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
18226 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
18227 sizeof(struct hfsplus_cat_folder));
18228 /* simple node checks? */
18229 @@ -501,7 +501,7 @@ int hfsplus_cat_write_inode(struct inode
18230 struct hfsplus_cat_file *file = &entry.file;
18232 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
18235 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
18236 sizeof(struct hfsplus_cat_file));
18237 hfsplus_inode_write_fork(inode, &file->data_fork);
18238 diff -urNp linux-2.6.29/fs/jffs2/debug.h linux-2.6.29/fs/jffs2/debug.h
18239 --- linux-2.6.29/fs/jffs2/debug.h 2009-03-23 19:12:14.000000000 -0400
18240 +++ linux-2.6.29/fs/jffs2/debug.h 2009-03-28 14:26:20.000000000 -0400
18241 @@ -52,13 +52,13 @@
18242 #if CONFIG_JFFS2_FS_DEBUG > 0
18246 +#define D1(x) do {} while (0);
18249 #if CONFIG_JFFS2_FS_DEBUG > 1
18253 +#define D2(x) do {} while (0);
18256 /* The prefixes of JFFS2 messages */
18257 @@ -114,73 +114,73 @@
18258 #ifdef JFFS2_DBG_READINODE_MESSAGES
18259 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18261 -#define dbg_readinode(fmt, ...)
18262 +#define dbg_readinode(fmt, ...) do {} while (0)
18264 #ifdef JFFS2_DBG_READINODE2_MESSAGES
18265 #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18267 -#define dbg_readinode2(fmt, ...)
18268 +#define dbg_readinode2(fmt, ...) do {} while (0)
18271 /* Fragtree build debugging messages */
18272 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
18273 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18275 -#define dbg_fragtree(fmt, ...)
18276 +#define dbg_fragtree(fmt, ...) do {} while (0)
18278 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
18279 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18281 -#define dbg_fragtree2(fmt, ...)
18282 +#define dbg_fragtree2(fmt, ...) do {} while (0)
18285 /* Directory entry list manilulation debugging messages */
18286 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
18287 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18289 -#define dbg_dentlist(fmt, ...)
18290 +#define dbg_dentlist(fmt, ...) do {} while (0)
18293 /* Print the messages about manipulating node_refs */
18294 #ifdef JFFS2_DBG_NODEREF_MESSAGES
18295 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18297 -#define dbg_noderef(fmt, ...)
18298 +#define dbg_noderef(fmt, ...) do {} while (0)
18301 /* Manipulations with the list of inodes (JFFS2 inocache) */
18302 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
18303 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18305 -#define dbg_inocache(fmt, ...)
18306 +#define dbg_inocache(fmt, ...) do {} while (0)
18309 /* Summary debugging messages */
18310 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
18311 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18313 -#define dbg_summary(fmt, ...)
18314 +#define dbg_summary(fmt, ...) do {} while (0)
18317 /* File system build messages */
18318 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
18319 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18321 -#define dbg_fsbuild(fmt, ...)
18322 +#define dbg_fsbuild(fmt, ...) do {} while (0)
18325 /* Watch the object allocations */
18326 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
18327 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18329 -#define dbg_memalloc(fmt, ...)
18330 +#define dbg_memalloc(fmt, ...) do {} while (0)
18333 /* Watch the XATTR subsystem */
18334 #ifdef JFFS2_DBG_XATTR_MESSAGES
18335 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18337 -#define dbg_xattr(fmt, ...)
18338 +#define dbg_xattr(fmt, ...) do {} while (0)
18341 /* "Sanity" checks */
18342 diff -urNp linux-2.6.29/fs/jffs2/erase.c linux-2.6.29/fs/jffs2/erase.c
18343 --- linux-2.6.29/fs/jffs2/erase.c 2009-03-23 19:12:14.000000000 -0400
18344 +++ linux-2.6.29/fs/jffs2/erase.c 2009-03-28 14:26:20.000000000 -0400
18345 @@ -432,7 +432,8 @@ static void jffs2_mark_erased_block(stru
18346 struct jffs2_unknown_node marker = {
18347 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
18348 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
18349 - .totlen = cpu_to_je32(c->cleanmarker_size)
18350 + .totlen = cpu_to_je32(c->cleanmarker_size),
18351 + .hdr_crc = cpu_to_je32(0)
18354 jffs2_prealloc_raw_node_refs(c, jeb, 1);
18355 diff -urNp linux-2.6.29/fs/jffs2/summary.h linux-2.6.29/fs/jffs2/summary.h
18356 --- linux-2.6.29/fs/jffs2/summary.h 2009-03-23 19:12:14.000000000 -0400
18357 +++ linux-2.6.29/fs/jffs2/summary.h 2009-03-28 14:26:20.000000000 -0400
18358 @@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
18360 #define jffs2_sum_active() (0)
18361 #define jffs2_sum_init(a) (0)
18362 -#define jffs2_sum_exit(a)
18363 -#define jffs2_sum_disable_collecting(a)
18364 +#define jffs2_sum_exit(a) do {} while (0)
18365 +#define jffs2_sum_disable_collecting(a) do {} while (0)
18366 #define jffs2_sum_is_disabled(a) (0)
18367 -#define jffs2_sum_reset_collected(a)
18368 +#define jffs2_sum_reset_collected(a) do {} while (0)
18369 #define jffs2_sum_add_kvec(a,b,c,d) (0)
18370 -#define jffs2_sum_move_collected(a,b)
18371 +#define jffs2_sum_move_collected(a,b) do {} while (0)
18372 #define jffs2_sum_write_sumnode(a) (0)
18373 -#define jffs2_sum_add_padding_mem(a,b)
18374 -#define jffs2_sum_add_inode_mem(a,b,c)
18375 -#define jffs2_sum_add_dirent_mem(a,b,c)
18376 -#define jffs2_sum_add_xattr_mem(a,b,c)
18377 -#define jffs2_sum_add_xref_mem(a,b,c)
18378 +#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
18379 +#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
18380 +#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
18381 +#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
18382 +#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
18383 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
18385 #endif /* CONFIG_JFFS2_SUMMARY */
18386 diff -urNp linux-2.6.29/fs/jffs2/wbuf.c linux-2.6.29/fs/jffs2/wbuf.c
18387 --- linux-2.6.29/fs/jffs2/wbuf.c 2009-03-23 19:12:14.000000000 -0400
18388 +++ linux-2.6.29/fs/jffs2/wbuf.c 2009-03-28 14:26:20.000000000 -0400
18389 @@ -1012,7 +1012,8 @@ static const struct jffs2_unknown_node o
18391 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
18392 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
18393 - .totlen = constant_cpu_to_je32(8)
18394 + .totlen = constant_cpu_to_je32(8),
18395 + .hdr_crc = constant_cpu_to_je32(0)
18399 diff -urNp linux-2.6.29/fs/locks.c linux-2.6.29/fs/locks.c
18400 --- linux-2.6.29/fs/locks.c 2009-03-23 19:12:14.000000000 -0400
18401 +++ linux-2.6.29/fs/locks.c 2009-03-28 14:26:20.000000000 -0400
18402 @@ -2006,16 +2006,16 @@ void locks_remove_flock(struct file *fil
18405 if (filp->f_op && filp->f_op->flock) {
18406 - struct file_lock fl = {
18407 + struct file_lock flock = {
18408 .fl_pid = current->tgid,
18410 .fl_flags = FL_FLOCK,
18411 .fl_type = F_UNLCK,
18412 .fl_end = OFFSET_MAX,
18414 - filp->f_op->flock(filp, F_SETLKW, &fl);
18415 - if (fl.fl_ops && fl.fl_ops->fl_release_private)
18416 - fl.fl_ops->fl_release_private(&fl);
18417 + filp->f_op->flock(filp, F_SETLKW, &flock);
18418 + if (flock.fl_ops && flock.fl_ops->fl_release_private)
18419 + flock.fl_ops->fl_release_private(&flock);
18423 diff -urNp linux-2.6.29/fs/namei.c linux-2.6.29/fs/namei.c
18424 --- linux-2.6.29/fs/namei.c 2009-03-23 19:12:14.000000000 -0400
18425 +++ linux-2.6.29/fs/namei.c 2009-03-28 14:26:20.000000000 -0400
18426 @@ -622,7 +622,7 @@ static __always_inline int __do_follow_l
18427 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
18428 error = PTR_ERR(cookie);
18429 if (!IS_ERR(cookie)) {
18430 - char *s = nd_get_link(nd);
18431 + const char *s = nd_get_link(nd);
18434 error = __vfs_follow_link(nd, s);
18435 @@ -653,6 +653,13 @@ static inline int do_follow_link(struct
18436 err = security_inode_follow_link(path->dentry, nd);
18440 + if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
18441 + path->dentry->d_inode, path->dentry, nd->path.mnt)) {
18446 current->link_count++;
18447 current->total_link_count++;
18449 @@ -996,11 +1003,18 @@ return_reval:
18453 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
18454 + path_put(&nd->path);
18459 path_put_conditional(&next, nd);
18462 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
18465 path_put(&nd->path);
18468 @@ -1571,12 +1585,19 @@ static int __open_namei_create(struct na
18470 struct dentry *dir = nd->path.dentry;
18472 + if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
18477 if (!IS_POSIXACL(dir->d_inode))
18478 mode &= ~current->fs->umask;
18479 error = security_path_mknod(&nd->path, path->dentry, mode, 0);
18482 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
18484 + gr_handle_create(path->dentry, nd->path.mnt);
18486 mutex_unlock(&dir->d_inode->i_mutex);
18487 dput(nd->path.dentry);
18488 @@ -1658,6 +1679,17 @@ struct file *do_filp_open(int dfd, const
18491 return ERR_PTR(error);
18493 + if (gr_handle_rawio(nd.path.dentry->d_inode)) {
18498 + if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
18506 @@ -1730,6 +1762,20 @@ do_last:
18508 * It already exists.
18511 + if (gr_handle_rawio(path.dentry->d_inode)) {
18513 + goto exit_mutex_unlock;
18515 + if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
18517 + goto exit_mutex_unlock;
18519 + if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
18521 + goto exit_mutex_unlock;
18524 mutex_unlock(&dir->d_inode->i_mutex);
18525 audit_inode(pathname, path.dentry);
18527 @@ -1815,6 +1861,13 @@ do_link:
18528 error = security_inode_follow_link(path.dentry, &nd);
18532 + if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
18533 + path.dentry, nd.path.mnt)) {
18538 error = __do_follow_link(&path, &nd);
18540 /* Does someone understand code flow here? Or it is only
18541 @@ -1987,6 +2040,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
18542 error = may_mknod(mode);
18546 + if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
18551 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
18556 error = mnt_want_write(nd.path.mnt);
18559 @@ -2007,6 +2071,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
18562 mnt_drop_write(nd.path.mnt);
18565 + gr_handle_create(dentry, nd.path.mnt);
18569 @@ -2060,6 +2127,11 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
18570 if (IS_ERR(dentry))
18573 + if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
18578 if (!IS_POSIXACL(nd.path.dentry->d_inode))
18579 mode &= ~current->fs->umask;
18580 error = mnt_want_write(nd.path.mnt);
18581 @@ -2071,6 +2143,10 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
18582 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
18584 mnt_drop_write(nd.path.mnt);
18587 + gr_handle_create(dentry, nd.path.mnt);
18592 @@ -2152,6 +2228,8 @@ static long do_rmdir(int dfd, const char
18594 struct dentry *dentry;
18595 struct nameidata nd;
18596 + ino_t saved_ino = 0;
18597 + dev_t saved_dev = 0;
18599 error = user_path_parent(dfd, pathname, &nd, &name);
18601 @@ -2176,6 +2254,19 @@ static long do_rmdir(int dfd, const char
18602 error = PTR_ERR(dentry);
18603 if (IS_ERR(dentry))
18606 + if (dentry->d_inode != NULL) {
18607 + if (dentry->d_inode->i_nlink <= 1) {
18608 + saved_ino = dentry->d_inode->i_ino;
18609 + saved_dev = dentry->d_inode->i_sb->s_dev;
18612 + if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
18618 error = mnt_want_write(nd.path.mnt);
18621 @@ -2183,6 +2274,8 @@ static long do_rmdir(int dfd, const char
18624 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
18625 + if (!error && (saved_dev || saved_ino))
18626 + gr_handle_delete(saved_ino, saved_dev);
18628 mnt_drop_write(nd.path.mnt);
18630 @@ -2244,6 +2337,8 @@ static long do_unlinkat(int dfd, const c
18631 struct dentry *dentry;
18632 struct nameidata nd;
18633 struct inode *inode = NULL;
18634 + ino_t saved_ino = 0;
18635 + dev_t saved_dev = 0;
18637 error = user_path_parent(dfd, pathname, &nd, &name);
18639 @@ -2263,8 +2358,19 @@ static long do_unlinkat(int dfd, const c
18640 if (nd.last.name[nd.last.len])
18642 inode = dentry->d_inode;
18645 + if (inode->i_nlink <= 1) {
18646 + saved_ino = inode->i_ino;
18647 + saved_dev = inode->i_sb->s_dev;
18650 atomic_inc(&inode->i_count);
18652 + if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
18657 error = mnt_want_write(nd.path.mnt);
18660 @@ -2272,6 +2378,8 @@ static long do_unlinkat(int dfd, const c
18663 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
18664 + if (!error && (saved_ino || saved_dev))
18665 + gr_handle_delete(saved_ino, saved_dev);
18667 mnt_drop_write(nd.path.mnt);
18669 @@ -2350,6 +2458,11 @@ SYSCALL_DEFINE3(symlinkat, const char __
18670 if (IS_ERR(dentry))
18673 + if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
18678 error = mnt_want_write(nd.path.mnt);
18681 @@ -2357,6 +2470,8 @@ SYSCALL_DEFINE3(symlinkat, const char __
18683 goto out_drop_write;
18684 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
18686 + gr_handle_create(dentry, nd.path.mnt);
18688 mnt_drop_write(nd.path.mnt);
18690 @@ -2450,6 +2565,20 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
18691 error = PTR_ERR(new_dentry);
18692 if (IS_ERR(new_dentry))
18695 + if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
18696 + old_path.dentry->d_inode,
18697 + old_path.dentry->d_inode->i_mode, to)) {
18702 + if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
18703 + old_path.dentry, old_path.mnt, to)) {
18708 error = mnt_want_write(nd.path.mnt);
18711 @@ -2457,6 +2586,8 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
18713 goto out_drop_write;
18714 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
18716 + gr_handle_create(new_dentry, nd.path.mnt);
18718 mnt_drop_write(nd.path.mnt);
18720 @@ -2690,6 +2821,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
18721 if (new_dentry == trap)
18724 + error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
18725 + old_dentry, old_dir->d_inode, oldnd.path.mnt,
18730 error = mnt_want_write(oldnd.path.mnt);
18733 @@ -2699,6 +2836,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
18735 error = vfs_rename(old_dir->d_inode, old_dentry,
18736 new_dir->d_inode, new_dentry);
18738 + gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
18739 + new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
18741 mnt_drop_write(oldnd.path.mnt);
18743 diff -urNp linux-2.6.29/fs/namespace.c linux-2.6.29/fs/namespace.c
18744 --- linux-2.6.29/fs/namespace.c 2009-03-23 19:12:14.000000000 -0400
18745 +++ linux-2.6.29/fs/namespace.c 2009-03-28 14:26:20.000000000 -0400
18746 @@ -1096,6 +1096,8 @@ static int do_umount(struct vfsmount *mn
18748 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
18751 + gr_log_remount(mnt->mnt_devname, retval);
18753 up_write(&sb->s_umount);
18755 @@ -1119,6 +1121,9 @@ static int do_umount(struct vfsmount *mn
18756 security_sb_umount_busy(mnt);
18757 up_write(&namespace_sem);
18758 release_mounts(&umount_list);
18760 + gr_log_unmount(mnt->mnt_devname, retval);
18765 @@ -1948,6 +1953,11 @@ long do_mount(char *dev_name, char *dir_
18769 + if (gr_handle_chroot_mount(path.dentry, path.mnt, dev_name)) {
18774 if (flags & MS_REMOUNT)
18775 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
18777 @@ -1962,6 +1972,9 @@ long do_mount(char *dev_name, char *dir_
18778 dev_name, data_page);
18782 + gr_log_mount(dev_name, dir_name, retval);
18787 @@ -2073,6 +2086,9 @@ SYSCALL_DEFINE5(mount, char __user *, de
18791 + if (gr_handle_chroot_pivot())
18795 retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
18796 flags, (void *)data_page);
18797 diff -urNp linux-2.6.29/fs/nfs/nfs4proc.c linux-2.6.29/fs/nfs/nfs4proc.c
18798 --- linux-2.6.29/fs/nfs/nfs4proc.c 2009-03-23 19:12:14.000000000 -0400
18799 +++ linux-2.6.29/fs/nfs/nfs4proc.c 2009-03-28 14:26:20.000000000 -0400
18800 @@ -763,7 +763,7 @@ static int _nfs4_do_open_reclaim(struct
18801 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
18803 struct nfs_server *server = NFS_SERVER(state->inode);
18804 - struct nfs4_exception exception = { };
18805 + struct nfs4_exception exception = {0, 0};
18808 err = _nfs4_do_open_reclaim(ctx, state);
18809 @@ -805,7 +805,7 @@ static int _nfs4_open_delegation_recall(
18811 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
18813 - struct nfs4_exception exception = { };
18814 + struct nfs4_exception exception = {0, 0};
18815 struct nfs_server *server = NFS_SERVER(state->inode);
18818 @@ -1099,7 +1099,7 @@ static int _nfs4_open_expired(struct nfs
18819 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
18821 struct nfs_server *server = NFS_SERVER(state->inode);
18822 - struct nfs4_exception exception = { };
18823 + struct nfs4_exception exception = {0, 0};
18827 @@ -1197,7 +1197,7 @@ out_err:
18829 static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred)
18831 - struct nfs4_exception exception = { };
18832 + struct nfs4_exception exception = {0, 0};
18833 struct nfs4_state *res;
18836 @@ -1288,7 +1288,7 @@ static int nfs4_do_setattr(struct inode
18837 struct nfs4_state *state)
18839 struct nfs_server *server = NFS_SERVER(inode);
18840 - struct nfs4_exception exception = { };
18841 + struct nfs4_exception exception = {0, 0};
18844 err = nfs4_handle_exception(server,
18845 @@ -1607,7 +1607,7 @@ static int _nfs4_server_capabilities(str
18847 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
18849 - struct nfs4_exception exception = { };
18850 + struct nfs4_exception exception = {0, 0};
18853 err = nfs4_handle_exception(server,
18854 @@ -1640,7 +1640,7 @@ static int _nfs4_lookup_root(struct nfs_
18855 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
18856 struct nfs_fsinfo *info)
18858 - struct nfs4_exception exception = { };
18859 + struct nfs4_exception exception = {0, 0};
18862 err = nfs4_handle_exception(server,
18863 @@ -1729,7 +1729,7 @@ static int _nfs4_proc_getattr(struct nfs
18865 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
18867 - struct nfs4_exception exception = { };
18868 + struct nfs4_exception exception = {0, 0};
18871 err = nfs4_handle_exception(server,
18872 @@ -1817,7 +1817,7 @@ static int nfs4_proc_lookupfh(struct nfs
18873 struct qstr *name, struct nfs_fh *fhandle,
18874 struct nfs_fattr *fattr)
18876 - struct nfs4_exception exception = { };
18877 + struct nfs4_exception exception = {0, 0};
18880 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
18881 @@ -1846,7 +1846,7 @@ static int _nfs4_proc_lookup(struct inod
18883 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
18885 - struct nfs4_exception exception = { };
18886 + struct nfs4_exception exception = {0, 0};
18889 err = nfs4_handle_exception(NFS_SERVER(dir),
18890 @@ -1910,7 +1910,7 @@ static int _nfs4_proc_access(struct inod
18892 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
18894 - struct nfs4_exception exception = { };
18895 + struct nfs4_exception exception = {0, 0};
18898 err = nfs4_handle_exception(NFS_SERVER(inode),
18899 @@ -1965,7 +1965,7 @@ static int _nfs4_proc_readlink(struct in
18900 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
18901 unsigned int pgbase, unsigned int pglen)
18903 - struct nfs4_exception exception = { };
18904 + struct nfs4_exception exception = {0, 0};
18907 err = nfs4_handle_exception(NFS_SERVER(inode),
18908 @@ -2063,7 +2063,7 @@ static int _nfs4_proc_remove(struct inod
18910 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
18912 - struct nfs4_exception exception = { };
18913 + struct nfs4_exception exception = {0, 0};
18916 err = nfs4_handle_exception(NFS_SERVER(dir),
18917 @@ -2135,7 +2135,7 @@ static int _nfs4_proc_rename(struct inod
18918 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
18919 struct inode *new_dir, struct qstr *new_name)
18921 - struct nfs4_exception exception = { };
18922 + struct nfs4_exception exception = {0, 0};
18925 err = nfs4_handle_exception(NFS_SERVER(old_dir),
18926 @@ -2182,7 +2182,7 @@ static int _nfs4_proc_link(struct inode
18928 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
18930 - struct nfs4_exception exception = { };
18931 + struct nfs4_exception exception = {0, 0};
18934 err = nfs4_handle_exception(NFS_SERVER(inode),
18935 @@ -2273,7 +2273,7 @@ out:
18936 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
18937 struct page *page, unsigned int len, struct iattr *sattr)
18939 - struct nfs4_exception exception = { };
18940 + struct nfs4_exception exception = {0, 0};
18943 err = nfs4_handle_exception(NFS_SERVER(dir),
18944 @@ -2304,7 +2304,7 @@ out:
18945 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
18946 struct iattr *sattr)
18948 - struct nfs4_exception exception = { };
18949 + struct nfs4_exception exception = {0, 0};
18952 err = nfs4_handle_exception(NFS_SERVER(dir),
18953 @@ -2353,7 +2353,7 @@ static int _nfs4_proc_readdir(struct den
18954 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
18955 u64 cookie, struct page *page, unsigned int count, int plus)
18957 - struct nfs4_exception exception = { };
18958 + struct nfs4_exception exception = {0, 0};
18961 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
18962 @@ -2401,7 +2401,7 @@ out:
18963 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
18964 struct iattr *sattr, dev_t rdev)
18966 - struct nfs4_exception exception = { };
18967 + struct nfs4_exception exception = {0, 0};
18970 err = nfs4_handle_exception(NFS_SERVER(dir),
18971 @@ -2430,7 +2430,7 @@ static int _nfs4_proc_statfs(struct nfs_
18973 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
18975 - struct nfs4_exception exception = { };
18976 + struct nfs4_exception exception = {0, 0};
18979 err = nfs4_handle_exception(server,
18980 @@ -2458,7 +2458,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
18982 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
18984 - struct nfs4_exception exception = { };
18985 + struct nfs4_exception exception = {0, 0};
18989 @@ -2501,7 +2501,7 @@ static int _nfs4_proc_pathconf(struct nf
18990 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
18991 struct nfs_pathconf *pathconf)
18993 - struct nfs4_exception exception = { };
18994 + struct nfs4_exception exception = {0, 0};
18998 @@ -2788,7 +2788,7 @@ out_free:
19000 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
19002 - struct nfs4_exception exception = { };
19003 + struct nfs4_exception exception = {0, 0};
19006 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
19007 @@ -2845,7 +2845,7 @@ static int __nfs4_proc_set_acl(struct in
19009 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
19011 - struct nfs4_exception exception = { };
19012 + struct nfs4_exception exception = {0, 0};
19015 err = nfs4_handle_exception(NFS_SERVER(inode),
19016 @@ -3068,7 +3068,7 @@ out:
19017 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
19019 struct nfs_server *server = NFS_SERVER(inode);
19020 - struct nfs4_exception exception = { };
19021 + struct nfs4_exception exception = {0, 0};
19024 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
19025 @@ -3141,7 +3141,7 @@ out:
19027 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
19029 - struct nfs4_exception exception = { };
19030 + struct nfs4_exception exception = {0, 0};
19034 @@ -3498,7 +3498,7 @@ static int _nfs4_do_setlk(struct nfs4_st
19035 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
19037 struct nfs_server *server = NFS_SERVER(state->inode);
19038 - struct nfs4_exception exception = { };
19039 + struct nfs4_exception exception = {0, 0};
19043 @@ -3516,7 +3516,7 @@ static int nfs4_lock_reclaim(struct nfs4
19044 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
19046 struct nfs_server *server = NFS_SERVER(state->inode);
19047 - struct nfs4_exception exception = { };
19048 + struct nfs4_exception exception = {0, 0};
19051 err = nfs4_set_lock_state(state, request);
19052 @@ -3571,7 +3571,7 @@ out:
19054 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
19056 - struct nfs4_exception exception = { };
19057 + struct nfs4_exception exception = {0, 0};
19061 @@ -3621,7 +3621,7 @@ nfs4_proc_lock(struct file *filp, int cm
19062 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
19064 struct nfs_server *server = NFS_SERVER(state->inode);
19065 - struct nfs4_exception exception = { };
19066 + struct nfs4_exception exception = {0, 0};
19069 err = nfs4_set_lock_state(state, fl);
19070 diff -urNp linux-2.6.29/fs/nfsd/export.c linux-2.6.29/fs/nfsd/export.c
19071 --- linux-2.6.29/fs/nfsd/export.c 2009-03-23 19:12:14.000000000 -0400
19072 +++ linux-2.6.29/fs/nfsd/export.c 2009-03-28 14:26:20.000000000 -0400
19073 @@ -472,7 +472,7 @@ static int secinfo_parse(char **mesg, ch
19074 * probably discover the problem when someone fails to
19077 - if (f->pseudoflavor < 0)
19078 + if ((s32)f->pseudoflavor < 0)
19080 err = get_int(mesg, &f->flags);
19082 diff -urNp linux-2.6.29/fs/nls/nls_base.c linux-2.6.29/fs/nls/nls_base.c
19083 --- linux-2.6.29/fs/nls/nls_base.c 2009-03-23 19:12:14.000000000 -0400
19084 +++ linux-2.6.29/fs/nls/nls_base.c 2009-03-28 14:26:20.000000000 -0400
19085 @@ -40,7 +40,7 @@ static const struct utf8_table utf8_tabl
19086 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
19087 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
19088 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
19089 - {0, /* end of table */}
19090 + {0, 0, 0, 0, 0, /* end of table */}
19094 diff -urNp linux-2.6.29/fs/ntfs/file.c linux-2.6.29/fs/ntfs/file.c
19095 --- linux-2.6.29/fs/ntfs/file.c 2009-03-23 19:12:14.000000000 -0400
19096 +++ linux-2.6.29/fs/ntfs/file.c 2009-03-28 14:26:20.000000000 -0400
19097 @@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
19098 #endif /* NTFS_RW */
19101 -const struct file_operations ntfs_empty_file_ops = {};
19102 +const struct file_operations ntfs_empty_file_ops;
19104 -const struct inode_operations ntfs_empty_inode_ops = {};
19105 +const struct inode_operations ntfs_empty_inode_ops;
19106 diff -urNp linux-2.6.29/fs/open.c linux-2.6.29/fs/open.c
19107 --- linux-2.6.29/fs/open.c 2009-03-23 19:12:14.000000000 -0400
19108 +++ linux-2.6.29/fs/open.c 2009-03-28 15:24:51.000000000 -0400
19109 @@ -214,6 +214,9 @@
19113 + if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
19116 newattrs.ia_size = length;
19117 newattrs.ia_valid = ATTR_SIZE | time_attrs;
19119 @@ -518,6 +521,9 @@
19120 if (__mnt_is_readonly(path.mnt))
19123 + if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
19129 @@ -544,6 +550,8 @@
19133 + gr_log_chdir(path.dentry, path.mnt);
19135 set_fs_pwd(current->fs, &path);
19138 @@ -570,6 +578,13 @@
19141 error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
19143 + if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
19147 + gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
19150 set_fs_pwd(current->fs, &file->f_path);
19152 @@ -595,7 +610,18 @@
19153 if (!capable(CAP_SYS_CHROOT))
19156 + if (gr_handle_chroot_chroot(path.dentry, path.mnt))
19157 + goto dput_and_out;
19159 + if (gr_handle_chroot_caps(&path)) {
19161 + goto dput_and_out;
19164 set_fs_root(current->fs, &path);
19166 + gr_handle_chroot_chdir(&path);
19171 @@ -623,13 +649,28 @@
19172 err = mnt_want_write(file->f_path.mnt);
19176 + if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
19178 + goto out_drop_write;
19181 mutex_lock(&inode->i_mutex);
19182 if (mode == (mode_t) -1)
19183 mode = inode->i_mode;
19185 + if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
19187 + mutex_unlock(&inode->i_mutex);
19188 + goto out_drop_write;
19191 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
19192 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
19193 err = notify_change(dentry, &newattrs);
19194 mutex_unlock(&inode->i_mutex);
19197 mnt_drop_write(file->f_path.mnt);
19200 @@ -656,13 +697,28 @@
19201 error = mnt_want_write(path.mnt);
19205 + if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
19207 + goto out_drop_write;
19210 mutex_lock(&inode->i_mutex);
19211 if (mode == (mode_t) -1)
19212 mode = inode->i_mode;
19214 + if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
19216 + mutex_unlock(&inode->i_mutex);
19217 + goto out_drop_write;
19220 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
19221 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
19222 error = notify_change(path.dentry, &newattrs);
19223 mutex_unlock(&inode->i_mutex);
19226 mnt_drop_write(path.mnt);
19229 @@ -675,12 +731,15 @@
19230 return sys_fchmodat(AT_FDCWD, filename, mode);
19233 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
19234 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
19236 struct inode *inode = dentry->d_inode;
19238 struct iattr newattrs;
19240 + if (!gr_acl_handle_chown(dentry, mnt))
19243 newattrs.ia_valid = ATTR_CTIME;
19244 if (user != (uid_t) -1) {
19245 newattrs.ia_valid |= ATTR_UID;
19246 @@ -715,7 +774,7 @@
19247 error = cow_check_and_break(&path);
19250 - error = chown_common(path.dentry, user, group);
19251 + error = chown_common(path.dentry, user, group, path.mnt);
19252 mnt_drop_write(path.mnt);
19255 @@ -744,7 +803,7 @@
19256 error = cow_check_and_break(&path);
19259 - error = chown_common(path.dentry, user, group);
19260 + error = chown_common(path.dentry, user, group, path.mnt);
19261 mnt_drop_write(path.mnt);
19264 @@ -767,7 +826,7 @@
19265 error = cow_check_and_break(&path);
19268 - error = chown_common(path.dentry, user, group);
19269 + error = chown_common(path.dentry, user, group, path.mnt);
19270 mnt_drop_write(path.mnt);
19273 @@ -790,7 +849,7 @@
19275 dentry = file->f_path.dentry;
19276 audit_inode(NULL, dentry);
19277 - error = chown_common(dentry, user, group);
19278 + error = chown_common(dentry, user, group, file->f_path.mnt);
19279 mnt_drop_write(file->f_path.mnt);
19282 diff -urNp linux-2.6.29/fs/pipe.c linux-2.6.29/fs/pipe.c
19283 --- linux-2.6.29/fs/pipe.c 2009-03-23 19:12:14.000000000 -0400
19284 +++ linux-2.6.29/fs/pipe.c 2009-03-28 14:26:20.000000000 -0400
19285 @@ -848,7 +848,7 @@ void free_pipe_info(struct inode *inode)
19286 inode->i_pipe = NULL;
19289 -static struct vfsmount *pipe_mnt __read_mostly;
19290 +struct vfsmount *pipe_mnt __read_mostly;
19291 static int pipefs_delete_dentry(struct dentry *dentry)
19294 diff -urNp linux-2.6.29/fs/proc/array.c linux-2.6.29/fs/proc/array.c
19295 --- linux-2.6.29/fs/proc/array.c 2009-03-23 19:12:14.000000000 -0400
19296 +++ linux-2.6.29/fs/proc/array.c 2009-03-28 14:26:20.000000000 -0400
19297 @@ -320,6 +320,21 @@ static inline void task_context_switch_c
19301 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19302 +static inline void task_pax(struct seq_file *m, struct task_struct *p)
19305 + seq_printf(m, "PaX:\t%c%c%c%c%c\n",
19306 + p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
19307 + p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
19308 + p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
19309 + p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
19310 + p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
19312 + seq_printf(m, "PaX:\t-----\n");
19316 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
19317 struct pid *pid, struct task_struct *task)
19319 @@ -339,9 +354,20 @@ int proc_pid_status(struct seq_file *m,
19320 task_show_regs(m, task);
19322 task_context_switch_counts(m, task);
19324 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19325 + task_pax(m, task);
19331 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19332 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
19333 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
19334 + _mm->pax_flags & MF_PAX_SEGMEXEC))
19337 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
19338 struct pid *pid, struct task_struct *task, int whole)
19340 @@ -434,6 +460,19 @@ static int do_task_stat(struct seq_file
19341 gtime = task_gtime(task);
19344 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19345 + if (PAX_RAND_FLAGS(mm)) {
19351 +#ifdef CONFIG_GRKERNSEC_HIDESYM
19357 /* scale priority and nice values from timeslices to -20..20 */
19358 /* to make it look like a "normal" Unix priority/nice value */
19359 priority = task_prio(task);
19360 @@ -474,9 +513,15 @@ static int do_task_stat(struct seq_file
19362 mm ? get_mm_rss(mm) : 0,
19364 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19365 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
19366 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
19367 + PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
19369 mm ? mm->start_code : 0,
19370 mm ? mm->end_code : 0,
19371 mm ? mm->start_stack : 0,
19375 /* The signal information here is obsolete.
19376 @@ -529,3 +574,10 @@ int proc_pid_statm(struct seq_file *m, s
19381 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19382 +int proc_pid_ipaddr(struct task_struct *task, char *buffer)
19384 + return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
19387 diff -urNp linux-2.6.29/fs/proc/base.c linux-2.6.29/fs/proc/base.c
19388 --- linux-2.6.29/fs/proc/base.c 2009-03-23 19:12:14.000000000 -0400
19389 +++ linux-2.6.29/fs/proc/base.c 2009-03-28 14:26:20.000000000 -0400
19390 @@ -225,6 +225,9 @@
19391 if (task == current)
19394 + if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
19398 * If current is actively ptrace'ing, and would also be
19399 * permitted to freshly attach with ptrace now, permit it.
19400 @@ -302,12 +305,26 @@
19404 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19405 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
19406 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
19407 + _mm->pax_flags & MF_PAX_SEGMEXEC))
19410 static int proc_pid_auxv(struct task_struct *task, char *buffer)
19413 struct mm_struct *mm = get_task_mm(task);
19415 unsigned int nwords = 0;
19417 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19418 + if (PAX_RAND_FLAGS(mm)) {
19426 } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
19427 @@ -533,7 +550,7 @@
19431 -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
19432 +#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
19433 static int proc_pid_syscall(struct task_struct *task, char *buffer)
19436 @@ -1457,7 +1474,11 @@
19438 cred = __task_cred(task);
19439 inode->i_uid = cred->euid;
19440 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19441 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19443 inode->i_gid = cred->egid;
19447 /* procfs is xid tagged */
19448 @@ -1477,6 +1498,9 @@
19449 struct inode *inode = dentry->d_inode;
19450 struct task_struct *task;
19451 const struct cred *cred;
19452 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19453 + const struct cred *tmpcred = current_cred();
19456 generic_fillattr(inode, stat);
19458 @@ -1484,12 +1508,34 @@
19461 task = pid_task(proc_pid(inode), PIDTYPE_PID);
19463 + if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
19464 + rcu_read_unlock();
19469 + cred = __task_cred(task);
19470 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19471 + if (!tmpcred->uid || (tmpcred->uid == cred->uid)
19472 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19473 + || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
19477 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
19478 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19479 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
19480 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19481 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
19483 task_dumpable(task)) {
19484 - cred = __task_cred(task);
19485 stat->uid = cred->euid;
19486 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19487 + stat->gid = CONFIG_GRKERNSEC_PROC_GID;
19489 stat->gid = cred->egid;
19494 @@ -1521,11 +1567,20 @@
19497 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
19498 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19499 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
19500 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19501 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
19503 task_dumpable(task)) {
19505 cred = __task_cred(task);
19506 inode->i_uid = cred->euid;
19507 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19508 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19510 inode->i_gid = cred->egid;
19515 @@ -1898,12 +1953,22 @@
19516 static int proc_fd_permission(struct inode *inode, int mask)
19519 + struct task_struct *task;
19521 rv = generic_permission(inode, mask, NULL);
19525 if (task_pid(current) == proc_pid(inode))
19528 + task = get_proc_task(inode);
19529 + if (task == NULL)
19532 + if (gr_acl_handle_procpidmem(task))
19535 + put_task_struct(task);
19540 @@ -2019,6 +2084,9 @@
19541 !memcmp(dentry->d_name.name, "ninfo", 5)))
19544 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19548 * Yes, it does not scale. And it should not. Don't add
19549 * new entries into /proc/<tgid>/ without very good reasons.
19550 @@ -2063,6 +2131,9 @@
19554 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19560 @@ -2423,6 +2494,9 @@
19564 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19567 error = proc_base_instantiate(dir, dentry, task, p);
19570 @@ -2512,7 +2586,7 @@
19571 #ifdef CONFIG_SCHED_DEBUG
19572 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
19574 -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
19575 +#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
19576 INF("syscall", S_IRUSR, proc_pid_syscall),
19578 INF("cmdline", S_IRUGO, proc_pid_cmdline),
19579 @@ -2702,7 +2776,14 @@
19583 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19584 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
19585 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19586 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19587 + inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
19589 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
19591 inode->i_op = &proc_tgid_base_inode_operations;
19592 inode->i_fop = &proc_tgid_base_operations;
19593 inode->i_flags|=S_IMMUTABLE;
19594 @@ -2744,7 +2825,11 @@
19598 + if (gr_check_hidden_task(task))
19599 + goto out_put_task;
19601 result = proc_pid_instantiate(dir, dentry, task, NULL);
19603 put_task_struct(task);
19606 @@ -2809,6 +2894,10 @@
19608 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
19609 struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
19610 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19611 + const struct cred *tmpcred = current_cred();
19612 + const struct cred *itercred;
19614 struct tgid_iter iter;
19615 struct pid_namespace *ns;
19617 @@ -2827,6 +2916,20 @@
19618 for (iter = next_tgid(ns, iter);
19620 iter.tgid += 1, iter = next_tgid(ns, iter)) {
19621 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19622 + itercred = __task_cred(iter.task);
19624 + if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
19625 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19626 + || (tmpcred->uid && (itercred->uid != tmpcred->uid)
19627 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19628 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
19635 filp->f_pos = iter.tgid + TGID_OFFSET;
19636 if (!vx_proc_task_visible(iter.task))
19638 @@ -2910,6 +3013,9 @@
19639 #ifdef CONFIG_TASK_IO_ACCOUNTING
19640 INF("io", S_IRUGO, proc_tid_io_accounting),
19642 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19643 + INF("ipaddr", S_IRUSR, proc_pid_ipaddr),
19647 static int proc_tid_base_readdir(struct file * filp,
19648 diff -urNp linux-2.6.29/fs/proc/cmdline.c linux-2.6.29/fs/proc/cmdline.c
19649 --- linux-2.6.29/fs/proc/cmdline.c 2009-03-23 19:12:14.000000000 -0400
19650 +++ linux-2.6.29/fs/proc/cmdline.c 2009-03-28 14:26:20.000000000 -0400
19651 @@ -23,7 +23,11 @@ static const struct file_operations cmdl
19653 static int __init proc_cmdline_init(void)
19655 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
19656 + proc_create_grsec("cmdline", 0, NULL, &cmdline_proc_fops);
19658 proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
19662 module_init(proc_cmdline_init);
19663 diff -urNp linux-2.6.29/fs/proc/devices.c linux-2.6.29/fs/proc/devices.c
19664 --- linux-2.6.29/fs/proc/devices.c 2009-03-23 19:12:14.000000000 -0400
19665 +++ linux-2.6.29/fs/proc/devices.c 2009-03-28 14:26:20.000000000 -0400
19666 @@ -64,7 +64,11 @@ static const struct file_operations proc
19668 static int __init proc_devices_init(void)
19670 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
19671 + proc_create_grsec("devices", 0, NULL, &proc_devinfo_operations);
19673 proc_create("devices", 0, NULL, &proc_devinfo_operations);
19677 module_init(proc_devices_init);
19678 diff -urNp linux-2.6.29/fs/proc/inode.c linux-2.6.29/fs/proc/inode.c
19679 --- linux-2.6.29/fs/proc/inode.c 2009-03-23 19:12:14.000000000 -0400
19680 +++ linux-2.6.29/fs/proc/inode.c 2009-03-28 14:26:20.000000000 -0400
19681 @@ -463,7 +463,11 @@ struct inode *proc_get_inode(struct supe
19683 inode->i_mode = de->mode;
19684 inode->i_uid = de->uid;
19685 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19686 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19688 inode->i_gid = de->gid;
19692 inode->i_size = de->size;
19693 diff -urNp linux-2.6.29/fs/proc/internal.h linux-2.6.29/fs/proc/internal.h
19694 --- linux-2.6.29/fs/proc/internal.h 2009-03-23 19:12:14.000000000 -0400
19695 +++ linux-2.6.29/fs/proc/internal.h 2009-03-28 14:26:20.000000000 -0400
19696 @@ -54,6 +54,9 @@ extern int proc_pid_statm(struct seq_fil
19697 struct pid *pid, struct task_struct *task);
19698 extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
19699 struct pid *pid, struct task_struct *task);
19700 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19701 +extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
19704 extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
19706 diff -urNp linux-2.6.29/fs/proc/Kconfig linux-2.6.29/fs/proc/Kconfig
19707 --- linux-2.6.29/fs/proc/Kconfig 2009-03-23 19:12:14.000000000 -0400
19708 +++ linux-2.6.29/fs/proc/Kconfig 2009-03-28 14:26:20.000000000 -0400
19709 @@ -30,12 +30,12 @@ config PROC_FS
19712 bool "/proc/kcore support" if !ARM
19713 - depends on PROC_FS && MMU
19714 + depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
19717 bool "/proc/vmcore support (EXPERIMENTAL)"
19718 - depends on PROC_FS && CRASH_DUMP
19720 + depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
19723 Exports the dump image of crashed kernel in ELF format.
19725 @@ -59,8 +59,8 @@ config PROC_SYSCTL
19728 config PROC_PAGE_MONITOR
19730 - depends on PROC_FS && MMU
19732 + depends on PROC_FS && MMU && !GRKERNSEC
19733 bool "Enable /proc page monitoring" if EMBEDDED
19735 Various /proc files exist to monitor process memory utilization:
19736 diff -urNp linux-2.6.29/fs/proc/kcore.c linux-2.6.29/fs/proc/kcore.c
19737 --- linux-2.6.29/fs/proc/kcore.c 2009-03-23 19:12:14.000000000 -0400
19738 +++ linux-2.6.29/fs/proc/kcore.c 2009-03-28 14:26:20.000000000 -0400
19739 @@ -404,10 +404,12 @@ read_kcore(struct file *file, char __use
19741 static int __init proc_kcore_init(void)
19743 +#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
19744 proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
19745 if (proc_root_kcore)
19746 proc_root_kcore->size =
19747 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
19751 module_init(proc_kcore_init);
19752 diff -urNp linux-2.6.29/fs/proc/nommu.c linux-2.6.29/fs/proc/nommu.c
19753 --- linux-2.6.29/fs/proc/nommu.c 2009-03-23 19:12:14.000000000 -0400
19754 +++ linux-2.6.29/fs/proc/nommu.c 2009-03-28 14:26:20.000000000 -0400
19755 @@ -67,7 +67,7 @@ static int nommu_region_show(struct seq_
19758 seq_printf(m, "%*c", len, ' ');
19759 - seq_path(m, &file->f_path, "");
19760 + seq_path(m, &file->f_path, "\n\\");
19764 diff -urNp linux-2.6.29/fs/proc/proc_net.c linux-2.6.29/fs/proc/proc_net.c
19765 --- linux-2.6.29/fs/proc/proc_net.c 2009-03-23 19:12:14.000000000 -0400
19766 +++ linux-2.6.29/fs/proc/proc_net.c 2009-03-28 14:26:20.000000000 -0400
19767 @@ -104,6 +104,17 @@ static struct net *get_proc_task_net(str
19768 struct task_struct *task;
19769 struct nsproxy *ns;
19770 struct net *net = NULL;
19771 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19772 + const struct cred *cred = current_cred();
19775 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19778 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19779 + if (cred->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
19784 task = pid_task(proc_pid(dir), PIDTYPE_PID);
19785 diff -urNp linux-2.6.29/fs/proc/proc_sysctl.c linux-2.6.29/fs/proc/proc_sysctl.c
19786 --- linux-2.6.29/fs/proc/proc_sysctl.c 2009-03-23 19:12:14.000000000 -0400
19787 +++ linux-2.6.29/fs/proc/proc_sysctl.c 2009-03-28 14:26:20.000000000 -0400
19789 #include <linux/security.h>
19790 #include "internal.h"
19792 +extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
19794 static struct dentry_operations proc_sys_dentry_operations;
19795 static const struct file_operations proc_sys_file_operations;
19796 static const struct inode_operations proc_sys_inode_operations;
19797 @@ -109,6 +111,9 @@ static struct dentry *proc_sys_lookup(st
19801 + if (gr_handle_sysctl(p, MAY_EXEC))
19804 err = ERR_PTR(-ENOMEM);
19805 inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
19807 @@ -228,6 +233,9 @@ static int scan(struct ctl_table_header
19808 if (*pos < file->f_pos)
19811 + if (gr_handle_sysctl(table, 0))
19814 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
19817 @@ -344,6 +352,9 @@ static int proc_sys_getattr(struct vfsmo
19819 return PTR_ERR(head);
19821 + if (table && gr_handle_sysctl(table, MAY_EXEC))
19824 generic_fillattr(inode, stat);
19826 stat->mode = (stat->mode & S_IFMT) | table->mode;
19827 diff -urNp linux-2.6.29/fs/proc/root.c linux-2.6.29/fs/proc/root.c
19828 --- linux-2.6.29/fs/proc/root.c 2009-03-23 19:12:14.000000000 -0400
19829 +++ linux-2.6.29/fs/proc/root.c 2009-03-28 14:26:20.000000000 -0400
19830 @@ -134,7 +134,15 @@ void __init proc_root_init(void)
19831 #ifdef CONFIG_PROC_DEVICETREE
19832 proc_device_tree_init();
19834 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
19835 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19836 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
19837 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19838 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
19841 proc_mkdir("bus", NULL);
19846 diff -urNp linux-2.6.29/fs/proc/task_mmu.c linux-2.6.29/fs/proc/task_mmu.c
19847 --- linux-2.6.29/fs/proc/task_mmu.c 2009-03-23 19:12:14.000000000 -0400
19848 +++ linux-2.6.29/fs/proc/task_mmu.c 2009-03-28 14:26:20.000000000 -0400
19849 @@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
19850 "VmStk:\t%8lu kB\n"
19851 "VmExe:\t%8lu kB\n"
19852 "VmLib:\t%8lu kB\n"
19853 - "VmPTE:\t%8lu kB\n",
19854 - hiwater_vm << (PAGE_SHIFT-10),
19855 + "VmPTE:\t%8lu kB\n"
19857 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19858 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
19861 + ,hiwater_vm << (PAGE_SHIFT-10),
19862 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
19863 mm->locked_vm << (PAGE_SHIFT-10),
19864 hiwater_rss << (PAGE_SHIFT-10),
19865 total_rss << (PAGE_SHIFT-10),
19866 data << (PAGE_SHIFT-10),
19867 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
19868 - (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
19869 + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
19871 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19872 + , mm->context.user_cs_base, mm->context.user_cs_limit
19878 unsigned long task_vsize(struct mm_struct *mm)
19879 @@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
19883 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19884 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
19885 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
19886 + _mm->pax_flags & MF_PAX_SEGMEXEC))
19889 static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
19891 struct mm_struct *mm = vma->vm_mm;
19892 @@ -214,13 +231,22 @@ static void show_map_vma(struct seq_file
19895 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
19896 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19897 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
19898 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
19903 flags & VM_READ ? 'r' : '-',
19904 flags & VM_WRITE ? 'w' : '-',
19905 flags & VM_EXEC ? 'x' : '-',
19906 flags & VM_MAYSHARE ? 's' : 'p',
19907 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19908 + PAX_RAND_FLAGS(mm) ? 0UL : ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
19910 ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
19912 MAJOR(dev), MINOR(dev), ino, &len);
19915 @@ -229,16 +255,16 @@ static void show_map_vma(struct seq_file
19918 pad_len_spaces(m, len);
19919 - seq_path(m, &file->f_path, "\n");
19920 + seq_path(m, &file->f_path, "\n\\");
19922 const char *name = arch_vma_name(vma);
19925 - if (vma->vm_start <= mm->start_brk &&
19926 - vma->vm_end >= mm->brk) {
19927 + if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
19929 - } else if (vma->vm_start <= mm->start_stack &&
19930 - vma->vm_end >= mm->start_stack) {
19931 + } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
19932 + (vma->vm_start <= mm->start_stack &&
19933 + vma->vm_end >= mm->start_stack)) {
19937 @@ -381,9 +407,16 @@ static int show_smap(struct seq_file *m,
19940 memset(&mss, 0, sizeof mss);
19942 - if (vma->vm_mm && !is_vm_hugetlb_page(vma))
19943 - walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
19945 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19946 + if (!PAX_RAND_FLAGS(vma->vm_mm)) {
19949 + if (vma->vm_mm && !is_vm_hugetlb_page(vma))
19950 + walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
19951 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19955 show_map_vma(m, vma);
19957 @@ -399,7 +432,11 @@ static int show_smap(struct seq_file *m,
19959 "KernelPageSize: %8lu kB\n"
19960 "MMUPageSize: %8lu kB\n",
19961 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19962 + PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
19964 (vma->vm_end - vma->vm_start) >> 10,
19966 mss.resident >> 10,
19967 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
19968 mss.shared_clean >> 10,
19969 diff -urNp linux-2.6.29/fs/proc/task_nommu.c linux-2.6.29/fs/proc/task_nommu.c
19970 --- linux-2.6.29/fs/proc/task_nommu.c 2009-03-23 19:12:14.000000000 -0400
19971 +++ linux-2.6.29/fs/proc/task_nommu.c 2009-03-28 14:26:20.000000000 -0400
19972 @@ -151,7 +151,7 @@ static int nommu_vma_show(struct seq_fil
19975 seq_printf(m, "%*c", len, ' ');
19976 - seq_path(m, &file->f_path, "");
19977 + seq_path(m, &file->f_path, "\n\\");
19981 diff -urNp linux-2.6.29/fs/readdir.c linux-2.6.29/fs/readdir.c
19982 --- linux-2.6.29/fs/readdir.c 2009-03-23 19:12:14.000000000 -0400
19983 +++ linux-2.6.29/fs/readdir.c 2009-03-28 14:26:20.000000000 -0400
19985 #include <linux/security.h>
19986 #include <linux/syscalls.h>
19987 #include <linux/unistd.h>
19988 +#include <linux/namei.h>
19990 #include <asm/uaccess.h>
19992 @@ -67,6 +68,7 @@ struct old_linux_dirent {
19994 struct readdir_callback {
19995 struct old_linux_dirent __user * dirent;
19996 + struct file * file;
20000 @@ -84,6 +86,10 @@ static int fillonedir(void * __buf, cons
20001 buf->result = -EOVERFLOW;
20005 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
20009 dirent = buf->dirent;
20010 if (!access_ok(VERIFY_WRITE, dirent,
20011 @@ -116,6 +122,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned in
20014 buf.dirent = dirent;
20017 error = vfs_readdir(file, fillonedir, &buf);
20019 @@ -142,6 +149,7 @@ struct linux_dirent {
20020 struct getdents_callback {
20021 struct linux_dirent __user * current_dir;
20022 struct linux_dirent __user * previous;
20023 + struct file * file;
20027 @@ -162,6 +170,10 @@ static int filldir(void * __buf, const c
20028 buf->error = -EOVERFLOW;
20032 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
20035 dirent = buf->previous;
20037 if (__put_user(offset, &dirent->d_off))
20038 @@ -209,6 +221,7 @@ SYSCALL_DEFINE3(getdents, unsigned int,
20039 buf.previous = NULL;
20044 error = vfs_readdir(file, filldir, &buf);
20046 @@ -228,6 +241,7 @@ out:
20047 struct getdents_callback64 {
20048 struct linux_dirent64 __user * current_dir;
20049 struct linux_dirent64 __user * previous;
20050 + struct file *file;
20054 @@ -242,6 +256,10 @@ static int filldir64(void * __buf, const
20055 buf->error = -EINVAL; /* only used if we fail.. */
20056 if (reclen > buf->count)
20059 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
20062 dirent = buf->previous;
20064 if (__put_user(offset, &dirent->d_off))
20065 @@ -289,6 +307,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int
20067 buf.current_dir = dirent;
20068 buf.previous = NULL;
20073 diff -urNp linux-2.6.29/fs/select.c linux-2.6.29/fs/select.c
20074 --- linux-2.6.29/fs/select.c 2009-03-23 19:12:14.000000000 -0400
20075 +++ linux-2.6.29/fs/select.c 2009-03-28 14:26:20.000000000 -0400
20077 #include <linux/module.h>
20078 #include <linux/slab.h>
20079 #include <linux/poll.h>
20080 +#include <linux/security.h>
20081 #include <linux/personality.h> /* for STICKY_TIMEOUTS */
20082 #include <linux/file.h>
20083 #include <linux/fdtable.h>
20084 @@ -781,6 +782,7 @@ int do_sys_poll(struct pollfd __user *uf
20085 struct poll_list *walk = head;
20086 unsigned long todo = nfds;
20088 + gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
20089 if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
20092 diff -urNp linux-2.6.29/fs/smbfs/symlink.c linux-2.6.29/fs/smbfs/symlink.c
20093 --- linux-2.6.29/fs/smbfs/symlink.c 2009-03-23 19:12:14.000000000 -0400
20094 +++ linux-2.6.29/fs/smbfs/symlink.c 2009-03-28 14:26:20.000000000 -0400
20095 @@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
20097 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
20099 - char *s = nd_get_link(nd);
20100 + const char *s = nd_get_link(nd);
20104 diff -urNp linux-2.6.29/fs/sysfs/symlink.c linux-2.6.29/fs/sysfs/symlink.c
20105 --- linux-2.6.29/fs/sysfs/symlink.c 2009-03-23 19:12:14.000000000 -0400
20106 +++ linux-2.6.29/fs/sysfs/symlink.c 2009-03-28 14:26:20.000000000 -0400
20107 @@ -200,7 +200,7 @@ static void *sysfs_follow_link(struct de
20109 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
20111 - char *page = nd_get_link(nd);
20112 + const char *page = nd_get_link(nd);
20114 free_page((unsigned long)page);
20116 diff -urNp linux-2.6.29/fs/udf/balloc.c linux-2.6.29/fs/udf/balloc.c
20117 --- linux-2.6.29/fs/udf/balloc.c 2009-03-23 19:12:14.000000000 -0400
20118 +++ linux-2.6.29/fs/udf/balloc.c 2009-03-28 14:26:20.000000000 -0400
20119 @@ -169,9 +169,7 @@ static void udf_bitmap_free_blocks(struc
20120 unsigned long overflow;
20122 mutex_lock(&sbi->s_alloc_mutex);
20123 - if (bloc.logicalBlockNum < 0 ||
20124 - (bloc.logicalBlockNum + count) >
20125 - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
20126 + if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
20127 udf_debug("%d < %d || %d + %d > %d\n",
20128 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
20129 sbi->s_partmaps[bloc.partitionReferenceNum].
20130 @@ -239,7 +237,7 @@ static int udf_bitmap_prealloc_blocks(st
20132 mutex_lock(&sbi->s_alloc_mutex);
20133 part_len = sbi->s_partmaps[partition].s_partition_len;
20134 - if (first_block < 0 || first_block >= part_len)
20135 + if (first_block >= part_len)
20138 if (first_block + block_count > part_len)
20139 @@ -300,7 +298,7 @@ static int udf_bitmap_new_block(struct s
20140 mutex_lock(&sbi->s_alloc_mutex);
20143 - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
20144 + if (goal >= sbi->s_partmaps[partition].s_partition_len)
20147 nr_groups = bitmap->s_nr_groups;
20148 @@ -438,9 +436,7 @@ static void udf_table_free_blocks(struct
20149 struct udf_inode_info *iinfo;
20151 mutex_lock(&sbi->s_alloc_mutex);
20152 - if (bloc.logicalBlockNum < 0 ||
20153 - (bloc.logicalBlockNum + count) >
20154 - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
20155 + if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
20156 udf_debug("%d < %d || %d + %d > %d\n",
20157 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
20158 sbi->s_partmaps[bloc.partitionReferenceNum].
20159 @@ -671,8 +667,7 @@ static int udf_table_prealloc_blocks(str
20161 struct udf_inode_info *iinfo;
20163 - if (first_block < 0 ||
20164 - first_block >= sbi->s_partmaps[partition].s_partition_len)
20165 + if (first_block >= sbi->s_partmaps[partition].s_partition_len)
20168 iinfo = UDF_I(table);
20169 @@ -750,7 +745,7 @@ static int udf_table_new_block(struct su
20172 mutex_lock(&sbi->s_alloc_mutex);
20173 - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
20174 + if (goal >= sbi->s_partmaps[partition].s_partition_len)
20177 /* We search for the closest matching block to goal. If we find
20178 diff -urNp linux-2.6.29/fs/ufs/inode.c linux-2.6.29/fs/ufs/inode.c
20179 --- linux-2.6.29/fs/ufs/inode.c 2009-03-23 19:12:14.000000000 -0400
20180 +++ linux-2.6.29/fs/ufs/inode.c 2009-03-28 14:26:20.000000000 -0400
20181 @@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
20184 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
20185 - if (i_block < 0) {
20186 - ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
20187 - } else if (i_block < direct_blocks) {
20188 + if (i_block < direct_blocks) {
20189 offsets[n++] = i_block;
20190 } else if ((i_block -= direct_blocks) < indirect_blocks) {
20191 offsets[n++] = UFS_IND_BLOCK;
20192 @@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
20195 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
20196 - if (fragment < 0)
20197 - goto abort_negative;
20199 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
20200 << uspi->s_fpbshift))
20201 @@ -504,10 +500,6 @@ abort:
20206 - ufs_warning(sb, "ufs_get_block", "block < 0");
20210 ufs_warning(sb, "ufs_get_block", "block > big");
20212 diff -urNp linux-2.6.29/fs/utimes.c linux-2.6.29/fs/utimes.c
20213 --- linux-2.6.29/fs/utimes.c 2009-03-23 19:12:14.000000000 -0400
20214 +++ linux-2.6.29/fs/utimes.c 2009-03-28 14:26:20.000000000 -0400
20216 #include <linux/compiler.h>
20217 #include <linux/file.h>
20218 #include <linux/fs.h>
20219 +#include <linux/security.h>
20220 #include <linux/linkage.h>
20221 #include <linux/mount.h>
20222 #include <linux/namei.h>
20223 @@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
20224 goto mnt_drop_write_and_out;
20228 + if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
20230 + goto mnt_drop_write_and_out;
20233 mutex_lock(&inode->i_mutex);
20234 error = notify_change(path->dentry, &newattrs);
20235 mutex_unlock(&inode->i_mutex);
20236 diff -urNp linux-2.6.29/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.29/fs/xfs/linux-2.6/xfs_iops.c
20237 --- linux-2.6.29/fs/xfs/linux-2.6/xfs_iops.c 2009-03-23 19:12:14.000000000 -0400
20238 +++ linux-2.6.29/fs/xfs/linux-2.6/xfs_iops.c 2009-03-28 14:26:20.000000000 -0400
20239 @@ -494,7 +494,7 @@ xfs_vn_put_link(
20240 struct nameidata *nd,
20243 - char *s = nd_get_link(nd);
20244 + const char *s = nd_get_link(nd);
20248 diff -urNp linux-2.6.29/fs/xfs/xfs_bmap.c linux-2.6.29/fs/xfs/xfs_bmap.c
20249 --- linux-2.6.29/fs/xfs/xfs_bmap.c 2009-03-23 19:12:14.000000000 -0400
20250 +++ linux-2.6.29/fs/xfs/xfs_bmap.c 2009-03-28 14:26:20.000000000 -0400
20251 @@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
20255 -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
20256 +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
20259 #if defined(XFS_RW_TRACE)
20260 diff -urNp linux-2.6.29/grsecurity/gracl_alloc.c linux-2.6.29/grsecurity/gracl_alloc.c
20261 --- linux-2.6.29/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
20262 +++ linux-2.6.29/grsecurity/gracl_alloc.c 2009-03-28 14:26:20.000000000 -0400
20264 +#include <linux/kernel.h>
20265 +#include <linux/mm.h>
20266 +#include <linux/slab.h>
20267 +#include <linux/vmalloc.h>
20268 +#include <linux/gracl.h>
20269 +#include <linux/grsecurity.h>
20271 +static unsigned long alloc_stack_next = 1;
20272 +static unsigned long alloc_stack_size = 1;
20273 +static void **alloc_stack;
20275 +static __inline__ int
20278 + if (alloc_stack_next == 1)
20281 + kfree(alloc_stack[alloc_stack_next - 2]);
20283 + alloc_stack_next--;
20288 +static __inline__ void
20289 +alloc_push(void *buf)
20291 + if (alloc_stack_next >= alloc_stack_size)
20294 + alloc_stack[alloc_stack_next - 1] = buf;
20296 + alloc_stack_next++;
20302 +acl_alloc(unsigned long len)
20306 + if (len > PAGE_SIZE)
20309 + ret = kmalloc(len, GFP_KERNEL);
20318 +acl_free_all(void)
20320 + if (gr_acl_is_enabled() || !alloc_stack)
20323 + while (alloc_pop()) ;
20325 + if (alloc_stack) {
20326 + if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
20327 + kfree(alloc_stack);
20329 + vfree(alloc_stack);
20332 + alloc_stack = NULL;
20333 + alloc_stack_size = 1;
20334 + alloc_stack_next = 1;
20340 +acl_alloc_stack_init(unsigned long size)
20342 + if ((size * sizeof (void *)) <= PAGE_SIZE)
20344 + (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
20346 + alloc_stack = (void **) vmalloc(size * sizeof (void *));
20348 + alloc_stack_size = size;
20350 + if (!alloc_stack)
20355 diff -urNp linux-2.6.29/grsecurity/gracl.c linux-2.6.29/grsecurity/gracl.c
20356 --- linux-2.6.29/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
20357 +++ linux-2.6.29/grsecurity/gracl.c 2009-03-28 14:26:20.000000000 -0400
20359 +#include <linux/kernel.h>
20360 +#include <linux/module.h>
20361 +#include <linux/sched.h>
20362 +#include <linux/mm.h>
20363 +#include <linux/file.h>
20364 +#include <linux/fs.h>
20365 +#include <linux/namei.h>
20366 +#include <linux/mount.h>
20367 +#include <linux/tty.h>
20368 +#include <linux/proc_fs.h>
20369 +#include <linux/smp_lock.h>
20370 +#include <linux/slab.h>
20371 +#include <linux/vmalloc.h>
20372 +#include <linux/types.h>
20373 +#include <linux/sysctl.h>
20374 +#include <linux/netdevice.h>
20375 +#include <linux/ptrace.h>
20376 +#include <linux/gracl.h>
20377 +#include <linux/gralloc.h>
20378 +#include <linux/grsecurity.h>
20379 +#include <linux/grinternal.h>
20380 +#include <linux/pid_namespace.h>
20381 +#include <linux/fdtable.h>
20382 +#include <linux/percpu.h>
20384 +#include <asm/uaccess.h>
20385 +#include <asm/errno.h>
20386 +#include <asm/mman.h>
20388 +static struct acl_role_db acl_role_set;
20389 +static struct name_db name_set;
20390 +static struct inodev_db inodev_set;
20392 +/* for keeping track of userspace pointers used for subjects, so we
20393 + can share references in the kernel as well
20396 +static struct dentry *real_root;
20397 +static struct vfsmount *real_root_mnt;
20399 +static struct acl_subj_map_db subj_map_set;
20401 +static struct acl_role_label *default_role;
20403 +static u16 acl_sp_role_value;
20405 +extern char *gr_shared_page[4];
20406 +static DECLARE_MUTEX(gr_dev_sem);
20407 +DEFINE_RWLOCK(gr_inode_lock);
20409 +struct gr_arg *gr_usermode;
20411 +static unsigned int gr_status = GR_STATUS_INIT;
20413 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
20414 +extern void gr_clear_learn_entries(void);
20416 +#ifdef CONFIG_GRKERNSEC_RESLOG
20417 +extern void gr_log_resource(const struct task_struct *task,
20418 + const int res, const unsigned long wanted, const int gt);
20421 +unsigned char *gr_system_salt;
20422 +unsigned char *gr_system_sum;
20424 +static struct sprole_pw **acl_special_roles = NULL;
20425 +static __u16 num_sprole_pws = 0;
20427 +static struct acl_role_label *kernel_role = NULL;
20429 +static unsigned int gr_auth_attempts = 0;
20430 +static unsigned long gr_auth_expires = 0UL;
20432 +extern struct vfsmount *sock_mnt;
20433 +extern struct vfsmount *pipe_mnt;
20434 +extern struct vfsmount *shm_mnt;
20435 +static struct acl_object_label *fakefs_obj;
20437 +extern int gr_init_uidset(void);
20438 +extern void gr_free_uidset(void);
20439 +extern void gr_remove_uid(uid_t uid);
20440 +extern int gr_find_uid(uid_t uid);
20443 +gr_acl_is_enabled(void)
20445 + return (gr_status & GR_READY);
20448 +char gr_roletype_to_char(void)
20450 + switch (current->role->roletype &
20451 + (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
20452 + GR_ROLE_SPECIAL)) {
20453 + case GR_ROLE_DEFAULT:
20455 + case GR_ROLE_USER:
20457 + case GR_ROLE_GROUP:
20459 + case GR_ROLE_SPECIAL:
20467 +gr_acl_tpe_check(void)
20469 + if (unlikely(!(gr_status & GR_READY)))
20471 + if (current->role->roletype & GR_ROLE_TPE)
20478 +gr_handle_rawio(const struct inode *inode)
20480 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
20481 + if (inode && S_ISBLK(inode->i_mode) &&
20482 + grsec_enable_chroot_caps && proc_is_chrooted(current) &&
20483 + !capable(CAP_SYS_RAWIO))
20490 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
20493 + unsigned long *l1;
20494 + unsigned long *l2;
20495 + unsigned char *c1;
20496 + unsigned char *c2;
20499 + if (likely(lena != lenb))
20502 + l1 = (unsigned long *)a;
20503 + l2 = (unsigned long *)b;
20505 + num_longs = lena / sizeof(unsigned long);
20507 + for (i = num_longs; i--; l1++, l2++) {
20508 + if (unlikely(*l1 != *l2))
20512 + c1 = (unsigned char *) l1;
20513 + c2 = (unsigned char *) l2;
20515 + i = lena - (num_longs * sizeof(unsigned long));
20517 + for (; i--; c1++, c2++) {
20518 + if (unlikely(*c1 != *c2))
20525 +static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
20526 + struct dentry *root, struct vfsmount *rootmnt,
20527 + char *buffer, int buflen)
20529 + char * end = buffer+buflen;
20538 + /* Get '/' right */
20543 + struct dentry * parent;
20545 + if (dentry == root && vfsmnt == rootmnt)
20547 + if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
20548 + /* Global root? */
20549 + spin_lock(&vfsmount_lock);
20550 + if (vfsmnt->mnt_parent == vfsmnt) {
20551 + spin_unlock(&vfsmount_lock);
20552 + goto global_root;
20554 + dentry = vfsmnt->mnt_mountpoint;
20555 + vfsmnt = vfsmnt->mnt_parent;
20556 + spin_unlock(&vfsmount_lock);
20559 + parent = dentry->d_parent;
20560 + prefetch(parent);
20561 + namelen = dentry->d_name.len;
20562 + buflen -= namelen + 1;
20566 + memcpy(end, dentry->d_name.name, namelen);
20575 + namelen = dentry->d_name.len;
20576 + buflen -= namelen;
20579 + retval -= namelen-1; /* hit the slash */
20580 + memcpy(retval, dentry->d_name.name, namelen);
20583 + return ERR_PTR(-ENAMETOOLONG);
20587 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
20588 + struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
20592 + retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
20593 + if (unlikely(IS_ERR(retval)))
20594 + retval = strcpy(buf, "<path too long>");
20595 + else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
20596 + retval[1] = '\0';
20602 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
20603 + char *buf, int buflen)
20607 + /* we can use real_root, real_root_mnt, because this is only called
20608 + by the RBAC system */
20609 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
20615 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
20616 + char *buf, int buflen)
20619 + struct dentry *root;
20620 + struct vfsmount *rootmnt;
20621 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
20623 + /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
20624 + read_lock(&reaper->fs->lock);
20625 + root = dget(reaper->fs->root.dentry);
20626 + rootmnt = mntget(reaper->fs->root.mnt);
20627 + read_unlock(&reaper->fs->lock);
20629 + spin_lock(&dcache_lock);
20630 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
20631 + spin_unlock(&dcache_lock);
20639 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
20642 + spin_lock(&dcache_lock);
20643 + ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
20645 + spin_unlock(&dcache_lock);
20650 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
20652 + return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
20657 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
20659 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
20664 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
20666 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
20671 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
20673 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
20678 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
20680 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
20685 +to_gr_audit(const __u32 reqmode)
20687 + /* masks off auditable permission flags, then shifts them to create
20688 + auditing flags, and adds the special case of append auditing if
20689 + we're requesting write */
20690 + return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
20693 +struct acl_subject_label *
20694 +lookup_subject_map(const struct acl_subject_label *userp)
20696 + unsigned int index = shash(userp, subj_map_set.s_size);
20697 + struct subject_map *match;
20699 + match = subj_map_set.s_hash[index];
20701 + while (match && match->user != userp)
20702 + match = match->next;
20704 + if (match != NULL)
20705 + return match->kernel;
20711 +insert_subj_map_entry(struct subject_map *subjmap)
20713 + unsigned int index = shash(subjmap->user, subj_map_set.s_size);
20714 + struct subject_map **curr;
20716 + subjmap->prev = NULL;
20718 + curr = &subj_map_set.s_hash[index];
20719 + if (*curr != NULL)
20720 + (*curr)->prev = subjmap;
20722 + subjmap->next = *curr;
20728 +static struct acl_role_label *
20729 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
20732 + unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
20733 + struct acl_role_label *match;
20734 + struct role_allowed_ip *ipp;
20737 + match = acl_role_set.r_hash[index];
20740 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
20741 + for (x = 0; x < match->domain_child_num; x++) {
20742 + if (match->domain_children[x] == uid)
20745 + } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
20747 + match = match->next;
20750 + if (match == NULL) {
20752 + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
20753 + match = acl_role_set.r_hash[index];
20756 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
20757 + for (x = 0; x < match->domain_child_num; x++) {
20758 + if (match->domain_children[x] == gid)
20761 + } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
20763 + match = match->next;
20766 + if (match == NULL)
20767 + match = default_role;
20768 + if (match->allowed_ips == NULL)
20771 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
20773 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
20774 + (ntohl(ipp->addr) & ipp->netmask)))
20777 + match = default_role;
20779 + } else if (match->allowed_ips == NULL) {
20782 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
20784 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
20785 + (ntohl(ipp->addr) & ipp->netmask)))
20794 +struct acl_subject_label *
20795 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
20796 + const struct acl_role_label *role)
20798 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
20799 + struct acl_subject_label *match;
20801 + match = role->subj_hash[index];
20803 + while (match && (match->inode != ino || match->device != dev ||
20804 + (match->mode & GR_DELETED))) {
20805 + match = match->next;
20808 + if (match && !(match->mode & GR_DELETED))
20814 +static struct acl_object_label *
20815 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
20816 + const struct acl_subject_label *subj)
20818 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
20819 + struct acl_object_label *match;
20821 + match = subj->obj_hash[index];
20823 + while (match && (match->inode != ino || match->device != dev ||
20824 + (match->mode & GR_DELETED))) {
20825 + match = match->next;
20828 + if (match && !(match->mode & GR_DELETED))
20834 +static struct acl_object_label *
20835 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
20836 + const struct acl_subject_label *subj)
20838 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
20839 + struct acl_object_label *match;
20841 + match = subj->obj_hash[index];
20843 + while (match && (match->inode != ino || match->device != dev ||
20844 + !(match->mode & GR_DELETED))) {
20845 + match = match->next;
20848 + if (match && (match->mode & GR_DELETED))
20851 + match = subj->obj_hash[index];
20853 + while (match && (match->inode != ino || match->device != dev ||
20854 + (match->mode & GR_DELETED))) {
20855 + match = match->next;
20858 + if (match && !(match->mode & GR_DELETED))
20864 +static struct name_entry *
20865 +lookup_name_entry(const char *name)
20867 + unsigned int len = strlen(name);
20868 + unsigned int key = full_name_hash(name, len);
20869 + unsigned int index = key % name_set.n_size;
20870 + struct name_entry *match;
20872 + match = name_set.n_hash[index];
20874 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
20875 + match = match->next;
20880 +static struct name_entry *
20881 +lookup_name_entry_create(const char *name)
20883 + unsigned int len = strlen(name);
20884 + unsigned int key = full_name_hash(name, len);
20885 + unsigned int index = key % name_set.n_size;
20886 + struct name_entry *match;
20888 + match = name_set.n_hash[index];
20890 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
20891 + !match->deleted))
20892 + match = match->next;
20894 + if (match && match->deleted)
20897 + match = name_set.n_hash[index];
20899 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
20901 + match = match->next;
20903 + if (match && !match->deleted)
20909 +static struct inodev_entry *
20910 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
20912 + unsigned int index = fhash(ino, dev, inodev_set.i_size);
20913 + struct inodev_entry *match;
20915 + match = inodev_set.i_hash[index];
20917 + while (match && (match->nentry->inode != ino || match->nentry->device != dev))
20918 + match = match->next;
20924 +insert_inodev_entry(struct inodev_entry *entry)
20926 + unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
20927 + inodev_set.i_size);
20928 + struct inodev_entry **curr;
20930 + entry->prev = NULL;
20932 + curr = &inodev_set.i_hash[index];
20933 + if (*curr != NULL)
20934 + (*curr)->prev = entry;
20936 + entry->next = *curr;
20943 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
20945 + unsigned int index =
20946 + rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
20947 + struct acl_role_label **curr;
20949 + role->prev = NULL;
20951 + curr = &acl_role_set.r_hash[index];
20952 + if (*curr != NULL)
20953 + (*curr)->prev = role;
20955 + role->next = *curr;
20962 +insert_acl_role_label(struct acl_role_label *role)
20966 + if (role->roletype & GR_ROLE_DOMAIN) {
20967 + for (i = 0; i < role->domain_child_num; i++)
20968 + __insert_acl_role_label(role, role->domain_children[i]);
20970 + __insert_acl_role_label(role, role->uidgid);
20974 +insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
20976 + struct name_entry **curr, *nentry;
20977 + struct inodev_entry *ientry;
20978 + unsigned int len = strlen(name);
20979 + unsigned int key = full_name_hash(name, len);
20980 + unsigned int index = key % name_set.n_size;
20982 + curr = &name_set.n_hash[index];
20984 + while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
20985 + curr = &((*curr)->next);
20987 + if (*curr != NULL)
20990 + nentry = acl_alloc(sizeof (struct name_entry));
20991 + if (nentry == NULL)
20993 + ientry = acl_alloc(sizeof (struct inodev_entry));
20994 + if (ientry == NULL)
20996 + ientry->nentry = nentry;
20998 + nentry->key = key;
20999 + nentry->name = name;
21000 + nentry->inode = inode;
21001 + nentry->device = device;
21002 + nentry->len = len;
21003 + nentry->deleted = deleted;
21005 + nentry->prev = NULL;
21006 + curr = &name_set.n_hash[index];
21007 + if (*curr != NULL)
21008 + (*curr)->prev = nentry;
21009 + nentry->next = *curr;
21012 + /* insert us into the table searchable by inode/dev */
21013 + insert_inodev_entry(ientry);
21019 +insert_acl_obj_label(struct acl_object_label *obj,
21020 + struct acl_subject_label *subj)
21022 + unsigned int index =
21023 + fhash(obj->inode, obj->device, subj->obj_hash_size);
21024 + struct acl_object_label **curr;
21027 + obj->prev = NULL;
21029 + curr = &subj->obj_hash[index];
21030 + if (*curr != NULL)
21031 + (*curr)->prev = obj;
21033 + obj->next = *curr;
21040 +insert_acl_subj_label(struct acl_subject_label *obj,
21041 + struct acl_role_label *role)
21043 + unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
21044 + struct acl_subject_label **curr;
21046 + obj->prev = NULL;
21048 + curr = &role->subj_hash[index];
21049 + if (*curr != NULL)
21050 + (*curr)->prev = obj;
21052 + obj->next = *curr;
21058 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
21061 +create_table(__u32 * len, int elementsize)
21063 + unsigned int table_sizes[] = {
21064 + 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
21065 + 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
21066 + 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
21067 + 268435399, 536870909, 1073741789, 2147483647
21069 + void *newtable = NULL;
21070 + unsigned int pwr = 0;
21072 + while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
21073 + table_sizes[pwr] <= *len)
21076 + if (table_sizes[pwr] <= *len)
21079 + if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
21081 + kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
21083 + newtable = vmalloc(table_sizes[pwr] * elementsize);
21085 + *len = table_sizes[pwr];
21091 +init_variables(const struct gr_arg *arg)
21093 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
21094 + unsigned int stacksize;
21096 + subj_map_set.s_size = arg->role_db.num_subjects;
21097 + acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
21098 + name_set.n_size = arg->role_db.num_objects;
21099 + inodev_set.i_size = arg->role_db.num_objects;
21101 + if (!subj_map_set.s_size || !acl_role_set.r_size ||
21102 + !name_set.n_size || !inodev_set.i_size)
21105 + if (!gr_init_uidset())
21108 + /* set up the stack that holds allocation info */
21110 + stacksize = arg->role_db.num_pointers + 5;
21112 + if (!acl_alloc_stack_init(stacksize))
21115 + /* grab reference for the real root dentry and vfsmount */
21116 + read_lock(&reaper->fs->lock);
21117 + real_root_mnt = mntget(reaper->fs->root.mnt);
21118 + real_root = dget(reaper->fs->root.dentry);
21119 + read_unlock(&reaper->fs->lock);
21121 + fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
21122 + if (fakefs_obj == NULL)
21124 + fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
21126 + subj_map_set.s_hash =
21127 + (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
21128 + acl_role_set.r_hash =
21129 + (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
21130 + name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
21131 + inodev_set.i_hash =
21132 + (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
21134 + if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
21135 + !name_set.n_hash || !inodev_set.i_hash)
21138 + memset(subj_map_set.s_hash, 0,
21139 + sizeof(struct subject_map *) * subj_map_set.s_size);
21140 + memset(acl_role_set.r_hash, 0,
21141 + sizeof (struct acl_role_label *) * acl_role_set.r_size);
21142 + memset(name_set.n_hash, 0,
21143 + sizeof (struct name_entry *) * name_set.n_size);
21144 + memset(inodev_set.i_hash, 0,
21145 + sizeof (struct inodev_entry *) * inodev_set.i_size);
21150 +/* free information not needed after startup
21151 + currently contains user->kernel pointer mappings for subjects
21155 +free_init_variables(void)
21159 + if (subj_map_set.s_hash) {
21160 + for (i = 0; i < subj_map_set.s_size; i++) {
21161 + if (subj_map_set.s_hash[i]) {
21162 + kfree(subj_map_set.s_hash[i]);
21163 + subj_map_set.s_hash[i] = NULL;
21167 + if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
21169 + kfree(subj_map_set.s_hash);
21171 + vfree(subj_map_set.s_hash);
21178 +free_variables(void)
21180 + struct acl_subject_label *s;
21181 + struct acl_role_label *r;
21182 + struct task_struct *task, *task2;
21183 + unsigned int i, x;
21185 + gr_clear_learn_entries();
21187 + read_lock(&tasklist_lock);
21188 + do_each_thread(task2, task) {
21189 + task->acl_sp_role = 0;
21190 + task->acl_role_id = 0;
21191 + task->acl = NULL;
21192 + task->role = NULL;
21193 + } while_each_thread(task2, task);
21194 + read_unlock(&tasklist_lock);
21196 + /* release the reference to the real root dentry and vfsmount */
21199 + real_root = NULL;
21200 + if (real_root_mnt)
21201 + mntput(real_root_mnt);
21202 + real_root_mnt = NULL;
21204 + /* free all object hash tables */
21206 + FOR_EACH_ROLE_START(r, i)
21207 + if (r->subj_hash == NULL)
21209 + FOR_EACH_SUBJECT_START(r, s, x)
21210 + if (s->obj_hash == NULL)
21212 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
21213 + kfree(s->obj_hash);
21215 + vfree(s->obj_hash);
21216 + FOR_EACH_SUBJECT_END(s, x)
21217 + FOR_EACH_NESTED_SUBJECT_START(r, s)
21218 + if (s->obj_hash == NULL)
21220 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
21221 + kfree(s->obj_hash);
21223 + vfree(s->obj_hash);
21224 + FOR_EACH_NESTED_SUBJECT_END(s)
21225 + if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
21226 + kfree(r->subj_hash);
21228 + vfree(r->subj_hash);
21229 + r->subj_hash = NULL;
21230 + FOR_EACH_ROLE_END(r,i)
21234 + if (acl_role_set.r_hash) {
21235 + if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
21237 + kfree(acl_role_set.r_hash);
21239 + vfree(acl_role_set.r_hash);
21241 + if (name_set.n_hash) {
21242 + if ((name_set.n_size * sizeof (struct name_entry *)) <=
21244 + kfree(name_set.n_hash);
21246 + vfree(name_set.n_hash);
21249 + if (inodev_set.i_hash) {
21250 + if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
21252 + kfree(inodev_set.i_hash);
21254 + vfree(inodev_set.i_hash);
21257 + gr_free_uidset();
21259 + memset(&name_set, 0, sizeof (struct name_db));
21260 + memset(&inodev_set, 0, sizeof (struct inodev_db));
21261 + memset(&acl_role_set, 0, sizeof (struct acl_role_db));
21262 + memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
21264 + default_role = NULL;
21270 +count_user_objs(struct acl_object_label *userp)
21272 + struct acl_object_label o_tmp;
21276 + if (copy_from_user(&o_tmp, userp,
21277 + sizeof (struct acl_object_label)))
21280 + userp = o_tmp.prev;
21287 +static struct acl_subject_label *
21288 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
21291 +copy_user_glob(struct acl_object_label *obj)
21293 + struct acl_object_label *g_tmp, **guser;
21294 + unsigned int len;
21297 + if (obj->globbed == NULL)
21300 + guser = &obj->globbed;
21302 + g_tmp = (struct acl_object_label *)
21303 + acl_alloc(sizeof (struct acl_object_label));
21304 + if (g_tmp == NULL)
21307 + if (copy_from_user(g_tmp, *guser,
21308 + sizeof (struct acl_object_label)))
21311 + len = strnlen_user(g_tmp->filename, PATH_MAX);
21313 + if (!len || len >= PATH_MAX)
21316 + if ((tmp = (char *) acl_alloc(len)) == NULL)
21319 + if (copy_from_user(tmp, g_tmp->filename, len))
21322 + g_tmp->filename = tmp;
21325 + guser = &(g_tmp->next);
21332 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
21333 + struct acl_role_label *role)
21335 + struct acl_object_label *o_tmp;
21336 + unsigned int len;
21341 + if ((o_tmp = (struct acl_object_label *)
21342 + acl_alloc(sizeof (struct acl_object_label))) == NULL)
21345 + if (copy_from_user(o_tmp, userp,
21346 + sizeof (struct acl_object_label)))
21349 + userp = o_tmp->prev;
21351 + len = strnlen_user(o_tmp->filename, PATH_MAX);
21353 + if (!len || len >= PATH_MAX)
21356 + if ((tmp = (char *) acl_alloc(len)) == NULL)
21359 + if (copy_from_user(tmp, o_tmp->filename, len))
21362 + o_tmp->filename = tmp;
21364 + insert_acl_obj_label(o_tmp, subj);
21365 + if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
21366 + o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
21369 + ret = copy_user_glob(o_tmp);
21373 + if (o_tmp->nested) {
21374 + o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
21375 + if (IS_ERR(o_tmp->nested))
21376 + return PTR_ERR(o_tmp->nested);
21378 + /* insert into nested subject list */
21379 + o_tmp->nested->next = role->hash->first;
21380 + role->hash->first = o_tmp->nested;
21388 +count_user_subjs(struct acl_subject_label *userp)
21390 + struct acl_subject_label s_tmp;
21394 + if (copy_from_user(&s_tmp, userp,
21395 + sizeof (struct acl_subject_label)))
21398 + userp = s_tmp.prev;
21399 + /* do not count nested subjects against this count, since
21400 + they are not included in the hash table, but are
21401 + attached to objects. We have already counted
21402 + the subjects in userspace for the allocation
21405 + if (!(s_tmp.mode & GR_NESTED))
21413 +copy_user_allowedips(struct acl_role_label *rolep)
21415 + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
21417 + ruserip = rolep->allowed_ips;
21419 + while (ruserip) {
21422 + if ((rtmp = (struct role_allowed_ip *)
21423 + acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
21426 + if (copy_from_user(rtmp, ruserip,
21427 + sizeof (struct role_allowed_ip)))
21430 + ruserip = rtmp->prev;
21433 + rtmp->prev = NULL;
21434 + rolep->allowed_ips = rtmp;
21436 + rlast->next = rtmp;
21437 + rtmp->prev = rlast;
21441 + rtmp->next = NULL;
21448 +copy_user_transitions(struct acl_role_label *rolep)
21450 + struct role_transition *rusertp, *rtmp = NULL, *rlast;
21452 + unsigned int len;
21455 + rusertp = rolep->transitions;
21457 + while (rusertp) {
21460 + if ((rtmp = (struct role_transition *)
21461 + acl_alloc(sizeof (struct role_transition))) == NULL)
21464 + if (copy_from_user(rtmp, rusertp,
21465 + sizeof (struct role_transition)))
21468 + rusertp = rtmp->prev;
21470 + len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
21472 + if (!len || len >= GR_SPROLE_LEN)
21475 + if ((tmp = (char *) acl_alloc(len)) == NULL)
21478 + if (copy_from_user(tmp, rtmp->rolename, len))
21481 + rtmp->rolename = tmp;
21484 + rtmp->prev = NULL;
21485 + rolep->transitions = rtmp;
21487 + rlast->next = rtmp;
21488 + rtmp->prev = rlast;
21492 + rtmp->next = NULL;
21498 +static struct acl_subject_label *
21499 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
21501 + struct acl_subject_label *s_tmp = NULL, *s_tmp2;
21502 + unsigned int len;
21505 + struct acl_ip_label **i_tmp, *i_utmp2;
21506 + struct gr_hash_struct ghash;
21507 + struct subject_map *subjmap;
21508 + unsigned int i_num;
21511 + s_tmp = lookup_subject_map(userp);
21513 + /* we've already copied this subject into the kernel, just return
21514 + the reference to it, and don't copy it over again
21519 + if ((s_tmp = (struct acl_subject_label *)
21520 + acl_alloc(sizeof (struct acl_subject_label))) == NULL)
21521 + return ERR_PTR(-ENOMEM);
21523 + subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
21524 + if (subjmap == NULL)
21525 + return ERR_PTR(-ENOMEM);
21527 + subjmap->user = userp;
21528 + subjmap->kernel = s_tmp;
21529 + insert_subj_map_entry(subjmap);
21531 + if (copy_from_user(s_tmp, userp,
21532 + sizeof (struct acl_subject_label)))
21533 + return ERR_PTR(-EFAULT);
21535 + len = strnlen_user(s_tmp->filename, PATH_MAX);
21537 + if (!len || len >= PATH_MAX)
21538 + return ERR_PTR(-EINVAL);
21540 + if ((tmp = (char *) acl_alloc(len)) == NULL)
21541 + return ERR_PTR(-ENOMEM);
21543 + if (copy_from_user(tmp, s_tmp->filename, len))
21544 + return ERR_PTR(-EFAULT);
21546 + s_tmp->filename = tmp;
21548 + if (!strcmp(s_tmp->filename, "/"))
21549 + role->root_label = s_tmp;
21551 + if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
21552 + return ERR_PTR(-EFAULT);
21554 + /* copy user and group transition tables */
21556 + if (s_tmp->user_trans_num) {
21559 + uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
21560 + if (uidlist == NULL)
21561 + return ERR_PTR(-ENOMEM);
21562 + if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
21563 + return ERR_PTR(-EFAULT);
21565 + s_tmp->user_transitions = uidlist;
21568 + if (s_tmp->group_trans_num) {
21571 + gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
21572 + if (gidlist == NULL)
21573 + return ERR_PTR(-ENOMEM);
21574 + if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
21575 + return ERR_PTR(-EFAULT);
21577 + s_tmp->group_transitions = gidlist;
21580 + /* set up object hash table */
21581 + num_objs = count_user_objs(ghash.first);
21583 + s_tmp->obj_hash_size = num_objs;
21584 + s_tmp->obj_hash =
21585 + (struct acl_object_label **)
21586 + create_table(&(s_tmp->obj_hash_size), sizeof(void *));
21588 + if (!s_tmp->obj_hash)
21589 + return ERR_PTR(-ENOMEM);
21591 + memset(s_tmp->obj_hash, 0,
21592 + s_tmp->obj_hash_size *
21593 + sizeof (struct acl_object_label *));
21595 + /* add in objects */
21596 + err = copy_user_objs(ghash.first, s_tmp, role);
21599 + return ERR_PTR(err);
21601 + /* set pointer for parent subject */
21602 + if (s_tmp->parent_subject) {
21603 + s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
21605 + if (IS_ERR(s_tmp2))
21608 + s_tmp->parent_subject = s_tmp2;
21611 + /* add in ip acls */
21613 + if (!s_tmp->ip_num) {
21614 + s_tmp->ips = NULL;
21619 + (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
21621 + acl_ip_label *));
21624 + return ERR_PTR(-ENOMEM);
21626 + for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
21627 + *(i_tmp + i_num) =
21628 + (struct acl_ip_label *)
21629 + acl_alloc(sizeof (struct acl_ip_label));
21630 + if (!*(i_tmp + i_num))
21631 + return ERR_PTR(-ENOMEM);
21633 + if (copy_from_user
21634 + (&i_utmp2, s_tmp->ips + i_num,
21635 + sizeof (struct acl_ip_label *)))
21636 + return ERR_PTR(-EFAULT);
21638 + if (copy_from_user
21639 + (*(i_tmp + i_num), i_utmp2,
21640 + sizeof (struct acl_ip_label)))
21641 + return ERR_PTR(-EFAULT);
21643 + if ((*(i_tmp + i_num))->iface == NULL)
21646 + len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
21647 + if (!len || len >= IFNAMSIZ)
21648 + return ERR_PTR(-EINVAL);
21649 + tmp = acl_alloc(len);
21651 + return ERR_PTR(-ENOMEM);
21652 + if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
21653 + return ERR_PTR(-EFAULT);
21654 + (*(i_tmp + i_num))->iface = tmp;
21657 + s_tmp->ips = i_tmp;
21660 + if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
21661 + s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
21662 + return ERR_PTR(-ENOMEM);
21668 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
21670 + struct acl_subject_label s_pre;
21671 + struct acl_subject_label * ret;
21675 + if (copy_from_user(&s_pre, userp,
21676 + sizeof (struct acl_subject_label)))
21679 + /* do not add nested subjects here, add
21680 + while parsing objects
21683 + if (s_pre.mode & GR_NESTED) {
21684 + userp = s_pre.prev;
21688 + ret = do_copy_user_subj(userp, role);
21690 + err = PTR_ERR(ret);
21694 + insert_acl_subj_label(ret, role);
21696 + userp = s_pre.prev;
21703 +copy_user_acl(struct gr_arg *arg)
21705 + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
21706 + struct sprole_pw *sptmp;
21707 + struct gr_hash_struct *ghash;
21708 + uid_t *domainlist;
21709 + unsigned int r_num;
21710 + unsigned int len;
21716 + /* we need a default and kernel role */
21717 + if (arg->role_db.num_roles < 2)
21720 + /* copy special role authentication info from userspace */
21722 + num_sprole_pws = arg->num_sprole_pws;
21723 + acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
21725 + if (!acl_special_roles) {
21730 + for (i = 0; i < num_sprole_pws; i++) {
21731 + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
21736 + if (copy_from_user(sptmp, arg->sprole_pws + i,
21737 + sizeof (struct sprole_pw))) {
21743 + strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
21745 + if (!len || len >= GR_SPROLE_LEN) {
21750 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
21755 + if (copy_from_user(tmp, sptmp->rolename, len)) {
21760 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
21761 + printk(KERN_ALERT "Copying special role %s\n", tmp);
21763 + sptmp->rolename = tmp;
21764 + acl_special_roles[i] = sptmp;
21767 + r_utmp = (struct acl_role_label **) arg->role_db.r_table;
21769 + for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
21770 + r_tmp = acl_alloc(sizeof (struct acl_role_label));
21777 + if (copy_from_user(&r_utmp2, r_utmp + r_num,
21778 + sizeof (struct acl_role_label *))) {
21783 + if (copy_from_user(r_tmp, r_utmp2,
21784 + sizeof (struct acl_role_label))) {
21789 + len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
21791 + if (!len || len >= PATH_MAX) {
21796 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
21800 + if (copy_from_user(tmp, r_tmp->rolename, len)) {
21804 + r_tmp->rolename = tmp;
21806 + if (!strcmp(r_tmp->rolename, "default")
21807 + && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
21808 + default_role = r_tmp;
21809 + } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
21810 + kernel_role = r_tmp;
21813 + if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
21817 + if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
21822 + r_tmp->hash = ghash;
21824 + num_subjs = count_user_subjs(r_tmp->hash->first);
21826 + r_tmp->subj_hash_size = num_subjs;
21827 + r_tmp->subj_hash =
21828 + (struct acl_subject_label **)
21829 + create_table(&(r_tmp->subj_hash_size), sizeof(void *));
21831 + if (!r_tmp->subj_hash) {
21836 + err = copy_user_allowedips(r_tmp);
21840 + /* copy domain info */
21841 + if (r_tmp->domain_children != NULL) {
21842 + domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
21843 + if (domainlist == NULL) {
21847 + if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
21851 + r_tmp->domain_children = domainlist;
21854 + err = copy_user_transitions(r_tmp);
21858 + memset(r_tmp->subj_hash, 0,
21859 + r_tmp->subj_hash_size *
21860 + sizeof (struct acl_subject_label *));
21862 + err = copy_user_subjs(r_tmp->hash->first, r_tmp);
21867 + /* set nested subject list to null */
21868 + r_tmp->hash->first = NULL;
21870 + insert_acl_role_label(r_tmp);
21875 + free_variables();
21882 +gracl_init(struct gr_arg *args)
21886 + memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
21887 + memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
21889 + if (init_variables(args)) {
21890 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
21892 + free_variables();
21896 + error = copy_user_acl(args);
21897 + free_init_variables();
21899 + free_variables();
21903 + if ((error = gr_set_acls(0))) {
21904 + free_variables();
21908 + gr_status |= GR_READY;
21913 +/* derived from glibc fnmatch() 0: match, 1: no match*/
21916 +glob_match(const char *p, const char *n)
21920 + while ((c = *p++) != '\0') {
21925 + else if (*n == '/')
21933 + for (c = *p++; c == '?' || c == '*'; c = *p++) {
21936 + else if (c == '?') {
21946 + const char *endp;
21948 + if ((endp = strchr(n, '/')) == NULL)
21949 + endp = n + strlen(n);
21952 + for (--p; n < endp; ++n)
21953 + if (!glob_match(p, n))
21955 + } else if (c == '/') {
21956 + while (*n != '\0' && *n != '/')
21958 + if (*n == '/' && !glob_match(p, n + 1))
21961 + for (--p; n < endp; ++n)
21962 + if (*n == c && !glob_match(p, n))
21973 + if (*n == '\0' || *n == '/')
21976 + not = (*p == '!' || *p == '^');
21982 + unsigned char fn = (unsigned char)*n;
21992 + if (c == '-' && *p != ']') {
21993 + unsigned char cend = *p++;
21995 + if (cend == '\0')
21998 + if (cold <= fn && fn <= cend)
22012 + while (c != ']') {
22039 +static struct acl_object_label *
22040 +chk_glob_label(struct acl_object_label *globbed,
22041 + struct dentry *dentry, struct vfsmount *mnt, char **path)
22043 + struct acl_object_label *tmp;
22045 + if (*path == NULL)
22046 + *path = gr_to_filename_nolock(dentry, mnt);
22051 + if (!glob_match(tmp->filename, *path))
22059 +static struct acl_object_label *
22060 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
22061 + const ino_t curr_ino, const dev_t curr_dev,
22062 + const struct acl_subject_label *subj, char **path)
22064 + struct acl_subject_label *tmpsubj;
22065 + struct acl_object_label *retval;
22066 + struct acl_object_label *retval2;
22068 + tmpsubj = (struct acl_subject_label *) subj;
22069 + read_lock(&gr_inode_lock);
22071 + retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
22073 + if (retval->globbed) {
22074 + retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
22075 + (struct vfsmount *)orig_mnt, path);
22077 + retval = retval2;
22081 + } while ((tmpsubj = tmpsubj->parent_subject));
22082 + read_unlock(&gr_inode_lock);
22087 +static __inline__ struct acl_object_label *
22088 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
22089 + const struct dentry *curr_dentry,
22090 + const struct acl_subject_label *subj, char **path)
22092 + return __full_lookup(orig_dentry, orig_mnt,
22093 + curr_dentry->d_inode->i_ino,
22094 + curr_dentry->d_inode->i_sb->s_dev, subj, path);
22097 +static struct acl_object_label *
22098 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
22099 + const struct acl_subject_label *subj, char *path)
22101 + struct dentry *dentry = (struct dentry *) l_dentry;
22102 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
22103 + struct acl_object_label *retval;
22105 + spin_lock(&dcache_lock);
22107 + if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
22108 + /* ignore Eric Biederman */
22109 + IS_PRIVATE(l_dentry->d_inode))) {
22110 + retval = fakefs_obj;
22115 + if (dentry == real_root && mnt == real_root_mnt)
22118 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
22119 + if (mnt->mnt_parent == mnt)
22122 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
22123 + if (retval != NULL)
22126 + dentry = mnt->mnt_mountpoint;
22127 + mnt = mnt->mnt_parent;
22131 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
22132 + if (retval != NULL)
22135 + dentry = dentry->d_parent;
22138 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
22140 + if (retval == NULL)
22141 + retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
22143 + spin_unlock(&dcache_lock);
22147 +static __inline__ struct acl_object_label *
22148 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
22149 + const struct acl_subject_label *subj)
22151 + char *path = NULL;
22152 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
22155 +static __inline__ struct acl_object_label *
22156 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
22157 + const struct acl_subject_label *subj, char *path)
22159 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
22162 +static struct acl_subject_label *
22163 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
22164 + const struct acl_role_label *role)
22166 + struct dentry *dentry = (struct dentry *) l_dentry;
22167 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
22168 + struct acl_subject_label *retval;
22170 + spin_lock(&dcache_lock);
22173 + if (dentry == real_root && mnt == real_root_mnt)
22175 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
22176 + if (mnt->mnt_parent == mnt)
22179 + read_lock(&gr_inode_lock);
22181 + lookup_acl_subj_label(dentry->d_inode->i_ino,
22182 + dentry->d_inode->i_sb->s_dev, role);
22183 + read_unlock(&gr_inode_lock);
22184 + if (retval != NULL)
22187 + dentry = mnt->mnt_mountpoint;
22188 + mnt = mnt->mnt_parent;
22192 + read_lock(&gr_inode_lock);
22193 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
22194 + dentry->d_inode->i_sb->s_dev, role);
22195 + read_unlock(&gr_inode_lock);
22196 + if (retval != NULL)
22199 + dentry = dentry->d_parent;
22202 + read_lock(&gr_inode_lock);
22203 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
22204 + dentry->d_inode->i_sb->s_dev, role);
22205 + read_unlock(&gr_inode_lock);
22207 + if (unlikely(retval == NULL)) {
22208 + read_lock(&gr_inode_lock);
22209 + retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
22210 + real_root->d_inode->i_sb->s_dev, role);
22211 + read_unlock(&gr_inode_lock);
22214 + spin_unlock(&dcache_lock);
22220 +gr_log_learn(const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
22222 + struct task_struct *task = current;
22223 + const struct cred *cred = current_cred();
22225 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
22226 + cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
22227 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
22228 + 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
22234 +gr_log_learn_sysctl(const char *path, const __u32 mode)
22236 + struct task_struct *task = current;
22237 + const struct cred *cred = current_cred();
22239 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
22240 + cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
22241 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
22242 + 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
22248 +gr_log_learn_id_change(const char type, const unsigned int real,
22249 + const unsigned int effective, const unsigned int fs)
22251 + struct task_struct *task = current;
22252 + const struct cred *cred = current_cred();
22254 + security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
22255 + cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
22256 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
22257 + type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
22263 +gr_check_link(const struct dentry * new_dentry,
22264 + const struct dentry * parent_dentry,
22265 + const struct vfsmount * parent_mnt,
22266 + const struct dentry * old_dentry, const struct vfsmount * old_mnt)
22268 + struct acl_object_label *obj;
22269 + __u32 oldmode, newmode;
22272 + if (unlikely(!(gr_status & GR_READY)))
22273 + return (GR_CREATE | GR_LINK);
22275 + obj = chk_obj_label(old_dentry, old_mnt, current->acl);
22276 + oldmode = obj->mode;
22278 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22279 + oldmode |= (GR_CREATE | GR_LINK);
22281 + needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
22282 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
22283 + needmode |= GR_SETID | GR_AUDIT_SETID;
22286 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
22287 + oldmode | needmode);
22289 + needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
22290 + GR_SETID | GR_READ | GR_FIND | GR_DELETE |
22291 + GR_INHERIT | GR_AUDIT_INHERIT);
22293 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
22296 + if ((oldmode & needmode) != needmode)
22299 + needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
22300 + if ((newmode & needmode) != needmode)
22303 + if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
22306 + needmode = oldmode;
22307 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
22308 + needmode |= GR_SETID;
22310 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
22311 + gr_log_learn(old_dentry, old_mnt, needmode);
22312 + return (GR_CREATE | GR_LINK);
22313 + } else if (newmode & GR_SUPPRESS)
22314 + return GR_SUPPRESS;
22320 +gr_search_file(const struct dentry * dentry, const __u32 mode,
22321 + const struct vfsmount * mnt)
22323 + __u32 retval = mode;
22324 + struct acl_subject_label *curracl;
22325 + struct acl_object_label *currobj;
22327 + if (unlikely(!(gr_status & GR_READY)))
22328 + return (mode & ~GR_AUDITS);
22330 + curracl = current->acl;
22332 + currobj = chk_obj_label(dentry, mnt, curracl);
22333 + retval = currobj->mode & mode;
22336 + ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
22337 + && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
22338 + __u32 new_mode = mode;
22340 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
22342 + retval = new_mode;
22344 + if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
22345 + new_mode |= GR_INHERIT;
22347 + if (!(mode & GR_NOLEARN))
22348 + gr_log_learn(dentry, mnt, new_mode);
22355 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
22356 + const struct vfsmount * mnt, const __u32 mode)
22358 + struct name_entry *match;
22359 + struct acl_object_label *matchpo;
22360 + struct acl_subject_label *curracl;
22364 + if (unlikely(!(gr_status & GR_READY)))
22365 + return (mode & ~GR_AUDITS);
22367 + preempt_disable();
22368 + path = gr_to_filename_rbac(new_dentry, mnt);
22369 + match = lookup_name_entry_create(path);
22372 + goto check_parent;
22374 + curracl = current->acl;
22376 + read_lock(&gr_inode_lock);
22377 + matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
22378 + read_unlock(&gr_inode_lock);
22381 + if ((matchpo->mode & mode) !=
22382 + (mode & ~(GR_AUDITS | GR_SUPPRESS))
22383 + && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
22384 + __u32 new_mode = mode;
22386 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
22388 + gr_log_learn(new_dentry, mnt, new_mode);
22390 + preempt_enable();
22393 + preempt_enable();
22394 + return (matchpo->mode & mode);
22398 + curracl = current->acl;
22400 + matchpo = chk_obj_create_label(parent, mnt, curracl, path);
22401 + retval = matchpo->mode & mode;
22403 + if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
22404 + && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
22405 + __u32 new_mode = mode;
22407 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
22409 + gr_log_learn(new_dentry, mnt, new_mode);
22410 + preempt_enable();
22414 + preempt_enable();
22419 +gr_check_hidden_task(const struct task_struct *task)
22421 + if (unlikely(!(gr_status & GR_READY)))
22424 + if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
22431 +gr_check_protected_task(const struct task_struct *task)
22433 + if (unlikely(!(gr_status & GR_READY) || !task))
22436 + if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
22437 + task->acl != current->acl)
22444 +gr_copy_label(struct task_struct *tsk)
22446 + tsk->signal->used_accept = 0;
22447 + tsk->acl_sp_role = 0;
22448 + tsk->acl_role_id = current->acl_role_id;
22449 + tsk->acl = current->acl;
22450 + tsk->role = current->role;
22451 + tsk->signal->curr_ip = current->signal->curr_ip;
22452 + if (current->exec_file)
22453 + get_file(current->exec_file);
22454 + tsk->exec_file = current->exec_file;
22455 + tsk->is_writable = current->is_writable;
22456 + if (unlikely(current->signal->used_accept))
22457 + current->signal->curr_ip = 0;
22463 +gr_set_proc_res(struct task_struct *task)
22465 + struct acl_subject_label *proc;
22466 + unsigned short i;
22468 + proc = task->acl;
22470 + if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
22473 + for (i = 0; i < RLIM_NLIMITS; i++) {
22474 + if (!(proc->resmask & (1 << i)))
22477 + task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
22478 + task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
22485 +gr_check_user_change(int real, int effective, int fs)
22492 + int effectiveok = 0;
22495 + if (unlikely(!(gr_status & GR_READY)))
22498 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22499 + gr_log_learn_id_change('u', real, effective, fs);
22501 + num = current->acl->user_trans_num;
22502 + uidlist = current->acl->user_transitions;
22504 + if (uidlist == NULL)
22509 + if (effective == -1)
22514 + if (current->acl->user_trans_type & GR_ID_ALLOW) {
22515 + for (i = 0; i < num; i++) {
22516 + curuid = (int)uidlist[i];
22517 + if (real == curuid)
22519 + if (effective == curuid)
22521 + if (fs == curuid)
22524 + } else if (current->acl->user_trans_type & GR_ID_DENY) {
22525 + for (i = 0; i < num; i++) {
22526 + curuid = (int)uidlist[i];
22527 + if (real == curuid)
22529 + if (effective == curuid)
22531 + if (fs == curuid)
22534 + /* not in deny list */
22542 + if (realok && effectiveok && fsok)
22545 + gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
22551 +gr_check_group_change(int real, int effective, int fs)
22558 + int effectiveok = 0;
22561 + if (unlikely(!(gr_status & GR_READY)))
22564 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22565 + gr_log_learn_id_change('g', real, effective, fs);
22567 + num = current->acl->group_trans_num;
22568 + gidlist = current->acl->group_transitions;
22570 + if (gidlist == NULL)
22575 + if (effective == -1)
22580 + if (current->acl->group_trans_type & GR_ID_ALLOW) {
22581 + for (i = 0; i < num; i++) {
22582 + curgid = (int)gidlist[i];
22583 + if (real == curgid)
22585 + if (effective == curgid)
22587 + if (fs == curgid)
22590 + } else if (current->acl->group_trans_type & GR_ID_DENY) {
22591 + for (i = 0; i < num; i++) {
22592 + curgid = (int)gidlist[i];
22593 + if (real == curgid)
22595 + if (effective == curgid)
22597 + if (fs == curgid)
22600 + /* not in deny list */
22608 + if (realok && effectiveok && fsok)
22611 + gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
22617 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
22619 + struct acl_role_label *role = task->role;
22620 + struct acl_subject_label *subj = NULL;
22621 + struct acl_object_label *obj;
22622 + struct file *filp;
22624 + if (unlikely(!(gr_status & GR_READY)))
22627 + filp = task->exec_file;
22629 + /* kernel process, we'll give them the kernel role */
22630 + if (unlikely(!filp)) {
22631 + task->role = kernel_role;
22632 + task->acl = kernel_role->root_label;
22634 + } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
22635 + role = lookup_acl_role_label(task, uid, gid);
22637 + /* perform subject lookup in possibly new role
22638 + we can use this result below in the case where role == task->role
22640 + subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
22642 + /* if we changed uid/gid, but result in the same role
22643 + and are using inheritance, don't lose the inherited subject
22644 + if current subject is other than what normal lookup
22645 + would result in, we arrived via inheritance, don't
22648 + if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
22649 + (subj == task->acl)))
22650 + task->acl = subj;
22652 + task->role = role;
22654 + task->is_writable = 0;
22656 + /* ignore additional mmap checks for processes that are writable
22657 + by the default ACL */
22658 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
22659 + if (unlikely(obj->mode & GR_WRITE))
22660 + task->is_writable = 1;
22661 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
22662 + if (unlikely(obj->mode & GR_WRITE))
22663 + task->is_writable = 1;
22665 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22666 + printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
22669 + gr_set_proc_res(task);
22675 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
22677 + struct task_struct *task = current;
22678 + struct acl_subject_label *newacl;
22679 + struct acl_object_label *obj;
22682 + if (unlikely(!(gr_status & GR_READY)))
22685 + newacl = chk_subj_label(dentry, mnt, task->role);
22688 + if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
22689 + GR_POVERRIDE) && (task->acl != newacl) &&
22690 + !(task->role->roletype & GR_ROLE_GOD) &&
22691 + !gr_search_file(dentry, GR_PTRACERD, mnt) &&
22692 + !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
22693 + (atomic_read(&task->fs->count) > 1 ||
22694 + atomic_read(&task->files->count) > 1 ||
22695 + atomic_read(&task->sighand->count) > 1)) {
22696 + task_unlock(task);
22697 + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
22700 + task_unlock(task);
22702 + obj = chk_obj_label(dentry, mnt, task->acl);
22703 + retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
22705 + if (!(task->acl->mode & GR_INHERITLEARN) &&
22706 + ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
22708 + task->acl = obj->nested;
22710 + task->acl = newacl;
22711 + } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
22712 + gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
22714 + task->is_writable = 0;
22716 + /* ignore additional mmap checks for processes that are writable
22717 + by the default ACL */
22718 + obj = chk_obj_label(dentry, mnt, default_role->root_label);
22719 + if (unlikely(obj->mode & GR_WRITE))
22720 + task->is_writable = 1;
22721 + obj = chk_obj_label(dentry, mnt, task->role->root_label);
22722 + if (unlikely(obj->mode & GR_WRITE))
22723 + task->is_writable = 1;
22725 + gr_set_proc_res(task);
22727 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22728 + printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
22733 +/* always called with valid inodev ptr */
22735 +do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
22737 + struct acl_object_label *matchpo;
22738 + struct acl_subject_label *matchps;
22739 + struct acl_subject_label *subj;
22740 + struct acl_role_label *role;
22741 + unsigned int i, x;
22743 + FOR_EACH_ROLE_START(role, i)
22744 + FOR_EACH_SUBJECT_START(role, subj, x)
22745 + if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
22746 + matchpo->mode |= GR_DELETED;
22747 + FOR_EACH_SUBJECT_END(subj,x)
22748 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
22749 + if (subj->inode == ino && subj->device == dev)
22750 + subj->mode |= GR_DELETED;
22751 + FOR_EACH_NESTED_SUBJECT_END(subj)
22752 + if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
22753 + matchps->mode |= GR_DELETED;
22754 + FOR_EACH_ROLE_END(role,i)
22756 + inodev->nentry->deleted = 1;
22762 +gr_handle_delete(const ino_t ino, const dev_t dev)
22764 + struct inodev_entry *inodev;
22766 + if (unlikely(!(gr_status & GR_READY)))
22769 + write_lock(&gr_inode_lock);
22770 + inodev = lookup_inodev_entry(ino, dev);
22771 + if (inodev != NULL)
22772 + do_handle_delete(inodev, ino, dev);
22773 + write_unlock(&gr_inode_lock);
22779 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
22780 + const ino_t newinode, const dev_t newdevice,
22781 + struct acl_subject_label *subj)
22783 + unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
22784 + struct acl_object_label *match;
22786 + match = subj->obj_hash[index];
22788 + while (match && (match->inode != oldinode ||
22789 + match->device != olddevice ||
22790 + !(match->mode & GR_DELETED)))
22791 + match = match->next;
22793 + if (match && (match->inode == oldinode)
22794 + && (match->device == olddevice)
22795 + && (match->mode & GR_DELETED)) {
22796 + if (match->prev == NULL) {
22797 + subj->obj_hash[index] = match->next;
22798 + if (match->next != NULL)
22799 + match->next->prev = NULL;
22801 + match->prev->next = match->next;
22802 + if (match->next != NULL)
22803 + match->next->prev = match->prev;
22805 + match->prev = NULL;
22806 + match->next = NULL;
22807 + match->inode = newinode;
22808 + match->device = newdevice;
22809 + match->mode &= ~GR_DELETED;
22811 + insert_acl_obj_label(match, subj);
22818 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
22819 + const ino_t newinode, const dev_t newdevice,
22820 + struct acl_role_label *role)
22822 + unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
22823 + struct acl_subject_label *match;
22825 + match = role->subj_hash[index];
22827 + while (match && (match->inode != oldinode ||
22828 + match->device != olddevice ||
22829 + !(match->mode & GR_DELETED)))
22830 + match = match->next;
22832 + if (match && (match->inode == oldinode)
22833 + && (match->device == olddevice)
22834 + && (match->mode & GR_DELETED)) {
22835 + if (match->prev == NULL) {
22836 + role->subj_hash[index] = match->next;
22837 + if (match->next != NULL)
22838 + match->next->prev = NULL;
22840 + match->prev->next = match->next;
22841 + if (match->next != NULL)
22842 + match->next->prev = match->prev;
22844 + match->prev = NULL;
22845 + match->next = NULL;
22846 + match->inode = newinode;
22847 + match->device = newdevice;
22848 + match->mode &= ~GR_DELETED;
22850 + insert_acl_subj_label(match, role);
22857 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
22858 + const ino_t newinode, const dev_t newdevice)
22860 + unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
22861 + struct inodev_entry *match;
22863 + match = inodev_set.i_hash[index];
22865 + while (match && (match->nentry->inode != oldinode ||
22866 + match->nentry->device != olddevice || !match->nentry->deleted))
22867 + match = match->next;
22869 + if (match && (match->nentry->inode == oldinode)
22870 + && (match->nentry->device == olddevice) &&
22871 + match->nentry->deleted) {
22872 + if (match->prev == NULL) {
22873 + inodev_set.i_hash[index] = match->next;
22874 + if (match->next != NULL)
22875 + match->next->prev = NULL;
22877 + match->prev->next = match->next;
22878 + if (match->next != NULL)
22879 + match->next->prev = match->prev;
22881 + match->prev = NULL;
22882 + match->next = NULL;
22883 + match->nentry->inode = newinode;
22884 + match->nentry->device = newdevice;
22885 + match->nentry->deleted = 0;
22887 + insert_inodev_entry(match);
22894 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
22895 + const struct vfsmount *mnt)
22897 + struct acl_subject_label *subj;
22898 + struct acl_role_label *role;
22899 + unsigned int i, x;
22901 + FOR_EACH_ROLE_START(role, i)
22902 + update_acl_subj_label(matchn->inode, matchn->device,
22903 + dentry->d_inode->i_ino,
22904 + dentry->d_inode->i_sb->s_dev, role);
22906 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
22907 + if ((subj->inode == dentry->d_inode->i_ino) &&
22908 + (subj->device == dentry->d_inode->i_sb->s_dev)) {
22909 + subj->inode = dentry->d_inode->i_ino;
22910 + subj->device = dentry->d_inode->i_sb->s_dev;
22912 + FOR_EACH_NESTED_SUBJECT_END(subj)
22913 + FOR_EACH_SUBJECT_START(role, subj, x)
22914 + update_acl_obj_label(matchn->inode, matchn->device,
22915 + dentry->d_inode->i_ino,
22916 + dentry->d_inode->i_sb->s_dev, subj);
22917 + FOR_EACH_SUBJECT_END(subj,x)
22918 + FOR_EACH_ROLE_END(role,i)
22920 + update_inodev_entry(matchn->inode, matchn->device,
22921 + dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
22927 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
22929 + struct name_entry *matchn;
22931 + if (unlikely(!(gr_status & GR_READY)))
22934 + preempt_disable();
22935 + matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
22937 + if (unlikely((unsigned long)matchn)) {
22938 + write_lock(&gr_inode_lock);
22939 + do_handle_create(matchn, dentry, mnt);
22940 + write_unlock(&gr_inode_lock);
22942 + preempt_enable();
22948 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
22949 + struct dentry *old_dentry,
22950 + struct dentry *new_dentry,
22951 + struct vfsmount *mnt, const __u8 replace)
22953 + struct name_entry *matchn;
22954 + struct inodev_entry *inodev;
22956 + /* vfs_rename swaps the name and parent link for old_dentry and
22958 + at this point, old_dentry has the new name, parent link, and inode
22959 + for the renamed file
22960 + if a file is being replaced by a rename, new_dentry has the inode
22961 + and name for the replaced file
22964 + if (unlikely(!(gr_status & GR_READY)))
22967 + preempt_disable();
22968 + matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
22970 + /* we wouldn't have to check d_inode if it weren't for
22971 + NFS silly-renaming
22974 + write_lock(&gr_inode_lock);
22975 + if (unlikely(replace && new_dentry->d_inode)) {
22976 + inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
22977 + new_dentry->d_inode->i_sb->s_dev);
22978 + if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
22979 + do_handle_delete(inodev, new_dentry->d_inode->i_ino,
22980 + new_dentry->d_inode->i_sb->s_dev);
22983 + inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
22984 + old_dentry->d_inode->i_sb->s_dev);
22985 + if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
22986 + do_handle_delete(inodev, old_dentry->d_inode->i_ino,
22987 + old_dentry->d_inode->i_sb->s_dev);
22989 + if (unlikely((unsigned long)matchn))
22990 + do_handle_create(matchn, old_dentry, mnt);
22992 + write_unlock(&gr_inode_lock);
22993 + preempt_enable();
22999 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
23000 + unsigned char **sum)
23002 + struct acl_role_label *r;
23003 + struct role_allowed_ip *ipp;
23004 + struct role_transition *trans;
23008 + /* check transition table */
23010 + for (trans = current->role->transitions; trans; trans = trans->next) {
23011 + if (!strcmp(rolename, trans->rolename)) {
23020 + /* handle special roles that do not require authentication
23023 + FOR_EACH_ROLE_START(r, i)
23024 + if (!strcmp(rolename, r->rolename) &&
23025 + (r->roletype & GR_ROLE_SPECIAL)) {
23027 + if (r->allowed_ips != NULL) {
23028 + for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
23029 + if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
23030 + (ntohl(ipp->addr) & ipp->netmask))
23038 + if (((mode == GR_SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
23039 + ((mode == GR_SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
23045 + FOR_EACH_ROLE_END(r,i)
23047 + for (i = 0; i < num_sprole_pws; i++) {
23048 + if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
23049 + *salt = acl_special_roles[i]->salt;
23050 + *sum = acl_special_roles[i]->sum;
23059 +assign_special_role(char *rolename)
23061 + struct acl_object_label *obj;
23062 + struct acl_role_label *r;
23063 + struct acl_role_label *assigned = NULL;
23064 + struct task_struct *tsk;
23065 + struct file *filp;
23068 + FOR_EACH_ROLE_START(r, i)
23069 + if (!strcmp(rolename, r->rolename) &&
23070 + (r->roletype & GR_ROLE_SPECIAL))
23072 + FOR_EACH_ROLE_END(r,i)
23077 + read_lock(&tasklist_lock);
23078 + read_lock(&grsec_exec_file_lock);
23080 + tsk = current->parent;
23084 + filp = tsk->exec_file;
23085 + if (filp == NULL)
23088 + tsk->is_writable = 0;
23090 + tsk->acl_sp_role = 1;
23091 + tsk->acl_role_id = ++acl_sp_role_value;
23092 + tsk->role = assigned;
23093 + tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
23095 + /* ignore additional mmap checks for processes that are writable
23096 + by the default ACL */
23097 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23098 + if (unlikely(obj->mode & GR_WRITE))
23099 + tsk->is_writable = 1;
23100 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
23101 + if (unlikely(obj->mode & GR_WRITE))
23102 + tsk->is_writable = 1;
23104 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
23105 + printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
23109 + read_unlock(&grsec_exec_file_lock);
23110 + read_unlock(&tasklist_lock);
23114 +int gr_check_secure_terminal(struct task_struct *task)
23116 + struct task_struct *p, *p2, *p3;
23117 + struct files_struct *files;
23118 + struct fdtable *fdt;
23119 + struct file *our_file = NULL, *file;
23122 + if (task->signal->tty == NULL)
23125 + files = get_files_struct(task);
23126 + if (files != NULL) {
23128 + fdt = files_fdtable(files);
23129 + for (i=0; i < fdt->max_fds; i++) {
23130 + file = fcheck_files(files, i);
23131 + if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
23136 + rcu_read_unlock();
23137 + put_files_struct(files);
23140 + if (our_file == NULL)
23143 + read_lock(&tasklist_lock);
23144 + do_each_thread(p2, p) {
23145 + files = get_files_struct(p);
23146 + if (files == NULL ||
23147 + (p->signal && p->signal->tty == task->signal->tty)) {
23148 + if (files != NULL)
23149 + put_files_struct(files);
23153 + fdt = files_fdtable(files);
23154 + for (i=0; i < fdt->max_fds; i++) {
23155 + file = fcheck_files(files, i);
23156 + if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
23157 + file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
23159 + while (p3->pid > 0) {
23166 + gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
23167 + gr_handle_alertkill(p);
23168 + rcu_read_unlock();
23169 + put_files_struct(files);
23170 + read_unlock(&tasklist_lock);
23175 + rcu_read_unlock();
23176 + put_files_struct(files);
23177 + } while_each_thread(p2, p);
23178 + read_unlock(&tasklist_lock);
23185 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
23187 + struct gr_arg_wrapper uwrap;
23188 + unsigned char *sprole_salt;
23189 + unsigned char *sprole_sum;
23190 + int error = sizeof (struct gr_arg_wrapper);
23193 + down(&gr_dev_sem);
23195 + if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
23200 + if (count != sizeof (struct gr_arg_wrapper)) {
23201 + gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
23207 + if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
23208 + gr_auth_expires = 0;
23209 + gr_auth_attempts = 0;
23212 + if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
23217 + if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
23222 + if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
23227 + if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_SPROLEPAM &&
23228 + gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
23229 + time_after(gr_auth_expires, get_seconds())) {
23234 + /* if non-root trying to do anything other than use a special role,
23235 + do not attempt authentication, do not count towards authentication
23239 + if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_STATUS &&
23240 + gr_usermode->mode != GR_UNSPROLE && gr_usermode->mode != GR_SPROLEPAM &&
23246 + /* ensure pw and special role name are null terminated */
23248 + gr_usermode->pw[GR_PW_LEN - 1] = '\0';
23249 + gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
23252 + * We have our enough of the argument structure..(we have yet
23253 + * to copy_from_user the tables themselves) . Copy the tables
23254 + * only if we need them, i.e. for loading operations. */
23256 + switch (gr_usermode->mode) {
23258 + if (gr_status & GR_READY) {
23260 + if (!gr_check_secure_terminal(current))
23265 + case GR_SHUTDOWN:
23266 + if ((gr_status & GR_READY)
23267 + && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
23268 + gr_status &= ~GR_READY;
23269 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
23270 + free_variables();
23271 + memset(gr_usermode, 0, sizeof (struct gr_arg));
23272 + memset(gr_system_salt, 0, GR_SALT_LEN);
23273 + memset(gr_system_sum, 0, GR_SHA_LEN);
23274 + } else if (gr_status & GR_READY) {
23275 + gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
23278 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
23283 + if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
23284 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
23286 + if (gr_status & GR_READY)
23290 + gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
23294 + if (!(gr_status & GR_READY)) {
23295 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
23297 + } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
23299 + gr_status &= ~GR_READY;
23300 + free_variables();
23301 + if (!(error2 = gracl_init(gr_usermode))) {
23303 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
23307 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
23310 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
23315 + if (unlikely(!(gr_status & GR_READY))) {
23316 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
23321 + if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
23322 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
23323 + if (gr_usermode->segv_device && gr_usermode->segv_inode) {
23324 + struct acl_subject_label *segvacl;
23326 + lookup_acl_subj_label(gr_usermode->segv_inode,
23327 + gr_usermode->segv_device,
23330 + segvacl->crashes = 0;
23331 + segvacl->expires = 0;
23333 + } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
23334 + gr_remove_uid(gr_usermode->segv_uid);
23337 + gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
23342 + case GR_SPROLEPAM:
23343 + if (unlikely(!(gr_status & GR_READY))) {
23344 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
23349 + if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
23350 + current->role->expires = 0;
23351 + current->role->auth_attempts = 0;
23354 + if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
23355 + time_after(current->role->expires, get_seconds())) {
23360 + if (lookup_special_role_auth
23361 + (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
23362 + && ((!sprole_salt && !sprole_sum)
23363 + || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
23365 + assign_special_role(gr_usermode->sp_role);
23366 + read_lock(&tasklist_lock);
23367 + if (current->parent)
23368 + p = current->parent->role->rolename;
23369 + read_unlock(&tasklist_lock);
23370 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
23371 + p, acl_sp_role_value);
23373 + gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
23375 + if(!(current->role->auth_attempts++))
23376 + current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
23381 + case GR_UNSPROLE:
23382 + if (unlikely(!(gr_status & GR_READY))) {
23383 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
23388 + if (current->role->roletype & GR_ROLE_SPECIAL) {
23392 + read_lock(&tasklist_lock);
23393 + if (current->parent) {
23394 + p = current->parent->role->rolename;
23395 + i = current->parent->acl_role_id;
23397 + read_unlock(&tasklist_lock);
23399 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
23402 + gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
23408 + gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
23413 + if (error != -EPERM)
23416 + if(!(gr_auth_attempts++))
23417 + gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
23425 +gr_set_acls(const int type)
23427 + struct acl_object_label *obj;
23428 + struct task_struct *task, *task2;
23429 + struct file *filp;
23430 + struct acl_role_label *role = current->role;
23431 + __u16 acl_role_id = current->acl_role_id;
23432 + const struct cred *cred;
23434 + read_lock(&tasklist_lock);
23435 + read_lock(&grsec_exec_file_lock);
23436 + do_each_thread(task2, task) {
23437 + /* check to see if we're called from the exit handler,
23438 + if so, only replace ACLs that have inherited the admin
23441 + if (type && (task->role != role ||
23442 + task->acl_role_id != acl_role_id))
23445 + task->acl_role_id = 0;
23446 + task->acl_sp_role = 0;
23448 + if ((filp = task->exec_file)) {
23449 + cred = __task_cred(task);
23450 + task->role = lookup_acl_role_label(task, cred->uid, cred->gid);
23453 + chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
23456 + struct acl_subject_label *curr;
23457 + curr = task->acl;
23459 + task->is_writable = 0;
23460 + /* ignore additional mmap checks for processes that are writable
23461 + by the default ACL */
23462 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23463 + if (unlikely(obj->mode & GR_WRITE))
23464 + task->is_writable = 1;
23465 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
23466 + if (unlikely(obj->mode & GR_WRITE))
23467 + task->is_writable = 1;
23469 + gr_set_proc_res(task);
23471 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
23472 + printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
23475 + read_unlock(&grsec_exec_file_lock);
23476 + read_unlock(&tasklist_lock);
23477 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
23481 + // it's a kernel process
23482 + task->role = kernel_role;
23483 + task->acl = kernel_role->root_label;
23484 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
23485 + task->acl->mode &= ~GR_PROCFIND;
23488 + } while_each_thread(task2, task);
23489 + read_unlock(&grsec_exec_file_lock);
23490 + read_unlock(&tasklist_lock);
23495 +gr_learn_resource(const struct task_struct *task,
23496 + const int res, const unsigned long wanted, const int gt)
23498 + struct acl_subject_label *acl;
23500 + if (unlikely((gr_status & GR_READY) &&
23501 + task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
23502 + goto skip_reslog;
23504 +#ifdef CONFIG_GRKERNSEC_RESLOG
23505 + gr_log_resource(task, res, wanted, gt);
23509 + if (unlikely(!(gr_status & GR_READY) || !wanted || res >= GR_NLIMITS))
23514 + if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
23515 + !(acl->resmask & (1 << (unsigned short) res))))
23518 + if (wanted >= acl->res[res].rlim_cur) {
23519 + unsigned long res_add;
23521 + res_add = wanted;
23524 + res_add += GR_RLIM_CPU_BUMP;
23526 + case RLIMIT_FSIZE:
23527 + res_add += GR_RLIM_FSIZE_BUMP;
23529 + case RLIMIT_DATA:
23530 + res_add += GR_RLIM_DATA_BUMP;
23532 + case RLIMIT_STACK:
23533 + res_add += GR_RLIM_STACK_BUMP;
23535 + case RLIMIT_CORE:
23536 + res_add += GR_RLIM_CORE_BUMP;
23539 + res_add += GR_RLIM_RSS_BUMP;
23541 + case RLIMIT_NPROC:
23542 + res_add += GR_RLIM_NPROC_BUMP;
23544 + case RLIMIT_NOFILE:
23545 + res_add += GR_RLIM_NOFILE_BUMP;
23547 + case RLIMIT_MEMLOCK:
23548 + res_add += GR_RLIM_MEMLOCK_BUMP;
23551 + res_add += GR_RLIM_AS_BUMP;
23553 + case RLIMIT_LOCKS:
23554 + res_add += GR_RLIM_LOCKS_BUMP;
23556 + case RLIMIT_SIGPENDING:
23557 + res_add += GR_RLIM_SIGPENDING_BUMP;
23559 + case RLIMIT_MSGQUEUE:
23560 + res_add += GR_RLIM_MSGQUEUE_BUMP;
23562 + case RLIMIT_NICE:
23563 + res_add += GR_RLIM_NICE_BUMP;
23565 + case RLIMIT_RTPRIO:
23566 + res_add += GR_RLIM_RTPRIO_BUMP;
23568 + case RLIMIT_RTTIME:
23569 + res_add += GR_RLIM_RTTIME_BUMP;
23573 + acl->res[res].rlim_cur = res_add;
23575 + if (wanted > acl->res[res].rlim_max)
23576 + acl->res[res].rlim_max = res_add;
23578 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
23579 + task->role->roletype, acl->filename,
23580 + acl->res[res].rlim_cur, acl->res[res].rlim_max,
23581 + "", (unsigned long) res);
23587 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
23589 +pax_set_initial_flags(struct linux_binprm *bprm)
23591 + struct task_struct *task = current;
23592 + struct acl_subject_label *proc;
23593 + unsigned long flags;
23595 + if (unlikely(!(gr_status & GR_READY)))
23598 + flags = pax_get_flags(task);
23600 + proc = task->acl;
23602 + if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
23603 + flags &= ~MF_PAX_PAGEEXEC;
23604 + if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
23605 + flags &= ~MF_PAX_SEGMEXEC;
23606 + if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
23607 + flags &= ~MF_PAX_RANDMMAP;
23608 + if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
23609 + flags &= ~MF_PAX_EMUTRAMP;
23610 + if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
23611 + flags &= ~MF_PAX_MPROTECT;
23613 + if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
23614 + flags |= MF_PAX_PAGEEXEC;
23615 + if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
23616 + flags |= MF_PAX_SEGMEXEC;
23617 + if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
23618 + flags |= MF_PAX_RANDMMAP;
23619 + if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
23620 + flags |= MF_PAX_EMUTRAMP;
23621 + if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
23622 + flags |= MF_PAX_MPROTECT;
23624 + pax_set_flags(task, flags);
23630 +#ifdef CONFIG_SYSCTL
23631 +/* Eric Biederman likes breaking userland ABI and every inode-based security
23632 + system to save 35kb of memory */
23634 +/* we modify the passed in filename, but adjust it back before returning */
23635 +static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
23637 + struct name_entry *nmatch;
23638 + char *p, *lastp = NULL;
23639 + struct acl_object_label *obj = NULL, *tmp;
23640 + struct acl_subject_label *tmpsubj;
23643 + read_lock(&gr_inode_lock);
23645 + p = name + len - 1;
23647 + nmatch = lookup_name_entry(name);
23648 + if (lastp != NULL)
23651 + if (nmatch == NULL)
23652 + goto next_component;
23653 + tmpsubj = current->acl;
23655 + obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
23656 + if (obj != NULL) {
23657 + tmp = obj->globbed;
23659 + if (!glob_match(tmp->filename, name)) {
23667 + } while ((tmpsubj = tmpsubj->parent_subject));
23673 + while (*p != '/')
23685 + read_unlock(&gr_inode_lock);
23686 + /* obj returned will always be non-null */
23690 +/* returns 0 when allowing, non-zero on error
23691 + op of 0 is used for readdir, so we don't log the names of hidden files
23694 +gr_handle_sysctl(const struct ctl_table *table, const int op)
23697 + const char *proc_sys = "/proc/sys";
23699 + struct acl_object_label *obj;
23700 + unsigned short len = 0, pos = 0, depth = 0, i;
23704 + if (unlikely(!(gr_status & GR_READY)))
23707 + /* for now, ignore operations on non-sysctl entries if it's not a
23709 + if (table->child != NULL && op != 0)
23713 + /* it's only a read if it's an entry, read on dirs is for readdir */
23714 + if (op & MAY_READ)
23716 + if (op & MAY_WRITE)
23717 + mode |= GR_WRITE;
23719 + preempt_disable();
23721 + path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
23723 + /* it's only a read/write if it's an actual entry, not a dir
23724 + (which are opened for readdir)
23727 + /* convert the requested sysctl entry into a pathname */
23729 + for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
23730 + len += strlen(tmp->procname);
23735 + if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
23740 + memset(path, 0, PAGE_SIZE);
23742 + memcpy(path, proc_sys, strlen(proc_sys));
23744 + pos += strlen(proc_sys);
23746 + for (; depth > 0; depth--) {
23749 + for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
23750 + if (depth == i) {
23751 + memcpy(path + pos, tmp->procname,
23752 + strlen(tmp->procname));
23753 + pos += strlen(tmp->procname);
23759 + obj = gr_lookup_by_name(path, pos);
23760 + err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
23762 + if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
23763 + ((err & mode) != mode))) {
23764 + __u32 new_mode = mode;
23766 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
23769 + gr_log_learn_sysctl(path, new_mode);
23770 + } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
23771 + gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
23773 + } else if (!(err & GR_FIND)) {
23775 + } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
23776 + gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
23777 + path, (mode & GR_READ) ? " reading" : "",
23778 + (mode & GR_WRITE) ? " writing" : "");
23780 + } else if ((err & mode) != mode) {
23782 + } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
23783 + gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
23784 + path, (mode & GR_READ) ? " reading" : "",
23785 + (mode & GR_WRITE) ? " writing" : "");
23791 + preempt_enable();
23798 +gr_handle_proc_ptrace(struct task_struct *task)
23800 + struct file *filp;
23801 + struct task_struct *tmp = task;
23802 + struct task_struct *curtemp = current;
23805 + if (unlikely(!(gr_status & GR_READY)))
23808 + read_lock(&tasklist_lock);
23809 + read_lock(&grsec_exec_file_lock);
23810 + filp = task->exec_file;
23812 + while (tmp->pid > 0) {
23813 + if (tmp == curtemp)
23815 + tmp = tmp->parent;
23818 + if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
23819 + read_unlock(&grsec_exec_file_lock);
23820 + read_unlock(&tasklist_lock);
23824 + retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
23825 + read_unlock(&grsec_exec_file_lock);
23826 + read_unlock(&tasklist_lock);
23828 + if (retmode & GR_NOPTRACE)
23831 + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
23832 + && (current->acl != task->acl || (current->acl != current->role->root_label
23833 + && current->pid != task->pid)))
23840 +gr_handle_ptrace(struct task_struct *task, const long request)
23842 + struct task_struct *tmp = task;
23843 + struct task_struct *curtemp = current;
23846 + if (unlikely(!(gr_status & GR_READY)))
23849 + read_lock(&tasklist_lock);
23850 + while (tmp->pid > 0) {
23851 + if (tmp == curtemp)
23853 + tmp = tmp->parent;
23856 + if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
23857 + read_unlock(&tasklist_lock);
23858 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23861 + read_unlock(&tasklist_lock);
23863 + read_lock(&grsec_exec_file_lock);
23864 + if (unlikely(!task->exec_file)) {
23865 + read_unlock(&grsec_exec_file_lock);
23869 + retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
23870 + read_unlock(&grsec_exec_file_lock);
23872 + if (retmode & GR_NOPTRACE) {
23873 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23877 + if (retmode & GR_PTRACERD) {
23878 + switch (request) {
23879 + case PTRACE_POKETEXT:
23880 + case PTRACE_POKEDATA:
23881 + case PTRACE_POKEUSR:
23882 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
23883 + case PTRACE_SETREGS:
23884 + case PTRACE_SETFPREGS:
23887 + case PTRACE_SETFPXREGS:
23889 +#ifdef CONFIG_ALTIVEC
23890 + case PTRACE_SETVRREGS:
23896 + } else if (!(current->acl->mode & GR_POVERRIDE) &&
23897 + !(current->role->roletype & GR_ROLE_GOD) &&
23898 + (current->acl != task->acl)) {
23899 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23906 +static int is_writable_mmap(const struct file *filp)
23908 + struct task_struct *task = current;
23909 + struct acl_object_label *obj, *obj2;
23911 + if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
23912 + !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
23913 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23914 + obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
23915 + task->role->root_label);
23916 + if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
23917 + gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
23925 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
23929 + if (unlikely(!file || !(prot & PROT_EXEC)))
23932 + if (is_writable_mmap(file))
23936 + gr_search_file(file->f_path.dentry,
23937 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
23938 + file->f_path.mnt);
23940 + if (!gr_tpe_allow(file))
23943 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
23944 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23946 + } else if (unlikely(!(mode & GR_EXEC))) {
23948 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
23949 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23957 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
23961 + if (unlikely(!file || !(prot & PROT_EXEC)))
23964 + if (is_writable_mmap(file))
23968 + gr_search_file(file->f_path.dentry,
23969 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
23970 + file->f_path.mnt);
23972 + if (!gr_tpe_allow(file))
23975 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
23976 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23978 + } else if (unlikely(!(mode & GR_EXEC))) {
23980 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
23981 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23989 +gr_acl_handle_psacct(struct task_struct *task, const long code)
23991 + unsigned long runtime;
23992 + unsigned long cputime;
23993 + unsigned int wday, cday;
23997 + struct timespec timeval;
23999 + if (unlikely(!(gr_status & GR_READY) || !task->acl ||
24000 + !(task->acl->mode & GR_PROCACCT)))
24003 + do_posix_clock_monotonic_gettime(&timeval);
24004 + runtime = timeval.tv_sec - task->start_time.tv_sec;
24005 + wday = runtime / (3600 * 24);
24006 + runtime -= wday * (3600 * 24);
24007 + whr = runtime / 3600;
24008 + runtime -= whr * 3600;
24009 + wmin = runtime / 60;
24010 + runtime -= wmin * 60;
24013 + cputime = (task->utime + task->stime) / HZ;
24014 + cday = cputime / (3600 * 24);
24015 + cputime -= cday * (3600 * 24);
24016 + chr = cputime / 3600;
24017 + cputime -= chr * 3600;
24018 + cmin = cputime / 60;
24019 + cputime -= cmin * 60;
24022 + gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
24027 +void gr_set_kernel_label(struct task_struct *task)
24029 + if (gr_status & GR_READY) {
24030 + task->role = kernel_role;
24031 + task->acl = kernel_role->root_label;
24036 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
24038 + struct task_struct *task = current;
24039 + struct dentry *dentry = file->f_path.dentry;
24040 + struct vfsmount *mnt = file->f_path.mnt;
24041 + struct acl_object_label *obj, *tmp;
24042 + struct acl_subject_label *subj;
24043 + unsigned int bufsize;
24047 + if (unlikely(!(gr_status & GR_READY)))
24050 + if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
24053 + /* ignore Eric Biederman */
24054 + if (IS_PRIVATE(dentry->d_inode))
24057 + subj = task->acl;
24059 + obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
24061 + return (obj->mode & GR_FIND) ? 1 : 0;
24062 + } while ((subj = subj->parent_subject));
24064 + obj = chk_obj_label(dentry, mnt, task->acl);
24065 + if (obj->globbed == NULL)
24066 + return (obj->mode & GR_FIND) ? 1 : 0;
24068 + is_not_root = ((obj->filename[0] == '/') &&
24069 + (obj->filename[1] == '\0')) ? 0 : 1;
24070 + bufsize = PAGE_SIZE - namelen - is_not_root;
24072 + /* check bufsize > PAGE_SIZE || bufsize == 0 */
24073 + if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
24076 + preempt_disable();
24077 + path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
24080 + bufsize = strlen(path);
24082 + /* if base is "/", don't append an additional slash */
24084 + *(path + bufsize) = '/';
24085 + memcpy(path + bufsize + is_not_root, name, namelen);
24086 + *(path + bufsize + namelen + is_not_root) = '\0';
24088 + tmp = obj->globbed;
24090 + if (!glob_match(tmp->filename, path)) {
24091 + preempt_enable();
24092 + return (tmp->mode & GR_FIND) ? 1 : 0;
24096 + preempt_enable();
24097 + return (obj->mode & GR_FIND) ? 1 : 0;
24100 +EXPORT_SYMBOL(gr_learn_resource);
24101 +EXPORT_SYMBOL(gr_set_kernel_label);
24102 +#ifdef CONFIG_SECURITY
24103 +EXPORT_SYMBOL(gr_check_user_change);
24104 +EXPORT_SYMBOL(gr_check_group_change);
24107 diff -urNp linux-2.6.29/grsecurity/gracl_cap.c linux-2.6.29/grsecurity/gracl_cap.c
24108 --- linux-2.6.29/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
24109 +++ linux-2.6.29/grsecurity/gracl_cap.c 2009-03-28 14:38:57.000000000 -0400
24111 +#include <linux/kernel.h>
24112 +#include <linux/module.h>
24113 +#include <linux/sched.h>
24114 +#include <linux/gracl.h>
24115 +#include <linux/grsecurity.h>
24116 +#include <linux/grinternal.h>
24118 +static const char *captab_log[] = {
24120 + "CAP_DAC_OVERRIDE",
24121 + "CAP_DAC_READ_SEARCH",
24128 + "CAP_LINUX_IMMUTABLE",
24129 + "CAP_NET_BIND_SERVICE",
24130 + "CAP_NET_BROADCAST",
24135 + "CAP_SYS_MODULE",
24137 + "CAP_SYS_CHROOT",
24138 + "CAP_SYS_PTRACE",
24143 + "CAP_SYS_RESOURCE",
24145 + "CAP_SYS_TTY_CONFIG",
24148 + "CAP_AUDIT_WRITE",
24149 + "CAP_AUDIT_CONTROL",
24151 + "CAP_MAC_OVERRIDE",
24155 +EXPORT_SYMBOL(gr_is_capable);
24156 +EXPORT_SYMBOL(gr_is_capable_nolog);
24159 +gr_is_capable(const int cap)
24161 + struct task_struct *task = current;
24162 + const struct cred *cred = current_cred();
24163 + struct acl_subject_label *curracl;
24164 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
24166 + if (!gr_acl_is_enabled())
24169 + curracl = task->acl;
24171 + cap_drop = curracl->cap_lower;
24172 + cap_mask = curracl->cap_mask;
24174 + while ((curracl = curracl->parent_subject)) {
24175 + /* if the cap isn't specified in the current computed mask but is specified in the
24176 + current level subject, and is lowered in the current level subject, then add
24177 + it to the set of dropped capabilities
24178 + otherwise, add the current level subject's mask to the current computed mask
24180 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
24181 + cap_raise(cap_mask, cap);
24182 + if (cap_raised(curracl->cap_lower, cap))
24183 + cap_raise(cap_drop, cap);
24187 + if (!cap_raised(cap_drop, cap))
24190 + curracl = task->acl;
24192 + if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
24193 + && cap_raised(cred->cap_effective, cap)) {
24194 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
24195 + task->role->roletype, cred->uid,
24196 + cred->gid, task->exec_file ?
24197 + gr_to_filename(task->exec_file->f_path.dentry,
24198 + task->exec_file->f_path.mnt) : curracl->filename,
24199 + curracl->filename, 0UL,
24200 + 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
24204 + if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(cred->cap_effective, cap))
24205 + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
24210 +gr_is_capable_nolog(const int cap)
24212 + struct acl_subject_label *curracl;
24213 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
24215 + if (!gr_acl_is_enabled())
24218 + curracl = current->acl;
24220 + cap_drop = curracl->cap_lower;
24221 + cap_mask = curracl->cap_mask;
24223 + while ((curracl = curracl->parent_subject)) {
24224 + /* if the cap isn't specified in the current computed mask but is specified in the
24225 + current level subject, and is lowered in the current level subject, then add
24226 + it to the set of dropped capabilities
24227 + otherwise, add the current level subject's mask to the current computed mask
24229 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
24230 + cap_raise(cap_mask, cap);
24231 + if (cap_raised(curracl->cap_lower, cap))
24232 + cap_raise(cap_drop, cap);
24236 + if (!cap_raised(cap_drop, cap))
24242 diff -urNp linux-2.6.29/grsecurity/gracl_fs.c linux-2.6.29/grsecurity/gracl_fs.c
24243 --- linux-2.6.29/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
24244 +++ linux-2.6.29/grsecurity/gracl_fs.c 2009-03-28 14:26:20.000000000 -0400
24246 +#include <linux/kernel.h>
24247 +#include <linux/sched.h>
24248 +#include <linux/types.h>
24249 +#include <linux/fs.h>
24250 +#include <linux/file.h>
24251 +#include <linux/stat.h>
24252 +#include <linux/grsecurity.h>
24253 +#include <linux/grinternal.h>
24254 +#include <linux/gracl.h>
24257 +gr_acl_handle_hidden_file(const struct dentry * dentry,
24258 + const struct vfsmount * mnt)
24262 + if (unlikely(!dentry->d_inode))
24266 + gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
24268 + if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
24269 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
24271 + } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
24272 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
24274 + } else if (unlikely(!(mode & GR_FIND)))
24281 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
24284 + __u32 reqmode = GR_FIND;
24287 + if (unlikely(!dentry->d_inode))
24290 + if (unlikely(fmode & O_APPEND))
24291 + reqmode |= GR_APPEND;
24292 + else if (unlikely(fmode & FMODE_WRITE))
24293 + reqmode |= GR_WRITE;
24294 + if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
24295 + reqmode |= GR_READ;
24298 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
24301 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
24302 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
24303 + reqmode & GR_READ ? " reading" : "",
24304 + reqmode & GR_WRITE ? " writing" : reqmode &
24305 + GR_APPEND ? " appending" : "");
24308 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
24310 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
24311 + reqmode & GR_READ ? " reading" : "",
24312 + reqmode & GR_WRITE ? " writing" : reqmode &
24313 + GR_APPEND ? " appending" : "");
24315 + } else if (unlikely((mode & reqmode) != reqmode))
24322 +gr_acl_handle_creat(const struct dentry * dentry,
24323 + const struct dentry * p_dentry,
24324 + const struct vfsmount * p_mnt, const int fmode,
24327 + __u32 reqmode = GR_WRITE | GR_CREATE;
24330 + if (unlikely(fmode & O_APPEND))
24331 + reqmode |= GR_APPEND;
24332 + if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
24333 + reqmode |= GR_READ;
24334 + if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
24335 + reqmode |= GR_SETID;
24338 + gr_check_create(dentry, p_dentry, p_mnt,
24339 + reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
24341 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
24342 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
24343 + reqmode & GR_READ ? " reading" : "",
24344 + reqmode & GR_WRITE ? " writing" : reqmode &
24345 + GR_APPEND ? " appending" : "");
24348 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
24350 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
24351 + reqmode & GR_READ ? " reading" : "",
24352 + reqmode & GR_WRITE ? " writing" : reqmode &
24353 + GR_APPEND ? " appending" : "");
24355 + } else if (unlikely((mode & reqmode) != reqmode))
24362 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
24365 + __u32 mode, reqmode = GR_FIND;
24367 + if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
24368 + reqmode |= GR_EXEC;
24369 + if (fmode & S_IWOTH)
24370 + reqmode |= GR_WRITE;
24371 + if (fmode & S_IROTH)
24372 + reqmode |= GR_READ;
24375 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
24378 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
24379 + gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
24380 + reqmode & GR_READ ? " reading" : "",
24381 + reqmode & GR_WRITE ? " writing" : "",
24382 + reqmode & GR_EXEC ? " executing" : "");
24385 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
24387 + gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
24388 + reqmode & GR_READ ? " reading" : "",
24389 + reqmode & GR_WRITE ? " writing" : "",
24390 + reqmode & GR_EXEC ? " executing" : "");
24392 + } else if (unlikely((mode & reqmode) != reqmode))
24398 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
24402 + mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
24404 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
24405 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
24407 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
24408 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
24410 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
24413 + return (reqmode);
24417 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
24419 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
24423 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
24425 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
24429 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
24431 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
24435 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
24437 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
24441 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
24444 + if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
24447 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
24448 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
24449 + GR_FCHMOD_ACL_MSG);
24451 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
24456 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
24459 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
24460 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
24461 + GR_CHMOD_ACL_MSG);
24463 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
24468 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
24470 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
24474 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
24476 + return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
24480 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
24482 + return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
24483 + GR_UNIXCONNECT_ACL_MSG);
24486 +/* hardlinks require at minimum create permission,
24487 + any additional privilege required is based on the
24488 + privilege of the file being linked to
24491 +gr_acl_handle_link(const struct dentry * new_dentry,
24492 + const struct dentry * parent_dentry,
24493 + const struct vfsmount * parent_mnt,
24494 + const struct dentry * old_dentry,
24495 + const struct vfsmount * old_mnt, const char *to)
24498 + __u32 needmode = GR_CREATE | GR_LINK;
24499 + __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
24502 + gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
24505 + if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
24506 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
24508 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
24509 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
24511 + } else if (unlikely((mode & needmode) != needmode))
24518 +gr_acl_handle_symlink(const struct dentry * new_dentry,
24519 + const struct dentry * parent_dentry,
24520 + const struct vfsmount * parent_mnt, const char *from)
24522 + __u32 needmode = GR_WRITE | GR_CREATE;
24526 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
24527 + GR_CREATE | GR_AUDIT_CREATE |
24528 + GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
24530 + if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
24531 + gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
24533 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
24534 + gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
24536 + } else if (unlikely((mode & needmode) != needmode))
24539 + return (GR_WRITE | GR_CREATE);
24542 +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)
24546 + mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
24548 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
24549 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
24551 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
24552 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
24554 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
24557 + return (reqmode);
24561 +gr_acl_handle_mknod(const struct dentry * new_dentry,
24562 + const struct dentry * parent_dentry,
24563 + const struct vfsmount * parent_mnt,
24566 + __u32 reqmode = GR_WRITE | GR_CREATE;
24567 + if (unlikely(mode & (S_ISUID | S_ISGID)))
24568 + reqmode |= GR_SETID;
24570 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
24571 + reqmode, GR_MKNOD_ACL_MSG);
24575 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
24576 + const struct dentry *parent_dentry,
24577 + const struct vfsmount *parent_mnt)
24579 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
24580 + GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
24583 +#define RENAME_CHECK_SUCCESS(old, new) \
24584 + (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
24585 + ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
24588 +gr_acl_handle_rename(struct dentry *new_dentry,
24589 + struct dentry *parent_dentry,
24590 + const struct vfsmount *parent_mnt,
24591 + struct dentry *old_dentry,
24592 + struct inode *old_parent_inode,
24593 + struct vfsmount *old_mnt, const char *newname)
24595 + __u32 comp1, comp2;
24598 + if (unlikely(!gr_acl_is_enabled()))
24601 + if (!new_dentry->d_inode) {
24602 + comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
24603 + GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
24604 + GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
24605 + comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
24606 + GR_DELETE | GR_AUDIT_DELETE |
24607 + GR_AUDIT_READ | GR_AUDIT_WRITE |
24608 + GR_SUPPRESS, old_mnt);
24610 + comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
24611 + GR_CREATE | GR_DELETE |
24612 + GR_AUDIT_CREATE | GR_AUDIT_DELETE |
24613 + GR_AUDIT_READ | GR_AUDIT_WRITE |
24614 + GR_SUPPRESS, parent_mnt);
24616 + gr_search_file(old_dentry,
24617 + GR_READ | GR_WRITE | GR_AUDIT_READ |
24618 + GR_DELETE | GR_AUDIT_DELETE |
24619 + GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
24622 + if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
24623 + ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
24624 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
24625 + else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
24626 + && !(comp2 & GR_SUPPRESS)) {
24627 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
24629 + } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
24636 +gr_acl_handle_exit(void)
24640 + struct file *exec_file;
24642 + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
24643 + id = current->acl_role_id;
24644 + rolename = current->role->rolename;
24646 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
24649 + write_lock(&grsec_exec_file_lock);
24650 + exec_file = current->exec_file;
24651 + current->exec_file = NULL;
24652 + write_unlock(&grsec_exec_file_lock);
24659 +gr_acl_handle_procpidmem(const struct task_struct *task)
24661 + if (unlikely(!gr_acl_is_enabled()))
24664 + if (task != current && task->acl->mode & GR_PROTPROCFD)
24669 diff -urNp linux-2.6.29/grsecurity/gracl_ip.c linux-2.6.29/grsecurity/gracl_ip.c
24670 --- linux-2.6.29/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
24671 +++ linux-2.6.29/grsecurity/gracl_ip.c 2009-03-28 14:26:20.000000000 -0400
24673 +#include <linux/kernel.h>
24674 +#include <asm/uaccess.h>
24675 +#include <asm/errno.h>
24676 +#include <net/sock.h>
24677 +#include <linux/file.h>
24678 +#include <linux/fs.h>
24679 +#include <linux/net.h>
24680 +#include <linux/in.h>
24681 +#include <linux/skbuff.h>
24682 +#include <linux/ip.h>
24683 +#include <linux/udp.h>
24684 +#include <linux/smp_lock.h>
24685 +#include <linux/types.h>
24686 +#include <linux/sched.h>
24687 +#include <linux/netdevice.h>
24688 +#include <linux/inetdevice.h>
24689 +#include <linux/gracl.h>
24690 +#include <linux/grsecurity.h>
24691 +#include <linux/grinternal.h>
24693 +#define GR_BIND 0x01
24694 +#define GR_CONNECT 0x02
24695 +#define GR_INVERT 0x04
24696 +#define GR_BINDOVERRIDE 0x08
24697 +#define GR_CONNECTOVERRIDE 0x10
24699 +static const char * gr_protocols[256] = {
24700 + "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
24701 + "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
24702 + "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
24703 + "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
24704 + "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
24705 + "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
24706 + "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
24707 + "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
24708 + "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
24709 + "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
24710 + "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
24711 + "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
24712 + "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
24713 + "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
24714 + "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
24715 + "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
24716 + "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
24717 + "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
24718 + "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
24719 + "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
24720 + "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
24721 + "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
24722 + "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
24723 + "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
24724 + "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
24725 + "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
24726 + "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
24727 + "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
24728 + "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
24729 + "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
24730 + "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
24731 + "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
24734 +static const char * gr_socktypes[11] = {
24735 + "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
24736 + "unknown:7", "unknown:8", "unknown:9", "packet"
24740 +gr_proto_to_name(unsigned char proto)
24742 + return gr_protocols[proto];
24746 +gr_socktype_to_name(unsigned char type)
24748 + return gr_socktypes[type];
24752 +gr_search_socket(const int domain, const int type, const int protocol)
24754 + struct acl_subject_label *curr;
24755 + const struct cred *cred = current_cred();
24757 + if (unlikely(!gr_acl_is_enabled()))
24760 + if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
24761 + || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
24762 + goto exit; // let the kernel handle it
24764 + curr = current->acl;
24769 + if ((curr->ip_type & (1 << type)) &&
24770 + (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
24773 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
24774 + /* we don't place acls on raw sockets , and sometimes
24775 + dgram/ip sockets are opened for ioctl and not
24776 + bind/connect, so we'll fake a bind learn log */
24777 + if (type == SOCK_RAW || type == SOCK_PACKET) {
24778 + __u32 fakeip = 0;
24779 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24780 + current->role->roletype, cred->uid,
24781 + cred->gid, current->exec_file ?
24782 + gr_to_filename(current->exec_file->f_path.dentry,
24783 + current->exec_file->f_path.mnt) :
24784 + curr->filename, curr->filename,
24785 + NIPQUAD(fakeip), 0, type,
24786 + protocol, GR_CONNECT,
24787 +NIPQUAD(current->signal->curr_ip));
24788 + } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
24789 + __u32 fakeip = 0;
24790 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24791 + current->role->roletype, cred->uid,
24792 + cred->gid, current->exec_file ?
24793 + gr_to_filename(current->exec_file->f_path.dentry,
24794 + current->exec_file->f_path.mnt) :
24795 + curr->filename, curr->filename,
24796 + NIPQUAD(fakeip), 0, type,
24797 + protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
24799 + /* we'll log when they use connect or bind */
24803 + gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
24804 + gr_socktype_to_name(type), gr_proto_to_name(protocol));
24811 +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)
24813 + if ((ip->mode & mode) &&
24814 + (ip_port >= ip->low) &&
24815 + (ip_port <= ip->high) &&
24816 + ((ntohl(ip_addr) & our_netmask) ==
24817 + (ntohl(our_addr) & our_netmask))
24818 + && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
24819 + && (ip->type & (1 << type))) {
24820 + if (ip->mode & GR_INVERT)
24821 + return 2; // specifically denied
24823 + return 1; // allowed
24826 + return 0; // not specifically allowed, may continue parsing
24830 +gr_search_connectbind(const int full_mode, struct sock *sk,
24831 + struct sockaddr_in *addr, const int type)
24833 + char iface[IFNAMSIZ] = {0};
24834 + struct acl_subject_label *curr;
24835 + struct acl_ip_label *ip;
24836 + struct inet_sock *isk;
24837 + struct net_device *dev;
24838 + struct in_device *idev;
24841 + int mode = full_mode & (GR_BIND | GR_CONNECT);
24842 + __u32 ip_addr = 0;
24844 + __u32 our_netmask;
24846 + __u16 ip_port = 0;
24847 + const struct cred *cred = current_cred();
24849 + if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
24852 + curr = current->acl;
24853 + isk = inet_sk(sk);
24855 + /* INADDR_ANY overriding for binds, inaddr_any_override is already in network order */
24856 + if ((full_mode & GR_BINDOVERRIDE) && addr->sin_addr.s_addr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0)
24857 + addr->sin_addr.s_addr = curr->inaddr_any_override;
24858 + if ((full_mode & GR_CONNECT) && isk->saddr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0) {
24859 + struct sockaddr_in saddr;
24862 + saddr.sin_family = AF_INET;
24863 + saddr.sin_addr.s_addr = curr->inaddr_any_override;
24864 + saddr.sin_port = isk->sport;
24866 + err = security_socket_bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
24870 + err = sk->sk_socket->ops->bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
24878 + ip_addr = addr->sin_addr.s_addr;
24879 + ip_port = ntohs(addr->sin_port);
24881 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
24882 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24883 + current->role->roletype, cred->uid,
24884 + cred->gid, current->exec_file ?
24885 + gr_to_filename(current->exec_file->f_path.dentry,
24886 + current->exec_file->f_path.mnt) :
24887 + curr->filename, curr->filename,
24888 + NIPQUAD(ip_addr), ip_port, type,
24889 + sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
24893 + for (i = 0; i < curr->ip_num; i++) {
24894 + ip = *(curr->ips + i);
24895 + if (ip->iface != NULL) {
24896 + strncpy(iface, ip->iface, IFNAMSIZ - 1);
24897 + p = strchr(iface, ':');
24900 + dev = dev_get_by_name(sock_net(sk), iface);
24903 + idev = in_dev_get(dev);
24904 + if (idev == NULL) {
24910 + if (!strcmp(ip->iface, ifa->ifa_label)) {
24911 + our_addr = ifa->ifa_address;
24912 + our_netmask = 0xffffffff;
24913 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
24915 + rcu_read_unlock();
24916 + in_dev_put(idev);
24919 + } else if (ret == 2) {
24920 + rcu_read_unlock();
24921 + in_dev_put(idev);
24926 + } endfor_ifa(idev);
24927 + rcu_read_unlock();
24928 + in_dev_put(idev);
24931 + our_addr = ip->addr;
24932 + our_netmask = ip->netmask;
24933 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
24936 + else if (ret == 2)
24942 + if (mode == GR_BIND)
24943 + 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));
24944 + else if (mode == GR_CONNECT)
24945 + 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));
24951 +gr_search_connect(struct socket *sock, struct sockaddr_in *addr)
24953 + return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sock->sk, addr, sock->type);
24957 +gr_search_bind(struct socket *sock, struct sockaddr_in *addr)
24959 + return gr_search_connectbind(GR_BIND | GR_BINDOVERRIDE, sock->sk, addr, sock->type);
24962 +int gr_search_listen(struct socket *sock)
24964 + struct sock *sk = sock->sk;
24965 + struct sockaddr_in addr;
24967 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
24968 + addr.sin_port = inet_sk(sk)->sport;
24970 + return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
24973 +int gr_search_accept(struct socket *sock)
24975 + struct sock *sk = sock->sk;
24976 + struct sockaddr_in addr;
24978 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
24979 + addr.sin_port = inet_sk(sk)->sport;
24981 + return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
24985 +gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr)
24988 + return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
24990 + struct sockaddr_in sin;
24991 + const struct inet_sock *inet = inet_sk(sk);
24993 + sin.sin_addr.s_addr = inet->daddr;
24994 + sin.sin_port = inet->dport;
24996 + return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
25001 +gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb)
25003 + struct sockaddr_in sin;
25005 + if (unlikely(skb->len < sizeof (struct udphdr)))
25006 + return 0; // skip this packet
25008 + sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
25009 + sin.sin_port = udp_hdr(skb)->source;
25011 + return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
25013 diff -urNp linux-2.6.29/grsecurity/gracl_learn.c linux-2.6.29/grsecurity/gracl_learn.c
25014 --- linux-2.6.29/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
25015 +++ linux-2.6.29/grsecurity/gracl_learn.c 2009-03-28 14:26:20.000000000 -0400
25017 +#include <linux/kernel.h>
25018 +#include <linux/mm.h>
25019 +#include <linux/sched.h>
25020 +#include <linux/poll.h>
25021 +#include <linux/smp_lock.h>
25022 +#include <linux/string.h>
25023 +#include <linux/file.h>
25024 +#include <linux/types.h>
25025 +#include <linux/vmalloc.h>
25026 +#include <linux/grinternal.h>
25028 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
25029 + size_t count, loff_t *ppos);
25030 +extern int gr_acl_is_enabled(void);
25032 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
25033 +static int gr_learn_attached;
25035 +/* use a 512k buffer */
25036 +#define LEARN_BUFFER_SIZE (512 * 1024)
25038 +static DEFINE_SPINLOCK(gr_learn_lock);
25039 +static DECLARE_MUTEX(gr_learn_user_sem);
25041 +/* we need to maintain two buffers, so that the kernel context of grlearn
25042 + uses a semaphore around the userspace copying, and the other kernel contexts
25043 + use a spinlock when copying into the buffer, since they cannot sleep
25045 +static char *learn_buffer;
25046 +static char *learn_buffer_user;
25047 +static int learn_buffer_len;
25048 +static int learn_buffer_user_len;
25051 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
25053 + DECLARE_WAITQUEUE(wait, current);
25054 + ssize_t retval = 0;
25056 + add_wait_queue(&learn_wait, &wait);
25057 + set_current_state(TASK_INTERRUPTIBLE);
25059 + down(&gr_learn_user_sem);
25060 + spin_lock(&gr_learn_lock);
25061 + if (learn_buffer_len)
25063 + spin_unlock(&gr_learn_lock);
25064 + up(&gr_learn_user_sem);
25065 + if (file->f_flags & O_NONBLOCK) {
25066 + retval = -EAGAIN;
25069 + if (signal_pending(current)) {
25070 + retval = -ERESTARTSYS;
25077 + memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
25078 + learn_buffer_user_len = learn_buffer_len;
25079 + retval = learn_buffer_len;
25080 + learn_buffer_len = 0;
25082 + spin_unlock(&gr_learn_lock);
25084 + if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
25085 + retval = -EFAULT;
25087 + up(&gr_learn_user_sem);
25089 + set_current_state(TASK_RUNNING);
25090 + remove_wait_queue(&learn_wait, &wait);
25094 +static unsigned int
25095 +poll_learn(struct file * file, poll_table * wait)
25097 + poll_wait(file, &learn_wait, wait);
25099 + if (learn_buffer_len)
25100 + return (POLLIN | POLLRDNORM);
25106 +gr_clear_learn_entries(void)
25110 + down(&gr_learn_user_sem);
25111 + if (learn_buffer != NULL) {
25112 + spin_lock(&gr_learn_lock);
25113 + tmp = learn_buffer;
25114 + learn_buffer = NULL;
25115 + spin_unlock(&gr_learn_lock);
25116 + vfree(learn_buffer);
25118 + if (learn_buffer_user != NULL) {
25119 + vfree(learn_buffer_user);
25120 + learn_buffer_user = NULL;
25122 + learn_buffer_len = 0;
25123 + up(&gr_learn_user_sem);
25129 +gr_add_learn_entry(const char *fmt, ...)
25132 + unsigned int len;
25134 + if (!gr_learn_attached)
25137 + spin_lock(&gr_learn_lock);
25139 + /* leave a gap at the end so we know when it's "full" but don't have to
25140 + compute the exact length of the string we're trying to append
25142 + if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
25143 + spin_unlock(&gr_learn_lock);
25144 + wake_up_interruptible(&learn_wait);
25147 + if (learn_buffer == NULL) {
25148 + spin_unlock(&gr_learn_lock);
25152 + va_start(args, fmt);
25153 + len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
25156 + learn_buffer_len += len + 1;
25158 + spin_unlock(&gr_learn_lock);
25159 + wake_up_interruptible(&learn_wait);
25165 +open_learn(struct inode *inode, struct file *file)
25167 + if (file->f_mode & FMODE_READ && gr_learn_attached)
25169 + if (file->f_mode & FMODE_READ) {
25171 + down(&gr_learn_user_sem);
25172 + if (learn_buffer == NULL)
25173 + learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
25174 + if (learn_buffer_user == NULL)
25175 + learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
25176 + if (learn_buffer == NULL) {
25177 + retval = -ENOMEM;
25180 + if (learn_buffer_user == NULL) {
25181 + retval = -ENOMEM;
25184 + learn_buffer_len = 0;
25185 + learn_buffer_user_len = 0;
25186 + gr_learn_attached = 1;
25188 + up(&gr_learn_user_sem);
25195 +close_learn(struct inode *inode, struct file *file)
25199 + if (file->f_mode & FMODE_READ) {
25200 + down(&gr_learn_user_sem);
25201 + if (learn_buffer != NULL) {
25202 + spin_lock(&gr_learn_lock);
25203 + tmp = learn_buffer;
25204 + learn_buffer = NULL;
25205 + spin_unlock(&gr_learn_lock);
25208 + if (learn_buffer_user != NULL) {
25209 + vfree(learn_buffer_user);
25210 + learn_buffer_user = NULL;
25212 + learn_buffer_len = 0;
25213 + learn_buffer_user_len = 0;
25214 + gr_learn_attached = 0;
25215 + up(&gr_learn_user_sem);
25221 +struct file_operations grsec_fops = {
25222 + .read = read_learn,
25223 + .write = write_grsec_handler,
25224 + .open = open_learn,
25225 + .release = close_learn,
25226 + .poll = poll_learn,
25228 diff -urNp linux-2.6.29/grsecurity/gracl_res.c linux-2.6.29/grsecurity/gracl_res.c
25229 --- linux-2.6.29/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
25230 +++ linux-2.6.29/grsecurity/gracl_res.c 2009-03-28 14:39:44.000000000 -0400
25232 +#include <linux/kernel.h>
25233 +#include <linux/sched.h>
25234 +#include <linux/gracl.h>
25235 +#include <linux/grinternal.h>
25237 +static const char *restab_log[] = {
25238 + [RLIMIT_CPU] = "RLIMIT_CPU",
25239 + [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
25240 + [RLIMIT_DATA] = "RLIMIT_DATA",
25241 + [RLIMIT_STACK] = "RLIMIT_STACK",
25242 + [RLIMIT_CORE] = "RLIMIT_CORE",
25243 + [RLIMIT_RSS] = "RLIMIT_RSS",
25244 + [RLIMIT_NPROC] = "RLIMIT_NPROC",
25245 + [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
25246 + [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
25247 + [RLIMIT_AS] = "RLIMIT_AS",
25248 + [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
25249 + [RLIMIT_SIGPENDING] = "RLIMIT_SIGPENDING",
25250 + [RLIMIT_MSGQUEUE] = "RLIMIT_MSGQUEUE",
25251 + [RLIMIT_NICE] = "RLIMIT_NICE",
25252 + [RLIMIT_RTPRIO] = "RLIMIT_RTPRIO",
25253 + [RLIMIT_RTTIME] = "RLIMIT_RTTIME",
25254 + [GR_CRASH_RES] = "RLIMIT_CRASH"
25258 +gr_log_resource(const struct task_struct *task,
25259 + const int res, const unsigned long wanted, const int gt)
25261 + const struct cred *cred = __task_cred(task);
25263 + if (res == RLIMIT_NPROC &&
25264 + (cap_raised(cred->cap_effective, CAP_SYS_ADMIN) ||
25265 + cap_raised(cred->cap_effective, CAP_SYS_RESOURCE)))
25267 + else if (res == RLIMIT_MEMLOCK &&
25268 + cap_raised(cred->cap_effective, CAP_IPC_LOCK))
25270 + else if (res == RLIMIT_NICE && cap_raised(cred->cap_effective, CAP_SYS_NICE))
25273 + if (!gr_acl_is_enabled() && !grsec_resource_logging)
25276 + preempt_disable();
25278 + if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
25279 + (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
25280 + task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
25281 + gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
25282 + preempt_enable_no_resched();
25286 diff -urNp linux-2.6.29/grsecurity/gracl_segv.c linux-2.6.29/grsecurity/gracl_segv.c
25287 --- linux-2.6.29/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
25288 +++ linux-2.6.29/grsecurity/gracl_segv.c 2009-03-28 14:26:20.000000000 -0400
25290 +#include <linux/kernel.h>
25291 +#include <linux/mm.h>
25292 +#include <asm/uaccess.h>
25293 +#include <asm/errno.h>
25294 +#include <asm/mman.h>
25295 +#include <net/sock.h>
25296 +#include <linux/file.h>
25297 +#include <linux/fs.h>
25298 +#include <linux/net.h>
25299 +#include <linux/in.h>
25300 +#include <linux/smp_lock.h>
25301 +#include <linux/slab.h>
25302 +#include <linux/types.h>
25303 +#include <linux/sched.h>
25304 +#include <linux/timer.h>
25305 +#include <linux/gracl.h>
25306 +#include <linux/grsecurity.h>
25307 +#include <linux/grinternal.h>
25309 +static struct crash_uid *uid_set;
25310 +static unsigned short uid_used;
25311 +static DEFINE_SPINLOCK(gr_uid_lock);
25312 +extern rwlock_t gr_inode_lock;
25313 +extern struct acl_subject_label *
25314 + lookup_acl_subj_label(const ino_t inode, const dev_t dev,
25315 + struct acl_role_label *role);
25316 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
25319 +gr_init_uidset(void)
25322 + kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
25325 + return uid_set ? 1 : 0;
25329 +gr_free_uidset(void)
25338 +gr_find_uid(const uid_t uid)
25340 + struct crash_uid *tmp = uid_set;
25342 + int low = 0, high = uid_used - 1, mid;
25344 + while (high >= low) {
25345 + mid = (low + high) >> 1;
25346 + buid = tmp[mid].uid;
25358 +static __inline__ void
25359 +gr_insertsort(void)
25361 + unsigned short i, j;
25362 + struct crash_uid index;
25364 + for (i = 1; i < uid_used; i++) {
25365 + index = uid_set[i];
25367 + while ((j > 0) && uid_set[j - 1].uid > index.uid) {
25368 + uid_set[j] = uid_set[j - 1];
25371 + uid_set[j] = index;
25377 +static __inline__ void
25378 +gr_insert_uid(const uid_t uid, const unsigned long expires)
25382 + if (uid_used == GR_UIDTABLE_MAX)
25385 + loc = gr_find_uid(uid);
25388 + uid_set[loc].expires = expires;
25392 + uid_set[uid_used].uid = uid;
25393 + uid_set[uid_used].expires = expires;
25402 +gr_remove_uid(const unsigned short loc)
25404 + unsigned short i;
25406 + for (i = loc + 1; i < uid_used; i++)
25407 + uid_set[i - 1] = uid_set[i];
25415 +gr_check_crash_uid(const uid_t uid)
25420 + if (unlikely(!gr_acl_is_enabled()))
25423 + spin_lock(&gr_uid_lock);
25424 + loc = gr_find_uid(uid);
25429 + if (time_before_eq(uid_set[loc].expires, get_seconds()))
25430 + gr_remove_uid(loc);
25435 + spin_unlock(&gr_uid_lock);
25439 +static __inline__ int
25440 +proc_is_setxid(const struct cred *cred)
25442 + if (cred->uid != cred->euid || cred->uid != cred->suid ||
25443 + cred->uid != cred->fsuid)
25445 + if (cred->gid != cred->egid || cred->gid != cred->sgid ||
25446 + cred->gid != cred->fsgid)
25451 +static __inline__ int
25452 +gr_fake_force_sig(int sig, struct task_struct *t)
25454 + unsigned long int flags;
25455 + int ret, blocked, ignored;
25456 + struct k_sigaction *action;
25458 + spin_lock_irqsave(&t->sighand->siglock, flags);
25459 + action = &t->sighand->action[sig-1];
25460 + ignored = action->sa.sa_handler == SIG_IGN;
25461 + blocked = sigismember(&t->blocked, sig);
25462 + if (blocked || ignored) {
25463 + action->sa.sa_handler = SIG_DFL;
25465 + sigdelset(&t->blocked, sig);
25466 + recalc_sigpending_and_wake(t);
25469 + if (action->sa.sa_handler == SIG_DFL)
25470 + t->signal->flags &= ~SIGNAL_UNKILLABLE;
25471 + ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
25473 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
25479 +gr_handle_crash(struct task_struct *task, const int sig)
25481 + struct acl_subject_label *curr;
25482 + struct acl_subject_label *curr2;
25483 + struct task_struct *tsk, *tsk2;
25484 + const struct cred *cred = __task_cred(task);
25485 + const struct cred *cred2;
25487 + if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
25490 + if (unlikely(!gr_acl_is_enabled()))
25493 + curr = task->acl;
25495 + if (!(curr->resmask & (1 << GR_CRASH_RES)))
25498 + if (time_before_eq(curr->expires, get_seconds())) {
25499 + curr->expires = 0;
25500 + curr->crashes = 0;
25505 + if (!curr->expires)
25506 + curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
25508 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
25509 + time_after(curr->expires, get_seconds())) {
25510 + if (cred->uid && proc_is_setxid(cred)) {
25511 + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
25512 + spin_lock(&gr_uid_lock);
25513 + gr_insert_uid(cred->uid, curr->expires);
25514 + spin_unlock(&gr_uid_lock);
25515 + curr->expires = 0;
25516 + curr->crashes = 0;
25517 + read_lock(&tasklist_lock);
25518 + do_each_thread(tsk2, tsk) {
25519 + cred2 = __task_cred(tsk);
25520 + if (tsk != task && cred2->uid == cred->uid)
25521 + gr_fake_force_sig(SIGKILL, tsk);
25522 + } while_each_thread(tsk2, tsk);
25523 + read_unlock(&tasklist_lock);
25525 + gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
25526 + read_lock(&tasklist_lock);
25527 + do_each_thread(tsk2, tsk) {
25528 + if (likely(tsk != task)) {
25529 + curr2 = tsk->acl;
25531 + if (curr2->device == curr->device &&
25532 + curr2->inode == curr->inode)
25533 + gr_fake_force_sig(SIGKILL, tsk);
25535 + } while_each_thread(tsk2, tsk);
25536 + read_unlock(&tasklist_lock);
25544 +gr_check_crash_exec(const struct file *filp)
25546 + struct acl_subject_label *curr;
25548 + if (unlikely(!gr_acl_is_enabled()))
25551 + read_lock(&gr_inode_lock);
25552 + curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
25553 + filp->f_path.dentry->d_inode->i_sb->s_dev,
25555 + read_unlock(&gr_inode_lock);
25557 + if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
25558 + (!curr->crashes && !curr->expires))
25561 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
25562 + time_after(curr->expires, get_seconds()))
25564 + else if (time_before_eq(curr->expires, get_seconds())) {
25565 + curr->crashes = 0;
25566 + curr->expires = 0;
25573 +gr_handle_alertkill(struct task_struct *task)
25575 + struct acl_subject_label *curracl;
25577 + struct task_struct *p, *p2;
25579 + if (unlikely(!gr_acl_is_enabled()))
25582 + curracl = task->acl;
25583 + curr_ip = task->signal->curr_ip;
25585 + if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
25586 + read_lock(&tasklist_lock);
25587 + do_each_thread(p2, p) {
25588 + if (p->signal->curr_ip == curr_ip)
25589 + gr_fake_force_sig(SIGKILL, p);
25590 + } while_each_thread(p2, p);
25591 + read_unlock(&tasklist_lock);
25592 + } else if (curracl->mode & GR_KILLPROC)
25593 + gr_fake_force_sig(SIGKILL, task);
25597 diff -urNp linux-2.6.29/grsecurity/gracl_shm.c linux-2.6.29/grsecurity/gracl_shm.c
25598 --- linux-2.6.29/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
25599 +++ linux-2.6.29/grsecurity/gracl_shm.c 2009-03-28 14:26:20.000000000 -0400
25601 +#include <linux/kernel.h>
25602 +#include <linux/mm.h>
25603 +#include <linux/sched.h>
25604 +#include <linux/file.h>
25605 +#include <linux/ipc.h>
25606 +#include <linux/gracl.h>
25607 +#include <linux/grsecurity.h>
25608 +#include <linux/grinternal.h>
25611 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25612 + const time_t shm_createtime, const uid_t cuid, const int shmid)
25614 + struct task_struct *task;
25616 + if (!gr_acl_is_enabled())
25619 + read_lock(&tasklist_lock);
25621 + task = find_task_by_vpid(shm_cprid);
25623 + if (unlikely(!task))
25624 + task = find_task_by_vpid(shm_lapid);
25626 + if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
25627 + (task->pid == shm_lapid)) &&
25628 + (task->acl->mode & GR_PROTSHM) &&
25629 + (task->acl != current->acl))) {
25630 + read_unlock(&tasklist_lock);
25631 + gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
25634 + read_unlock(&tasklist_lock);
25638 diff -urNp linux-2.6.29/grsecurity/grsec_chdir.c linux-2.6.29/grsecurity/grsec_chdir.c
25639 --- linux-2.6.29/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
25640 +++ linux-2.6.29/grsecurity/grsec_chdir.c 2009-03-28 14:26:20.000000000 -0400
25642 +#include <linux/kernel.h>
25643 +#include <linux/sched.h>
25644 +#include <linux/fs.h>
25645 +#include <linux/file.h>
25646 +#include <linux/grsecurity.h>
25647 +#include <linux/grinternal.h>
25650 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
25652 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
25653 + if ((grsec_enable_chdir && grsec_enable_group &&
25654 + in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
25655 + !grsec_enable_group)) {
25656 + gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
25661 diff -urNp linux-2.6.29/grsecurity/grsec_chroot.c linux-2.6.29/grsecurity/grsec_chroot.c
25662 --- linux-2.6.29/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
25663 +++ linux-2.6.29/grsecurity/grsec_chroot.c 2009-03-28 15:25:26.000000000 -0400
25665 +#include <linux/kernel.h>
25666 +#include <linux/module.h>
25667 +#include <linux/sched.h>
25668 +#include <linux/file.h>
25669 +#include <linux/fs.h>
25670 +#include <linux/mount.h>
25671 +#include <linux/types.h>
25672 +#include <linux/pid_namespace.h>
25673 +#include <linux/grsecurity.h>
25674 +#include <linux/grinternal.h>
25677 +gr_handle_chroot_unix(const pid_t pid)
25679 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
25680 + struct pid *spid = NULL;
25682 + if (unlikely(!grsec_enable_chroot_unix))
25685 + if (likely(!proc_is_chrooted(current)))
25688 + read_lock(&tasklist_lock);
25690 + spid = find_vpid(pid);
25692 + struct task_struct *p;
25693 + p = pid_task(spid, PIDTYPE_PID);
25695 + if (unlikely(!have_same_root(current, p))) {
25697 + read_unlock(&tasklist_lock);
25698 + gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
25703 + read_unlock(&tasklist_lock);
25709 +gr_handle_chroot_nice(void)
25711 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25712 + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
25713 + gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
25721 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
25723 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25724 + if (grsec_enable_chroot_nice && (niceval < task_nice(p))
25725 + && proc_is_chrooted(current)) {
25726 + gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
25734 +gr_handle_chroot_rawio(const struct inode *inode)
25736 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25737 + if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
25738 + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
25745 +gr_pid_is_chrooted(struct task_struct *p)
25747 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
25748 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
25752 + if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
25753 + !have_same_root(current, p)) {
25762 +EXPORT_SYMBOL(gr_pid_is_chrooted);
25764 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
25765 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
25767 + struct dentry *dentry = (struct dentry *)u_dentry;
25768 + struct vfsmount *mnt = (struct vfsmount *)u_mnt;
25769 + struct dentry *realroot;
25770 + struct vfsmount *realrootmnt;
25771 + struct dentry *currentroot;
25772 + struct vfsmount *currentmnt;
25773 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
25776 + read_lock(&reaper->fs->lock);
25777 + realrootmnt = mntget(reaper->fs->root.mnt);
25778 + realroot = dget(reaper->fs->root.dentry);
25779 + read_unlock(&reaper->fs->lock);
25781 + read_lock(¤t->fs->lock);
25782 + currentmnt = mntget(current->fs->root.mnt);
25783 + currentroot = dget(current->fs->root.dentry);
25784 + read_unlock(¤t->fs->lock);
25786 + spin_lock(&dcache_lock);
25788 + if (unlikely((dentry == realroot && mnt == realrootmnt)
25789 + || (dentry == currentroot && mnt == currentmnt)))
25791 + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
25792 + if (mnt->mnt_parent == mnt)
25794 + dentry = mnt->mnt_mountpoint;
25795 + mnt = mnt->mnt_parent;
25798 + dentry = dentry->d_parent;
25800 + spin_unlock(&dcache_lock);
25802 + dput(currentroot);
25803 + mntput(currentmnt);
25805 + /* access is outside of chroot */
25806 + if (dentry == realroot && mnt == realrootmnt)
25810 + mntput(realrootmnt);
25816 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
25818 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
25819 + if (!grsec_enable_chroot_fchdir)
25822 + if (!proc_is_chrooted(current))
25824 + else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
25825 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
25833 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25834 + const time_t shm_createtime)
25836 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
25837 + struct pid *pid = NULL;
25838 + time_t starttime;
25840 + if (unlikely(!grsec_enable_chroot_shmat))
25843 + if (likely(!proc_is_chrooted(current)))
25846 + read_lock(&tasklist_lock);
25848 + pid = find_vpid(shm_cprid);
25850 + struct task_struct *p;
25851 + p = pid_task(pid, PIDTYPE_PID);
25853 + starttime = p->start_time.tv_sec;
25854 + if (unlikely(!have_same_root(current, p) &&
25855 + time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
25857 + read_unlock(&tasklist_lock);
25858 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
25863 + pid = find_vpid(shm_lapid);
25865 + struct task_struct *p;
25866 + p = pid_task(pid, PIDTYPE_PID);
25868 + if (unlikely(!have_same_root(current, p))) {
25870 + read_unlock(&tasklist_lock);
25871 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
25878 + read_unlock(&tasklist_lock);
25884 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
25886 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
25887 + if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
25888 + gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
25894 +gr_handle_chroot_mknod(const struct dentry *dentry,
25895 + const struct vfsmount *mnt, const int mode)
25897 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
25898 + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
25899 + proc_is_chrooted(current)) {
25900 + gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
25908 +gr_handle_chroot_mount(const struct dentry *dentry,
25909 + const struct vfsmount *mnt, const char *dev_name)
25911 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
25912 + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
25913 + gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
25921 +gr_handle_chroot_pivot(void)
25923 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
25924 + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
25925 + gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
25933 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
25935 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
25936 + if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
25937 + !gr_is_outside_chroot(dentry, mnt)) {
25938 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
25946 +gr_handle_chroot_caps(struct path *path)
25948 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25949 + if (grsec_enable_chroot_caps && current->pid > 1 && current->fs != NULL &&
25950 + ((current->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb !=
25951 + path->dentry->d_inode->i_sb) ||
25952 + (current->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino !=
25953 + path->dentry->d_inode->i_ino))) {
25955 + kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
25956 + const struct cred *old = current_cred();
25957 + struct cred *new = prepare_creds();
25961 + new->cap_permitted = cap_drop(old->cap_permitted,
25963 + new->cap_inheritable = cap_drop(old->cap_inheritable,
25965 + new->cap_effective = cap_drop(old->cap_effective,
25968 + commit_creds(new);
25977 +gr_handle_chroot_sysctl(const int op)
25979 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
25980 + if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
25981 + && (op & MAY_WRITE))
25988 +gr_handle_chroot_chdir(struct path *path)
25990 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
25991 + if (grsec_enable_chroot_chdir)
25992 + set_fs_pwd(current->fs, path);
25998 +gr_handle_chroot_chmod(const struct dentry *dentry,
25999 + const struct vfsmount *mnt, const int mode)
26001 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
26002 + if (grsec_enable_chroot_chmod &&
26003 + ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
26004 + proc_is_chrooted(current)) {
26005 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
26012 +#ifdef CONFIG_SECURITY
26013 +EXPORT_SYMBOL(gr_handle_chroot_caps);
26015 diff -urNp linux-2.6.29/grsecurity/grsec_disabled.c linux-2.6.29/grsecurity/grsec_disabled.c
26016 --- linux-2.6.29/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
26017 +++ linux-2.6.29/grsecurity/grsec_disabled.c 2009-03-28 14:26:20.000000000 -0400
26019 +#include <linux/kernel.h>
26020 +#include <linux/module.h>
26021 +#include <linux/sched.h>
26022 +#include <linux/file.h>
26023 +#include <linux/fs.h>
26024 +#include <linux/kdev_t.h>
26025 +#include <linux/net.h>
26026 +#include <linux/in.h>
26027 +#include <linux/ip.h>
26028 +#include <linux/skbuff.h>
26029 +#include <linux/sysctl.h>
26031 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
26033 +pax_set_initial_flags(struct linux_binprm *bprm)
26039 +#ifdef CONFIG_SYSCTL
26041 +gr_handle_sysctl(const struct ctl_table * table, const int op)
26048 +gr_acl_is_enabled(void)
26054 +gr_handle_rawio(const struct inode *inode)
26060 +gr_acl_handle_psacct(struct task_struct *task, const long code)
26066 +gr_handle_ptrace(struct task_struct *task, const long request)
26072 +gr_handle_proc_ptrace(struct task_struct *task)
26078 +gr_learn_resource(const struct task_struct *task,
26079 + const int res, const unsigned long wanted, const int gt)
26085 +gr_set_acls(const int type)
26091 +gr_check_hidden_task(const struct task_struct *tsk)
26097 +gr_check_protected_task(const struct task_struct *task)
26103 +gr_copy_label(struct task_struct *tsk)
26109 +gr_set_pax_flags(struct task_struct *task)
26115 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
26121 +gr_handle_delete(const ino_t ino, const dev_t dev)
26127 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
26133 +gr_handle_crash(struct task_struct *task, const int sig)
26139 +gr_check_crash_exec(const struct file *filp)
26145 +gr_check_crash_uid(const uid_t uid)
26151 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
26152 + struct dentry *old_dentry,
26153 + struct dentry *new_dentry,
26154 + struct vfsmount *mnt, const __u8 replace)
26160 +gr_search_socket(const int family, const int type, const int protocol)
26166 +gr_search_connectbind(const int mode, const struct socket *sock,
26167 + const struct sockaddr_in *addr)
26173 +gr_is_capable(const int cap)
26179 +gr_is_capable_nolog(const int cap)
26185 +gr_handle_alertkill(struct task_struct *task)
26191 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
26197 +gr_acl_handle_hidden_file(const struct dentry * dentry,
26198 + const struct vfsmount * mnt)
26204 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
26211 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
26217 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
26223 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
26224 + unsigned int *vm_flags)
26230 +gr_acl_handle_truncate(const struct dentry * dentry,
26231 + const struct vfsmount * mnt)
26237 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
26243 +gr_acl_handle_access(const struct dentry * dentry,
26244 + const struct vfsmount * mnt, const int fmode)
26250 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
26257 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
26264 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
26270 +grsecurity_init(void)
26276 +gr_acl_handle_mknod(const struct dentry * new_dentry,
26277 + const struct dentry * parent_dentry,
26278 + const struct vfsmount * parent_mnt,
26285 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
26286 + const struct dentry * parent_dentry,
26287 + const struct vfsmount * parent_mnt)
26293 +gr_acl_handle_symlink(const struct dentry * new_dentry,
26294 + const struct dentry * parent_dentry,
26295 + const struct vfsmount * parent_mnt, const char *from)
26301 +gr_acl_handle_link(const struct dentry * new_dentry,
26302 + const struct dentry * parent_dentry,
26303 + const struct vfsmount * parent_mnt,
26304 + const struct dentry * old_dentry,
26305 + const struct vfsmount * old_mnt, const char *to)
26311 +gr_acl_handle_rename(const struct dentry *new_dentry,
26312 + const struct dentry *parent_dentry,
26313 + const struct vfsmount *parent_mnt,
26314 + const struct dentry *old_dentry,
26315 + const struct inode *old_parent_inode,
26316 + const struct vfsmount *old_mnt, const char *newname)
26322 +gr_acl_handle_filldir(const struct file *file, const char *name,
26323 + const int namelen, const ino_t ino)
26329 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
26330 + const time_t shm_createtime, const uid_t cuid, const int shmid)
26336 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
26342 +gr_search_accept(const struct socket *sock)
26348 +gr_search_listen(const struct socket *sock)
26354 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
26360 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
26366 +gr_acl_handle_creat(const struct dentry * dentry,
26367 + const struct dentry * p_dentry,
26368 + const struct vfsmount * p_mnt, const int fmode,
26375 +gr_acl_handle_exit(void)
26381 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
26387 +gr_set_role_label(const uid_t uid, const gid_t gid)
26393 +gr_acl_handle_procpidmem(const struct task_struct *task)
26399 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
26405 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
26411 +gr_set_kernel_label(struct task_struct *task)
26417 +gr_check_user_change(int real, int effective, int fs)
26423 +gr_check_group_change(int real, int effective, int fs)
26429 +EXPORT_SYMBOL(gr_is_capable);
26430 +EXPORT_SYMBOL(gr_is_capable_nolog);
26431 +EXPORT_SYMBOL(gr_learn_resource);
26432 +EXPORT_SYMBOL(gr_set_kernel_label);
26433 +#ifdef CONFIG_SECURITY
26434 +EXPORT_SYMBOL(gr_check_user_change);
26435 +EXPORT_SYMBOL(gr_check_group_change);
26437 diff -urNp linux-2.6.29/grsecurity/grsec_exec.c linux-2.6.29/grsecurity/grsec_exec.c
26438 --- linux-2.6.29/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
26439 +++ linux-2.6.29/grsecurity/grsec_exec.c 2009-03-28 14:26:20.000000000 -0400
26441 +#include <linux/kernel.h>
26442 +#include <linux/sched.h>
26443 +#include <linux/file.h>
26444 +#include <linux/binfmts.h>
26445 +#include <linux/smp_lock.h>
26446 +#include <linux/fs.h>
26447 +#include <linux/types.h>
26448 +#include <linux/grdefs.h>
26449 +#include <linux/grinternal.h>
26450 +#include <linux/capability.h>
26452 +#include <asm/uaccess.h>
26454 +#ifdef CONFIG_GRKERNSEC_EXECLOG
26455 +static char gr_exec_arg_buf[132];
26456 +static DECLARE_MUTEX(gr_exec_arg_sem);
26460 +gr_handle_nproc(void)
26462 +#ifdef CONFIG_GRKERNSEC_EXECVE
26463 + const struct cred *cred = current_cred();
26464 + if (grsec_enable_execve && cred->user &&
26465 + (atomic_read(&cred->user->processes) >
26466 + current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
26467 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
26468 + gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
26476 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
26478 +#ifdef CONFIG_GRKERNSEC_EXECLOG
26479 + char *grarg = gr_exec_arg_buf;
26480 + unsigned int i, x, execlen = 0;
26483 + if (!((grsec_enable_execlog && grsec_enable_group &&
26484 + in_group_p(grsec_audit_gid))
26485 + || (grsec_enable_execlog && !grsec_enable_group)))
26488 + down(&gr_exec_arg_sem);
26489 + memset(grarg, 0, sizeof(gr_exec_arg_buf));
26491 + if (unlikely(argv == NULL))
26494 + for (i = 0; i < bprm->argc && execlen < 128; i++) {
26495 + const char __user *p;
26496 + unsigned int len;
26498 + if (copy_from_user(&p, argv + i, sizeof(p)))
26502 + len = strnlen_user(p, 128 - execlen);
26503 + if (len > 128 - execlen)
26504 + len = 128 - execlen;
26505 + else if (len > 0)
26507 + if (copy_from_user(grarg + execlen, p, len))
26510 + /* rewrite unprintable characters */
26511 + for (x = 0; x < len; x++) {
26512 + c = *(grarg + execlen + x);
26513 + if (c < 32 || c > 126)
26514 + *(grarg + execlen + x) = ' ';
26518 + *(grarg + execlen) = ' ';
26519 + *(grarg + execlen + 1) = '\0';
26524 + gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
26525 + bprm->file->f_path.mnt, grarg);
26526 + up(&gr_exec_arg_sem);
26530 diff -urNp linux-2.6.29/grsecurity/grsec_fifo.c linux-2.6.29/grsecurity/grsec_fifo.c
26531 --- linux-2.6.29/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
26532 +++ linux-2.6.29/grsecurity/grsec_fifo.c 2009-03-28 14:26:20.000000000 -0400
26534 +#include <linux/kernel.h>
26535 +#include <linux/sched.h>
26536 +#include <linux/fs.h>
26537 +#include <linux/file.h>
26538 +#include <linux/grinternal.h>
26541 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
26542 + const struct dentry *dir, const int flag, const int acc_mode)
26544 +#ifdef CONFIG_GRKERNSEC_FIFO
26545 + const struct cred *cred = current_cred();
26547 + if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
26548 + !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
26549 + (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
26550 + (cred->fsuid != dentry->d_inode->i_uid)) {
26551 + if (!generic_permission(dentry->d_inode, acc_mode, NULL))
26552 + gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
26558 diff -urNp linux-2.6.29/grsecurity/grsec_fork.c linux-2.6.29/grsecurity/grsec_fork.c
26559 --- linux-2.6.29/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
26560 +++ linux-2.6.29/grsecurity/grsec_fork.c 2009-03-28 14:26:20.000000000 -0400
26562 +#include <linux/kernel.h>
26563 +#include <linux/sched.h>
26564 +#include <linux/grsecurity.h>
26565 +#include <linux/grinternal.h>
26566 +#include <linux/errno.h>
26569 +gr_log_forkfail(const int retval)
26571 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
26572 + if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
26573 + gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
26577 diff -urNp linux-2.6.29/grsecurity/grsec_init.c linux-2.6.29/grsecurity/grsec_init.c
26578 --- linux-2.6.29/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
26579 +++ linux-2.6.29/grsecurity/grsec_init.c 2009-03-28 14:26:20.000000000 -0400
26581 +#include <linux/kernel.h>
26582 +#include <linux/sched.h>
26583 +#include <linux/mm.h>
26584 +#include <linux/smp_lock.h>
26585 +#include <linux/gracl.h>
26586 +#include <linux/slab.h>
26587 +#include <linux/vmalloc.h>
26588 +#include <linux/percpu.h>
26590 +int grsec_enable_link;
26591 +int grsec_enable_dmesg;
26592 +int grsec_enable_fifo;
26593 +int grsec_enable_execve;
26594 +int grsec_enable_execlog;
26595 +int grsec_enable_signal;
26596 +int grsec_enable_forkfail;
26597 +int grsec_enable_time;
26598 +int grsec_enable_audit_textrel;
26599 +int grsec_enable_group;
26600 +int grsec_audit_gid;
26601 +int grsec_enable_chdir;
26602 +int grsec_enable_audit_ipc;
26603 +int grsec_enable_mount;
26604 +int grsec_enable_chroot_findtask;
26605 +int grsec_enable_chroot_mount;
26606 +int grsec_enable_chroot_shmat;
26607 +int grsec_enable_chroot_fchdir;
26608 +int grsec_enable_chroot_double;
26609 +int grsec_enable_chroot_pivot;
26610 +int grsec_enable_chroot_chdir;
26611 +int grsec_enable_chroot_chmod;
26612 +int grsec_enable_chroot_mknod;
26613 +int grsec_enable_chroot_nice;
26614 +int grsec_enable_chroot_execlog;
26615 +int grsec_enable_chroot_caps;
26616 +int grsec_enable_chroot_sysctl;
26617 +int grsec_enable_chroot_unix;
26618 +int grsec_enable_tpe;
26619 +int grsec_tpe_gid;
26620 +int grsec_enable_tpe_all;
26621 +int grsec_enable_socket_all;
26622 +int grsec_socket_all_gid;
26623 +int grsec_enable_socket_client;
26624 +int grsec_socket_client_gid;
26625 +int grsec_enable_socket_server;
26626 +int grsec_socket_server_gid;
26627 +int grsec_resource_logging;
26630 +DEFINE_SPINLOCK(grsec_alert_lock);
26631 +unsigned long grsec_alert_wtime = 0;
26632 +unsigned long grsec_alert_fyet = 0;
26634 +DEFINE_SPINLOCK(grsec_audit_lock);
26636 +DEFINE_RWLOCK(grsec_exec_file_lock);
26638 +char *gr_shared_page[4];
26640 +char *gr_alert_log_fmt;
26641 +char *gr_audit_log_fmt;
26642 +char *gr_alert_log_buf;
26643 +char *gr_audit_log_buf;
26645 +extern struct gr_arg *gr_usermode;
26646 +extern unsigned char *gr_system_salt;
26647 +extern unsigned char *gr_system_sum;
26650 +grsecurity_init(void)
26653 + /* create the per-cpu shared pages */
26656 + memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
26659 + for (j = 0; j < 4; j++) {
26660 + gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
26661 + if (gr_shared_page[j] == NULL) {
26662 + panic("Unable to allocate grsecurity shared page");
26667 + /* allocate log buffers */
26668 + gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
26669 + if (!gr_alert_log_fmt) {
26670 + panic("Unable to allocate grsecurity alert log format buffer");
26673 + gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
26674 + if (!gr_audit_log_fmt) {
26675 + panic("Unable to allocate grsecurity audit log format buffer");
26678 + gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
26679 + if (!gr_alert_log_buf) {
26680 + panic("Unable to allocate grsecurity alert log buffer");
26683 + gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
26684 + if (!gr_audit_log_buf) {
26685 + panic("Unable to allocate grsecurity audit log buffer");
26689 + /* allocate memory for authentication structure */
26690 + gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
26691 + gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
26692 + gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
26694 + if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
26695 + panic("Unable to allocate grsecurity authentication structure");
26699 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
26700 +#ifndef CONFIG_GRKERNSEC_SYSCTL
26703 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
26704 + grsec_enable_audit_textrel = 1;
26706 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
26707 + grsec_enable_group = 1;
26708 + grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
26710 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
26711 + grsec_enable_chdir = 1;
26713 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26714 + grsec_enable_audit_ipc = 1;
26716 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26717 + grsec_enable_mount = 1;
26719 +#ifdef CONFIG_GRKERNSEC_LINK
26720 + grsec_enable_link = 1;
26722 +#ifdef CONFIG_GRKERNSEC_DMESG
26723 + grsec_enable_dmesg = 1;
26725 +#ifdef CONFIG_GRKERNSEC_FIFO
26726 + grsec_enable_fifo = 1;
26728 +#ifdef CONFIG_GRKERNSEC_EXECVE
26729 + grsec_enable_execve = 1;
26731 +#ifdef CONFIG_GRKERNSEC_EXECLOG
26732 + grsec_enable_execlog = 1;
26734 +#ifdef CONFIG_GRKERNSEC_SIGNAL
26735 + grsec_enable_signal = 1;
26737 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
26738 + grsec_enable_forkfail = 1;
26740 +#ifdef CONFIG_GRKERNSEC_TIME
26741 + grsec_enable_time = 1;
26743 +#ifdef CONFIG_GRKERNSEC_RESLOG
26744 + grsec_resource_logging = 1;
26746 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
26747 + grsec_enable_chroot_findtask = 1;
26749 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
26750 + grsec_enable_chroot_unix = 1;
26752 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
26753 + grsec_enable_chroot_mount = 1;
26755 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
26756 + grsec_enable_chroot_fchdir = 1;
26758 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
26759 + grsec_enable_chroot_shmat = 1;
26761 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
26762 + grsec_enable_chroot_double = 1;
26764 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
26765 + grsec_enable_chroot_pivot = 1;
26767 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
26768 + grsec_enable_chroot_chdir = 1;
26770 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
26771 + grsec_enable_chroot_chmod = 1;
26773 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
26774 + grsec_enable_chroot_mknod = 1;
26776 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
26777 + grsec_enable_chroot_nice = 1;
26779 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
26780 + grsec_enable_chroot_execlog = 1;
26782 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
26783 + grsec_enable_chroot_caps = 1;
26785 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
26786 + grsec_enable_chroot_sysctl = 1;
26788 +#ifdef CONFIG_GRKERNSEC_TPE
26789 + grsec_enable_tpe = 1;
26790 + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
26791 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
26792 + grsec_enable_tpe_all = 1;
26795 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
26796 + grsec_enable_socket_all = 1;
26797 + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
26799 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
26800 + grsec_enable_socket_client = 1;
26801 + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
26803 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
26804 + grsec_enable_socket_server = 1;
26805 + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
26811 diff -urNp linux-2.6.29/grsecurity/grsec_ipc.c linux-2.6.29/grsecurity/grsec_ipc.c
26812 --- linux-2.6.29/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
26813 +++ linux-2.6.29/grsecurity/grsec_ipc.c 2009-03-28 14:26:20.000000000 -0400
26815 +#include <linux/kernel.h>
26816 +#include <linux/sched.h>
26817 +#include <linux/types.h>
26818 +#include <linux/ipc.h>
26819 +#include <linux/grsecurity.h>
26820 +#include <linux/grinternal.h>
26823 +gr_log_msgget(const int ret, const int msgflg)
26825 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26826 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26827 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26828 + !grsec_enable_group)) && (ret >= 0)
26829 + && (msgflg & IPC_CREAT))
26830 + gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
26836 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
26838 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26839 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26840 + grsec_enable_audit_ipc) ||
26841 + (grsec_enable_audit_ipc && !grsec_enable_group))
26842 + gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
26848 +gr_log_semget(const int err, const int semflg)
26850 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26851 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26852 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26853 + !grsec_enable_group)) && (err >= 0)
26854 + && (semflg & IPC_CREAT))
26855 + gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
26861 +gr_log_semrm(const uid_t uid, const uid_t cuid)
26863 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26864 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26865 + grsec_enable_audit_ipc) ||
26866 + (grsec_enable_audit_ipc && !grsec_enable_group))
26867 + gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
26873 +gr_log_shmget(const int err, const int shmflg, const size_t size)
26875 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26876 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26877 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26878 + !grsec_enable_group)) && (err >= 0)
26879 + && (shmflg & IPC_CREAT))
26880 + gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
26886 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
26888 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26889 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26890 + grsec_enable_audit_ipc) ||
26891 + (grsec_enable_audit_ipc && !grsec_enable_group))
26892 + gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
26896 diff -urNp linux-2.6.29/grsecurity/grsec_link.c linux-2.6.29/grsecurity/grsec_link.c
26897 --- linux-2.6.29/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
26898 +++ linux-2.6.29/grsecurity/grsec_link.c 2009-03-28 14:26:20.000000000 -0400
26900 +#include <linux/kernel.h>
26901 +#include <linux/sched.h>
26902 +#include <linux/fs.h>
26903 +#include <linux/file.h>
26904 +#include <linux/grinternal.h>
26907 +gr_handle_follow_link(const struct inode *parent,
26908 + const struct inode *inode,
26909 + const struct dentry *dentry, const struct vfsmount *mnt)
26911 +#ifdef CONFIG_GRKERNSEC_LINK
26912 + const struct cred *cred = current_cred();
26914 + if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
26915 + (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
26916 + (parent->i_mode & S_IWOTH) && (cred->fsuid != inode->i_uid)) {
26917 + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
26925 +gr_handle_hardlink(const struct dentry *dentry,
26926 + const struct vfsmount *mnt,
26927 + struct inode *inode, const int mode, const char *to)
26929 +#ifdef CONFIG_GRKERNSEC_LINK
26930 + const struct cred *cred = current_cred();
26932 + if (grsec_enable_link && cred->fsuid != inode->i_uid &&
26933 + (!S_ISREG(mode) || (mode & S_ISUID) ||
26934 + ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
26935 + (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
26936 + !capable(CAP_FOWNER) && cred->uid) {
26937 + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
26943 diff -urNp linux-2.6.29/grsecurity/grsec_log.c linux-2.6.29/grsecurity/grsec_log.c
26944 --- linux-2.6.29/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
26945 +++ linux-2.6.29/grsecurity/grsec_log.c 2009-03-28 14:26:20.000000000 -0400
26947 +#include <linux/kernel.h>
26948 +#include <linux/sched.h>
26949 +#include <linux/file.h>
26950 +#include <linux/tty.h>
26951 +#include <linux/fs.h>
26952 +#include <linux/grinternal.h>
26954 +#define BEGIN_LOCKS(x) \
26955 + read_lock(&tasklist_lock); \
26956 + read_lock(&grsec_exec_file_lock); \
26957 + if (x != GR_DO_AUDIT) \
26958 + spin_lock(&grsec_alert_lock); \
26960 + spin_lock(&grsec_audit_lock)
26962 +#define END_LOCKS(x) \
26963 + if (x != GR_DO_AUDIT) \
26964 + spin_unlock(&grsec_alert_lock); \
26966 + spin_unlock(&grsec_audit_lock); \
26967 + read_unlock(&grsec_exec_file_lock); \
26968 + read_unlock(&tasklist_lock); \
26969 + if (x == GR_DONT_AUDIT) \
26970 + gr_handle_alertkill(current)
26977 +extern char *gr_alert_log_fmt;
26978 +extern char *gr_audit_log_fmt;
26979 +extern char *gr_alert_log_buf;
26980 +extern char *gr_audit_log_buf;
26982 +static int gr_log_start(int audit)
26984 + char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
26985 + char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
26986 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26988 + if (audit == GR_DO_AUDIT)
26991 + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
26992 + grsec_alert_wtime = jiffies;
26993 + grsec_alert_fyet = 0;
26994 + } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
26995 + grsec_alert_fyet++;
26996 + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
26997 + grsec_alert_wtime = jiffies;
26998 + grsec_alert_fyet++;
26999 + printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
27001 + } else return FLOODING;
27004 + memset(buf, 0, PAGE_SIZE);
27005 + if (current->signal->curr_ip && gr_acl_is_enabled()) {
27006 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
27007 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
27008 + } else if (current->signal->curr_ip) {
27009 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
27010 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
27011 + } else if (gr_acl_is_enabled()) {
27012 + sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
27013 + snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
27015 + sprintf(fmt, "%s%s", loglevel, "grsec: ");
27016 + strcpy(buf, fmt);
27019 + return NO_FLOODING;
27022 +static void gr_log_middle(int audit, const char *msg, va_list ap)
27024 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
27025 + unsigned int len = strlen(buf);
27027 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
27032 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
27034 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
27035 + unsigned int len = strlen(buf);
27038 + va_start(ap, msg);
27039 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
27045 +static void gr_log_end(int audit)
27047 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
27048 + unsigned int len = strlen(buf);
27050 + snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current, current_cred(), __task_cred(current->parent)));
27051 + printk("%s\n", buf);
27056 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
27059 + char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
27060 + char *str1, *str2, *str3;
27062 + unsigned long ulong1, ulong2;
27063 + struct dentry *dentry;
27064 + struct vfsmount *mnt;
27065 + struct file *file;
27066 + struct task_struct *task;
27067 + const struct cred *cred, *pcred;
27070 + BEGIN_LOCKS(audit);
27071 + logtype = gr_log_start(audit);
27072 + if (logtype == FLOODING) {
27073 + END_LOCKS(audit);
27076 + va_start(ap, argtypes);
27077 + switch (argtypes) {
27078 + case GR_TTYSNIFF:
27079 + task = va_arg(ap, struct task_struct *);
27080 + 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);
27082 + case GR_SYSCTL_HIDDEN:
27083 + str1 = va_arg(ap, char *);
27084 + gr_log_middle_varargs(audit, msg, result, str1);
27087 + dentry = va_arg(ap, struct dentry *);
27088 + mnt = va_arg(ap, struct vfsmount *);
27089 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
27091 + case GR_RBAC_STR:
27092 + dentry = va_arg(ap, struct dentry *);
27093 + mnt = va_arg(ap, struct vfsmount *);
27094 + str1 = va_arg(ap, char *);
27095 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
27097 + case GR_STR_RBAC:
27098 + str1 = va_arg(ap, char *);
27099 + dentry = va_arg(ap, struct dentry *);
27100 + mnt = va_arg(ap, struct vfsmount *);
27101 + gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
27103 + case GR_RBAC_MODE2:
27104 + dentry = va_arg(ap, struct dentry *);
27105 + mnt = va_arg(ap, struct vfsmount *);
27106 + str1 = va_arg(ap, char *);
27107 + str2 = va_arg(ap, char *);
27108 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
27110 + case GR_RBAC_MODE3:
27111 + dentry = va_arg(ap, struct dentry *);
27112 + mnt = va_arg(ap, struct vfsmount *);
27113 + str1 = va_arg(ap, char *);
27114 + str2 = va_arg(ap, char *);
27115 + str3 = va_arg(ap, char *);
27116 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
27118 + case GR_FILENAME:
27119 + dentry = va_arg(ap, struct dentry *);
27120 + mnt = va_arg(ap, struct vfsmount *);
27121 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
27123 + case GR_STR_FILENAME:
27124 + str1 = va_arg(ap, char *);
27125 + dentry = va_arg(ap, struct dentry *);
27126 + mnt = va_arg(ap, struct vfsmount *);
27127 + gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
27129 + case GR_FILENAME_STR:
27130 + dentry = va_arg(ap, struct dentry *);
27131 + mnt = va_arg(ap, struct vfsmount *);
27132 + str1 = va_arg(ap, char *);
27133 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
27135 + case GR_FILENAME_TWO_INT:
27136 + dentry = va_arg(ap, struct dentry *);
27137 + mnt = va_arg(ap, struct vfsmount *);
27138 + num1 = va_arg(ap, int);
27139 + num2 = va_arg(ap, int);
27140 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
27142 + case GR_FILENAME_TWO_INT_STR:
27143 + dentry = va_arg(ap, struct dentry *);
27144 + mnt = va_arg(ap, struct vfsmount *);
27145 + num1 = va_arg(ap, int);
27146 + num2 = va_arg(ap, int);
27147 + str1 = va_arg(ap, char *);
27148 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
27151 + file = va_arg(ap, struct file *);
27152 + ulong1 = va_arg(ap, unsigned long);
27153 + ulong2 = va_arg(ap, unsigned long);
27154 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
27157 + task = va_arg(ap, struct task_struct *);
27158 + 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);
27160 + case GR_RESOURCE:
27161 + task = va_arg(ap, struct task_struct *);
27162 + cred = __task_cred(task);
27163 + pcred = __task_cred(task->parent);
27164 + ulong1 = va_arg(ap, unsigned long);
27165 + str1 = va_arg(ap, char *);
27166 + ulong2 = va_arg(ap, unsigned long);
27167 + gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid);
27170 + task = va_arg(ap, struct task_struct *);
27171 + cred = __task_cred(task);
27172 + pcred = __task_cred(task->parent);
27173 + str1 = va_arg(ap, char *);
27174 + gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid);
27177 + task = va_arg(ap, struct task_struct *);
27178 + cred = __task_cred(task);
27179 + pcred = __task_cred(task->parent);
27180 + num1 = va_arg(ap, int);
27181 + gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid);
27184 + task = va_arg(ap, struct task_struct *);
27185 + cred = __task_cred(task);
27186 + pcred = __task_cred(task->parent);
27187 + ulong1 = va_arg(ap, unsigned long);
27188 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid, cred->uid, ulong1);
27191 + task = va_arg(ap, struct task_struct *);
27192 + cred = __task_cred(task);
27193 + pcred = __task_cred(task->parent);
27194 + ulong1 = va_arg(ap, unsigned long);
27195 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid, ulong1);
27199 + unsigned int wday, cday;
27203 + char cur_tty[64] = { 0 };
27204 + char parent_tty[64] = { 0 };
27206 + task = va_arg(ap, struct task_struct *);
27207 + wday = va_arg(ap, unsigned int);
27208 + cday = va_arg(ap, unsigned int);
27209 + whr = va_arg(ap, int);
27210 + chr = va_arg(ap, int);
27211 + wmin = va_arg(ap, int);
27212 + cmin = va_arg(ap, int);
27213 + wsec = va_arg(ap, int);
27214 + csec = va_arg(ap, int);
27215 + ulong1 = va_arg(ap, unsigned long);
27216 + cred = __task_cred(task);
27217 + pcred = __task_cred(task->parent);
27219 + 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), cred->uid, cred->euid, cred->gid, cred->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), pcred->uid, pcred->euid, pcred->gid, pcred->egid);
27223 + gr_log_middle(audit, msg, ap);
27226 + gr_log_end(audit);
27227 + END_LOCKS(audit);
27229 diff -urNp linux-2.6.29/grsecurity/grsec_mem.c linux-2.6.29/grsecurity/grsec_mem.c
27230 --- linux-2.6.29/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
27231 +++ linux-2.6.29/grsecurity/grsec_mem.c 2009-03-28 14:26:20.000000000 -0400
27233 +#include <linux/kernel.h>
27234 +#include <linux/sched.h>
27235 +#include <linux/mm.h>
27236 +#include <linux/mman.h>
27237 +#include <linux/grinternal.h>
27240 +gr_handle_ioperm(void)
27242 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
27247 +gr_handle_iopl(void)
27249 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
27254 +gr_handle_mem_write(void)
27256 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
27261 +gr_handle_kmem_write(void)
27263 + gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
27268 +gr_handle_open_port(void)
27270 + gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
27275 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
27277 + unsigned long start, end;
27280 + end = start + vma->vm_end - vma->vm_start;
27282 + if (start > end) {
27283 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
27287 + /* allowed ranges : ISA I/O BIOS */
27288 + if ((start >= __pa(high_memory))
27290 + || (start >= 0x000a0000 && end <= 0x00100000)
27291 + || (start >= 0x00000000 && end <= 0x00001000)
27296 + if (vma->vm_flags & VM_WRITE) {
27297 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
27300 + vma->vm_flags &= ~VM_MAYWRITE;
27304 diff -urNp linux-2.6.29/grsecurity/grsec_mount.c linux-2.6.29/grsecurity/grsec_mount.c
27305 --- linux-2.6.29/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
27306 +++ linux-2.6.29/grsecurity/grsec_mount.c 2009-03-28 14:26:20.000000000 -0400
27308 +#include <linux/kernel.h>
27309 +#include <linux/sched.h>
27310 +#include <linux/grsecurity.h>
27311 +#include <linux/grinternal.h>
27314 +gr_log_remount(const char *devname, const int retval)
27316 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
27317 + if (grsec_enable_mount && (retval >= 0))
27318 + gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
27324 +gr_log_unmount(const char *devname, const int retval)
27326 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
27327 + if (grsec_enable_mount && (retval >= 0))
27328 + gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
27334 +gr_log_mount(const char *from, const char *to, const int retval)
27336 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
27337 + if (grsec_enable_mount && (retval >= 0))
27338 + gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
27342 diff -urNp linux-2.6.29/grsecurity/grsec_sig.c linux-2.6.29/grsecurity/grsec_sig.c
27343 --- linux-2.6.29/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
27344 +++ linux-2.6.29/grsecurity/grsec_sig.c 2009-03-28 14:26:20.000000000 -0400
27346 +#include <linux/kernel.h>
27347 +#include <linux/sched.h>
27348 +#include <linux/delay.h>
27349 +#include <linux/grsecurity.h>
27350 +#include <linux/grinternal.h>
27353 +gr_log_signal(const int sig, const struct task_struct *t)
27355 +#ifdef CONFIG_GRKERNSEC_SIGNAL
27356 + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
27357 + (sig == SIGABRT) || (sig == SIGBUS))) {
27358 + if (t->pid == current->pid) {
27359 + gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
27361 + gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
27369 +gr_handle_signal(const struct task_struct *p, const int sig)
27371 +#ifdef CONFIG_GRKERNSEC
27372 + if (current->pid > 1 && gr_check_protected_task(p)) {
27373 + gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
27375 + } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
27382 +void gr_handle_brute_attach(struct task_struct *p)
27384 +#ifdef CONFIG_GRKERNSEC_BRUTE
27385 + read_lock(&tasklist_lock);
27386 + read_lock(&grsec_exec_file_lock);
27387 + if (p->parent && p->parent->exec_file == p->exec_file)
27388 + p->parent->brute = 1;
27389 + read_unlock(&grsec_exec_file_lock);
27390 + read_unlock(&tasklist_lock);
27395 +void gr_handle_brute_check(void)
27397 +#ifdef CONFIG_GRKERNSEC_BRUTE
27398 + if (current->brute)
27399 + msleep(30 * 1000);
27404 diff -urNp linux-2.6.29/grsecurity/grsec_sock.c linux-2.6.29/grsecurity/grsec_sock.c
27405 --- linux-2.6.29/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
27406 +++ linux-2.6.29/grsecurity/grsec_sock.c 2009-03-28 14:26:20.000000000 -0400
27408 +#include <linux/kernel.h>
27409 +#include <linux/module.h>
27410 +#include <linux/sched.h>
27411 +#include <linux/file.h>
27412 +#include <linux/net.h>
27413 +#include <linux/in.h>
27414 +#include <linux/ip.h>
27415 +#include <net/sock.h>
27416 +#include <net/inet_sock.h>
27417 +#include <linux/grsecurity.h>
27418 +#include <linux/grinternal.h>
27419 +#include <linux/gracl.h>
27421 +kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
27422 +EXPORT_SYMBOL(gr_cap_rtnetlink);
27424 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
27425 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
27427 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
27428 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
27430 +#ifdef CONFIG_UNIX_MODULE
27431 +EXPORT_SYMBOL(gr_acl_handle_unix);
27432 +EXPORT_SYMBOL(gr_acl_handle_mknod);
27433 +EXPORT_SYMBOL(gr_handle_chroot_unix);
27434 +EXPORT_SYMBOL(gr_handle_create);
27437 +#ifdef CONFIG_GRKERNSEC
27438 +#define gr_conn_table_size 32749
27439 +struct conn_table_entry {
27440 + struct conn_table_entry *next;
27441 + struct signal_struct *sig;
27444 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
27445 +DEFINE_SPINLOCK(gr_conn_table_lock);
27447 +extern const char * gr_socktype_to_name(unsigned char type);
27448 +extern const char * gr_proto_to_name(unsigned char proto);
27450 +static __inline__ int
27451 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
27453 + return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
27456 +static __inline__ int
27457 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
27458 + __u16 sport, __u16 dport)
27460 + if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
27461 + sig->gr_sport == sport && sig->gr_dport == dport))
27467 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
27469 + struct conn_table_entry **match;
27470 + unsigned int index;
27472 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
27473 + sig->gr_sport, sig->gr_dport,
27474 + gr_conn_table_size);
27476 + newent->sig = sig;
27478 + match = &gr_conn_table[index];
27479 + newent->next = *match;
27485 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
27487 + struct conn_table_entry *match, *last = NULL;
27488 + unsigned int index;
27490 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
27491 + sig->gr_sport, sig->gr_dport,
27492 + gr_conn_table_size);
27494 + match = gr_conn_table[index];
27495 + while (match && !conn_match(match->sig,
27496 + sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
27497 + sig->gr_dport)) {
27499 + match = match->next;
27504 + last->next = match->next;
27506 + gr_conn_table[index] = NULL;
27513 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
27514 + __u16 sport, __u16 dport)
27516 + struct conn_table_entry *match;
27517 + unsigned int index;
27519 + index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
27521 + match = gr_conn_table[index];
27522 + while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
27523 + match = match->next;
27526 + return match->sig;
27533 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
27535 +#ifdef CONFIG_GRKERNSEC
27536 + struct signal_struct *sig = task->signal;
27537 + struct conn_table_entry *newent;
27539 + newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
27540 + if (newent == NULL)
27542 + /* no bh lock needed since we are called with bh disabled */
27543 + spin_lock(&gr_conn_table_lock);
27544 + gr_del_task_from_ip_table_nolock(sig);
27545 + sig->gr_saddr = inet->rcv_saddr;
27546 + sig->gr_daddr = inet->daddr;
27547 + sig->gr_sport = inet->sport;
27548 + sig->gr_dport = inet->dport;
27549 + gr_add_to_task_ip_table_nolock(sig, newent);
27550 + spin_unlock(&gr_conn_table_lock);
27555 +void gr_del_task_from_ip_table(struct task_struct *task)
27557 +#ifdef CONFIG_GRKERNSEC
27558 + spin_lock_bh(&gr_conn_table_lock);
27559 + gr_del_task_from_ip_table_nolock(task->signal);
27560 + spin_unlock_bh(&gr_conn_table_lock);
27566 +gr_attach_curr_ip(const struct sock *sk)
27568 +#ifdef CONFIG_GRKERNSEC
27569 + struct signal_struct *p, *set;
27570 + const struct inet_sock *inet = inet_sk(sk);
27572 + if (unlikely(sk->sk_protocol != IPPROTO_TCP))
27575 + set = current->signal;
27577 + spin_lock_bh(&gr_conn_table_lock);
27578 + p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
27579 + inet->dport, inet->sport);
27580 + if (unlikely(p != NULL)) {
27581 + set->curr_ip = p->curr_ip;
27582 + set->used_accept = 1;
27583 + gr_del_task_from_ip_table_nolock(p);
27584 + spin_unlock_bh(&gr_conn_table_lock);
27587 + spin_unlock_bh(&gr_conn_table_lock);
27589 + set->curr_ip = inet->daddr;
27590 + set->used_accept = 1;
27596 +gr_handle_sock_all(const int family, const int type, const int protocol)
27598 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
27599 + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
27600 + (family != AF_UNIX) && (family != AF_LOCAL)) {
27601 + gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
27609 +gr_handle_sock_server(const struct sockaddr *sck)
27611 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27612 + if (grsec_enable_socket_server &&
27613 + in_group_p(grsec_socket_server_gid) &&
27614 + sck && (sck->sa_family != AF_UNIX) &&
27615 + (sck->sa_family != AF_LOCAL)) {
27616 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
27624 +gr_handle_sock_server_other(const struct sock *sck)
27626 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27627 + if (grsec_enable_socket_server &&
27628 + in_group_p(grsec_socket_server_gid) &&
27629 + sck && (sck->sk_family != AF_UNIX) &&
27630 + (sck->sk_family != AF_LOCAL)) {
27631 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
27639 +gr_handle_sock_client(const struct sockaddr *sck)
27641 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
27642 + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
27643 + sck && (sck->sa_family != AF_UNIX) &&
27644 + (sck->sa_family != AF_LOCAL)) {
27645 + gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
27653 +gr_cap_rtnetlink(struct sock *sock)
27655 +#ifdef CONFIG_GRKERNSEC
27656 + if (!gr_acl_is_enabled())
27657 + return current_cap();
27658 + else if (sock->sk_protocol == NETLINK_ISCSI &&
27659 + cap_raised(current_cap(), CAP_SYS_ADMIN) &&
27660 + gr_is_capable(CAP_SYS_ADMIN))
27661 + return current_cap();
27662 + else if (sock->sk_protocol == NETLINK_AUDIT &&
27663 + cap_raised(current_cap(), CAP_AUDIT_WRITE) &&
27664 + gr_is_capable(CAP_AUDIT_WRITE) &&
27665 + cap_raised(current_cap(), CAP_AUDIT_CONTROL) &&
27666 + gr_is_capable(CAP_AUDIT_CONTROL))
27667 + return current_cap();
27668 + else if (cap_raised(current_cap(), CAP_NET_ADMIN) &&
27669 + gr_is_capable(CAP_NET_ADMIN))
27670 + return current_cap();
27672 + return __cap_empty_set;
27674 + return current_cap();
27677 diff -urNp linux-2.6.29/grsecurity/grsec_sysctl.c linux-2.6.29/grsecurity/grsec_sysctl.c
27678 --- linux-2.6.29/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
27679 +++ linux-2.6.29/grsecurity/grsec_sysctl.c 2009-03-28 14:26:20.000000000 -0400
27681 +#include <linux/kernel.h>
27682 +#include <linux/sched.h>
27683 +#include <linux/sysctl.h>
27684 +#include <linux/grsecurity.h>
27685 +#include <linux/grinternal.h>
27687 +#ifdef CONFIG_GRKERNSEC_MODSTOP
27688 +int grsec_modstop;
27692 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
27694 +#ifdef CONFIG_GRKERNSEC_SYSCTL
27695 + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
27696 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
27700 +#ifdef CONFIG_GRKERNSEC_MODSTOP
27701 + if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
27702 + grsec_modstop && (op & MAY_WRITE)) {
27703 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
27710 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
27711 +ctl_table grsecurity_table[] = {
27712 +#ifdef CONFIG_GRKERNSEC_SYSCTL
27713 +#ifdef CONFIG_GRKERNSEC_LINK
27715 + .ctl_name = CTL_UNNUMBERED,
27716 + .procname = "linking_restrictions",
27717 + .data = &grsec_enable_link,
27718 + .maxlen = sizeof(int),
27720 + .proc_handler = &proc_dointvec,
27723 +#ifdef CONFIG_GRKERNSEC_FIFO
27725 + .ctl_name = CTL_UNNUMBERED,
27726 + .procname = "fifo_restrictions",
27727 + .data = &grsec_enable_fifo,
27728 + .maxlen = sizeof(int),
27730 + .proc_handler = &proc_dointvec,
27733 +#ifdef CONFIG_GRKERNSEC_EXECVE
27735 + .ctl_name = CTL_UNNUMBERED,
27736 + .procname = "execve_limiting",
27737 + .data = &grsec_enable_execve,
27738 + .maxlen = sizeof(int),
27740 + .proc_handler = &proc_dointvec,
27743 +#ifdef CONFIG_GRKERNSEC_EXECLOG
27745 + .ctl_name = CTL_UNNUMBERED,
27746 + .procname = "exec_logging",
27747 + .data = &grsec_enable_execlog,
27748 + .maxlen = sizeof(int),
27750 + .proc_handler = &proc_dointvec,
27753 +#ifdef CONFIG_GRKERNSEC_SIGNAL
27755 + .ctl_name = CTL_UNNUMBERED,
27756 + .procname = "signal_logging",
27757 + .data = &grsec_enable_signal,
27758 + .maxlen = sizeof(int),
27760 + .proc_handler = &proc_dointvec,
27763 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
27765 + .ctl_name = CTL_UNNUMBERED,
27766 + .procname = "forkfail_logging",
27767 + .data = &grsec_enable_forkfail,
27768 + .maxlen = sizeof(int),
27770 + .proc_handler = &proc_dointvec,
27773 +#ifdef CONFIG_GRKERNSEC_TIME
27775 + .ctl_name = CTL_UNNUMBERED,
27776 + .procname = "timechange_logging",
27777 + .data = &grsec_enable_time,
27778 + .maxlen = sizeof(int),
27780 + .proc_handler = &proc_dointvec,
27783 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
27785 + .ctl_name = CTL_UNNUMBERED,
27786 + .procname = "chroot_deny_shmat",
27787 + .data = &grsec_enable_chroot_shmat,
27788 + .maxlen = sizeof(int),
27790 + .proc_handler = &proc_dointvec,
27793 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
27795 + .ctl_name = CTL_UNNUMBERED,
27796 + .procname = "chroot_deny_unix",
27797 + .data = &grsec_enable_chroot_unix,
27798 + .maxlen = sizeof(int),
27800 + .proc_handler = &proc_dointvec,
27803 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
27805 + .ctl_name = CTL_UNNUMBERED,
27806 + .procname = "chroot_deny_mount",
27807 + .data = &grsec_enable_chroot_mount,
27808 + .maxlen = sizeof(int),
27810 + .proc_handler = &proc_dointvec,
27813 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
27815 + .ctl_name = CTL_UNNUMBERED,
27816 + .procname = "chroot_deny_fchdir",
27817 + .data = &grsec_enable_chroot_fchdir,
27818 + .maxlen = sizeof(int),
27820 + .proc_handler = &proc_dointvec,
27823 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
27825 + .ctl_name = CTL_UNNUMBERED,
27826 + .procname = "chroot_deny_chroot",
27827 + .data = &grsec_enable_chroot_double,
27828 + .maxlen = sizeof(int),
27830 + .proc_handler = &proc_dointvec,
27833 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
27835 + .ctl_name = CTL_UNNUMBERED,
27836 + .procname = "chroot_deny_pivot",
27837 + .data = &grsec_enable_chroot_pivot,
27838 + .maxlen = sizeof(int),
27840 + .proc_handler = &proc_dointvec,
27843 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
27845 + .ctl_name = CTL_UNNUMBERED,
27846 + .procname = "chroot_enforce_chdir",
27847 + .data = &grsec_enable_chroot_chdir,
27848 + .maxlen = sizeof(int),
27850 + .proc_handler = &proc_dointvec,
27853 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
27855 + .ctl_name = CTL_UNNUMBERED,
27856 + .procname = "chroot_deny_chmod",
27857 + .data = &grsec_enable_chroot_chmod,
27858 + .maxlen = sizeof(int),
27860 + .proc_handler = &proc_dointvec,
27863 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
27865 + .ctl_name = CTL_UNNUMBERED,
27866 + .procname = "chroot_deny_mknod",
27867 + .data = &grsec_enable_chroot_mknod,
27868 + .maxlen = sizeof(int),
27870 + .proc_handler = &proc_dointvec,
27873 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
27875 + .ctl_name = CTL_UNNUMBERED,
27876 + .procname = "chroot_restrict_nice",
27877 + .data = &grsec_enable_chroot_nice,
27878 + .maxlen = sizeof(int),
27880 + .proc_handler = &proc_dointvec,
27883 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
27885 + .ctl_name = CTL_UNNUMBERED,
27886 + .procname = "chroot_execlog",
27887 + .data = &grsec_enable_chroot_execlog,
27888 + .maxlen = sizeof(int),
27890 + .proc_handler = &proc_dointvec,
27893 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
27895 + .ctl_name = CTL_UNNUMBERED,
27896 + .procname = "chroot_caps",
27897 + .data = &grsec_enable_chroot_caps,
27898 + .maxlen = sizeof(int),
27900 + .proc_handler = &proc_dointvec,
27903 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
27905 + .ctl_name = CTL_UNNUMBERED,
27906 + .procname = "chroot_deny_sysctl",
27907 + .data = &grsec_enable_chroot_sysctl,
27908 + .maxlen = sizeof(int),
27910 + .proc_handler = &proc_dointvec,
27913 +#ifdef CONFIG_GRKERNSEC_TPE
27915 + .ctl_name = CTL_UNNUMBERED,
27916 + .procname = "tpe",
27917 + .data = &grsec_enable_tpe,
27918 + .maxlen = sizeof(int),
27920 + .proc_handler = &proc_dointvec,
27923 + .ctl_name = CTL_UNNUMBERED,
27924 + .procname = "tpe_gid",
27925 + .data = &grsec_tpe_gid,
27926 + .maxlen = sizeof(int),
27928 + .proc_handler = &proc_dointvec,
27931 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
27933 + .ctl_name = CTL_UNNUMBERED,
27934 + .procname = "tpe_restrict_all",
27935 + .data = &grsec_enable_tpe_all,
27936 + .maxlen = sizeof(int),
27938 + .proc_handler = &proc_dointvec,
27941 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
27943 + .ctl_name = CTL_UNNUMBERED,
27944 + .procname = "socket_all",
27945 + .data = &grsec_enable_socket_all,
27946 + .maxlen = sizeof(int),
27948 + .proc_handler = &proc_dointvec,
27951 + .ctl_name = CTL_UNNUMBERED,
27952 + .procname = "socket_all_gid",
27953 + .data = &grsec_socket_all_gid,
27954 + .maxlen = sizeof(int),
27956 + .proc_handler = &proc_dointvec,
27959 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
27961 + .ctl_name = CTL_UNNUMBERED,
27962 + .procname = "socket_client",
27963 + .data = &grsec_enable_socket_client,
27964 + .maxlen = sizeof(int),
27966 + .proc_handler = &proc_dointvec,
27969 + .ctl_name = CTL_UNNUMBERED,
27970 + .procname = "socket_client_gid",
27971 + .data = &grsec_socket_client_gid,
27972 + .maxlen = sizeof(int),
27974 + .proc_handler = &proc_dointvec,
27977 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27979 + .ctl_name = CTL_UNNUMBERED,
27980 + .procname = "socket_server",
27981 + .data = &grsec_enable_socket_server,
27982 + .maxlen = sizeof(int),
27984 + .proc_handler = &proc_dointvec,
27987 + .ctl_name = CTL_UNNUMBERED,
27988 + .procname = "socket_server_gid",
27989 + .data = &grsec_socket_server_gid,
27990 + .maxlen = sizeof(int),
27992 + .proc_handler = &proc_dointvec,
27995 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
27997 + .ctl_name = CTL_UNNUMBERED,
27998 + .procname = "audit_group",
27999 + .data = &grsec_enable_group,
28000 + .maxlen = sizeof(int),
28002 + .proc_handler = &proc_dointvec,
28005 + .ctl_name = CTL_UNNUMBERED,
28006 + .procname = "audit_gid",
28007 + .data = &grsec_audit_gid,
28008 + .maxlen = sizeof(int),
28010 + .proc_handler = &proc_dointvec,
28013 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
28015 + .ctl_name = CTL_UNNUMBERED,
28016 + .procname = "audit_chdir",
28017 + .data = &grsec_enable_chdir,
28018 + .maxlen = sizeof(int),
28020 + .proc_handler = &proc_dointvec,
28023 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
28025 + .ctl_name = CTL_UNNUMBERED,
28026 + .procname = "audit_mount",
28027 + .data = &grsec_enable_mount,
28028 + .maxlen = sizeof(int),
28030 + .proc_handler = &proc_dointvec,
28033 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
28035 + .ctl_name = CTL_UNNUMBERED,
28036 + .procname = "audit_ipc",
28037 + .data = &grsec_enable_audit_ipc,
28038 + .maxlen = sizeof(int),
28040 + .proc_handler = &proc_dointvec,
28043 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
28045 + .ctl_name = CTL_UNNUMBERED,
28046 + .procname = "audit_textrel",
28047 + .data = &grsec_enable_audit_textrel,
28048 + .maxlen = sizeof(int),
28050 + .proc_handler = &proc_dointvec,
28053 +#ifdef CONFIG_GRKERNSEC_DMESG
28055 + .ctl_name = CTL_UNNUMBERED,
28056 + .procname = "dmesg",
28057 + .data = &grsec_enable_dmesg,
28058 + .maxlen = sizeof(int),
28060 + .proc_handler = &proc_dointvec,
28063 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
28065 + .ctl_name = CTL_UNNUMBERED,
28066 + .procname = "chroot_findtask",
28067 + .data = &grsec_enable_chroot_findtask,
28068 + .maxlen = sizeof(int),
28070 + .proc_handler = &proc_dointvec,
28073 +#ifdef CONFIG_GRKERNSEC_RESLOG
28075 + .ctl_name = CTL_UNNUMBERED,
28076 + .procname = "resource_logging",
28077 + .data = &grsec_resource_logging,
28078 + .maxlen = sizeof(int),
28080 + .proc_handler = &proc_dointvec,
28084 + .ctl_name = CTL_UNNUMBERED,
28085 + .procname = "grsec_lock",
28086 + .data = &grsec_lock,
28087 + .maxlen = sizeof(int),
28089 + .proc_handler = &proc_dointvec,
28092 +#ifdef CONFIG_GRKERNSEC_MODSTOP
28094 + .ctl_name = CTL_UNNUMBERED,
28095 + .procname = "disable_modules",
28096 + .data = &grsec_modstop,
28097 + .maxlen = sizeof(int),
28099 + .proc_handler = &proc_dointvec,
28102 + { .ctl_name = 0 }
28106 +int gr_check_modstop(void)
28108 +#ifdef CONFIG_GRKERNSEC_MODSTOP
28109 + if (grsec_modstop == 1) {
28110 + gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
28116 diff -urNp linux-2.6.29/grsecurity/grsec_textrel.c linux-2.6.29/grsecurity/grsec_textrel.c
28117 --- linux-2.6.29/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
28118 +++ linux-2.6.29/grsecurity/grsec_textrel.c 2009-03-28 14:26:20.000000000 -0400
28120 +#include <linux/kernel.h>
28121 +#include <linux/sched.h>
28122 +#include <linux/mm.h>
28123 +#include <linux/file.h>
28124 +#include <linux/grinternal.h>
28125 +#include <linux/grsecurity.h>
28128 +gr_log_textrel(struct vm_area_struct * vma)
28130 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
28131 + if (grsec_enable_audit_textrel)
28132 + gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
28136 diff -urNp linux-2.6.29/grsecurity/grsec_time.c linux-2.6.29/grsecurity/grsec_time.c
28137 --- linux-2.6.29/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
28138 +++ linux-2.6.29/grsecurity/grsec_time.c 2009-03-28 14:26:20.000000000 -0400
28140 +#include <linux/kernel.h>
28141 +#include <linux/sched.h>
28142 +#include <linux/grinternal.h>
28145 +gr_log_timechange(void)
28147 +#ifdef CONFIG_GRKERNSEC_TIME
28148 + if (grsec_enable_time)
28149 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
28153 diff -urNp linux-2.6.29/grsecurity/grsec_tpe.c linux-2.6.29/grsecurity/grsec_tpe.c
28154 --- linux-2.6.29/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
28155 +++ linux-2.6.29/grsecurity/grsec_tpe.c 2009-03-28 14:26:20.000000000 -0400
28157 +#include <linux/kernel.h>
28158 +#include <linux/sched.h>
28159 +#include <linux/file.h>
28160 +#include <linux/fs.h>
28161 +#include <linux/grinternal.h>
28163 +extern int gr_acl_tpe_check(void);
28166 +gr_tpe_allow(const struct file *file)
28168 +#ifdef CONFIG_GRKERNSEC
28169 + struct inode *inode = file->f_path.dentry->d_parent->d_inode;
28170 + const struct cred *cred = current_cred();
28172 + if (cred->uid && ((grsec_enable_tpe &&
28173 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
28174 + !in_group_p(grsec_tpe_gid)
28176 + in_group_p(grsec_tpe_gid)
28178 + ) || gr_acl_tpe_check()) &&
28179 + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
28180 + (inode->i_mode & S_IWOTH))))) {
28181 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
28184 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
28185 + if (cred->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
28186 + ((inode->i_uid && (inode->i_uid != cred->uid)) ||
28187 + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
28188 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
28195 diff -urNp linux-2.6.29/grsecurity/grsum.c linux-2.6.29/grsecurity/grsum.c
28196 --- linux-2.6.29/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
28197 +++ linux-2.6.29/grsecurity/grsum.c 2009-03-28 14:26:20.000000000 -0400
28199 +#include <linux/err.h>
28200 +#include <linux/kernel.h>
28201 +#include <linux/sched.h>
28202 +#include <linux/mm.h>
28203 +#include <linux/scatterlist.h>
28204 +#include <linux/crypto.h>
28205 +#include <linux/gracl.h>
28208 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
28209 +#error "crypto and sha256 must be built into the kernel"
28213 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
28216 + struct crypto_hash *tfm;
28217 + struct hash_desc desc;
28218 + struct scatterlist sg;
28219 + unsigned char temp_sum[GR_SHA_LEN];
28220 + volatile int retval = 0;
28221 + volatile int dummy = 0;
28224 + tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
28225 + if (IS_ERR(tfm)) {
28226 + /* should never happen, since sha256 should be built in */
28233 + crypto_hash_init(&desc);
28236 + sg_set_buf(&sg, p, GR_SALT_LEN);
28237 + crypto_hash_update(&desc, &sg, sg.length);
28240 + sg_set_buf(&sg, p, strlen(p));
28242 + crypto_hash_update(&desc, &sg, sg.length);
28244 + crypto_hash_final(&desc, temp_sum);
28246 + memset(entry->pw, 0, GR_PW_LEN);
28248 + for (i = 0; i < GR_SHA_LEN; i++)
28249 + if (sum[i] != temp_sum[i])
28252 + dummy = 1; // waste a cycle
28254 + crypto_free_hash(tfm);
28258 diff -urNp linux-2.6.29/grsecurity/Kconfig linux-2.6.29/grsecurity/Kconfig
28259 --- linux-2.6.29/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
28260 +++ linux-2.6.29/grsecurity/Kconfig 2009-03-28 14:26:20.000000000 -0400
28263 +# grecurity configuration
28269 + bool "Grsecurity"
28271 + select CRYPTO_SHA256
28273 + select SECURITY_CAPABILITIES
28275 + If you say Y here, you will be able to configure many features
28276 + that will enhance the security of your system. It is highly
28277 + recommended that you say Y here and read through the help
28278 + for each option so that you fully understand the features and
28279 + can evaluate their usefulness for your machine.
28282 + prompt "Security Level"
28283 + depends on GRKERNSEC
28284 + default GRKERNSEC_CUSTOM
28286 +config GRKERNSEC_LOW
28288 + select GRKERNSEC_LINK
28289 + select GRKERNSEC_FIFO
28290 + select GRKERNSEC_EXECVE
28291 + select GRKERNSEC_RANDNET
28292 + select GRKERNSEC_DMESG
28293 + select GRKERNSEC_CHROOT
28294 + select GRKERNSEC_CHROOT_CHDIR
28295 + select GRKERNSEC_MODSTOP if (MODULES)
28298 + If you choose this option, several of the grsecurity options will
28299 + be enabled that will give you greater protection against a number
28300 + of attacks, while assuring that none of your software will have any
28301 + conflicts with the additional security measures. If you run a lot
28302 + of unusual software, or you are having problems with the higher
28303 + security levels, you should say Y here. With this option, the
28304 + following features are enabled:
28306 + - Linking restrictions
28307 + - FIFO restrictions
28308 + - Enforcing RLIMIT_NPROC on execve
28309 + - Restricted dmesg
28310 + - Enforced chdir("/") on chroot
28311 + - Runtime module disabling
28313 +config GRKERNSEC_MEDIUM
28316 + select PAX_EI_PAX
28317 + select PAX_PT_PAX_FLAGS
28318 + select PAX_HAVE_ACL_FLAGS
28319 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
28320 + select GRKERNSEC_CHROOT
28321 + select GRKERNSEC_CHROOT_SYSCTL
28322 + select GRKERNSEC_LINK
28323 + select GRKERNSEC_FIFO
28324 + select GRKERNSEC_EXECVE
28325 + select GRKERNSEC_DMESG
28326 + select GRKERNSEC_RANDNET
28327 + select GRKERNSEC_FORKFAIL
28328 + select GRKERNSEC_TIME
28329 + select GRKERNSEC_SIGNAL
28330 + select GRKERNSEC_CHROOT
28331 + select GRKERNSEC_CHROOT_UNIX
28332 + select GRKERNSEC_CHROOT_MOUNT
28333 + select GRKERNSEC_CHROOT_PIVOT
28334 + select GRKERNSEC_CHROOT_DOUBLE
28335 + select GRKERNSEC_CHROOT_CHDIR
28336 + select GRKERNSEC_CHROOT_MKNOD
28337 + select GRKERNSEC_PROC
28338 + select GRKERNSEC_PROC_USERGROUP
28339 + select GRKERNSEC_MODSTOP if (MODULES)
28340 + select PAX_RANDUSTACK
28342 + select PAX_RANDMMAP
28343 + select PAX_REFCOUNT if (X86)
28346 + If you say Y here, several features in addition to those included
28347 + in the low additional security level will be enabled. These
28348 + features provide even more security to your system, though in rare
28349 + cases they may be incompatible with very old or poorly written
28350 + software. If you enable this option, make sure that your auth
28351 + service (identd) is running as gid 1001. With this option,
28352 + the following features (in addition to those provided in the
28353 + low additional security level) will be enabled:
28355 + - Failed fork logging
28356 + - Time change logging
28358 + - Deny mounts in chroot
28359 + - Deny double chrooting
28360 + - Deny sysctl writes in chroot
28361 + - Deny mknod in chroot
28362 + - Deny access to abstract AF_UNIX sockets out of chroot
28363 + - Deny pivot_root in chroot
28364 + - Denied writes of /dev/kmem, /dev/mem, and /dev/port
28365 + - /proc restrictions with special GID set to 10 (usually wheel)
28366 + - Address Space Layout Randomization (ASLR)
28367 + - Prevent exploitation of most refcount overflows
28369 +config GRKERNSEC_HIGH
28371 + select GRKERNSEC_LINK
28372 + select GRKERNSEC_FIFO
28373 + select GRKERNSEC_EXECVE
28374 + select GRKERNSEC_DMESG
28375 + select GRKERNSEC_FORKFAIL
28376 + select GRKERNSEC_TIME
28377 + select GRKERNSEC_SIGNAL
28378 + select GRKERNSEC_CHROOT
28379 + select GRKERNSEC_CHROOT_SHMAT
28380 + select GRKERNSEC_CHROOT_UNIX
28381 + select GRKERNSEC_CHROOT_MOUNT
28382 + select GRKERNSEC_CHROOT_FCHDIR
28383 + select GRKERNSEC_CHROOT_PIVOT
28384 + select GRKERNSEC_CHROOT_DOUBLE
28385 + select GRKERNSEC_CHROOT_CHDIR
28386 + select GRKERNSEC_CHROOT_MKNOD
28387 + select GRKERNSEC_CHROOT_CAPS
28388 + select GRKERNSEC_CHROOT_SYSCTL
28389 + select GRKERNSEC_CHROOT_FINDTASK
28390 + select GRKERNSEC_PROC
28391 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
28392 + select GRKERNSEC_HIDESYM
28393 + select GRKERNSEC_BRUTE
28394 + select GRKERNSEC_PROC_USERGROUP
28395 + select GRKERNSEC_KMEM
28396 + select GRKERNSEC_RESLOG
28397 + select GRKERNSEC_RANDNET
28398 + select GRKERNSEC_PROC_ADD
28399 + select GRKERNSEC_CHROOT_CHMOD
28400 + select GRKERNSEC_CHROOT_NICE
28401 + select GRKERNSEC_AUDIT_MOUNT
28402 + select GRKERNSEC_MODSTOP if (MODULES)
28404 + select PAX_RANDUSTACK
28406 + select PAX_RANDMMAP
28407 + select PAX_NOEXEC
28408 + select PAX_MPROTECT
28409 + select PAX_EI_PAX
28410 + select PAX_PT_PAX_FLAGS
28411 + select PAX_HAVE_ACL_FLAGS
28412 + select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
28413 + select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
28414 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
28415 + select PAX_SEGMEXEC if (X86 && !X86_64)
28416 + select PAX_PAGEEXEC if (!X86)
28417 + select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
28418 + select PAX_DLRESOLVE if (SPARC32 || SPARC64)
28419 + select PAX_SYSCALL if (PPC32)
28420 + select PAX_EMUTRAMP if (PARISC)
28421 + select PAX_EMUSIGRT if (PARISC)
28422 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
28423 + select PAX_REFCOUNT if (X86)
28425 + If you say Y here, many of the features of grsecurity will be
28426 + enabled, which will protect you against many kinds of attacks
28427 + against your system. The heightened security comes at a cost
28428 + of an increased chance of incompatibilities with rare software
28429 + on your machine. Since this security level enables PaX, you should
28430 + view <http://pax.grsecurity.net> and read about the PaX
28431 + project. While you are there, download chpax and run it on
28432 + binaries that cause problems with PaX. Also remember that
28433 + since the /proc restrictions are enabled, you must run your
28434 + identd as gid 1001. This security level enables the following
28435 + features in addition to those listed in the low and medium
28438 + - Additional /proc restrictions
28439 + - Chmod restrictions in chroot
28440 + - No signals, ptrace, or viewing of processes outside of chroot
28441 + - Capability restrictions in chroot
28442 + - Deny fchdir out of chroot
28443 + - Priority restrictions in chroot
28444 + - Segmentation-based implementation of PaX
28445 + - Mprotect restrictions
28446 + - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
28447 + - Kernel stack randomization
28448 + - Mount/unmount/remount logging
28449 + - Kernel symbol hiding
28450 + - Prevention of memory exhaustion-based exploits
28451 +config GRKERNSEC_CUSTOM
28454 + If you say Y here, you will be able to configure every grsecurity
28455 + option, which allows you to enable many more features that aren't
28456 + covered in the basic security levels. These additional features
28457 + include TPE, socket restrictions, and the sysctl system for
28458 + grsecurity. It is advised that you read through the help for
28459 + each option to determine its usefulness in your situation.
28463 +menu "Address Space Protection"
28464 +depends on GRKERNSEC
28466 +config GRKERNSEC_KMEM
28467 + bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
28469 + If you say Y here, /dev/kmem and /dev/mem won't be allowed to
28470 + be written to via mmap or otherwise to modify the running kernel.
28471 + /dev/port will also not be allowed to be opened. If you have module
28472 + support disabled, enabling this will close up four ways that are
28473 + currently used to insert malicious code into the running kernel.
28474 + Even with all these features enabled, we still highly recommend that
28475 + you use the RBAC system, as it is still possible for an attacker to
28476 + modify the running kernel through privileged I/O granted by ioperm/iopl.
28477 + If you are not using XFree86, you may be able to stop this additional
28478 + case by enabling the 'Disable privileged I/O' option. Though nothing
28479 + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
28480 + but only to video memory, which is the only writing we allow in this
28481 + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
28482 + not be allowed to mprotect it with PROT_WRITE later.
28483 + It is highly recommended that you say Y here if you meet all the
28484 + conditions above.
28486 +config GRKERNSEC_IO
28487 + bool "Disable privileged I/O"
28490 + select RTC_INTF_DEV
28491 + select RTC_DRV_CMOS
28494 + If you say Y here, all ioperm and iopl calls will return an error.
28495 + Ioperm and iopl can be used to modify the running kernel.
28496 + Unfortunately, some programs need this access to operate properly,
28497 + the most notable of which are XFree86 and hwclock. hwclock can be
28498 + remedied by having RTC support in the kernel, so real-time
28499 + clock support is enabled if this option is enabled, to ensure
28500 + that hwclock operates correctly. XFree86 still will not
28501 + operate correctly with this option enabled, so DO NOT CHOOSE Y
28502 + IF YOU USE XFree86. If you use XFree86 and you still want to
28503 + protect your kernel against modification, use the RBAC system.
28505 +config GRKERNSEC_PROC_MEMMAP
28506 + bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
28507 + depends on PAX_NOEXEC || PAX_ASLR
28509 + If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
28510 + give no information about the addresses of its mappings if
28511 + PaX features that rely on random addresses are enabled on the task.
28512 + If you use PaX it is greatly recommended that you say Y here as it
28513 + closes up a hole that makes the full ASLR useless for suid
28516 +config GRKERNSEC_BRUTE
28517 + bool "Deter exploit bruteforcing"
28519 + If you say Y here, attempts to bruteforce exploits against forking
28520 + daemons such as apache or sshd will be deterred. When a child of a
28521 + forking daemon is killed by PaX or crashes due to an illegal
28522 + instruction, the parent process will be delayed 30 seconds upon every
28523 + subsequent fork until the administrator is able to assess the
28524 + situation and restart the daemon. It is recommended that you also
28525 + enable signal logging in the auditing section so that logs are
28526 + generated when a process performs an illegal instruction.
28528 +config GRKERNSEC_MODSTOP
28529 + bool "Runtime module disabling"
28530 + depends on MODULES
28532 + If you say Y here, you will be able to disable the ability to (un)load
28533 + modules at runtime. This feature is useful if you need the ability
28534 + to load kernel modules at boot time, but do not want to allow an
28535 + attacker to load a rootkit kernel module into the system, or to remove
28536 + a loaded kernel module important to system functioning. You should
28537 + enable the /dev/mem protection feature as well, since rootkits can be
28538 + inserted into the kernel via other methods than kernel modules. Since
28539 + an untrusted module could still be loaded by modifying init scripts and
28540 + rebooting the system, it is also recommended that you enable the RBAC
28541 + system. If you enable this option, a sysctl option with name
28542 + "disable_modules" will be created. Setting this option to "1" disables
28543 + module loading. After this option is set, no further writes to it are
28544 + allowed until the system is rebooted.
28546 +config GRKERNSEC_HIDESYM
28547 + bool "Hide kernel symbols"
28549 + If you say Y here, getting information on loaded modules, and
28550 + displaying all kernel symbols through a syscall will be restricted
28551 + to users with CAP_SYS_MODULE. This option is only effective
28552 + provided the following conditions are met:
28553 + 1) The kernel using grsecurity is not precompiled by some distribution
28554 + 2) You are using the RBAC system and hiding other files such as your
28555 + kernel image and System.map
28556 + 3) You have the additional /proc restrictions enabled, which removes
28558 + If the above conditions are met, this option will aid to provide a
28559 + useful protection against local and remote kernel exploitation of
28560 + overflows and arbitrary read/write vulnerabilities.
28563 +menu "Role Based Access Control Options"
28564 +depends on GRKERNSEC
28566 +config GRKERNSEC_ACL_HIDEKERN
28567 + bool "Hide kernel processes"
28569 + If you say Y here, all kernel threads will be hidden to all
28570 + processes but those whose subject has the "view hidden processes"
28573 +config GRKERNSEC_ACL_MAXTRIES
28574 + int "Maximum tries before password lockout"
28577 + This option enforces the maximum number of times a user can attempt
28578 + to authorize themselves with the grsecurity RBAC system before being
28579 + denied the ability to attempt authorization again for a specified time.
28580 + The lower the number, the harder it will be to brute-force a password.
28582 +config GRKERNSEC_ACL_TIMEOUT
28583 + int "Time to wait after max password tries, in seconds"
28586 + This option specifies the time the user must wait after attempting to
28587 + authorize to the RBAC system with the maximum number of invalid
28588 + passwords. The higher the number, the harder it will be to brute-force
28592 +menu "Filesystem Protections"
28593 +depends on GRKERNSEC
28595 +config GRKERNSEC_PROC
28596 + bool "Proc restrictions"
28598 + If you say Y here, the permissions of the /proc filesystem
28599 + will be altered to enhance system security and privacy. You MUST
28600 + choose either a user only restriction or a user and group restriction.
28601 + Depending upon the option you choose, you can either restrict users to
28602 + see only the processes they themselves run, or choose a group that can
28603 + view all processes and files normally restricted to root if you choose
28604 + the "restrict to user only" option. NOTE: If you're running identd as
28605 + a non-root user, you will have to run it as the group you specify here.
28607 +config GRKERNSEC_PROC_USER
28608 + bool "Restrict /proc to user only"
28609 + depends on GRKERNSEC_PROC
28611 + If you say Y here, non-root users will only be able to view their own
28612 + processes, and restricts them from viewing network-related information,
28613 + and viewing kernel symbol and module information.
28615 +config GRKERNSEC_PROC_USERGROUP
28616 + bool "Allow special group"
28617 + depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
28619 + If you say Y here, you will be able to select a group that will be
28620 + able to view all processes, network-related information, and
28621 + kernel and symbol information. This option is useful if you want
28622 + to run identd as a non-root user.
28624 +config GRKERNSEC_PROC_GID
28625 + int "GID for special group"
28626 + depends on GRKERNSEC_PROC_USERGROUP
28629 +config GRKERNSEC_PROC_ADD
28630 + bool "Additional restrictions"
28631 + depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
28633 + If you say Y here, additional restrictions will be placed on
28634 + /proc that keep normal users from viewing device information and
28635 + slabinfo information that could be useful for exploits.
28637 +config GRKERNSEC_LINK
28638 + bool "Linking restrictions"
28640 + If you say Y here, /tmp race exploits will be prevented, since users
28641 + will no longer be able to follow symlinks owned by other users in
28642 + world-writable +t directories (i.e. /tmp), unless the owner of the
28643 + symlink is the owner of the directory. users will also not be
28644 + able to hardlink to files they do not own. If the sysctl option is
28645 + enabled, a sysctl option with name "linking_restrictions" is created.
28647 +config GRKERNSEC_FIFO
28648 + bool "FIFO restrictions"
28650 + If you say Y here, users will not be able to write to FIFOs they don't
28651 + own in world-writable +t directories (i.e. /tmp), unless the owner of
28652 + the FIFO is the same owner of the directory it's held in. If the sysctl
28653 + option is enabled, a sysctl option with name "fifo_restrictions" is
28656 +config GRKERNSEC_CHROOT
28657 + bool "Chroot jail restrictions"
28659 + If you say Y here, you will be able to choose several options that will
28660 + make breaking out of a chrooted jail much more difficult. If you
28661 + encounter no software incompatibilities with the following options, it
28662 + is recommended that you enable each one.
28664 +config GRKERNSEC_CHROOT_MOUNT
28665 + bool "Deny mounts"
28666 + depends on GRKERNSEC_CHROOT
28668 + If you say Y here, processes inside a chroot will not be able to
28669 + mount or remount filesystems. If the sysctl option is enabled, a
28670 + sysctl option with name "chroot_deny_mount" is created.
28672 +config GRKERNSEC_CHROOT_DOUBLE
28673 + bool "Deny double-chroots"
28674 + depends on GRKERNSEC_CHROOT
28676 + If you say Y here, processes inside a chroot will not be able to chroot
28677 + again outside the chroot. This is a widely used method of breaking
28678 + out of a chroot jail and should not be allowed. If the sysctl
28679 + option is enabled, a sysctl option with name
28680 + "chroot_deny_chroot" is created.
28682 +config GRKERNSEC_CHROOT_PIVOT
28683 + bool "Deny pivot_root in chroot"
28684 + depends on GRKERNSEC_CHROOT
28686 + If you say Y here, processes inside a chroot will not be able to use
28687 + a function called pivot_root() that was introduced in Linux 2.3.41. It
28688 + works similar to chroot in that it changes the root filesystem. This
28689 + function could be misused in a chrooted process to attempt to break out
28690 + of the chroot, and therefore should not be allowed. If the sysctl
28691 + option is enabled, a sysctl option with name "chroot_deny_pivot" is
28694 +config GRKERNSEC_CHROOT_CHDIR
28695 + bool "Enforce chdir(\"/\") on all chroots"
28696 + depends on GRKERNSEC_CHROOT
28698 + If you say Y here, the current working directory of all newly-chrooted
28699 + applications will be set to the the root directory of the chroot.
28700 + The man page on chroot(2) states:
28701 + Note that this call does not change the current working
28702 + directory, so that `.' can be outside the tree rooted at
28703 + `/'. In particular, the super-user can escape from a
28704 + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
28706 + It is recommended that you say Y here, since it's not known to break
28707 + any software. If the sysctl option is enabled, a sysctl option with
28708 + name "chroot_enforce_chdir" is created.
28710 +config GRKERNSEC_CHROOT_CHMOD
28711 + bool "Deny (f)chmod +s"
28712 + depends on GRKERNSEC_CHROOT
28714 + If you say Y here, processes inside a chroot will not be able to chmod
28715 + or fchmod files to make them have suid or sgid bits. This protects
28716 + against another published method of breaking a chroot. If the sysctl
28717 + option is enabled, a sysctl option with name "chroot_deny_chmod" is
28720 +config GRKERNSEC_CHROOT_FCHDIR
28721 + bool "Deny fchdir out of chroot"
28722 + depends on GRKERNSEC_CHROOT
28724 + If you say Y here, a well-known method of breaking chroots by fchdir'ing
28725 + to a file descriptor of the chrooting process that points to a directory
28726 + outside the filesystem will be stopped. If the sysctl option
28727 + is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
28729 +config GRKERNSEC_CHROOT_MKNOD
28730 + bool "Deny mknod"
28731 + depends on GRKERNSEC_CHROOT
28733 + If you say Y here, processes inside a chroot will not be allowed to
28734 + mknod. The problem with using mknod inside a chroot is that it
28735 + would allow an attacker to create a device entry that is the same
28736 + as one on the physical root of your system, which could range from
28737 + anything from the console device to a device for your harddrive (which
28738 + they could then use to wipe the drive or steal data). It is recommended
28739 + that you say Y here, unless you run into software incompatibilities.
28740 + If the sysctl option is enabled, a sysctl option with name
28741 + "chroot_deny_mknod" is created.
28743 +config GRKERNSEC_CHROOT_SHMAT
28744 + bool "Deny shmat() out of chroot"
28745 + depends on GRKERNSEC_CHROOT
28747 + If you say Y here, processes inside a chroot will not be able to attach
28748 + to shared memory segments that were created outside of the chroot jail.
28749 + It is recommended that you say Y here. If the sysctl option is enabled,
28750 + a sysctl option with name "chroot_deny_shmat" is created.
28752 +config GRKERNSEC_CHROOT_UNIX
28753 + bool "Deny access to abstract AF_UNIX sockets out of chroot"
28754 + depends on GRKERNSEC_CHROOT
28756 + If you say Y here, processes inside a chroot will not be able to
28757 + connect to abstract (meaning not belonging to a filesystem) Unix
28758 + domain sockets that were bound outside of a chroot. It is recommended
28759 + that you say Y here. If the sysctl option is enabled, a sysctl option
28760 + with name "chroot_deny_unix" is created.
28762 +config GRKERNSEC_CHROOT_FINDTASK
28763 + bool "Protect outside processes"
28764 + depends on GRKERNSEC_CHROOT
28766 + If you say Y here, processes inside a chroot will not be able to
28767 + kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
28768 + or view any process outside of the chroot. If the sysctl
28769 + option is enabled, a sysctl option with name "chroot_findtask" is
28772 +config GRKERNSEC_CHROOT_NICE
28773 + bool "Restrict priority changes"
28774 + depends on GRKERNSEC_CHROOT
28776 + If you say Y here, processes inside a chroot will not be able to raise
28777 + the priority of processes in the chroot, or alter the priority of
28778 + processes outside the chroot. This provides more security than simply
28779 + removing CAP_SYS_NICE from the process' capability set. If the
28780 + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
28783 +config GRKERNSEC_CHROOT_SYSCTL
28784 + bool "Deny sysctl writes"
28785 + depends on GRKERNSEC_CHROOT
28787 + If you say Y here, an attacker in a chroot will not be able to
28788 + write to sysctl entries, either by sysctl(2) or through a /proc
28789 + interface. It is strongly recommended that you say Y here. If the
28790 + sysctl option is enabled, a sysctl option with name
28791 + "chroot_deny_sysctl" is created.
28793 +config GRKERNSEC_CHROOT_CAPS
28794 + bool "Capability restrictions"
28795 + depends on GRKERNSEC_CHROOT
28797 + If you say Y here, the capabilities on all root processes within a
28798 + chroot jail will be lowered to stop module insertion, raw i/o,
28799 + system and net admin tasks, rebooting the system, modifying immutable
28800 + files, modifying IPC owned by another, and changing the system time.
28801 + This is left an option because it can break some apps. Disable this
28802 + if your chrooted apps are having problems performing those kinds of
28803 + tasks. If the sysctl option is enabled, a sysctl option with
28804 + name "chroot_caps" is created.
28807 +menu "Kernel Auditing"
28808 +depends on GRKERNSEC
28810 +config GRKERNSEC_AUDIT_GROUP
28811 + bool "Single group for auditing"
28813 + If you say Y here, the exec, chdir, (un)mount, and ipc logging features
28814 + will only operate on a group you specify. This option is recommended
28815 + if you only want to watch certain users instead of having a large
28816 + amount of logs from the entire system. If the sysctl option is enabled,
28817 + a sysctl option with name "audit_group" is created.
28819 +config GRKERNSEC_AUDIT_GID
28820 + int "GID for auditing"
28821 + depends on GRKERNSEC_AUDIT_GROUP
28824 +config GRKERNSEC_EXECLOG
28825 + bool "Exec logging"
28827 + If you say Y here, all execve() calls will be logged (since the
28828 + other exec*() calls are frontends to execve(), all execution
28829 + will be logged). Useful for shell-servers that like to keep track
28830 + of their users. If the sysctl option is enabled, a sysctl option with
28831 + name "exec_logging" is created.
28832 + WARNING: This option when enabled will produce a LOT of logs, especially
28833 + on an active system.
28835 +config GRKERNSEC_RESLOG
28836 + bool "Resource logging"
28838 + If you say Y here, all attempts to overstep resource limits will
28839 + be logged with the resource name, the requested size, and the current
28840 + limit. It is highly recommended that you say Y here. If the sysctl
28841 + option is enabled, a sysctl option with name "resource_logging" is
28842 + created. If the RBAC system is enabled, the sysctl value is ignored.
28844 +config GRKERNSEC_CHROOT_EXECLOG
28845 + bool "Log execs within chroot"
28847 + If you say Y here, all executions inside a chroot jail will be logged
28848 + to syslog. This can cause a large amount of logs if certain
28849 + applications (eg. djb's daemontools) are installed on the system, and
28850 + is therefore left as an option. If the sysctl option is enabled, a
28851 + sysctl option with name "chroot_execlog" is created.
28853 +config GRKERNSEC_AUDIT_CHDIR
28854 + bool "Chdir logging"
28856 + If you say Y here, all chdir() calls will be logged. If the sysctl
28857 + option is enabled, a sysctl option with name "audit_chdir" is created.
28859 +config GRKERNSEC_AUDIT_MOUNT
28860 + bool "(Un)Mount logging"
28862 + If you say Y here, all mounts and unmounts will be logged. If the
28863 + sysctl option is enabled, a sysctl option with name "audit_mount" is
28866 +config GRKERNSEC_AUDIT_IPC
28867 + bool "IPC logging"
28869 + If you say Y here, creation and removal of message queues, semaphores,
28870 + and shared memory will be logged. If the sysctl option is enabled, a
28871 + sysctl option with name "audit_ipc" is created.
28873 +config GRKERNSEC_SIGNAL
28874 + bool "Signal logging"
28876 + If you say Y here, certain important signals will be logged, such as
28877 + SIGSEGV, which will as a result inform you of when a error in a program
28878 + occurred, which in some cases could mean a possible exploit attempt.
28879 + If the sysctl option is enabled, a sysctl option with name
28880 + "signal_logging" is created.
28882 +config GRKERNSEC_FORKFAIL
28883 + bool "Fork failure logging"
28885 + If you say Y here, all failed fork() attempts will be logged.
28886 + This could suggest a fork bomb, or someone attempting to overstep
28887 + their process limit. If the sysctl option is enabled, a sysctl option
28888 + with name "forkfail_logging" is created.
28890 +config GRKERNSEC_TIME
28891 + bool "Time change logging"
28893 + If you say Y here, any changes of the system clock will be logged.
28894 + If the sysctl option is enabled, a sysctl option with name
28895 + "timechange_logging" is created.
28897 +config GRKERNSEC_PROC_IPADDR
28898 + bool "/proc/<pid>/ipaddr support"
28900 + If you say Y here, a new entry will be added to each /proc/<pid>
28901 + directory that contains the IP address of the person using the task.
28902 + The IP is carried across local TCP and AF_UNIX stream sockets.
28903 + This information can be useful for IDS/IPSes to perform remote response
28904 + to a local attack. The entry is readable by only the owner of the
28905 + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
28906 + the RBAC system), and thus does not create privacy concerns.
28908 +config GRKERNSEC_AUDIT_TEXTREL
28909 + bool 'ELF text relocations logging (READ HELP)'
28910 + depends on PAX_MPROTECT
28912 + If you say Y here, text relocations will be logged with the filename
28913 + of the offending library or binary. The purpose of the feature is
28914 + to help Linux distribution developers get rid of libraries and
28915 + binaries that need text relocations which hinder the future progress
28916 + of PaX. Only Linux distribution developers should say Y here, and
28917 + never on a production machine, as this option creates an information
28918 + leak that could aid an attacker in defeating the randomization of
28919 + a single memory region. If the sysctl option is enabled, a sysctl
28920 + option with name "audit_textrel" is created.
28924 +menu "Executable Protections"
28925 +depends on GRKERNSEC
28927 +config GRKERNSEC_EXECVE
28928 + bool "Enforce RLIMIT_NPROC on execs"
28930 + If you say Y here, users with a resource limit on processes will
28931 + have the value checked during execve() calls. The current system
28932 + only checks the system limit during fork() calls. If the sysctl option
28933 + is enabled, a sysctl option with name "execve_limiting" is created.
28935 +config GRKERNSEC_DMESG
28936 + bool "Dmesg(8) restriction"
28938 + If you say Y here, non-root users will not be able to use dmesg(8)
28939 + to view up to the last 4kb of messages in the kernel's log buffer.
28940 + If the sysctl option is enabled, a sysctl option with name "dmesg" is
28943 +config GRKERNSEC_TPE
28944 + bool "Trusted Path Execution (TPE)"
28946 + If you say Y here, you will be able to choose a gid to add to the
28947 + supplementary groups of users you want to mark as "untrusted."
28948 + These users will not be able to execute any files that are not in
28949 + root-owned directories writable only by root. If the sysctl option
28950 + is enabled, a sysctl option with name "tpe" is created.
28952 +config GRKERNSEC_TPE_ALL
28953 + bool "Partially restrict non-root users"
28954 + depends on GRKERNSEC_TPE
28956 + If you say Y here, All non-root users other than the ones in the
28957 + group specified in the main TPE option will only be allowed to
28958 + execute files in directories they own that are not group or
28959 + world-writable, or in directories owned by root and writable only by
28960 + root. If the sysctl option is enabled, a sysctl option with name
28961 + "tpe_restrict_all" is created.
28963 +config GRKERNSEC_TPE_INVERT
28964 + bool "Invert GID option"
28965 + depends on GRKERNSEC_TPE
28967 + If you say Y here, the group you specify in the TPE configuration will
28968 + decide what group TPE restrictions will be *disabled* for. This
28969 + option is useful if you want TPE restrictions to be applied to most
28970 + users on the system.
28972 +config GRKERNSEC_TPE_GID
28973 + int "GID for untrusted users"
28974 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
28977 + If you have selected the "Invert GID option" above, setting this
28978 + GID determines what group TPE restrictions will be *disabled* for.
28979 + If you have not selected the "Invert GID option" above, setting this
28980 + GID determines what group TPE restrictions will be *enabled* for.
28981 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
28984 +config GRKERNSEC_TPE_GID
28985 + int "GID for trusted users"
28986 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
28989 + If you have selected the "Invert GID option" above, setting this
28990 + GID determines what group TPE restrictions will be *disabled* for.
28991 + If you have not selected the "Invert GID option" above, setting this
28992 + GID determines what group TPE restrictions will be *enabled* for.
28993 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
28997 +menu "Network Protections"
28998 +depends on GRKERNSEC
29000 +config GRKERNSEC_RANDNET
29001 + bool "Larger entropy pools"
29003 + If you say Y here, the entropy pools used for many features of Linux
29004 + and grsecurity will be doubled in size. Since several grsecurity
29005 + features use additional randomness, it is recommended that you say Y
29006 + here. Saying Y here has a similar effect as modifying
29007 + /proc/sys/kernel/random/poolsize.
29009 +config GRKERNSEC_SOCKET
29010 + bool "Socket restrictions"
29012 + If you say Y here, you will be able to choose from several options.
29013 + If you assign a GID on your system and add it to the supplementary
29014 + groups of users you want to restrict socket access to, this patch
29015 + will perform up to three things, based on the option(s) you choose.
29017 +config GRKERNSEC_SOCKET_ALL
29018 + bool "Deny any sockets to group"
29019 + depends on GRKERNSEC_SOCKET
29021 + If you say Y here, you will be able to choose a GID of whose users will
29022 + be unable to connect to other hosts from your machine or run server
29023 + applications from your machine. If the sysctl option is enabled, a
29024 + sysctl option with name "socket_all" is created.
29026 +config GRKERNSEC_SOCKET_ALL_GID
29027 + int "GID to deny all sockets for"
29028 + depends on GRKERNSEC_SOCKET_ALL
29031 + Here you can choose the GID to disable socket access for. Remember to
29032 + add the users you want socket access disabled for to the GID
29033 + specified here. If the sysctl option is enabled, a sysctl option
29034 + with name "socket_all_gid" is created.
29036 +config GRKERNSEC_SOCKET_CLIENT
29037 + bool "Deny client sockets to group"
29038 + depends on GRKERNSEC_SOCKET
29040 + If you say Y here, you will be able to choose a GID of whose users will
29041 + be unable to connect to other hosts from your machine, but will be
29042 + able to run servers. If this option is enabled, all users in the group
29043 + you specify will have to use passive mode when initiating ftp transfers
29044 + from the shell on your machine. If the sysctl option is enabled, a
29045 + sysctl option with name "socket_client" is created.
29047 +config GRKERNSEC_SOCKET_CLIENT_GID
29048 + int "GID to deny client sockets for"
29049 + depends on GRKERNSEC_SOCKET_CLIENT
29052 + Here you can choose the GID to disable client socket access for.
29053 + Remember to add the users you want client socket access disabled for to
29054 + the GID specified here. If the sysctl option is enabled, a sysctl
29055 + option with name "socket_client_gid" is created.
29057 +config GRKERNSEC_SOCKET_SERVER
29058 + bool "Deny server sockets to group"
29059 + depends on GRKERNSEC_SOCKET
29061 + If you say Y here, you will be able to choose a GID of whose users will
29062 + be unable to run server applications from your machine. If the sysctl
29063 + option is enabled, a sysctl option with name "socket_server" is created.
29065 +config GRKERNSEC_SOCKET_SERVER_GID
29066 + int "GID to deny server sockets for"
29067 + depends on GRKERNSEC_SOCKET_SERVER
29070 + Here you can choose the GID to disable server socket access for.
29071 + Remember to add the users you want server socket access disabled for to
29072 + the GID specified here. If the sysctl option is enabled, a sysctl
29073 + option with name "socket_server_gid" is created.
29076 +menu "Sysctl support"
29077 +depends on GRKERNSEC && SYSCTL
29079 +config GRKERNSEC_SYSCTL
29080 + bool "Sysctl support"
29082 + If you say Y here, you will be able to change the options that
29083 + grsecurity runs with at bootup, without having to recompile your
29084 + kernel. You can echo values to files in /proc/sys/kernel/grsecurity
29085 + to enable (1) or disable (0) various features. All the sysctl entries
29086 + are mutable until the "grsec_lock" entry is set to a non-zero value.
29087 + All features enabled in the kernel configuration are disabled at boot
29088 + if you do not say Y to the "Turn on features by default" option.
29089 + All options should be set at startup, and the grsec_lock entry should
29090 + be set to a non-zero value after all the options are set.
29091 + *THIS IS EXTREMELY IMPORTANT*
29093 +config GRKERNSEC_SYSCTL_ON
29094 + bool "Turn on features by default"
29095 + depends on GRKERNSEC_SYSCTL
29097 + If you say Y here, instead of having all features enabled in the
29098 + kernel configuration disabled at boot time, the features will be
29099 + enabled at boot time. It is recommended you say Y here unless
29100 + there is some reason you would want all sysctl-tunable features to
29101 + be disabled by default. As mentioned elsewhere, it is important
29102 + to enable the grsec_lock entry once you have finished modifying
29103 + the sysctl entries.
29106 +menu "Logging Options"
29107 +depends on GRKERNSEC
29109 +config GRKERNSEC_FLOODTIME
29110 + int "Seconds in between log messages (minimum)"
29113 + This option allows you to enforce the number of seconds between
29114 + grsecurity log messages. The default should be suitable for most
29115 + people, however, if you choose to change it, choose a value small enough
29116 + to allow informative logs to be produced, but large enough to
29117 + prevent flooding.
29119 +config GRKERNSEC_FLOODBURST
29120 + int "Number of messages in a burst (maximum)"
29123 + This option allows you to choose the maximum number of messages allowed
29124 + within the flood time interval you chose in a separate option. The
29125 + default should be suitable for most people, however if you find that
29126 + many of your logs are being interpreted as flooding, you may want to
29127 + raise this value.
29132 diff -urNp linux-2.6.29/grsecurity/Makefile linux-2.6.29/grsecurity/Makefile
29133 --- linux-2.6.29/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
29134 +++ linux-2.6.29/grsecurity/Makefile 2009-03-28 14:26:20.000000000 -0400
29136 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
29137 +# during 2001-2005 it has been completely redesigned by Brad Spengler
29138 +# into an RBAC system
29140 +# All code in this directory and various hooks inserted throughout the kernel
29141 +# are copyright Brad Spengler, and released under the GPL v2 or higher
29143 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
29144 + grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
29145 + grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
29147 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
29148 + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
29149 + gracl_learn.o grsec_log.o
29150 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
29152 +ifndef CONFIG_GRKERNSEC
29153 +obj-y += grsec_disabled.o
29156 diff -urNp linux-2.6.29/include/asm-frv/kmap_types.h linux-2.6.29/include/asm-frv/kmap_types.h
29157 --- linux-2.6.29/include/asm-frv/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
29158 +++ linux-2.6.29/include/asm-frv/kmap_types.h 2009-03-28 14:26:20.000000000 -0400
29159 @@ -23,6 +23,7 @@ enum km_type {
29167 diff -urNp linux-2.6.29/include/asm-generic/futex.h linux-2.6.29/include/asm-generic/futex.h
29168 --- linux-2.6.29/include/asm-generic/futex.h 2009-03-23 19:12:14.000000000 -0400
29169 +++ linux-2.6.29/include/asm-generic/futex.h 2009-03-28 14:26:20.000000000 -0400
29171 #include <asm/errno.h>
29174 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
29175 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
29177 int op = (encoded_op >> 28) & 7;
29178 int cmp = (encoded_op >> 24) & 15;
29179 @@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
29183 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
29184 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
29188 diff -urNp linux-2.6.29/include/asm-generic/vmlinux.lds.h linux-2.6.29/include/asm-generic/vmlinux.lds.h
29189 --- linux-2.6.29/include/asm-generic/vmlinux.lds.h 2009-03-23 19:12:14.000000000 -0400
29190 +++ linux-2.6.29/include/asm-generic/vmlinux.lds.h 2009-03-28 14:26:20.000000000 -0400
29192 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
29193 VMLINUX_SYMBOL(__start_rodata) = .; \
29194 *(.rodata) *(.rodata.*) \
29195 + *(.data.read_only) \
29196 *(__vermagic) /* Kernel version magic */ \
29197 *(__markers_strings) /* Markers: strings */ \
29198 *(__tracepoints_strings)/* Tracepoints: strings */ \
29199 diff -urNp linux-2.6.29/include/asm-m32r/kmap_types.h linux-2.6.29/include/asm-m32r/kmap_types.h
29200 --- linux-2.6.29/include/asm-m32r/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
29201 +++ linux-2.6.29/include/asm-m32r/kmap_types.h 2009-03-28 14:26:20.000000000 -0400
29202 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
29207 +D(13) KM_CLEARPAGE,
29212 diff -urNp linux-2.6.29/include/asm-mn10300/kmap_types.h linux-2.6.29/include/asm-mn10300/kmap_types.h
29213 --- linux-2.6.29/include/asm-mn10300/kmap_types.h 2009-03-23 19:12:14.000000000 -0400
29214 +++ linux-2.6.29/include/asm-mn10300/kmap_types.h 2009-03-28 14:26:20.000000000 -0400
29215 @@ -25,6 +25,7 @@ enum km_type {
29223 diff -urNp linux-2.6.29/include/drm/drm_pciids.h linux-2.6.29/include/drm/drm_pciids.h
29224 --- linux-2.6.29/include/drm/drm_pciids.h 2009-03-23 19:12:14.000000000 -0400
29225 +++ linux-2.6.29/include/drm/drm_pciids.h 2009-03-28 14:26:20.000000000 -0400
29226 @@ -243,7 +243,7 @@
29227 {0x1002, 0x796d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
29228 {0x1002, 0x796e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
29229 {0x1002, 0x796f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
29231 + {0, 0, 0, 0, 0, 0}
29233 #define r128_PCI_IDS \
29234 {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29235 @@ -283,14 +283,14 @@
29236 {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29237 {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29238 {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29240 + {0, 0, 0, 0, 0, 0}
29242 #define mga_PCI_IDS \
29243 {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
29244 {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
29245 {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
29246 {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
29248 + {0, 0, 0, 0, 0, 0}
29250 #define mach64_PCI_IDS \
29251 {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29252 @@ -313,7 +313,7 @@
29253 {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29254 {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29255 {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29257 + {0, 0, 0, 0, 0, 0}
29259 #define sisdrv_PCI_IDS \
29260 {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29261 @@ -324,7 +324,7 @@
29262 {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29263 {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
29264 {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
29266 + {0, 0, 0, 0, 0, 0}
29268 #define tdfx_PCI_IDS \
29269 {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29270 @@ -333,7 +333,7 @@
29271 {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29272 {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29273 {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29275 + {0, 0, 0, 0, 0, 0}
29277 #define viadrv_PCI_IDS \
29278 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29279 @@ -345,25 +345,25 @@
29280 {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29281 {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
29282 {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
29284 + {0, 0, 0, 0, 0, 0}
29286 #define i810_PCI_IDS \
29287 {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29288 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29289 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29290 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29292 + {0, 0, 0, 0, 0, 0}
29294 #define i830_PCI_IDS \
29295 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29296 {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29297 {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29298 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29300 + {0, 0, 0, 0, 0, 0}
29302 #define gamma_PCI_IDS \
29303 {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29305 + {0, 0, 0, 0, 0, 0}
29307 #define savage_PCI_IDS \
29308 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
29309 @@ -389,10 +389,10 @@
29310 {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
29311 {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
29312 {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
29314 + {0, 0, 0, 0, 0, 0}
29316 #define ffb_PCI_IDS \
29318 + {0, 0, 0, 0, 0, 0}
29320 #define i915_PCI_IDS \
29321 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
29322 @@ -418,4 +418,4 @@
29323 {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
29324 {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
29325 {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
29327 + {0, 0, 0, 0, 0, 0}
29328 diff -urNp linux-2.6.29/include/linux/a.out.h linux-2.6.29/include/linux/a.out.h
29329 --- linux-2.6.29/include/linux/a.out.h 2009-03-23 19:12:14.000000000 -0400
29330 +++ linux-2.6.29/include/linux/a.out.h 2009-03-28 14:26:20.000000000 -0400
29331 @@ -39,6 +39,14 @@ enum machine_type {
29332 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
29335 +/* Constants for the N_FLAGS field */
29336 +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29337 +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
29338 +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
29339 +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
29340 +/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29341 +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29343 #if !defined (N_MAGIC)
29344 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
29346 diff -urNp linux-2.6.29/include/linux/binfmts.h linux-2.6.29/include/linux/binfmts.h
29347 --- linux-2.6.29/include/linux/binfmts.h 2009-03-23 19:12:14.000000000 -0400
29348 +++ linux-2.6.29/include/linux/binfmts.h 2009-03-28 14:26:20.000000000 -0400
29349 @@ -79,6 +79,7 @@ struct linux_binfmt {
29350 int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
29351 int (*load_shlib)(struct file *);
29352 int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
29353 + void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags);
29354 unsigned long min_coredump; /* minimal dump size */
29357 diff -urNp linux-2.6.29/include/linux/cache.h linux-2.6.29/include/linux/cache.h
29358 --- linux-2.6.29/include/linux/cache.h 2009-03-23 19:12:14.000000000 -0400
29359 +++ linux-2.6.29/include/linux/cache.h 2009-03-28 14:26:20.000000000 -0400
29361 #define __read_mostly
29364 +#ifndef __read_only
29365 +#define __read_only __read_mostly
29368 #ifndef ____cacheline_aligned
29369 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
29371 diff -urNp linux-2.6.29/include/linux/capability.h linux-2.6.29/include/linux/capability.h
29372 --- linux-2.6.29/include/linux/capability.h 2009-03-23 19:12:14.000000000 -0400
29373 +++ linux-2.6.29/include/linux/capability.h 2009-03-28 14:26:20.000000000 -0400
29374 @@ -548,6 +548,7 @@ extern const kernel_cap_t __cap_init_eff
29375 (security_real_capable_noaudit((t), (cap)) == 0)
29377 extern int capable(int cap);
29378 +int capable_nolog(int cap);
29380 /* audit system wants to get cap info from files as well */
29382 diff -urNp linux-2.6.29/include/linux/cpumask.h linux-2.6.29/include/linux/cpumask.h
29383 --- linux-2.6.29/include/linux/cpumask.h 2009-03-23 19:12:14.000000000 -0400
29384 +++ linux-2.6.29/include/linux/cpumask.h 2009-03-28 14:26:20.000000000 -0400
29385 @@ -142,7 +142,6 @@
29386 #include <linux/bitmap.h>
29388 typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
29389 -extern cpumask_t _unused_cpumask_arg_;
29391 #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS
29392 #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
29393 diff -urNp linux-2.6.29/include/linux/elf.h linux-2.6.29/include/linux/elf.h
29394 --- linux-2.6.29/include/linux/elf.h 2009-03-23 19:12:14.000000000 -0400
29395 +++ linux-2.6.29/include/linux/elf.h 2009-03-28 14:26:20.000000000 -0400
29396 @@ -49,6 +49,17 @@ typedef __s64 Elf64_Sxword;
29397 #define PT_GNU_EH_FRAME 0x6474e550
29399 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
29400 +#define PT_GNU_RELRO (PT_LOOS + 0x474e552)
29402 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
29404 +/* Constants for the e_flags field */
29405 +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29406 +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
29407 +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
29408 +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
29409 +/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29410 +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29412 /* These constants define the different elf file types */
29414 @@ -84,6 +95,8 @@ typedef __s64 Elf64_Sxword;
29415 #define DT_DEBUG 21
29416 #define DT_TEXTREL 22
29417 #define DT_JMPREL 23
29418 +#define DT_FLAGS 30
29419 + #define DF_TEXTREL 0x00000004
29420 #define DT_ENCODING 32
29421 #define OLD_DT_LOOS 0x60000000
29422 #define DT_LOOS 0x6000000d
29423 @@ -230,6 +243,19 @@ typedef struct elf64_hdr {
29427 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
29428 +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
29429 +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
29430 +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
29431 +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
29432 +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
29433 +/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
29434 +/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
29435 +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
29436 +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
29437 +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
29438 +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
29440 typedef struct elf32_phdr{
29442 Elf32_Off p_offset;
29443 @@ -322,6 +348,8 @@ typedef struct elf64_shdr {
29449 #define ELFMAG0 0x7f /* EI_MAG */
29450 #define ELFMAG1 'E'
29451 #define ELFMAG2 'L'
29452 @@ -385,6 +413,7 @@ extern Elf32_Dyn _DYNAMIC [];
29453 #define elf_phdr elf32_phdr
29454 #define elf_note elf32_note
29455 #define elf_addr_t Elf32_Off
29456 +#define elf_dyn Elf32_Dyn
29460 @@ -393,6 +422,7 @@ extern Elf64_Dyn _DYNAMIC [];
29461 #define elf_phdr elf64_phdr
29462 #define elf_note elf64_note
29463 #define elf_addr_t Elf64_Off
29464 +#define elf_dyn Elf64_Dyn
29468 diff -urNp linux-2.6.29/include/linux/gracl.h linux-2.6.29/include/linux/gracl.h
29469 --- linux-2.6.29/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
29470 +++ linux-2.6.29/include/linux/gracl.h 2009-03-28 14:26:20.000000000 -0400
29475 +#include <linux/grdefs.h>
29476 +#include <linux/resource.h>
29477 +#include <linux/capability.h>
29478 +#include <linux/dcache.h>
29479 +#include <asm/resource.h>
29481 +/* Major status information */
29483 +#define GR_VERSION "grsecurity 2.1.14"
29484 +#define GRSECURITY_VERSION 0x2114
29495 + GR_SPROLEPAM = 8,
29498 +/* Password setup definitions
29499 + * kernel/grhash.c */
29502 + GR_SALT_LEN = 16,
29507 + GR_SPROLE_LEN = 64,
29510 +#define GR_NLIMITS 32
29512 +/* Begin Data Structures */
29514 +struct sprole_pw {
29515 + unsigned char *rolename;
29516 + unsigned char salt[GR_SALT_LEN];
29517 + unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
29520 +struct name_entry {
29527 + struct name_entry *prev;
29528 + struct name_entry *next;
29531 +struct inodev_entry {
29532 + struct name_entry *nentry;
29533 + struct inodev_entry *prev;
29534 + struct inodev_entry *next;
29537 +struct acl_role_db {
29538 + struct acl_role_label **r_hash;
29542 +struct inodev_db {
29543 + struct inodev_entry **i_hash;
29548 + struct name_entry **n_hash;
29552 +struct crash_uid {
29554 + unsigned long expires;
29557 +struct gr_hash_struct {
29559 + void **nametable;
29561 + __u32 table_size;
29566 +/* Userspace Grsecurity ACL data structures */
29568 +struct acl_subject_label {
29573 + kernel_cap_t cap_mask;
29574 + kernel_cap_t cap_lower;
29576 + struct rlimit res[GR_NLIMITS];
29579 + __u8 user_trans_type;
29580 + __u8 group_trans_type;
29581 + uid_t *user_transitions;
29582 + gid_t *group_transitions;
29583 + __u16 user_trans_num;
29584 + __u16 group_trans_num;
29586 + __u32 ip_proto[8];
29588 + struct acl_ip_label **ips;
29590 + __u32 inaddr_any_override;
29593 + unsigned long expires;
29595 + struct acl_subject_label *parent_subject;
29596 + struct gr_hash_struct *hash;
29597 + struct acl_subject_label *prev;
29598 + struct acl_subject_label *next;
29600 + struct acl_object_label **obj_hash;
29601 + __u32 obj_hash_size;
29605 +struct role_allowed_ip {
29609 + struct role_allowed_ip *prev;
29610 + struct role_allowed_ip *next;
29613 +struct role_transition {
29616 + struct role_transition *prev;
29617 + struct role_transition *next;
29620 +struct acl_role_label {
29625 + __u16 auth_attempts;
29626 + unsigned long expires;
29628 + struct acl_subject_label *root_label;
29629 + struct gr_hash_struct *hash;
29631 + struct acl_role_label *prev;
29632 + struct acl_role_label *next;
29634 + struct role_transition *transitions;
29635 + struct role_allowed_ip *allowed_ips;
29636 + uid_t *domain_children;
29637 + __u16 domain_child_num;
29639 + struct acl_subject_label **subj_hash;
29640 + __u32 subj_hash_size;
29643 +struct user_acl_role_db {
29644 + struct acl_role_label **r_table;
29645 + __u32 num_pointers; /* Number of allocations to track */
29646 + __u32 num_roles; /* Number of roles */
29647 + __u32 num_domain_children; /* Number of domain children */
29648 + __u32 num_subjects; /* Number of subjects */
29649 + __u32 num_objects; /* Number of objects */
29652 +struct acl_object_label {
29658 + struct acl_subject_label *nested;
29659 + struct acl_object_label *globbed;
29661 + /* next two structures not used */
29663 + struct acl_object_label *prev;
29664 + struct acl_object_label *next;
29667 +struct acl_ip_label {
29676 + /* next two structures not used */
29678 + struct acl_ip_label *prev;
29679 + struct acl_ip_label *next;
29683 + struct user_acl_role_db role_db;
29684 + unsigned char pw[GR_PW_LEN];
29685 + unsigned char salt[GR_SALT_LEN];
29686 + unsigned char sum[GR_SHA_LEN];
29687 + unsigned char sp_role[GR_SPROLE_LEN];
29688 + struct sprole_pw *sprole_pws;
29689 + dev_t segv_device;
29690 + ino_t segv_inode;
29692 + __u16 num_sprole_pws;
29696 +struct gr_arg_wrapper {
29697 + struct gr_arg *arg;
29702 +struct subject_map {
29703 + struct acl_subject_label *user;
29704 + struct acl_subject_label *kernel;
29705 + struct subject_map *prev;
29706 + struct subject_map *next;
29709 +struct acl_subj_map_db {
29710 + struct subject_map **s_hash;
29714 +/* End Data Structures Section */
29716 +/* Hash functions generated by empirical testing by Brad Spengler
29717 + Makes good use of the low bits of the inode. Generally 0-1 times
29718 + in loop for successful match. 0-3 for unsuccessful match.
29719 + Shift/add algorithm with modulus of table size and an XOR*/
29721 +static __inline__ unsigned int
29722 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
29724 + return (((uid << type) + (uid ^ type)) % sz);
29727 + static __inline__ unsigned int
29728 +shash(const struct acl_subject_label *userp, const unsigned int sz)
29730 + return ((const unsigned long)userp % sz);
29733 +static __inline__ unsigned int
29734 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
29736 + return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
29739 +static __inline__ unsigned int
29740 +nhash(const char *name, const __u16 len, const unsigned int sz)
29742 + return full_name_hash(name, len) % sz;
29745 +#define FOR_EACH_ROLE_START(role,iter) \
29748 + while (iter < acl_role_set.r_size) { \
29749 + if (role == NULL) \
29750 + role = acl_role_set.r_hash[iter]; \
29751 + if (role == NULL) { \
29756 +#define FOR_EACH_ROLE_END(role,iter) \
29757 + role = role->next; \
29758 + if (role == NULL) \
29762 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
29765 + while (iter < role->subj_hash_size) { \
29766 + if (subj == NULL) \
29767 + subj = role->subj_hash[iter]; \
29768 + if (subj == NULL) { \
29773 +#define FOR_EACH_SUBJECT_END(subj,iter) \
29774 + subj = subj->next; \
29775 + if (subj == NULL) \
29780 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
29781 + subj = role->hash->first; \
29782 + while (subj != NULL) {
29784 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
29785 + subj = subj->next; \
29790 diff -urNp linux-2.6.29/include/linux/gralloc.h linux-2.6.29/include/linux/gralloc.h
29791 --- linux-2.6.29/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
29792 +++ linux-2.6.29/include/linux/gralloc.h 2009-03-28 14:26:20.000000000 -0400
29794 +#ifndef __GRALLOC_H
29795 +#define __GRALLOC_H
29797 +void acl_free_all(void);
29798 +int acl_alloc_stack_init(unsigned long size);
29799 +void *acl_alloc(unsigned long len);
29802 diff -urNp linux-2.6.29/include/linux/grdefs.h linux-2.6.29/include/linux/grdefs.h
29803 --- linux-2.6.29/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
29804 +++ linux-2.6.29/include/linux/grdefs.h 2009-03-28 14:26:20.000000000 -0400
29809 +/* Begin grsecurity status declarations */
29813 + GR_STATUS_INIT = 0x00 // disabled state
29816 +/* Begin ACL declarations */
29821 + GR_ROLE_USER = 0x0001,
29822 + GR_ROLE_GROUP = 0x0002,
29823 + GR_ROLE_DEFAULT = 0x0004,
29824 + GR_ROLE_SPECIAL = 0x0008,
29825 + GR_ROLE_AUTH = 0x0010,
29826 + GR_ROLE_NOPW = 0x0020,
29827 + GR_ROLE_GOD = 0x0040,
29828 + GR_ROLE_LEARN = 0x0080,
29829 + GR_ROLE_TPE = 0x0100,
29830 + GR_ROLE_DOMAIN = 0x0200,
29831 + GR_ROLE_PAM = 0x0400
29834 +/* ACL Subject and Object mode flags */
29836 + GR_DELETED = 0x80000000
29839 +/* ACL Object-only mode flags */
29841 + GR_READ = 0x00000001,
29842 + GR_APPEND = 0x00000002,
29843 + GR_WRITE = 0x00000004,
29844 + GR_EXEC = 0x00000008,
29845 + GR_FIND = 0x00000010,
29846 + GR_INHERIT = 0x00000020,
29847 + GR_SETID = 0x00000040,
29848 + GR_CREATE = 0x00000080,
29849 + GR_DELETE = 0x00000100,
29850 + GR_LINK = 0x00000200,
29851 + GR_AUDIT_READ = 0x00000400,
29852 + GR_AUDIT_APPEND = 0x00000800,
29853 + GR_AUDIT_WRITE = 0x00001000,
29854 + GR_AUDIT_EXEC = 0x00002000,
29855 + GR_AUDIT_FIND = 0x00004000,
29856 + GR_AUDIT_INHERIT= 0x00008000,
29857 + GR_AUDIT_SETID = 0x00010000,
29858 + GR_AUDIT_CREATE = 0x00020000,
29859 + GR_AUDIT_DELETE = 0x00040000,
29860 + GR_AUDIT_LINK = 0x00080000,
29861 + GR_PTRACERD = 0x00100000,
29862 + GR_NOPTRACE = 0x00200000,
29863 + GR_SUPPRESS = 0x00400000,
29864 + GR_NOLEARN = 0x00800000
29867 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
29868 + GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
29869 + GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
29871 +/* ACL subject-only mode flags */
29873 + GR_KILL = 0x00000001,
29874 + GR_VIEW = 0x00000002,
29875 + GR_PROTECTED = 0x00000004,
29876 + GR_LEARN = 0x00000008,
29877 + GR_OVERRIDE = 0x00000010,
29878 + /* just a placeholder, this mode is only used in userspace */
29879 + GR_DUMMY = 0x00000020,
29880 + GR_PROTSHM = 0x00000040,
29881 + GR_KILLPROC = 0x00000080,
29882 + GR_KILLIPPROC = 0x00000100,
29883 + /* just a placeholder, this mode is only used in userspace */
29884 + GR_NOTROJAN = 0x00000200,
29885 + GR_PROTPROCFD = 0x00000400,
29886 + GR_PROCACCT = 0x00000800,
29887 + GR_RELAXPTRACE = 0x00001000,
29888 + GR_NESTED = 0x00002000,
29889 + GR_INHERITLEARN = 0x00004000,
29890 + GR_PROCFIND = 0x00008000,
29891 + GR_POVERRIDE = 0x00010000,
29892 + GR_KERNELAUTH = 0x00020000,
29896 + GR_PAX_ENABLE_SEGMEXEC = 0x0001,
29897 + GR_PAX_ENABLE_PAGEEXEC = 0x0002,
29898 + GR_PAX_ENABLE_MPROTECT = 0x0004,
29899 + GR_PAX_ENABLE_RANDMMAP = 0x0008,
29900 + GR_PAX_ENABLE_EMUTRAMP = 0x0010,
29901 + GR_PAX_DISABLE_SEGMEXEC = 0x0100,
29902 + GR_PAX_DISABLE_PAGEEXEC = 0x0200,
29903 + GR_PAX_DISABLE_MPROTECT = 0x0400,
29904 + GR_PAX_DISABLE_RANDMMAP = 0x0800,
29905 + GR_PAX_DISABLE_EMUTRAMP = 0x1000,
29909 + GR_ID_USER = 0x01,
29910 + GR_ID_GROUP = 0x02,
29914 + GR_ID_ALLOW = 0x01,
29915 + GR_ID_DENY = 0x02,
29918 +#define GR_CRASH_RES 31
29919 +#define GR_UIDTABLE_MAX 500
29921 +/* begin resource learning section */
29923 + GR_RLIM_CPU_BUMP = 60,
29924 + GR_RLIM_FSIZE_BUMP = 50000,
29925 + GR_RLIM_DATA_BUMP = 10000,
29926 + GR_RLIM_STACK_BUMP = 1000,
29927 + GR_RLIM_CORE_BUMP = 10000,
29928 + GR_RLIM_RSS_BUMP = 500000,
29929 + GR_RLIM_NPROC_BUMP = 1,
29930 + GR_RLIM_NOFILE_BUMP = 5,
29931 + GR_RLIM_MEMLOCK_BUMP = 50000,
29932 + GR_RLIM_AS_BUMP = 500000,
29933 + GR_RLIM_LOCKS_BUMP = 2,
29934 + GR_RLIM_SIGPENDING_BUMP = 5,
29935 + GR_RLIM_MSGQUEUE_BUMP = 10000,
29936 + GR_RLIM_NICE_BUMP = 1,
29937 + GR_RLIM_RTPRIO_BUMP = 1,
29938 + GR_RLIM_RTTIME_BUMP = 1000000
29942 diff -urNp linux-2.6.29/include/linux/grinternal.h linux-2.6.29/include/linux/grinternal.h
29943 --- linux-2.6.29/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
29944 +++ linux-2.6.29/include/linux/grinternal.h 2009-03-28 14:26:20.000000000 -0400
29946 +#ifndef __GRINTERNAL_H
29947 +#define __GRINTERNAL_H
29949 +#ifdef CONFIG_GRKERNSEC
29951 +#include <linux/fs.h>
29952 +#include <linux/gracl.h>
29953 +#include <linux/grdefs.h>
29954 +#include <linux/grmsg.h>
29956 +void gr_add_learn_entry(const char *fmt, ...);
29957 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
29958 + const struct vfsmount *mnt);
29959 +__u32 gr_check_create(const struct dentry *new_dentry,
29960 + const struct dentry *parent,
29961 + const struct vfsmount *mnt, const __u32 mode);
29962 +int gr_check_protected_task(const struct task_struct *task);
29963 +__u32 to_gr_audit(const __u32 reqmode);
29964 +int gr_set_acls(const int type);
29966 +int gr_acl_is_enabled(void);
29967 +char gr_roletype_to_char(void);
29969 +void gr_handle_alertkill(struct task_struct *task);
29970 +char *gr_to_filename(const struct dentry *dentry,
29971 + const struct vfsmount *mnt);
29972 +char *gr_to_filename1(const struct dentry *dentry,
29973 + const struct vfsmount *mnt);
29974 +char *gr_to_filename2(const struct dentry *dentry,
29975 + const struct vfsmount *mnt);
29976 +char *gr_to_filename3(const struct dentry *dentry,
29977 + const struct vfsmount *mnt);
29979 +extern int grsec_enable_link;
29980 +extern int grsec_enable_fifo;
29981 +extern int grsec_enable_execve;
29982 +extern int grsec_enable_shm;
29983 +extern int grsec_enable_execlog;
29984 +extern int grsec_enable_signal;
29985 +extern int grsec_enable_forkfail;
29986 +extern int grsec_enable_time;
29987 +extern int grsec_enable_chroot_shmat;
29988 +extern int grsec_enable_chroot_findtask;
29989 +extern int grsec_enable_chroot_mount;
29990 +extern int grsec_enable_chroot_double;
29991 +extern int grsec_enable_chroot_pivot;
29992 +extern int grsec_enable_chroot_chdir;
29993 +extern int grsec_enable_chroot_chmod;
29994 +extern int grsec_enable_chroot_mknod;
29995 +extern int grsec_enable_chroot_fchdir;
29996 +extern int grsec_enable_chroot_nice;
29997 +extern int grsec_enable_chroot_execlog;
29998 +extern int grsec_enable_chroot_caps;
29999 +extern int grsec_enable_chroot_sysctl;
30000 +extern int grsec_enable_chroot_unix;
30001 +extern int grsec_enable_tpe;
30002 +extern int grsec_tpe_gid;
30003 +extern int grsec_enable_tpe_all;
30004 +extern int grsec_enable_sidcaps;
30005 +extern int grsec_enable_socket_all;
30006 +extern int grsec_socket_all_gid;
30007 +extern int grsec_enable_socket_client;
30008 +extern int grsec_socket_client_gid;
30009 +extern int grsec_enable_socket_server;
30010 +extern int grsec_socket_server_gid;
30011 +extern int grsec_audit_gid;
30012 +extern int grsec_enable_group;
30013 +extern int grsec_enable_audit_ipc;
30014 +extern int grsec_enable_audit_textrel;
30015 +extern int grsec_enable_mount;
30016 +extern int grsec_enable_chdir;
30017 +extern int grsec_resource_logging;
30018 +extern int grsec_lock;
30020 +extern spinlock_t grsec_alert_lock;
30021 +extern unsigned long grsec_alert_wtime;
30022 +extern unsigned long grsec_alert_fyet;
30024 +extern spinlock_t grsec_audit_lock;
30026 +extern rwlock_t grsec_exec_file_lock;
30028 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
30029 + gr_to_filename2(tsk->exec_file->f_path.dentry, \
30030 + tsk->exec_file->f_vfsmnt) : "/")
30032 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
30033 + gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
30034 + tsk->parent->exec_file->f_vfsmnt) : "/")
30036 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
30037 + gr_to_filename(tsk->exec_file->f_path.dentry, \
30038 + tsk->exec_file->f_vfsmnt) : "/")
30040 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
30041 + gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
30042 + tsk->parent->exec_file->f_vfsmnt) : "/")
30044 +#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
30045 + ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
30046 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
30047 + (tsk_a->fs->root.dentry->d_inode->i_ino != \
30048 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
30050 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
30051 + (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
30052 + tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
30053 + (tsk_a->fs->root.dentry->d_inode->i_ino == \
30054 + tsk_b->fs->root.dentry->d_inode->i_ino))
30056 +#define DEFAULTSECARGS(task, cred, pcred) gr_task_fullpath(task), task->comm, \
30057 + task->pid, cred->uid, \
30058 + cred->euid, cred->gid, cred->egid, \
30059 + gr_parent_task_fullpath(task), \
30060 + task->parent->comm, task->parent->pid, \
30061 + pcred->uid, pcred->euid, \
30062 + pcred->gid, pcred->egid
30064 +#define GR_CHROOT_CAPS {{ \
30065 + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
30066 + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
30067 + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
30068 + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
30069 + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
30070 + CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
30072 +#define security_learn(normal_msg,args...) \
30074 + read_lock(&grsec_exec_file_lock); \
30075 + gr_add_learn_entry(normal_msg "\n", ## args); \
30076 + read_unlock(&grsec_exec_file_lock); \
30082 + GR_DONT_AUDIT_GOOD
30093 + GR_SYSCTL_HIDDEN,
30096 + GR_ONE_INT_TWO_STR,
30101 + GR_FIVE_INT_TWO_STR,
30107 + GR_FILENAME_TWO_INT,
30108 + GR_FILENAME_TWO_INT_STR,
30119 +#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
30120 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
30121 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
30122 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
30123 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
30124 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
30125 +#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)
30126 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
30127 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
30128 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
30129 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
30130 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
30131 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
30132 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
30133 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
30134 +#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)
30135 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
30136 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
30137 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
30138 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
30139 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
30140 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
30141 +#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)
30142 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
30143 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
30144 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
30145 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
30146 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
30147 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
30148 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
30149 +#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)
30151 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
30156 diff -urNp linux-2.6.29/include/linux/grmsg.h linux-2.6.29/include/linux/grmsg.h
30157 --- linux-2.6.29/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
30158 +++ linux-2.6.29/include/linux/grmsg.h 2009-03-28 14:26:20.000000000 -0400
30160 +#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"
30161 +#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"
30162 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
30163 +#define GR_STOPMOD_MSG "denied modification of module state by "
30164 +#define GR_IOPERM_MSG "denied use of ioperm() by "
30165 +#define GR_IOPL_MSG "denied use of iopl() by "
30166 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
30167 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
30168 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
30169 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
30170 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
30171 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
30172 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
30173 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
30174 +#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"
30175 +#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"
30176 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
30177 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
30178 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
30179 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
30180 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
30181 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
30182 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
30183 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
30184 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
30185 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
30186 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
30187 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
30188 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
30189 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
30190 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
30191 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
30192 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
30193 +#define GR_NPROC_MSG "denied overstep of process limit by "
30194 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
30195 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
30196 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
30197 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
30198 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
30199 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
30200 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
30201 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
30202 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
30203 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
30204 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
30205 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
30206 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
30207 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
30208 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
30209 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
30210 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
30211 +#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"
30212 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
30213 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
30214 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
30215 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
30216 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
30217 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
30218 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
30219 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
30220 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
30221 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
30222 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
30223 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
30224 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
30225 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
30226 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
30227 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
30228 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
30229 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
30230 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
30231 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
30232 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
30233 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
30234 +#define GR_NICE_CHROOT_MSG "denied priority change by "
30235 +#define GR_UNISIGLOG_MSG "signal %d sent to "
30236 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
30237 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
30238 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
30239 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
30240 +#define GR_TIME_MSG "time set by "
30241 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
30242 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
30243 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
30244 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
30245 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
30246 +#define GR_BIND_MSG "denied bind() by "
30247 +#define GR_CONNECT_MSG "denied connect() by "
30248 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
30249 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
30250 +#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"
30251 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
30252 +#define GR_CAP_ACL_MSG "use of %s denied for "
30253 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
30254 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
30255 +#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
30256 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
30257 +#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
30258 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
30259 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
30260 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
30261 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
30262 +#define GR_SEM_AUDIT_MSG "semaphore created by "
30263 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
30264 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
30265 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
30266 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
30267 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
30268 diff -urNp linux-2.6.29/include/linux/grsecurity.h linux-2.6.29/include/linux/grsecurity.h
30269 --- linux-2.6.29/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
30270 +++ linux-2.6.29/include/linux/grsecurity.h 2009-03-28 15:16:43.000000000 -0400
30272 +#ifndef GR_SECURITY_H
30273 +#define GR_SECURITY_H
30274 +#include <linux/fs.h>
30275 +#include <linux/binfmts.h>
30276 +#include <linux/gracl.h>
30278 +/* notify of brain-dead configs */
30279 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
30280 +#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
30282 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
30283 +#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
30285 +#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
30286 +#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
30288 +#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
30289 +#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
30291 +#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
30292 +#error "CONFIG_PAX enabled, but no PaX options are enabled."
30295 +void gr_handle_brute_attach(struct task_struct *p);
30296 +void gr_handle_brute_check(void);
30298 +char gr_roletype_to_char(void);
30300 +int gr_check_user_change(int real, int effective, int fs);
30301 +int gr_check_group_change(int real, int effective, int fs);
30303 +void gr_del_task_from_ip_table(struct task_struct *p);
30305 +int gr_pid_is_chrooted(struct task_struct *p);
30306 +int gr_handle_chroot_nice(void);
30307 +int gr_handle_chroot_sysctl(const int op);
30308 +int gr_handle_chroot_setpriority(struct task_struct *p,
30309 + const int niceval);
30310 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
30311 +int gr_handle_chroot_chroot(const struct dentry *dentry,
30312 + const struct vfsmount *mnt);
30313 +int gr_handle_chroot_caps(struct path *path);
30314 +void gr_handle_chroot_chdir(struct path *path);
30315 +int gr_handle_chroot_chmod(const struct dentry *dentry,
30316 + const struct vfsmount *mnt, const int mode);
30317 +int gr_handle_chroot_mknod(const struct dentry *dentry,
30318 + const struct vfsmount *mnt, const int mode);
30319 +int gr_handle_chroot_mount(const struct dentry *dentry,
30320 + const struct vfsmount *mnt,
30321 + const char *dev_name);
30322 +int gr_handle_chroot_pivot(void);
30323 +int gr_handle_chroot_unix(const pid_t pid);
30325 +int gr_handle_rawio(const struct inode *inode);
30326 +int gr_handle_nproc(void);
30328 +void gr_handle_ioperm(void);
30329 +void gr_handle_iopl(void);
30331 +int gr_tpe_allow(const struct file *file);
30333 +int gr_random_pid(void);
30335 +void gr_log_forkfail(const int retval);
30336 +void gr_log_timechange(void);
30337 +void gr_log_signal(const int sig, const struct task_struct *t);
30338 +void gr_log_chdir(const struct dentry *dentry,
30339 + const struct vfsmount *mnt);
30340 +void gr_log_chroot_exec(const struct dentry *dentry,
30341 + const struct vfsmount *mnt);
30342 +void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
30343 +void gr_log_remount(const char *devname, const int retval);
30344 +void gr_log_unmount(const char *devname, const int retval);
30345 +void gr_log_mount(const char *from, const char *to, const int retval);
30346 +void gr_log_msgget(const int ret, const int msgflg);
30347 +void gr_log_msgrm(const uid_t uid, const uid_t cuid);
30348 +void gr_log_semget(const int err, const int semflg);
30349 +void gr_log_semrm(const uid_t uid, const uid_t cuid);
30350 +void gr_log_shmget(const int err, const int shmflg, const size_t size);
30351 +void gr_log_shmrm(const uid_t uid, const uid_t cuid);
30352 +void gr_log_textrel(struct vm_area_struct *vma);
30354 +int gr_handle_follow_link(const struct inode *parent,
30355 + const struct inode *inode,
30356 + const struct dentry *dentry,
30357 + const struct vfsmount *mnt);
30358 +int gr_handle_fifo(const struct dentry *dentry,
30359 + const struct vfsmount *mnt,
30360 + const struct dentry *dir, const int flag,
30361 + const int acc_mode);
30362 +int gr_handle_hardlink(const struct dentry *dentry,
30363 + const struct vfsmount *mnt,
30364 + struct inode *inode,
30365 + const int mode, const char *to);
30367 +int gr_is_capable(const int cap);
30368 +int gr_is_capable_nolog(const int cap);
30369 +void gr_learn_resource(const struct task_struct *task, const int limit,
30370 + const unsigned long wanted, const int gt);
30371 +void gr_copy_label(struct task_struct *tsk);
30372 +void gr_handle_crash(struct task_struct *task, const int sig);
30373 +int gr_handle_signal(const struct task_struct *p, const int sig);
30374 +int gr_check_crash_uid(const uid_t uid);
30375 +int gr_check_protected_task(const struct task_struct *task);
30376 +int gr_acl_handle_mmap(const struct file *file,
30377 + const unsigned long prot);
30378 +int gr_acl_handle_mprotect(const struct file *file,
30379 + const unsigned long prot);
30380 +int gr_check_hidden_task(const struct task_struct *tsk);
30381 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
30382 + const struct vfsmount *mnt);
30383 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
30384 + const struct vfsmount *mnt);
30385 +__u32 gr_acl_handle_access(const struct dentry *dentry,
30386 + const struct vfsmount *mnt, const int fmode);
30387 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
30388 + const struct vfsmount *mnt, mode_t mode);
30389 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
30390 + const struct vfsmount *mnt, mode_t mode);
30391 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
30392 + const struct vfsmount *mnt);
30393 +int gr_handle_ptrace(struct task_struct *task, const long request);
30394 +int gr_handle_proc_ptrace(struct task_struct *task);
30395 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
30396 + const struct vfsmount *mnt);
30397 +int gr_check_crash_exec(const struct file *filp);
30398 +int gr_acl_is_enabled(void);
30399 +void gr_set_kernel_label(struct task_struct *task);
30400 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
30401 + const gid_t gid);
30402 +int gr_set_proc_label(const struct dentry *dentry,
30403 + const struct vfsmount *mnt);
30404 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
30405 + const struct vfsmount *mnt);
30406 +__u32 gr_acl_handle_open(const struct dentry *dentry,
30407 + const struct vfsmount *mnt, const int fmode);
30408 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
30409 + const struct dentry *p_dentry,
30410 + const struct vfsmount *p_mnt, const int fmode,
30411 + const int imode);
30412 +void gr_handle_create(const struct dentry *dentry,
30413 + const struct vfsmount *mnt);
30414 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
30415 + const struct dentry *parent_dentry,
30416 + const struct vfsmount *parent_mnt,
30418 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
30419 + const struct dentry *parent_dentry,
30420 + const struct vfsmount *parent_mnt);
30421 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
30422 + const struct vfsmount *mnt);
30423 +void gr_handle_delete(const ino_t ino, const dev_t dev);
30424 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
30425 + const struct vfsmount *mnt);
30426 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
30427 + const struct dentry *parent_dentry,
30428 + const struct vfsmount *parent_mnt,
30429 + const char *from);
30430 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
30431 + const struct dentry *parent_dentry,
30432 + const struct vfsmount *parent_mnt,
30433 + const struct dentry *old_dentry,
30434 + const struct vfsmount *old_mnt, const char *to);
30435 +int gr_acl_handle_rename(struct dentry *new_dentry,
30436 + struct dentry *parent_dentry,
30437 + const struct vfsmount *parent_mnt,
30438 + struct dentry *old_dentry,
30439 + struct inode *old_parent_inode,
30440 + struct vfsmount *old_mnt, const char *newname);
30441 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
30442 + struct dentry *old_dentry,
30443 + struct dentry *new_dentry,
30444 + struct vfsmount *mnt, const __u8 replace);
30445 +__u32 gr_check_link(const struct dentry *new_dentry,
30446 + const struct dentry *parent_dentry,
30447 + const struct vfsmount *parent_mnt,
30448 + const struct dentry *old_dentry,
30449 + const struct vfsmount *old_mnt);
30450 +int gr_acl_handle_filldir(const struct file *file, const char *name,
30451 + const unsigned int namelen, const ino_t ino);
30453 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
30454 + const struct vfsmount *mnt);
30455 +void gr_acl_handle_exit(void);
30456 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
30457 +int gr_acl_handle_procpidmem(const struct task_struct *task);
30459 +#ifdef CONFIG_GRKERNSEC
30460 +void gr_handle_mem_write(void);
30461 +void gr_handle_kmem_write(void);
30462 +void gr_handle_open_port(void);
30463 +int gr_handle_mem_mmap(const unsigned long offset,
30464 + struct vm_area_struct *vma);
30466 +extern int grsec_enable_dmesg;
30467 +extern int grsec_enable_randsrc;
30468 +extern int grsec_enable_shm;
30472 diff -urNp linux-2.6.29/include/linux/highmem.h linux-2.6.29/include/linux/highmem.h
30473 --- linux-2.6.29/include/linux/highmem.h 2009-03-23 19:12:14.000000000 -0400
30474 +++ linux-2.6.29/include/linux/highmem.h 2009-03-28 14:26:20.000000000 -0400
30475 @@ -124,6 +124,18 @@ static inline void clear_highpage(struct
30476 kunmap_atomic(kaddr, KM_USER0);
30479 +static inline void sanitize_highpage(struct page *page)
30482 + unsigned long flags;
30484 + local_irq_save(flags);
30485 + kaddr = kmap_atomic(page, KM_CLEARPAGE);
30486 + clear_page(kaddr);
30487 + kunmap_atomic(kaddr, KM_CLEARPAGE);
30488 + local_irq_restore(flags);
30491 static inline void zero_user_segments(struct page *page,
30492 unsigned start1, unsigned end1,
30493 unsigned start2, unsigned end2)
30494 diff -urNp linux-2.6.29/include/linux/jbd2.h linux-2.6.29/include/linux/jbd2.h
30495 --- linux-2.6.29/include/linux/jbd2.h 2009-03-23 19:12:14.000000000 -0400
30496 +++ linux-2.6.29/include/linux/jbd2.h 2009-03-28 14:26:20.000000000 -0400
30497 @@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
30501 -#define jbd_debug(f, a...) /**/
30502 +#define jbd_debug(f, a...) do {} while (0)
30505 static inline void *jbd2_alloc(size_t size, gfp_t flags)
30506 diff -urNp linux-2.6.29/include/linux/jbd.h linux-2.6.29/include/linux/jbd.h
30507 --- linux-2.6.29/include/linux/jbd.h 2009-03-23 19:12:14.000000000 -0400
30508 +++ linux-2.6.29/include/linux/jbd.h 2009-03-28 14:26:20.000000000 -0400
30509 @@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
30513 -#define jbd_debug(f, a...) /**/
30514 +#define jbd_debug(f, a...) do {} while (0)
30517 static inline void *jbd_alloc(size_t size, gfp_t flags)
30518 diff -urNp linux-2.6.29/include/linux/kvm_host.h linux-2.6.29/include/linux/kvm_host.h
30519 --- linux-2.6.29/include/linux/kvm_host.h 2009-03-23 19:12:14.000000000 -0400
30520 +++ linux-2.6.29/include/linux/kvm_host.h 2009-03-28 14:26:20.000000000 -0400
30521 @@ -151,7 +151,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vc
30522 void vcpu_load(struct kvm_vcpu *vcpu);
30523 void vcpu_put(struct kvm_vcpu *vcpu);
30525 -int kvm_init(void *opaque, unsigned int vcpu_size,
30526 +int kvm_init(const void *opaque, unsigned int vcpu_size,
30527 struct module *module);
30528 void kvm_exit(void);
30530 @@ -259,7 +259,7 @@ int kvm_arch_vcpu_ioctl_debug_guest(stru
30531 struct kvm_debug_guest *dbg);
30532 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
30534 -int kvm_arch_init(void *opaque);
30535 +int kvm_arch_init(const void *opaque);
30536 void kvm_arch_exit(void);
30538 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu);
30539 diff -urNp linux-2.6.29/include/linux/libata.h linux-2.6.29/include/linux/libata.h
30540 --- linux-2.6.29/include/linux/libata.h 2009-03-23 19:12:14.000000000 -0400
30541 +++ linux-2.6.29/include/linux/libata.h 2009-03-28 14:26:20.000000000 -0400
30542 @@ -64,11 +64,11 @@
30543 #ifdef ATA_VERBOSE_DEBUG
30544 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30546 -#define VPRINTK(fmt, args...)
30547 +#define VPRINTK(fmt, args...) do {} while (0)
30548 #endif /* ATA_VERBOSE_DEBUG */
30550 -#define DPRINTK(fmt, args...)
30551 -#define VPRINTK(fmt, args...)
30552 +#define DPRINTK(fmt, args...) do {} while (0)
30553 +#define VPRINTK(fmt, args...) do {} while (0)
30554 #endif /* ATA_DEBUG */
30556 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30557 diff -urNp linux-2.6.29/include/linux/mm.h linux-2.6.29/include/linux/mm.h
30558 --- linux-2.6.29/include/linux/mm.h 2009-03-23 19:12:14.000000000 -0400
30559 +++ linux-2.6.29/include/linux/mm.h 2009-03-28 14:26:20.000000000 -0400
30560 @@ -39,6 +39,7 @@ extern unsigned long mmap_min_addr;
30561 #include <asm/page.h>
30562 #include <asm/pgtable.h>
30563 #include <asm/processor.h>
30564 +#include <asm/mman.h>
30566 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
30568 @@ -105,6 +106,10 @@ extern unsigned int kobjsize(const void
30569 #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
30570 #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
30572 +#ifdef CONFIG_PAX_PAGEEXEC
30573 +#define VM_PAGEEXEC 0x40000000 /* vma->vm_page_prot needs special handling */
30576 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
30577 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
30579 @@ -887,6 +892,8 @@ struct shrinker {
30580 extern void register_shrinker(struct shrinker *);
30581 extern void unregister_shrinker(struct shrinker *);
30583 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
30585 int vma_wants_writenotify(struct vm_area_struct *vma);
30587 extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
30588 @@ -1158,6 +1165,7 @@ out:
30591 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
30592 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
30594 extern unsigned long do_brk(unsigned long, unsigned long);
30596 @@ -1211,6 +1219,10 @@ extern struct vm_area_struct * find_vma(
30597 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
30598 struct vm_area_struct **pprev);
30600 +extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
30601 +extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
30602 +extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
30604 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
30605 NULL if none. Assume start_addr < end_addr. */
30606 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
30607 @@ -1227,7 +1239,6 @@ static inline unsigned long vma_pages(st
30608 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
30611 -pgprot_t vm_get_page_prot(unsigned long vm_flags);
30612 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
30613 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
30614 unsigned long pfn, unsigned long size, pgprot_t);
30615 @@ -1319,5 +1330,12 @@ void vmemmap_populate_print_last(void);
30616 extern void *alloc_locked_buffer(size_t size);
30617 extern void free_locked_buffer(void *buffer, size_t size);
30618 extern void release_locked_buffer(void *buffer, size_t size);
30620 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
30621 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
30623 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
30626 #endif /* __KERNEL__ */
30627 #endif /* _LINUX_MM_H */
30628 diff -urNp linux-2.6.29/include/linux/mm_types.h linux-2.6.29/include/linux/mm_types.h
30629 --- linux-2.6.29/include/linux/mm_types.h 2009-03-23 19:12:14.000000000 -0400
30630 +++ linux-2.6.29/include/linux/mm_types.h 2009-03-28 14:26:20.000000000 -0400
30631 @@ -174,6 +174,8 @@ struct vm_area_struct {
30633 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
30636 + struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
30639 struct core_thread {
30640 @@ -274,6 +276,24 @@ struct mm_struct {
30641 #ifdef CONFIG_MMU_NOTIFIER
30642 struct mmu_notifier_mm *mmu_notifier_mm;
30645 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30646 + unsigned long pax_flags;
30649 +#ifdef CONFIG_PAX_DLRESOLVE
30650 + unsigned long call_dl_resolve;
30653 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
30654 + unsigned long call_syscall;
30657 +#ifdef CONFIG_PAX_ASLR
30658 + unsigned long delta_mmap; /* randomized offset */
30659 + unsigned long delta_stack; /* randomized offset */
30664 /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */
30665 diff -urNp linux-2.6.29/include/linux/module.h linux-2.6.29/include/linux/module.h
30666 --- linux-2.6.29/include/linux/module.h 2009-03-23 19:12:14.000000000 -0400
30667 +++ linux-2.6.29/include/linux/module.h 2009-03-28 14:26:20.000000000 -0400
30668 @@ -278,16 +278,16 @@ struct module
30671 /* If this is non-NULL, vfree after init() returns */
30672 - void *module_init;
30673 + void *module_init_rx, *module_init_rw;
30675 /* Here is the actual code + data, vfree'd on unload. */
30676 - void *module_core;
30677 + void *module_core_rx, *module_core_rw;
30679 /* Here are the sizes of the init and core sections */
30680 - unsigned int init_size, core_size;
30681 + unsigned int init_size_rw, core_size_rw;
30683 /* The size of the executable code in each section. */
30684 - unsigned int init_text_size, core_text_size;
30685 + unsigned int init_size_rx, core_size_rx;
30687 /* Arch-specific module values */
30688 struct mod_arch_specific arch;
30689 @@ -363,16 +363,46 @@ struct module *module_text_address(unsig
30690 struct module *__module_text_address(unsigned long addr);
30691 int is_module_address(unsigned long addr);
30693 +static inline int within_module_range(unsigned long addr, void *start, unsigned long size)
30696 +#ifdef CONFIG_PAX_KERNEXEC
30697 + if (ktla_ktva(addr) >= (unsigned long)start &&
30698 + ktla_ktva(addr) < (unsigned long)start + size)
30702 + return ((void *)addr >= start && (void *)addr < start + size);
30705 +static inline int within_module_core_rx(unsigned long addr, struct module *mod)
30707 + return within_module_range(addr, mod->module_core_rx, mod->core_size_rx);
30710 +static inline int within_module_core_rw(unsigned long addr, struct module *mod)
30712 + return within_module_range(addr, mod->module_core_rw, mod->core_size_rw);
30715 +static inline int within_module_init_rx(unsigned long addr, struct module *mod)
30717 + return within_module_range(addr, mod->module_init_rx, mod->init_size_rx);
30720 +static inline int within_module_init_rw(unsigned long addr, struct module *mod)
30722 + return within_module_range(addr, mod->module_init_rw, mod->init_size_rw);
30725 static inline int within_module_core(unsigned long addr, struct module *mod)
30727 - return (unsigned long)mod->module_core <= addr &&
30728 - addr < (unsigned long)mod->module_core + mod->core_size;
30729 + return within_module_core_rx(addr, mod) || within_module_core_rw(addr, mod);
30732 static inline int within_module_init(unsigned long addr, struct module *mod)
30734 - return (unsigned long)mod->module_init <= addr &&
30735 - addr < (unsigned long)mod->module_init + mod->init_size;
30736 + return within_module_init_rx(addr, mod) || within_module_init_rw(addr, mod);
30739 /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
30740 @@ -396,7 +426,11 @@ void symbol_put_addr(void *addr);
30741 static inline local_t *__module_ref_addr(struct module *mod, int cpu)
30744 +#ifdef CONFIG_X86_32
30745 + return (local_t *) (mod->refptr + __per_cpu_offset[cpu]);
30747 return (local_t *) (mod->refptr + per_cpu_offset(cpu));
30752 diff -urNp linux-2.6.29/include/linux/moduleloader.h linux-2.6.29/include/linux/moduleloader.h
30753 --- linux-2.6.29/include/linux/moduleloader.h 2009-03-23 19:12:14.000000000 -0400
30754 +++ linux-2.6.29/include/linux/moduleloader.h 2009-03-28 14:26:20.000000000 -0400
30755 @@ -20,9 +20,21 @@ unsigned int arch_mod_section_prepend(st
30756 sections. Returns NULL on failure. */
30757 void *module_alloc(unsigned long size);
30759 +#ifdef CONFIG_PAX_KERNEXEC
30760 +void *module_alloc_exec(unsigned long size);
30762 +#define module_alloc_exec(x) module_alloc(x)
30765 /* Free memory returned from module_alloc. */
30766 void module_free(struct module *mod, void *module_region);
30768 +#ifdef CONFIG_PAX_KERNEXEC
30769 +void module_free_exec(struct module *mod, void *module_region);
30771 +#define module_free_exec(x, y) module_free(x, y)
30774 /* Apply the given relocation to the (simplified) ELF. Return -error
30776 int apply_relocate(Elf_Shdr *sechdrs,
30777 diff -urNp linux-2.6.29/include/linux/namei.h linux-2.6.29/include/linux/namei.h
30778 --- linux-2.6.29/include/linux/namei.h 2009-03-23 19:12:14.000000000 -0400
30779 +++ linux-2.6.29/include/linux/namei.h 2009-03-28 14:26:20.000000000 -0400
30780 @@ -21,7 +21,7 @@ struct nameidata {
30781 unsigned int flags;
30784 - char *saved_names[MAX_NESTED_LINKS + 1];
30785 + const char *saved_names[MAX_NESTED_LINKS + 1];
30789 @@ -84,12 +84,12 @@ extern int follow_up(struct vfsmount **,
30790 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
30791 extern void unlock_rename(struct dentry *, struct dentry *);
30793 -static inline void nd_set_link(struct nameidata *nd, char *path)
30794 +static inline void nd_set_link(struct nameidata *nd, const char *path)
30796 nd->saved_names[nd->depth] = path;
30799 -static inline char *nd_get_link(struct nameidata *nd)
30800 +static inline const char *nd_get_link(struct nameidata *nd)
30802 return nd->saved_names[nd->depth];
30804 diff -urNp linux-2.6.29/include/linux/nodemask.h linux-2.6.29/include/linux/nodemask.h
30805 --- linux-2.6.29/include/linux/nodemask.h 2009-03-23 19:12:14.000000000 -0400
30806 +++ linux-2.6.29/include/linux/nodemask.h 2009-03-28 14:26:20.000000000 -0400
30807 @@ -442,11 +442,11 @@ static inline int num_node_state(enum no
30809 #define any_online_node(mask) \
30812 - for_each_node_mask(node, (mask)) \
30813 - if (node_online(node)) \
30815 + for_each_node_mask(__node, (mask)) \
30816 + if (node_online(__node)) \
30822 #define num_online_nodes() num_node_state(N_ONLINE)
30823 diff -urNp linux-2.6.29/include/linux/percpu.h linux-2.6.29/include/linux/percpu.h
30824 --- linux-2.6.29/include/linux/percpu.h 2009-03-23 19:12:14.000000000 -0400
30825 +++ linux-2.6.29/include/linux/percpu.h 2009-03-28 14:26:20.000000000 -0400
30829 #define PERCPU_ENOUGH_ROOM \
30830 - (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
30831 + ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
30832 #endif /* PERCPU_ENOUGH_ROOM */
30835 diff -urNp linux-2.6.29/include/linux/poison.h linux-2.6.29/include/linux/poison.h
30836 --- linux-2.6.29/include/linux/poison.h 2009-03-23 19:12:14.000000000 -0400
30837 +++ linux-2.6.29/include/linux/poison.h 2009-03-28 14:26:20.000000000 -0400
30839 * under normal circumstances, used to verify that nobody uses
30840 * non-initialized list entries.
30842 -#define LIST_POISON1 ((void *) 0x00100100)
30843 -#define LIST_POISON2 ((void *) 0x00200200)
30844 +#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
30845 +#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
30847 /********** include/linux/timer.h **********/
30849 diff -urNp linux-2.6.29/include/linux/proc_fs.h linux-2.6.29/include/linux/proc_fs.h
30850 --- linux-2.6.29/include/linux/proc_fs.h 2009-03-23 19:12:14.000000000 -0400
30851 +++ linux-2.6.29/include/linux/proc_fs.h 2009-03-28 14:26:20.000000000 -0400
30852 @@ -174,6 +174,19 @@ static inline struct proc_dir_entry *pro
30853 return proc_create_data(name, mode, parent, proc_fops, NULL);
30856 +static inline struct proc_dir_entry *proc_create_grsec(const char *name, mode_t mode,
30857 + struct proc_dir_entry *parent, const struct file_operations *proc_fops)
30859 +#ifdef CONFIG_GRKERNSEC_PROC_USER
30860 + return proc_create_data(name, S_IRUSR, parent, proc_fops, NULL);
30861 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
30862 + return proc_create_data(name, S_IRUSR | S_IRGRP, parent, proc_fops, NULL);
30864 + return proc_create_data(name, mode, parent, proc_fops, NULL);
30869 static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
30870 mode_t mode, struct proc_dir_entry *base,
30871 read_proc_t *read_proc, void * data)
30872 diff -urNp linux-2.6.29/include/linux/raid/md_k.h linux-2.6.29/include/linux/raid/md_k.h
30873 --- linux-2.6.29/include/linux/raid/md_k.h 2009-03-23 19:12:14.000000000 -0400
30874 +++ linux-2.6.29/include/linux/raid/md_k.h 2009-03-28 14:26:20.000000000 -0400
30875 @@ -293,7 +293,13 @@ static inline void rdev_dec_pending(mdk_
30877 static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors)
30880 +#ifdef CONFIG_PAX_REFCOUNT
30881 + atomic_add_unchecked(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
30883 atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
30888 struct mdk_personality
30889 diff -urNp linux-2.6.29/include/linux/random.h linux-2.6.29/include/linux/random.h
30890 --- linux-2.6.29/include/linux/random.h 2009-03-23 19:12:14.000000000 -0400
30891 +++ linux-2.6.29/include/linux/random.h 2009-03-28 14:26:20.000000000 -0400
30892 @@ -74,6 +74,11 @@ unsigned long randomize_range(unsigned l
30893 u32 random32(void);
30894 void srandom32(u32 seed);
30896 +static inline unsigned long pax_get_random_long(void)
30898 + return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
30901 #endif /* __KERNEL___ */
30903 #endif /* _LINUX_RANDOM_H */
30904 diff -urNp linux-2.6.29/include/linux/sched.h linux-2.6.29/include/linux/sched.h
30905 --- linux-2.6.29/include/linux/sched.h 2009-03-23 19:12:14.000000000 -0400
30906 +++ linux-2.6.29/include/linux/sched.h 2009-03-28 14:26:20.000000000 -0400
30907 @@ -97,6 +97,7 @@ struct futex_pi_state;
30908 struct robust_list_head;
30911 +struct linux_binprm;
30914 * List of flags we want to share for kernel threads,
30915 @@ -605,6 +606,15 @@ struct signal_struct {
30916 unsigned audit_tty;
30917 struct tty_audit_buf *tty_audit_buf;
30920 +#ifdef CONFIG_GRKERNSEC
30926 + u8 used_accept:1;
30930 /* Context switch must be unlocked if interrupts are to be enabled */
30931 @@ -1113,7 +1123,7 @@ struct sched_rt_entity {
30933 struct task_struct {
30934 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
30936 + struct thread_info *stack;
30938 unsigned int flags; /* per process flags, defined below */
30939 unsigned int ptrace;
30940 @@ -1178,10 +1188,9 @@ struct task_struct {
30944 -#ifdef CONFIG_CC_STACKPROTECTOR
30945 /* Canary value for the -fstack-protector gcc feature */
30946 unsigned long stack_canary;
30950 * pointers to (original) parent process, youngest child, younger sibling,
30951 * older sibling, respectively. (p->father can be replaced with
30952 @@ -1222,8 +1231,8 @@ struct task_struct {
30953 struct list_head thread_group;
30955 struct completion *vfork_done; /* for vfork() */
30956 - int __user *set_child_tid; /* CLONE_CHILD_SETTID */
30957 - int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30958 + pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
30959 + pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30961 cputime_t utime, stime, utimescaled, stimescaled;
30963 @@ -1417,8 +1426,64 @@ struct task_struct {
30964 /* state flags for use by tracers */
30965 unsigned long trace;
30968 +#ifdef CONFIG_GRKERNSEC
30970 + struct acl_subject_label *acl;
30971 + struct acl_role_label *role;
30972 + struct file *exec_file;
30981 +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
30982 +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
30983 +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
30984 +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
30985 +/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
30986 +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
30988 +#ifdef CONFIG_PAX_SOFTMODE
30989 +extern unsigned int pax_softmode;
30992 +extern int pax_check_flags(unsigned long *);
30994 +/* if tsk != current then task_lock must be held on it */
30995 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30996 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
30998 + if (likely(tsk->mm))
30999 + return tsk->mm->pax_flags;
31004 +/* if tsk != current then task_lock must be held on it */
31005 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
31007 + if (likely(tsk->mm)) {
31008 + tsk->mm->pax_flags = flags;
31015 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
31016 +extern void pax_set_initial_flags(struct linux_binprm *bprm);
31017 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
31018 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
31021 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
31022 +void pax_report_insns(void *pc, void *sp);
31023 +void pax_report_refcount_overflow(struct pt_regs *regs);
31025 /* Future-safe accessor for struct task_struct's cpus_allowed. */
31026 #define tsk_cpumask(tsk) (&(tsk)->cpus_allowed)
31028 @@ -1960,7 +2025,7 @@ extern void __cleanup_sighand(struct sig
31029 extern void exit_itimers(struct signal_struct *);
31030 extern void flush_itimer_signals(void);
31032 -extern NORET_TYPE void do_group_exit(int);
31033 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
31035 extern void daemonize(const char *, ...);
31036 extern int allow_signal(int);
31037 @@ -2065,8 +2130,8 @@ static inline void unlock_task_sighand(s
31039 #ifndef __HAVE_THREAD_FUNCTIONS
31041 -#define task_thread_info(task) ((struct thread_info *)(task)->stack)
31042 -#define task_stack_page(task) ((task)->stack)
31043 +#define task_thread_info(task) ((task)->stack)
31044 +#define task_stack_page(task) ((void *)(task)->stack)
31046 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
31048 diff -urNp linux-2.6.29/include/linux/screen_info.h linux-2.6.29/include/linux/screen_info.h
31049 --- linux-2.6.29/include/linux/screen_info.h 2009-03-23 19:12:14.000000000 -0400
31050 +++ linux-2.6.29/include/linux/screen_info.h 2009-03-28 14:26:20.000000000 -0400
31051 @@ -42,7 +42,8 @@ struct screen_info {
31052 __u16 pages; /* 0x32 */
31053 __u16 vesa_attributes; /* 0x34 */
31054 __u32 capabilities; /* 0x36 */
31055 - __u8 _reserved[6]; /* 0x3a */
31056 + __u16 vesapm_size; /* 0x3a */
31057 + __u8 _reserved[4]; /* 0x3c */
31058 } __attribute__((packed));
31060 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
31061 diff -urNp linux-2.6.29/include/linux/security.h linux-2.6.29/include/linux/security.h
31062 --- linux-2.6.29/include/linux/security.h 2009-03-23 19:12:14.000000000 -0400
31063 +++ linux-2.6.29/include/linux/security.h 2009-03-28 14:26:20.000000000 -0400
31065 #include <linux/sched.h>
31066 #include <linux/key.h>
31067 #include <linux/xfrm.h>
31068 +#include <linux/grsecurity.h>
31069 #include <net/flow.h>
31071 /* Maximum number of letters for an LSM name string */
31072 diff -urNp linux-2.6.29/include/linux/shm.h linux-2.6.29/include/linux/shm.h
31073 --- linux-2.6.29/include/linux/shm.h 2009-03-23 19:12:14.000000000 -0400
31074 +++ linux-2.6.29/include/linux/shm.h 2009-03-28 14:26:20.000000000 -0400
31075 @@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
31078 struct user_struct *mlock_user;
31079 +#ifdef CONFIG_GRKERNSEC
31080 + time_t shm_createtime;
31085 /* shm_mode upper byte flags */
31086 diff -urNp linux-2.6.29/include/linux/slab.h linux-2.6.29/include/linux/slab.h
31087 --- linux-2.6.29/include/linux/slab.h 2009-03-23 19:12:14.000000000 -0400
31088 +++ linux-2.6.29/include/linux/slab.h 2009-03-28 14:26:20.000000000 -0400
31090 * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
31091 * Both make kfree a no-op.
31093 -#define ZERO_SIZE_PTR ((void *)16)
31094 +#define ZERO_SIZE_PTR ((void *)-1024L)
31096 -#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
31097 - (unsigned long)ZERO_SIZE_PTR)
31098 +#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
31101 * struct kmem_cache related prototypes
31102 diff -urNp linux-2.6.29/include/linux/slub_def.h linux-2.6.29/include/linux/slub_def.h
31103 --- linux-2.6.29/include/linux/slub_def.h 2009-03-23 19:12:14.000000000 -0400
31104 +++ linux-2.6.29/include/linux/slub_def.h 2009-03-28 14:26:20.000000000 -0400
31105 @@ -85,7 +85,7 @@ struct kmem_cache {
31106 struct kmem_cache_order_objects max;
31107 struct kmem_cache_order_objects min;
31108 gfp_t allocflags; /* gfp flags to use on each alloc */
31109 - int refcount; /* Refcount for slab cache destroy */
31110 + atomic_t refcount; /* Refcount for slab cache destroy */
31111 void (*ctor)(void *);
31112 int inuse; /* Offset to metadata */
31113 int align; /* Alignment */
31114 diff -urNp linux-2.6.29/include/linux/sysctl.h linux-2.6.29/include/linux/sysctl.h
31115 --- linux-2.6.29/include/linux/sysctl.h 2009-03-23 19:12:14.000000000 -0400
31116 +++ linux-2.6.29/include/linux/sysctl.h 2009-03-28 14:26:20.000000000 -0400
31117 @@ -165,7 +165,11 @@ enum
31118 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
31122 +#ifdef CONFIG_PAX_SOFTMODE
31124 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
31128 /* CTL_VM names: */
31130 diff -urNp linux-2.6.29/include/linux/thread_info.h linux-2.6.29/include/linux/thread_info.h
31131 --- linux-2.6.29/include/linux/thread_info.h 2009-03-23 19:12:14.000000000 -0400
31132 +++ linux-2.6.29/include/linux/thread_info.h 2009-03-28 14:26:20.000000000 -0400
31133 @@ -23,7 +23,7 @@ struct restart_block {
31135 /* For futex_wait */
31138 + u32 __user *uaddr;
31142 diff -urNp linux-2.6.29/include/linux/tty_ldisc.h linux-2.6.29/include/linux/tty_ldisc.h
31143 --- linux-2.6.29/include/linux/tty_ldisc.h 2009-03-23 19:12:14.000000000 -0400
31144 +++ linux-2.6.29/include/linux/tty_ldisc.h 2009-03-28 14:26:20.000000000 -0400
31145 @@ -139,12 +139,12 @@ struct tty_ldisc_ops {
31147 struct module *owner;
31150 + atomic_t refcount;
31154 struct tty_ldisc_ops *ops;
31156 + atomic_t refcount;
31159 #define TTY_LDISC_MAGIC 0x5403
31160 diff -urNp linux-2.6.29/include/linux/uaccess.h linux-2.6.29/include/linux/uaccess.h
31161 --- linux-2.6.29/include/linux/uaccess.h 2009-03-23 19:12:14.000000000 -0400
31162 +++ linux-2.6.29/include/linux/uaccess.h 2009-03-28 14:26:20.000000000 -0400
31163 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
31165 mm_segment_t old_fs = get_fs(); \
31167 - set_fs(KERNEL_DS); \
31168 pagefault_disable(); \
31169 + set_fs(KERNEL_DS); \
31170 ret = __copy_from_user_inatomic(&(retval), (__force typeof(retval) __user *)(addr), sizeof(retval)); \
31171 - pagefault_enable(); \
31173 + pagefault_enable(); \
31177 diff -urNp linux-2.6.29/include/linux/vmalloc.h linux-2.6.29/include/linux/vmalloc.h
31178 --- linux-2.6.29/include/linux/vmalloc.h 2009-03-23 19:12:14.000000000 -0400
31179 +++ linux-2.6.29/include/linux/vmalloc.h 2009-03-28 14:26:20.000000000 -0400
31180 @@ -13,6 +13,11 @@ struct vm_area_struct; /* vma defining
31181 #define VM_MAP 0x00000004 /* vmap()ed pages */
31182 #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
31183 #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
31185 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
31186 +#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
31189 /* bits [20..32] reserved for arch specific ioremap internals */
31192 diff -urNp linux-2.6.29/include/net/sctp/sctp.h linux-2.6.29/include/net/sctp/sctp.h
31193 --- linux-2.6.29/include/net/sctp/sctp.h 2009-03-23 19:12:14.000000000 -0400
31194 +++ linux-2.6.29/include/net/sctp/sctp.h 2009-03-28 14:26:20.000000000 -0400
31195 @@ -310,8 +310,8 @@ extern int sctp_debug_flag;
31197 #else /* SCTP_DEBUG */
31199 -#define SCTP_DEBUG_PRINTK(whatever...)
31200 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
31201 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
31202 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
31203 #define SCTP_ENABLE_DEBUG
31204 #define SCTP_DISABLE_DEBUG
31205 #define SCTP_ASSERT(expr, str, func)
31206 diff -urNp linux-2.6.29/include/sound/core.h linux-2.6.29/include/sound/core.h
31207 --- linux-2.6.29/include/sound/core.h 2009-03-23 19:12:14.000000000 -0400
31208 +++ linux-2.6.29/include/sound/core.h 2009-03-28 14:26:20.000000000 -0400
31209 @@ -427,7 +427,7 @@ static inline int __snd_bug_on(int cond)
31211 #define snd_printdd(format, args...) snd_printk(format, ##args)
31213 -#define snd_printdd(format, args...) /* nothing */
31214 +#define snd_printdd(format, args...) do {} while (0)
31218 diff -urNp linux-2.6.29/include/video/uvesafb.h linux-2.6.29/include/video/uvesafb.h
31219 --- linux-2.6.29/include/video/uvesafb.h 2009-03-23 19:12:14.000000000 -0400
31220 +++ linux-2.6.29/include/video/uvesafb.h 2009-03-28 14:26:20.000000000 -0400
31221 @@ -177,6 +177,7 @@ struct uvesafb_par {
31222 u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
31223 u8 pmi_setpal; /* PMI for palette changes */
31224 u16 *pmi_base; /* protected mode interface location */
31225 + u8 *pmi_code; /* protected mode code location */
31228 u8 *vbe_state_orig; /*
31229 diff -urNp linux-2.6.29/init/do_mounts.c linux-2.6.29/init/do_mounts.c
31230 --- linux-2.6.29/init/do_mounts.c 2009-03-23 19:12:14.000000000 -0400
31231 +++ linux-2.6.29/init/do_mounts.c 2009-03-28 14:26:20.000000000 -0400
31232 @@ -215,11 +215,11 @@ static void __init get_fs_names(char *pa
31234 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
31236 - int err = sys_mount(name, "/root", fs, flags, data);
31237 + int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
31241 - sys_chdir("/root");
31242 + sys_chdir((char __user *)"/root");
31243 ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
31244 printk("VFS: Mounted root (%s filesystem)%s on device %u:%u.\n",
31245 current->fs->pwd.mnt->mnt_sb->s_type->name,
31246 @@ -309,18 +309,18 @@ void __init change_floppy(char *fmt, ...
31247 va_start(args, fmt);
31248 vsprintf(buf, fmt, args);
31250 - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
31251 + fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
31253 sys_ioctl(fd, FDEJECT, 0);
31256 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
31257 - fd = sys_open("/dev/console", O_RDWR, 0);
31258 + fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
31260 sys_ioctl(fd, TCGETS, (long)&termios);
31261 termios.c_lflag &= ~ICANON;
31262 sys_ioctl(fd, TCSETSF, (long)&termios);
31263 - sys_read(fd, &c, 1);
31264 + sys_read(fd, (char __user *)&c, 1);
31265 termios.c_lflag |= ICANON;
31266 sys_ioctl(fd, TCSETSF, (long)&termios);
31268 @@ -413,7 +413,7 @@ void __init prepare_namespace(void)
31272 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
31274 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
31275 + sys_chroot((char __user *)".");
31278 diff -urNp linux-2.6.29/init/do_mounts.h linux-2.6.29/init/do_mounts.h
31279 --- linux-2.6.29/init/do_mounts.h 2009-03-23 19:12:14.000000000 -0400
31280 +++ linux-2.6.29/init/do_mounts.h 2009-03-28 14:26:20.000000000 -0400
31281 @@ -14,15 +14,15 @@ extern int root_mountflags;
31283 static inline int create_dev(char *name, dev_t dev)
31285 - sys_unlink(name);
31286 - return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
31287 + sys_unlink((char __user *)name);
31288 + return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
31291 #if BITS_PER_LONG == 32
31292 static inline u32 bstat(char *name)
31294 struct stat64 stat;
31295 - if (sys_stat64(name, &stat) != 0)
31296 + if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
31298 if (!S_ISBLK(stat.st_mode))
31300 diff -urNp linux-2.6.29/init/do_mounts_initrd.c linux-2.6.29/init/do_mounts_initrd.c
31301 --- linux-2.6.29/init/do_mounts_initrd.c 2009-03-23 19:12:14.000000000 -0400
31302 +++ linux-2.6.29/init/do_mounts_initrd.c 2009-03-28 14:26:20.000000000 -0400
31303 @@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
31304 sys_close(old_fd);sys_close(root_fd);
31305 sys_close(0);sys_close(1);sys_close(2);
31307 - (void) sys_open("/dev/console",O_RDWR,0);
31308 + (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
31311 return kernel_execve(shell, argv, envp_init);
31312 @@ -47,13 +47,13 @@ static void __init handle_initrd(void)
31313 create_dev("/dev/root.old", Root_RAM0);
31314 /* mount initrd on rootfs' /root */
31315 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
31316 - sys_mkdir("/old", 0700);
31317 - root_fd = sys_open("/", 0, 0);
31318 - old_fd = sys_open("/old", 0, 0);
31319 + sys_mkdir((const char __user *)"/old", 0700);
31320 + root_fd = sys_open((const char __user *)"/", 0, 0);
31321 + old_fd = sys_open((const char __user *)"/old", 0, 0);
31322 /* move initrd over / and chdir/chroot in initrd root */
31323 - sys_chdir("/root");
31324 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
31326 + sys_chdir((const char __user *)"/root");
31327 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
31328 + sys_chroot((const char __user *)".");
31331 * In case that a resume from disk is carried out by linuxrc or one of
31332 @@ -70,15 +70,15 @@ static void __init handle_initrd(void)
31334 /* move initrd to rootfs' /old */
31335 sys_fchdir(old_fd);
31336 - sys_mount("/", ".", NULL, MS_MOVE, NULL);
31337 + sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
31338 /* switch root and cwd back to / of rootfs */
31339 sys_fchdir(root_fd);
31341 + sys_chroot((const char __user *)".");
31343 sys_close(root_fd);
31345 if (new_decode_dev(real_root_dev) == Root_RAM0) {
31346 - sys_chdir("/old");
31347 + sys_chdir((const char __user *)"/old");
31351 @@ -86,17 +86,17 @@ static void __init handle_initrd(void)
31354 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
31355 - error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
31356 + error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
31360 - int fd = sys_open("/dev/root.old", O_RDWR, 0);
31361 + int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
31362 if (error == -ENOENT)
31363 printk("/initrd does not exist. Ignored.\n");
31365 printk("failed\n");
31366 printk(KERN_NOTICE "Unmounting old root\n");
31367 - sys_umount("/old", MNT_DETACH);
31368 + sys_umount((char __user *)"/old", MNT_DETACH);
31369 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
31372 @@ -119,11 +119,11 @@ int __init initrd_load(void)
31373 * mounted in the normal path.
31375 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
31376 - sys_unlink("/initrd.image");
31377 + sys_unlink((const char __user *)"/initrd.image");
31382 - sys_unlink("/initrd.image");
31383 + sys_unlink((const char __user *)"/initrd.image");
31386 diff -urNp linux-2.6.29/init/do_mounts_md.c linux-2.6.29/init/do_mounts_md.c
31387 --- linux-2.6.29/init/do_mounts_md.c 2009-03-23 19:12:14.000000000 -0400
31388 +++ linux-2.6.29/init/do_mounts_md.c 2009-03-28 14:26:20.000000000 -0400
31389 @@ -171,7 +171,7 @@ static void __init md_setup_drive(void)
31390 partitioned ? "_d" : "", minor,
31391 md_setup_args[ent].device_names);
31393 - fd = sys_open(name, 0, 0);
31394 + fd = sys_open((char __user *)name, 0, 0);
31396 printk(KERN_ERR "md: open failed - cannot start "
31397 "array %s\n", name);
31398 @@ -234,7 +234,7 @@ static void __init md_setup_drive(void)
31402 - fd = sys_open(name, 0, 0);
31403 + fd = sys_open((char __user *)name, 0, 0);
31404 sys_ioctl(fd, BLKRRPART, 0);
31407 @@ -284,7 +284,7 @@ static void __init autodetect_raid(void)
31409 wait_for_device_probe();
31411 - fd = sys_open("/dev/md0", 0, 0);
31412 + fd = sys_open((char __user *)"/dev/md0", 0, 0);
31414 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
31416 diff -urNp linux-2.6.29/init/initramfs.c linux-2.6.29/init/initramfs.c
31417 --- linux-2.6.29/init/initramfs.c 2009-03-23 19:12:14.000000000 -0400
31418 +++ linux-2.6.29/init/initramfs.c 2009-03-28 14:26:20.000000000 -0400
31419 @@ -276,7 +276,7 @@ static int __init maybe_link(void)
31421 char *old = find_link(major, minor, ino, mode, collected);
31423 - return (sys_link(old, collected) < 0) ? -1 : 1;
31424 + return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
31428 @@ -285,11 +285,11 @@ static void __init clean_path(char *path
31432 - if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
31433 + if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
31434 if (S_ISDIR(st.st_mode))
31436 + sys_rmdir((char __user *)path);
31438 - sys_unlink(path);
31439 + sys_unlink((char __user *)path);
31443 @@ -312,7 +312,7 @@ static int __init do_name(void)
31444 int openflags = O_WRONLY|O_CREAT;
31446 openflags |= O_TRUNC;
31447 - wfd = sys_open(collected, openflags, mode);
31448 + wfd = sys_open((char __user *)collected, openflags, mode);
31451 sys_fchown(wfd, uid, gid);
31452 @@ -323,16 +323,16 @@ static int __init do_name(void)
31455 } else if (S_ISDIR(mode)) {
31456 - sys_mkdir(collected, mode);
31457 - sys_chown(collected, uid, gid);
31458 - sys_chmod(collected, mode);
31459 + sys_mkdir((char __user *)collected, mode);
31460 + sys_chown((char __user *)collected, uid, gid);
31461 + sys_chmod((char __user *)collected, mode);
31462 dir_add(collected, mtime);
31463 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
31464 S_ISFIFO(mode) || S_ISSOCK(mode)) {
31465 if (maybe_link() == 0) {
31466 - sys_mknod(collected, mode, rdev);
31467 - sys_chown(collected, uid, gid);
31468 - sys_chmod(collected, mode);
31469 + sys_mknod((char __user *)collected, mode, rdev);
31470 + sys_chown((char __user *)collected, uid, gid);
31471 + sys_chmod((char __user *)collected, mode);
31472 do_utime(collected, mtime);
31475 @@ -342,7 +342,7 @@ static int __init do_name(void)
31476 static int __init do_copy(void)
31478 if (count >= body_len) {
31479 - sys_write(wfd, victim, body_len);
31480 + sys_write(wfd, (char __user *)victim, body_len);
31482 do_utime(vcollected, mtime);
31484 @@ -350,7 +350,7 @@ static int __init do_copy(void)
31488 - sys_write(wfd, victim, count);
31489 + sys_write(wfd, (char __user *)victim, count);
31493 @@ -361,8 +361,8 @@ static int __init do_symlink(void)
31495 collected[N_ALIGN(name_len) + body_len] = '\0';
31496 clean_path(collected, 0);
31497 - sys_symlink(collected + N_ALIGN(name_len), collected);
31498 - sys_lchown(collected, uid, gid);
31499 + sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
31500 + sys_lchown((char __user *)collected, uid, gid);
31501 do_utime(collected, mtime);
31503 next_state = Reset;
31504 diff -urNp linux-2.6.29/init/Kconfig linux-2.6.29/init/Kconfig
31505 --- linux-2.6.29/init/Kconfig 2009-03-23 19:12:14.000000000 -0400
31506 +++ linux-2.6.29/init/Kconfig 2009-03-28 14:26:20.000000000 -0400
31507 @@ -712,6 +712,7 @@ config SYSCTL_SYSCALL
31509 bool "Load all symbols for debugging/ksymoops" if EMBEDDED
31511 + depends on !GRKERNSEC_HIDESYM
31513 Say Y here to let the kernel print out symbolic crash information and
31514 symbolic stack backtraces. This increases the size of the kernel
31515 @@ -960,9 +961,9 @@ config HAVE_GENERIC_DMA_COHERENT
31519 - depends on PROC_FS
31520 + depends on PROC_FS && !GRKERNSEC_PROC_ADD
31521 depends on SLAB || SLUB_DEBUG
31527 diff -urNp linux-2.6.29/init/main.c linux-2.6.29/init/main.c
31528 --- linux-2.6.29/init/main.c 2009-03-23 19:12:14.000000000 -0400
31529 +++ linux-2.6.29/init/main.c 2009-03-28 14:26:20.000000000 -0400
31530 @@ -96,6 +96,7 @@ static inline void mark_rodata_ro(void)
31532 extern void tc_init(void);
31534 +extern void grsecurity_init(void);
31536 enum system_states system_state __read_mostly;
31537 EXPORT_SYMBOL(system_state);
31538 @@ -182,6 +183,40 @@ static int __init set_reset_devices(char
31540 __setup("reset_devices", set_reset_devices);
31542 +#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
31543 +static int __init setup_pax_nouderef(char *str)
31545 + unsigned int cpu;
31547 +#ifdef CONFIG_PAX_KERNEXEC
31548 + unsigned long cr0;
31550 + pax_open_kernel(cr0);
31553 + for (cpu = 0; cpu < NR_CPUS; cpu++)
31554 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
31556 +#ifdef CONFIG_PAX_KERNEXEC
31557 + pax_close_kernel(cr0);
31562 +__setup("pax_nouderef", setup_pax_nouderef);
31565 +#ifdef CONFIG_PAX_SOFTMODE
31566 +unsigned int pax_softmode;
31568 +static int __init setup_pax_softmode(char *str)
31570 + get_option(&str, &pax_softmode);
31573 +__setup("pax_softmode=", setup_pax_softmode);
31576 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
31577 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
31578 static const char *panic_later, *panic_param;
31579 @@ -375,7 +410,7 @@ static void __init setup_nr_cpu_ids(void
31582 #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
31583 -unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
31584 +unsigned long __per_cpu_offset[NR_CPUS] __read_only;
31586 EXPORT_SYMBOL(__per_cpu_offset);
31588 @@ -694,6 +729,7 @@ int do_one_initcall(initcall_t fn)
31590 int count = preempt_count();
31591 ktime_t calltime, delta, rettime;
31592 + const char *msg1 = "", *msg2 = "";
31594 struct boot_trace_call call;
31595 struct boot_trace_ret ret;
31596 @@ -724,15 +760,15 @@ int do_one_initcall(initcall_t fn)
31597 sprintf(msgbuf, "error code %d ", ret.result);
31599 if (preempt_count() != count) {
31600 - strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
31601 + msg1 = " preemption imbalance";
31602 preempt_count() = count;
31604 if (irqs_disabled()) {
31605 - strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
31606 + msg2 = " disabled interrupts";
31607 local_irq_enable();
31610 - printk("initcall %pF returned with %s\n", fn, msgbuf);
31611 + if (msgbuf[0] || *msg1 || *msg2) {
31612 + printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
31616 @@ -873,6 +909,8 @@ static int __init kernel_init(void * unu
31617 prepare_namespace();
31620 + grsecurity_init();
31623 * Ok, we have completed the initial bootup, and
31624 * we're essentially up and running. Get rid of the
31625 diff -urNp linux-2.6.29/init/noinitramfs.c linux-2.6.29/init/noinitramfs.c
31626 --- linux-2.6.29/init/noinitramfs.c 2009-03-23 19:12:14.000000000 -0400
31627 +++ linux-2.6.29/init/noinitramfs.c 2009-03-28 14:26:20.000000000 -0400
31628 @@ -29,7 +29,7 @@ static int __init default_rootfs(void)
31632 - err = sys_mkdir("/dev", 0755);
31633 + err = sys_mkdir((const char __user *)"/dev", 0755);
31637 @@ -39,7 +39,7 @@ static int __init default_rootfs(void)
31641 - err = sys_mkdir("/root", 0700);
31642 + err = sys_mkdir((const char __user *)"/root", 0700);
31646 diff -urNp linux-2.6.29/ipc/ipc_sysctl.c linux-2.6.29/ipc/ipc_sysctl.c
31647 --- linux-2.6.29/ipc/ipc_sysctl.c 2009-03-23 19:12:14.000000000 -0400
31648 +++ linux-2.6.29/ipc/ipc_sysctl.c 2009-03-28 14:26:20.000000000 -0400
31649 @@ -267,7 +267,7 @@ static struct ctl_table ipc_kern_table[]
31654 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31657 static struct ctl_table ipc_root_table[] = {
31658 @@ -277,7 +277,7 @@ static struct ctl_table ipc_root_table[]
31660 .child = ipc_kern_table,
31663 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31666 static int __init ipc_sysctl_init(void)
31667 diff -urNp linux-2.6.29/ipc/mqueue.c linux-2.6.29/ipc/mqueue.c
31668 --- linux-2.6.29/ipc/mqueue.c 2009-03-23 19:12:14.000000000 -0400
31669 +++ linux-2.6.29/ipc/mqueue.c 2009-03-28 14:26:20.000000000 -0400
31670 @@ -151,6 +151,7 @@ static struct inode *mqueue_get_inode(st
31671 mq_bytes = (mq_msg_tblsz +
31672 (info->attr.mq_maxmsg * info->attr.mq_msgsize));
31674 + gr_learn_resource(current, RLIMIT_MSGQUEUE, u->mq_bytes + mq_bytes, 1);
31675 spin_lock(&mq_lock);
31676 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
31677 u->mq_bytes + mq_bytes >
31678 diff -urNp linux-2.6.29/ipc/msg.c linux-2.6.29/ipc/msg.c
31679 --- linux-2.6.29/ipc/msg.c 2009-03-23 19:12:14.000000000 -0400
31680 +++ linux-2.6.29/ipc/msg.c 2009-03-28 14:26:20.000000000 -0400
31681 @@ -314,6 +314,7 @@ SYSCALL_DEFINE2(msgget, key_t, key, int,
31682 struct ipc_namespace *ns;
31683 struct ipc_ops msg_ops;
31684 struct ipc_params msg_params;
31687 ns = current->nsproxy->ipc_ns;
31689 @@ -324,7 +325,11 @@ SYSCALL_DEFINE2(msgget, key_t, key, int,
31690 msg_params.key = key;
31691 msg_params.flg = msgflg;
31693 - return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31694 + err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31696 + gr_log_msgget(err, msgflg);
31701 static inline unsigned long
31702 @@ -434,6 +439,7 @@ static int msgctl_down(struct ipc_namesp
31706 + gr_log_msgrm(ipcp->uid, ipcp->cuid);
31710 diff -urNp linux-2.6.29/ipc/sem.c linux-2.6.29/ipc/sem.c
31711 --- linux-2.6.29/ipc/sem.c 2009-03-23 19:12:14.000000000 -0400
31712 +++ linux-2.6.29/ipc/sem.c 2009-03-28 14:26:20.000000000 -0400
31713 @@ -313,6 +313,7 @@ SYSCALL_DEFINE3(semget, key_t, key, int,
31714 struct ipc_namespace *ns;
31715 struct ipc_ops sem_ops;
31716 struct ipc_params sem_params;
31719 ns = current->nsproxy->ipc_ns;
31721 @@ -327,7 +328,11 @@ SYSCALL_DEFINE3(semget, key_t, key, int,
31722 sem_params.flg = semflg;
31723 sem_params.u.nsems = nsems;
31725 - return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31726 + err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31728 + gr_log_semget(err, semflg);
31734 @@ -870,6 +875,7 @@ static int semctl_down(struct ipc_namesp
31738 + gr_log_semrm(ipcp->uid, ipcp->cuid);
31742 diff -urNp linux-2.6.29/ipc/shm.c linux-2.6.29/ipc/shm.c
31743 --- linux-2.6.29/ipc/shm.c 2009-03-23 19:12:14.000000000 -0400
31744 +++ linux-2.6.29/ipc/shm.c 2009-03-28 14:26:20.000000000 -0400
31745 @@ -69,6 +69,14 @@ static void shm_destroy (struct ipc_name
31746 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
31749 +#ifdef CONFIG_GRKERNSEC
31750 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31751 + const time_t shm_createtime, const uid_t cuid,
31752 + const int shmid);
31753 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31754 + const time_t shm_createtime);
31757 void shm_init_ns(struct ipc_namespace *ns)
31759 ns->shm_ctlmax = SHMMAX;
31760 @@ -87,6 +95,8 @@ static void do_shm_rmid(struct ipc_names
31761 struct shmid_kernel *shp;
31762 shp = container_of(ipcp, struct shmid_kernel, shm_perm);
31764 + gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
31766 if (shp->shm_nattch){
31767 shp->shm_perm.mode |= SHM_DEST;
31768 /* Do not find it any more */
31769 @@ -394,6 +404,14 @@ static int newseg(struct ipc_namespace *
31770 shp->shm_lprid = 0;
31771 shp->shm_atim = shp->shm_dtim = 0;
31772 shp->shm_ctim = get_seconds();
31773 +#ifdef CONFIG_GRKERNSEC
31775 + struct timespec timeval;
31776 + do_posix_clock_monotonic_gettime(&timeval);
31778 + shp->shm_createtime = timeval.tv_sec;
31781 shp->shm_segsz = size;
31782 shp->shm_nattch = 0;
31783 shp->shm_file = file;
31784 @@ -447,6 +465,7 @@ SYSCALL_DEFINE3(shmget, key_t, key, size
31785 struct ipc_namespace *ns;
31786 struct ipc_ops shm_ops;
31787 struct ipc_params shm_params;
31790 ns = current->nsproxy->ipc_ns;
31792 @@ -458,7 +477,11 @@ SYSCALL_DEFINE3(shmget, key_t, key, size
31793 shm_params.flg = shmflg;
31794 shm_params.u.size = size;
31796 - return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31797 + err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31799 + gr_log_shmget(err, shmflg, size);
31804 static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
31805 @@ -873,9 +896,21 @@ long do_shmat(int shmid, char __user *sh
31809 +#ifdef CONFIG_GRKERNSEC
31810 + if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
31811 + shp->shm_perm.cuid, shmid) ||
31812 + !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
31818 path.dentry = dget(shp->shm_file->f_path.dentry);
31819 path.mnt = shp->shm_file->f_path.mnt;
31821 +#ifdef CONFIG_GRKERNSEC
31822 + shp->shm_lapid = current->pid;
31824 size = i_size_read(path.dentry->d_inode);
31827 diff -urNp linux-2.6.29/kernel/acct.c linux-2.6.29/kernel/acct.c
31828 --- linux-2.6.29/kernel/acct.c 2009-03-23 19:12:14.000000000 -0400
31829 +++ linux-2.6.29/kernel/acct.c 2009-03-28 14:26:20.000000000 -0400
31830 @@ -572,7 +572,7 @@ static void do_acct_process(struct bsd_a
31832 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
31833 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
31834 - file->f_op->write(file, (char *)&ac,
31835 + file->f_op->write(file, (char __user *)&ac,
31836 sizeof(acct_t), &file->f_pos);
31837 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
31839 diff -urNp linux-2.6.29/kernel/capability.c linux-2.6.29/kernel/capability.c
31840 --- linux-2.6.29/kernel/capability.c 2009-03-23 19:12:14.000000000 -0400
31841 +++ linux-2.6.29/kernel/capability.c 2009-03-28 14:26:20.000000000 -0400
31842 @@ -306,10 +306,21 @@ int capable(int cap)
31846 - if (security_capable(cap) == 0) {
31847 + if (security_capable(cap) == 0 && gr_is_capable(cap)) {
31848 current->flags |= PF_SUPERPRIV;
31854 +int capable_nolog(int cap)
31856 + if (security_capable(cap) == 0 && gr_is_capable_nolog(cap)) {
31857 + current->flags |= PF_SUPERPRIV;
31863 EXPORT_SYMBOL(capable);
31864 +EXPORT_SYMBOL(capable_nolog);
31865 diff -urNp linux-2.6.29/kernel/configs.c linux-2.6.29/kernel/configs.c
31866 --- linux-2.6.29/kernel/configs.c 2009-03-23 19:12:14.000000000 -0400
31867 +++ linux-2.6.29/kernel/configs.c 2009-03-28 14:26:20.000000000 -0400
31868 @@ -73,8 +73,19 @@ static int __init ikconfig_init(void)
31869 struct proc_dir_entry *entry;
31871 /* create the current config file */
31872 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
31873 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31874 + entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
31875 + &ikconfig_file_ops);
31876 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31877 + entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
31878 + &ikconfig_file_ops);
31881 entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
31882 &ikconfig_file_ops);
31888 diff -urNp linux-2.6.29/kernel/cpu.c linux-2.6.29/kernel/cpu.c
31889 --- linux-2.6.29/kernel/cpu.c 2009-03-23 19:12:14.000000000 -0400
31890 +++ linux-2.6.29/kernel/cpu.c 2009-03-28 14:26:20.000000000 -0400
31892 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
31893 static DEFINE_MUTEX(cpu_add_remove_lock);
31895 -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
31896 +static RAW_NOTIFIER_HEAD(cpu_chain);
31898 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
31899 * Should always be manipulated under cpu_add_remove_lock
31900 diff -urNp linux-2.6.29/kernel/cred.c linux-2.6.29/kernel/cred.c
31901 --- linux-2.6.29/kernel/cred.c 2009-03-23 19:12:14.000000000 -0400
31902 +++ linux-2.6.29/kernel/cred.c 2009-03-28 14:26:20.000000000 -0400
31903 @@ -366,6 +366,8 @@ int commit_creds(struct cred *new)
31905 get_cred(new); /* we will require a ref for the subj creds too */
31907 + gr_set_role_label(task, new->uid, new->gid);
31909 /* dumpability changes */
31910 if (old->euid != new->euid ||
31911 old->egid != new->egid ||
31912 diff -urNp linux-2.6.29/kernel/exit.c linux-2.6.29/kernel/exit.c
31913 --- linux-2.6.29/kernel/exit.c 2009-03-23 19:12:14.000000000 -0400
31914 +++ linux-2.6.29/kernel/exit.c 2009-03-28 14:26:20.000000000 -0400
31915 @@ -59,6 +59,10 @@ DEFINE_TRACE(sched_process_free);
31916 DEFINE_TRACE(sched_process_exit);
31917 DEFINE_TRACE(sched_process_wait);
31919 +#ifdef CONFIG_GRKERNSEC
31920 +extern rwlock_t grsec_exec_file_lock;
31923 static void exit_mm(struct task_struct * tsk);
31925 static inline int task_detached(struct task_struct *p)
31926 @@ -172,6 +176,8 @@ void release_task(struct task_struct * p
31927 struct task_struct *leader;
31930 + gr_del_task_from_ip_table(p);
31932 tracehook_prepare_release_task(p);
31933 /* don't need to get the RCU readlock here - the process is dead and
31934 * can't be modifying its own credentials */
31935 @@ -338,11 +344,22 @@ static void reparent_to_kthreadd(void)
31937 write_lock_irq(&tasklist_lock);
31939 +#ifdef CONFIG_GRKERNSEC
31940 + write_lock(&grsec_exec_file_lock);
31941 + if (current->exec_file) {
31942 + fput(current->exec_file);
31943 + current->exec_file = NULL;
31945 + write_unlock(&grsec_exec_file_lock);
31948 ptrace_unlink(current);
31949 /* Reparent to init */
31950 current->real_parent = current->parent = kthreadd_task;
31951 list_move_tail(¤t->sibling, ¤t->real_parent->children);
31953 + gr_set_kernel_label(current);
31955 /* Set the exit signal to SIGCHLD so we signal init on exit */
31956 current->exit_signal = SIGCHLD;
31958 @@ -436,6 +453,17 @@ void daemonize(const char *name, ...)
31959 vsnprintf(current->comm, sizeof(current->comm), name, args);
31962 +#ifdef CONFIG_GRKERNSEC
31963 + write_lock(&grsec_exec_file_lock);
31964 + if (current->exec_file) {
31965 + fput(current->exec_file);
31966 + current->exec_file = NULL;
31968 + write_unlock(&grsec_exec_file_lock);
31971 + gr_set_kernel_label(current);
31974 * If we were started as result of loading a module, close all of the
31975 * user space pages. We don't need them, and if we didn't close them
31976 @@ -1069,6 +1097,9 @@ NORET_TYPE void do_exit(long code)
31977 tsk->exit_code = code;
31978 taskstats_exit(tsk, group_dead);
31980 + gr_acl_handle_psacct(tsk, code);
31981 + gr_acl_handle_exit();
31986 @@ -1273,7 +1304,7 @@ static int wait_task_zombie(struct task_
31988 if (unlikely(options & WNOWAIT)) {
31989 int exit_code = p->exit_code;
31993 get_task_struct(p);
31994 read_unlock(&tasklist_lock);
31995 diff -urNp linux-2.6.29/kernel/fork.c linux-2.6.29/kernel/fork.c
31996 --- linux-2.6.29/kernel/fork.c 2009-03-23 19:12:14.000000000 -0400
31997 +++ linux-2.6.29/kernel/fork.c 2009-03-28 14:26:20.000000000 -0400
31998 @@ -239,7 +239,7 @@ static struct task_struct *dup_task_stru
31999 setup_thread_stack(tsk, orig);
32001 #ifdef CONFIG_CC_STACKPROTECTOR
32002 - tsk->stack_canary = get_random_int();
32003 + tsk->stack_canary = pax_get_random_long();
32006 /* One for us, one for whoever does the "release_task()" (usually parent) */
32007 @@ -276,8 +276,8 @@ static int dup_mmap(struct mm_struct *mm
32010 mm->mmap_cache = NULL;
32011 - mm->free_area_cache = oldmm->mmap_base;
32012 - mm->cached_hole_size = ~0UL;
32013 + mm->free_area_cache = oldmm->free_area_cache;
32014 + mm->cached_hole_size = oldmm->cached_hole_size;
32016 cpus_clear(mm->cpu_vm_mask);
32017 mm->mm_rb = RB_ROOT;
32018 @@ -314,6 +314,7 @@ static int dup_mmap(struct mm_struct *mm
32019 tmp->vm_flags &= ~VM_LOCKED;
32021 tmp->vm_next = NULL;
32022 + tmp->vm_mirror = NULL;
32023 anon_vma_link(tmp);
32024 file = tmp->vm_file;
32026 @@ -361,6 +362,31 @@ static int dup_mmap(struct mm_struct *mm
32031 +#ifdef CONFIG_PAX_SEGMEXEC
32032 + if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
32033 + struct vm_area_struct *mpnt_m;
32035 + for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
32036 + BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
32038 + if (!mpnt->vm_mirror)
32041 + if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
32042 + BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
32043 + mpnt->vm_mirror = mpnt_m;
32045 + BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
32046 + mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
32047 + mpnt_m->vm_mirror->vm_mirror = mpnt_m;
32048 + mpnt->vm_mirror->vm_mirror = mpnt;
32055 /* a new mm has just been created */
32056 arch_dup_mmap(oldmm, mm);
32058 @@ -541,9 +567,11 @@ void mm_release(struct task_struct *tsk,
32059 #ifdef CONFIG_FUTEX
32060 if (unlikely(tsk->robust_list))
32061 exit_robust_list(tsk);
32062 + tsk->robust_list = NULL;
32063 #ifdef CONFIG_COMPAT
32064 if (unlikely(tsk->compat_robust_list))
32065 compat_exit_robust_list(tsk);
32066 + tsk->compat_robust_list = NULL;
32070 @@ -565,7 +593,7 @@ void mm_release(struct task_struct *tsk,
32071 if (tsk->clear_child_tid
32072 && !(tsk->flags & PF_SIGNALED)
32073 && atomic_read(&mm->mm_users) > 1) {
32074 - u32 __user * tidptr = tsk->clear_child_tid;
32075 + pid_t __user * tidptr = tsk->clear_child_tid;
32076 tsk->clear_child_tid = NULL;
32079 @@ -573,7 +601,7 @@ void mm_release(struct task_struct *tsk,
32080 * not set up a proper pointer then tough luck.
32082 put_user(0, tidptr);
32083 - sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
32084 + sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
32088 @@ -1051,6 +1051,7 @@
32090 if (!vx_nproc_avail(1))
32091 goto bad_fork_cleanup_vm;
32092 + gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->real_cred->user->processes), 0);
32093 if (atomic_read(&p->real_cred->user->processes) >=
32094 p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
32095 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
32096 @@ -1150,6 +1181,8 @@ static struct task_struct *copy_process(
32097 goto bad_fork_free_graph;
32100 + gr_copy_label(p);
32102 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
32104 * Clear TID on mm_release()?
32105 @@ -1318,6 +1351,8 @@ bad_fork_cleanup_count:
32109 + gr_log_forkfail(retval);
32111 return ERR_PTR(retval);
32114 @@ -1411,6 +1446,8 @@ long do_fork(unsigned long clone_flags,
32115 if (clone_flags & CLONE_PARENT_SETTID)
32116 put_user(nr, parent_tidptr);
32118 + gr_handle_brute_check();
32120 if (clone_flags & CLONE_VFORK) {
32121 p->vfork_done = &vfork;
32122 init_completion(&vfork);
32123 diff -urNp linux-2.6.29/kernel/futex.c linux-2.6.29/kernel/futex.c
32124 --- linux-2.6.29/kernel/futex.c 2009-03-23 19:12:14.000000000 -0400
32125 +++ linux-2.6.29/kernel/futex.c 2009-03-28 14:26:20.000000000 -0400
32126 @@ -211,6 +211,11 @@ static int get_futex_key(u32 __user *uad
32130 +#ifdef CONFIG_PAX_SEGMEXEC
32131 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
32136 * The futex address must be "naturally" aligned.
32138 @@ -1304,7 +1309,7 @@ retry:
32140 restart = ¤t_thread_info()->restart_block;
32141 restart->fn = futex_wait_restart;
32142 - restart->futex.uaddr = (u32 *)uaddr;
32143 + restart->futex.uaddr = uaddr;
32144 restart->futex.val = val;
32145 restart->futex.time = abs_time->tv64;
32146 restart->futex.bitset = bitset;
32147 @@ -1846,7 +1851,7 @@ retry:
32149 static inline int fetch_robust_entry(struct robust_list __user **entry,
32150 struct robust_list __user * __user *head,
32152 + unsigned int *pi)
32154 unsigned long uentry;
32156 diff -urNp linux-2.6.29/kernel/irq/handle.c linux-2.6.29/kernel/irq/handle.c
32157 --- linux-2.6.29/kernel/irq/handle.c 2009-03-23 19:12:14.000000000 -0400
32158 +++ linux-2.6.29/kernel/irq/handle.c 2009-03-28 14:26:20.000000000 -0400
32159 @@ -222,7 +222,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
32161 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
32163 - .affinity = CPU_MASK_ALL
32164 + .affinity = CPU_MASK_ALL,
32169 diff -urNp linux-2.6.29/kernel/kallsyms.c linux-2.6.29/kernel/kallsyms.c
32170 --- linux-2.6.29/kernel/kallsyms.c 2009-03-23 19:12:14.000000000 -0400
32171 +++ linux-2.6.29/kernel/kallsyms.c 2009-03-28 14:26:20.000000000 -0400
32172 @@ -62,6 +62,18 @@ static inline int is_kernel_text(unsigne
32174 static inline int is_kernel(unsigned long addr)
32177 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
32178 + if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
32179 + ktla_ktva(addr) < (unsigned long)MODULES_END)
32183 +#ifdef CONFIG_X86_32
32184 + if (is_kernel_inittext(addr))
32188 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
32190 return in_gate_area_no_task(addr);
32191 @@ -372,7 +384,6 @@ static unsigned long get_ksymbol_core(st
32193 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
32195 - iter->name[0] = '\0';
32196 iter->nameoff = get_symbol_offset(new_pos);
32197 iter->pos = new_pos;
32199 @@ -456,7 +467,7 @@ static int kallsyms_open(struct inode *i
32200 struct kallsym_iter *iter;
32203 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
32204 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
32207 reset_iter(iter, 0);
32208 @@ -478,7 +489,15 @@ static const struct file_operations kall
32210 static int __init kallsyms_init(void)
32212 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
32213 +#ifdef CONFIG_GRKERNSEC_PROC_USER
32214 + proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
32215 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
32216 + proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
32219 proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
32223 __initcall(kallsyms_init);
32224 diff -urNp linux-2.6.29/kernel/kmod.c linux-2.6.29/kernel/kmod.c
32225 --- linux-2.6.29/kernel/kmod.c 2009-03-23 19:12:14.000000000 -0400
32226 +++ linux-2.6.29/kernel/kmod.c 2009-03-28 14:26:20.000000000 -0400
32227 @@ -108,7 +108,7 @@ int request_module(const char *fmt, ...)
32231 - ret = call_usermodehelper(modprobe_path, argv, envp, 1);
32232 + ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
32233 atomic_dec(&kmod_concurrent);
32236 diff -urNp linux-2.6.29/kernel/kprobes.c linux-2.6.29/kernel/kprobes.c
32237 --- linux-2.6.29/kernel/kprobes.c 2009-03-23 19:12:14.000000000 -0400
32238 +++ linux-2.6.29/kernel/kprobes.c 2009-03-28 14:26:20.000000000 -0400
32239 @@ -183,7 +183,7 @@ static kprobe_opcode_t __kprobes *__get_
32240 * kernel image and loaded module images reside. This is required
32241 * so x86_64 can correctly handle the %rip-relative fixups.
32243 - kip->insns = module_alloc(PAGE_SIZE);
32244 + kip->insns = module_alloc_exec(PAGE_SIZE);
32248 @@ -224,7 +224,7 @@ static int __kprobes collect_one_slot(st
32249 hlist_add_head(&kip->hlist,
32250 &kprobe_insn_pages);
32252 - module_free(NULL, kip->insns);
32253 + module_free_exec(NULL, kip->insns);
32257 diff -urNp linux-2.6.29/kernel/lockdep.c linux-2.6.29/kernel/lockdep.c
32258 --- linux-2.6.29/kernel/lockdep.c 2009-03-23 19:12:14.000000000 -0400
32259 +++ linux-2.6.29/kernel/lockdep.c 2009-03-28 14:26:20.000000000 -0400
32260 @@ -631,6 +631,10 @@ static int static_obj(void *obj)
32264 +#ifdef CONFIG_PAX_KERNEXEC
32265 + start = (unsigned long )&_data;
32271 @@ -642,9 +646,12 @@ static int static_obj(void *obj)
32274 for_each_possible_cpu(i) {
32275 +#ifdef CONFIG_X86_32
32276 + start = per_cpu_offset(i);
32278 start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
32279 - end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
32280 - + per_cpu_offset(i);
32282 + end = start + PERCPU_ENOUGH_ROOM;
32284 if ((addr >= start) && (addr < end))
32286 diff -urNp linux-2.6.29/kernel/module.c linux-2.6.29/kernel/module.c
32287 --- linux-2.6.29/kernel/module.c 2009-03-23 19:12:14.000000000 -0400
32288 +++ linux-2.6.29/kernel/module.c 2009-03-28 14:26:20.000000000 -0400
32290 #include <linux/rculist.h>
32291 #include <asm/uaccess.h>
32292 #include <asm/cacheflush.h>
32294 +#ifdef CONFIG_PAX_KERNEXEC
32295 +#include <asm/desc.h>
32298 #include <linux/license.h>
32299 #include <asm/sections.h>
32300 #include <linux/tracepoint.h>
32301 @@ -76,7 +81,10 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
32302 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
32304 /* Bounds of module allocation, for speeding __module_text_address */
32305 -static unsigned long module_addr_min = -1UL, module_addr_max = 0;
32306 +static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
32307 +static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
32309 +extern int gr_check_modstop(void);
32311 int register_module_notifier(struct notifier_block * nb)
32313 @@ -245,7 +253,7 @@ static bool each_symbol(bool (*fn)(const
32316 list_for_each_entry_rcu(mod, &modules, list) {
32317 - struct symsearch arr[] = {
32318 + struct symsearch modarr[] = {
32319 { mod->syms, mod->syms + mod->num_syms, mod->crcs,
32320 NOT_GPL_ONLY, false },
32321 { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
32322 @@ -267,7 +275,7 @@ static bool each_symbol(bool (*fn)(const
32326 - if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
32327 + if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
32331 @@ -403,6 +411,8 @@ static inline unsigned int block_size(in
32335 +EXPORT_SYMBOL(__per_cpu_start);
32337 static void *percpu_modalloc(unsigned long size, unsigned long align,
32340 @@ -410,7 +420,7 @@ static void *percpu_modalloc(unsigned lo
32344 - if (align > PAGE_SIZE) {
32345 + if (align-1 >= PAGE_SIZE) {
32346 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
32347 name, align, PAGE_SIZE);
32349 @@ -492,7 +502,11 @@ static void percpu_modcopy(void *pcpudes
32352 for_each_possible_cpu(cpu)
32353 +#ifdef CONFIG_X86_32
32354 + memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
32356 memcpy(pcpudest + per_cpu_offset(cpu), from, size);
32360 static int percpu_modinit(void)
32361 @@ -751,6 +765,9 @@ SYSCALL_DEFINE2(delete_module, const cha
32362 char name[MODULE_NAME_LEN];
32363 int ret, forced = 0;
32365 + if (gr_check_modstop())
32368 if (!capable(CAP_SYS_MODULE))
32371 @@ -1458,10 +1475,11 @@ static void free_module(struct module *m
32372 module_unload_free(mod);
32374 /* release any pointers to mcount in this module */
32375 - ftrace_release(mod->module_core, mod->core_size);
32376 + ftrace_release(mod->module_core_rx, mod->core_size_rx);
32378 /* This may be NULL, but that's OK */
32379 - module_free(mod, mod->module_init);
32380 + module_free(mod, mod->module_init_rw);
32381 + module_free_exec(mod, mod->module_init_rx);
32384 percpu_modfree(mod->percpu);
32385 @@ -1470,10 +1488,12 @@ static void free_module(struct module *m
32386 percpu_modfree(mod->refptr);
32388 /* Free lock-classes: */
32389 - lockdep_free_key_range(mod->module_core, mod->core_size);
32390 + lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
32391 + lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
32393 /* Finally, free the core (containing the module structure) */
32394 - module_free(mod, mod->module_core);
32395 + module_free_exec(mod, mod->module_core_rx);
32396 + module_free(mod, mod->module_core_rw);
32399 void *__symbol_get(const char *symbol)
32400 @@ -1539,10 +1559,14 @@ static int simplify_symbols(Elf_Shdr *se
32401 struct module *mod)
32403 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
32404 - unsigned long secbase;
32405 + unsigned long secbase, symbol;
32406 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32409 +#ifdef CONFIG_PAX_KERNEXEC
32410 + unsigned long cr0;
32413 for (i = 1; i < n; i++) {
32414 switch (sym[i].st_shndx) {
32416 @@ -1561,10 +1585,19 @@ static int simplify_symbols(Elf_Shdr *se
32421 - = resolve_symbol(sechdrs, versindex,
32422 + symbol = resolve_symbol(sechdrs, versindex,
32423 strtab + sym[i].st_name, mod);
32425 +#ifdef CONFIG_PAX_KERNEXEC
32426 + pax_open_kernel(cr0);
32429 + sym[i].st_value = symbol;
32431 +#ifdef CONFIG_PAX_KERNEXEC
32432 + pax_close_kernel(cr0);
32435 /* Ok if resolved. */
32436 if (!IS_ERR_VALUE(sym[i].st_value))
32438 @@ -1579,11 +1612,27 @@ static int simplify_symbols(Elf_Shdr *se
32441 /* Divert to percpu allocation if a percpu var. */
32442 - if (sym[i].st_shndx == pcpuindex)
32443 + if (sym[i].st_shndx == pcpuindex) {
32445 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
32446 + secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
32448 secbase = (unsigned long)mod->percpu;
32453 secbase = sechdrs[sym[i].st_shndx].sh_addr;
32455 +#ifdef CONFIG_PAX_KERNEXEC
32456 + pax_open_kernel(cr0);
32459 sym[i].st_value += secbase;
32461 +#ifdef CONFIG_PAX_KERNEXEC
32462 + pax_close_kernel(cr0);
32468 @@ -1645,11 +1694,12 @@ static void layout_sections(struct modul
32469 || strncmp(secstrings + s->sh_name,
32472 - s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
32473 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32474 + s->sh_entsize = get_offset(mod, &mod->core_size_rw, s, i);
32476 + s->sh_entsize = get_offset(mod, &mod->core_size_rx, s, i);
32477 DEBUGP("\t%s\n", secstrings + s->sh_name);
32480 - mod->core_text_size = mod->core_size;
32483 DEBUGP("Init section allocation order:\n");
32484 @@ -1663,12 +1713,13 @@ static void layout_sections(struct modul
32485 || strncmp(secstrings + s->sh_name,
32488 - s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
32489 - | INIT_OFFSET_MASK);
32490 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32491 + s->sh_entsize = get_offset(mod, &mod->init_size_rw, s, i);
32493 + s->sh_entsize = get_offset(mod, &mod->init_size_rx, s, i);
32494 + s->sh_entsize |= INIT_OFFSET_MASK;
32495 DEBUGP("\t%s\n", secstrings + s->sh_name);
32498 - mod->init_text_size = mod->init_size;
32502 @@ -1808,14 +1859,31 @@ static void add_kallsyms(struct module *
32506 +#ifdef CONFIG_PAX_KERNEXEC
32507 + unsigned long cr0;
32510 mod->symtab = (void *)sechdrs[symindex].sh_addr;
32511 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32512 mod->strtab = (void *)sechdrs[strindex].sh_addr;
32514 /* Set types up while we still have access to sections. */
32515 - for (i = 0; i < mod->num_symtab; i++)
32516 - mod->symtab[i].st_info
32517 - = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32519 + for (i = 0; i < mod->num_symtab; i++) {
32520 + char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32522 +#ifdef CONFIG_PAX_KERNEXEC
32523 + pax_open_kernel(cr0);
32526 + mod->symtab[i].st_info = type;
32528 +#ifdef CONFIG_PAX_KERNEXEC
32529 + pax_close_kernel(cr0);
32536 static inline void add_kallsyms(struct module *mod,
32537 @@ -1842,16 +1910,30 @@ static void dynamic_printk_setup(struct
32538 #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
32541 -static void *module_alloc_update_bounds(unsigned long size)
32542 +static void *module_alloc_update_bounds_rw(unsigned long size)
32544 void *ret = module_alloc(size);
32547 /* Update module bounds. */
32548 - if ((unsigned long)ret < module_addr_min)
32549 - module_addr_min = (unsigned long)ret;
32550 - if ((unsigned long)ret + size > module_addr_max)
32551 - module_addr_max = (unsigned long)ret + size;
32552 + if ((unsigned long)ret < module_addr_min_rw)
32553 + module_addr_min_rw = (unsigned long)ret;
32554 + if ((unsigned long)ret + size > module_addr_max_rw)
32555 + module_addr_max_rw = (unsigned long)ret + size;
32560 +static void *module_alloc_update_bounds_rx(unsigned long size)
32562 + void *ret = module_alloc_exec(size);
32565 + /* Update module bounds. */
32566 + if ((unsigned long)ret < module_addr_min_rx)
32567 + module_addr_min_rx = (unsigned long)ret;
32568 + if ((unsigned long)ret + size > module_addr_max_rx)
32569 + module_addr_max_rx = (unsigned long)ret + size;
32573 @@ -1878,6 +1960,10 @@ static noinline struct module *load_modu
32574 unsigned long *mseg;
32575 mm_segment_t old_fs;
32577 +#ifdef CONFIG_PAX_KERNEXEC
32578 + unsigned long cr0;
32581 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
32583 if (len < sizeof(*hdr))
32584 @@ -2034,22 +2120,57 @@ static noinline struct module *load_modu
32585 layout_sections(mod, hdr, sechdrs, secstrings);
32587 /* Do the allocs. */
32588 - ptr = module_alloc_update_bounds(mod->core_size);
32589 + ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
32594 - memset(ptr, 0, mod->core_size);
32595 - mod->module_core = ptr;
32596 + memset(ptr, 0, mod->core_size_rw);
32597 + mod->module_core_rw = ptr;
32599 + ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
32600 + if (!ptr && mod->init_size_rw) {
32602 + goto free_core_rw;
32604 + memset(ptr, 0, mod->init_size_rw);
32605 + mod->module_init_rw = ptr;
32607 + ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
32610 + goto free_init_rw;
32613 +#ifdef CONFIG_PAX_KERNEXEC
32614 + pax_open_kernel(cr0);
32617 + memset(ptr, 0, mod->core_size_rx);
32619 - ptr = module_alloc_update_bounds(mod->init_size);
32620 - if (!ptr && mod->init_size) {
32621 +#ifdef CONFIG_PAX_KERNEXEC
32622 + pax_close_kernel(cr0);
32625 + mod->module_core_rx = ptr;
32627 + ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
32628 + if (!ptr && mod->init_size_rx) {
32631 + goto free_core_rx;
32633 - memset(ptr, 0, mod->init_size);
32634 - mod->module_init = ptr;
32636 +#ifdef CONFIG_PAX_KERNEXEC
32637 + pax_open_kernel(cr0);
32640 + memset(ptr, 0, mod->init_size_rx);
32642 +#ifdef CONFIG_PAX_KERNEXEC
32643 + pax_close_kernel(cr0);
32646 + mod->module_init_rx = ptr;
32647 /* Transfer each section which specifies SHF_ALLOC */
32648 DEBUGP("final section addresses:\n");
32649 for (i = 0; i < hdr->e_shnum; i++) {
32650 @@ -2058,17 +2179,41 @@ static noinline struct module *load_modu
32651 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
32654 - if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
32655 - dest = mod->module_init
32656 - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32658 - dest = mod->module_core + sechdrs[i].sh_entsize;
32659 + if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
32660 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32661 + dest = mod->module_init_rw
32662 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32664 + dest = mod->module_init_rx
32665 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32667 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32668 + dest = mod->module_core_rw + sechdrs[i].sh_entsize;
32670 + dest = mod->module_core_rx + sechdrs[i].sh_entsize;
32673 - if (sechdrs[i].sh_type != SHT_NOBITS)
32674 - memcpy(dest, (void *)sechdrs[i].sh_addr,
32675 - sechdrs[i].sh_size);
32676 + if (sechdrs[i].sh_type != SHT_NOBITS) {
32678 +#ifdef CONFIG_PAX_KERNEXEC
32679 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
32680 + pax_open_kernel(cr0);
32681 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32682 + pax_close_kernel(cr0);
32686 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32688 /* Update sh_addr to point to copy in image. */
32689 - sechdrs[i].sh_addr = (unsigned long)dest;
32691 +#ifdef CONFIG_PAX_KERNEXEC
32692 + if (sechdrs[i].sh_flags & SHF_EXECINSTR)
32693 + sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
32697 + sechdrs[i].sh_addr = (unsigned long)dest;
32698 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
32700 /* Module has been moved. */
32701 @@ -2079,7 +2224,7 @@ static noinline struct module *load_modu
32703 if (!mod->refptr) {
32706 + goto free_init_rx;
32709 /* Now we've moved module, initialize linked lists, etc. */
32710 @@ -2176,8 +2321,8 @@ static noinline struct module *load_modu
32712 /* Now do relocations. */
32713 for (i = 1; i < hdr->e_shnum; i++) {
32714 - const char *strtab = (char *)sechdrs[strindex].sh_addr;
32715 unsigned int info = sechdrs[i].sh_info;
32716 + strtab = (char *)sechdrs[strindex].sh_addr;
32718 /* Not a valid relocation section? */
32719 if (info >= hdr->e_shnum)
32720 @@ -2239,12 +2384,12 @@ static noinline struct module *load_modu
32721 * Do it before processing of module parameters, so the module
32722 * can provide parameter accessor functions of its own.
32724 - if (mod->module_init)
32725 - flush_icache_range((unsigned long)mod->module_init,
32726 - (unsigned long)mod->module_init
32727 - + mod->init_size);
32728 - flush_icache_range((unsigned long)mod->module_core,
32729 - (unsigned long)mod->module_core + mod->core_size);
32730 + if (mod->module_init_rx)
32731 + flush_icache_range((unsigned long)mod->module_init_rx,
32732 + (unsigned long)mod->module_init_rx
32733 + + mod->init_size_rx);
32734 + flush_icache_range((unsigned long)mod->module_core_rx,
32735 + (unsigned long)mod->module_core_rx + mod->core_size_rx);
32739 @@ -2285,16 +2430,20 @@ static noinline struct module *load_modu
32741 kobject_del(&mod->mkobj.kobj);
32742 kobject_put(&mod->mkobj.kobj);
32743 - ftrace_release(mod->module_core, mod->core_size);
32744 + ftrace_release(mod->module_core_rx, mod->core_size_rx);
32746 module_unload_free(mod);
32749 #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
32750 percpu_modfree(mod->refptr);
32752 - module_free(mod, mod->module_init);
32754 - module_free(mod, mod->module_core);
32755 + module_free_exec(mod, mod->module_init_rx);
32757 + module_free_exec(mod, mod->module_core_rx);
32759 + module_free(mod, mod->module_init_rw);
32761 + module_free(mod, mod->module_core_rw);
32762 /* mod will be freed with core. Don't access it beyond this line! */
32765 @@ -2319,6 +2468,9 @@ SYSCALL_DEFINE3(init_module, void __user
32766 struct module *mod;
32769 + if (gr_check_modstop())
32772 /* Must have permission */
32773 if (!capable(CAP_SYS_MODULE))
32775 @@ -2375,20 +2527,17 @@ SYSCALL_DEFINE3(init_module, void __user
32776 mutex_lock(&module_mutex);
32777 /* Drop initial reference. */
32779 - module_free(mod, mod->module_init);
32780 - mod->module_init = NULL;
32781 - mod->init_size = 0;
32782 - mod->init_text_size = 0;
32783 + module_free(mod, mod->module_init_rw);
32784 + module_free_exec(mod, mod->module_init_rx);
32785 + mod->module_init_rw = NULL;
32786 + mod->module_init_rx = NULL;
32787 + mod->init_size_rw = 0;
32788 + mod->init_size_rx = 0;
32789 mutex_unlock(&module_mutex);
32794 -static inline int within(unsigned long addr, void *start, unsigned long size)
32796 - return ((void *)addr >= start && (void *)addr < start + size);
32799 #ifdef CONFIG_KALLSYMS
32801 * This ignores the intensely annoying "mapping symbols" found
32802 @@ -2409,10 +2558,16 @@ static const char *get_ksymbol(struct mo
32803 unsigned long nextval;
32805 /* At worse, next value is at end of module */
32806 - if (within_module_init(addr, mod))
32807 - nextval = (unsigned long)mod->module_init+mod->init_text_size;
32808 + if (within_module_init_rx(addr, mod))
32809 + nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
32810 + else if (within_module_init_rw(addr, mod))
32811 + nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
32812 + else if (within_module_core_rx(addr, mod))
32813 + nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
32814 + else if (within_module_core_rw(addr, mod))
32815 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
32817 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
32820 /* Scan for closest preceeding symbol, and next symbol. (ELF
32821 starts real symbols at 1). */
32822 @@ -2639,7 +2794,7 @@ static int m_show(struct seq_file *m, vo
32825 seq_printf(m, "%s %u",
32826 - mod->name, mod->init_size + mod->core_size);
32827 + mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
32828 print_unload_info(m, mod);
32830 /* Informative for users. */
32831 @@ -2648,7 +2803,7 @@ static int m_show(struct seq_file *m, vo
32832 mod->state == MODULE_STATE_COMING ? "Loading":
32834 /* Used by oprofile and other similar tools. */
32835 - seq_printf(m, " 0x%p", mod->module_core);
32836 + seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
32840 @@ -2741,12 +2896,15 @@ __notrace_funcgraph struct module *__mod
32842 struct module *mod;
32844 - if (addr < module_addr_min || addr > module_addr_max)
32845 +#ifdef CONFIG_X86_32
32846 + addr = ktla_ktva(addr);
32849 + if (addr < module_addr_min_rx || addr > module_addr_max_rx)
32852 list_for_each_entry_rcu(mod, &modules, list)
32853 - if (within(addr, mod->module_init, mod->init_text_size)
32854 - || within(addr, mod->module_core, mod->core_text_size))
32855 + if (within_module_init_rx(addr, mod) || within_module_core_rx(addr, mod))
32859 diff -urNp linux-2.6.29/kernel/mutex.c linux-2.6.29/kernel/mutex.c
32860 --- linux-2.6.29/kernel/mutex.c 2009-03-23 19:12:14.000000000 -0400
32861 +++ linux-2.6.29/kernel/mutex.c 2009-03-28 14:26:20.000000000 -0400
32862 @@ -83,7 +83,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
32864 * This function is similar to (but not equivalent to) down().
32866 -void inline __sched mutex_lock(struct mutex *lock)
32867 +inline void __sched mutex_lock(struct mutex *lock)
32871 diff -urNp linux-2.6.29/kernel/panic.c linux-2.6.29/kernel/panic.c
32872 --- linux-2.6.29/kernel/panic.c 2009-03-23 19:12:14.000000000 -0400
32873 +++ linux-2.6.29/kernel/panic.c 2009-03-28 14:26:20.000000000 -0400
32874 @@ -361,6 +361,8 @@ EXPORT_SYMBOL(warn_slowpath);
32876 void __stack_chk_fail(void)
32878 + print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
32880 panic("stack-protector: Kernel stack is corrupted");
32882 EXPORT_SYMBOL(__stack_chk_fail);
32883 diff -urNp linux-2.6.29/kernel/pid.c linux-2.6.29/kernel/pid.c
32884 --- linux-2.6.29/kernel/pid.c 2009-03-23 19:12:14.000000000 -0400
32885 +++ linux-2.6.29/kernel/pid.c 2009-03-28 14:26:20.000000000 -0400
32887 #include <linux/rculist.h>
32888 #include <linux/bootmem.h>
32889 #include <linux/hash.h>
32890 +#include <linux/security.h>
32891 #include <linux/pid_namespace.h>
32892 #include <linux/init_task.h>
32893 #include <linux/syscalls.h>
32894 @@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
32896 int pid_max = PID_MAX_DEFAULT;
32898 -#define RESERVED_PIDS 300
32899 +#define RESERVED_PIDS 500
32901 int pid_max_min = RESERVED_PIDS + 1;
32902 int pid_max_max = PID_MAX_LIMIT;
32903 @@ -381,7 +382,14 @@ EXPORT_SYMBOL(pid_task);
32904 struct task_struct *find_task_by_pid_type_ns(int type, int nr,
32905 struct pid_namespace *ns)
32907 - return pid_task(find_pid_ns(nr, ns), type);
32908 + struct task_struct *task;
32910 + task = pid_task(find_pid_ns(nr, ns), type);
32912 + if (gr_pid_is_chrooted(task))
32918 EXPORT_SYMBOL(find_task_by_pid_type_ns);
32919 diff -urNp linux-2.6.29/kernel/posix-cpu-timers.c linux-2.6.29/kernel/posix-cpu-timers.c
32920 --- linux-2.6.29/kernel/posix-cpu-timers.c 2009-03-23 19:12:14.000000000 -0400
32921 +++ linux-2.6.29/kernel/posix-cpu-timers.c 2009-03-28 14:26:20.000000000 -0400
32923 #include <linux/posix-timers.h>
32924 #include <linux/errno.h>
32925 #include <linux/math64.h>
32926 +#include <linux/security.h>
32927 #include <asm/uaccess.h>
32928 #include <linux/kernel_stat.h>
32930 @@ -1039,6 +1040,7 @@ static void check_thread_timers(struct t
32931 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
32934 + gr_learn_resource(tsk, RLIMIT_RTTIME, tsk->rt.timeout, 1);
32935 if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) {
32937 * At the soft limit, send a SIGXCPU every second.
32938 @@ -1194,6 +1196,7 @@ static void check_process_timers(struct
32939 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
32942 + gr_learn_resource(tsk, RLIMIT_CPU, psecs, 0);
32943 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
32945 * At the soft limit, send a SIGXCPU every second.
32946 @@ -1418,17 +1421,17 @@ void run_posix_cpu_timers(struct task_st
32947 * timer call will interfere.
32949 list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
32952 spin_lock(&timer->it_lock);
32953 list_del_init(&timer->it.cpu.entry);
32954 - firing = timer->it.cpu.firing;
32955 + __firing = timer->it.cpu.firing;
32956 timer->it.cpu.firing = 0;
32958 * The firing flag is -1 if we collided with a reset
32959 * of the timer, which already reported this
32960 * almost-firing as an overrun. So don't generate an event.
32962 - if (likely(firing >= 0)) {
32963 + if (likely(__firing >= 0)) {
32964 cpu_timer_fire(timer);
32966 spin_unlock(&timer->it_lock);
32967 diff -urNp linux-2.6.29/kernel/power/poweroff.c linux-2.6.29/kernel/power/poweroff.c
32968 --- linux-2.6.29/kernel/power/poweroff.c 2009-03-23 19:12:14.000000000 -0400
32969 +++ linux-2.6.29/kernel/power/poweroff.c 2009-03-28 14:26:20.000000000 -0400
32970 @@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
32971 .enable_mask = SYSRQ_ENABLE_BOOT,
32974 -static int pm_sysrq_init(void)
32975 +static int __init pm_sysrq_init(void)
32977 register_sysrq_key('o', &sysrq_poweroff_op);
32979 diff -urNp linux-2.6.29/kernel/printk.c linux-2.6.29/kernel/printk.c
32980 --- linux-2.6.29/kernel/printk.c 2009-03-23 19:12:14.000000000 -0400
32981 +++ linux-2.6.29/kernel/printk.c 2009-03-28 14:26:20.000000000 -0400
32982 @@ -253,6 +253,11 @@ int do_syslog(int type, char __user *buf
32986 +#ifdef CONFIG_GRKERNSEC_DMESG
32987 + if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
32991 error = security_syslog(type);
32994 diff -urNp linux-2.6.29/kernel/ptrace.c linux-2.6.29/kernel/ptrace.c
32995 --- linux-2.6.29/kernel/ptrace.c 2009-03-23 19:12:14.000000000 -0400
32996 +++ linux-2.6.29/kernel/ptrace.c 2009-03-28 14:26:20.000000000 -0400
32997 @@ -149,7 +149,7 @@ int __ptrace_may_access(struct task_stru
32998 cred->gid != tcred->egid ||
32999 cred->gid != tcred->sgid ||
33000 cred->gid != tcred->gid) &&
33001 - !capable(CAP_SYS_PTRACE)) {
33002 + !capable_nolog(CAP_SYS_PTRACE)) {
33006 @@ -157,7 +157,7 @@ int __ptrace_may_access(struct task_stru
33009 dumpable = get_dumpable(task->mm);
33010 - if (!dumpable && !capable(CAP_SYS_PTRACE))
33011 + if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
33014 return security_ptrace_may_access(task, mode);
33015 @@ -221,7 +221,7 @@ repeat:
33018 task->ptrace |= PT_PTRACED;
33019 - if (capable(CAP_SYS_PTRACE))
33020 + if (capable_nolog(CAP_SYS_PTRACE))
33021 task->ptrace |= PT_PTRACE_CAP;
33023 __ptrace_link(task, current);
33024 @@ -611,6 +611,11 @@ SYSCALL_DEFINE4(ptrace, long, request, l
33026 goto out_put_task_struct;
33028 + if (gr_handle_ptrace(child, request)) {
33030 + goto out_put_task_struct;
33033 ret = arch_ptrace(child, request, addr, data);
33035 goto out_put_task_struct;
33036 diff -urNp linux-2.6.29/kernel/relay.c linux-2.6.29/kernel/relay.c
33037 --- linux-2.6.29/kernel/relay.c 2009-03-23 19:12:14.000000000 -0400
33038 +++ linux-2.6.29/kernel/relay.c 2009-03-28 14:26:20.000000000 -0400
33039 @@ -1292,7 +1292,7 @@ static int subbuf_splice_actor(struct fi
33042 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
33043 - if (ret < 0 || ret < total_len)
33044 + if ((int)ret < 0 || ret < total_len)
33047 if (read_start + ret == nonpad_end)
33048 diff -urNp linux-2.6.29/kernel/resource.c linux-2.6.29/kernel/resource.c
33049 --- linux-2.6.29/kernel/resource.c 2009-03-23 19:12:14.000000000 -0400
33050 +++ linux-2.6.29/kernel/resource.c 2009-03-28 14:26:20.000000000 -0400
33051 @@ -132,8 +132,18 @@ static const struct file_operations proc
33053 static int __init ioresources_init(void)
33055 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
33056 +#ifdef CONFIG_GRKERNSEC_PROC_USER
33057 + proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
33058 + proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
33059 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33060 + proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
33061 + proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
33064 proc_create("ioports", 0, NULL, &proc_ioports_operations);
33065 proc_create("iomem", 0, NULL, &proc_iomem_operations);
33069 __initcall(ioresources_init);
33070 diff -urNp linux-2.6.29/kernel/sched.c linux-2.6.29/kernel/sched.c
33071 --- linux-2.6.29/kernel/sched.c 2009-03-23 19:12:14.000000000 -0400
33072 +++ linux-2.6.29/kernel/sched.c 2009-03-28 14:26:20.000000000 -0400
33073 @@ -5118,6 +5118,8 @@ int can_nice(const struct task_struct *p
33074 /* convert nice value [19,-20] to rlimit style value [1,40] */
33075 int nice_rlim = 20 - nice;
33077 + gr_learn_resource(p, RLIMIT_NICE, nice_rlim, 1);
33079 return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur ||
33080 capable(CAP_SYS_NICE));
33082 @@ -5194,7 +5194,7 @@ SYSCALL_DEFINE1(nice, int, increment)
33086 - if (increment < 0 && !can_nice(current, nice))
33087 + if (increment < 0 && (!can_nice(current, nice) || gr_handle_chroot_nice()))
33088 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
33090 retval = security_task_setnice(current, nice);
33091 @@ -5293,6 +5296,8 @@ recheck:
33092 if (rt_policy(policy)) {
33093 unsigned long rlim_rtprio;
33095 + gr_learn_resource(p, RLIMIT_RTPRIO, param->sched_priority, 1);
33097 if (!lock_task_sighand(p, &flags))
33099 rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur;
33100 @@ -6440,7 +6445,7 @@ static struct ctl_table sd_ctl_dir[] = {
33101 .procname = "sched_domain",
33105 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33108 static struct ctl_table sd_ctl_root[] = {
33109 @@ -6450,7 +6455,7 @@ static struct ctl_table sd_ctl_root[] =
33111 .child = sd_ctl_dir,
33114 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33117 static struct ctl_table *sd_alloc_ctl_entry(int n)
33118 diff -urNp linux-2.6.29/kernel/signal.c linux-2.6.29/kernel/signal.c
33119 --- linux-2.6.29/kernel/signal.c 2009-03-23 19:12:14.000000000 -0400
33120 +++ linux-2.6.29/kernel/signal.c 2009-03-28 14:26:20.000000000 -0400
33121 @@ -198,6 +198,9 @@ static struct sigqueue *__sigqueue_alloc
33123 user = get_uid(__task_cred(t)->user);
33124 atomic_inc(&user->sigpending);
33126 + if (!override_rlimit)
33127 + gr_learn_resource(t, RLIMIT_SIGPENDING, atomic_read(&user->sigpending), 1);
33128 if (override_rlimit ||
33129 atomic_read(&user->sigpending) <=
33130 t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
33131 @@ -636,6 +636,9 @@ static int check_kill_permission(int sig
33135 + if (gr_handle_signal(t, sig))
33138 return security_task_kill(t, info, sig, 0);
33141 @@ -903,8 +909,8 @@ static void print_fatal_signal(struct pt
33142 for (i = 0; i < 16; i++) {
33143 unsigned char insn;
33145 - __get_user(insn, (unsigned char *)(regs->ip + i));
33146 - printk("%02x ", insn);
33147 + if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
33148 + printk("%02x ", insn);
33152 @@ -929,7 +935,7 @@ __group_send_sig_info(int sig, struct si
33153 return send_signal(sig, info, p, 1);
33158 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
33160 return send_signal(sig, info, t, 0);
33161 @@ -969,6 +975,9 @@ force_sig_info(int sig, struct siginfo *
33162 ret = specific_send_sig_info(sig, info, t);
33163 spin_unlock_irqrestore(&t->sighand->siglock, flags);
33165 + gr_log_signal(sig, t);
33166 + gr_handle_crash(t, sig);
33171 @@ -1043,6 +1052,8 @@ int group_send_sig_info(int sig, struct
33172 ret = __group_send_sig_info(sig, info, p);
33173 unlock_task_sighand(p, &flags);
33176 + gr_log_signal(sig, p);
33180 diff -urNp linux-2.6.29/kernel/softirq.c linux-2.6.29/kernel/softirq.c
33181 --- linux-2.6.29/kernel/softirq.c 2009-03-23 19:12:14.000000000 -0400
33182 +++ linux-2.6.29/kernel/softirq.c 2009-03-28 14:26:20.000000000 -0400
33183 @@ -450,9 +450,9 @@ void tasklet_kill(struct tasklet_struct
33184 printk("Attempt to kill tasklet from interrupt\n");
33186 while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
33190 - while (test_bit(TASKLET_STATE_SCHED, &t->state));
33191 + } while (test_bit(TASKLET_STATE_SCHED, &t->state));
33193 tasklet_unlock_wait(t);
33194 clear_bit(TASKLET_STATE_SCHED, &t->state);
33195 diff -urNp linux-2.6.29/kernel/sys.c linux-2.6.29/kernel/sys.c
33196 --- linux-2.6.29/kernel/sys.c 2009-03-23 19:12:14.000000000 -0400
33197 +++ linux-2.6.29/kernel/sys.c 2009-03-28 14:26:20.000000000 -0400
33198 @@ -131,6 +131,12 @@ static int set_one_prio(struct task_stru
33203 + if (gr_handle_chroot_setpriority(p, niceval)) {
33208 no_nice = security_task_setnice(p, niceval);
33211 @@ -503,6 +509,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, g
33216 if (egid != (gid_t) -1) {
33217 if (old->gid == egid ||
33218 old->egid == egid ||
33219 @@ -513,6 +520,9 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, g
33223 + if (gr_check_group_change(new->gid, new->egid, -1))
33226 if (rgid != (gid_t) -1 ||
33227 (egid != (gid_t) -1 && egid != old->gid))
33228 new->sgid = new->egid;
33229 @@ -546,6 +556,10 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
33234 + if (gr_check_group_change(gid, gid, gid))
33237 if (capable(CAP_SETGID))
33238 new->gid = new->egid = new->sgid = new->fsgid = gid;
33239 else if (gid == old->gid || gid == old->sgid)
33240 @@ -636,6 +650,9 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, u
33244 + if (gr_check_user_change(new->uid, new->euid, -1))
33247 if (new->uid != old->uid) {
33248 retval = set_user(new);
33250 @@ -684,6 +701,12 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
33255 + if (gr_check_crash_uid(uid))
33257 + if (gr_check_user_change(uid, uid, uid))
33260 if (capable(CAP_SETUID)) {
33261 new->suid = new->uid = uid;
33262 if (uid != old->uid) {
33263 @@ -741,6 +764,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid,
33267 + if (gr_check_user_change(ruid, euid, -1))
33270 if (ruid != (uid_t) -1) {
33272 if (ruid != old->uid) {
33273 @@ -809,6 +835,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid,
33277 + if (gr_check_group_change(rgid, egid, -1))
33280 if (rgid != (gid_t) -1)
33282 if (egid != (gid_t) -1)
33283 @@ -858,6 +887,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
33284 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS) < 0)
33287 + if (gr_check_user_change(-1, -1, uid))
33290 if (uid == old->uid || uid == old->euid ||
33291 uid == old->suid || uid == old->fsuid ||
33292 capable(CAP_SETUID)) {
33293 @@ -898,6 +930,9 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
33294 if (gid == old->gid || gid == old->egid ||
33295 gid == old->sgid || gid == old->fsgid ||
33296 capable(CAP_SETGID)) {
33297 + if (gr_check_group_change(-1, -1, gid))
33300 if (gid != old_fsgid) {
33303 @@ -974,7 +1009,10 @@ SYSCALL_DEFINE2(setpgid, pid_t, pid, pid
33304 write_lock_irq(&tasklist_lock);
33307 - p = find_task_by_vpid(pid);
33308 + /* grsec: replaced find_task_by_vpid with equivalent call which
33309 + lacks the chroot restriction
33311 + p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
33315 @@ -1732,7 +1770,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
33316 error = get_dumpable(me->mm);
33318 case PR_SET_DUMPABLE:
33319 - if (arg2 < 0 || arg2 > 1) {
33324 diff -urNp linux-2.6.29/kernel/sysctl.c linux-2.6.29/kernel/sysctl.c
33325 --- linux-2.6.29/kernel/sysctl.c 2009-03-23 19:12:14.000000000 -0400
33326 +++ linux-2.6.29/kernel/sysctl.c 2009-03-28 14:26:20.000000000 -0400
33328 static int deprecated_sysctl_warning(struct __sysctl_args *args);
33330 #if defined(CONFIG_SYSCTL)
33331 +#include <linux/grsecurity.h>
33332 +#include <linux/grinternal.h>
33334 +extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
33335 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
33337 +extern int gr_handle_chroot_sysctl(const int op);
33339 /* External variables not in a header file. */
33341 @@ -158,6 +165,7 @@ static int proc_do_cad_pid(struct ctl_ta
33342 static int proc_taint(struct ctl_table *table, int write, struct file *filp,
33343 void __user *buffer, size_t *lenp, loff_t *ppos);
33345 +extern ctl_table grsecurity_table[];
33347 static struct ctl_table root_table[];
33348 static struct ctl_table_root sysctl_table_root;
33349 @@ -190,6 +198,21 @@ extern struct ctl_table epoll_table[];
33350 int sysctl_legacy_va_layout;
33353 +#ifdef CONFIG_PAX_SOFTMODE
33354 +static ctl_table pax_table[] = {
33356 + .ctl_name = CTL_UNNUMBERED,
33357 + .procname = "softmode",
33358 + .data = &pax_softmode,
33359 + .maxlen = sizeof(unsigned int),
33361 + .proc_handler = &proc_dointvec,
33364 + { .ctl_name = 0 }
33368 extern int prove_locking;
33369 extern int lock_stat;
33371 @@ -900,6 +923,25 @@ static struct ctl_table kern_table[] = {
33372 .proc_handler = &scan_unevictable_handler,
33376 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
33378 + .ctl_name = CTL_UNNUMBERED,
33379 + .procname = "grsecurity",
33381 + .child = grsecurity_table,
33385 +#ifdef CONFIG_PAX_SOFTMODE
33387 + .ctl_name = CTL_UNNUMBERED,
33388 + .procname = "pax",
33390 + .child = pax_table,
33395 * NOTE: do not add new entries to this table unless you have read
33396 * Documentation/sysctl/ctl_unnumbered.txt
33397 @@ -1637,6 +1679,8 @@ static int do_sysctl_strategy(struct ctl
33401 +static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
33403 static int parse_table(int __user *name, int nlen,
33404 void __user *oldval, size_t __user *oldlenp,
33405 void __user *newval, size_t newlen,
33406 @@ -1655,7 +1699,7 @@ repeat:
33407 if (n == table->ctl_name) {
33409 if (table->child) {
33410 - if (sysctl_perm(root, table, MAY_EXEC))
33411 + if (sysctl_perm_nochk(root, table, MAY_EXEC))
33415 @@ -1740,6 +1784,33 @@ int sysctl_perm(struct ctl_table_root *r
33419 + if (table->parent != NULL && table->parent->procname != NULL &&
33420 + table->procname != NULL &&
33421 + gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
33423 + if (gr_handle_chroot_sysctl(op))
33425 + error = gr_handle_sysctl(table, op);
33429 + error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
33433 + if (root->permissions)
33434 + mode = root->permissions(root, current->nsproxy, table);
33436 + mode = table->mode;
33438 + return test_perm(mode, op);
33441 +int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
33446 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
33449 diff -urNp linux-2.6.29/kernel/time/tick-broadcast.c linux-2.6.29/kernel/time/tick-broadcast.c
33450 --- linux-2.6.29/kernel/time/tick-broadcast.c 2009-03-23 19:12:14.000000000 -0400
33451 +++ linux-2.6.29/kernel/time/tick-broadcast.c 2009-03-28 14:26:20.000000000 -0400
33452 @@ -116,7 +116,7 @@ int tick_device_uses_broadcast(struct cl
33453 * then clear the broadcast bit.
33455 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
33456 - int cpu = smp_processor_id();
33457 + cpu = smp_processor_id();
33459 cpumask_clear_cpu(cpu, tick_get_broadcast_mask());
33460 tick_broadcast_clear_oneshot(cpu);
33461 diff -urNp linux-2.6.29/kernel/time.c linux-2.6.29/kernel/time.c
33462 --- linux-2.6.29/kernel/time.c 2009-03-23 19:12:14.000000000 -0400
33463 +++ linux-2.6.29/kernel/time.c 2009-03-28 14:26:20.000000000 -0400
33464 @@ -94,6 +94,9 @@ SYSCALL_DEFINE1(stime, time_t __user *,
33467 vx_settimeofday(&tv);
33469 + gr_log_timechange();
33474 @@ -202,6 +205,8 @@ SYSCALL_DEFINE2(settimeofday, struct tim
33478 + gr_log_timechange();
33480 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
33483 @@ -240,7 +245,7 @@ EXPORT_SYMBOL(current_fs_time);
33484 * Avoid unnecessary multiplications/divisions in the
33485 * two most common HZ cases:
33487 -unsigned int inline jiffies_to_msecs(const unsigned long j)
33488 +inline unsigned int jiffies_to_msecs(const unsigned long j)
33490 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
33491 return (MSEC_PER_SEC / HZ) * j;
33492 @@ -256,7 +261,7 @@ unsigned int inline jiffies_to_msecs(con
33494 EXPORT_SYMBOL(jiffies_to_msecs);
33496 -unsigned int inline jiffies_to_usecs(const unsigned long j)
33497 +inline unsigned int jiffies_to_usecs(const unsigned long j)
33499 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
33500 return (USEC_PER_SEC / HZ) * j;
33501 diff -urNp linux-2.6.29/kernel/trace/trace.c linux-2.6.29/kernel/trace/trace.c
33502 --- linux-2.6.29/kernel/trace/trace.c 2009-03-23 19:12:14.000000000 -0400
33503 +++ linux-2.6.29/kernel/trace/trace.c 2009-03-28 14:26:20.000000000 -0400
33504 @@ -442,7 +442,7 @@ trace_seq_path(struct trace_seq *s, stru
33506 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
33508 - p = mangle_path(s->buffer + s->len, p, "\n");
33509 + p = mangle_path(s->buffer + s->len, p, "\n\\");
33511 s->len = p - s->buffer;
33513 diff -urNp linux-2.6.29/kernel/utsname_sysctl.c linux-2.6.29/kernel/utsname_sysctl.c
33514 --- linux-2.6.29/kernel/utsname_sysctl.c 2009-03-23 19:12:14.000000000 -0400
33515 +++ linux-2.6.29/kernel/utsname_sysctl.c 2009-03-28 14:26:20.000000000 -0400
33516 @@ -123,7 +123,7 @@ static struct ctl_table uts_kern_table[]
33517 .proc_handler = proc_do_uts_string,
33518 .strategy = sysctl_uts_string,
33521 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33524 static struct ctl_table uts_root_table[] = {
33525 @@ -133,7 +133,7 @@ static struct ctl_table uts_root_table[]
33527 .child = uts_kern_table,
33530 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33533 static int __init utsname_sysctl_init(void)
33534 diff -urNp linux-2.6.29/lib/radix-tree.c linux-2.6.29/lib/radix-tree.c
33535 --- linux-2.6.29/lib/radix-tree.c 2009-03-23 19:12:14.000000000 -0400
33536 +++ linux-2.6.29/lib/radix-tree.c 2009-03-28 14:26:20.000000000 -0400
33537 @@ -81,7 +81,7 @@ struct radix_tree_preload {
33539 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
33541 -static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
33542 +static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
33544 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
33546 diff -urNp linux-2.6.29/localversion-grsec linux-2.6.29/localversion-grsec
33547 --- linux-2.6.29/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
33548 +++ linux-2.6.29/localversion-grsec 2009-03-28 14:26:20.000000000 -0400
33551 diff -urNp linux-2.6.29/Makefile linux-2.6.29/Makefile
33552 --- linux-2.6.29/Makefile 2009-03-23 19:12:14.000000000 -0400
33553 +++ linux-2.6.29/Makefile 2009-03-28 14:26:20.000000000 -0400
33554 @@ -226,7 +226,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
33558 -HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
33559 +HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
33562 # Decide whether to build built-in, modular, or both.
33563 @@ -636,7 +636,7 @@ export mod_strip_cmd
33566 ifeq ($(KBUILD_EXTMOD),)
33567 -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
33568 +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
33570 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
33571 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
33572 diff -urNp linux-2.6.29/mm/filemap.c linux-2.6.29/mm/filemap.c
33573 --- linux-2.6.29/mm/filemap.c 2009-03-23 19:12:14.000000000 -0400
33574 +++ linux-2.6.29/mm/filemap.c 2009-03-28 14:26:20.000000000 -0400
33575 @@ -1615,7 +1615,7 @@ int generic_file_mmap(struct file * file
33576 struct address_space *mapping = file->f_mapping;
33578 if (!mapping->a_ops->readpage)
33581 file_accessed(file);
33582 vma->vm_ops = &generic_file_vm_ops;
33583 vma->vm_flags |= VM_CAN_NONLINEAR;
33584 @@ -1976,6 +1976,7 @@ inline int generic_write_checks(struct f
33585 *pos = i_size_read(inode);
33587 if (limit != RLIM_INFINITY) {
33588 + gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
33589 if (*pos >= limit) {
33590 send_sig(SIGXFSZ, current, 0);
33592 diff -urNp linux-2.6.29/mm/fremap.c linux-2.6.29/mm/fremap.c
33593 --- linux-2.6.29/mm/fremap.c 2009-03-23 19:12:14.000000000 -0400
33594 +++ linux-2.6.29/mm/fremap.c 2009-03-28 14:26:20.000000000 -0400
33595 @@ -153,6 +153,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
33597 vma = find_vma(mm, start);
33599 +#ifdef CONFIG_PAX_SEGMEXEC
33600 + if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC))
33605 * Make sure the vma is shared, that it supports prefaulting,
33606 * and that the remapped range is valid and fully within
33607 diff -urNp linux-2.6.29/mm/hugetlb.c linux-2.6.29/mm/hugetlb.c
33608 --- linux-2.6.29/mm/hugetlb.c 2009-03-23 19:12:14.000000000 -0400
33609 +++ linux-2.6.29/mm/hugetlb.c 2009-03-28 14:26:20.000000000 -0400
33610 @@ -1864,6 +1864,26 @@ static int unmap_ref_private(struct mm_s
33614 +#ifdef CONFIG_PAX_SEGMEXEC
33615 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
33617 + struct mm_struct *mm = vma->vm_mm;
33618 + struct vm_area_struct *vma_m;
33619 + unsigned long address_m;
33622 + vma_m = pax_find_mirror_vma(vma);
33626 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33627 + address_m = address + SEGMEXEC_TASK_SIZE;
33628 + ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
33629 + get_page(page_m);
33630 + set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
33634 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
33635 unsigned long address, pte_t *ptep, pte_t pte,
33636 struct page *pagecache_page)
33637 @@ -1935,6 +1955,11 @@ retry_avoidcopy:
33638 huge_ptep_clear_flush(vma, address, ptep);
33639 set_huge_pte_at(mm, address, ptep,
33640 make_huge_pte(vma, new_page, 1));
33642 +#ifdef CONFIG_PAX_SEGMEXEC
33643 + pax_mirror_huge_pte(vma, address, new_page);
33646 /* Make the old page be freed below */
33647 new_page = old_page;
33649 @@ -2044,6 +2069,10 @@ retry:
33650 && (vma->vm_flags & VM_SHARED)));
33651 set_huge_pte_at(mm, address, ptep, new_pte);
33653 +#ifdef CONFIG_PAX_SEGMEXEC
33654 + pax_mirror_huge_pte(vma, address, page);
33657 if (write_access && !(vma->vm_flags & VM_SHARED)) {
33658 /* Optimization, do the COW without a second fault */
33659 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
33660 @@ -2072,6 +2101,28 @@ int hugetlb_fault(struct mm_struct *mm,
33661 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
33662 struct hstate *h = hstate_vma(vma);
33664 +#ifdef CONFIG_PAX_SEGMEXEC
33665 + struct vm_area_struct *vma_m;
33667 + vma_m = pax_find_mirror_vma(vma);
33669 + unsigned long address_m;
33671 + if (vma->vm_start > vma_m->vm_start) {
33672 + address_m = address;
33673 + address -= SEGMEXEC_TASK_SIZE;
33675 + h = hstate_vma(vma);
33677 + address_m = address + SEGMEXEC_TASK_SIZE;
33679 + if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
33680 + return VM_FAULT_OOM;
33681 + address_m &= HPAGE_MASK;
33682 + unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
33686 ptep = huge_pte_alloc(mm, address, huge_page_size(h));
33688 return VM_FAULT_OOM;
33689 diff -urNp linux-2.6.29/mm/madvise.c linux-2.6.29/mm/madvise.c
33690 --- linux-2.6.29/mm/madvise.c 2009-03-23 19:12:14.000000000 -0400
33691 +++ linux-2.6.29/mm/madvise.c 2009-03-28 14:26:20.000000000 -0400
33692 @@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
33694 int new_flags = vma->vm_flags;
33696 +#ifdef CONFIG_PAX_SEGMEXEC
33697 + struct vm_area_struct *vma_m;
33700 switch (behavior) {
33702 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
33703 @@ -92,6 +96,13 @@ success:
33705 * vm_flags is protected by the mmap_sem held in write mode.
33708 +#ifdef CONFIG_PAX_SEGMEXEC
33709 + vma_m = pax_find_mirror_vma(vma);
33711 + vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
33714 vma->vm_flags = new_flags;
33717 @@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
33719 case MADV_DONTNEED:
33720 error = madvise_dontneed(vma, prev, start, end);
33722 +#ifdef CONFIG_PAX_SEGMEXEC
33724 + struct vm_area_struct *vma_m, *prev_m;
33726 + vma_m = pax_find_mirror_vma(vma);
33728 + error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
33735 @@ -308,6 +330,16 @@ SYSCALL_DEFINE3(madvise, unsigned long,
33739 +#ifdef CONFIG_PAX_SEGMEXEC
33740 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
33741 + if (end > SEGMEXEC_TASK_SIZE)
33746 + if (end > TASK_SIZE)
33752 diff -urNp linux-2.6.29/mm/memory.c linux-2.6.29/mm/memory.c
33753 --- linux-2.6.29/mm/memory.c 2009-03-23 19:12:14.000000000 -0400
33754 +++ linux-2.6.29/mm/memory.c 2009-03-28 14:26:20.000000000 -0400
33756 #include <linux/pagemap.h>
33757 #include <linux/rmap.h>
33758 #include <linux/module.h>
33759 +#include <linux/security.h>
33760 #include <linux/delayacct.h>
33761 #include <linux/init.h>
33762 #include <linux/writeback.h>
33763 @@ -1222,11 +1223,11 @@ int __get_user_pages(struct task_struct
33764 vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
33769 struct vm_area_struct *vma;
33770 unsigned int foll_flags;
33772 - vma = find_extend_vma(mm, start);
33773 + vma = find_vma(mm, start);
33774 if (!vma && in_gate_area(tsk, start)) {
33775 unsigned long pg = start & PAGE_MASK;
33776 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
33777 @@ -1268,7 +1269,7 @@ int __get_user_pages(struct task_struct
33782 + if (!vma || start < vma->vm_start ||
33783 (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
33784 (!ignore && !(vm_flags & vma->vm_flags)))
33785 return i ? : -EFAULT;
33786 @@ -1351,7 +1352,7 @@ int __get_user_pages(struct task_struct
33787 start += PAGE_SIZE;
33789 } while (len && start < vma->vm_end);
33795 @@ -1867,6 +1868,186 @@ static inline void cow_user_page(struct
33796 copy_user_highpage(dst, src, va, vma);
33799 +#ifdef CONFIG_PAX_SEGMEXEC
33800 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
33802 + struct mm_struct *mm = vma->vm_mm;
33804 + pte_t *pte, entry;
33806 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
33808 + if (!pte_present(entry)) {
33809 + if (!pte_none(entry)) {
33810 + BUG_ON(pte_file(entry));
33811 + free_swap_and_cache(pte_to_swp_entry(entry));
33812 + pte_clear_not_present_full(mm, address, pte, 0);
33815 + struct page *page;
33817 + flush_cache_page(vma, address, pte_pfn(entry));
33818 + entry = ptep_clear_flush(vma, address, pte);
33819 + BUG_ON(pte_dirty(entry));
33820 + page = vm_normal_page(vma, address, entry);
33822 + update_hiwater_rss(mm);
33823 + if (PageAnon(page))
33824 + dec_mm_counter(mm, anon_rss);
33826 + dec_mm_counter(mm, file_rss);
33827 + page_remove_rmap(page);
33828 + page_cache_release(page);
33831 + pte_unmap_unlock(pte, ptl);
33834 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
33836 + * the ptl of the lower mapped page is held on entry and is not released on exit
33837 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
33839 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33841 + struct mm_struct *mm = vma->vm_mm;
33842 + unsigned long address_m;
33843 + spinlock_t *ptl_m;
33844 + struct vm_area_struct *vma_m;
33846 + pte_t *pte_m, entry_m;
33848 + BUG_ON(!page_m || !PageAnon(page_m));
33850 + vma_m = pax_find_mirror_vma(vma);
33854 + BUG_ON(!PageLocked(page_m));
33855 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33856 + address_m = address + SEGMEXEC_TASK_SIZE;
33857 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33858 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33859 + ptl_m = pte_lockptr(mm, pmd_m);
33860 + if (ptl != ptl_m) {
33861 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33862 + if (!pte_none(*pte_m))
33866 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33867 + page_cache_get(page_m);
33868 + page_add_anon_rmap(page_m, vma_m, address_m);
33869 + inc_mm_counter(mm, anon_rss);
33870 + set_pte_at(mm, address_m, pte_m, entry_m);
33871 + update_mmu_cache(vma_m, address_m, entry_m);
33873 + if (ptl != ptl_m)
33874 + spin_unlock(ptl_m);
33875 + pte_unmap_nested(pte_m);
33876 + unlock_page(page_m);
33879 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33881 + struct mm_struct *mm = vma->vm_mm;
33882 + unsigned long address_m;
33883 + spinlock_t *ptl_m;
33884 + struct vm_area_struct *vma_m;
33886 + pte_t *pte_m, entry_m;
33888 + BUG_ON(!page_m || PageAnon(page_m));
33890 + vma_m = pax_find_mirror_vma(vma);
33894 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33895 + address_m = address + SEGMEXEC_TASK_SIZE;
33896 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33897 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33898 + ptl_m = pte_lockptr(mm, pmd_m);
33899 + if (ptl != ptl_m) {
33900 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33901 + if (!pte_none(*pte_m))
33905 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33906 + page_cache_get(page_m);
33907 + page_add_file_rmap(page_m);
33908 + inc_mm_counter(mm, file_rss);
33909 + set_pte_at(mm, address_m, pte_m, entry_m);
33910 + update_mmu_cache(vma_m, address_m, entry_m);
33912 + if (ptl != ptl_m)
33913 + spin_unlock(ptl_m);
33914 + pte_unmap_nested(pte_m);
33917 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
33919 + struct mm_struct *mm = vma->vm_mm;
33920 + unsigned long address_m;
33921 + spinlock_t *ptl_m;
33922 + struct vm_area_struct *vma_m;
33924 + pte_t *pte_m, entry_m;
33926 + vma_m = pax_find_mirror_vma(vma);
33930 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33931 + address_m = address + SEGMEXEC_TASK_SIZE;
33932 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33933 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33934 + ptl_m = pte_lockptr(mm, pmd_m);
33935 + if (ptl != ptl_m) {
33936 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33937 + if (!pte_none(*pte_m))
33941 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
33942 + set_pte_at(mm, address_m, pte_m, entry_m);
33944 + if (ptl != ptl_m)
33945 + spin_unlock(ptl_m);
33946 + pte_unmap_nested(pte_m);
33949 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
33951 + struct page *page_m;
33954 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
33958 + page_m = vm_normal_page(vma, address, entry);
33960 + pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
33961 + else if (PageAnon(page_m)) {
33962 + if (pax_find_mirror_vma(vma)) {
33963 + pte_unmap_unlock(pte, ptl);
33964 + lock_page(page_m);
33965 + pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
33966 + if (pte_same(entry, *pte))
33967 + pax_mirror_anon_pte(vma, address, page_m, ptl);
33969 + unlock_page(page_m);
33972 + pax_mirror_file_pte(vma, address, page_m, ptl);
33975 + pte_unmap_unlock(pte, ptl);
33980 * This routine handles present pages, when users try to write
33981 * to a shared page. It is done by copying the page to a new address
33982 @@ -2015,6 +2196,12 @@ gotten:
33984 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33985 if (likely(pte_same(*page_table, orig_pte))) {
33987 +#ifdef CONFIG_PAX_SEGMEXEC
33988 + if (pax_find_mirror_vma(vma))
33989 + BUG_ON(!trylock_page(new_page));
33993 if (!PageAnon(old_page)) {
33994 dec_mm_counter(mm, file_rss);
33995 @@ -2061,6 +2248,10 @@ gotten:
33996 page_remove_rmap(old_page);
33999 +#ifdef CONFIG_PAX_SEGMEXEC
34000 + pax_mirror_anon_pte(vma, address, new_page, ptl);
34003 /* Free the old page.. */
34004 new_page = old_page;
34005 ret |= VM_FAULT_WRITE;
34006 @@ -2320,6 +2511,7 @@ int vmtruncate(struct inode * inode, lof
34007 unsigned long limit;
34009 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
34010 + gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
34011 if (limit != RLIM_INFINITY && offset > limit)
34013 if (offset > inode->i_sb->s_maxbytes)
34014 @@ -2485,6 +2677,11 @@ static int do_swap_page(struct mm_struct
34016 if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
34017 try_to_free_swap(page);
34019 +#ifdef CONFIG_PAX_SEGMEXEC
34020 + if (write_access || !pax_find_mirror_vma(vma))
34025 if (write_access) {
34026 @@ -2496,6 +2693,11 @@ static int do_swap_page(struct mm_struct
34028 /* No need to invalidate - it was non-present before */
34029 update_mmu_cache(vma, address, pte);
34031 +#ifdef CONFIG_PAX_SEGMEXEC
34032 + pax_mirror_anon_pte(vma, address, page, ptl);
34036 pte_unmap_unlock(page_table, ptl);
34038 @@ -2540,12 +2742,23 @@ static int do_anonymous_page(struct mm_s
34039 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
34040 if (!pte_none(*page_table))
34043 +#ifdef CONFIG_PAX_SEGMEXEC
34044 + if (pax_find_mirror_vma(vma))
34045 + BUG_ON(!trylock_page(page));
34048 inc_mm_counter(mm, anon_rss);
34049 page_add_new_anon_rmap(page, vma, address);
34050 set_pte_at(mm, address, page_table, entry);
34052 /* No need to invalidate - it was non-present before */
34053 update_mmu_cache(vma, address, entry);
34055 +#ifdef CONFIG_PAX_SEGMEXEC
34056 + pax_mirror_anon_pte(vma, address, page, ptl);
34060 pte_unmap_unlock(page_table, ptl);
34062 @@ -2682,6 +2895,12 @@ static int __do_fault(struct mm_struct *
34064 /* Only go through if we didn't race with anybody else... */
34065 if (likely(pte_same(*page_table, orig_pte))) {
34067 +#ifdef CONFIG_PAX_SEGMEXEC
34068 + if (anon && pax_find_mirror_vma(vma))
34069 + BUG_ON(!trylock_page(page));
34072 flush_icache_page(vma, page);
34073 entry = mk_pte(page, vma->vm_page_prot);
34074 if (flags & FAULT_FLAG_WRITE)
34075 @@ -2701,6 +2920,14 @@ static int __do_fault(struct mm_struct *
34077 /* no need to invalidate: a not-present page won't be cached */
34078 update_mmu_cache(vma, address, entry);
34080 +#ifdef CONFIG_PAX_SEGMEXEC
34082 + pax_mirror_anon_pte(vma, address, page, ptl);
34084 + pax_mirror_file_pte(vma, address, page, ptl);
34089 mem_cgroup_uncharge_page(page);
34090 @@ -2833,6 +3060,12 @@ static inline int handle_pte_fault(struc
34092 flush_tlb_page(vma, address);
34095 +#ifdef CONFIG_PAX_SEGMEXEC
34096 + pax_mirror_pte(vma, address, pte, pmd, ptl);
34101 pte_unmap_unlock(pte, ptl);
34103 @@ -2849,6 +3082,10 @@ int handle_mm_fault(struct mm_struct *mm
34107 +#ifdef CONFIG_PAX_SEGMEXEC
34108 + struct vm_area_struct *vma_m;
34111 __set_current_state(TASK_RUNNING);
34113 count_vm_event(PGFAULT);
34114 @@ -2856,6 +3093,34 @@ int handle_mm_fault(struct mm_struct *mm
34115 if (unlikely(is_vm_hugetlb_page(vma)))
34116 return hugetlb_fault(mm, vma, address, write_access);
34118 +#ifdef CONFIG_PAX_SEGMEXEC
34119 + vma_m = pax_find_mirror_vma(vma);
34121 + unsigned long address_m;
34126 + if (vma->vm_start > vma_m->vm_start) {
34127 + address_m = address;
34128 + address -= SEGMEXEC_TASK_SIZE;
34131 + address_m = address + SEGMEXEC_TASK_SIZE;
34133 + pgd_m = pgd_offset(mm, address_m);
34134 + pud_m = pud_alloc(mm, pgd_m, address_m);
34136 + return VM_FAULT_OOM;
34137 + pmd_m = pmd_alloc(mm, pud_m, address_m);
34139 + return VM_FAULT_OOM;
34140 + if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
34141 + return VM_FAULT_OOM;
34142 + pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
34146 pgd = pgd_offset(mm, address);
34147 pud = pud_alloc(mm, pgd, address);
34149 @@ -2953,7 +3218,7 @@ static int __init gate_vma_init(void)
34150 gate_vma.vm_start = FIXADDR_USER_START;
34151 gate_vma.vm_end = FIXADDR_USER_END;
34152 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
34153 - gate_vma.vm_page_prot = __P101;
34154 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
34156 * Make sure the vDSO gets into every core dump.
34157 * Dumping its contents makes post-mortem fully interpretable later
34158 diff -urNp linux-2.6.29/mm/mempolicy.c linux-2.6.29/mm/mempolicy.c
34159 --- linux-2.6.29/mm/mempolicy.c 2009-03-23 19:12:14.000000000 -0400
34160 +++ linux-2.6.29/mm/mempolicy.c 2009-03-28 14:26:20.000000000 -0400
34161 @@ -551,6 +551,10 @@ static int mbind_range(struct vm_area_st
34162 struct vm_area_struct *next;
34165 +#ifdef CONFIG_PAX_SEGMEXEC
34166 + struct vm_area_struct *vma_m;
34170 for (; vma && vma->vm_start < end; vma = next) {
34171 next = vma->vm_next;
34172 @@ -562,6 +566,16 @@ static int mbind_range(struct vm_area_st
34173 err = policy_vma(vma, new);
34177 +#ifdef CONFIG_PAX_SEGMEXEC
34178 + vma_m = pax_find_mirror_vma(vma);
34180 + err = policy_vma(vma_m, new);
34189 @@ -954,6 +968,17 @@ static long do_mbind(unsigned long start
34194 +#ifdef CONFIG_PAX_SEGMEXEC
34195 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
34196 + if (end > SEGMEXEC_TASK_SIZE)
34201 + if (end > TASK_SIZE)
34207 @@ -2290,7 +2315,7 @@ int show_numa_map(struct seq_file *m, vo
34210 seq_printf(m, " file=");
34211 - seq_path(m, &file->f_path, "\n\t= ");
34212 + seq_path(m, &file->f_path, "\n\t\\= ");
34213 } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
34214 seq_printf(m, " heap");
34215 } else if (vma->vm_start <= mm->start_stack &&
34216 diff -urNp linux-2.6.29/mm/mlock.c linux-2.6.29/mm/mlock.c
34217 --- linux-2.6.29/mm/mlock.c 2009-03-23 19:12:14.000000000 -0400
34218 +++ linux-2.6.29/mm/mlock.c 2009-03-28 14:26:20.000000000 -0400
34220 #include <linux/pagemap.h>
34221 #include <linux/mempolicy.h>
34222 #include <linux/syscalls.h>
34223 +#include <linux/security.h>
34224 #include <linux/sched.h>
34225 #include <linux/module.h>
34226 #include <linux/rmap.h>
34227 @@ -453,6 +454,17 @@ static int do_mlock(unsigned long start,
34232 +#ifdef CONFIG_PAX_SEGMEXEC
34233 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
34234 + if (end > SEGMEXEC_TASK_SIZE)
34239 + if (end > TASK_SIZE)
34242 vma = find_vma_prev(current->mm, start, &prev);
34243 if (!vma || vma->vm_start > start)
34245 @@ -512,6 +524,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
34246 lock_limit >>= PAGE_SHIFT;
34248 /* check against resource limits */
34249 + gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
34250 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
34251 error = do_mlock(start, len, 1);
34252 up_write(¤t->mm->mmap_sem);
34253 @@ -533,10 +546,10 @@ SYSCALL_DEFINE2(munlock, unsigned long,
34254 static int do_mlockall(int flags)
34256 struct vm_area_struct * vma, * prev = NULL;
34257 - unsigned int def_flags = 0;
34258 + unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
34260 if (flags & MCL_FUTURE)
34261 - def_flags = VM_LOCKED;
34262 + def_flags |= VM_LOCKED;
34263 current->mm->def_flags = def_flags;
34264 if (flags == MCL_FUTURE)
34266 @@ -544,6 +557,12 @@ static int do_mlockall(int flags)
34267 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
34268 unsigned int newflags;
34270 +#ifdef CONFIG_PAX_SEGMEXEC
34271 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
34275 + BUG_ON(vma->vm_end > TASK_SIZE);
34276 newflags = vma->vm_flags | VM_LOCKED;
34277 if (!(flags & MCL_CURRENT))
34278 newflags &= ~VM_LOCKED;
34279 @@ -600,6 +600,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
34281 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
34283 + gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
34284 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
34285 capable(CAP_IPC_LOCK))
34286 ret = do_mlockall(flags);
34287 diff -urNp linux-2.6.29/mm/mmap.c linux-2.6.29/mm/mmap.c
34288 --- linux-2.6.29/mm/mmap.c 2009-03-23 19:12:14.000000000 -0400
34289 +++ linux-2.6.29/mm/mmap.c 2009-03-28 14:26:20.000000000 -0400
34291 #define arch_rebalance_pgtables(addr, len) (addr)
34294 +static inline void verify_mm_writelocked(struct mm_struct *mm)
34296 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
34297 + if (unlikely(down_read_trylock(&mm->mmap_sem))) {
34298 + up_read(&mm->mmap_sem);
34304 static void unmap_region(struct mm_struct *mm,
34305 struct vm_area_struct *vma, struct vm_area_struct *prev,
34306 unsigned long start, unsigned long end);
34307 @@ -68,16 +78,25 @@
34308 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
34311 -pgprot_t protection_map[16] = {
34312 +pgprot_t protection_map[16] __read_only = {
34313 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
34314 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
34317 pgprot_t vm_get_page_prot(unsigned long vm_flags)
34319 - return __pgprot(pgprot_val(protection_map[vm_flags &
34320 + pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
34321 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
34322 pgprot_val(arch_vm_get_page_prot(vm_flags)));
34324 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34325 + if (!nx_enabled &&
34326 + (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
34327 + (vm_flags & (VM_READ | VM_WRITE)))
34328 + prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
34333 EXPORT_SYMBOL(vm_get_page_prot);
34335 @@ -233,6 +252,7 @@
34336 struct vm_area_struct *next = vma->vm_next;
34339 + BUG_ON(vma->vm_mirror);
34340 if (vma->vm_ops && vma->vm_ops->close)
34341 vma->vm_ops->close(vma);
34342 if (vma->vm_file) {
34343 @@ -269,6 +289,7 @@
34344 * not page aligned -Ram Gupta
34346 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
34347 + gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
34348 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
34349 (mm->end_data - mm->start_data) > rlim)
34351 @@ -698,6 +719,12 @@
34352 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
34353 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34356 +#ifdef CONFIG_PAX_SEGMEXEC
34357 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
34361 if (is_mergeable_vma(vma, file, vm_flags) &&
34362 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34363 if (vma->vm_pgoff == vm_pgoff)
34364 @@ -717,6 +744,12 @@
34365 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
34366 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34369 +#ifdef CONFIG_PAX_SEGMEXEC
34370 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
34374 if (is_mergeable_vma(vma, file, vm_flags) &&
34375 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34377 @@ -759,12 +792,19 @@
34378 struct vm_area_struct *vma_merge(struct mm_struct *mm,
34379 struct vm_area_struct *prev, unsigned long addr,
34380 unsigned long end, unsigned long vm_flags,
34381 - struct anon_vma *anon_vma, struct file *file,
34382 + struct anon_vma *anon_vma, struct file *file,
34383 pgoff_t pgoff, struct mempolicy *policy)
34385 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
34386 struct vm_area_struct *area, *next;
34388 +#ifdef CONFIG_PAX_SEGMEXEC
34389 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
34390 + struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
34392 + BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
34396 * We later require that vma->vm_flags == vm_flags,
34397 * so this tests vma->vm_flags & VM_SPECIAL, too.
34398 @@ -780,6 +820,15 @@
34399 if (next && next->vm_end == end) /* cases 6, 7, 8 */
34400 next = next->vm_next;
34402 +#ifdef CONFIG_PAX_SEGMEXEC
34404 + prev_m = pax_find_mirror_vma(prev);
34406 + area_m = pax_find_mirror_vma(area);
34408 + next_m = pax_find_mirror_vma(next);
34412 * Can it merge with the predecessor?
34414 @@ -799,9 +848,24 @@
34416 vma_adjust(prev, prev->vm_start,
34417 next->vm_end, prev->vm_pgoff, NULL);
34418 - } else /* cases 2, 5, 7 */
34420 +#ifdef CONFIG_PAX_SEGMEXEC
34422 + vma_adjust(prev_m, prev_m->vm_start,
34423 + next_m->vm_end, prev_m->vm_pgoff, NULL);
34426 + } else { /* cases 2, 5, 7 */
34427 vma_adjust(prev, prev->vm_start,
34428 end, prev->vm_pgoff, NULL);
34430 +#ifdef CONFIG_PAX_SEGMEXEC
34432 + vma_adjust(prev_m, prev_m->vm_start,
34433 + end_m, prev_m->vm_pgoff, NULL);
34440 @@ -812,12 +876,27 @@
34441 mpol_equal(policy, vma_policy(next)) &&
34442 can_vma_merge_before(next, vm_flags,
34443 anon_vma, file, pgoff+pglen)) {
34444 - if (prev && addr < prev->vm_end) /* case 4 */
34445 + if (prev && addr < prev->vm_end) { /* case 4 */
34446 vma_adjust(prev, prev->vm_start,
34447 addr, prev->vm_pgoff, NULL);
34448 - else /* cases 3, 8 */
34450 +#ifdef CONFIG_PAX_SEGMEXEC
34452 + vma_adjust(prev_m, prev_m->vm_start,
34453 + addr_m, prev_m->vm_pgoff, NULL);
34456 + } else { /* cases 3, 8 */
34457 vma_adjust(area, addr, next->vm_end,
34458 next->vm_pgoff - pglen, NULL);
34460 +#ifdef CONFIG_PAX_SEGMEXEC
34462 + vma_adjust(area_m, addr_m, next_m->vm_end,
34463 + next_m->vm_pgoff - pglen, NULL);
34470 @@ -892,14 +971,11 @@
34471 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
34472 struct file *file, long pages)
34474 - const unsigned long stack_flags
34475 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
34478 mm->shared_vm += pages;
34479 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
34480 mm->exec_vm += pages;
34481 - } else if (flags & stack_flags)
34482 + } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
34483 mm->stack_vm += pages;
34484 if (flags & (VM_RESERVED|VM_IO))
34485 mm->reserved_vm += pages;
34486 @@ -926,7 +1002,7 @@
34487 * (the exception is when the underlying filesystem is noexec
34488 * mounted, in which case we dont add PROT_EXEC.)
34490 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
34491 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
34492 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
34495 @@ -936,15 +1012,15 @@
34496 if (!(flags & MAP_FIXED))
34497 addr = round_hint_to_min(addr);
34499 - error = arch_mmap_check(addr, len, flags);
34503 /* Careful about overflows.. */
34504 len = PAGE_ALIGN(len);
34505 if (!len || len > TASK_SIZE)
34508 + error = arch_mmap_check(addr, len, flags);
34512 /* offset overflow? */
34513 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
34515 @@ -956,7 +1032,7 @@
34516 /* Obtain the address to map to. we verify (or select) it and ensure
34517 * that it represents a valid section of the address space.
34519 - addr = get_unmapped_area(file, addr, len, pgoff, flags);
34520 + addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
34521 if (addr & ~PAGE_MASK)
34524 @@ -967,6 +1043,26 @@
34525 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
34526 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
34528 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
34529 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
34531 +#ifdef CONFIG_PAX_MPROTECT
34532 + if (mm->pax_flags & MF_PAX_MPROTECT) {
34533 + if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
34534 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
34536 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
34543 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34544 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
34545 + vm_flags &= ~VM_PAGEEXEC;
34548 if (flags & MAP_LOCKED) {
34549 if (!can_do_mlock())
34551 @@ -980,6 +1076,7 @@
34552 locked += mm->locked_vm;
34553 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
34554 lock_limit >>= PAGE_SHIFT;
34555 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34556 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
34559 @@ -1050,6 +1147,9 @@
34563 + if (!gr_acl_handle_mmap(file, prot))
34566 return mmap_region(file, addr, len, flags, vm_flags, pgoff);
34568 EXPORT_SYMBOL(do_mmap_pgoff);
34569 @@ -1062,10 +1162,10 @@
34571 int vma_wants_writenotify(struct vm_area_struct *vma)
34573 - unsigned int vm_flags = vma->vm_flags;
34574 + unsigned long vm_flags = vma->vm_flags;
34576 /* If it was private or non-writable, the write bit is already clear */
34577 - if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
34578 + if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
34581 /* The backer wishes to know when pages are first written to? */
34582 @@ -1114,14 +1214,24 @@
34583 unsigned long charged = 0;
34584 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
34586 +#ifdef CONFIG_PAX_SEGMEXEC
34587 + struct vm_area_struct *vma_m = NULL;
34591 + * mm->mmap_sem is required to protect against another thread
34592 + * changing the mappings in case we sleep.
34594 + verify_mm_writelocked(mm);
34596 /* Clear old maps */
34599 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34600 if (vma && vma->vm_start < addr + len) {
34601 if (do_munmap(mm, addr, len))
34603 - goto munmap_back;
34604 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34605 + BUG_ON(vma && vma->vm_start < addr + len);
34608 /* Check against address space limit. */
34609 @@ -1170,6 +1280,16 @@
34613 +#ifdef CONFIG_PAX_SEGMEXEC
34614 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
34615 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34624 vma->vm_start = addr;
34625 vma->vm_end = addr + len;
34626 @@ -1192,6 +1312,19 @@
34627 error = file->f_op->mmap(file, vma);
34629 goto unmap_and_free_vma;
34631 +#ifdef CONFIG_PAX_SEGMEXEC
34632 + if (vma_m && (vm_flags & VM_EXECUTABLE))
34633 + added_exe_file_vma(mm);
34636 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34637 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
34638 + vma->vm_flags |= VM_PAGEEXEC;
34639 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
34643 if (vm_flags & VM_EXECUTABLE)
34644 added_exe_file_vma(mm);
34645 } else if (vm_flags & VM_SHARED) {
34646 @@ -1215,6 +1348,11 @@
34647 vma_link(mm, vma, prev, rb_link, rb_parent);
34648 file = vma->vm_file;
34650 +#ifdef CONFIG_PAX_SEGMEXEC
34652 + pax_mirror_vma(vma_m, vma);
34655 /* Once vma denies write, undo our temporary denial count */
34656 if (correct_wcount)
34657 atomic_inc(&inode->i_writecount);
34658 @@ -1222,6 +1360,7 @@
34659 // mm->total_vm += len >> PAGE_SHIFT;
34660 vx_vmpages_add(mm, len >> PAGE_SHIFT);
34661 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
34662 + track_exec_limit(mm, addr, addr + len, vm_flags);
34663 if (vm_flags & VM_LOCKED) {
34665 * makes pages present; downgrades, drops, reacquires mmap_sem
34666 @@ -1245,6 +1384,12 @@
34667 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
34671 +#ifdef CONFIG_PAX_SEGMEXEC
34673 + kmem_cache_free(vm_area_cachep, vma_m);
34676 kmem_cache_free(vm_area_cachep, vma);
34679 @@ -1278,6 +1423,10 @@
34680 if (flags & MAP_FIXED)
34683 +#ifdef CONFIG_PAX_RANDMMAP
34684 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34688 addr = PAGE_ALIGN(addr);
34689 vma = find_vma(mm, addr);
34690 @@ -1286,10 +1435,10 @@
34693 if (len > mm->cached_hole_size) {
34694 - start_addr = addr = mm->free_area_cache;
34695 + start_addr = addr = mm->free_area_cache;
34697 - start_addr = addr = TASK_UNMAPPED_BASE;
34698 - mm->cached_hole_size = 0;
34699 + start_addr = addr = mm->mmap_base;
34700 + mm->cached_hole_size = 0;
34704 @@ -1300,9 +1449,8 @@
34705 * Start a new search - just in case we missed
34708 - if (start_addr != TASK_UNMAPPED_BASE) {
34709 - addr = TASK_UNMAPPED_BASE;
34710 - start_addr = addr;
34711 + if (start_addr != mm->mmap_base) {
34712 + start_addr = addr = mm->mmap_base;
34713 mm->cached_hole_size = 0;
34716 @@ -1324,10 +1472,16 @@
34718 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
34721 +#ifdef CONFIG_PAX_SEGMEXEC
34722 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34727 * Is this a new hole at the lowest possible address?
34729 - if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
34730 + if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
34731 mm->free_area_cache = addr;
34732 mm->cached_hole_size = ~0UL;
34734 @@ -1345,7 +1499,7 @@
34736 struct vm_area_struct *vma;
34737 struct mm_struct *mm = current->mm;
34738 - unsigned long addr = addr0;
34739 + unsigned long base = mm->mmap_base, addr = addr0;
34741 /* requested length too big for entire address space */
34742 if (len > TASK_SIZE)
34743 @@ -1354,6 +1508,10 @@
34744 if (flags & MAP_FIXED)
34747 +#ifdef CONFIG_PAX_RANDMMAP
34748 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34751 /* requesting a specific address */
34753 addr = PAGE_ALIGN(addr);
34754 @@ -1411,13 +1569,21 @@
34755 * can happen with large stack limits and large mmap()
34758 + mm->mmap_base = TASK_UNMAPPED_BASE;
34760 +#ifdef CONFIG_PAX_RANDMMAP
34761 + if (mm->pax_flags & MF_PAX_RANDMMAP)
34762 + mm->mmap_base += mm->delta_mmap;
34765 + mm->free_area_cache = mm->mmap_base;
34766 mm->cached_hole_size = ~0UL;
34767 - mm->free_area_cache = TASK_UNMAPPED_BASE;
34768 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
34770 * Restore the topdown base:
34772 - mm->free_area_cache = mm->mmap_base;
34773 + mm->mmap_base = base;
34774 + mm->free_area_cache = base;
34775 mm->cached_hole_size = ~0UL;
34778 @@ -1426,6 +1592,12 @@
34780 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
34783 +#ifdef CONFIG_PAX_SEGMEXEC
34784 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34789 * Is this a new hole at the highest possible address?
34791 @@ -1433,8 +1605,10 @@
34792 mm->free_area_cache = addr;
34794 /* dont allow allocations above current base */
34795 - if (mm->free_area_cache > mm->mmap_base)
34796 + if (mm->free_area_cache > mm->mmap_base) {
34797 mm->free_area_cache = mm->mmap_base;
34798 + mm->cached_hole_size = ~0UL;
34803 @@ -1534,6 +1708,27 @@
34804 return prev ? prev->vm_next : vma;
34807 +#ifdef CONFIG_PAX_SEGMEXEC
34808 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
34810 + struct vm_area_struct *vma_m;
34812 + BUG_ON(!vma || vma->vm_start >= vma->vm_end);
34813 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
34814 + BUG_ON(vma->vm_mirror);
34817 + BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
34818 + vma_m = vma->vm_mirror;
34819 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
34820 + BUG_ON(vma->vm_file != vma_m->vm_file);
34821 + BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
34822 + BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
34823 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
34829 * Verify that the stack growth is acceptable and
34830 * update accounting. This is shared with both the
34831 @@ -1550,6 +1745,7 @@
34834 /* Stack limit test */
34835 + gr_learn_resource(current, RLIMIT_STACK, size, 1);
34836 if (size > rlim[RLIMIT_STACK].rlim_cur)
34839 @@ -1559,6 +1755,7 @@
34840 unsigned long limit;
34841 locked = mm->locked_vm + grow;
34842 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
34843 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34844 if (locked > limit && !capable(CAP_IPC_LOCK))
34847 @@ -1594,35 +1791,40 @@
34849 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
34852 + int error, locknext;
34854 if (!(vma->vm_flags & VM_GROWSUP))
34857 + /* Also guard against wrapping around to address 0. */
34858 + if (address < PAGE_ALIGN(address+1))
34859 + address = PAGE_ALIGN(address+1);
34864 * We must make sure the anon_vma is allocated
34865 * so that the anon_vma locking is not a noop.
34867 if (unlikely(anon_vma_prepare(vma)))
34869 + locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
34870 + if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
34872 anon_vma_lock(vma);
34874 + anon_vma_lock(vma->vm_next);
34877 * vma->vm_start/vm_end cannot change under us because the caller
34878 * is required to hold the mmap_sem in read mode. We need the
34879 - * anon_vma lock to serialize against concurrent expand_stacks.
34880 - * Also guard against wrapping around to address 0.
34881 + * anon_vma locks to serialize against concurrent expand_stacks
34882 + * and expand_upwards.
34884 - if (address < PAGE_ALIGN(address+4))
34885 - address = PAGE_ALIGN(address+4);
34887 - anon_vma_unlock(vma);
34892 /* Somebody else might have raced and expanded it already */
34893 - if (address > vma->vm_end) {
34894 + if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
34895 unsigned long size, grow;
34897 size = address - vma->vm_start;
34898 @@ -1632,6 +1834,8 @@
34900 vma->vm_end = address;
34903 + anon_vma_unlock(vma->vm_next);
34904 anon_vma_unlock(vma);
34907 @@ -1643,7 +1847,8 @@
34908 static int expand_downwards(struct vm_area_struct *vma,
34909 unsigned long address)
34912 + int error, lockprev = 0;
34913 + struct vm_area_struct *prev = NULL;
34916 * We must make sure the anon_vma is allocated
34917 @@ -1657,6 +1862,15 @@
34921 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
34922 + find_vma_prev(vma->vm_mm, address, &prev);
34923 + lockprev = prev && (prev->vm_flags & VM_GROWSUP);
34925 + if (lockprev && unlikely(anon_vma_prepare(prev)))
34928 + anon_vma_lock(prev);
34930 anon_vma_lock(vma);
34933 @@ -1666,9 +1880,15 @@
34936 /* Somebody else might have raced and expanded it already */
34937 - if (address < vma->vm_start) {
34938 + if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
34939 unsigned long size, grow;
34941 +#ifdef CONFIG_PAX_SEGMEXEC
34942 + struct vm_area_struct *vma_m;
34944 + vma_m = pax_find_mirror_vma(vma);
34947 size = vma->vm_end - address;
34948 grow = (vma->vm_start - address) >> PAGE_SHIFT;
34950 @@ -1676,9 +1896,20 @@
34952 vma->vm_start = address;
34953 vma->vm_pgoff -= grow;
34954 + track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
34956 +#ifdef CONFIG_PAX_SEGMEXEC
34958 + vma_m->vm_start -= grow << PAGE_SHIFT;
34959 + vma_m->vm_pgoff -= grow;
34965 anon_vma_unlock(vma);
34967 + anon_vma_unlock(prev);
34971 @@ -1754,6 +1985,13 @@
34973 long nrpages = vma_pages(vma);
34975 +#ifdef CONFIG_PAX_SEGMEXEC
34976 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
34977 + vma = remove_vma(vma);
34982 // mm->total_vm -= nrpages;
34983 vx_vmpages_sub(mm, nrpages);
34984 vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
34985 @@ -1799,6 +2037,16 @@
34987 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
34990 +#ifdef CONFIG_PAX_SEGMEXEC
34991 + if (vma->vm_mirror) {
34992 + BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
34993 + vma->vm_mirror->vm_mirror = NULL;
34994 + vma->vm_mirror->vm_flags &= ~VM_EXEC;
34995 + vma->vm_mirror = NULL;
34999 rb_erase(&vma->vm_rb, &mm->mm_rb);
35002 @@ -1818,6 +2066,108 @@
35003 * Split a vma into two pieces at address 'addr', a new vma is allocated
35004 * either for the first part or the tail.
35007 +#ifdef CONFIG_PAX_SEGMEXEC
35008 +int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
35009 + unsigned long addr, int new_below)
35011 + struct mempolicy *pol;
35012 + struct vm_area_struct *new, *vma_m, *new_m = NULL;
35013 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
35015 + if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
35018 + vma_m = pax_find_mirror_vma(vma);
35020 + BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
35021 + if (mm->map_count >= sysctl_max_map_count-1)
35023 + } else if (mm->map_count >= sysctl_max_map_count)
35026 + new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
35031 + new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
35033 + kmem_cache_free(vm_area_cachep, new);
35038 + /* most fields are the same, copy all, and then fixup */
35042 + new->vm_end = addr;
35044 + new->vm_start = addr;
35045 + new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
35050 + new_m->vm_mirror = new;
35051 + new->vm_mirror = new_m;
35054 + new_m->vm_end = addr_m;
35056 + new_m->vm_start = addr_m;
35057 + new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
35061 + pol = mpol_dup(vma_policy(vma));
35062 + if (IS_ERR(pol)) {
35064 + kmem_cache_free(vm_area_cachep, new_m);
35065 + kmem_cache_free(vm_area_cachep, new);
35066 + return PTR_ERR(pol);
35068 + vma_set_policy(new, pol);
35070 + if (new->vm_file) {
35071 + get_file(new->vm_file);
35072 + if (vma->vm_flags & VM_EXECUTABLE)
35073 + added_exe_file_vma(mm);
35076 + if (new->vm_ops && new->vm_ops->open)
35077 + new->vm_ops->open(new);
35080 + vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
35081 + ((addr - new->vm_start) >> PAGE_SHIFT), new);
35083 + vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
35087 + vma_set_policy(new_m, pol);
35089 + if (new_m->vm_file) {
35090 + get_file(new_m->vm_file);
35091 + if (vma_m->vm_flags & VM_EXECUTABLE)
35092 + added_exe_file_vma(mm);
35095 + if (new_m->vm_ops && new_m->vm_ops->open)
35096 + new_m->vm_ops->open(new_m);
35099 + vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
35100 + ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
35102 + vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
35108 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
35109 unsigned long addr, int new_below)
35111 @@ -1869,17 +2219,37 @@
35117 /* Munmap is split into 2 main parts -- this part which finds
35118 * what needs doing, and the areas themselves, which do the
35119 * work. This now handles partial unmappings.
35120 * Jeremy Fitzhardinge <jeremy@goop.org>
35122 +#ifdef CONFIG_PAX_SEGMEXEC
35123 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35125 + int ret = __do_munmap(mm, start, len);
35126 + if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
35129 + return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
35132 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35134 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35138 struct vm_area_struct *vma, *prev, *last;
35141 + * mm->mmap_sem is required to protect against another thread
35142 + * changing the mappings in case we sleep.
35144 + verify_mm_writelocked(mm);
35146 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
35149 @@ -1944,6 +2314,8 @@
35150 /* Fix up all other VM information */
35151 remove_vma_list(mm, vma);
35153 + track_exec_limit(mm, start, end, 0UL);
35158 @@ -1956,22 +2328,18 @@
35160 profile_munmap(addr);
35162 +#ifdef CONFIG_PAX_SEGMEXEC
35163 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
35164 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
35168 down_write(&mm->mmap_sem);
35169 ret = do_munmap(mm, addr, len);
35170 up_write(&mm->mmap_sem);
35174 -static inline void verify_mm_writelocked(struct mm_struct *mm)
35176 -#ifdef CONFIG_DEBUG_VM
35177 - if (unlikely(down_read_trylock(&mm->mmap_sem))) {
35179 - up_read(&mm->mmap_sem);
35185 * this is really a simplified "do_mmap". it only handles
35186 * anonymous maps. eventually we may be able to do some
35187 @@ -1985,6 +2353,11 @@
35188 struct rb_node ** rb_link, * rb_parent;
35189 pgoff_t pgoff = addr >> PAGE_SHIFT;
35191 + unsigned long charged;
35193 +#ifdef CONFIG_PAX_SEGMEXEC
35194 + struct vm_area_struct *vma_m = NULL;
35197 len = PAGE_ALIGN(len);
35199 @@ -2002,19 +2375,34 @@
35201 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
35203 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
35204 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
35205 + flags &= ~VM_EXEC;
35207 +#ifdef CONFIG_PAX_MPROTECT
35208 + if (mm->pax_flags & MF_PAX_MPROTECT)
35209 + flags &= ~VM_MAYEXEC;
35215 error = arch_mmap_check(addr, len, flags);
35219 + charged = len >> PAGE_SHIFT;
35222 * mlock MCL_FUTURE?
35224 if (mm->def_flags & VM_LOCKED) {
35225 unsigned long locked, lock_limit;
35226 - locked = len >> PAGE_SHIFT;
35227 + locked = charged;
35228 locked += mm->locked_vm;
35229 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
35230 lock_limit >>= PAGE_SHIFT;
35231 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
35232 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
35234 if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
35235 @@ -2030,23 +2418,23 @@
35237 * Clear old maps. this also does some error checking for us
35240 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35241 if (vma && vma->vm_start < addr + len) {
35242 if (do_munmap(mm, addr, len))
35244 - goto munmap_back;
35245 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35246 + BUG_ON(vma && vma->vm_start < addr + len);
35249 /* Check against address space limits *after* clearing old maps... */
35250 - if (!may_expand_vm(mm, len >> PAGE_SHIFT))
35251 + if (!may_expand_vm(mm, charged))
35254 if (mm->map_count > sysctl_max_map_count)
35257 - if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
35258 - !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
35259 + if (security_vm_enough_memory(charged) ||
35260 + !vx_vmpages_avail(mm, charged))
35263 /* Can we just expand an old private anonymous mapping? */
35264 @@ -2060,10 +2448,21 @@
35266 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35268 - vm_unacct_memory(len >> PAGE_SHIFT);
35269 + vm_unacct_memory(charged);
35273 +#ifdef CONFIG_PAX_SEGMEXEC
35274 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
35275 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35277 + kmem_cache_free(vm_area_cachep, vma);
35278 + vm_unacct_memory(charged);
35285 vma->vm_start = addr;
35286 vma->vm_end = addr + len;
35287 @@ -2073,13 +2472,14 @@
35288 vma_link(mm, vma, prev, rb_link, rb_parent);
35290 // mm->total_vm += len >> PAGE_SHIFT;
35291 - vx_vmpages_add(mm, len >> PAGE_SHIFT);
35292 + vx_vmpages_add(mm, charged);
35294 if (flags & VM_LOCKED) {
35295 if (!mlock_vma_pages_range(vma, addr, addr + len))
35296 // mm->locked_vm += (len >> PAGE_SHIFT);
35297 - vx_vmlocked_add(mm, len >> PAGE_SHIFT);
35298 + vx_vmlocked_add(mm, charged);
35300 + track_exec_limit(mm, addr, addr + len, flags);
35304 @@ -2130,8 +2530,10 @@
35305 * Walk the list again, actually closing and freeing it,
35306 * with preemption enabled, without holding any MM locks.
35310 + vma->vm_mirror = NULL;
35311 vma = remove_vma(vma);
35314 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
35316 @@ -2145,6 +2547,10 @@
35317 struct vm_area_struct * __vma, * prev;
35318 struct rb_node ** rb_link, * rb_parent;
35320 +#ifdef CONFIG_PAX_SEGMEXEC
35321 + struct vm_area_struct *vma_m = NULL;
35325 * The vm_pgoff of a purely anonymous vma should be irrelevant
35326 * until its first write fault, when page's anon_vma and index
35327 @@ -2168,7 +2574,22 @@
35328 (security_vm_enough_memory_mm(mm, vma_pages(vma)) ||
35329 !vx_vmpages_avail(mm, vma_pages(vma))))
35332 +#ifdef CONFIG_PAX_SEGMEXEC
35333 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
35334 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35340 vma_link(mm, vma, prev, rb_link, rb_parent);
35342 +#ifdef CONFIG_PAX_SEGMEXEC
35344 + pax_mirror_vma(vma_m, vma);
35350 @@ -2186,6 +2607,8 @@
35351 struct rb_node **rb_link, *rb_parent;
35352 struct mempolicy *pol;
35354 + BUG_ON(vma->vm_mirror);
35357 * If anonymous vma has not yet been faulted, update new pgoff
35358 * to match new location, to increase its chance of merging.
35359 @@ -2229,6 +2652,35 @@
35363 +#ifdef CONFIG_PAX_SEGMEXEC
35364 +void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
35366 + struct vm_area_struct *prev_m;
35367 + struct rb_node **rb_link_m, *rb_parent_m;
35368 + struct mempolicy *pol_m;
35370 + BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
35371 + BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
35372 + BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
35374 + pol_m = vma_policy(vma_m);
35376 + vma_set_policy(vma_m, pol_m);
35377 + vma_m->vm_start += SEGMEXEC_TASK_SIZE;
35378 + vma_m->vm_end += SEGMEXEC_TASK_SIZE;
35379 + vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
35380 + vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
35381 + if (vma_m->vm_file)
35382 + get_file(vma_m->vm_file);
35383 + if (vma_m->vm_ops && vma_m->vm_ops->open)
35384 + vma_m->vm_ops->open(vma_m);
35385 + find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
35386 + vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
35387 + vma_m->vm_mirror = vma;
35388 + vma->vm_mirror = vma_m;
35393 * Return true if the calling process may expand its vm space by the passed
35395 @@ -2239,7 +2691,7 @@
35398 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
35400 + gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
35401 if (cur + npages > lim)
35403 if (!vx_vmpages_avail(mm, npages))
35404 @@ -2310,6 +2762,15 @@
35405 vma->vm_start = addr;
35406 vma->vm_end = addr + len;
35408 +#ifdef CONFIG_PAX_MPROTECT
35409 + if (mm->pax_flags & MF_PAX_MPROTECT) {
35410 + if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
35411 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
35413 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
35417 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
35418 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
35420 diff -urNp linux-2.6.29/mm/mprotect.c linux-2.6.29/mm/mprotect.c
35421 --- linux-2.6.29/mm/mprotect.c 2009-03-23 19:12:14.000000000 -0400
35422 +++ linux-2.6.29/mm/mprotect.c 2009-03-28 14:26:20.000000000 -0400
35423 @@ -23,10 +23,16 @@
35424 #include <linux/swapops.h>
35425 #include <linux/mmu_notifier.h>
35426 #include <linux/migrate.h>
35428 +#ifdef CONFIG_PAX_MPROTECT
35429 +#include <linux/elf.h>
35432 #include <asm/uaccess.h>
35433 #include <asm/pgtable.h>
35434 #include <asm/cacheflush.h>
35435 #include <asm/tlbflush.h>
35436 +#include <asm/mmu_context.h>
35438 #ifndef pgprot_modify
35439 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
35440 @@ -131,6 +137,48 @@ static void change_protection(struct vm_
35441 flush_tlb_range(vma, start, end);
35444 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35445 +/* called while holding the mmap semaphor for writing except stack expansion */
35446 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
35448 + unsigned long oldlimit, newlimit = 0UL;
35450 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
35453 + spin_lock(&mm->page_table_lock);
35454 + oldlimit = mm->context.user_cs_limit;
35455 + if ((prot & VM_EXEC) && oldlimit < end)
35456 + /* USER_CS limit moved up */
35458 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
35459 + /* USER_CS limit moved down */
35460 + newlimit = start;
35463 + mm->context.user_cs_limit = newlimit;
35467 + cpus_clear(mm->context.cpu_user_cs_mask);
35468 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
35471 + set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
35473 + spin_unlock(&mm->page_table_lock);
35474 + if (newlimit == end) {
35475 + struct vm_area_struct *vma = find_vma(mm, oldlimit);
35477 + for (; vma && vma->vm_start < end; vma = vma->vm_next)
35478 + if (is_vm_hugetlb_page(vma))
35479 + hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
35481 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
35487 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
35488 unsigned long start, unsigned long end, unsigned long newflags)
35489 @@ -143,6 +191,14 @@ mprotect_fixup(struct vm_area_struct *vm
35491 int dirty_accountable = 0;
35493 +#ifdef CONFIG_PAX_SEGMEXEC
35494 + struct vm_area_struct *vma_m = NULL;
35495 + unsigned long start_m, end_m;
35497 + start_m = start + SEGMEXEC_TASK_SIZE;
35498 + end_m = end + SEGMEXEC_TASK_SIZE;
35501 if (newflags == oldflags) {
35504 @@ -164,6 +220,38 @@ mprotect_fixup(struct vm_area_struct *vm
35508 +#ifdef CONFIG_PAX_SEGMEXEC
35509 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
35510 + if (start != vma->vm_start) {
35511 + error = split_vma(mm, vma, start, 1);
35514 + BUG_ON(!*pprev || (*pprev)->vm_next == vma);
35515 + *pprev = (*pprev)->vm_next;
35518 + if (end != vma->vm_end) {
35519 + error = split_vma(mm, vma, end, 0);
35524 + if (pax_find_mirror_vma(vma)) {
35525 + error = __do_munmap(mm, start_m, end_m - start_m);
35529 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35534 + vma->vm_flags = newflags;
35535 + pax_mirror_vma(vma_m, vma);
35541 * First try to merge with previous and/or next vma.
35543 @@ -195,8 +283,14 @@ success:
35544 * held in write mode.
35546 vma->vm_flags = newflags;
35548 +#ifdef CONFIG_PAX_MPROTECT
35549 + if (current->binfmt && current->binfmt->handle_mprotect)
35550 + current->binfmt->handle_mprotect(vma, newflags);
35553 vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
35554 - vm_get_page_prot(newflags));
35555 + vm_get_page_prot(vma->vm_flags));
35557 if (vma_wants_writenotify(vma)) {
35558 vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
35559 @@ -237,6 +331,17 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
35564 +#ifdef CONFIG_PAX_SEGMEXEC
35565 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
35566 + if (end > SEGMEXEC_TASK_SIZE)
35571 + if (end > TASK_SIZE)
35574 if (!arch_validate_prot(prot))
35577 @@ -244,7 +349,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
35579 * Does the application expect PROT_READ to imply PROT_EXEC:
35581 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
35582 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
35585 vm_flags = calc_vm_prot_bits(prot);
35586 @@ -276,6 +381,16 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
35587 if (start > vma->vm_start)
35590 + if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
35595 +#ifdef CONFIG_PAX_MPROTECT
35596 + if (current->binfmt && current->binfmt->handle_mprotect)
35597 + current->binfmt->handle_mprotect(vma, vm_flags);
35600 for (nstart = start ; ; ) {
35601 unsigned long newflags;
35603 @@ -299,6 +414,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
35604 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
35608 + track_exec_limit(current->mm, nstart, tmp, vm_flags);
35612 if (nstart < prev->vm_end)
35613 diff -urNp linux-2.6.29/mm/mremap.c linux-2.6.29/mm/mremap.c
35614 --- linux-2.6.29/mm/mremap.c 2009-03-23 19:12:14.000000000 -0400
35615 +++ linux-2.6.29/mm/mremap.c 2009-03-28 14:26:20.000000000 -0400
35616 @@ -113,6 +113,12 @@ static void move_ptes(struct vm_area_str
35618 pte = ptep_clear_flush(vma, old_addr, old_pte);
35619 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
35621 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35622 + if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
35623 + pte = pte_exprotect(pte);
35626 set_pte_at(mm, new_addr, new_pte, pte);
35629 @@ -262,6 +268,7 @@ unsigned long do_mremap(unsigned long ad
35630 struct vm_area_struct *vma;
35631 unsigned long ret = -EINVAL;
35632 unsigned long charged = 0;
35633 + unsigned long pax_task_size = TASK_SIZE;
35635 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
35637 @@ -280,6 +287,15 @@ unsigned long do_mremap(unsigned long ad
35641 +#ifdef CONFIG_PAX_SEGMEXEC
35642 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
35643 + pax_task_size = SEGMEXEC_TASK_SIZE;
35646 + if (new_len > pax_task_size || addr > pax_task_size-new_len ||
35647 + old_len > pax_task_size || addr > pax_task_size-old_len)
35650 /* new_addr is only valid if MREMAP_FIXED is specified */
35651 if (flags & MREMAP_FIXED) {
35652 if (new_addr & ~PAGE_MASK)
35653 @@ -287,16 +303,13 @@ unsigned long do_mremap(unsigned long ad
35654 if (!(flags & MREMAP_MAYMOVE))
35657 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
35658 + if (new_addr > pax_task_size - new_len)
35661 /* Check if the location we're moving into overlaps the
35662 * old location at all, and fail if it does.
35664 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
35667 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
35668 + if (addr + old_len > new_addr && new_addr + new_len > addr)
35671 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
35672 @@ -334,6 +347,14 @@ unsigned long do_mremap(unsigned long ad
35677 +#ifdef CONFIG_PAX_SEGMEXEC
35678 + if (pax_find_mirror_vma(vma)) {
35684 /* We can't remap across vm area boundaries */
35685 if (old_len > vma->vm_end - addr)
35687 @@ -367,7 +388,7 @@ unsigned long do_mremap(unsigned long ad
35688 if (old_len == vma->vm_end - addr &&
35689 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
35690 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
35691 - unsigned long max_addr = TASK_SIZE;
35692 + unsigned long max_addr = pax_task_size;
35694 max_addr = vma->vm_next->vm_start;
35695 /* can we just expand the current mapping? */
35696 @@ -385,6 +406,7 @@ unsigned long do_mremap(unsigned long ad
35700 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
35704 @@ -395,8 +417,8 @@ unsigned long do_mremap(unsigned long ad
35707 if (flags & MREMAP_MAYMOVE) {
35708 + unsigned long map_flags = 0;
35709 if (!(flags & MREMAP_FIXED)) {
35710 - unsigned long map_flags = 0;
35711 if (vma->vm_flags & VM_MAYSHARE)
35712 map_flags |= MAP_SHARED;
35714 @@ -411,7 +433,12 @@ unsigned long do_mremap(unsigned long ad
35718 + map_flags = vma->vm_flags;
35719 ret = move_vma(vma, addr, old_len, new_len, new_addr);
35720 + if (!(ret & ~PAGE_MASK)) {
35721 + track_exec_limit(current->mm, addr, addr + old_len, 0UL);
35722 + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
35726 if (ret & ~PAGE_MASK)
35727 diff -urNp linux-2.6.29/mm/nommu.c linux-2.6.29/mm/nommu.c
35728 --- linux-2.6.29/mm/nommu.c 2009-03-23 19:12:14.000000000 -0400
35729 +++ linux-2.6.29/mm/nommu.c 2009-03-28 14:26:20.000000000 -0400
35730 @@ -766,15 +766,6 @@ struct vm_area_struct *find_vma(struct m
35731 EXPORT_SYMBOL(find_vma);
35735 - * - we don't extend stack VMAs under NOMMU conditions
35737 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
35739 - return find_vma(mm, addr);
35743 * expand a stack to a given address
35744 * - not supported under NOMMU conditions
35746 diff -urNp linux-2.6.29/mm/page_alloc.c linux-2.6.29/mm/page_alloc.c
35747 --- linux-2.6.29/mm/page_alloc.c 2009-03-23 19:12:14.000000000 -0400
35748 +++ linux-2.6.29/mm/page_alloc.c 2009-03-28 14:26:20.000000000 -0400
35749 @@ -549,6 +549,10 @@ static void __free_pages_ok(struct page
35753 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35754 + unsigned long index = 1UL << order;
35757 for (i = 0 ; i < (1 << order) ; ++i)
35758 bad += free_pages_check(page + i);
35760 @@ -559,6 +563,12 @@ static void __free_pages_ok(struct page
35761 debug_check_no_obj_freed(page_address(page),
35762 PAGE_SIZE << order);
35765 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35766 + for (; index; --index)
35767 + sanitize_highpage(page + index - 1);
35770 arch_free_page(page, order);
35771 kernel_map_pages(page, 1 << order, 0);
35773 @@ -647,8 +657,10 @@ static int prep_new_page(struct page *pa
35774 arch_alloc_page(page, order);
35775 kernel_map_pages(page, 1 << order, 1);
35777 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
35778 if (gfp_flags & __GFP_ZERO)
35779 prep_zero_page(page, order, gfp_flags);
35782 if (order && (gfp_flags & __GFP_COMP))
35783 prep_compound_page(page, order);
35784 @@ -1009,6 +1021,11 @@ static void free_hot_cold_page(struct pa
35785 debug_check_no_locks_freed(page_address(page), PAGE_SIZE);
35786 debug_check_no_obj_freed(page_address(page), PAGE_SIZE);
35789 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35790 + sanitize_highpage(page);
35793 arch_free_page(page, 0);
35794 kernel_map_pages(page, 1, 0);
35796 diff -urNp linux-2.6.29/mm/rmap.c linux-2.6.29/mm/rmap.c
35797 --- linux-2.6.29/mm/rmap.c 2009-03-23 19:12:14.000000000 -0400
35798 +++ linux-2.6.29/mm/rmap.c 2009-03-28 14:26:20.000000000 -0400
35799 @@ -103,6 +103,10 @@ int anon_vma_prepare(struct vm_area_stru
35800 struct mm_struct *mm = vma->vm_mm;
35801 struct anon_vma *allocated;
35803 +#ifdef CONFIG_PAX_SEGMEXEC
35804 + struct vm_area_struct *vma_m;
35807 anon_vma = find_mergeable_anon_vma(vma);
35810 @@ -116,6 +120,15 @@ int anon_vma_prepare(struct vm_area_stru
35811 /* page_table_lock to protect against threads */
35812 spin_lock(&mm->page_table_lock);
35813 if (likely(!vma->anon_vma)) {
35815 +#ifdef CONFIG_PAX_SEGMEXEC
35816 + vma_m = pax_find_mirror_vma(vma);
35818 + vma_m->anon_vma = anon_vma;
35819 + __anon_vma_link(vma_m);
35823 vma->anon_vma = anon_vma;
35824 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
35826 diff -urNp linux-2.6.29/mm/shmem.c linux-2.6.29/mm/shmem.c
35827 --- linux-2.6.29/mm/shmem.c 2009-03-23 19:12:14.000000000 -0400
35828 +++ linux-2.6.29/mm/shmem.c 2009-03-28 14:26:20.000000000 -0400
35830 #include <linux/module.h>
35831 #include <linux/swap.h>
35833 -static struct vfsmount *shm_mnt;
35834 +struct vfsmount *shm_mnt;
35836 #ifdef CONFIG_SHMEM
35838 diff -urNp linux-2.6.29/mm/slab.c linux-2.6.29/mm/slab.c
35839 --- linux-2.6.29/mm/slab.c 2009-03-23 19:12:14.000000000 -0400
35840 +++ linux-2.6.29/mm/slab.c 2009-03-28 14:26:20.000000000 -0400
35841 @@ -305,7 +305,7 @@ struct kmem_list3 {
35842 * Need this for bootstrapping a per node allocator.
35844 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
35845 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
35846 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
35847 #define CACHE_CACHE 0
35848 #define SIZE_AC MAX_NUMNODES
35849 #define SIZE_L3 (2 * MAX_NUMNODES)
35850 @@ -654,14 +654,14 @@ struct cache_names {
35851 static struct cache_names __initdata cache_names[] = {
35852 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
35853 #include <linux/kmalloc_sizes.h>
35859 static struct arraycache_init initarray_cache __initdata =
35860 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35861 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35862 static struct arraycache_init initarray_generic =
35863 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35864 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35866 /* internal cache of cache description objs */
35867 static struct kmem_cache cache_cache = {
35868 @@ -4428,10 +4428,12 @@ static const struct file_operations proc
35870 static int __init slab_proc_init(void)
35872 +#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
35873 proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
35874 #ifdef CONFIG_DEBUG_SLAB_LEAK
35875 proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
35880 module_init(slab_proc_init);
35881 diff -urNp linux-2.6.29/mm/slub.c linux-2.6.29/mm/slub.c
35882 --- linux-2.6.29/mm/slub.c 2009-03-23 19:12:14.000000000 -0400
35883 +++ linux-2.6.29/mm/slub.c 2009-03-28 14:26:20.000000000 -0400
35884 @@ -2319,7 +2319,7 @@ static int kmem_cache_open(struct kmem_c
35885 if (!calculate_sizes(s, -1))
35889 + atomic_set(&s->refcount, 1);
35891 s->remote_node_defrag_ratio = 1000;
35893 @@ -2456,8 +2456,7 @@ static inline int kmem_cache_close(struc
35894 void kmem_cache_destroy(struct kmem_cache *s)
35896 down_write(&slub_lock);
35898 - if (!s->refcount) {
35899 + if (atomic_dec_and_test(&s->refcount)) {
35900 list_del(&s->list);
35901 up_write(&slub_lock);
35902 if (kmem_cache_close(s)) {
35903 @@ -2967,7 +2966,7 @@ void __init kmem_cache_init(void)
35905 create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node",
35906 sizeof(struct kmem_cache_node), GFP_KERNEL);
35907 - kmalloc_caches[0].refcount = -1;
35908 + atomic_set(&kmalloc_caches[0].refcount, -1);
35911 hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI);
35912 @@ -3057,7 +3056,7 @@ static int slab_unmergeable(struct kmem_
35914 * We may have set a slab to be unmergeable during bootstrap.
35916 - if (s->refcount < 0)
35917 + if (atomic_read(&s->refcount) < 0)
35921 @@ -3114,7 +3113,7 @@ struct kmem_cache *kmem_cache_create(con
35926 + atomic_inc(&s->refcount);
35928 * Adjust the object sizes so that we clear
35929 * the complete object on kzalloc.
35930 @@ -3133,7 +3132,7 @@ struct kmem_cache *kmem_cache_create(con
35932 if (sysfs_slab_alias(s, name)) {
35933 down_write(&slub_lock);
35935 + atomic_dec(&s->refcount);
35936 up_write(&slub_lock);
35939 @@ -3849,7 +3848,7 @@ SLAB_ATTR_RO(ctor);
35941 static ssize_t aliases_show(struct kmem_cache *s, char *buf)
35943 - return sprintf(buf, "%d\n", s->refcount - 1);
35944 + return sprintf(buf, "%d\n", atomic_read(&s->refcount) - 1);
35946 SLAB_ATTR_RO(aliases);
35948 @@ -4527,7 +4526,9 @@ static const struct file_operations proc
35950 static int __init slab_proc_init(void)
35952 +#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
35953 proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
35957 module_init(slab_proc_init);
35958 diff -urNp linux-2.6.29/mm/util.c linux-2.6.29/mm/util.c
35959 --- linux-2.6.29/mm/util.c 2009-03-23 19:12:14.000000000 -0400
35960 +++ linux-2.6.29/mm/util.c 2009-03-28 14:26:20.000000000 -0400
35961 @@ -187,6 +187,12 @@ EXPORT_SYMBOL(strndup_user);
35962 void arch_pick_mmap_layout(struct mm_struct *mm)
35964 mm->mmap_base = TASK_UNMAPPED_BASE;
35966 +#ifdef CONFIG_PAX_RANDMMAP
35967 + if (mm->pax_flags & MF_PAX_RANDMMAP)
35968 + mm->mmap_base += mm->delta_mmap;
35971 mm->get_unmapped_area = arch_get_unmapped_area;
35972 mm->unmap_area = arch_unmap_area;
35974 diff -urNp linux-2.6.29/mm/vmalloc.c linux-2.6.29/mm/vmalloc.c
35975 --- linux-2.6.29/mm/vmalloc.c 2009-03-23 19:12:14.000000000 -0400
35976 +++ linux-2.6.29/mm/vmalloc.c 2009-03-28 14:26:20.000000000 -0400
35977 @@ -90,6 +90,11 @@ static int vmap_pte_range(pmd_t *pmd, un
35978 unsigned long end, pgprot_t prot, struct page **pages, int *nr)
35981 + int ret = -ENOMEM;
35983 +#ifdef CONFIG_PAX_KERNEXEC
35984 + unsigned long cr0;
35988 * nr is a running index into the array which helps higher level
35989 @@ -99,17 +104,33 @@ static int vmap_pte_range(pmd_t *pmd, un
35990 pte = pte_alloc_kernel(pmd, addr);
35994 +#ifdef CONFIG_PAX_KERNEXEC
35995 + pax_open_kernel(cr0);
35999 struct page *page = pages[*nr];
36001 - if (WARN_ON(!pte_none(*pte)))
36003 - if (WARN_ON(!page))
36005 + if (WARN_ON(!pte_none(*pte))) {
36009 + if (WARN_ON(!page)) {
36013 set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
36015 } while (pte++, addr += PAGE_SIZE, addr != end);
36020 +#ifdef CONFIG_PAX_KERNEXEC
36021 + pax_close_kernel(cr0);
36027 static int vmap_pmd_range(pud_t *pud, unsigned long addr,
36028 @@ -1056,6 +1077,16 @@ static struct vm_struct *__get_vm_area_n
36029 unsigned long align = 1;
36031 BUG_ON(in_interrupt());
36033 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
36034 + if (flags & VM_KERNEXEC) {
36035 + if (start != VMALLOC_START || end != VMALLOC_END)
36037 + start = (unsigned long)MODULES_VADDR;
36038 + end = (unsigned long)MODULES_END;
36042 if (flags & VM_IOREMAP) {
36043 int bit = fls(size);
36045 @@ -1289,6 +1320,11 @@ void *vmap(struct page **pages, unsigned
36046 if (count > num_physpages)
36049 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
36050 + if (!(pgprot_val(prot) & _PAGE_NX))
36051 + flags |= VM_KERNEXEC;
36054 area = get_vm_area_caller((count << PAGE_SHIFT), flags,
36055 __builtin_return_address(0));
36057 @@ -1385,6 +1421,13 @@ static void *__vmalloc_node(unsigned lon
36058 if (!size || (size >> PAGE_SHIFT) > num_physpages)
36061 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
36062 + if (!(pgprot_val(prot) & _PAGE_NX))
36063 + area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
36064 + node, gfp_mask, caller);
36068 area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
36069 node, gfp_mask, caller);
36071 @@ -1475,7 +1518,7 @@ EXPORT_SYMBOL(vmalloc_node);
36073 void *vmalloc_exec(unsigned long size)
36075 - return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
36076 + return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC,
36077 -1, __builtin_return_address(0));
36080 diff -urNp linux-2.6.29/net/bridge/br_stp_if.c linux-2.6.29/net/bridge/br_stp_if.c
36081 --- linux-2.6.29/net/bridge/br_stp_if.c 2009-03-23 19:12:14.000000000 -0400
36082 +++ linux-2.6.29/net/bridge/br_stp_if.c 2009-03-28 14:26:20.000000000 -0400
36083 @@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg
36084 char *envp[] = { NULL };
36086 if (br->stp_enabled == BR_USER_STP) {
36087 - r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
36088 + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
36089 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
36092 diff -urNp linux-2.6.29/net/core/flow.c linux-2.6.29/net/core/flow.c
36093 --- linux-2.6.29/net/core/flow.c 2009-03-23 19:12:14.000000000 -0400
36094 +++ linux-2.6.29/net/core/flow.c 2009-03-28 14:26:20.000000000 -0400
36095 @@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
36097 static u32 flow_hash_shift;
36098 #define flow_hash_size (1 << flow_hash_shift)
36099 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
36100 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
36102 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
36104 @@ -52,7 +52,7 @@ struct flow_percpu_info {
36108 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
36109 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
36111 #define flow_hash_rnd_recalc(cpu) \
36112 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
36113 @@ -69,7 +69,7 @@ struct flow_flush_info {
36115 struct completion completion;
36117 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
36118 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
36120 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
36122 diff -urNp linux-2.6.29/net/dccp/ccids/ccid3.c linux-2.6.29/net/dccp/ccids/ccid3.c
36123 --- linux-2.6.29/net/dccp/ccids/ccid3.c 2009-03-23 19:12:14.000000000 -0400
36124 +++ linux-2.6.29/net/dccp/ccids/ccid3.c 2009-03-28 14:26:20.000000000 -0400
36126 static int ccid3_debug;
36127 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
36129 -#define ccid3_pr_debug(format, a...)
36130 +#define ccid3_pr_debug(format, a...) do {} while (0)
36134 diff -urNp linux-2.6.29/net/dccp/dccp.h linux-2.6.29/net/dccp/dccp.h
36135 --- linux-2.6.29/net/dccp/dccp.h 2009-03-23 19:12:14.000000000 -0400
36136 +++ linux-2.6.29/net/dccp/dccp.h 2009-03-28 14:26:20.000000000 -0400
36137 @@ -43,8 +43,8 @@ extern int dccp_debug;
36138 #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
36139 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
36141 -#define dccp_pr_debug(format, a...)
36142 -#define dccp_pr_debug_cat(format, a...)
36143 +#define dccp_pr_debug(format, a...) do {} while (0)
36144 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
36147 extern struct inet_hashinfo dccp_hashinfo;
36148 diff -urNp linux-2.6.29/net/ipv4/inet_connection_sock.c linux-2.6.29/net/ipv4/inet_connection_sock.c
36149 --- linux-2.6.29/net/ipv4/inet_connection_sock.c 2009-03-23 19:12:14.000000000 -0400
36150 +++ linux-2.6.29/net/ipv4/inet_connection_sock.c 2009-03-28 14:26:20.000000000 -0400
36153 #include <linux/module.h>
36154 #include <linux/jhash.h>
36155 +#include <linux/security.h>
36157 #include <net/inet_connection_sock.h>
36158 #include <net/inet_hashtables.h>
36159 diff -urNp linux-2.6.29/net/ipv4/inet_hashtables.c linux-2.6.29/net/ipv4/inet_hashtables.c
36160 --- linux-2.6.29/net/ipv4/inet_hashtables.c 2009-03-23 19:12:14.000000000 -0400
36161 +++ linux-2.6.29/net/ipv4/inet_hashtables.c 2009-03-28 14:26:20.000000000 -0400
36162 @@ -18,11 +18,14 @@
36163 #include <linux/slab.h>
36164 #include <linux/wait.h>
36165 +#include <linux/security.h>
36167 #include <net/inet_connection_sock.h>
36168 #include <net/inet_hashtables.h>
36169 #include <net/route.h>
36170 #include <net/ip.h>
36172 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
36175 * Allocate and initialize a new local port bind bucket.
36176 * The bindhash mutex for snum's hash chain must be held here.
36177 @@ -481,6 +484,8 @@ ok:
36179 spin_unlock(&head->lock);
36181 + gr_update_task_in_ip_table(current, inet_sk(sk));
36184 inet_twsk_deschedule(tw, death_row);
36186 diff -urNp linux-2.6.29/net/ipv4/netfilter/ipt_stealth.c linux-2.6.29/net/ipv4/netfilter/ipt_stealth.c
36187 --- linux-2.6.29/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
36188 +++ linux-2.6.29/net/ipv4/netfilter/ipt_stealth.c 2009-03-28 14:26:20.000000000 -0400
36190 +/* Kernel module to add stealth support.
36192 + * Copyright (C) 2002-2006 Brad Spengler <spender@grsecurity.net>
36196 +#include <linux/kernel.h>
36197 +#include <linux/module.h>
36198 +#include <linux/skbuff.h>
36199 +#include <linux/net.h>
36200 +#include <linux/sched.h>
36201 +#include <linux/inet.h>
36202 +#include <linux/stddef.h>
36204 +#include <net/ip.h>
36205 +#include <net/sock.h>
36206 +#include <net/tcp.h>
36207 +#include <net/udp.h>
36208 +#include <net/route.h>
36209 +#include <net/inet_common.h>
36211 +#include <linux/netfilter_ipv4/ip_tables.h>
36213 +MODULE_LICENSE("GPL");
36216 +match(const struct sk_buff *skb, const struct xt_match_param *par)
36218 + struct iphdr *ip = ip_hdr(skb);
36219 + struct tcphdr th;
36220 + struct udphdr uh;
36221 + struct sock *sk = NULL;
36223 + if (!ip || par->fragoff) return false;
36225 + switch(ip->protocol) {
36226 + case IPPROTO_TCP:
36227 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
36228 + *(par->hotdrop) = true;
36231 + if (!(th.syn && !th.ack)) return false;
36232 + sk = inet_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
36234 + case IPPROTO_UDP:
36235 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
36236 + *(par->hotdrop) = true;
36239 + sk = udp4_lib_lookup(dev_net(skb->dev), ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
36245 + if(!sk) // port is being listened on, match this
36253 +/* Called when user tries to insert an entry of this type. */
36255 +checkentry(const struct xt_mtchk_param *par)
36257 + const struct ipt_ip *ip = par->entryinfo;
36259 + if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
36260 + ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
36261 + && (par->hook_mask & (1 << NF_INET_LOCAL_IN)))
36264 + printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
36270 +static struct xt_match stealth_match __read_mostly = {
36271 + .name = "stealth",
36272 + .family = NFPROTO_IPV4,
36274 + .checkentry = checkentry,
36276 + .me = THIS_MODULE
36279 +static int __init init(void)
36281 + return xt_register_match(&stealth_match);
36284 +static void __exit fini(void)
36286 + xt_unregister_match(&stealth_match);
36289 +module_init(init);
36290 +module_exit(fini);
36291 diff -urNp linux-2.6.29/net/ipv4/netfilter/Kconfig linux-2.6.29/net/ipv4/netfilter/Kconfig
36292 --- linux-2.6.29/net/ipv4/netfilter/Kconfig 2009-03-23 19:12:14.000000000 -0400
36293 +++ linux-2.6.29/net/ipv4/netfilter/Kconfig 2009-03-28 14:26:20.000000000 -0400
36294 @@ -101,6 +101,21 @@ config IP_NF_MATCH_TTL
36296 To compile it as a module, choose M here. If unsure, say N.
36298 +config IP_NF_MATCH_STEALTH
36299 + tristate "stealth match support"
36300 + depends on IP_NF_IPTABLES
36302 + Enabling this option will drop all syn packets coming to unserved tcp
36303 + ports as well as all packets coming to unserved udp ports. If you
36304 + are using your system to route any type of packets (ie. via NAT)
36305 + you should put this module at the end of your ruleset, since it will
36306 + drop packets that aren't going to ports that are listening on your
36307 + machine itself, it doesn't take into account that the packet might be
36308 + destined for someone on your internal network if you're using NAT for
36311 + To compile it as a module, choose M here. If unsure, say N.
36313 # `filter', generic and specific targets
36314 config IP_NF_FILTER
36315 tristate "Packet filtering"
36316 diff -urNp linux-2.6.29/net/ipv4/netfilter/Makefile linux-2.6.29/net/ipv4/netfilter/Makefile
36317 --- linux-2.6.29/net/ipv4/netfilter/Makefile 2009-03-23 19:12:14.000000000 -0400
36318 +++ linux-2.6.29/net/ipv4/netfilter/Makefile 2009-03-28 14:26:20.000000000 -0400
36319 @@ -61,6 +61,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
36320 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
36321 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
36322 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
36323 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
36324 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
36325 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
36327 diff -urNp linux-2.6.29/net/ipv4/tcp_ipv4.c linux-2.6.29/net/ipv4/tcp_ipv4.c
36328 --- linux-2.6.29/net/ipv4/tcp_ipv4.c 2009-03-23 19:12:14.000000000 -0400
36329 +++ linux-2.6.29/net/ipv4/tcp_ipv4.c 2009-03-28 14:26:20.000000000 -0400
36331 #include <linux/fcntl.h>
36332 #include <linux/module.h>
36333 #include <linux/random.h>
36334 +#include <linux/security.h>
36335 #include <linux/cache.h>
36336 #include <linux/jhash.h>
36337 #include <linux/init.h>
36338 diff -urNp linux-2.6.29/net/ipv4/udp.c linux-2.6.29/net/ipv4/udp.c
36339 --- linux-2.6.29/net/ipv4/udp.c 2009-03-23 19:12:14.000000000 -0400
36340 +++ linux-2.6.29/net/ipv4/udp.c 2009-03-28 14:26:20.000000000 -0400
36342 #include <linux/types.h>
36343 #include <linux/fcntl.h>
36344 #include <linux/module.h>
36345 +#include <linux/security.h>
36346 #include <linux/socket.h>
36347 #include <linux/sockios.h>
36348 #include <linux/igmp.h>
36349 @@ -369,6 +370,9 @@ found:
36353 +extern int gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb);
36354 +extern int gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr);
36357 * This routine is called by the ICMP module when it gets some
36358 * sort of error condition. If err < 0 then the socket should
36359 @@ -630,9 +634,18 @@ int udp_sendmsg(struct kiocb *iocb, stru
36360 dport = usin->sin_port;
36364 + err = gr_search_udp_sendmsg(sk, usin);
36368 if (sk->sk_state != TCP_ESTABLISHED)
36369 return -EDESTADDRREQ;
36371 + err = gr_search_udp_sendmsg(sk, NULL);
36375 daddr = inet->daddr;
36376 dport = inet->dport;
36377 /* Open fast path for connected socket.
36378 @@ -898,6 +911,10 @@ try_again:
36382 + err = gr_search_udp_recvmsg(sk, skb);
36386 ulen = skb->len - sizeof(struct udphdr);
36389 diff -urNp linux-2.6.29/net/ipv6/exthdrs.c linux-2.6.29/net/ipv6/exthdrs.c
36390 --- linux-2.6.29/net/ipv6/exthdrs.c 2009-03-23 19:12:14.000000000 -0400
36391 +++ linux-2.6.29/net/ipv6/exthdrs.c 2009-03-28 14:26:20.000000000 -0400
36392 @@ -630,7 +630,7 @@ static struct tlvtype_proc tlvprochopopt
36393 .type = IPV6_TLV_JUMBO,
36394 .func = ipv6_hop_jumbo,
36400 int ipv6_parse_hopopts(struct sk_buff *skb)
36401 diff -urNp linux-2.6.29/net/ipv6/raw.c linux-2.6.29/net/ipv6/raw.c
36402 --- linux-2.6.29/net/ipv6/raw.c 2009-03-23 19:12:14.000000000 -0400
36403 +++ linux-2.6.29/net/ipv6/raw.c 2009-03-28 14:26:20.000000000 -0400
36404 @@ -600,7 +600,7 @@ out:
36408 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
36409 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
36410 struct flowi *fl, struct rt6_info *rt,
36411 unsigned int flags)
36413 diff -urNp linux-2.6.29/net/sctp/socket.c linux-2.6.29/net/sctp/socket.c
36414 --- linux-2.6.29/net/sctp/socket.c 2009-03-23 19:12:14.000000000 -0400
36415 +++ linux-2.6.29/net/sctp/socket.c 2009-03-28 14:26:20.000000000 -0400
36416 @@ -1434,7 +1434,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
36417 struct sctp_sndrcvinfo *sinfo;
36418 struct sctp_initmsg *sinit;
36419 sctp_assoc_t associd = 0;
36420 - sctp_cmsgs_t cmsgs = { NULL };
36421 + sctp_cmsgs_t cmsgs = { NULL, NULL };
36423 sctp_scope_t scope;
36425 @@ -5756,7 +5756,6 @@ pp_found:
36427 int reuse = sk->sk_reuse;
36429 - struct hlist_node *node;
36431 SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
36432 if (pp->fastreuse && sk->sk_reuse &&
36433 diff -urNp linux-2.6.29/net/socket.c linux-2.6.29/net/socket.c
36434 --- linux-2.6.29/net/socket.c 2009-03-23 19:12:14.000000000 -0400
36435 +++ linux-2.6.29/net/socket.c 2009-03-28 14:26:20.000000000 -0400
36437 #include <linux/audit.h>
36438 #include <linux/wireless.h>
36439 #include <linux/nsproxy.h>
36440 +#include <linux/in.h>
36442 #include <asm/uaccess.h>
36443 #include <asm/unistd.h>
36445 #include <net/sock.h>
36446 #include <linux/netfilter.h>
36448 +extern void gr_attach_curr_ip(const struct sock *sk);
36449 +extern int gr_handle_sock_all(const int family, const int type,
36450 + const int protocol);
36451 +extern int gr_handle_sock_server(const struct sockaddr *sck);
36452 +extern int gr_handle_sock_server_other(const struct socket *sck);
36453 +extern int gr_handle_sock_client(const struct sockaddr *sck);
36454 +extern int gr_search_connect(struct socket * sock,
36455 + struct sockaddr_in * addr);
36456 +extern int gr_search_bind(struct socket * sock,
36457 + struct sockaddr_in * addr);
36458 +extern int gr_search_listen(struct socket * sock);
36459 +extern int gr_search_accept(struct socket * sock);
36460 +extern int gr_search_socket(const int domain, const int type,
36461 + const int protocol);
36463 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
36464 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
36465 unsigned long nr_segs, loff_t pos);
36466 @@ -299,7 +315,7 @@ static int sockfs_get_sb(struct file_sys
36470 -static struct vfsmount *sock_mnt __read_mostly;
36471 +struct vfsmount *sock_mnt __read_mostly;
36473 static struct file_system_type sock_fs_type = {
36475 @@ -1234,6 +1250,16 @@ SYSCALL_DEFINE3(socket, int, family, int
36476 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
36477 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
36479 + if(!gr_search_socket(family, type, protocol)) {
36480 + retval = -EACCES;
36484 + if (gr_handle_sock_all(family, type, protocol)) {
36485 + retval = -EACCES;
36489 retval = sock_create(family, type, protocol, &sock);
36492 @@ -1366,6 +1392,14 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
36494 err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
36496 + if (gr_handle_sock_server((struct sockaddr *)&address)) {
36500 + err = gr_search_bind(sock, (struct sockaddr_in *)&address);
36504 err = security_socket_bind(sock,
36505 (struct sockaddr *)&address,
36507 @@ -1374,6 +1408,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
36508 (struct sockaddr *)
36509 &address, addrlen);
36512 fput_light(sock->file, fput_needed);
36515 @@ -1397,10 +1432,20 @@ SYSCALL_DEFINE2(listen, int, fd, int, ba
36516 if ((unsigned)backlog > somaxconn)
36517 backlog = somaxconn;
36519 + if (gr_handle_sock_server_other(sock)) {
36524 + err = gr_search_listen(sock);
36528 err = security_socket_listen(sock, backlog);
36530 err = sock->ops->listen(sock, backlog);
36533 fput_light(sock->file, fput_needed);
36536 @@ -1443,6 +1488,18 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
36537 newsock->type = sock->type;
36538 newsock->ops = sock->ops;
36540 + if (gr_handle_sock_server_other(sock)) {
36542 + sock_release(newsock);
36546 + err = gr_search_accept(sock);
36548 + sock_release(newsock);
36553 * We don't need try_module_get here, as the listening socket (sock)
36554 * has the protocol module (sock->ops->owner) held.
36555 @@ -1486,6 +1543,7 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
36558 security_socket_post_accept(sock, newsock);
36559 + gr_attach_curr_ip(newsock->sk);
36562 fput_light(sock->file, fput_needed);
36563 @@ -1524,6 +1582,7 @@ SYSCALL_DEFINE3(connect, int, fd, struct
36566 struct socket *sock;
36567 + struct sockaddr *sck;
36568 struct sockaddr_storage address;
36569 int err, fput_needed;
36571 @@ -1534,6 +1593,17 @@ SYSCALL_DEFINE3(connect, int, fd, struct
36575 + sck = (struct sockaddr *)&address;
36577 + if (gr_handle_sock_client(sck)) {
36582 + err = gr_search_connect(sock, (struct sockaddr_in *)sck);
36587 security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
36589 diff -urNp linux-2.6.29/net/unix/af_unix.c linux-2.6.29/net/unix/af_unix.c
36590 --- linux-2.6.29/net/unix/af_unix.c 2009-03-23 19:12:14.000000000 -0400
36591 +++ linux-2.6.29/net/unix/af_unix.c 2009-03-28 14:26:20.000000000 -0400
36592 @@ -734,6 +734,12 @@ static struct sock *unix_find_other(stru
36593 err = -ECONNREFUSED;
36594 if (!S_ISSOCK(inode->i_mode))
36597 + if (!gr_acl_handle_unix(path.dentry, path.mnt)) {
36602 u = unix_find_socket_byinode(net, inode);
36605 @@ -754,6 +760,13 @@ static struct sock *unix_find_other(stru
36607 struct dentry *dentry;
36608 dentry = unix_sk(u)->dentry;
36610 + if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
36617 touch_atime(unix_sk(u)->mnt, dentry);
36619 @@ -839,11 +852,18 @@ static int unix_bind(struct socket *sock
36620 err = security_path_mknod(&nd.path, dentry, mode, 0);
36622 goto out_mknod_drop_write;
36623 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
36625 + goto out_mknod_drop_write;
36627 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
36628 out_mknod_drop_write:
36629 mnt_drop_write(nd.path.mnt);
36631 goto out_mknod_dput;
36633 + gr_handle_create(dentry, nd.path.mnt);
36635 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
36636 dput(nd.path.dentry);
36637 nd.path.dentry = dentry;
36638 @@ -861,6 +881,10 @@ out_mknod_drop_write:
36642 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
36643 + sk->sk_peercred.pid = current->pid;
36646 list = &unix_socket_table[addr->hash];
36648 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
36649 diff -urNp linux-2.6.29/scripts/mod/modpost.c linux-2.6.29/scripts/mod/modpost.c
36650 --- linux-2.6.29/scripts/mod/modpost.c 2009-03-23 19:12:14.000000000 -0400
36651 +++ linux-2.6.29/scripts/mod/modpost.c 2009-03-28 14:26:20.000000000 -0400
36652 @@ -830,6 +830,7 @@ enum mismatch {
36655 EXPORT_TO_INIT_EXIT,
36659 struct sectioncheck {
36660 @@ -891,6 +892,12 @@ const struct sectioncheck sectioncheck[]
36661 .fromsec = { "__ksymtab*", NULL },
36662 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
36663 .mismatch = EXPORT_TO_INIT_EXIT
36665 +/* Do not reference code from writable data */
36667 + .fromsec = { DATA_SECTIONS, NULL },
36668 + .tosec = { TEXT_SECTIONS, NULL },
36669 + .mismatch = DATA_TO_TEXT
36673 @@ -1249,6 +1256,14 @@ static void report_sec_mismatch(const ch
36674 "Fix this by removing the %sannotation of %s "
36675 "or drop the export.\n",
36676 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
36677 + case DATA_TO_TEXT:
36680 + "The variable %s references\n"
36681 + "the %s %s%s%s\n"
36682 + fromsym, to, sec2annotation(tosec), tosym, to_p);
36686 /* To get warnings on missing members */
36688 diff -urNp linux-2.6.29/scripts/pnmtologo.c linux-2.6.29/scripts/pnmtologo.c
36689 --- linux-2.6.29/scripts/pnmtologo.c 2009-03-23 19:12:14.000000000 -0400
36690 +++ linux-2.6.29/scripts/pnmtologo.c 2009-03-28 14:26:20.000000000 -0400
36691 @@ -237,14 +237,14 @@ static void write_header(void)
36692 fprintf(out, " * Linux logo %s\n", logoname);
36693 fputs(" */\n\n", out);
36694 fputs("#include <linux/linux_logo.h>\n\n", out);
36695 - fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
36696 + fprintf(out, "static unsigned char %s_data[] = {\n",
36700 static void write_footer(void)
36702 fputs("\n};\n\n", out);
36703 - fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
36704 + fprintf(out, "struct linux_logo %s = {\n", logoname);
36705 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
36706 fprintf(out, " .width\t= %d,\n", logo_width);
36707 fprintf(out, " .height\t= %d,\n", logo_height);
36708 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
36709 fputs("\n};\n\n", out);
36711 /* write logo clut */
36712 - fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
36713 + fprintf(out, "static unsigned char %s_clut[] = {\n",
36716 for (i = 0; i < logo_clutsize; i++) {
36717 diff -urNp linux-2.6.29/security/commoncap.c linux-2.6.29/security/commoncap.c
36718 --- linux-2.6.29/security/commoncap.c 2009-03-23 19:12:14.000000000 -0400
36719 +++ linux-2.6.29/security/commoncap.c 2009-03-28 14:26:20.000000000 -0400
36721 #include <linux/prctl.h>
36722 #include <linux/securebits.h>
36724 +extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
36726 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
36728 - NETLINK_CB(skb).eff_cap = vx_mbcaps(current_cap());
36729 + NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
36733 diff -urNp linux-2.6.29/security/Kconfig linux-2.6.29/security/Kconfig
36734 --- linux-2.6.29/security/Kconfig 2009-03-23 19:12:14.000000000 -0400
36735 +++ linux-2.6.29/security/Kconfig 2009-03-28 14:26:20.000000000 -0400
36738 menu "Security options"
36740 +source grsecurity/Kconfig
36745 + bool "Enable various PaX features"
36746 + depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
36748 + This allows you to enable various PaX features. PaX adds
36749 + intrusion prevention mechanisms to the kernel that reduce
36750 + the risks posed by exploitable memory corruption bugs.
36752 +menu "PaX Control"
36755 +config PAX_SOFTMODE
36756 + bool 'Support soft mode'
36758 + Enabling this option will allow you to run PaX in soft mode, that
36759 + is, PaX features will not be enforced by default, only on executables
36760 + marked explicitly. You must also enable PT_PAX_FLAGS support as it
36761 + is the only way to mark executables for soft mode use.
36763 + Soft mode can be activated by using the "pax_softmode=1" kernel command
36764 + line option on boot. Furthermore you can control various PaX features
36765 + at runtime via the entries in /proc/sys/kernel/pax.
36768 + bool 'Use legacy ELF header marking'
36770 + Enabling this option will allow you to control PaX features on
36771 + a per executable basis via the 'chpax' utility available at
36772 + http://pax.grsecurity.net/. The control flags will be read from
36773 + an otherwise reserved part of the ELF header. This marking has
36774 + numerous drawbacks (no support for soft-mode, toolchain does not
36775 + know about the non-standard use of the ELF header) therefore it
36776 + has been deprecated in favour of PT_PAX_FLAGS support.
36778 + If you have applications not marked by the PT_PAX_FLAGS ELF
36779 + program header then you MUST enable this option otherwise they
36780 + will not get any protection.
36782 + Note that if you enable PT_PAX_FLAGS marking support as well,
36783 + the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
36785 +config PAX_PT_PAX_FLAGS
36786 + bool 'Use ELF program header marking'
36788 + Enabling this option will allow you to control PaX features on
36789 + a per executable basis via the 'paxctl' utility available at
36790 + http://pax.grsecurity.net/. The control flags will be read from
36791 + a PaX specific ELF program header (PT_PAX_FLAGS). This marking
36792 + has the benefits of supporting both soft mode and being fully
36793 + integrated into the toolchain (the binutils patch is available
36794 + from http://pax.grsecurity.net).
36796 + If you have applications not marked by the PT_PAX_FLAGS ELF
36797 + program header then you MUST enable the EI_PAX marking support
36798 + otherwise they will not get any protection.
36800 + Note that if you enable the legacy EI_PAX marking support as well,
36801 + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
36804 + prompt 'MAC system integration'
36805 + default PAX_HAVE_ACL_FLAGS
36807 + Mandatory Access Control systems have the option of controlling
36808 + PaX flags on a per executable basis, choose the method supported
36809 + by your particular system.
36811 + - "none": if your MAC system does not interact with PaX,
36812 + - "direct": if your MAC system defines pax_set_initial_flags() itself,
36813 + - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
36815 + NOTE: this option is for developers/integrators only.
36817 + config PAX_NO_ACL_FLAGS
36820 + config PAX_HAVE_ACL_FLAGS
36823 + config PAX_HOOK_ACL_FLAGS
36829 +menu "Non-executable pages"
36833 + bool "Enforce non-executable pages"
36834 + 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)
36836 + By design some architectures do not allow for protecting memory
36837 + pages against execution or even if they do, Linux does not make
36838 + use of this feature. In practice this means that if a page is
36839 + readable (such as the stack or heap) it is also executable.
36841 + There is a well known exploit technique that makes use of this
36842 + fact and a common programming mistake where an attacker can
36843 + introduce code of his choice somewhere in the attacked program's
36844 + memory (typically the stack or the heap) and then execute it.
36846 + If the attacked program was running with different (typically
36847 + higher) privileges than that of the attacker, then he can elevate
36848 + his own privilege level (e.g. get a root shell, write to files for
36849 + which he does not have write access to, etc).
36851 + Enabling this option will let you choose from various features
36852 + that prevent the injection and execution of 'foreign' code in
36855 + This will also break programs that rely on the old behaviour and
36856 + expect that dynamically allocated memory via the malloc() family
36857 + of functions is executable (which it is not). Notable examples
36858 + are the XFree86 4.x server, the java runtime and wine.
36860 +config PAX_PAGEEXEC
36861 + bool "Paging based non-executable pages"
36862 + 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)
36864 + This implementation is based on the paging feature of the CPU.
36865 + On i386 without hardware non-executable bit support there is a
36866 + variable but usually low performance impact, however on Intel's
36867 + P4 core based CPUs it is very high so you should not enable this
36868 + for kernels meant to be used on such CPUs.
36870 + On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
36871 + with hardware non-executable bit support there is no performance
36872 + impact, on ppc the impact is negligible.
36874 + Note that several architectures require various emulations due to
36875 + badly designed userland ABIs, this will cause a performance impact
36876 + but will disappear as soon as userland is fixed (e.g., ppc users
36877 + can make use of the secure-plt feature found in binutils).
36879 +config PAX_SEGMEXEC
36880 + bool "Segmentation based non-executable pages"
36881 + depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
36883 + This implementation is based on the segmentation feature of the
36884 + CPU and has a very small performance impact, however applications
36885 + will be limited to a 1.5 GB address space instead of the normal
36888 +config PAX_EMUTRAMP
36889 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
36890 + default y if PARISC || PPC32
36892 + There are some programs and libraries that for one reason or
36893 + another attempt to execute special small code snippets from
36894 + non-executable memory pages. Most notable examples are the
36895 + signal handler return code generated by the kernel itself and
36896 + the GCC trampolines.
36898 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
36899 + such programs will no longer work under your kernel.
36901 + As a remedy you can say Y here and use the 'chpax' or 'paxctl'
36902 + utilities to enable trampoline emulation for the affected programs
36903 + yet still have the protection provided by the non-executable pages.
36905 + On parisc and ppc you MUST enable this option and EMUSIGRT as
36906 + well, otherwise your system will not even boot.
36908 + Alternatively you can say N here and use the 'chpax' or 'paxctl'
36909 + utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
36910 + for the affected files.
36912 + NOTE: enabling this feature *may* open up a loophole in the
36913 + protection provided by non-executable pages that an attacker
36914 + could abuse. Therefore the best solution is to not have any
36915 + files on your system that would require this option. This can
36916 + be achieved by not using libc5 (which relies on the kernel
36917 + signal handler return code) and not using or rewriting programs
36918 + that make use of the nested function implementation of GCC.
36919 + Skilled users can just fix GCC itself so that it implements
36920 + nested function calls in a way that does not interfere with PaX.
36922 +config PAX_EMUSIGRT
36923 + bool "Automatically emulate sigreturn trampolines"
36924 + depends on PAX_EMUTRAMP && (PARISC || PPC32)
36927 + Enabling this option will have the kernel automatically detect
36928 + and emulate signal return trampolines executing on the stack
36929 + that would otherwise lead to task termination.
36931 + This solution is intended as a temporary one for users with
36932 + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
36933 + Modula-3 runtime, etc) or executables linked to such, basically
36934 + everything that does not specify its own SA_RESTORER function in
36935 + normal executable memory like glibc 2.1+ does.
36937 + On parisc and ppc you MUST enable this option, otherwise your
36938 + system will not even boot.
36940 + NOTE: this feature cannot be disabled on a per executable basis
36941 + and since it *does* open up a loophole in the protection provided
36942 + by non-executable pages, the best solution is to not have any
36943 + files on your system that would require this option.
36945 +config PAX_MPROTECT
36946 + bool "Restrict mprotect()"
36947 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
36949 + Enabling this option will prevent programs from
36950 + - changing the executable status of memory pages that were
36951 + not originally created as executable,
36952 + - making read-only executable pages writable again,
36953 + - creating executable pages from anonymous memory.
36955 + You should say Y here to complete the protection provided by
36956 + the enforcement of non-executable pages.
36958 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36959 + this feature on a per file basis.
36961 +config PAX_NOELFRELOCS
36962 + bool "Disallow ELF text relocations"
36963 + depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
36965 + Non-executable pages and mprotect() restrictions are effective
36966 + in preventing the introduction of new executable code into an
36967 + attacked task's address space. There remain only two venues
36968 + for this kind of attack: if the attacker can execute already
36969 + existing code in the attacked task then he can either have it
36970 + create and mmap() a file containing his code or have it mmap()
36971 + an already existing ELF library that does not have position
36972 + independent code in it and use mprotect() on it to make it
36973 + writable and copy his code there. While protecting against
36974 + the former approach is beyond PaX, the latter can be prevented
36975 + by having only PIC ELF libraries on one's system (which do not
36976 + need to relocate their code). If you are sure this is your case,
36977 + then enable this option otherwise be careful as you may not even
36978 + be able to boot or log on your system (for example, some PAM
36979 + modules are erroneously compiled as non-PIC by default).
36981 + NOTE: if you are using dynamic ELF executables (as suggested
36982 + when using ASLR) then you must have made sure that you linked
36983 + your files using the PIC version of crt1 (the et_dyn.tar.gz package
36984 + referenced there has already been updated to support this).
36986 +config PAX_ETEXECRELOCS
36987 + bool "Allow ELF ET_EXEC text relocations"
36988 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
36991 + On some architectures there are incorrectly created applications
36992 + that require text relocations and would not work without enabling
36993 + this option. If you are an alpha, ia64 or parisc user, you should
36994 + enable this option and disable it once you have made sure that
36995 + none of your applications need it.
36998 + bool "Automatically emulate ELF PLT"
36999 + depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
37002 + Enabling this option will have the kernel automatically detect
37003 + and emulate the Procedure Linkage Table entries in ELF files.
37004 + On some architectures such entries are in writable memory, and
37005 + become non-executable leading to task termination. Therefore
37006 + it is mandatory that you enable this option on alpha, parisc,
37007 + ppc (if secure-plt is not used throughout in userland), sparc
37008 + and sparc64, otherwise your system would not even boot.
37010 + NOTE: this feature *does* open up a loophole in the protection
37011 + provided by the non-executable pages, therefore the proper
37012 + solution is to modify the toolchain to produce a PLT that does
37013 + not need to be writable.
37015 +config PAX_DLRESOLVE
37017 + depends on PAX_EMUPLT && (SPARC32 || SPARC64)
37020 +config PAX_SYSCALL
37022 + depends on PAX_PAGEEXEC && PPC32
37025 +config PAX_KERNEXEC
37026 + bool "Enforce non-executable kernel pages"
37027 + depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
37029 + This is the kernel land equivalent of PAGEEXEC and MPROTECT,
37030 + that is, enabling this option will make it harder to inject
37031 + and execute 'foreign' code in kernel memory itself.
37035 +menu "Address Space Layout Randomization"
37039 + bool "Address Space Layout Randomization"
37040 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
37042 + Many if not most exploit techniques rely on the knowledge of
37043 + certain addresses in the attacked program. The following options
37044 + will allow the kernel to apply a certain amount of randomization
37045 + to specific parts of the program thereby forcing an attacker to
37046 + guess them in most cases. Any failed guess will most likely crash
37047 + the attacked program which allows the kernel to detect such attempts
37048 + and react on them. PaX itself provides no reaction mechanisms,
37049 + instead it is strongly encouraged that you make use of Nergal's
37050 + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
37051 + (http://www.grsecurity.net/) built-in crash detection features or
37052 + develop one yourself.
37054 + By saying Y here you can choose to randomize the following areas:
37055 + - top of the task's kernel stack
37056 + - top of the task's userland stack
37057 + - base address for mmap() requests that do not specify one
37058 + (this includes all libraries)
37059 + - base address of the main executable
37061 + It is strongly recommended to say Y here as address space layout
37062 + randomization has negligible impact on performance yet it provides
37063 + a very effective protection.
37065 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
37066 + this feature on a per file basis.
37068 +config PAX_RANDKSTACK
37069 + bool "Randomize kernel stack base"
37070 + depends on PAX_ASLR && X86_TSC && X86_32
37072 + By saying Y here the kernel will randomize every task's kernel
37073 + stack on every system call. This will not only force an attacker
37074 + to guess it but also prevent him from making use of possible
37075 + leaked information about it.
37077 + Since the kernel stack is a rather scarce resource, randomization
37078 + may cause unexpected stack overflows, therefore you should very
37079 + carefully test your system. Note that once enabled in the kernel
37080 + configuration, this feature cannot be disabled on a per file basis.
37082 +config PAX_RANDUSTACK
37083 + bool "Randomize user stack base"
37084 + depends on PAX_ASLR
37086 + By saying Y here the kernel will randomize every task's userland
37087 + stack. The randomization is done in two steps where the second
37088 + one may apply a big amount of shift to the top of the stack and
37089 + cause problems for programs that want to use lots of memory (more
37090 + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
37091 + For this reason the second step can be controlled by 'chpax' or
37092 + 'paxctl' on a per file basis.
37094 +config PAX_RANDMMAP
37095 + bool "Randomize mmap() base"
37096 + depends on PAX_ASLR
37098 + By saying Y here the kernel will use a randomized base address for
37099 + mmap() requests that do not specify one themselves. As a result
37100 + all dynamically loaded libraries will appear at random addresses
37101 + and therefore be harder to exploit by a technique where an attacker
37102 + attempts to execute library code for his purposes (e.g. spawn a
37103 + shell from an exploited program that is running at an elevated
37104 + privilege level).
37106 + Furthermore, if a program is relinked as a dynamic ELF file, its
37107 + base address will be randomized as well, completing the full
37108 + randomization of the address space layout. Attacking such programs
37109 + becomes a guess game. You can find an example of doing this at
37110 + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
37111 + http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
37113 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
37114 + feature on a per file basis.
37118 +menu "Miscellaneous hardening features"
37120 +config PAX_MEMORY_SANITIZE
37121 + bool "Sanitize all freed memory"
37123 + By saying Y here the kernel will erase memory pages as soon as they
37124 + are freed. This in turn reduces the lifetime of data stored in the
37125 + pages, making it less likely that sensitive information such as
37126 + passwords, cryptographic secrets, etc stay in memory for too long.
37128 + This is especially useful for programs whose runtime is short, long
37129 + lived processes and the kernel itself benefit from this as long as
37130 + they operate on whole memory pages and ensure timely freeing of pages
37131 + that may hold sensitive information.
37133 + The tradeoff is performance impact, on a single CPU system kernel
37134 + compilation sees a 3% slowdown, other systems and workloads may vary
37135 + and you are advised to test this feature on your expected workload
37136 + before deploying it.
37138 + Note that this feature does not protect data stored in live pages,
37139 + e.g., process memory swapped to disk may stay there for a long time.
37141 +config PAX_MEMORY_UDEREF
37142 + bool "Prevent invalid userland pointer dereference"
37143 + depends on X86_32 && !COMPAT_VDSO && !UML_X86
37145 + By saying Y here the kernel will be prevented from dereferencing
37146 + userland pointers in contexts where the kernel expects only kernel
37147 + pointers. This is both a useful runtime debugging feature and a
37148 + security measure that prevents exploiting a class of kernel bugs.
37150 + The tradeoff is that some virtualization solutions may experience
37151 + a huge slowdown and therefore you should not enable this feature
37152 + for kernels meant to run in such environments. Whether a given VM
37153 + solution is affected or not is best determined by simply trying it
37154 + out, the performance impact will be obvious right on boot as this
37155 + mechanism engages from very early on. A good rule of thumb is that
37156 + VMs running on CPUs without hardware virtualization support (i.e.,
37157 + the majority of IA-32 CPUs) will likely experience the slowdown.
37159 +config PAX_REFCOUNT
37160 + bool "Prevent various kernel object reference counter overflows"
37163 + By saying Y here the kernel will detect and prevent overflowing
37164 + various (but not all) kinds of object reference counters. Such
37165 + overflows can normally occur due to bugs only and are often, if
37166 + not always, exploitable.
37168 + The tradeoff is that data structures protected by an overflowed
37169 + refcount will never be freed and therefore will leak memory. Note
37170 + that this leak also happens even without this protection but in
37171 + that case the overflow can eventually trigger the freeing of the
37172 + data structure while it is still being used elsewhere, resulting
37173 + in the exploitable situation that this feature prevents.
37175 + Since this has a negligible performance impact, you should enable
37182 bool "Enable access key retention support"
37184 diff -urNp linux-2.6.29/sound/core/oss/pcm_oss.c linux-2.6.29/sound/core/oss/pcm_oss.c
37185 --- linux-2.6.29/sound/core/oss/pcm_oss.c 2009-03-23 19:12:14.000000000 -0400
37186 +++ linux-2.6.29/sound/core/oss/pcm_oss.c 2009-03-28 14:26:20.000000000 -0400
37187 @@ -2929,8 +2929,8 @@ static void snd_pcm_oss_proc_done(struct
37190 #else /* !CONFIG_SND_VERBOSE_PROCFS */
37191 -#define snd_pcm_oss_proc_init(pcm)
37192 -#define snd_pcm_oss_proc_done(pcm)
37193 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
37194 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
37195 #endif /* CONFIG_SND_VERBOSE_PROCFS */
37198 diff -urNp linux-2.6.29/sound/core/seq/seq_lock.h linux-2.6.29/sound/core/seq/seq_lock.h
37199 --- linux-2.6.29/sound/core/seq/seq_lock.h 2009-03-23 19:12:14.000000000 -0400
37200 +++ linux-2.6.29/sound/core/seq/seq_lock.h 2009-03-28 14:26:20.000000000 -0400
37201 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
37202 #else /* SMP || CONFIG_SND_DEBUG */
37204 typedef spinlock_t snd_use_lock_t; /* dummy */
37205 -#define snd_use_lock_init(lockp) /**/
37206 -#define snd_use_lock_use(lockp) /**/
37207 -#define snd_use_lock_free(lockp) /**/
37208 -#define snd_use_lock_sync(lockp) /**/
37209 +#define snd_use_lock_init(lockp) do {} while (0)
37210 +#define snd_use_lock_use(lockp) do {} while (0)
37211 +#define snd_use_lock_free(lockp) do {} while (0)
37212 +#define snd_use_lock_sync(lockp) do {} while (0)
37214 #endif /* SMP || CONFIG_SND_DEBUG */
37216 diff -urNp linux-2.6.29/sound/pci/ac97/ac97_patch.c linux-2.6.29/sound/pci/ac97/ac97_patch.c
37217 --- linux-2.6.29/sound/pci/ac97/ac97_patch.c 2009-03-23 19:12:14.000000000 -0400
37218 +++ linux-2.6.29/sound/pci/ac97/ac97_patch.c 2009-03-28 14:26:20.000000000 -0400
37219 @@ -1498,7 +1498,7 @@ static const struct snd_ac97_res_table a
37220 { AC97_VIDEO, 0x9f1f },
37221 { AC97_AUX, 0x9f1f },
37222 { AC97_PCM, 0x9f1f },
37223 - { } /* terminator */
37224 + { 0, 0 } /* terminator */
37227 static int patch_ad1819(struct snd_ac97 * ac97)
37228 @@ -3873,7 +3873,7 @@ static struct snd_ac97_res_table lm4550_
37229 { AC97_AUX, 0x1f1f },
37230 { AC97_PCM, 0x1f1f },
37231 { AC97_REC_GAIN, 0x0f0f },
37232 - { } /* terminator */
37233 + { 0, 0 } /* terminator */
37236 static int patch_lm4550(struct snd_ac97 *ac97)
37237 diff -urNp linux-2.6.29/sound/pci/ens1370.c linux-2.6.29/sound/pci/ens1370.c
37238 --- linux-2.6.29/sound/pci/ens1370.c 2009-03-23 19:12:14.000000000 -0400
37239 +++ linux-2.6.29/sound/pci/ens1370.c 2009-03-28 14:26:20.000000000 -0400
37240 @@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
37241 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
37242 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
37245 + { 0, 0, 0, 0, 0, 0, 0 }
37248 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
37249 diff -urNp linux-2.6.29/sound/pci/intel8x0.c linux-2.6.29/sound/pci/intel8x0.c
37250 --- linux-2.6.29/sound/pci/intel8x0.c 2009-03-23 19:12:14.000000000 -0400
37251 +++ linux-2.6.29/sound/pci/intel8x0.c 2009-03-28 14:26:20.000000000 -0400
37252 @@ -443,7 +443,7 @@ static struct pci_device_id snd_intel8x0
37253 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37254 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
37255 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37257 + { 0, 0, 0, 0, 0, 0, 0 }
37260 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
37261 @@ -2088,7 +2088,7 @@ static struct ac97_quirk ac97_quirks[] _
37262 .type = AC97_TUNE_HP_ONLY
37265 - { } /* terminator */
37266 + { 0, 0, 0, 0, NULL, 0 } /* terminator */
37269 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
37270 diff -urNp linux-2.6.29/sound/pci/intel8x0m.c linux-2.6.29/sound/pci/intel8x0m.c
37271 --- linux-2.6.29/sound/pci/intel8x0m.c 2009-03-23 19:12:14.000000000 -0400
37272 +++ linux-2.6.29/sound/pci/intel8x0m.c 2009-03-28 14:26:20.000000000 -0400
37273 @@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
37274 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37275 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37278 + { 0, 0, 0, 0, 0, 0, 0 }
37281 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
37282 @@ -1258,7 +1258,7 @@ static struct shortname_table {
37283 { 0x5455, "ALi M5455" },
37284 { 0x746d, "AMD AMD8111" },
37290 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
37291 diff -urNp linux-2.6.29/virt/kvm/kvm_main.c linux-2.6.29/virt/kvm/kvm_main.c
37292 --- linux-2.6.29/virt/kvm/kvm_main.c 2009-03-23 19:12:14.000000000 -0400
37293 +++ linux-2.6.29/virt/kvm/kvm_main.c 2009-03-28 14:26:20.000000000 -0400
37294 @@ -2055,6 +2055,9 @@ static struct miscdevice kvm_dev = {
37303 static void hardware_enable(void *junk)
37304 @@ -2286,7 +2289,7 @@ static void kvm_sched_out(struct preempt
37305 kvm_arch_vcpu_put(vcpu);
37308 -int kvm_init(void *opaque, unsigned int vcpu_size,
37309 +int kvm_init(const void *opaque, unsigned int vcpu_size,
37310 struct module *module)