1 diff -urNp linux-2.6.24.4/arch/alpha/kernel/module.c linux-2.6.24.4/arch/alpha/kernel/module.c
2 --- linux-2.6.24.4/arch/alpha/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
3 +++ linux-2.6.24.4/arch/alpha/kernel/module.c 2008-03-26 20:21:07.000000000 -0400
4 @@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
6 /* The small sections were sorted to the end of the segment.
7 The following should definitely cover them. */
8 - gp = (u64)me->module_core + me->core_size - 0x8000;
9 + gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
10 got = sechdrs[me->arch.gotsecindex].sh_addr;
12 for (i = 0; i < n; i++) {
13 diff -urNp linux-2.6.24.4/arch/alpha/kernel/osf_sys.c linux-2.6.24.4/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.24.4/arch/alpha/kernel/osf_sys.c 2008-03-24 14:49:18.000000000 -0400
15 +++ linux-2.6.24.4/arch/alpha/kernel/osf_sys.c 2008-03-26 20:21:07.000000000 -0400
16 @@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
17 merely specific addresses, but regions of memory -- perhaps
18 this feature should be incorporated into all ports? */
20 +#ifdef CONFIG_PAX_RANDMMAP
21 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
25 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
26 if (addr != (unsigned long) -ENOMEM)
27 @@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
30 /* Next, try allocating at TASK_UNMAPPED_BASE. */
31 - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
33 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
35 if (addr != (unsigned long) -ENOMEM)
38 diff -urNp linux-2.6.24.4/arch/alpha/kernel/ptrace.c linux-2.6.24.4/arch/alpha/kernel/ptrace.c
39 --- linux-2.6.24.4/arch/alpha/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400
40 +++ linux-2.6.24.4/arch/alpha/kernel/ptrace.c 2008-03-26 20:21:07.000000000 -0400
42 #include <linux/security.h>
43 #include <linux/signal.h>
44 #include <linux/vs_base.h>
45 +#include <linux/grsecurity.h>
47 #include <asm/uaccess.h>
48 #include <asm/pgtable.h>
49 @@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
53 + if (gr_handle_ptrace(child, request))
57 /* When I and D space are separate, these will need to be fixed. */
58 case PTRACE_PEEKTEXT: /* read word at location addr. */
59 diff -urNp linux-2.6.24.4/arch/alpha/mm/fault.c linux-2.6.24.4/arch/alpha/mm/fault.c
60 --- linux-2.6.24.4/arch/alpha/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
61 +++ linux-2.6.24.4/arch/alpha/mm/fault.c 2008-03-26 20:21:07.000000000 -0400
63 #include <linux/smp.h>
64 #include <linux/interrupt.h>
65 #include <linux/module.h>
66 +#include <linux/binfmts.h>
68 #include <asm/system.h>
69 #include <asm/uaccess.h>
70 @@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
74 +#ifdef CONFIG_PAX_PAGEEXEC
76 + * PaX: decide what to do with offenders (regs->pc = fault address)
78 + * returns 1 when task should be killed
79 + * 2 when patched PLT trampoline was detected
80 + * 3 when unpatched PLT trampoline was detected
82 +static int pax_handle_fetch_fault(struct pt_regs *regs)
85 +#ifdef CONFIG_PAX_EMUPLT
88 + do { /* PaX: patched PLT emulation #1 */
89 + unsigned int ldah, ldq, jmp;
91 + err = get_user(ldah, (unsigned int *)regs->pc);
92 + err |= get_user(ldq, (unsigned int *)(regs->pc+4));
93 + err |= get_user(jmp, (unsigned int *)(regs->pc+8));
98 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
99 + (ldq & 0xFFFF0000U) == 0xA77B0000U &&
100 + jmp == 0x6BFB0000U)
102 + unsigned long r27, addr;
103 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
104 + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
106 + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
107 + err = get_user(r27, (unsigned long *)addr);
117 + do { /* PaX: patched PLT emulation #2 */
118 + unsigned int ldah, lda, br;
120 + err = get_user(ldah, (unsigned int *)regs->pc);
121 + err |= get_user(lda, (unsigned int *)(regs->pc+4));
122 + err |= get_user(br, (unsigned int *)(regs->pc+8));
127 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
128 + (lda & 0xFFFF0000U) == 0xA77B0000U &&
129 + (br & 0xFFE00000U) == 0xC3E00000U)
131 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
132 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
133 + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
135 + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
136 + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
141 + do { /* PaX: unpatched PLT emulation */
144 + err = get_user(br, (unsigned int *)regs->pc);
146 + if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
147 + unsigned int br2, ldq, nop, jmp;
148 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
150 + addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
151 + err = get_user(br2, (unsigned int *)addr);
152 + err |= get_user(ldq, (unsigned int *)(addr+4));
153 + err |= get_user(nop, (unsigned int *)(addr+8));
154 + err |= get_user(jmp, (unsigned int *)(addr+12));
155 + err |= get_user(resolver, (unsigned long *)(addr+16));
160 + if (br2 == 0xC3600000U &&
161 + ldq == 0xA77B000CU &&
162 + nop == 0x47FF041FU &&
163 + jmp == 0x6B7B0000U)
165 + regs->r28 = regs->pc+4;
166 + regs->r27 = addr+16;
167 + regs->pc = resolver;
177 +void pax_report_insns(void *pc, void *sp)
181 + printk(KERN_ERR "PAX: bytes at PC: ");
182 + for (i = 0; i < 5; i++) {
184 + if (get_user(c, (unsigned int *)pc+i))
185 + printk("???????? ");
187 + printk("%08x ", c);
194 * This routine handles page faults. It determines the address,
195 @@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
197 si_code = SEGV_ACCERR;
199 - if (!(vma->vm_flags & VM_EXEC))
200 + if (!(vma->vm_flags & VM_EXEC)) {
202 +#ifdef CONFIG_PAX_PAGEEXEC
203 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
206 + up_read(&mm->mmap_sem);
207 + switch (pax_handle_fetch_fault(regs)) {
209 +#ifdef CONFIG_PAX_EMUPLT
216 + pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
217 + do_group_exit(SIGKILL);
224 /* Allow reads even for write-only mappings */
225 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
226 diff -urNp linux-2.6.24.4/arch/arm/mm/mmap.c linux-2.6.24.4/arch/arm/mm/mmap.c
227 --- linux-2.6.24.4/arch/arm/mm/mmap.c 2008-03-24 14:49:18.000000000 -0400
228 +++ linux-2.6.24.4/arch/arm/mm/mmap.c 2008-03-26 20:21:07.000000000 -0400
229 @@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
233 +#ifdef CONFIG_PAX_RANDMMAP
234 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
239 addr = COLOUR_ALIGN(addr, pgoff);
240 @@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
243 if (len > mm->cached_hole_size) {
244 - start_addr = addr = mm->free_area_cache;
245 + start_addr = addr = mm->free_area_cache;
247 - start_addr = addr = TASK_UNMAPPED_BASE;
248 - mm->cached_hole_size = 0;
249 + start_addr = addr = mm->mmap_base;
250 + mm->cached_hole_size = 0;
254 @@ -91,8 +95,8 @@ full_search:
255 * Start a new search - just in case we missed
258 - if (start_addr != TASK_UNMAPPED_BASE) {
259 - start_addr = addr = TASK_UNMAPPED_BASE;
260 + if (start_addr != mm->mmap_base) {
261 + start_addr = addr = mm->mmap_base;
262 mm->cached_hole_size = 0;
265 diff -urNp linux-2.6.24.4/arch/avr32/mm/fault.c linux-2.6.24.4/arch/avr32/mm/fault.c
266 --- linux-2.6.24.4/arch/avr32/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
267 +++ linux-2.6.24.4/arch/avr32/mm/fault.c 2008-03-26 20:21:07.000000000 -0400
268 @@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
270 int exception_trace = 1;
272 +#ifdef CONFIG_PAX_PAGEEXEC
273 +void pax_report_insns(void *pc, void *sp)
277 + printk(KERN_ERR "PAX: bytes at PC: ");
278 + for (i = 0; i < 20; i++) {
280 + if (get_user(c, (unsigned char *)pc+i))
281 + printk("???????? ");
283 + printk("%02x ", c);
290 * This routine handles page faults. It determines the address and the
291 * problem, and then passes it off to one of the appropriate routines.
292 @@ -157,6 +174,16 @@ bad_area:
293 up_read(&mm->mmap_sem);
295 if (user_mode(regs)) {
297 +#ifdef CONFIG_PAX_PAGEEXEC
298 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
299 + if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
300 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
301 + do_group_exit(SIGKILL);
306 if (exception_trace && printk_ratelimit())
307 printk("%s%s[%d]: segfault at %08lx pc %08lx "
308 "sp %08lx ecr %lu\n",
309 diff -urNp linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c
310 --- linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c 2008-03-24 14:49:18.000000000 -0400
311 +++ linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c 2008-03-26 20:21:07.000000000 -0400
312 @@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
314 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
316 +#ifdef CONFIG_PAX_ASLR
317 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
319 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
320 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
323 /* Ugly but avoids duplication */
324 #include "../../../fs/binfmt_elf.c"
326 diff -urNp linux-2.6.24.4/arch/ia64/ia32/ia32priv.h linux-2.6.24.4/arch/ia64/ia32/ia32priv.h
327 --- linux-2.6.24.4/arch/ia64/ia32/ia32priv.h 2008-03-24 14:49:18.000000000 -0400
328 +++ linux-2.6.24.4/arch/ia64/ia32/ia32priv.h 2008-03-26 20:21:07.000000000 -0400
329 @@ -303,7 +303,14 @@ struct old_linux32_dirent {
330 #define ELF_DATA ELFDATA2LSB
331 #define ELF_ARCH EM_386
333 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
334 +#ifdef CONFIG_PAX_RANDUSTACK
335 +#define __IA32_DELTA_STACK (current->mm->delta_stack)
337 +#define __IA32_DELTA_STACK 0UL
340 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
342 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
343 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
345 diff -urNp linux-2.6.24.4/arch/ia64/kernel/module.c linux-2.6.24.4/arch/ia64/kernel/module.c
346 --- linux-2.6.24.4/arch/ia64/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
347 +++ linux-2.6.24.4/arch/ia64/kernel/module.c 2008-03-26 20:21:07.000000000 -0400
348 @@ -321,7 +321,7 @@ module_alloc (unsigned long size)
350 module_free (struct module *mod, void *module_region)
352 - if (mod->arch.init_unw_table && module_region == mod->module_init) {
353 + if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
354 unw_remove_unwind_table(mod->arch.init_unw_table);
355 mod->arch.init_unw_table = NULL;
357 @@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
361 +in_init_rx (const struct module *mod, uint64_t addr)
363 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
367 +in_init_rw (const struct module *mod, uint64_t addr)
369 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
373 in_init (const struct module *mod, uint64_t addr)
375 - return addr - (uint64_t) mod->module_init < mod->init_size;
376 + return in_init_rx(mod, value) || in_init_rw(mod, value);
380 +in_core_rx (const struct module *mod, uint64_t addr)
382 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
386 +in_core_rw (const struct module *mod, uint64_t addr)
388 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
392 in_core (const struct module *mod, uint64_t addr)
394 - return addr - (uint64_t) mod->module_core < mod->core_size;
395 + return in_core_rx(mod, addr) || in_core_rw(mod, addr);
399 @@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
403 - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
404 + if (in_init_rx(mod, val))
405 + val -= (uint64_t) mod->module_init_rx;
406 + else if (in_init_rw(mod, val))
407 + val -= (uint64_t) mod->module_init_rw;
408 + else if (in_core_rx(mod, val))
409 + val -= (uint64_t) mod->module_core_rx;
410 + else if (in_core_rw(mod, val))
411 + val -= (uint64_t) mod->module_core_rw;
415 @@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
416 * addresses have been selected...
419 - if (mod->core_size > MAX_LTOFF)
420 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
422 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
423 * at the end of the module.
425 - gp = mod->core_size - MAX_LTOFF / 2;
426 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
428 - gp = mod->core_size / 2;
429 - gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
430 + gp = (mod->core_size_rx + mod->core_size_rw) / 2;
431 + gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
433 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
435 diff -urNp linux-2.6.24.4/arch/ia64/kernel/ptrace.c linux-2.6.24.4/arch/ia64/kernel/ptrace.c
436 --- linux-2.6.24.4/arch/ia64/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400
437 +++ linux-2.6.24.4/arch/ia64/kernel/ptrace.c 2008-03-26 20:21:07.000000000 -0400
439 #include <linux/audit.h>
440 #include <linux/signal.h>
441 #include <linux/vs_base.h>
442 +#include <linux/grsecurity.h>
444 #include <asm/pgtable.h>
445 #include <asm/processor.h>
446 @@ -1451,6 +1452,9 @@ sys_ptrace (long request, pid_t pid, uns
447 if (pid == 1) /* no messing around with init! */
450 + if (gr_handle_ptrace(child, request))
453 if (request == PTRACE_ATTACH) {
454 ret = ptrace_attach(child);
456 diff -urNp linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c
457 --- linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c 2008-03-24 14:49:18.000000000 -0400
458 +++ linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c 2008-03-26 20:21:07.000000000 -0400
459 @@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
460 if (REGION_NUMBER(addr) == RGN_HPAGE)
464 +#ifdef CONFIG_PAX_RANDMMAP
465 + if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
466 + addr = mm->free_area_cache;
471 addr = mm->free_area_cache;
473 @@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
474 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
475 /* At this point: (!vma || addr < vma->vm_end). */
476 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
477 - if (start_addr != TASK_UNMAPPED_BASE) {
478 + if (start_addr != mm->mmap_base) {
479 /* Start a new search --- just in case we missed some holes. */
480 - addr = TASK_UNMAPPED_BASE;
481 + addr = mm->mmap_base;
485 diff -urNp linux-2.6.24.4/arch/ia64/mm/fault.c linux-2.6.24.4/arch/ia64/mm/fault.c
486 --- linux-2.6.24.4/arch/ia64/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
487 +++ linux-2.6.24.4/arch/ia64/mm/fault.c 2008-03-26 20:21:07.000000000 -0400
489 #include <linux/kprobes.h>
490 #include <linux/kdebug.h>
491 #include <linux/vs_memory.h>
492 +#include <linux/binfmts.h>
494 #include <asm/pgtable.h>
495 #include <asm/processor.h>
496 @@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
497 return pte_present(pte);
500 +#ifdef CONFIG_PAX_PAGEEXEC
501 +void pax_report_insns(void *pc, void *sp)
505 + printk(KERN_ERR "PAX: bytes at PC: ");
506 + for (i = 0; i < 8; i++) {
508 + if (get_user(c, (unsigned int *)pc+i))
509 + printk("???????? ");
511 + printk("%08x ", c);
518 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
520 @@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres
521 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
522 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
524 - if ((vma->vm_flags & mask) != mask)
525 + if ((vma->vm_flags & mask) != mask) {
527 +#ifdef CONFIG_PAX_PAGEEXEC
528 + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
529 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
532 + up_read(&mm->mmap_sem);
533 + pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
534 + do_group_exit(SIGKILL);
544 * If for any reason at all we couldn't handle the fault, make
545 diff -urNp linux-2.6.24.4/arch/ia64/mm/init.c linux-2.6.24.4/arch/ia64/mm/init.c
546 --- linux-2.6.24.4/arch/ia64/mm/init.c 2008-03-24 14:49:18.000000000 -0400
547 +++ linux-2.6.24.4/arch/ia64/mm/init.c 2008-03-26 20:21:07.000000000 -0400
549 #include <linux/proc_fs.h>
550 #include <linux/bitops.h>
551 #include <linux/kexec.h>
552 +#include <linux/a.out.h>
554 -#include <asm/a.out.h>
556 #include <asm/ia32.h>
558 @@ -128,6 +128,19 @@ ia64_init_addr_space (void)
559 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
560 vma->vm_end = vma->vm_start + PAGE_SIZE;
561 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
563 +#ifdef CONFIG_PAX_PAGEEXEC
564 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
565 + vm->vm_flags &= ~VM_EXEC;
567 +#ifdef CONFIG_PAX_MPROTECT
568 + if (current->mm->pax_flags & MF_PAX_MPROTECT)
569 + vma->vm_flags &= ~VM_MAYEXEC;
575 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
576 down_write(¤t->mm->mmap_sem);
577 if (insert_vm_struct(current->mm, vma)) {
578 diff -urNp linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c
579 --- linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c 2008-03-24 14:49:18.000000000 -0400
580 +++ linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c 2008-03-26 20:21:07.000000000 -0400
581 @@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
582 #undef ELF_ET_DYN_BASE
583 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
585 +#ifdef CONFIG_PAX_ASLR
586 +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
588 +#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
589 +#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
592 #include <asm/processor.h>
593 #include <linux/module.h>
594 #include <linux/elfcore.h>
595 diff -urNp linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c
596 --- linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c 2008-03-24 14:49:18.000000000 -0400
597 +++ linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c 2008-03-26 20:21:07.000000000 -0400
598 @@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
599 #undef ELF_ET_DYN_BASE
600 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
602 +#ifdef CONFIG_PAX_ASLR
603 +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
605 +#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
606 +#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
609 #include <asm/processor.h>
610 #include <linux/module.h>
611 #include <linux/elfcore.h>
612 diff -urNp linux-2.6.24.4/arch/mips/kernel/syscall.c linux-2.6.24.4/arch/mips/kernel/syscall.c
613 --- linux-2.6.24.4/arch/mips/kernel/syscall.c 2008-03-24 14:49:18.000000000 -0400
614 +++ linux-2.6.24.4/arch/mips/kernel/syscall.c 2008-03-26 20:21:07.000000000 -0400
615 @@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str
617 if (filp || (flags & MAP_SHARED))
620 +#ifdef CONFIG_PAX_RANDMMAP
621 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
626 addr = COLOUR_ALIGN(addr, pgoff);
627 @@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str
628 (!vmm || addr + len <= vmm->vm_start))
631 - addr = TASK_UNMAPPED_BASE;
632 + addr = current->mm->mmap_base;
634 addr = COLOUR_ALIGN(addr, pgoff);
636 diff -urNp linux-2.6.24.4/arch/mips/mm/fault.c linux-2.6.24.4/arch/mips/mm/fault.c
637 --- linux-2.6.24.4/arch/mips/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
638 +++ linux-2.6.24.4/arch/mips/mm/fault.c 2008-03-26 20:21:07.000000000 -0400
640 #include <asm/ptrace.h>
641 #include <asm/highmem.h> /* For VMALLOC_END */
643 +#ifdef CONFIG_PAX_PAGEEXEC
644 +void pax_report_insns(void *pc)
648 + printk(KERN_ERR "PAX: bytes at PC: ");
649 + for (i = 0; i < 5; i++) {
651 + if (get_user(c, (unsigned int *)pc+i))
652 + printk("???????? ");
654 + printk("%08x ", c);
661 * This routine handles page faults. It determines the address,
662 * and the problem, and then passes it off to one of the appropriate
663 diff -urNp linux-2.6.24.4/arch/parisc/kernel/module.c linux-2.6.24.4/arch/parisc/kernel/module.c
664 --- linux-2.6.24.4/arch/parisc/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
665 +++ linux-2.6.24.4/arch/parisc/kernel/module.c 2008-03-26 20:21:07.000000000 -0400
668 /* three functions to determine where in the module core
669 * or init pieces the location is */
670 +static inline int in_init_rx(struct module *me, void *loc)
672 + return (loc >= me->module_init_rx &&
673 + loc < (me->module_init_rx + me->init_size_rx));
676 +static inline int in_init_rw(struct module *me, void *loc)
678 + return (loc >= me->module_init_rw &&
679 + loc < (me->module_init_rw + me->init_size_rw));
682 static inline int in_init(struct module *me, void *loc)
684 - return (loc >= me->module_init &&
685 - loc <= (me->module_init + me->init_size));
686 + return in_init_rx(me, loc) || in_init_rw(me, loc);
689 +static inline int in_core_rx(struct module *me, void *loc)
691 + return (loc >= me->module_core_rx &&
692 + loc < (me->module_core_rx + me->core_size_rx));
695 +static inline int in_core_rw(struct module *me, void *loc)
697 + return (loc >= me->module_core_rw &&
698 + loc < (me->module_core_rw + me->core_size_rw));
701 static inline int in_core(struct module *me, void *loc)
703 - return (loc >= me->module_core &&
704 - loc <= (me->module_core + me->core_size));
705 + return in_core_rx(me, loc) || in_core_rw(me, loc);
708 static inline int in_local(struct module *me, void *loc)
709 @@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
712 /* align things a bit */
713 - me->core_size = ALIGN(me->core_size, 16);
714 - me->arch.got_offset = me->core_size;
715 - me->core_size += gots * sizeof(struct got_entry);
717 - me->core_size = ALIGN(me->core_size, 16);
718 - me->arch.fdesc_offset = me->core_size;
719 - me->core_size += fdescs * sizeof(Elf_Fdesc);
721 - me->core_size = ALIGN(me->core_size, 16);
722 - me->arch.stub_offset = me->core_size;
723 - me->core_size += stubs * sizeof(struct stub_entry);
725 - me->init_size = ALIGN(me->init_size, 16);
726 - me->arch.init_stub_offset = me->init_size;
727 - me->init_size += init_stubs * sizeof(struct stub_entry);
728 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
729 + me->arch.got_offset = me->core_size_rw;
730 + me->core_size_rw += gots * sizeof(struct got_entry);
732 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
733 + me->arch.fdesc_offset = me->core_size_rw;
734 + me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
736 + me->core_size_rx = ALIGN(me->core_size_rx, 16);
737 + me->arch.stub_offset = me->core_size_rx;
738 + me->core_size_rx += stubs * sizeof(struct stub_entry);
740 + me->init_size_rx = ALIGN(me->init_size_rx, 16);
741 + me->arch.init_stub_offset = me->init_size_rx;
742 + me->init_size_rx += init_stubs * sizeof(struct stub_entry);
744 me->arch.got_max = gots;
745 me->arch.fdesc_max = fdescs;
746 @@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
750 - got = me->module_core + me->arch.got_offset;
751 + got = me->module_core_rw + me->arch.got_offset;
752 for (i = 0; got[i].addr; i++)
753 if (got[i].addr == value)
755 @@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
757 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
759 - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
760 + Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
763 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
764 @@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
768 - fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
769 + fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
770 return (Elf_Addr)fdesc;
772 #endif /* CONFIG_64BIT */
773 @@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
775 i = me->arch.init_stub_count++;
776 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
777 - stub = me->module_init + me->arch.init_stub_offset +
778 + stub = me->module_init_rx + me->arch.init_stub_offset +
779 i * sizeof(struct stub_entry);
781 i = me->arch.stub_count++;
782 BUG_ON(me->arch.stub_count > me->arch.stub_max);
783 - stub = me->module_core + me->arch.stub_offset +
784 + stub = me->module_core_rx + me->arch.stub_offset +
785 i * sizeof(struct stub_entry);
788 @@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
790 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
791 end = table + sechdrs[me->arch.unwind_section].sh_size;
792 - gp = (Elf_Addr)me->module_core + me->arch.got_offset;
793 + gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
795 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
796 me->arch.unwind_section, table, end, gp);
797 diff -urNp linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c
798 --- linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c 2008-03-24 14:49:18.000000000 -0400
799 +++ linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c 2008-03-26 20:21:07.000000000 -0400
800 @@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
801 if (flags & MAP_FIXED)
804 - addr = TASK_UNMAPPED_BASE;
805 + addr = current->mm->mmap_base;
808 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
809 diff -urNp linux-2.6.24.4/arch/parisc/kernel/traps.c linux-2.6.24.4/arch/parisc/kernel/traps.c
810 --- linux-2.6.24.4/arch/parisc/kernel/traps.c 2008-03-24 14:49:18.000000000 -0400
811 +++ linux-2.6.24.4/arch/parisc/kernel/traps.c 2008-03-26 20:21:07.000000000 -0400
812 @@ -713,9 +713,7 @@ void handle_interruption(int code, struc
814 down_read(¤t->mm->mmap_sem);
815 vma = find_vma(current->mm,regs->iaoq[0]);
816 - if (vma && (regs->iaoq[0] >= vma->vm_start)
817 - && (vma->vm_flags & VM_EXEC)) {
819 + if (vma && (regs->iaoq[0] >= vma->vm_start)) {
820 fault_address = regs->iaoq[0];
821 fault_space = regs->iasq[0];
823 diff -urNp linux-2.6.24.4/arch/parisc/mm/fault.c linux-2.6.24.4/arch/parisc/mm/fault.c
824 --- linux-2.6.24.4/arch/parisc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
825 +++ linux-2.6.24.4/arch/parisc/mm/fault.c 2008-03-26 20:21:07.000000000 -0400
827 #include <linux/sched.h>
828 #include <linux/interrupt.h>
829 #include <linux/module.h>
830 +#include <linux/unistd.h>
831 +#include <linux/binfmts.h>
833 #include <asm/uaccess.h>
834 #include <asm/traps.h>
835 @@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
837 parisc_acctyp(unsigned long code, unsigned int inst)
839 - if (code == 6 || code == 16)
840 + if (code == 6 || code == 7 || code == 16)
843 switch (inst & 0xf0000000) {
844 @@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
848 +#ifdef CONFIG_PAX_PAGEEXEC
850 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
852 + * returns 1 when task should be killed
853 + * 2 when rt_sigreturn trampoline was detected
854 + * 3 when unpatched PLT trampoline was detected
856 +static int pax_handle_fetch_fault(struct pt_regs *regs)
859 +#ifdef CONFIG_PAX_EMUPLT
862 + do { /* PaX: unpatched PLT emulation */
863 + unsigned int bl, depwi;
865 + err = get_user(bl, (unsigned int *)instruction_pointer(regs));
866 + err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
871 + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
872 + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
874 + err = get_user(ldw, (unsigned int *)addr);
875 + err |= get_user(bv, (unsigned int *)(addr+4));
876 + err |= get_user(ldw2, (unsigned int *)(addr+8));
881 + if (ldw == 0x0E801096U &&
882 + bv == 0xEAC0C000U &&
883 + ldw2 == 0x0E881095U)
885 + unsigned int resolver, map;
887 + err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
888 + err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
892 + regs->gr[20] = instruction_pointer(regs)+8;
893 + regs->gr[21] = map;
894 + regs->gr[22] = resolver;
895 + regs->iaoq[0] = resolver | 3UL;
896 + regs->iaoq[1] = regs->iaoq[0] + 4;
903 +#ifdef CONFIG_PAX_EMUTRAMP
905 +#ifndef CONFIG_PAX_EMUSIGRT
906 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
910 + do { /* PaX: rt_sigreturn emulation */
911 + unsigned int ldi1, ldi2, bel, nop;
913 + err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
914 + err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
915 + err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
916 + err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
921 + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
922 + ldi2 == 0x3414015AU &&
923 + bel == 0xE4008200U &&
924 + nop == 0x08000240U)
926 + regs->gr[25] = (ldi1 & 2) >> 1;
927 + regs->gr[20] = __NR_rt_sigreturn;
928 + regs->gr[31] = regs->iaoq[1] + 16;
929 + regs->sr[0] = regs->iasq[1];
930 + regs->iaoq[0] = 0x100UL;
931 + regs->iaoq[1] = regs->iaoq[0] + 4;
932 + regs->iasq[0] = regs->sr[2];
933 + regs->iasq[1] = regs->sr[2];
942 +void pax_report_insns(void *pc, void *sp)
946 + printk(KERN_ERR "PAX: bytes at PC: ");
947 + for (i = 0; i < 5; i++) {
949 + if (get_user(c, (unsigned int *)pc+i))
950 + printk("???????? ");
952 + printk("%08x ", c);
958 void do_page_fault(struct pt_regs *regs, unsigned long code,
959 unsigned long address)
961 @@ -165,8 +277,33 @@ good_area:
963 acc_type = parisc_acctyp(code,regs->iir);
965 - if ((vma->vm_flags & acc_type) != acc_type)
966 + if ((vma->vm_flags & acc_type) != acc_type) {
968 +#ifdef CONFIG_PAX_PAGEEXEC
969 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
970 + (address & ~3UL) == instruction_pointer(regs))
972 + up_read(&mm->mmap_sem);
973 + switch (pax_handle_fetch_fault(regs)) {
975 +#ifdef CONFIG_PAX_EMUPLT
980 +#ifdef CONFIG_PAX_EMUTRAMP
986 + pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
987 + do_group_exit(SIGKILL);
995 * If for any reason at all we couldn't handle the fault, make
996 diff -urNp linux-2.6.24.4/arch/powerpc/kernel/module_32.c linux-2.6.24.4/arch/powerpc/kernel/module_32.c
997 --- linux-2.6.24.4/arch/powerpc/kernel/module_32.c 2008-03-24 14:49:18.000000000 -0400
998 +++ linux-2.6.24.4/arch/powerpc/kernel/module_32.c 2008-03-26 20:21:07.000000000 -0400
999 @@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1000 me->arch.core_plt_section = i;
1002 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1003 - printk("Module doesn't contain .plt or .init.plt sections.\n");
1004 + printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1008 @@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
1010 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1011 /* Init, or core PLT? */
1012 - if (location >= mod->module_core
1013 - && location < mod->module_core + mod->core_size)
1014 + if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1015 + (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1016 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1018 + else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1019 + (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1020 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1022 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1026 /* Find this entry, or if that fails, the next avail. entry */
1027 while (entry->jump[0]) {
1028 diff -urNp linux-2.6.24.4/arch/powerpc/kernel/signal_32.c linux-2.6.24.4/arch/powerpc/kernel/signal_32.c
1029 --- linux-2.6.24.4/arch/powerpc/kernel/signal_32.c 2008-03-24 14:49:18.000000000 -0400
1030 +++ linux-2.6.24.4/arch/powerpc/kernel/signal_32.c 2008-03-26 20:21:07.000000000 -0400
1031 @@ -731,7 +731,7 @@ int handle_rt_signal32(unsigned long sig
1032 /* Save user registers on the stack */
1033 frame = &rt_sf->uc.uc_mcontext;
1035 - if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1036 + if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1037 if (save_user_regs(regs, frame, 0))
1039 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1040 diff -urNp linux-2.6.24.4/arch/powerpc/kernel/signal_64.c linux-2.6.24.4/arch/powerpc/kernel/signal_64.c
1041 --- linux-2.6.24.4/arch/powerpc/kernel/signal_64.c 2008-03-24 14:49:18.000000000 -0400
1042 +++ linux-2.6.24.4/arch/powerpc/kernel/signal_64.c 2008-03-26 20:21:07.000000000 -0400
1043 @@ -369,7 +369,7 @@ int handle_rt_signal64(int signr, struct
1044 current->thread.fpscr.val = 0;
1046 /* Set up to return from userspace. */
1047 - if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1048 + if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1049 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1051 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1052 diff -urNp linux-2.6.24.4/arch/powerpc/kernel/vdso.c linux-2.6.24.4/arch/powerpc/kernel/vdso.c
1053 --- linux-2.6.24.4/arch/powerpc/kernel/vdso.c 2008-03-24 14:49:18.000000000 -0400
1054 +++ linux-2.6.24.4/arch/powerpc/kernel/vdso.c 2008-03-26 20:21:07.000000000 -0400
1055 @@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
1056 vdso_base = VDSO32_MBASE;
1059 - current->mm->context.vdso_base = 0;
1060 + current->mm->context.vdso_base = ~0UL;
1062 /* vDSO has a problem and was disabled, just don't "enable" it for the
1064 @@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
1066 down_write(&mm->mmap_sem);
1067 vdso_base = get_unmapped_area(NULL, vdso_base,
1068 - vdso_pages << PAGE_SHIFT, 0, 0);
1069 + vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1070 if (IS_ERR_VALUE(vdso_base)) {
1073 diff -urNp linux-2.6.24.4/arch/powerpc/mm/fault.c linux-2.6.24.4/arch/powerpc/mm/fault.c
1074 --- linux-2.6.24.4/arch/powerpc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
1075 +++ linux-2.6.24.4/arch/powerpc/mm/fault.c 2008-03-26 20:21:07.000000000 -0400
1077 #include <linux/module.h>
1078 #include <linux/kprobes.h>
1079 #include <linux/kdebug.h>
1080 +#include <linux/binfmts.h>
1081 +#include <linux/slab.h>
1082 +#include <linux/pagemap.h>
1083 +#include <linux/compiler.h>
1084 +#include <linux/binfmts.h>
1085 +#include <linux/unistd.h>
1087 #include <asm/page.h>
1088 #include <asm/pgtable.h>
1089 @@ -62,6 +68,363 @@ static inline int notify_page_fault(stru
1093 +#ifdef CONFIG_PAX_EMUSIGRT
1094 +void pax_syscall_close(struct vm_area_struct *vma)
1096 + vma->vm_mm->call_syscall = 0UL;
1099 +static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1101 + struct page *page;
1102 + unsigned int *kaddr;
1104 + page = alloc_page(GFP_HIGHUSER);
1106 + return NOPAGE_OOM;
1108 + kaddr = kmap(page);
1109 + memset(kaddr, 0, PAGE_SIZE);
1110 + kaddr[0] = 0x44000002U; /* sc */
1111 + __flush_dcache_icache(kaddr);
1114 + *type = VM_FAULT_MAJOR;
1118 +static struct vm_operations_struct pax_vm_ops = {
1119 + .close = pax_syscall_close,
1120 + .nopage = pax_syscall_nopage,
1123 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1127 + vma->vm_mm = current->mm;
1128 + vma->vm_start = addr;
1129 + vma->vm_end = addr + PAGE_SIZE;
1130 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1131 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1132 + vma->vm_ops = &pax_vm_ops;
1134 + ret = insert_vm_struct(current->mm, vma);
1138 + ++current->mm->total_vm;
1143 +#ifdef CONFIG_PAX_PAGEEXEC
1145 + * PaX: decide what to do with offenders (regs->nip = fault address)
1147 + * returns 1 when task should be killed
1148 + * 2 when patched GOT trampoline was detected
1149 + * 3 when patched PLT trampoline was detected
1150 + * 4 when unpatched PLT trampoline was detected
1151 + * 5 when sigreturn trampoline was detected
1152 + * 6 when rt_sigreturn trampoline was detected
1154 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1157 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1161 +#ifdef CONFIG_PAX_EMUPLT
1162 + do { /* PaX: patched GOT emulation */
1163 + unsigned int blrl;
1165 + err = get_user(blrl, (unsigned int *)regs->nip);
1167 + if (!err && blrl == 0x4E800021U) {
1168 + unsigned long temp = regs->nip;
1170 + regs->nip = regs->link & 0xFFFFFFFCUL;
1171 + regs->link = temp + 4UL;
1176 + do { /* PaX: patched PLT emulation #1 */
1179 + err = get_user(b, (unsigned int *)regs->nip);
1181 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
1182 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1187 + do { /* PaX: unpatched PLT emulation #1 */
1188 + unsigned int li, b;
1190 + err = get_user(li, (unsigned int *)regs->nip);
1191 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1193 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1194 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1195 + unsigned long addr = b | 0xFC000000UL;
1197 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1198 + err = get_user(rlwinm, (unsigned int *)addr);
1199 + err |= get_user(add, (unsigned int *)(addr+4));
1200 + err |= get_user(li2, (unsigned int *)(addr+8));
1201 + err |= get_user(addis2, (unsigned int *)(addr+12));
1202 + err |= get_user(mtctr, (unsigned int *)(addr+16));
1203 + err |= get_user(li3, (unsigned int *)(addr+20));
1204 + err |= get_user(addis3, (unsigned int *)(addr+24));
1205 + err |= get_user(bctr, (unsigned int *)(addr+28));
1210 + if (rlwinm == 0x556C083CU &&
1211 + add == 0x7D6C5A14U &&
1212 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1213 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1214 + mtctr == 0x7D8903A6U &&
1215 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1216 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1217 + bctr == 0x4E800420U)
1219 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1220 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1221 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1222 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1223 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1224 + regs->nip = regs->ctr;
1231 + do { /* PaX: unpatched PLT emulation #2 */
1232 + unsigned int lis, lwzu, b, bctr;
1234 + err = get_user(lis, (unsigned int *)regs->nip);
1235 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1236 + err |= get_user(b, (unsigned int *)(regs->nip+8));
1237 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1242 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
1243 + (lwzu & 0xU) == 0xU &&
1244 + (b & 0xFC000003U) == 0x48000000U &&
1245 + bctr == 0x4E800420U)
1247 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1248 + unsigned long addr = b | 0xFC000000UL;
1250 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1251 + err = get_user(addis, (unsigned int*)addr);
1252 + err |= get_user(addi, (unsigned int*)(addr+4));
1253 + err |= get_user(rlwinm, (unsigned int*)(addr+8));
1254 + err |= get_user(add, (unsigned int*)(addr+12));
1255 + err |= get_user(li2, (unsigned int*)(addr+16));
1256 + err |= get_user(addis2, (unsigned int*)(addr+20));
1257 + err |= get_user(mtctr, (unsigned int*)(addr+24));
1258 + err |= get_user(li3, (unsigned int*)(addr+28));
1259 + err |= get_user(addis3, (unsigned int*)(addr+32));
1260 + err |= get_user(bctr, (unsigned int*)(addr+36));
1265 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1266 + (addi & 0xFFFF0000U) == 0x396B0000U &&
1267 + rlwinm == 0x556C083CU &&
1268 + add == 0x7D6C5A14U &&
1269 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1270 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1271 + mtctr == 0x7D8903A6U &&
1272 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1273 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1274 + bctr == 0x4E800420U)
1276 + regs->gpr[PT_R11] =
1277 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1278 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1279 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1280 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1281 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1282 + regs->nip = regs->ctr;
1289 + do { /* PaX: unpatched PLT emulation #3 */
1290 + unsigned int li, b;
1292 + err = get_user(li, (unsigned int *)regs->nip);
1293 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1295 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1296 + unsigned int addis, lwz, mtctr, bctr;
1297 + unsigned long addr = b | 0xFC000000UL;
1299 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1300 + err = get_user(addis, (unsigned int *)addr);
1301 + err |= get_user(lwz, (unsigned int *)(addr+4));
1302 + err |= get_user(mtctr, (unsigned int *)(addr+8));
1303 + err |= get_user(bctr, (unsigned int *)(addr+12));
1308 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1309 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
1310 + mtctr == 0x7D6903A6U &&
1311 + bctr == 0x4E800420U)
1315 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1316 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1318 + err = get_user(r11, (unsigned int *)addr);
1322 + regs->gpr[PT_R11] = r11;
1331 +#ifdef CONFIG_PAX_EMUSIGRT
1332 + do { /* PaX: sigreturn emulation */
1333 + unsigned int li, sc;
1335 + err = get_user(li, (unsigned int *)regs->nip);
1336 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1338 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1339 + struct vm_area_struct *vma;
1340 + unsigned long call_syscall;
1342 + down_read(¤t->mm->mmap_sem);
1343 + call_syscall = current->mm->call_syscall;
1344 + up_read(¤t->mm->mmap_sem);
1345 + if (likely(call_syscall))
1348 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1350 + down_write(¤t->mm->mmap_sem);
1351 + if (current->mm->call_syscall) {
1352 + call_syscall = current->mm->call_syscall;
1353 + up_write(¤t->mm->mmap_sem);
1354 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1358 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1359 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1360 + up_write(¤t->mm->mmap_sem);
1361 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1365 + if (pax_insert_vma(vma, call_syscall)) {
1366 + up_write(¤t->mm->mmap_sem);
1367 + kmem_cache_free(vm_area_cachep, vma);
1371 + current->mm->call_syscall = call_syscall;
1372 + up_write(¤t->mm->mmap_sem);
1375 + regs->gpr[PT_R0] = __NR_sigreturn;
1376 + regs->nip = call_syscall;
1381 + do { /* PaX: rt_sigreturn emulation */
1382 + unsigned int li, sc;
1384 + err = get_user(li, (unsigned int *)regs->nip);
1385 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1387 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1388 + struct vm_area_struct *vma;
1389 + unsigned int call_syscall;
1391 + down_read(¤t->mm->mmap_sem);
1392 + call_syscall = current->mm->call_syscall;
1393 + up_read(¤t->mm->mmap_sem);
1394 + if (likely(call_syscall))
1397 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1399 + down_write(¤t->mm->mmap_sem);
1400 + if (current->mm->call_syscall) {
1401 + call_syscall = current->mm->call_syscall;
1402 + up_write(¤t->mm->mmap_sem);
1403 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1407 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1408 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1409 + up_write(¤t->mm->mmap_sem);
1410 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1414 + if (pax_insert_vma(vma, call_syscall)) {
1415 + up_write(¤t->mm->mmap_sem);
1416 + kmem_cache_free(vm_area_cachep, vma);
1420 + current->mm->call_syscall = call_syscall;
1421 + up_write(¤t->mm->mmap_sem);
1424 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
1425 + regs->nip = call_syscall;
1434 +void pax_report_insns(void *pc, void *sp)
1438 + printk(KERN_ERR "PAX: bytes at PC: ");
1439 + for (i = 0; i < 5; i++) {
1441 + if (get_user(c, (unsigned int *)pc+i))
1442 + printk("???????? ");
1444 + printk("%08x ", c);
1451 * Check whether the instruction at regs->nip is a store using
1452 * an update addressing form which will update r1.
1453 @@ -157,7 +520,7 @@ int __kprobes do_page_fault(struct pt_re
1454 * indicate errors in DSISR but can validly be set in SRR1.
1457 - error_code &= 0x48200000;
1458 + error_code &= 0x58200000;
1460 is_write = error_code & DSISR_ISSTORE;
1462 @@ -357,6 +720,37 @@ bad_area:
1463 bad_area_nosemaphore:
1464 /* User mode accesses cause a SIGSEGV */
1465 if (user_mode(regs)) {
1467 +#ifdef CONFIG_PAX_PAGEEXEC
1468 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1469 +#ifdef CONFIG_PPC64
1470 + if (is_exec && (error_code & DSISR_PROTFAULT)) {
1472 + if (is_exec && regs->nip == address) {
1474 + switch (pax_handle_fetch_fault(regs)) {
1476 +#ifdef CONFIG_PAX_EMUPLT
1483 +#ifdef CONFIG_PAX_EMUSIGRT
1491 + pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
1492 + do_group_exit(SIGKILL);
1497 _exception(SIGSEGV, regs, code, address);
1500 diff -urNp linux-2.6.24.4/arch/powerpc/mm/mmap.c linux-2.6.24.4/arch/powerpc/mm/mmap.c
1501 --- linux-2.6.24.4/arch/powerpc/mm/mmap.c 2008-03-24 14:49:18.000000000 -0400
1502 +++ linux-2.6.24.4/arch/powerpc/mm/mmap.c 2008-03-26 20:21:07.000000000 -0400
1503 @@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1505 if (mmap_is_legacy()) {
1506 mm->mmap_base = TASK_UNMAPPED_BASE;
1508 +#ifdef CONFIG_PAX_RANDMMAP
1509 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1510 + mm->mmap_base += mm->delta_mmap;
1513 mm->get_unmapped_area = arch_get_unmapped_area;
1514 mm->unmap_area = arch_unmap_area;
1516 mm->mmap_base = mmap_base();
1518 +#ifdef CONFIG_PAX_RANDMMAP
1519 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1520 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1523 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1524 mm->unmap_area = arch_unmap_area_topdown;
1526 diff -urNp linux-2.6.24.4/arch/ppc/mm/fault.c linux-2.6.24.4/arch/ppc/mm/fault.c
1527 --- linux-2.6.24.4/arch/ppc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
1528 +++ linux-2.6.24.4/arch/ppc/mm/fault.c 2008-03-26 20:21:07.000000000 -0400
1530 #include <linux/interrupt.h>
1531 #include <linux/highmem.h>
1532 #include <linux/module.h>
1533 +#include <linux/slab.h>
1534 +#include <linux/pagemap.h>
1535 +#include <linux/compiler.h>
1536 +#include <linux/binfmts.h>
1537 +#include <linux/unistd.h>
1539 #include <asm/page.h>
1540 #include <asm/pgtable.h>
1541 @@ -48,6 +53,363 @@ unsigned long pte_misses; /* updated by
1542 unsigned long pte_errors; /* updated by do_page_fault() */
1543 unsigned int probingmem;
1545 +#ifdef CONFIG_PAX_EMUSIGRT
1546 +void pax_syscall_close(struct vm_area_struct *vma)
1548 + vma->vm_mm->call_syscall = 0UL;
1551 +static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1553 + struct page *page;
1554 + unsigned int *kaddr;
1556 + page = alloc_page(GFP_HIGHUSER);
1558 + return NOPAGE_OOM;
1560 + kaddr = kmap(page);
1561 + memset(kaddr, 0, PAGE_SIZE);
1562 + kaddr[0] = 0x44000002U; /* sc */
1563 + __flush_dcache_icache(kaddr);
1566 + *type = VM_FAULT_MAJOR;
1570 +static struct vm_operations_struct pax_vm_ops = {
1571 + .close = pax_syscall_close,
1572 + .nopage = pax_syscall_nopage,
1575 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1579 + vma->vm_mm = current->mm;
1580 + vma->vm_start = addr;
1581 + vma->vm_end = addr + PAGE_SIZE;
1582 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1583 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1584 + vma->vm_ops = &pax_vm_ops;
1586 + ret = insert_vm_struct(current->mm, vma);
1590 + ++current->mm->total_vm;
1595 +#ifdef CONFIG_PAX_PAGEEXEC
1597 + * PaX: decide what to do with offenders (regs->nip = fault address)
1599 + * returns 1 when task should be killed
1600 + * 2 when patched GOT trampoline was detected
1601 + * 3 when patched PLT trampoline was detected
1602 + * 4 when unpatched PLT trampoline was detected
1603 + * 5 when sigreturn trampoline was detected
1604 + * 6 when rt_sigreturn trampoline was detected
1606 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1609 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1613 +#ifdef CONFIG_PAX_EMUPLT
1614 + do { /* PaX: patched GOT emulation */
1615 + unsigned int blrl;
1617 + err = get_user(blrl, (unsigned int *)regs->nip);
1619 + if (!err && blrl == 0x4E800021U) {
1620 + unsigned long temp = regs->nip;
1622 + regs->nip = regs->link & 0xFFFFFFFCUL;
1623 + regs->link = temp + 4UL;
1628 + do { /* PaX: patched PLT emulation #1 */
1631 + err = get_user(b, (unsigned int *)regs->nip);
1633 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
1634 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1639 + do { /* PaX: unpatched PLT emulation #1 */
1640 + unsigned int li, b;
1642 + err = get_user(li, (unsigned int *)regs->nip);
1643 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1645 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1646 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1647 + unsigned long addr = b | 0xFC000000UL;
1649 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1650 + err = get_user(rlwinm, (unsigned int *)addr);
1651 + err |= get_user(add, (unsigned int *)(addr+4));
1652 + err |= get_user(li2, (unsigned int *)(addr+8));
1653 + err |= get_user(addis2, (unsigned int *)(addr+12));
1654 + err |= get_user(mtctr, (unsigned int *)(addr+16));
1655 + err |= get_user(li3, (unsigned int *)(addr+20));
1656 + err |= get_user(addis3, (unsigned int *)(addr+24));
1657 + err |= get_user(bctr, (unsigned int *)(addr+28));
1662 + if (rlwinm == 0x556C083CU &&
1663 + add == 0x7D6C5A14U &&
1664 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1665 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1666 + mtctr == 0x7D8903A6U &&
1667 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1668 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1669 + bctr == 0x4E800420U)
1671 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1672 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1673 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1674 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1675 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1676 + regs->nip = regs->ctr;
1683 + do { /* PaX: unpatched PLT emulation #2 */
1684 + unsigned int lis, lwzu, b, bctr;
1686 + err = get_user(lis, (unsigned int *)regs->nip);
1687 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1688 + err |= get_user(b, (unsigned int *)(regs->nip+8));
1689 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1694 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
1695 + (lwzu & 0xU) == 0xU &&
1696 + (b & 0xFC000003U) == 0x48000000U &&
1697 + bctr == 0x4E800420U)
1699 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1700 + unsigned long addr = b | 0xFC000000UL;
1702 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1703 + err = get_user(addis, (unsigned int*)addr);
1704 + err |= get_user(addi, (unsigned int*)(addr+4));
1705 + err |= get_user(rlwinm, (unsigned int*)(addr+8));
1706 + err |= get_user(add, (unsigned int*)(addr+12));
1707 + err |= get_user(li2, (unsigned int*)(addr+16));
1708 + err |= get_user(addis2, (unsigned int*)(addr+20));
1709 + err |= get_user(mtctr, (unsigned int*)(addr+24));
1710 + err |= get_user(li3, (unsigned int*)(addr+28));
1711 + err |= get_user(addis3, (unsigned int*)(addr+32));
1712 + err |= get_user(bctr, (unsigned int*)(addr+36));
1717 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1718 + (addi & 0xFFFF0000U) == 0x396B0000U &&
1719 + rlwinm == 0x556C083CU &&
1720 + add == 0x7D6C5A14U &&
1721 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1722 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1723 + mtctr == 0x7D8903A6U &&
1724 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1725 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1726 + bctr == 0x4E800420U)
1728 + regs->gpr[PT_R11] =
1729 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1730 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1731 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1732 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1733 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1734 + regs->nip = regs->ctr;
1741 + do { /* PaX: unpatched PLT emulation #3 */
1742 + unsigned int li, b;
1744 + err = get_user(li, (unsigned int *)regs->nip);
1745 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1747 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1748 + unsigned int addis, lwz, mtctr, bctr;
1749 + unsigned long addr = b | 0xFC000000UL;
1751 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1752 + err = get_user(addis, (unsigned int *)addr);
1753 + err |= get_user(lwz, (unsigned int *)(addr+4));
1754 + err |= get_user(mtctr, (unsigned int *)(addr+8));
1755 + err |= get_user(bctr, (unsigned int *)(addr+12));
1760 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1761 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
1762 + mtctr == 0x7D6903A6U &&
1763 + bctr == 0x4E800420U)
1767 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1768 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1770 + err = get_user(r11, (unsigned int *)addr);
1774 + regs->gpr[PT_R11] = r11;
1783 +#ifdef CONFIG_PAX_EMUSIGRT
1784 + do { /* PaX: sigreturn emulation */
1785 + unsigned int li, sc;
1787 + err = get_user(li, (unsigned int *)regs->nip);
1788 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1790 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1791 + struct vm_area_struct *vma;
1792 + unsigned long call_syscall;
1794 + down_read(¤t->mm->mmap_sem);
1795 + call_syscall = current->mm->call_syscall;
1796 + up_read(¤t->mm->mmap_sem);
1797 + if (likely(call_syscall))
1800 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1802 + down_write(¤t->mm->mmap_sem);
1803 + if (current->mm->call_syscall) {
1804 + call_syscall = current->mm->call_syscall;
1805 + up_write(¤t->mm->mmap_sem);
1806 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1810 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1811 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1812 + up_write(¤t->mm->mmap_sem);
1813 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1817 + if (pax_insert_vma(vma, call_syscall)) {
1818 + up_write(¤t->mm->mmap_sem);
1819 + kmem_cache_free(vm_area_cachep, vma);
1823 + current->mm->call_syscall = call_syscall;
1824 + up_write(¤t->mm->mmap_sem);
1827 + regs->gpr[PT_R0] = __NR_sigreturn;
1828 + regs->nip = call_syscall;
1833 + do { /* PaX: rt_sigreturn emulation */
1834 + unsigned int li, sc;
1836 + err = get_user(li, (unsigned int *)regs->nip);
1837 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1839 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1840 + struct vm_area_struct *vma;
1841 + unsigned int call_syscall;
1843 + down_read(¤t->mm->mmap_sem);
1844 + call_syscall = current->mm->call_syscall;
1845 + up_read(¤t->mm->mmap_sem);
1846 + if (likely(call_syscall))
1849 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1851 + down_write(¤t->mm->mmap_sem);
1852 + if (current->mm->call_syscall) {
1853 + call_syscall = current->mm->call_syscall;
1854 + up_write(¤t->mm->mmap_sem);
1855 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1859 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1860 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1861 + up_write(¤t->mm->mmap_sem);
1862 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1866 + if (pax_insert_vma(vma, call_syscall)) {
1867 + up_write(¤t->mm->mmap_sem);
1868 + kmem_cache_free(vm_area_cachep, vma);
1872 + current->mm->call_syscall = call_syscall;
1873 + up_write(¤t->mm->mmap_sem);
1876 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
1877 + regs->nip = call_syscall;
1886 +void pax_report_insns(void *pc, void *sp)
1890 + printk(KERN_ERR "PAX: bytes at PC: ");
1891 + for (i = 0; i < 5; i++) {
1893 + if (get_user(c, (unsigned int *)pc+i))
1894 + printk("???????? ");
1896 + printk("%08x ", c);
1903 * Check whether the instruction at regs->nip is a store using
1904 * an update addressing form which will update r1.
1905 @@ -109,7 +471,7 @@ int do_page_fault(struct pt_regs *regs,
1906 * indicate errors in DSISR but can validly be set in SRR1.
1908 if (TRAP(regs) == 0x400)
1909 - error_code &= 0x48200000;
1910 + error_code &= 0x58200000;
1912 is_write = error_code & 0x02000000;
1913 #endif /* CONFIG_4xx || CONFIG_BOOKE */
1914 @@ -204,15 +566,14 @@ good_area:
1920 /* It would be nice to actually enforce the VM execute
1921 permission on CPUs which can do so, but far too
1922 much stuff in userspace doesn't get the permissions
1923 right, so we let any page be executed for now. */
1924 if (! (vma->vm_flags & VM_EXEC))
1929 /* Since 4xx/Book-E supports per-page execute permission,
1930 * we lazily flush dcache to icache. */
1932 @@ -235,6 +596,7 @@ good_area:
1933 pte_unmap_unlock(ptep, ptl);
1939 /* protection fault */
1940 @@ -278,6 +640,33 @@ bad_area:
1942 /* User mode accesses cause a SIGSEGV */
1943 if (user_mode(regs)) {
1945 +#ifdef CONFIG_PAX_PAGEEXEC
1946 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1947 + if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
1948 + switch (pax_handle_fetch_fault(regs)) {
1950 +#ifdef CONFIG_PAX_EMUPLT
1957 +#ifdef CONFIG_PAX_EMUSIGRT
1965 + pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
1966 + do_group_exit(SIGKILL);
1971 _exception(SIGSEGV, regs, code, address);
1974 diff -urNp linux-2.6.24.4/arch/s390/kernel/module.c linux-2.6.24.4/arch/s390/kernel/module.c
1975 --- linux-2.6.24.4/arch/s390/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
1976 +++ linux-2.6.24.4/arch/s390/kernel/module.c 2008-03-26 20:21:07.000000000 -0400
1977 @@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
1979 /* Increase core size by size of got & plt and set start
1980 offsets for got and plt. */
1981 - me->core_size = ALIGN(me->core_size, 4);
1982 - me->arch.got_offset = me->core_size;
1983 - me->core_size += me->arch.got_size;
1984 - me->arch.plt_offset = me->core_size;
1985 - me->core_size += me->arch.plt_size;
1986 + me->core_size_rw = ALIGN(me->core_size_rw, 4);
1987 + me->arch.got_offset = me->core_size_rw;
1988 + me->core_size_rw += me->arch.got_size;
1989 + me->arch.plt_offset = me->core_size_rx;
1990 + me->core_size_rx += me->arch.plt_size;
1994 @@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1995 if (info->got_initialized == 0) {
1998 - gotent = me->module_core + me->arch.got_offset +
1999 + gotent = me->module_core_rw + me->arch.got_offset +
2002 info->got_initialized = 1;
2003 @@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2004 else if (r_type == R_390_GOTENT ||
2005 r_type == R_390_GOTPLTENT)
2006 *(unsigned int *) loc =
2007 - (val + (Elf_Addr) me->module_core - loc) >> 1;
2008 + (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
2009 else if (r_type == R_390_GOT64 ||
2010 r_type == R_390_GOTPLT64)
2011 *(unsigned long *) loc = val;
2012 @@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2013 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
2014 if (info->plt_initialized == 0) {
2016 - ip = me->module_core + me->arch.plt_offset +
2017 + ip = me->module_core_rx + me->arch.plt_offset +
2019 #ifndef CONFIG_64BIT
2020 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
2021 @@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2022 val = me->arch.plt_offset - me->arch.got_offset +
2023 info->plt_offset + rela->r_addend;
2025 - val = (Elf_Addr) me->module_core +
2026 + val = (Elf_Addr) me->module_core_rx +
2027 me->arch.plt_offset + info->plt_offset +
2028 rela->r_addend - loc;
2029 if (r_type == R_390_PLT16DBL)
2030 @@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2031 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
2032 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
2033 val = val + rela->r_addend -
2034 - ((Elf_Addr) me->module_core + me->arch.got_offset);
2035 + ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
2036 if (r_type == R_390_GOTOFF16)
2037 *(unsigned short *) loc = val;
2038 else if (r_type == R_390_GOTOFF32)
2039 @@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2041 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
2042 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
2043 - val = (Elf_Addr) me->module_core + me->arch.got_offset +
2044 + val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
2045 rela->r_addend - loc;
2046 if (r_type == R_390_GOTPC)
2047 *(unsigned int *) loc = val;
2048 diff -urNp linux-2.6.24.4/arch/sparc/kernel/ptrace.c linux-2.6.24.4/arch/sparc/kernel/ptrace.c
2049 --- linux-2.6.24.4/arch/sparc/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400
2050 +++ linux-2.6.24.4/arch/sparc/kernel/ptrace.c 2008-03-26 20:21:07.000000000 -0400
2052 #include <linux/security.h>
2053 #include <linux/signal.h>
2054 #include <linux/vs_base.h>
2055 +#include <linux/grsecurity.h>
2057 #include <asm/pgtable.h>
2058 #include <asm/system.h>
2059 @@ -303,6 +304,11 @@ asmlinkage void do_ptrace(struct pt_regs
2063 + if (gr_handle_ptrace(child, request)) {
2064 + pt_error_return(regs, EPERM);
2068 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
2069 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
2070 if (ptrace_attach(child)) {
2071 diff -urNp linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c
2072 --- linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c 2008-03-24 14:49:18.000000000 -0400
2073 +++ linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c 2008-03-26 20:21:07.000000000 -0400
2074 @@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
2075 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
2078 - addr = TASK_UNMAPPED_BASE;
2079 + addr = current->mm->mmap_base;
2081 if (flags & MAP_SHARED)
2082 addr = COLOUR_ALIGN(addr);
2083 diff -urNp linux-2.6.24.4/arch/sparc/Makefile linux-2.6.24.4/arch/sparc/Makefile
2084 --- linux-2.6.24.4/arch/sparc/Makefile 2008-03-24 14:49:18.000000000 -0400
2085 +++ linux-2.6.24.4/arch/sparc/Makefile 2008-03-26 20:21:07.000000000 -0400
2086 @@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
2087 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
2088 INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
2090 -CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
2091 +CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
2092 CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
2093 DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
2094 NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
2095 diff -urNp linux-2.6.24.4/arch/sparc/mm/fault.c linux-2.6.24.4/arch/sparc/mm/fault.c
2096 --- linux-2.6.24.4/arch/sparc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
2097 +++ linux-2.6.24.4/arch/sparc/mm/fault.c 2008-03-26 20:21:07.000000000 -0400
2099 #include <linux/interrupt.h>
2100 #include <linux/module.h>
2101 #include <linux/kdebug.h>
2102 +#include <linux/slab.h>
2103 +#include <linux/pagemap.h>
2104 +#include <linux/compiler.h>
2105 +#include <linux/binfmts.h>
2107 #include <asm/system.h>
2108 #include <asm/page.h>
2109 @@ -216,6 +220,251 @@ static unsigned long compute_si_addr(str
2110 return safe_compute_effective_address(regs, insn);
2113 +#ifdef CONFIG_PAX_PAGEEXEC
2114 +void pax_emuplt_close(struct vm_area_struct *vma)
2116 + vma->vm_mm->call_dl_resolve = 0UL;
2119 +static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2121 + struct page *page;
2122 + unsigned int *kaddr;
2124 + page = alloc_page(GFP_HIGHUSER);
2126 + return NOPAGE_OOM;
2128 + kaddr = kmap(page);
2129 + memset(kaddr, 0, PAGE_SIZE);
2130 + kaddr[0] = 0x9DE3BFA8U; /* save */
2131 + flush_dcache_page(page);
2134 + *type = VM_FAULT_MAJOR;
2139 +static struct vm_operations_struct pax_vm_ops = {
2140 + .close = pax_emuplt_close,
2141 + .nopage = pax_emuplt_nopage,
2144 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2148 + vma->vm_mm = current->mm;
2149 + vma->vm_start = addr;
2150 + vma->vm_end = addr + PAGE_SIZE;
2151 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2152 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2153 + vma->vm_ops = &pax_vm_ops;
2155 + ret = insert_vm_struct(current->mm, vma);
2159 + ++current->mm->total_vm;
2164 + * PaX: decide what to do with offenders (regs->pc = fault address)
2166 + * returns 1 when task should be killed
2167 + * 2 when patched PLT trampoline was detected
2168 + * 3 when unpatched PLT trampoline was detected
2170 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2173 +#ifdef CONFIG_PAX_EMUPLT
2176 + do { /* PaX: patched PLT emulation #1 */
2177 + unsigned int sethi1, sethi2, jmpl;
2179 + err = get_user(sethi1, (unsigned int *)regs->pc);
2180 + err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
2181 + err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
2186 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2187 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2188 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2190 + unsigned int addr;
2192 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2193 + addr = regs->u_regs[UREG_G1];
2194 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2196 + regs->npc = addr+4;
2201 + { /* PaX: patched PLT emulation #2 */
2204 + err = get_user(ba, (unsigned int *)regs->pc);
2206 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2207 + unsigned int addr;
2209 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2211 + regs->npc = addr+4;
2216 + do { /* PaX: patched PLT emulation #3 */
2217 + unsigned int sethi, jmpl, nop;
2219 + err = get_user(sethi, (unsigned int *)regs->pc);
2220 + err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
2221 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
2226 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2227 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2228 + nop == 0x01000000U)
2230 + unsigned int addr;
2232 + addr = (sethi & 0x003FFFFFU) << 10;
2233 + regs->u_regs[UREG_G1] = addr;
2234 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2236 + regs->npc = addr+4;
2241 + do { /* PaX: unpatched PLT emulation step 1 */
2242 + unsigned int sethi, ba, nop;
2244 + err = get_user(sethi, (unsigned int *)regs->pc);
2245 + err |= get_user(ba, (unsigned int *)(regs->pc+4));
2246 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
2251 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2252 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2253 + nop == 0x01000000U)
2255 + unsigned int addr, save, call;
2257 + if ((ba & 0xFFC00000U) == 0x30800000U)
2258 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2260 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2262 + err = get_user(save, (unsigned int *)addr);
2263 + err |= get_user(call, (unsigned int *)(addr+4));
2264 + err |= get_user(nop, (unsigned int *)(addr+8));
2268 + if (save == 0x9DE3BFA8U &&
2269 + (call & 0xC0000000U) == 0x40000000U &&
2270 + nop == 0x01000000U)
2272 + struct vm_area_struct *vma;
2273 + unsigned long call_dl_resolve;
2275 + down_read(¤t->mm->mmap_sem);
2276 + call_dl_resolve = current->mm->call_dl_resolve;
2277 + up_read(¤t->mm->mmap_sem);
2278 + if (likely(call_dl_resolve))
2281 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2283 + down_write(¤t->mm->mmap_sem);
2284 + if (current->mm->call_dl_resolve) {
2285 + call_dl_resolve = current->mm->call_dl_resolve;
2286 + up_write(¤t->mm->mmap_sem);
2287 + if (vma) kmem_cache_free(vm_area_cachep, vma);
2291 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2292 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2293 + up_write(¤t->mm->mmap_sem);
2294 + if (vma) kmem_cache_free(vm_area_cachep, vma);
2298 + if (pax_insert_vma(vma, call_dl_resolve)) {
2299 + up_write(¤t->mm->mmap_sem);
2300 + kmem_cache_free(vm_area_cachep, vma);
2304 + current->mm->call_dl_resolve = call_dl_resolve;
2305 + up_write(¤t->mm->mmap_sem);
2308 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2309 + regs->pc = call_dl_resolve;
2310 + regs->npc = addr+4;
2316 + do { /* PaX: unpatched PLT emulation step 2 */
2317 + unsigned int save, call, nop;
2319 + err = get_user(save, (unsigned int *)(regs->pc-4));
2320 + err |= get_user(call, (unsigned int *)regs->pc);
2321 + err |= get_user(nop, (unsigned int *)(regs->pc+4));
2325 + if (save == 0x9DE3BFA8U &&
2326 + (call & 0xC0000000U) == 0x40000000U &&
2327 + nop == 0x01000000U)
2329 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2331 + regs->u_regs[UREG_RETPC] = regs->pc;
2332 + regs->pc = dl_resolve;
2333 + regs->npc = dl_resolve+4;
2342 +void pax_report_insns(void *pc, void *sp)
2346 + printk(KERN_ERR "PAX: bytes at PC: ");
2347 + for (i = 0; i < 5; i++) {
2349 + if (get_user(c, (unsigned int *)pc+i))
2350 + printk("???????? ");
2352 + printk("%08x ", c);
2358 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2359 unsigned long address)
2361 @@ -280,6 +529,24 @@ good_area:
2362 if(!(vma->vm_flags & VM_WRITE))
2366 +#ifdef CONFIG_PAX_PAGEEXEC
2367 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
2368 + up_read(&mm->mmap_sem);
2369 + switch (pax_handle_fetch_fault(regs)) {
2371 +#ifdef CONFIG_PAX_EMUPLT
2378 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2379 + do_group_exit(SIGKILL);
2383 /* Allow reads even for write-only mappings */
2384 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2386 diff -urNp linux-2.6.24.4/arch/sparc/mm/init.c linux-2.6.24.4/arch/sparc/mm/init.c
2387 --- linux-2.6.24.4/arch/sparc/mm/init.c 2008-03-24 14:49:18.000000000 -0400
2388 +++ linux-2.6.24.4/arch/sparc/mm/init.c 2008-03-26 20:21:07.000000000 -0400
2389 @@ -336,17 +336,17 @@ void __init paging_init(void)
2391 /* Initialize the protection map with non-constant, MMU dependent values. */
2392 protection_map[0] = PAGE_NONE;
2393 - protection_map[1] = PAGE_READONLY;
2394 - protection_map[2] = PAGE_COPY;
2395 - protection_map[3] = PAGE_COPY;
2396 + protection_map[1] = PAGE_READONLY_NOEXEC;
2397 + protection_map[2] = PAGE_COPY_NOEXEC;
2398 + protection_map[3] = PAGE_COPY_NOEXEC;
2399 protection_map[4] = PAGE_READONLY;
2400 protection_map[5] = PAGE_READONLY;
2401 protection_map[6] = PAGE_COPY;
2402 protection_map[7] = PAGE_COPY;
2403 protection_map[8] = PAGE_NONE;
2404 - protection_map[9] = PAGE_READONLY;
2405 - protection_map[10] = PAGE_SHARED;
2406 - protection_map[11] = PAGE_SHARED;
2407 + protection_map[9] = PAGE_READONLY_NOEXEC;
2408 + protection_map[10] = PAGE_SHARED_NOEXEC;
2409 + protection_map[11] = PAGE_SHARED_NOEXEC;
2410 protection_map[12] = PAGE_READONLY;
2411 protection_map[13] = PAGE_READONLY;
2412 protection_map[14] = PAGE_SHARED;
2413 diff -urNp linux-2.6.24.4/arch/sparc/mm/srmmu.c linux-2.6.24.4/arch/sparc/mm/srmmu.c
2414 --- linux-2.6.24.4/arch/sparc/mm/srmmu.c 2008-03-24 14:49:18.000000000 -0400
2415 +++ linux-2.6.24.4/arch/sparc/mm/srmmu.c 2008-03-26 20:21:07.000000000 -0400
2416 @@ -2157,6 +2157,13 @@ void __init ld_mmu_srmmu(void)
2417 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
2418 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
2419 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
2421 +#ifdef CONFIG_PAX_PAGEEXEC
2422 + PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2423 + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2424 + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2427 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2428 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2430 diff -urNp linux-2.6.24.4/arch/sparc64/kernel/Makefile linux-2.6.24.4/arch/sparc64/kernel/Makefile
2431 --- linux-2.6.24.4/arch/sparc64/kernel/Makefile 2008-03-24 14:49:18.000000000 -0400
2432 +++ linux-2.6.24.4/arch/sparc64/kernel/Makefile 2008-03-26 20:21:07.000000000 -0400
2436 EXTRA_AFLAGS := -ansi
2437 -EXTRA_CFLAGS := -Werror
2438 +#EXTRA_CFLAGS := -Werror
2440 extra-y := head.o init_task.o vmlinux.lds
2442 diff -urNp linux-2.6.24.4/arch/sparc64/kernel/ptrace.c linux-2.6.24.4/arch/sparc64/kernel/ptrace.c
2443 --- linux-2.6.24.4/arch/sparc64/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400
2444 +++ linux-2.6.24.4/arch/sparc64/kernel/ptrace.c 2008-03-26 20:21:07.000000000 -0400
2446 #include <linux/audit.h>
2447 #include <linux/signal.h>
2448 #include <linux/vs_base.h>
2449 +#include <linux/grsecurity.h>
2451 #include <asm/asi.h>
2452 #include <asm/pgtable.h>
2453 @@ -216,6 +217,11 @@ asmlinkage void do_ptrace(struct pt_regs
2457 + if (gr_handle_ptrace(child, (long)request)) {
2458 + pt_error_return(regs, EPERM);
2462 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
2463 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
2464 if (ptrace_attach(child)) {
2465 diff -urNp linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c
2466 --- linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c 2008-03-24 14:49:18.000000000 -0400
2467 +++ linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c 2008-03-26 20:21:07.000000000 -0400
2468 @@ -123,7 +123,7 @@ unsigned long arch_get_unmapped_area(str
2469 /* We do not accept a shared mapping if it would violate
2470 * cache aliasing constraints.
2472 - if ((flags & MAP_SHARED) &&
2473 + if ((filp || (flags & MAP_SHARED)) &&
2474 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2477 @@ -138,6 +138,10 @@ unsigned long arch_get_unmapped_area(str
2478 if (filp || (flags & MAP_SHARED))
2481 +#ifdef CONFIG_PAX_RANDMMAP
2482 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2487 addr = COLOUR_ALIGN(addr, pgoff);
2488 @@ -151,9 +155,9 @@ unsigned long arch_get_unmapped_area(str
2491 if (len > mm->cached_hole_size) {
2492 - start_addr = addr = mm->free_area_cache;
2493 + start_addr = addr = mm->free_area_cache;
2495 - start_addr = addr = TASK_UNMAPPED_BASE;
2496 + start_addr = addr = mm->mmap_base;
2497 mm->cached_hole_size = 0;
2500 @@ -173,8 +177,8 @@ full_search:
2501 vma = find_vma(mm, VA_EXCLUDE_END);
2503 if (unlikely(task_size < addr)) {
2504 - if (start_addr != TASK_UNMAPPED_BASE) {
2505 - start_addr = addr = TASK_UNMAPPED_BASE;
2506 + if (start_addr != mm->mmap_base) {
2507 + start_addr = addr = mm->mmap_base;
2508 mm->cached_hole_size = 0;
2511 @@ -214,7 +218,7 @@ arch_get_unmapped_area_topdown(struct fi
2512 /* We do not accept a shared mapping if it would violate
2513 * cache aliasing constraints.
2515 - if ((flags & MAP_SHARED) &&
2516 + if ((filp || (flags & MAP_SHARED)) &&
2517 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2520 @@ -377,6 +381,12 @@ void arch_pick_mmap_layout(struct mm_str
2521 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2522 sysctl_legacy_va_layout) {
2523 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2525 +#ifdef CONFIG_PAX_RANDMMAP
2526 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2527 + mm->mmap_base += mm->delta_mmap;
2530 mm->get_unmapped_area = arch_get_unmapped_area;
2531 mm->unmap_area = arch_unmap_area;
2533 @@ -391,6 +401,12 @@ void arch_pick_mmap_layout(struct mm_str
2534 gap = (task_size / 6 * 5);
2536 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2538 +#ifdef CONFIG_PAX_RANDMMAP
2539 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2540 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2543 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2544 mm->unmap_area = arch_unmap_area_topdown;
2546 diff -urNp linux-2.6.24.4/arch/sparc64/mm/fault.c linux-2.6.24.4/arch/sparc64/mm/fault.c
2547 --- linux-2.6.24.4/arch/sparc64/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
2548 +++ linux-2.6.24.4/arch/sparc64/mm/fault.c 2008-03-26 20:21:07.000000000 -0400
2550 #include <linux/kprobes.h>
2551 #include <linux/kallsyms.h>
2552 #include <linux/kdebug.h>
2553 +#include <linux/slab.h>
2554 +#include <linux/pagemap.h>
2555 +#include <linux/compiler.h>
2556 +#include <linux/binfmts.h>
2558 #include <asm/page.h>
2559 #include <asm/pgtable.h>
2560 @@ -262,6 +266,368 @@ cannot_handle:
2561 unhandled_fault (address, current, regs);
2564 +#ifdef CONFIG_PAX_PAGEEXEC
2565 +#ifdef CONFIG_PAX_EMUPLT
2566 +static void pax_emuplt_close(struct vm_area_struct *vma)
2568 + vma->vm_mm->call_dl_resolve = 0UL;
2571 +static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2573 + struct page *page;
2574 + unsigned int *kaddr;
2576 + page = alloc_page(GFP_HIGHUSER);
2578 + return NOPAGE_OOM;
2580 + kaddr = kmap(page);
2581 + memset(kaddr, 0, PAGE_SIZE);
2582 + kaddr[0] = 0x9DE3BFA8U; /* save */
2583 + flush_dcache_page(page);
2586 + *type = VM_FAULT_MAJOR;
2590 +static struct vm_operations_struct pax_vm_ops = {
2591 + .close = pax_emuplt_close,
2592 + .nopage = pax_emuplt_nopage,
2595 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2599 + vma->vm_mm = current->mm;
2600 + vma->vm_start = addr;
2601 + vma->vm_end = addr + PAGE_SIZE;
2602 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2603 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2604 + vma->vm_ops = &pax_vm_ops;
2606 + ret = insert_vm_struct(current->mm, vma);
2610 + ++current->mm->total_vm;
2616 + * PaX: decide what to do with offenders (regs->tpc = fault address)
2618 + * returns 1 when task should be killed
2619 + * 2 when patched PLT trampoline was detected
2620 + * 3 when unpatched PLT trampoline was detected
2622 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2625 +#ifdef CONFIG_PAX_EMUPLT
2628 + do { /* PaX: patched PLT emulation #1 */
2629 + unsigned int sethi1, sethi2, jmpl;
2631 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2632 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2633 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
2638 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2639 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2640 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2642 + unsigned long addr;
2644 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2645 + addr = regs->u_regs[UREG_G1];
2646 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2648 + regs->tnpc = addr+4;
2653 + { /* PaX: patched PLT emulation #2 */
2656 + err = get_user(ba, (unsigned int *)regs->tpc);
2658 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2659 + unsigned long addr;
2661 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2663 + regs->tnpc = addr+4;
2668 + do { /* PaX: patched PLT emulation #3 */
2669 + unsigned int sethi, jmpl, nop;
2671 + err = get_user(sethi, (unsigned int *)regs->tpc);
2672 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
2673 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2678 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2679 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2680 + nop == 0x01000000U)
2682 + unsigned long addr;
2684 + addr = (sethi & 0x003FFFFFU) << 10;
2685 + regs->u_regs[UREG_G1] = addr;
2686 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2688 + regs->tnpc = addr+4;
2693 + do { /* PaX: patched PLT emulation #4 */
2694 + unsigned int mov1, call, mov2;
2696 + err = get_user(mov1, (unsigned int *)regs->tpc);
2697 + err |= get_user(call, (unsigned int *)(regs->tpc+4));
2698 + err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
2703 + if (mov1 == 0x8210000FU &&
2704 + (call & 0xC0000000U) == 0x40000000U &&
2705 + mov2 == 0x9E100001U)
2707 + unsigned long addr;
2709 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2710 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2712 + regs->tnpc = addr+4;
2717 + do { /* PaX: patched PLT emulation #5 */
2718 + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
2720 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2721 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2722 + err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2723 + err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2724 + err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2725 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2726 + err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2731 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2732 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2733 + (or1 & 0xFFFFE000U) == 0x82106000U &&
2734 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
2735 + sllx == 0x83287020 &&
2736 + jmpl == 0x81C04005U &&
2737 + nop == 0x01000000U)
2739 + unsigned long addr;
2741 + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2742 + regs->u_regs[UREG_G1] <<= 32;
2743 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2744 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2746 + regs->tnpc = addr+4;
2751 + do { /* PaX: patched PLT emulation #6 */
2752 + unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
2754 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2755 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2756 + err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2757 + err |= get_user(or, (unsigned int *)(regs->tpc+12));
2758 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2759 + err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2764 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2765 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2766 + sllx == 0x83287020 &&
2767 + (or & 0xFFFFE000U) == 0x8A116000U &&
2768 + jmpl == 0x81C04005U &&
2769 + nop == 0x01000000U)
2771 + unsigned long addr;
2773 + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2774 + regs->u_regs[UREG_G1] <<= 32;
2775 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2776 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2778 + regs->tnpc = addr+4;
2783 + do { /* PaX: patched PLT emulation #7 */
2784 + unsigned int sethi, ba, nop;
2786 + err = get_user(sethi, (unsigned int *)regs->tpc);
2787 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2788 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2793 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2794 + (ba & 0xFFF00000U) == 0x30600000U &&
2795 + nop == 0x01000000U)
2797 + unsigned long addr;
2799 + addr = (sethi & 0x003FFFFFU) << 10;
2800 + regs->u_regs[UREG_G1] = addr;
2801 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2803 + regs->tnpc = addr+4;
2808 + do { /* PaX: unpatched PLT emulation step 1 */
2809 + unsigned int sethi, ba, nop;
2811 + err = get_user(sethi, (unsigned int *)regs->tpc);
2812 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2813 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2818 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2819 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2820 + nop == 0x01000000U)
2822 + unsigned long addr;
2823 + unsigned int save, call;
2825 + if ((ba & 0xFFC00000U) == 0x30800000U)
2826 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2828 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2830 + err = get_user(save, (unsigned int *)addr);
2831 + err |= get_user(call, (unsigned int *)(addr+4));
2832 + err |= get_user(nop, (unsigned int *)(addr+8));
2836 + if (save == 0x9DE3BFA8U &&
2837 + (call & 0xC0000000U) == 0x40000000U &&
2838 + nop == 0x01000000U)
2840 + struct vm_area_struct *vma;
2841 + unsigned long call_dl_resolve;
2843 + down_read(¤t->mm->mmap_sem);
2844 + call_dl_resolve = current->mm->call_dl_resolve;
2845 + up_read(¤t->mm->mmap_sem);
2846 + if (likely(call_dl_resolve))
2849 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2851 + down_write(¤t->mm->mmap_sem);
2852 + if (current->mm->call_dl_resolve) {
2853 + call_dl_resolve = current->mm->call_dl_resolve;
2854 + up_write(¤t->mm->mmap_sem);
2855 + if (vma) kmem_cache_free(vm_area_cachep, vma);
2859 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2860 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2861 + up_write(¤t->mm->mmap_sem);
2862 + if (vma) kmem_cache_free(vm_area_cachep, vma);
2866 + if (pax_insert_vma(vma, call_dl_resolve)) {
2867 + up_write(¤t->mm->mmap_sem);
2868 + kmem_cache_free(vm_area_cachep, vma);
2872 + current->mm->call_dl_resolve = call_dl_resolve;
2873 + up_write(¤t->mm->mmap_sem);
2876 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2877 + regs->tpc = call_dl_resolve;
2878 + regs->tnpc = addr+4;
2884 + do { /* PaX: unpatched PLT emulation step 2 */
2885 + unsigned int save, call, nop;
2887 + err = get_user(save, (unsigned int *)(regs->tpc-4));
2888 + err |= get_user(call, (unsigned int *)regs->tpc);
2889 + err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2893 + if (save == 0x9DE3BFA8U &&
2894 + (call & 0xC0000000U) == 0x40000000U &&
2895 + nop == 0x01000000U)
2897 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2899 + regs->u_regs[UREG_RETPC] = regs->tpc;
2900 + regs->tpc = dl_resolve;
2901 + regs->tnpc = dl_resolve+4;
2910 +void pax_report_insns(void *pc, void *sp)
2914 + printk(KERN_ERR "PAX: bytes at PC: ");
2915 + for (i = 0; i < 5; i++) {
2917 + if (get_user(c, (unsigned int *)pc+i))
2918 + printk("???????? ");
2920 + printk("%08x ", c);
2926 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2928 struct mm_struct *mm = current->mm;
2929 @@ -303,8 +669,10 @@ asmlinkage void __kprobes do_sparc64_fau
2932 if (test_thread_flag(TIF_32BIT)) {
2933 - if (!(regs->tstate & TSTATE_PRIV))
2934 + if (!(regs->tstate & TSTATE_PRIV)) {
2935 regs->tpc &= 0xffffffff;
2936 + regs->tnpc &= 0xffffffff;
2938 address &= 0xffffffff;
2941 @@ -321,6 +689,29 @@ asmlinkage void __kprobes do_sparc64_fau
2945 +#ifdef CONFIG_PAX_PAGEEXEC
2946 + /* PaX: detect ITLB misses on non-exec pages */
2947 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2948 + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2950 + if (address != regs->tpc)
2953 + up_read(&mm->mmap_sem);
2954 + switch (pax_handle_fetch_fault(regs)) {
2956 +#ifdef CONFIG_PAX_EMUPLT
2963 + pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
2964 + do_group_exit(SIGKILL);
2968 /* Pure DTLB misses do not tell us whether the fault causing
2969 * load/store/atomic was a write or not, it only says that there
2970 * was no match. So in such a case we (carefully) read the
2971 diff -urNp linux-2.6.24.4/arch/sparc64/mm/Makefile linux-2.6.24.4/arch/sparc64/mm/Makefile
2972 --- linux-2.6.24.4/arch/sparc64/mm/Makefile 2008-03-24 14:49:18.000000000 -0400
2973 +++ linux-2.6.24.4/arch/sparc64/mm/Makefile 2008-03-26 20:21:07.000000000 -0400
2977 EXTRA_AFLAGS := -ansi
2978 -EXTRA_CFLAGS := -Werror
2979 +#EXTRA_CFLAGS := -Werror
2981 obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
2983 diff -urNp linux-2.6.24.4/arch/v850/kernel/module.c linux-2.6.24.4/arch/v850/kernel/module.c
2984 --- linux-2.6.24.4/arch/v850/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
2985 +++ linux-2.6.24.4/arch/v850/kernel/module.c 2008-03-26 20:21:07.000000000 -0400
2986 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
2987 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
2989 /* Init, or core PLT? */
2990 - if (location >= mod->module_core
2991 - && location < mod->module_core + mod->core_size)
2992 + if (location >= mod->module_core_rx
2993 + && location < mod->module_core_rx + mod->core_size_rx)
2994 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
2996 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
2997 diff -urNp linux-2.6.24.4/arch/x86/boot/bitops.h linux-2.6.24.4/arch/x86/boot/bitops.h
2998 --- linux-2.6.24.4/arch/x86/boot/bitops.h 2008-03-24 14:49:18.000000000 -0400
2999 +++ linux-2.6.24.4/arch/x86/boot/bitops.h 2008-03-26 20:21:07.000000000 -0400
3000 @@ -28,7 +28,7 @@ static inline int variable_test_bit(int
3002 const u32 *p = (const u32 *)addr;
3004 - asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3005 + asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3009 @@ -39,7 +39,7 @@ static inline int variable_test_bit(int
3011 static inline void set_bit(int nr, void *addr)
3013 - asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3014 + asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3017 #endif /* BOOT_BITOPS_H */
3018 diff -urNp linux-2.6.24.4/arch/x86/boot/boot.h linux-2.6.24.4/arch/x86/boot/boot.h
3019 --- linux-2.6.24.4/arch/x86/boot/boot.h 2008-03-24 14:49:18.000000000 -0400
3020 +++ linux-2.6.24.4/arch/x86/boot/boot.h 2008-03-26 20:21:07.000000000 -0400
3021 @@ -78,7 +78,7 @@ static inline void io_delay(void)
3022 static inline u16 ds(void)
3025 - asm("movw %%ds,%0" : "=rm" (seg));
3026 + asm volatile("movw %%ds,%0" : "=rm" (seg));
3030 @@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t
3031 static inline int memcmp(const void *s1, const void *s2, size_t len)
3034 - asm("repe; cmpsb; setnz %0"
3035 + asm volatile("repe; cmpsb; setnz %0"
3036 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
3039 diff -urNp linux-2.6.24.4/arch/x86/boot/compressed/head_32.S linux-2.6.24.4/arch/x86/boot/compressed/head_32.S
3040 --- linux-2.6.24.4/arch/x86/boot/compressed/head_32.S 2008-03-24 14:49:18.000000000 -0400
3041 +++ linux-2.6.24.4/arch/x86/boot/compressed/head_32.S 2008-03-26 20:21:07.000000000 -0400
3042 @@ -70,7 +70,7 @@ startup_32:
3043 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
3044 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
3046 - movl $LOAD_PHYSICAL_ADDR, %ebx
3047 + movl $____LOAD_PHYSICAL_ADDR, %ebx
3050 /* Replace the compressed data size with the uncompressed size */
3051 @@ -105,7 +105,7 @@ startup_32:
3052 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
3053 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
3055 - movl $LOAD_PHYSICAL_ADDR, %ebp
3056 + movl $____LOAD_PHYSICAL_ADDR, %ebp
3060 @@ -159,16 +159,15 @@ relocated:
3061 * and where it was actually loaded.
3064 - subl $LOAD_PHYSICAL_ADDR, %ebx
3065 + subl $____LOAD_PHYSICAL_ADDR, %ebx
3066 jz 2f /* Nothing to be done if loaded at compiled addr. */
3068 * Process relocations.
3072 - movl 0(%edi), %ecx
3077 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
3080 diff -urNp linux-2.6.24.4/arch/x86/boot/compressed/misc_32.c linux-2.6.24.4/arch/x86/boot/compressed/misc_32.c
3081 --- linux-2.6.24.4/arch/x86/boot/compressed/misc_32.c 2008-03-24 14:49:18.000000000 -0400
3082 +++ linux-2.6.24.4/arch/x86/boot/compressed/misc_32.c 2008-03-26 20:21:07.000000000 -0400
3083 @@ -113,7 +113,8 @@ typedef unsigned char uch;
3084 typedef unsigned short ush;
3085 typedef unsigned long ulg;
3087 -#define WSIZE 0x80000000 /* Window size must be at least 32k,
3088 +#define WSIZE 0x80000000
3089 + /* Window size must be at least 32k,
3090 * and a power of two
3091 * We don't actually have a window just
3092 * a huge output buffer so I report
3093 @@ -370,7 +371,7 @@ asmlinkage void decompress_kernel(void *
3094 if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff))
3095 error("Destination address too large");
3096 #ifndef CONFIG_RELOCATABLE
3097 - if ((u32)output != LOAD_PHYSICAL_ADDR)
3098 + if ((u32)output != ____LOAD_PHYSICAL_ADDR)
3099 error("Wrong destination address");
3102 diff -urNp linux-2.6.24.4/arch/x86/boot/compressed/relocs.c linux-2.6.24.4/arch/x86/boot/compressed/relocs.c
3103 --- linux-2.6.24.4/arch/x86/boot/compressed/relocs.c 2008-03-24 14:49:18.000000000 -0400
3104 +++ linux-2.6.24.4/arch/x86/boot/compressed/relocs.c 2008-03-26 20:21:07.000000000 -0400
3109 +#include "../../../../include/linux/autoconf.h"
3111 +#define MAX_PHDRS 100
3112 #define MAX_SHDRS 100
3113 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3114 static Elf32_Ehdr ehdr;
3115 +static Elf32_Phdr phdr[MAX_PHDRS];
3116 static Elf32_Shdr shdr[MAX_SHDRS];
3117 static Elf32_Sym *symtab[MAX_SHDRS];
3118 static Elf32_Rel *reltab[MAX_SHDRS];
3119 @@ -244,6 +248,34 @@ static void read_ehdr(FILE *fp)
3123 +static void read_phdrs(FILE *fp)
3126 + if (ehdr.e_phnum > MAX_PHDRS) {
3127 + die("%d program headers supported: %d\n",
3128 + ehdr.e_phnum, MAX_PHDRS);
3130 + if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3131 + die("Seek to %d failed: %s\n",
3132 + ehdr.e_phoff, strerror(errno));
3134 + if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3135 + die("Cannot read ELF program headers: %s\n",
3138 + for(i = 0; i < ehdr.e_phnum; i++) {
3139 + phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
3140 + phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
3141 + phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
3142 + phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
3143 + phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
3144 + phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
3145 + phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
3146 + phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
3151 static void read_shdrs(FILE *fp)
3154 @@ -330,6 +362,8 @@ static void read_symtabs(FILE *fp)
3155 static void read_relocs(FILE *fp)
3160 for(i = 0; i < ehdr.e_shnum; i++) {
3161 if (shdr[i].sh_type != SHT_REL) {
3163 @@ -347,8 +381,17 @@ static void read_relocs(FILE *fp)
3164 die("Cannot read symbol table: %s\n",
3168 + for (j = 0; j < ehdr.e_phnum; j++) {
3169 + if (phdr[j].p_type != PT_LOAD )
3171 + if (shdr[shdr[i].sh_info].sh_offset < phdr[j].p_offset || shdr[shdr[i].sh_info].sh_offset > phdr[j].p_offset + phdr[j].p_filesz)
3173 + base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3176 for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
3177 - reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
3178 + reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
3179 reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info);
3182 @@ -485,6 +528,27 @@ static void walk_relocs(void (*visit)(El
3183 if (sym->st_shndx == SHN_ABS) {
3186 + /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
3187 + if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10)) {
3190 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3191 + /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3192 + if (!strcmp(sec_name(sym->st_shndx), ".init.text")) {
3195 + if (!strcmp(sec_name(sym->st_shndx), ".exit.text")) {
3198 + if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3199 + if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3200 + strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3203 + if (!strcmp(sec_name(sym->st_shndx), ".text")) {
3207 if (r_type == R_386_PC32) {
3208 /* PC relative relocations don't need to be adjusted */
3210 @@ -612,6 +676,7 @@ int main(int argc, char **argv)
3211 fname, strerror(errno));
3218 diff -urNp linux-2.6.24.4/arch/x86/boot/cpucheck.c linux-2.6.24.4/arch/x86/boot/cpucheck.c
3219 --- linux-2.6.24.4/arch/x86/boot/cpucheck.c 2008-03-24 14:49:18.000000000 -0400
3220 +++ linux-2.6.24.4/arch/x86/boot/cpucheck.c 2008-03-26 20:21:07.000000000 -0400
3221 @@ -84,7 +84,7 @@ static int has_fpu(void)
3222 u16 fcw = -1, fsw = -1;
3225 - asm("movl %%cr0,%0" : "=r" (cr0));
3226 + asm volatile("movl %%cr0,%0" : "=r" (cr0));
3227 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3228 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3229 asm volatile("movl %0,%%cr0" : : "r" (cr0));
3230 @@ -100,7 +100,7 @@ static int has_eflag(u32 mask)
3235 + asm volatile("pushfl ; "
3239 @@ -125,7 +125,7 @@ static void get_flags(void)
3240 set_bit(X86_FEATURE_FPU, cpu.flags);
3242 if (has_eflag(X86_EFLAGS_ID)) {
3244 + asm volatile("cpuid"
3245 : "=a" (max_intel_level),
3246 "=b" (cpu_vendor[0]),
3247 "=d" (cpu_vendor[1]),
3248 @@ -134,7 +134,7 @@ static void get_flags(void)
3250 if (max_intel_level >= 0x00000001 &&
3251 max_intel_level <= 0x0000ffff) {
3253 + asm volatile("cpuid"
3255 "=c" (cpu.flags[4]),
3257 @@ -146,7 +146,7 @@ static void get_flags(void)
3258 cpu.model += ((tfms >> 16) & 0xf) << 4;
3262 + asm volatile("cpuid"
3263 : "=a" (max_amd_level)
3265 : "ebx", "ecx", "edx");
3266 @@ -154,7 +154,7 @@ static void get_flags(void)
3267 if (max_amd_level >= 0x80000001 &&
3268 max_amd_level <= 0x8000ffff) {
3269 u32 eax = 0x80000001;
3271 + asm volatile("cpuid"
3273 "=c" (cpu.flags[6]),
3275 @@ -213,9 +213,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3276 u32 ecx = MSR_K7_HWCR;
3279 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3280 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3282 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3283 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3285 get_flags(); /* Make sure it really did something */
3286 err = check_flags();
3287 @@ -228,9 +228,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3288 u32 ecx = MSR_VIA_FCR;
3291 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3292 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3293 eax |= (1<<1)|(1<<7);
3294 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3295 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3297 set_bit(X86_FEATURE_CX8, cpu.flags);
3298 err = check_flags();
3299 @@ -241,12 +241,12 @@ int check_cpu(int *cpu_level_ptr, int *r
3303 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3304 - asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3306 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3307 + asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3308 + asm volatile("cpuid"
3309 : "+a" (level), "=d" (cpu.flags[0])
3311 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3312 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3314 err = check_flags();
3316 diff -urNp linux-2.6.24.4/arch/x86/boot/edd.c linux-2.6.24.4/arch/x86/boot/edd.c
3317 --- linux-2.6.24.4/arch/x86/boot/edd.c 2008-03-24 14:49:18.000000000 -0400
3318 +++ linux-2.6.24.4/arch/x86/boot/edd.c 2008-03-26 20:21:07.000000000 -0400
3319 @@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct
3323 - asm("pushfl; stc; int $0x13; setc %%al; popfl"
3324 + asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
3325 : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3328 @@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct
3329 ei->params.length = sizeof(ei->params);
3332 - asm("pushfl; int $0x13; popfl"
3333 + asm volatile("pushfl; int $0x13; popfl"
3334 : "+a" (ax), "+d" (dx), "=m" (ei->params)
3336 : "ebx", "ecx", "edi");
3337 @@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct
3341 - asm("pushw %%es; "
3342 + asm volatile("pushw %%es; "
3344 "pushfl; stc; int $0x13; setc %%al; popfl; "
3346 diff -urNp linux-2.6.24.4/arch/x86/boot/main.c linux-2.6.24.4/arch/x86/boot/main.c
3347 --- linux-2.6.24.4/arch/x86/boot/main.c 2008-03-24 14:49:18.000000000 -0400
3348 +++ linux-2.6.24.4/arch/x86/boot/main.c 2008-03-26 20:21:07.000000000 -0400
3349 @@ -75,7 +75,7 @@ static void keyboard_set_repeat(void)
3351 static void query_ist(void)
3354 + asm volatile("int $0x15"
3355 : "=a" (boot_params.ist_info.signature),
3356 "=b" (boot_params.ist_info.command),
3357 "=c" (boot_params.ist_info.event),
3358 diff -urNp linux-2.6.24.4/arch/x86/boot/mca.c linux-2.6.24.4/arch/x86/boot/mca.c
3359 --- linux-2.6.24.4/arch/x86/boot/mca.c 2008-03-24 14:49:18.000000000 -0400
3360 +++ linux-2.6.24.4/arch/x86/boot/mca.c 2008-03-26 20:21:07.000000000 -0400
3361 @@ -21,7 +21,7 @@ int query_mca(void)
3365 - asm("pushw %%es ; "
3366 + asm volatile("pushw %%es ; "
3370 diff -urNp linux-2.6.24.4/arch/x86/boot/memory.c linux-2.6.24.4/arch/x86/boot/memory.c
3371 --- linux-2.6.24.4/arch/x86/boot/memory.c 2008-03-24 14:49:18.000000000 -0400
3372 +++ linux-2.6.24.4/arch/x86/boot/memory.c 2008-03-26 20:21:07.000000000 -0400
3373 @@ -32,7 +32,7 @@ static int detect_memory_e820(void)
3374 /* Important: %edx is clobbered by some BIOSes,
3375 so it must be either used for the error output
3376 or explicitly marked clobbered. */
3377 - asm("int $0x15; setc %0"
3378 + asm volatile("int $0x15; setc %0"
3379 : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
3381 : "D" (desc), "d" (SMAP), "a" (0xe820));
3382 @@ -64,7 +64,7 @@ static int detect_memory_e801(void)
3386 - asm("stc; int $0x15; setc %0"
3387 + asm volatile("stc; int $0x15; setc %0"
3388 : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3391 @@ -94,7 +94,7 @@ static int detect_memory_88(void)
3395 - asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3396 + asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3398 boot_params.screen_info.ext_mem_k = ax;
3400 diff -urNp linux-2.6.24.4/arch/x86/boot/video.c linux-2.6.24.4/arch/x86/boot/video.c
3401 --- linux-2.6.24.4/arch/x86/boot/video.c 2008-03-24 14:49:18.000000000 -0400
3402 +++ linux-2.6.24.4/arch/x86/boot/video.c 2008-03-26 20:21:07.000000000 -0400
3403 @@ -40,7 +40,7 @@ static void store_cursor_position(void)
3408 + asm volatile(INT10
3409 : "=d" (curpos), "+a" (ax), "+b" (bx)
3410 : : "ecx", "esi", "edi");
3412 @@ -55,7 +55,7 @@ static void store_video_mode(void)
3413 /* N.B.: the saving of the video page here is a bit silly,
3414 since we pretty much assume page 0 everywhere. */
3417 + asm volatile(INT10
3418 : "+a" (ax), "=b" (page)
3419 : : "ecx", "edx", "esi", "edi");
3421 diff -urNp linux-2.6.24.4/arch/x86/boot/video-vesa.c linux-2.6.24.4/arch/x86/boot/video-vesa.c
3422 --- linux-2.6.24.4/arch/x86/boot/video-vesa.c 2008-03-24 14:49:18.000000000 -0400
3423 +++ linux-2.6.24.4/arch/x86/boot/video-vesa.c 2008-03-26 20:21:07.000000000 -0400
3424 @@ -41,7 +41,7 @@ static int vesa_probe(void)
3427 di = (size_t)&vginfo;
3429 + asm volatile(INT10
3430 : "+a" (ax), "+D" (di), "=m" (vginfo)
3431 : : "ebx", "ecx", "edx", "esi");
3433 @@ -68,7 +68,7 @@ static int vesa_probe(void)
3436 di = (size_t)&vminfo;
3438 + asm volatile(INT10
3439 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3440 : : "ebx", "edx", "esi");
3442 @@ -115,7 +115,7 @@ static int vesa_set_mode(struct mode_inf
3445 di = (size_t)&vminfo;
3447 + asm volatile(INT10
3448 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3449 : : "ebx", "edx", "esi");
3451 @@ -193,19 +193,20 @@ static void vesa_dac_set_8bits(void)
3452 /* Save the VESA protected mode info */
3453 static void vesa_store_pm_info(void)
3455 - u16 ax, bx, di, es;
3456 + u16 ax, bx, cx, di, es;
3460 - asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3461 - : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3462 - : : "ecx", "esi");
3464 + asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3465 + : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3471 boot_params.screen_info.vesapm_seg = es;
3472 boot_params.screen_info.vesapm_off = di;
3473 + boot_params.screen_info.vesapm_size = cx;
3477 @@ -259,7 +260,7 @@ void vesa_store_edid(void)
3478 /* Note: The VBE DDC spec is different from the main VESA spec;
3479 we genuinely have to assume all registers are destroyed here. */
3481 - asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3482 + asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3483 : "+a" (ax), "+b" (bx)
3484 : "c" (cx), "D" (di)
3486 @@ -275,7 +276,7 @@ void vesa_store_edid(void)
3487 cx = 0; /* Controller 0 */
3488 dx = 0; /* EDID block number */
3489 di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
3491 + asm volatile(INT10
3492 : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
3493 : "c" (cx), "D" (di)
3495 diff -urNp linux-2.6.24.4/arch/x86/boot/video-vga.c linux-2.6.24.4/arch/x86/boot/video-vga.c
3496 --- linux-2.6.24.4/arch/x86/boot/video-vga.c 2008-03-24 14:49:18.000000000 -0400
3497 +++ linux-2.6.24.4/arch/x86/boot/video-vga.c 2008-03-26 20:21:07.000000000 -0400
3498 @@ -225,7 +225,7 @@ static int vga_probe(void)
3503 + asm volatile(INT10
3504 : "=b" (boot_params.screen_info.orig_video_ega_bx)
3505 : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
3506 : "ecx", "edx", "esi", "edi");
3507 @@ -233,7 +233,7 @@ static int vga_probe(void)
3508 /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
3509 if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
3512 + asm volatile(INT10
3515 : "ebx", "ecx", "edx", "esi", "edi");
3516 diff -urNp linux-2.6.24.4/arch/x86/boot/voyager.c linux-2.6.24.4/arch/x86/boot/voyager.c
3517 --- linux-2.6.24.4/arch/x86/boot/voyager.c 2008-03-24 14:49:18.000000000 -0400
3518 +++ linux-2.6.24.4/arch/x86/boot/voyager.c 2008-03-26 20:21:07.000000000 -0400
3519 @@ -27,7 +27,7 @@ int query_voyager(void)
3521 data_ptr[0] = 0xff; /* Flag on config not found(?) */
3523 - asm("pushw %%es ; "
3524 + asm volatile("pushw %%es ; "
3528 diff -urNp linux-2.6.24.4/arch/x86/ia32/ia32_binfmt.c linux-2.6.24.4/arch/x86/ia32/ia32_binfmt.c
3529 --- linux-2.6.24.4/arch/x86/ia32/ia32_binfmt.c 2008-03-24 14:49:18.000000000 -0400
3530 +++ linux-2.6.24.4/arch/x86/ia32/ia32_binfmt.c 2008-03-26 20:21:07.000000000 -0400
3532 #define AT_SYSINFO 32
3533 #define AT_SYSINFO_EHDR 33
3535 -int sysctl_vsyscall32 = 1;
3536 +int sysctl_vsyscall32;
3539 #define ARCH_DLINFO do { \
3540 if (sysctl_vsyscall32) { \
3541 - current->mm->context.vdso = (void *)VSYSCALL32_BASE; \
3542 + current->mm->context.vdso = VSYSCALL32_BASE; \
3543 NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
3544 NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \
3546 @@ -66,6 +66,17 @@ struct file;
3548 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
3550 +#ifdef CONFIG_PAX_ASLR
3551 +#undef PAX_ELF_ET_DYN_BASE
3552 +#undef PAX_DELTA_MMAP_LEN
3553 +#undef PAX_DELTA_STACK_LEN
3555 +#define PAX_ELF_ET_DYN_BASE 0x08048000UL
3557 +#define PAX_DELTA_MMAP_LEN 16
3558 +#define PAX_DELTA_STACK_LEN 16
3561 #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
3563 #define _GET_SEG(x) \
3564 @@ -263,7 +274,7 @@ static ctl_table abi_table2[] = {
3566 .proc_handler = proc_dointvec
3569 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
3572 static ctl_table abi_root_table2[] = {
3573 @@ -273,7 +284,7 @@ static ctl_table abi_root_table2[] = {
3578 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
3581 static __init int ia32_binfmt_init(void)
3582 diff -urNp linux-2.6.24.4/arch/x86/ia32/ia32_signal.c linux-2.6.24.4/arch/x86/ia32/ia32_signal.c
3583 --- linux-2.6.24.4/arch/x86/ia32/ia32_signal.c 2008-03-24 14:49:18.000000000 -0400
3584 +++ linux-2.6.24.4/arch/x86/ia32/ia32_signal.c 2008-03-26 20:21:07.000000000 -0400
3585 @@ -573,6 +573,7 @@ int ia32_setup_rt_frame(int sig, struct
3586 __NR_ia32_rt_sigreturn,
3591 err |= __copy_to_user(frame->retcode, &code, 8);
3593 diff -urNp linux-2.6.24.4/arch/x86/ia32/mmap32.c linux-2.6.24.4/arch/x86/ia32/mmap32.c
3594 --- linux-2.6.24.4/arch/x86/ia32/mmap32.c 2008-03-24 14:49:18.000000000 -0400
3595 +++ linux-2.6.24.4/arch/x86/ia32/mmap32.c 2008-03-26 20:21:07.000000000 -0400
3596 @@ -69,10 +69,22 @@ void ia32_pick_mmap_layout(struct mm_str
3597 (current->personality & ADDR_COMPAT_LAYOUT) ||
3598 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
3599 mm->mmap_base = TASK_UNMAPPED_BASE;
3601 +#ifdef CONFIG_PAX_RANDMMAP
3602 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3603 + mm->mmap_base += mm->delta_mmap;
3606 mm->get_unmapped_area = arch_get_unmapped_area;
3607 mm->unmap_area = arch_unmap_area;
3609 mm->mmap_base = mmap_base(mm);
3611 +#ifdef CONFIG_PAX_RANDMMAP
3612 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3613 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3616 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3617 mm->unmap_area = arch_unmap_area_topdown;
3619 diff -urNp linux-2.6.24.4/arch/x86/ia32/ptrace32.c linux-2.6.24.4/arch/x86/ia32/ptrace32.c
3620 --- linux-2.6.24.4/arch/x86/ia32/ptrace32.c 2008-03-24 14:49:18.000000000 -0400
3621 +++ linux-2.6.24.4/arch/x86/ia32/ptrace32.c 2008-03-26 20:21:07.000000000 -0400
3622 @@ -382,7 +382,7 @@ asmlinkage long sys32_ptrace(long reques
3623 /* no checking to be bug-to-bug compatible with i386. */
3624 /* but silence warning */
3625 if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)))
3628 set_stopped_child_used_math(child);
3629 child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
3631 diff -urNp linux-2.6.24.4/arch/x86/ia32/syscall32.c linux-2.6.24.4/arch/x86/ia32/syscall32.c
3632 --- linux-2.6.24.4/arch/x86/ia32/syscall32.c 2008-03-24 14:49:18.000000000 -0400
3633 +++ linux-2.6.24.4/arch/x86/ia32/syscall32.c 2008-03-26 20:21:07.000000000 -0400
3634 @@ -30,6 +30,9 @@ int syscall32_setup_pages(struct linux_b
3635 struct mm_struct *mm = current->mm;
3638 + if (!sysctl_vsyscall32)
3641 down_write(&mm->mmap_sem);
3643 * MAYWRITE to allow gdb to COW and set breakpoints
3644 diff -urNp linux-2.6.24.4/arch/x86/Kconfig linux-2.6.24.4/arch/x86/Kconfig
3645 --- linux-2.6.24.4/arch/x86/Kconfig 2008-03-24 14:49:18.000000000 -0400
3646 +++ linux-2.6.24.4/arch/x86/Kconfig 2008-03-26 20:21:07.000000000 -0400
3647 @@ -792,7 +792,7 @@ config PAGE_OFFSET
3649 default 0xB0000000 if VMSPLIT_3G_OPT
3650 default 0x80000000 if VMSPLIT_2G
3651 - default 0x78000000 if VMSPLIT_2G_OPT
3652 + default 0x70000000 if VMSPLIT_2G_OPT
3653 default 0x40000000 if VMSPLIT_1G
3656 @@ -1096,8 +1096,7 @@ config CRASH_DUMP
3657 config PHYSICAL_START
3658 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
3659 default "0x1000000" if X86_NUMAQ
3660 - default "0x200000" if X86_64
3661 - default "0x100000"
3662 + default "0x200000"
3664 This gives the physical address where the kernel is loaded.
3666 @@ -1190,8 +1189,8 @@ config HOTPLUG_CPU
3669 bool "Compat VDSO support"
3673 + depends on X86_32 && !PAX_NOEXEC
3675 Map the VDSO to the predictable old-style address too.
3677 @@ -1387,7 +1386,7 @@ config PCI
3679 prompt "PCI access mode"
3680 depends on X86_32 && PCI && !X86_VISWS
3682 + default PCI_GODIRECT
3684 On PCI systems, the BIOS can be used to detect the PCI devices and
3685 determine their configuration. However, some old PCI motherboards
3686 diff -urNp linux-2.6.24.4/arch/x86/Kconfig.cpu linux-2.6.24.4/arch/x86/Kconfig.cpu
3687 --- linux-2.6.24.4/arch/x86/Kconfig.cpu 2008-03-24 14:49:18.000000000 -0400
3688 +++ linux-2.6.24.4/arch/x86/Kconfig.cpu 2008-03-26 20:21:16.000000000 -0400
3689 @@ -328,7 +328,7 @@ config X86_PPRO_FENCE
3693 - depends on M586MMX || M586TSC || M586 || M486 || M386
3694 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
3697 config X86_WP_WORKS_OK
3698 @@ -353,7 +353,7 @@ config X86_POPAD_OK
3700 config X86_ALIGNMENT_16
3702 - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3703 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3706 config X86_GOOD_APIC
3707 @@ -390,7 +390,7 @@ config X86_TSC
3711 - depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
3712 + depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
3715 config X86_MINIMUM_CPU_FAMILY
3716 diff -urNp linux-2.6.24.4/arch/x86/Kconfig.debug linux-2.6.24.4/arch/x86/Kconfig.debug
3717 --- linux-2.6.24.4/arch/x86/Kconfig.debug 2008-03-24 14:49:18.000000000 -0400
3718 +++ linux-2.6.24.4/arch/x86/Kconfig.debug 2008-03-26 20:21:07.000000000 -0400
3719 @@ -49,7 +49,7 @@ config DEBUG_PAGEALLOC
3722 bool "Write protect kernel read-only data structures"
3723 - depends on DEBUG_KERNEL
3724 + depends on DEBUG_KERNEL && BROKEN
3726 Mark the kernel read-only data as write-protected in the pagetables,
3727 in order to catch accidental (and incorrect) writes to such const
3728 diff -urNp linux-2.6.24.4/arch/x86/kernel/acpi/boot.c linux-2.6.24.4/arch/x86/kernel/acpi/boot.c
3729 --- linux-2.6.24.4/arch/x86/kernel/acpi/boot.c 2008-03-24 14:49:18.000000000 -0400
3730 +++ linux-2.6.24.4/arch/x86/kernel/acpi/boot.c 2008-03-26 20:21:07.000000000 -0400
3731 @@ -1155,7 +1155,7 @@ static struct dmi_system_id __initdata a
3732 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
3736 + { NULL, NULL, {{0, NULL}}, NULL}
3739 #endif /* __i386__ */
3740 diff -urNp linux-2.6.24.4/arch/x86/kernel/acpi/sleep_32.c linux-2.6.24.4/arch/x86/kernel/acpi/sleep_32.c
3741 --- linux-2.6.24.4/arch/x86/kernel/acpi/sleep_32.c 2008-03-24 14:49:18.000000000 -0400
3742 +++ linux-2.6.24.4/arch/x86/kernel/acpi/sleep_32.c 2008-03-26 20:21:07.000000000 -0400
3743 @@ -98,7 +98,7 @@ static __initdata struct dmi_system_id a
3744 DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
3748 + { NULL, NULL, {{0, NULL}}, NULL}
3751 static int __init acpisleep_dmi_init(void)
3752 diff -urNp linux-2.6.24.4/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.24.4/arch/x86/kernel/acpi/wakeup_32.S
3753 --- linux-2.6.24.4/arch/x86/kernel/acpi/wakeup_32.S 2008-03-24 14:49:18.000000000 -0400
3754 +++ linux-2.6.24.4/arch/x86/kernel/acpi/wakeup_32.S 2008-03-26 20:21:07.000000000 -0400
3756 #include <linux/linkage.h>
3757 #include <asm/segment.h>
3758 #include <asm/page.h>
3759 +#include <asm/msr-index.h>
3762 # wakeup_code runs in real mode, and at unknown address (determined at run-time).
3763 @@ -79,7 +80,7 @@ wakeup_code:
3764 # restore efer setting
3765 movl real_save_efer_edx - wakeup_code, %edx
3766 movl real_save_efer_eax - wakeup_code, %eax
3767 - mov $0xc0000080, %ecx
3768 + mov $MSR_EFER, %ecx
3771 # make sure %cr4 is set correctly (features, etc)
3772 @@ -196,13 +197,11 @@ wakeup_pmode_return:
3773 # and restore the stack ... but you need gdt for this to work
3774 movl saved_context_esp, %esp
3776 - movl %cs:saved_magic, %eax
3777 - cmpl $0x12345678, %eax
3778 + cmpl $0x12345678, saved_magic
3781 # jump to place where we left off
3782 - movl saved_eip,%eax
3788 @@ -233,7 +232,7 @@ ENTRY(acpi_copy_wakeup_routine)
3792 - mov $0xc0000080, %ecx
3793 + mov $MSR_EFER, %ecx
3795 movl %edx, real_save_efer_edx - wakeup_start (%ebx)
3796 movl %eax, real_save_efer_eax - wakeup_start (%ebx)
3797 diff -urNp linux-2.6.24.4/arch/x86/kernel/alternative.c linux-2.6.24.4/arch/x86/kernel/alternative.c
3798 --- linux-2.6.24.4/arch/x86/kernel/alternative.c 2008-03-24 14:49:18.000000000 -0400
3799 +++ linux-2.6.24.4/arch/x86/kernel/alternative.c 2008-03-26 20:21:07.000000000 -0400
3800 @@ -389,7 +389,7 @@ void apply_paravirt(struct paravirt_patc
3802 BUG_ON(p->len > MAX_PATCH_LEN);
3803 /* prep the buffer with the original instructions */
3804 - memcpy(insnbuf, p->instr, p->len);
3805 + memcpy(insnbuf, ktla_ktva(p->instr), p->len);
3806 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
3807 (unsigned long)p->instr, p->len);
3809 @@ -467,7 +467,19 @@ void __init alternative_instructions(voi
3811 void __kprobes text_poke(void *addr, unsigned char *opcode, int len)
3813 - memcpy(addr, opcode, len);
3815 +#ifdef CONFIG_PAX_KERNEXEC
3816 + unsigned long cr0;
3818 + pax_open_kernel(cr0);
3821 + memcpy(ktla_ktva(addr), opcode, len);
3823 +#ifdef CONFIG_PAX_KERNEXEC
3824 + pax_close_kernel(cr0);
3828 /* Could also do a CLFLUSH here to speed up CPU recovery; but
3829 that causes hangs on some VIA CPUs. */
3830 diff -urNp linux-2.6.24.4/arch/x86/kernel/apm_32.c linux-2.6.24.4/arch/x86/kernel/apm_32.c
3831 --- linux-2.6.24.4/arch/x86/kernel/apm_32.c 2008-03-24 14:49:18.000000000 -0400
3832 +++ linux-2.6.24.4/arch/x86/kernel/apm_32.c 2008-03-26 20:21:07.000000000 -0400
3833 @@ -407,7 +407,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
3834 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
3835 static struct apm_user * user_list;
3836 static DEFINE_SPINLOCK(user_list_lock);
3837 -static const struct desc_struct bad_bios_desc = { 0, 0x00409200 };
3838 +static const struct desc_struct bad_bios_desc = { 0, 0x00409300 };
3840 static const char driver_version[] = "1.16ac"; /* no spaces */
3842 @@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
3843 struct desc_struct save_desc_40;
3844 struct desc_struct *gdt;
3846 +#ifdef CONFIG_PAX_KERNEXEC
3847 + unsigned long cr0;
3850 cpus = apm_save_cpus();
3853 gdt = get_cpu_gdt_table(cpu);
3854 save_desc_40 = gdt[0x40 / 8];
3856 +#ifdef CONFIG_PAX_KERNEXEC
3857 + pax_open_kernel(cr0);
3860 gdt[0x40 / 8] = bad_bios_desc;
3862 +#ifdef CONFIG_PAX_KERNEXEC
3863 + pax_close_kernel(cr0);
3866 apm_irq_save(flags);
3868 apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
3869 APM_DO_RESTORE_SEGS;
3870 apm_irq_restore(flags);
3872 +#ifdef CONFIG_PAX_KERNEXEC
3873 + pax_open_kernel(cr0);
3876 gdt[0x40 / 8] = save_desc_40;
3878 +#ifdef CONFIG_PAX_KERNEXEC
3879 + pax_close_kernel(cr0);
3883 apm_restore_cpus(cpus);
3885 @@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
3886 struct desc_struct save_desc_40;
3887 struct desc_struct *gdt;
3889 +#ifdef CONFIG_PAX_KERNEXEC
3890 + unsigned long cr0;
3893 cpus = apm_save_cpus();
3896 gdt = get_cpu_gdt_table(cpu);
3897 save_desc_40 = gdt[0x40 / 8];
3899 +#ifdef CONFIG_PAX_KERNEXEC
3900 + pax_open_kernel(cr0);
3903 gdt[0x40 / 8] = bad_bios_desc;
3905 +#ifdef CONFIG_PAX_KERNEXEC
3906 + pax_close_kernel(cr0);
3909 apm_irq_save(flags);
3911 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
3912 APM_DO_RESTORE_SEGS;
3913 apm_irq_restore(flags);
3915 +#ifdef CONFIG_PAX_KERNEXEC
3916 + pax_open_kernel(cr0);
3919 gdt[0x40 / 8] = save_desc_40;
3921 +#ifdef CONFIG_PAX_KERNEXEC
3922 + pax_close_kernel(cr0);
3926 apm_restore_cpus(cpus);
3928 @@ -924,7 +970,7 @@ recalc:
3930 static void apm_power_off(void)
3932 - unsigned char po_bios_call[] = {
3933 + const unsigned char po_bios_call[] = {
3934 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
3935 0x8e, 0xd0, /* movw ax,ss */
3936 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
3937 @@ -1864,7 +1910,10 @@ static const struct file_operations apm_
3938 static struct miscdevice apm_device = {
3949 @@ -2177,7 +2226,7 @@ static struct dmi_system_id __initdata a
3950 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
3954 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
3958 @@ -2196,6 +2245,10 @@ static int __init apm_init(void)
3959 struct desc_struct *gdt;
3962 +#ifdef CONFIG_PAX_KERNEXEC
3963 + unsigned long cr0;
3966 dmi_check_system(apm_dmi_table);
3968 if (apm_info.bios.version == 0 || paravirt_enabled()) {
3969 @@ -2269,9 +2322,18 @@ static int __init apm_init(void)
3970 * This is for buggy BIOS's that refer to (real mode) segment 0x40
3971 * even though they are called in protected mode.
3974 +#ifdef CONFIG_PAX_KERNEXEC
3975 + pax_open_kernel(cr0);
3978 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
3979 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
3981 +#ifdef CONFIG_PAX_KERNEXEC
3982 + pax_close_kernel(cr0);
3986 * Set up the long jump entry point to the APM BIOS, which is called
3987 * from inline assembly.
3988 @@ -2290,6 +2352,11 @@ static int __init apm_init(void)
3991 gdt = get_cpu_gdt_table(0);
3993 +#ifdef CONFIG_PAX_KERNEXEC
3994 + pax_open_kernel(cr0);
3997 set_base(gdt[APM_CS >> 3],
3998 __va((unsigned long)apm_info.bios.cseg << 4));
3999 set_base(gdt[APM_CS_16 >> 3],
4000 @@ -2297,6 +2364,10 @@ static int __init apm_init(void)
4001 set_base(gdt[APM_DS >> 3],
4002 __va((unsigned long)apm_info.bios.dseg << 4));
4004 +#ifdef CONFIG_PAX_KERNEXEC
4005 + pax_close_kernel(cr0);
4008 apm_proc = create_proc_entry("apm", 0, NULL);
4010 apm_proc->proc_fops = &apm_file_ops;
4011 diff -urNp linux-2.6.24.4/arch/x86/kernel/asm-offsets_32.c linux-2.6.24.4/arch/x86/kernel/asm-offsets_32.c
4012 --- linux-2.6.24.4/arch/x86/kernel/asm-offsets_32.c 2008-03-24 14:49:18.000000000 -0400
4013 +++ linux-2.6.24.4/arch/x86/kernel/asm-offsets_32.c 2008-03-26 20:21:07.000000000 -0400
4014 @@ -110,6 +110,7 @@ void foo(void)
4015 DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
4016 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
4017 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
4018 + DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
4020 DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
4022 @@ -125,6 +126,7 @@ void foo(void)
4023 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
4024 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
4025 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
4026 + OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
4030 diff -urNp linux-2.6.24.4/arch/x86/kernel/asm-offsets_64.c linux-2.6.24.4/arch/x86/kernel/asm-offsets_64.c
4031 --- linux-2.6.24.4/arch/x86/kernel/asm-offsets_64.c 2008-03-24 14:49:18.000000000 -0400
4032 +++ linux-2.6.24.4/arch/x86/kernel/asm-offsets_64.c 2008-03-26 20:21:07.000000000 -0400
4033 @@ -108,6 +108,7 @@ int main(void)
4037 + DEFINE(TSS_size, sizeof(struct tss_struct));
4038 DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
4040 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
4041 diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/common.c linux-2.6.24.4/arch/x86/kernel/cpu/common.c
4042 --- linux-2.6.24.4/arch/x86/kernel/cpu/common.c 2008-03-24 14:49:18.000000000 -0400
4043 +++ linux-2.6.24.4/arch/x86/kernel/cpu/common.c 2008-03-26 20:21:07.000000000 -0400
4045 #include <linux/smp.h>
4046 #include <linux/module.h>
4047 #include <linux/percpu.h>
4048 -#include <linux/bootmem.h>
4049 #include <asm/semaphore.h>
4050 #include <asm/processor.h>
4051 #include <asm/i387.h>
4056 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
4057 - [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 },
4058 - [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 },
4059 - [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 },
4060 - [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 },
4062 - * Segments used for calling PnP BIOS have byte granularity.
4063 - * They code segments and data segments have fixed 64k limits,
4064 - * the transfer segment sizes are set at run time.
4066 - [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
4067 - [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */
4068 - [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */
4069 - [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */
4070 - [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */
4072 - * The APM segments have byte granularity and their bases
4073 - * are set at run time. All have 64k limits.
4075 - [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
4077 - [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
4078 - [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
4080 - [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
4081 - [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 },
4083 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
4085 static int cachesize_override __cpuinitdata = -1;
4086 static int disable_x86_fxsr __cpuinitdata;
4087 static int disable_x86_serial_nr __cpuinitdata = 1;
4088 -static int disable_x86_sep __cpuinitdata;
4090 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4091 +int disable_x86_sep __cpuinitdata = 1;
4093 +int disable_x86_sep __cpuinitdata;
4096 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
4098 @@ -262,9 +237,9 @@ void __init cpu_detect(struct cpuinfo_x8
4100 /* Get vendor name */
4101 cpuid(0x00000000, &c->cpuid_level,
4102 - (int *)&c->x86_vendor_id[0],
4103 - (int *)&c->x86_vendor_id[8],
4104 - (int *)&c->x86_vendor_id[4]);
4105 + (unsigned int *)&c->x86_vendor_id[0],
4106 + (unsigned int *)&c->x86_vendor_id[8],
4107 + (unsigned int *)&c->x86_vendor_id[4]);
4110 if (c->cpuid_level >= 0x00000001) {
4111 @@ -304,15 +279,14 @@ static void __init early_cpu_detect(void
4113 static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
4117 + u32 tfms, xlvl, ebx;
4119 if (have_cpuid_p()) {
4120 /* Get vendor name */
4121 cpuid(0x00000000, &c->cpuid_level,
4122 - (int *)&c->x86_vendor_id[0],
4123 - (int *)&c->x86_vendor_id[8],
4124 - (int *)&c->x86_vendor_id[4]);
4125 + (unsigned int *)&c->x86_vendor_id[0],
4126 + (unsigned int *)&c->x86_vendor_id[8],
4127 + (unsigned int *)&c->x86_vendor_id[4]);
4129 get_cpu_vendor(c, 0);
4130 /* Initialize the standard set of capabilities */
4131 @@ -644,7 +618,7 @@ void switch_to_new_gdt(void)
4133 struct Xgt_desc_struct gdt_descr;
4135 - gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
4136 + gdt_descr.address = get_cpu_gdt_table(smp_processor_id());
4137 gdt_descr.size = GDT_SIZE - 1;
4138 load_gdt(&gdt_descr);
4139 asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
4140 @@ -660,7 +634,7 @@ void __cpuinit cpu_init(void)
4142 int cpu = smp_processor_id();
4143 struct task_struct *curr = current;
4144 - struct tss_struct * t = &per_cpu(init_tss, cpu);
4145 + struct tss_struct *t = init_tss + cpu;
4146 struct thread_struct *thread = &curr->thread;
4148 if (cpu_test_and_set(cpu, cpu_initialized)) {
4149 diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
4150 --- linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-03-24 14:49:18.000000000 -0400
4151 +++ linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-03-26 20:21:07.000000000 -0400
4152 @@ -549,7 +549,7 @@ static const struct dmi_system_id sw_any
4153 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
4157 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
4161 diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
4162 --- linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-03-24 14:49:18.000000000 -0400
4163 +++ linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-03-26 20:21:07.000000000 -0400
4164 @@ -223,7 +223,7 @@ static struct cpu_model models[] =
4165 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
4166 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
4169 + { NULL, NULL, 0, NULL}
4173 diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/intel.c linux-2.6.24.4/arch/x86/kernel/cpu/intel.c
4174 --- linux-2.6.24.4/arch/x86/kernel/cpu/intel.c 2008-03-24 14:49:18.000000000 -0400
4175 +++ linux-2.6.24.4/arch/x86/kernel/cpu/intel.c 2008-03-26 20:21:07.000000000 -0400
4176 @@ -104,6 +104,7 @@ static void __cpuinit trap_init_f00f_bug
4177 * it uses the read-only mapped virtual address.
4179 idt_descr.address = fix_to_virt(FIX_F00F_IDT);
4180 + idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
4181 load_idt(&idt_descr);
4184 diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/intel_cacheinfo.c linux-2.6.24.4/arch/x86/kernel/cpu/intel_cacheinfo.c
4185 --- linux-2.6.24.4/arch/x86/kernel/cpu/intel_cacheinfo.c 2008-03-24 14:49:18.000000000 -0400
4186 +++ linux-2.6.24.4/arch/x86/kernel/cpu/intel_cacheinfo.c 2008-03-26 20:21:07.000000000 -0400
4187 @@ -352,8 +352,8 @@ unsigned int __cpuinit init_intel_cachei
4189 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
4190 /* supports eax=2 call */
4194 + unsigned int regs[4];
4195 unsigned char *dp = (unsigned char *)regs;
4198 @@ -368,7 +368,7 @@ unsigned int __cpuinit init_intel_cachei
4200 /* If bit 31 is set, this is an unknown format */
4201 for ( j = 0 ; j < 3 ; j++ ) {
4202 - if ( regs[j] < 0 ) regs[j] = 0;
4203 + if ( (int)regs[j] < 0 ) regs[j] = 0;
4206 /* Byte 0 is level count, not a descriptor */
4207 diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.24.4/arch/x86/kernel/cpu/mcheck/mce_64.c
4208 --- linux-2.6.24.4/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-03-24 14:49:18.000000000 -0400
4209 +++ linux-2.6.24.4/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-03-26 20:21:08.000000000 -0400
4210 @@ -671,6 +671,7 @@ static struct miscdevice mce_log_device
4214 + {NULL, NULL}, NULL, NULL
4217 static unsigned long old_cr4 __initdata;
4218 diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.24.4/arch/x86/kernel/cpu/mtrr/generic.c
4219 --- linux-2.6.24.4/arch/x86/kernel/cpu/mtrr/generic.c 2008-03-24 14:49:18.000000000 -0400
4220 +++ linux-2.6.24.4/arch/x86/kernel/cpu/mtrr/generic.c 2008-03-26 20:21:08.000000000 -0400
4221 @@ -29,11 +29,11 @@ static struct fixed_range_block fixed_ra
4222 { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
4223 { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
4224 { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
4229 static unsigned long smp_changes_mask;
4230 -static struct mtrr_state mtrr_state = {};
4231 +static struct mtrr_state mtrr_state;
4233 #undef MODULE_PARAM_PREFIX
4234 #define MODULE_PARAM_PREFIX "mtrr."
4235 diff -urNp linux-2.6.24.4/arch/x86/kernel/crash.c linux-2.6.24.4/arch/x86/kernel/crash.c
4236 --- linux-2.6.24.4/arch/x86/kernel/crash.c 2008-03-24 14:49:18.000000000 -0400
4237 +++ linux-2.6.24.4/arch/x86/kernel/crash.c 2008-03-26 20:21:08.000000000 -0400
4238 @@ -62,7 +62,7 @@ static int crash_nmi_callback(struct not
4239 local_irq_disable();
4241 #ifdef CONFIG_X86_32
4242 - if (!user_mode_vm(regs)) {
4243 + if (!user_mode(regs)) {
4244 crash_fixup_ss_esp(&fixed_regs, regs);
4247 diff -urNp linux-2.6.24.4/arch/x86/kernel/doublefault_32.c linux-2.6.24.4/arch/x86/kernel/doublefault_32.c
4248 --- linux-2.6.24.4/arch/x86/kernel/doublefault_32.c 2008-03-24 14:49:18.000000000 -0400
4249 +++ linux-2.6.24.4/arch/x86/kernel/doublefault_32.c 2008-03-26 20:21:08.000000000 -0400
4252 #define DOUBLEFAULT_STACKSIZE (1024)
4253 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
4254 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
4255 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
4257 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
4259 static void doublefault_fn(void)
4261 - struct Xgt_desc_struct gdt_desc = {0, 0};
4262 + struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
4263 unsigned long gdt, tss;
4265 store_gdt(&gdt_desc);
4266 - gdt = gdt_desc.address;
4267 + gdt = (unsigned long)gdt_desc.address;
4269 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
4271 @@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach
4272 /* 0x2 bit is always set */
4273 .eflags = X86_EFLAGS_SF | 0x2,
4276 + .es = __KERNEL_DS,
4280 + .ds = __KERNEL_DS,
4281 .fs = __KERNEL_PERCPU,
4283 .__cr3 = __pa(swapper_pg_dir)
4284 diff -urNp linux-2.6.24.4/arch/x86/kernel/efi_32.c linux-2.6.24.4/arch/x86/kernel/efi_32.c
4285 --- linux-2.6.24.4/arch/x86/kernel/efi_32.c 2008-03-24 14:49:18.000000000 -0400
4286 +++ linux-2.6.24.4/arch/x86/kernel/efi_32.c 2008-03-26 20:21:08.000000000 -0400
4287 @@ -63,71 +63,38 @@ extern void * boot_ioremap(unsigned long
4289 static unsigned long efi_rt_eflags;
4290 static DEFINE_SPINLOCK(efi_rt_lock);
4291 -static pgd_t efi_bak_pg_dir_pointer[2];
4292 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
4294 -static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
4295 +static void __init efi_call_phys_prelog(void) __acquires(efi_rt_lock)
4297 - unsigned long cr4;
4298 - unsigned long temp;
4299 struct Xgt_desc_struct gdt_descr;
4301 spin_lock(&efi_rt_lock);
4302 local_irq_save(efi_rt_eflags);
4305 - * If I don't have PSE, I should just duplicate two entries in page
4306 - * directory. If I have PSE, I just need to duplicate one entry in
4311 - if (cr4 & X86_CR4_PSE) {
4312 - efi_bak_pg_dir_pointer[0].pgd =
4313 - swapper_pg_dir[pgd_index(0)].pgd;
4314 - swapper_pg_dir[0].pgd =
4315 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4317 - efi_bak_pg_dir_pointer[0].pgd =
4318 - swapper_pg_dir[pgd_index(0)].pgd;
4319 - efi_bak_pg_dir_pointer[1].pgd =
4320 - swapper_pg_dir[pgd_index(0x400000)].pgd;
4321 - swapper_pg_dir[pgd_index(0)].pgd =
4322 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4323 - temp = PAGE_OFFSET + 0x400000;
4324 - swapper_pg_dir[pgd_index(0x400000)].pgd =
4325 - swapper_pg_dir[pgd_index(temp)].pgd;
4327 + clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
4328 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
4329 + min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
4332 * After the lock is released, the original page table is restored.
4336 - gdt_descr.address = __pa(get_cpu_gdt_table(0));
4337 + gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
4338 gdt_descr.size = GDT_SIZE - 1;
4339 load_gdt(&gdt_descr);
4342 -static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
4343 +static void __init efi_call_phys_epilog(void) __releases(efi_rt_lock)
4345 - unsigned long cr4;
4346 struct Xgt_desc_struct gdt_descr;
4348 - gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
4349 + gdt_descr.address = get_cpu_gdt_table(0);
4350 gdt_descr.size = GDT_SIZE - 1;
4351 load_gdt(&gdt_descr);
4355 - if (cr4 & X86_CR4_PSE) {
4356 - swapper_pg_dir[pgd_index(0)].pgd =
4357 - efi_bak_pg_dir_pointer[0].pgd;
4359 - swapper_pg_dir[pgd_index(0)].pgd =
4360 - efi_bak_pg_dir_pointer[0].pgd;
4361 - swapper_pg_dir[pgd_index(0x400000)].pgd =
4362 - efi_bak_pg_dir_pointer[1].pgd;
4364 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
4367 * After the lock is released, the original page table is restored.
4368 @@ -138,7 +105,7 @@ static void efi_call_phys_epilog(void) _
4369 spin_unlock(&efi_rt_lock);
4372 -static efi_status_t
4373 +static efi_status_t __init
4374 phys_efi_set_virtual_address_map(unsigned long memory_map_size,
4375 unsigned long descriptor_size,
4376 u32 descriptor_version,
4377 @@ -154,7 +121,7 @@ phys_efi_set_virtual_address_map(unsigne
4381 -static efi_status_t
4382 +static noinline efi_status_t __init
4383 phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
4385 efi_status_t status;
4386 @@ -198,7 +165,7 @@ inline int efi_set_rtc_mmss(unsigned lon
4387 * services have been remapped and also during suspend, therefore,
4388 * we'll need to call both in physical and virtual modes.
4390 -inline unsigned long efi_get_time(void)
4391 +unsigned long efi_get_time(void)
4393 efi_status_t status;
4395 diff -urNp linux-2.6.24.4/arch/x86/kernel/efi_stub_32.S linux-2.6.24.4/arch/x86/kernel/efi_stub_32.S
4396 --- linux-2.6.24.4/arch/x86/kernel/efi_stub_32.S 2008-03-24 14:49:18.000000000 -0400
4397 +++ linux-2.6.24.4/arch/x86/kernel/efi_stub_32.S 2008-03-26 20:21:08.000000000 -0400
4401 #include <linux/linkage.h>
4402 +#include <linux/init.h>
4403 #include <asm/page.h>
4407 * service functions will comply with gcc calling convention, too.
4412 ENTRY(efi_call_phys)
4414 * 0. The function can only be called in Linux kernel. So CS has been
4415 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
4416 * The mapping of lower virtual memory has been created in prelog and
4420 - subl $__PAGE_OFFSET, %edx
4422 + jmp 1f-__PAGE_OFFSET
4426 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
4427 * parameter 2, ..., param n. To make things easy, we save the return
4428 * address of efi_call_phys in a global variable.
4431 - movl %edx, saved_return_addr
4432 - /* get the function pointer into ECX*/
4434 - movl %ecx, efi_rt_function_ptr
4436 - subl $__PAGE_OFFSET, %edx
4438 + popl (saved_return_addr)
4439 + popl (efi_rt_function_ptr)
4442 * 3. Clear PG bit in %CR0.
4443 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
4445 * 5. Call the physical function.
4448 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
4452 * 6. After EFI runtime service returns, control will return to
4453 * following instruction. We'd better readjust stack pointer first.
4454 @@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
4456 orl $0x80000000, %edx
4462 * 8. Now restore the virtual mode from flat mode by
4463 * adding EIP with PAGE_OFFSET.
4467 + jmp 1f+__PAGE_OFFSET
4471 * 9. Balance the stack. And because EAX contain the return value,
4472 * we'd better not clobber it.
4474 - leal efi_rt_function_ptr, %edx
4477 + pushl (efi_rt_function_ptr)
4480 - * 10. Push the saved return address onto the stack and return.
4481 + * 10. Return to the saved return address.
4483 - leal saved_return_addr, %edx
4487 + jmpl *(saved_return_addr)
4494 efi_rt_function_ptr:
4495 diff -urNp linux-2.6.24.4/arch/x86/kernel/entry_32.S linux-2.6.24.4/arch/x86/kernel/entry_32.S
4496 --- linux-2.6.24.4/arch/x86/kernel/entry_32.S 2008-03-24 14:49:18.000000000 -0400
4497 +++ linux-2.6.24.4/arch/x86/kernel/entry_32.S 2008-03-26 20:21:08.000000000 -0400
4498 @@ -97,7 +97,7 @@ VM_MASK = 0x00020000
4499 #define resume_userspace_sig resume_userspace
4503 +#define __SAVE_ALL(_DS) \
4506 CFI_ADJUST_CFA_OFFSET 4;\
4507 @@ -129,12 +129,26 @@ VM_MASK = 0x00020000
4509 CFI_ADJUST_CFA_OFFSET 4;\
4510 CFI_REL_OFFSET ebx, 0;\
4511 - movl $(__USER_DS), %edx; \
4512 + movl $(_DS), %edx; \
4515 movl $(__KERNEL_PERCPU), %edx; \
4518 +#ifdef CONFIG_PAX_KERNEXEC
4520 + __SAVE_ALL(__KERNEL_DS); \
4521 + GET_CR0_INTO_EDX; \
4522 + movl %edx, %esi; \
4523 + orl $X86_CR0_WP, %edx; \
4524 + xorl %edx, %esi; \
4526 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4527 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
4529 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
4532 #define RESTORE_INT_REGS \
4534 CFI_ADJUST_CFA_OFFSET -4;\
4535 @@ -248,7 +262,17 @@ check_userspace:
4536 movb PT_CS(%esp), %al
4537 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
4538 cmpl $USER_RPL, %eax
4540 +#ifdef CONFIG_PAX_KERNEXEC
4541 + jae resume_userspace
4548 jb resume_kernel # not returning to v8086 or userspace
4551 ENTRY(resume_userspace)
4553 @@ -308,10 +332,9 @@ sysenter_past_esp:
4554 /*CFI_REL_OFFSET cs, 0*/
4556 * Push current_thread_info()->sysenter_return to the stack.
4557 - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
4558 - * pushed above; +8 corresponds to copy_thread's esp0 setting.
4560 - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
4561 + GET_THREAD_INFO(%ebp)
4562 + pushl TI_sysenter_return(%ebp)
4563 CFI_ADJUST_CFA_OFFSET 4
4564 CFI_REL_OFFSET eip, 0
4566 @@ -319,9 +342,17 @@ sysenter_past_esp:
4567 * Load the potential sixth argument from user stack.
4568 * Careful about security.
4570 + movl 12(%esp),%ebp
4572 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4574 +1: movl %ds:(%ebp),%ebp
4576 cmpl $__PAGE_OFFSET-3,%ebp
4581 .section __ex_table,"a"
4583 .long 1b,syscall_fault
4584 @@ -345,20 +376,37 @@ sysenter_past_esp:
4585 movl TI_flags(%ebp), %ecx
4586 testw $_TIF_ALLWORK_MASK, %cx
4587 jne syscall_exit_work
4589 +#ifdef CONFIG_PAX_RANDKSTACK
4591 + CFI_ADJUST_CFA_OFFSET 4
4592 + call pax_randomize_kstack
4594 + CFI_ADJUST_CFA_OFFSET -4
4597 /* if something modifies registers it must also disable sysexit */
4598 movl PT_EIP(%esp), %edx
4599 movl PT_OLDESP(%esp), %ecx
4602 1: mov PT_FS(%esp), %fs
4603 +2: mov PT_DS(%esp), %ds
4604 +3: mov PT_ES(%esp), %es
4605 ENABLE_INTERRUPTS_SYSEXIT
4607 .pushsection .fixup,"ax"
4608 -2: movl $0,PT_FS(%esp)
4609 +4: movl $0,PT_FS(%esp)
4611 +5: movl $0,PT_DS(%esp)
4613 +6: movl $0,PT_ES(%esp)
4615 .section __ex_table,"a"
4622 ENDPROC(sysenter_entry)
4624 @@ -392,6 +440,10 @@ no_singlestep:
4625 testw $_TIF_ALLWORK_MASK, %cx # current->work
4626 jne syscall_exit_work
4628 +#ifdef CONFIG_PAX_RANDKSTACK
4629 + call pax_randomize_kstack
4633 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
4634 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
4635 @@ -556,17 +608,24 @@ syscall_badsys:
4639 -#define FIXUP_ESPFIX_STACK \
4640 - /* since we are on a wrong stack, we cant make it a C code :( */ \
4641 - PER_CPU(gdt_page, %ebx); \
4642 - GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
4643 - addl %esp, %eax; \
4644 - pushl $__KERNEL_DS; \
4645 - CFI_ADJUST_CFA_OFFSET 4; \
4647 - CFI_ADJUST_CFA_OFFSET 4; \
4648 - lss (%esp), %esp; \
4649 +.macro FIXUP_ESPFIX_STACK
4650 + /* since we are on a wrong stack, we cant make it a C code :( */
4652 + movl PER_CPU_VAR(cpu_number), %ebx;
4653 + shll $PAGE_SHIFT_asm, %ebx;
4654 + addl $cpu_gdt_table, %ebx;
4656 + movl $cpu_gdt_table, %ebx;
4658 + GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
4660 + pushl $__KERNEL_DS;
4661 + CFI_ADJUST_CFA_OFFSET 4;
4663 + CFI_ADJUST_CFA_OFFSET 4;
4665 CFI_ADJUST_CFA_OFFSET -8;
4667 #define UNWIND_ESPFIX_STACK \
4669 /* see if on espfix stack */ \
4670 @@ -583,7 +642,7 @@ END(syscall_badsys)
4671 * Build the entry stubs and pointer table with
4672 * some assembler magic.
4675 +.section .rodata,"a",@progbits
4679 @@ -683,12 +742,21 @@ error_code:
4681 CFI_ADJUST_CFA_OFFSET -4
4682 /*CFI_REGISTER es, ecx*/
4684 +#ifdef CONFIG_PAX_KERNEXEC
4687 + orl $X86_CR0_WP, %edx
4692 movl PT_FS(%esp), %edi # get the function address
4693 movl PT_ORIG_EAX(%esp), %edx # get the error code
4694 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
4695 mov %ecx, PT_FS(%esp)
4696 /*CFI_REL_OFFSET fs, ES*/
4697 - movl $(__USER_DS), %ecx
4698 + movl $(__KERNEL_DS), %ecx
4701 movl %esp,%eax # pt_regs pointer
4702 @@ -822,6 +890,13 @@ nmi_stack_correct:
4703 xorl %edx,%edx # zero error code
4704 movl %esp,%eax # pt_regs pointer
4707 +#ifdef CONFIG_PAX_KERNEXEC
4713 jmp restore_nocheck_notrace
4716 @@ -862,6 +937,13 @@ nmi_espfix_stack:
4717 FIXUP_ESPFIX_STACK # %eax == %esp
4718 xorl %edx,%edx # zero error code
4721 +#ifdef CONFIG_PAX_KERNEXEC
4728 lss 12+4(%esp), %esp # back to espfix stack
4729 CFI_ADJUST_CFA_OFFSET -24
4730 @@ -1110,7 +1192,6 @@ ENDPROC(xen_failsafe_callback)
4732 #endif /* CONFIG_XEN */
4734 -.section .rodata,"a"
4735 #include "syscall_table_32.S"
4737 syscall_table_size=(.-sys_call_table)
4738 diff -urNp linux-2.6.24.4/arch/x86/kernel/entry_64.S linux-2.6.24.4/arch/x86/kernel/entry_64.S
4739 --- linux-2.6.24.4/arch/x86/kernel/entry_64.S 2008-03-24 14:49:18.000000000 -0400
4740 +++ linux-2.6.24.4/arch/x86/kernel/entry_64.S 2008-03-26 20:21:08.000000000 -0400
4741 @@ -440,6 +440,7 @@ ENTRY(stub_execve)
4742 CFI_REGISTER rip, r11
4744 FIXUP_TOP_OF_STACK %r11
4747 RESTORE_TOP_OF_STACK %r11
4749 @@ -735,17 +736,18 @@ END(spurious_interrupt)
4753 - movq %gs:pda_data_offset, %rbp
4754 + imul $TSS_size, %gs:pda_cpunumber, %ebp
4755 + lea init_tss(%rbp), %rbp
4758 movq ORIG_RAX(%rsp),%rsi
4759 movq $-1,ORIG_RAX(%rsp)
4761 - subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4762 + subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4766 - addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4767 + addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4771 @@ -1003,15 +1005,16 @@ ENDPROC(child_rip)
4772 * rdi: name, rsi: argv, rdx: envp
4774 * We want to fallback into:
4775 - * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
4776 + * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs)
4778 * do_sys_execve asm fallback arguments:
4779 - * rdi: name, rsi: argv, rdx: envp, fake frame on the stack
4780 + * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
4782 ENTRY(kernel_execve)
4788 movq %rax, RAX(%rsp)
4790 diff -urNp linux-2.6.24.4/arch/x86/kernel/head_32.S linux-2.6.24.4/arch/x86/kernel/head_32.S
4791 --- linux-2.6.24.4/arch/x86/kernel/head_32.S 2008-03-24 14:49:18.000000000 -0400
4792 +++ linux-2.6.24.4/arch/x86/kernel/head_32.S 2008-03-26 20:21:08.000000000 -0400
4794 #include <asm/thread_info.h>
4795 #include <asm/asm-offsets.h>
4796 #include <asm/setup.h>
4797 +#include <asm/msr-index.h>
4800 * References to members of the new_cpu_data structure.
4801 @@ -60,17 +61,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
4802 LOW_PAGES = LOW_PAGES + 0x1000000
4805 -#if PTRS_PER_PMD > 1
4806 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
4808 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
4810 +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
4811 BOOTBITMAP_SIZE = LOW_PAGES / 8
4814 INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
4817 + * Real beginning of normal "text" segment
4822 +.section .text.startup,"ax",@progbits
4823 + ljmp $(__BOOT_CS),$phys_startup_32
4826 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
4827 * %esi points to the real-mode code as a 32-bit pointer.
4828 * CS and DS must be 4 GB flat segments, but we don't depend on
4829 @@ -78,6 +84,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
4832 .section .text.head,"ax",@progbits
4834 +#ifdef CONFIG_PAX_KERNEXEC
4835 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
4840 /* check to see if KEEP_SEGMENTS flag is meaningful */
4841 cmpw $0x207, BP_version(%esi)
4842 @@ -99,6 +111,43 @@ ENTRY(startup_32)
4846 + movl $__per_cpu_start,%eax
4847 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
4849 + movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
4850 + movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
4851 + movl $__per_cpu_end + PERCPU_MODULE_RESERVE,%eax
4852 + subl $__per_cpu_start,%eax
4853 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
4855 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4856 + /* check for VMware */
4857 + movl $0x564d5868,%eax
4862 + cmpl $0x564d5868,%ebx
4865 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
4866 + movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
4870 +#ifdef CONFIG_PAX_KERNEXEC
4871 + movl $KERNEL_TEXT_OFFSET,%eax
4872 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
4874 + movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
4875 + movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
4877 + movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
4878 + movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
4880 + movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
4884 * Clear BSS first so that there are no surprises...
4886 @@ -141,9 +190,7 @@ ENTRY(startup_32)
4887 cmpl $num_subarch_entries, %eax
4890 - movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
4891 - subl $__PAGE_OFFSET, %eax
4893 + jmp *(subarch_entries - __PAGE_OFFSET)(,%eax,4)
4897 @@ -151,11 +198,11 @@ WEAK(xen_entry)
4898 /* Unknown implementation; there's really
4899 nothing we can do at this point. */
4902 +.section .rodata,"a",@progbits
4904 - .long default_entry /* normal x86/PC */
4905 - .long lguest_entry /* lguest hypervisor */
4906 - .long xen_entry /* Xen hypervisor */
4907 + .long default_entry - __PAGE_OFFSET /* normal x86/PC */
4908 + .long lguest_entry - __PAGE_OFFSET /* lguest hypervisor */
4909 + .long xen_entry - __PAGE_OFFSET /* Xen hypervisor */
4910 num_subarch_entries = (. - subarch_entries) / 4
4912 #endif /* CONFIG_PARAVIRT */
4913 @@ -170,34 +217,55 @@ num_subarch_entries = (. - subarch_entri
4914 * Warning: don't use %esi or the stack in this code. However, %esp
4915 * can be used as a GPR if you really need it...
4917 -page_pde_offset = (__PAGE_OFFSET >> 20);
4918 +#ifdef CONFIG_X86_PAE
4919 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (PAGE_SIZE_asm / PTRS_PER_PTE));
4921 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE));
4925 movl $(pg0 - __PAGE_OFFSET), %edi
4926 +#ifdef CONFIG_X86_PAE
4927 + movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
4929 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
4930 - movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
4932 + movl $0x063, %eax /* 0x063 = PRESENT+RW+ACCESSED+DIRTY */
4934 - leal 0x007(%edi),%ecx /* Create PDE entry */
4935 + leal 0x063(%edi),%ecx /* Create PDE entry */
4936 movl %ecx,(%edx) /* Store identity PDE entry */
4937 movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
4938 +#ifdef CONFIG_X86_PAE
4940 + movl $0,page_pde_offset+4(%edx)
4949 +#ifdef CONFIG_X86_PAE
4955 /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
4956 - /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
4957 - leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
4958 + /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
4959 + leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
4962 movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
4964 /* Do an early initialization of the fixmap area */
4965 - movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
4966 - movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax
4967 - addl $0x67, %eax /* 0x67 == _PAGE_TABLE */
4968 - movl %eax, 4092(%edx)
4969 + /* 0x067 = PRESENT+RW+USER+ACCESSED+DIRTY */
4970 +#ifdef CONFIG_X86_PAE
4971 + movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pm_dir - __PAGE_OFFSET + 4096 - 8)
4973 + movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pg_dir - __PAGE_OFFSET + 4096 - 4)
4976 xorl %ebx,%ebx /* This is the boot CPU (BSP) */
4978 @@ -223,6 +291,11 @@ ENTRY(startup_32_smp)
4982 + /* This is a secondary processor (AP) */
4985 +#endif /* CONFIG_SMP */
4988 * New page tables may be in 4Mbyte page mode and may
4989 * be using the global pages.
4990 @@ -238,42 +311,47 @@ ENTRY(startup_32_smp)
4991 * not yet offset PAGE_OFFSET..
4993 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
4999 movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
5003 - btl $5, %eax # check if PAE is enabled
5005 +#ifdef CONFIG_X86_PAE
5008 /* Check if extended functions are implemented */
5009 movl $0x80000000, %eax
5011 cmpl $0x80000000, %eax
5014 mov $0x80000001, %eax
5016 /* Execute Disable bit supported? */
5021 /* Setup EFER (Extended Feature Enable Register) */
5022 - movl $0xc0000080, %ecx
5023 + movl $MSR_EFER, %ecx
5027 /* Make changes effective */
5031 - /* This is a secondary processor (AP) */
5034 + btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET
5035 + movl $1,nx_enabled-__PAGE_OFFSET
5037 -#endif /* CONFIG_SMP */
5039 +#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
5040 + movl $0,disable_x86_sep-__PAGE_OFFSET
5050 @@ -298,9 +376,7 @@ ENTRY(startup_32_smp)
5054 - jz 1f /* Initial CPU cleans BSS */
5057 + jnz checkCPUtype /* Initial CPU cleans BSS */
5058 #endif /* CONFIG_SMP */
5061 @@ -377,12 +453,12 @@ is386: movl $2,%ecx # set MP
5062 ljmp $(__KERNEL_CS),$1f
5063 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
5064 movl %eax,%ss # after changing gdt.
5065 - movl %eax,%fs # gets reset once there's real percpu
5067 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
5071 + movl $(__KERNEL_PERCPU), %eax
5072 + movl %eax,%fs # set this cpu's percpu
5074 xorl %eax,%eax # Clear GS and LDT
5077 @@ -393,11 +469,7 @@ is386: movl $2,%ecx # set MP
5080 cmpb $0,%cl # the first CPU calls start_kernel
5082 - movl $(__KERNEL_PERCPU), %eax
5083 - movl %eax,%fs # set this cpu's percpu
5084 - jmp initialize_secondary # all other CPUs call initialize_secondary
5086 + jne initialize_secondary # all other CPUs call initialize_secondary
5087 #endif /* CONFIG_SMP */
5090 @@ -483,8 +555,8 @@ early_page_fault:
5095 #ifdef CONFIG_PRINTK
5098 movl $(__KERNEL_DS),%eax
5100 @@ -509,8 +581,8 @@ hlt_loop:
5101 /* This is the default interrupt "handler" :-) */
5105 #ifdef CONFIG_PRINTK
5110 @@ -541,31 +613,58 @@ ignore_int:
5116 - * Real beginning of normal "text" segment
5124 -.section ".bss.page_aligned","wa"
5125 +.section .swapper_pg_dir,"a",@progbits
5126 .align PAGE_SIZE_asm
5127 ENTRY(swapper_pg_dir)
5128 +#ifdef CONFIG_X86_PAE
5129 + .long swapper_pm_dir-__PAGE_OFFSET+1
5131 + .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
5133 + .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
5135 + .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
5141 +.section .swapper_pm_dir,"a",@progbits
5142 +#ifdef CONFIG_X86_PAE
5143 +ENTRY(swapper_pm_dir)
5150 ENTRY(swapper_pg_pmd)
5153 +.section .empty_zero_page,"a",@progbits
5154 ENTRY(empty_zero_page)
5158 + * The IDT has to be page-aligned to simplify the Pentium
5159 + * F0 0F bug workaround.. We have a special link segment
5162 +.section .idt,"a",@progbits
5167 * This starts the data section.
5171 +.section .rodata,"a",@progbits
5173 - .long init_thread_union+THREAD_SIZE
5174 + .long init_thread_union+THREAD_SIZE-8
5178 @@ -615,7 +714,7 @@ idt_descr:
5179 .word 0 # 32 bit align gdt_desc.address
5180 ENTRY(early_gdt_descr)
5181 .word GDT_ENTRIES*8-1
5182 - .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
5183 + .long cpu_gdt_table /* Overwritten for secondary CPUs */
5186 * The boot_gdt must mirror the equivalent in setup.S and is
5187 @@ -624,5 +723,61 @@ ENTRY(early_gdt_descr)
5188 .align L1_CACHE_BYTES
5190 .fill GDT_ENTRY_BOOT_CS,8,0
5191 - .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
5192 - .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
5193 + .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
5194 + .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
5196 + .align PAGE_SIZE_asm
5197 +ENTRY(cpu_gdt_table)
5198 + .quad 0x0000000000000000 /* NULL descriptor */
5199 + .quad 0x0000000000000000 /* 0x0b reserved */
5200 + .quad 0x0000000000000000 /* 0x13 reserved */
5201 + .quad 0x0000000000000000 /* 0x1b reserved */
5202 + .quad 0x0000000000000000 /* 0x20 unused */
5203 + .quad 0x0000000000000000 /* 0x28 unused */
5204 + .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
5205 + .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
5206 + .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
5207 + .quad 0x0000000000000000 /* 0x4b reserved */
5208 + .quad 0x0000000000000000 /* 0x53 reserved */
5209 + .quad 0x0000000000000000 /* 0x5b reserved */
5211 + .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
5212 + .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
5213 + .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
5214 + .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
5216 + .quad 0x0000000000000000 /* 0x80 TSS descriptor */
5217 + .quad 0x0000000000000000 /* 0x88 LDT descriptor */
5220 + * Segments used for calling PnP BIOS have byte granularity.
5221 + * The code segments and data segments have fixed 64k limits,
5222 + * the transfer segment sizes are set at run time.
5224 + .quad 0x00409b000000ffff /* 0x90 32-bit code */
5225 + .quad 0x00009b000000ffff /* 0x98 16-bit code */
5226 + .quad 0x000093000000ffff /* 0xa0 16-bit data */
5227 + .quad 0x0000930000000000 /* 0xa8 16-bit data */
5228 + .quad 0x0000930000000000 /* 0xb0 16-bit data */
5231 + * The APM segments have byte granularity and their bases
5232 + * are set at run time. All have 64k limits.
5234 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
5235 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
5236 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
5238 + .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
5239 + .quad 0x0040930000000000 /* 0xd8 - PERCPU */
5240 + .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
5241 + .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
5242 + .quad 0x0000000000000000 /* 0xf0 - unused */
5243 + .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
5245 + /* Be sure this is zeroed to avoid false validations in Xen */
5246 + .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
5249 + .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
5251 diff -urNp linux-2.6.24.4/arch/x86/kernel/head64.c linux-2.6.24.4/arch/x86/kernel/head64.c
5252 --- linux-2.6.24.4/arch/x86/kernel/head64.c 2008-03-24 14:49:18.000000000 -0400
5253 +++ linux-2.6.24.4/arch/x86/kernel/head64.c 2008-03-26 20:21:08.000000000 -0400
5254 @@ -24,7 +24,7 @@ static void __init zap_identity_mappings
5256 pgd_t *pgd = pgd_offset_k(0UL);
5259 + __flush_tlb_all();
5262 /* Don't add a printk in there. printk relies on the PDA which is not initialized
5263 @@ -56,16 +56,17 @@ void __init x86_64_start_kernel(char * r
5264 /* Make NULL pointers segfault */
5265 zap_identity_mappings();
5267 + for (i = 0; i < NR_CPUS; i++)
5268 + cpu_pda(i) = &boot_cpu_pda[i];
5272 for (i = 0; i < IDT_ENTRIES; i++)
5273 set_intr_gate(i, early_idt_handler);
5274 load_idt((const struct desc_ptr *)&idt_descr);
5276 early_printk("Kernel alive\n");
5278 - for (i = 0; i < NR_CPUS; i++)
5279 - cpu_pda(i) = &boot_cpu_pda[i];
5282 copy_bootdata(__va(real_mode_data));
5284 cpu_set(0, cpu_online_map);
5285 diff -urNp linux-2.6.24.4/arch/x86/kernel/head_64.S linux-2.6.24.4/arch/x86/kernel/head_64.S
5286 --- linux-2.6.24.4/arch/x86/kernel/head_64.S 2008-03-24 14:49:18.000000000 -0400
5287 +++ linux-2.6.24.4/arch/x86/kernel/head_64.S 2008-03-26 20:21:08.000000000 -0400
5288 @@ -173,6 +173,10 @@ ENTRY(secondary_startup_64)
5289 btl $20,%edi /* No Execute supported? */
5291 btsl $_EFER_NX, %eax
5292 + movq $(init_level4_pgt), %rdi
5293 + addq phys_base(%rip), %rdi
5294 + btsq $_PAGE_BIT_NX, 8*258(%rdi)
5295 + btsq $_PAGE_BIT_NX, 8*388(%rdi)
5296 1: wrmsr /* Make changes effective */
5299 @@ -242,24 +246,25 @@ ENTRY(secondary_startup_64)
5300 pushq %rax # target address in negative space
5306 /* SMP bootup changes these two */
5307 -#ifndef CONFIG_HOTPLUG_CPU
5308 - .pushsection .init.data
5309 +#ifdef CONFIG_HOTPLUG_CPU
5317 .quad x86_64_start_kernel
5318 -#ifndef CONFIG_HOTPLUG_CPU
5324 .quad init_thread_union+THREAD_SIZE-8
5330 ENTRY(early_idt_handler)
5331 cmpl $2,early_recursion_flag(%rip)
5333 @@ -280,9 +285,12 @@ ENTRY(early_idt_handler)
5339 early_recursion_flag:
5342 + .section .rodata,"a",@progbits
5344 .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n"
5346 @@ -312,7 +320,9 @@ NEXT_PAGE(init_level4_pgt)
5347 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5349 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5352 + .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
5354 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
5355 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
5357 @@ -320,6 +330,9 @@ NEXT_PAGE(level3_ident_pgt)
5358 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5361 +NEXT_PAGE(level3_vmalloc_pgt)
5364 NEXT_PAGE(level3_kernel_pgt)
5366 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
5367 @@ -355,19 +368,12 @@ NEXT_PAGE(level2_spare_pgt)
5373 .globl cpu_gdt_descr
5375 - .word gdt_end-cpu_gdt_table-1
5387 /* This must match the first entry in level2_kernel_pgt */
5388 @@ -377,8 +383,7 @@ ENTRY(phys_base)
5389 * IRET will check the segment types kkeil 2000/10/28
5390 * Also sysret mandates a special GDT layout
5393 - .section .data.page_aligned, "aw"
5397 /* The TLS descriptors are currently at a different place compared to i386.
5398 @@ -397,15 +402,15 @@ ENTRY(cpu_gdt_table)
5400 .quad 0,0,0 /* three TLS descriptors */
5401 .quad 0x0000f40000000000 /* node/CPU stored in limit */
5403 /* asm/segment.h:GDT_ENTRIES must match this */
5404 /* This should be a multiple of the cache line size */
5405 - /* GDTs of other CPUs are now dynamically allocated */
5407 /* zero the remaining page */
5408 .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
5410 + .fill (NR_CPUS-1) * (PAGE_SIZE),1,0 /* other CPU's GDT */
5413 - .section .bss, "aw", @nobits
5414 .align L1_CACHE_BYTES
5417 diff -urNp linux-2.6.24.4/arch/x86/kernel/hpet.c linux-2.6.24.4/arch/x86/kernel/hpet.c
5418 --- linux-2.6.24.4/arch/x86/kernel/hpet.c 2008-03-24 14:49:18.000000000 -0400
5419 +++ linux-2.6.24.4/arch/x86/kernel/hpet.c 2008-03-26 20:21:08.000000000 -0400
5420 @@ -137,7 +137,7 @@ static void hpet_reserve_platform_timers
5421 hd.hd_irq[1] = HPET_LEGACY_RTC;
5423 for (i = 2; i < nrtimers; timer++, i++)
5424 - hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
5425 + hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
5426 Tn_INT_ROUTE_CNF_SHIFT;
5429 diff -urNp linux-2.6.24.4/arch/x86/kernel/i386_ksyms_32.c linux-2.6.24.4/arch/x86/kernel/i386_ksyms_32.c
5430 --- linux-2.6.24.4/arch/x86/kernel/i386_ksyms_32.c 2008-03-24 14:49:18.000000000 -0400
5431 +++ linux-2.6.24.4/arch/x86/kernel/i386_ksyms_32.c 2008-03-26 20:21:08.000000000 -0400
5433 #include <asm/desc.h>
5434 #include <asm/pgtable.h>
5436 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
5438 EXPORT_SYMBOL(__down_failed);
5439 EXPORT_SYMBOL(__down_failed_interruptible);
5440 EXPORT_SYMBOL(__down_failed_trylock);
5441 EXPORT_SYMBOL(__up_wakeup);
5442 /* Networking helper routines. */
5443 EXPORT_SYMBOL(csum_partial_copy_generic);
5444 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
5445 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
5447 EXPORT_SYMBOL(__get_user_1);
5448 EXPORT_SYMBOL(__get_user_2);
5449 @@ -31,3 +35,7 @@ EXPORT_SYMBOL(__read_lock_failed);
5451 EXPORT_SYMBOL(csum_partial);
5452 EXPORT_SYMBOL(empty_zero_page);
5454 +#ifdef CONFIG_PAX_KERNEXEC
5455 +EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
5457 diff -urNp linux-2.6.24.4/arch/x86/kernel/init_task.c linux-2.6.24.4/arch/x86/kernel/init_task.c
5458 --- linux-2.6.24.4/arch/x86/kernel/init_task.c 2008-03-24 14:49:18.000000000 -0400
5459 +++ linux-2.6.24.4/arch/x86/kernel/init_task.c 2008-03-26 20:21:08.000000000 -0400
5460 @@ -43,5 +43,4 @@ EXPORT_SYMBOL(init_task);
5461 * section. Since TSS's are completely CPU-local, we want them
5462 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
5464 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
5466 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
5467 diff -urNp linux-2.6.24.4/arch/x86/kernel/ioport_32.c linux-2.6.24.4/arch/x86/kernel/ioport_32.c
5468 --- linux-2.6.24.4/arch/x86/kernel/ioport_32.c 2008-03-24 14:49:18.000000000 -0400
5469 +++ linux-2.6.24.4/arch/x86/kernel/ioport_32.c 2008-03-26 20:21:08.000000000 -0400
5471 #include <linux/slab.h>
5472 #include <linux/thread_info.h>
5473 #include <linux/syscalls.h>
5474 +#include <linux/grsecurity.h>
5476 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
5477 static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
5478 @@ -62,9 +63,16 @@ asmlinkage long sys_ioperm(unsigned long
5480 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
5482 +#ifdef CONFIG_GRKERNSEC_IO
5484 + gr_handle_ioperm();
5486 if (turn_on && !capable(CAP_SYS_RAWIO))
5490 +#ifdef CONFIG_GRKERNSEC_IO
5494 * If it's the first ioperm() call in this thread's lifetime, set the
5495 * IO bitmap up. ioperm() is much less timing critical than clone(),
5496 @@ -87,7 +95,7 @@ asmlinkage long sys_ioperm(unsigned long
5497 * because the ->io_bitmap_max value must match the bitmap
5500 - tss = &per_cpu(init_tss, get_cpu());
5501 + tss = init_tss + get_cpu();
5503 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5505 @@ -141,8 +149,13 @@ asmlinkage long sys_iopl(unsigned long u
5507 /* Trying to gain more privileges? */
5509 +#ifdef CONFIG_GRKERNSEC_IO
5513 if (!capable(CAP_SYS_RAWIO))
5517 t->iopl = level << 12;
5518 regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
5519 diff -urNp linux-2.6.24.4/arch/x86/kernel/ioport_64.c linux-2.6.24.4/arch/x86/kernel/ioport_64.c
5520 --- linux-2.6.24.4/arch/x86/kernel/ioport_64.c 2008-03-24 14:49:18.000000000 -0400
5521 +++ linux-2.6.24.4/arch/x86/kernel/ioport_64.c 2008-03-26 20:21:08.000000000 -0400
5523 #include <linux/slab.h>
5524 #include <linux/thread_info.h>
5525 #include <linux/syscalls.h>
5526 +#include <linux/grsecurity.h>
5528 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
5529 static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
5530 @@ -39,8 +40,17 @@ asmlinkage long sys_ioperm(unsigned long
5532 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
5535 +#ifdef CONFIG_GRKERNSEC_IO
5537 + gr_handle_ioperm();
5539 if (turn_on && !capable(CAP_SYS_RAWIO))
5542 +#ifdef CONFIG_GRKERNSEC_IO
5547 * If it's the first ioperm() call in this thread's lifetime, set the
5548 @@ -64,7 +74,7 @@ asmlinkage long sys_ioperm(unsigned long
5549 * because the ->io_bitmap_max value must match the bitmap
5552 - tss = &per_cpu(init_tss, get_cpu());
5553 + tss = init_tss + get_cpu();
5555 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5557 @@ -109,8 +119,13 @@ asmlinkage long sys_iopl(unsigned int le
5559 /* Trying to gain more privileges? */
5561 +#ifdef CONFIG_GRKERNSEC_IO
5565 if (!capable(CAP_SYS_RAWIO))
5569 regs->eflags = (regs->eflags &~ X86_EFLAGS_IOPL) | (level << 12);
5571 diff -urNp linux-2.6.24.4/arch/x86/kernel/irq_32.c linux-2.6.24.4/arch/x86/kernel/irq_32.c
5572 --- linux-2.6.24.4/arch/x86/kernel/irq_32.c 2008-03-24 14:49:18.000000000 -0400
5573 +++ linux-2.6.24.4/arch/x86/kernel/irq_32.c 2008-03-26 20:21:08.000000000 -0400
5574 @@ -115,7 +115,7 @@ fastcall unsigned int do_IRQ(struct pt_r
5575 int arg1, arg2, ebx;
5577 /* build the stack frame on the IRQ stack */
5578 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5579 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5580 irqctx->tinfo.task = curctx->tinfo.task;
5581 irqctx->tinfo.previous_esp = current_stack_pointer;
5583 @@ -211,7 +211,7 @@ asmlinkage void do_softirq(void)
5584 irqctx->tinfo.previous_esp = current_stack_pointer;
5586 /* build the stack frame on the softirq stack */
5587 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5588 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5591 " xchgl %%ebx,%%esp \n"
5592 diff -urNp linux-2.6.24.4/arch/x86/kernel/kprobes_32.c linux-2.6.24.4/arch/x86/kernel/kprobes_32.c
5593 --- linux-2.6.24.4/arch/x86/kernel/kprobes_32.c 2008-03-24 14:49:18.000000000 -0400
5594 +++ linux-2.6.24.4/arch/x86/kernel/kprobes_32.c 2008-03-26 20:21:08.000000000 -0400
5595 @@ -55,9 +55,24 @@ static __always_inline void set_jmp_op(v
5598 } __attribute__((packed)) *jop;
5599 - jop = (struct __arch_jmp_op *)from;
5601 +#ifdef CONFIG_PAX_KERNEXEC
5602 + unsigned long cr0;
5605 + jop = (struct __arch_jmp_op *)(ktla_ktva(from));
5607 +#ifdef CONFIG_PAX_KERNEXEC
5608 + pax_open_kernel(cr0);
5611 jop->raddr = (long)(to) - ((long)(from) + 5);
5612 jop->op = RELATIVEJUMP_INSTRUCTION;
5614 +#ifdef CONFIG_PAX_KERNEXEC
5615 + pax_close_kernel(cr0);
5621 @@ -159,14 +174,28 @@ static int __kprobes is_IF_modifier(kpro
5623 int __kprobes arch_prepare_kprobe(struct kprobe *p)
5626 +#ifdef CONFIG_PAX_KERNEXEC
5627 + unsigned long cr0;
5630 /* insn: must be on special executable page on i386. */
5631 p->ainsn.insn = get_insn_slot();
5635 - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5636 - p->opcode = *p->addr;
5637 - if (can_boost(p->addr)) {
5638 +#ifdef CONFIG_PAX_KERNEXEC
5639 + pax_open_kernel(cr0);
5642 + memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5644 +#ifdef CONFIG_PAX_KERNEXEC
5645 + pax_close_kernel(cr0);
5648 + p->opcode = *(ktla_ktva(p->addr));
5649 + if (can_boost(ktla_ktva(p->addr))) {
5650 p->ainsn.boostable = 0;
5652 p->ainsn.boostable = -1;
5653 @@ -225,7 +254,7 @@ static void __kprobes prepare_singlestep
5654 if (p->opcode == BREAKPOINT_INSTRUCTION)
5655 regs->eip = (unsigned long)p->addr;
5657 - regs->eip = (unsigned long)p->ainsn.insn;
5658 + regs->eip = ktva_ktla((unsigned long)p->ainsn.insn);
5661 /* Called with kretprobe_lock held */
5662 @@ -331,7 +360,7 @@ ss_probe:
5663 if (p->ainsn.boostable == 1 && !p->post_handler){
5664 /* Boost up -- we can execute copied instructions directly */
5665 reset_current_kprobe();
5666 - regs->eip = (unsigned long)p->ainsn.insn;
5667 + regs->eip = ktva_ktla((unsigned long)p->ainsn.insn);
5668 preempt_enable_no_resched();
5671 @@ -481,7 +510,7 @@ static void __kprobes resume_execution(s
5672 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
5674 unsigned long *tos = (unsigned long *)®s->esp;
5675 - unsigned long copy_eip = (unsigned long)p->ainsn.insn;
5676 + unsigned long copy_eip = ktva_ktla((unsigned long)p->ainsn.insn);
5677 unsigned long orig_eip = (unsigned long)p->addr;
5679 regs->eflags &= ~TF_MASK;
5680 @@ -655,7 +684,7 @@ int __kprobes kprobe_exceptions_notify(s
5681 struct die_args *args = (struct die_args *)data;
5682 int ret = NOTIFY_DONE;
5684 - if (args->regs && user_mode_vm(args->regs))
5685 + if (args->regs && user_mode(args->regs))
5689 diff -urNp linux-2.6.24.4/arch/x86/kernel/kprobes_64.c linux-2.6.24.4/arch/x86/kernel/kprobes_64.c
5690 --- linux-2.6.24.4/arch/x86/kernel/kprobes_64.c 2008-03-24 14:49:18.000000000 -0400
5691 +++ linux-2.6.24.4/arch/x86/kernel/kprobes_64.c 2008-03-26 20:21:08.000000000 -0400
5692 @@ -190,7 +190,19 @@ static s32 __kprobes *is_riprel(u8 *insn
5693 static void __kprobes arch_copy_kprobe(struct kprobe *p)
5697 +#ifdef CONFIG_PAX_KERNEXEC
5698 + unsigned long cr0;
5700 + pax_open_kernel(cr0);
5703 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
5705 +#ifdef CONFIG_PAX_KERNEXEC
5706 + pax_close_kernel(cr0);
5709 ripdisp = is_riprel(p->ainsn.insn);
5712 @@ -208,7 +220,17 @@ static void __kprobes arch_copy_kprobe(s
5714 s64 disp = (u8 *) p->addr + *ripdisp - (u8 *) p->ainsn.insn;
5715 BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
5717 +#ifdef CONFIG_PAX_KERNEXEC
5718 + pax_open_kernel(cr0);
5723 +#ifdef CONFIG_PAX_KERNEXEC
5724 + pax_close_kernel(cr0);
5728 p->opcode = *p->addr;
5730 diff -urNp linux-2.6.24.4/arch/x86/kernel/ldt_32.c linux-2.6.24.4/arch/x86/kernel/ldt_32.c
5731 --- linux-2.6.24.4/arch/x86/kernel/ldt_32.c 2008-03-24 14:49:18.000000000 -0400
5732 +++ linux-2.6.24.4/arch/x86/kernel/ldt_32.c 2008-03-26 20:21:08.000000000 -0400
5733 @@ -56,7 +56,7 @@ static int alloc_ldt(mm_context_t *pc, i
5738 + load_LDT_nolock(pc);
5739 mask = cpumask_of_cpu(smp_processor_id());
5740 if (!cpus_equal(current->mm->cpu_vm_mask, mask))
5741 smp_call_function(flush_ldt, NULL, 1, 1);
5742 @@ -100,6 +100,22 @@ int init_new_context(struct task_struct
5743 retval = copy_ldt(&mm->context, &old_mm->context);
5744 mutex_unlock(&old_mm->context.lock);
5747 + if (tsk == current) {
5748 + mm->context.vdso = ~0UL;
5750 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5751 + mm->context.user_cs_base = 0UL;
5752 + mm->context.user_cs_limit = ~0UL;
5754 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5755 + cpus_clear(mm->context.cpu_user_cs_mask);
5765 @@ -210,6 +226,13 @@ static int write_ldt(void __user * ptr,
5769 +#ifdef CONFIG_PAX_SEGMEXEC
5770 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
5776 entry_1 = LDT_entry_a(&ldt_info);
5777 entry_2 = LDT_entry_b(&ldt_info);
5779 diff -urNp linux-2.6.24.4/arch/x86/kernel/machine_kexec_32.c linux-2.6.24.4/arch/x86/kernel/machine_kexec_32.c
5780 --- linux-2.6.24.4/arch/x86/kernel/machine_kexec_32.c 2008-03-24 14:49:18.000000000 -0400
5781 +++ linux-2.6.24.4/arch/x86/kernel/machine_kexec_32.c 2008-03-26 20:21:08.000000000 -0400
5782 @@ -30,25 +30,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
5783 static u32 kexec_pte0[1024] PAGE_ALIGNED;
5784 static u32 kexec_pte1[1024] PAGE_ALIGNED;
5786 -static void set_idt(void *newidt, __u16 limit)
5787 +static void set_idt(struct desc_struct *newidt, __u16 limit)
5789 struct Xgt_desc_struct curidt;
5791 /* ia32 supports unaliged loads & stores */
5792 curidt.size = limit;
5793 - curidt.address = (unsigned long)newidt;
5794 + curidt.address = newidt;
5800 -static void set_gdt(void *newgdt, __u16 limit)
5801 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
5803 struct Xgt_desc_struct curgdt;
5805 /* ia32 supports unaligned loads & stores */
5806 curgdt.size = limit;
5807 - curgdt.address = (unsigned long)newgdt;
5808 + curgdt.address = newgdt;
5812 @@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim
5813 local_irq_disable();
5815 control_page = page_address(image->control_code_page);
5816 - memcpy(control_page, relocate_kernel, PAGE_SIZE);
5817 + memcpy(control_page, ktla_ktva(relocate_kernel), PAGE_SIZE);
5819 page_list[PA_CONTROL_PAGE] = __pa(control_page);
5820 - page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
5821 + page_list[VA_CONTROL_PAGE] = ktla_ktva((unsigned long)relocate_kernel);
5822 page_list[PA_PGD] = __pa(kexec_pgd);
5823 page_list[VA_PGD] = (unsigned long)kexec_pgd;
5824 #ifdef CONFIG_X86_PAE
5825 diff -urNp linux-2.6.24.4/arch/x86/kernel/Makefile_64 linux-2.6.24.4/arch/x86/kernel/Makefile_64
5826 --- linux-2.6.24.4/arch/x86/kernel/Makefile_64 2008-03-24 14:49:18.000000000 -0400
5827 +++ linux-2.6.24.4/arch/x86/kernel/Makefile_64 2008-03-26 20:21:08.000000000 -0400
5828 @@ -42,4 +42,6 @@ obj-$(CONFIG_PCI) += early-quirks.o
5830 obj-y += pcspeaker.o
5832 -CFLAGS_vsyscall_64.o := $(PROFILING) -g0
5833 +CFLAGS_vsyscall_64.o := $(PROFILING) -g0 -fno-stack-protector
5834 +CFLAGS_hpet.o := -fno-stack-protector
5835 +CFLAGS_tsc_64.o := -fno-stack-protector
5836 diff -urNp linux-2.6.24.4/arch/x86/kernel/module_32.c linux-2.6.24.4/arch/x86/kernel/module_32.c
5837 --- linux-2.6.24.4/arch/x86/kernel/module_32.c 2008-03-24 14:49:18.000000000 -0400
5838 +++ linux-2.6.24.4/arch/x86/kernel/module_32.c 2008-03-26 20:21:08.000000000 -0400
5840 #include <linux/kernel.h>
5841 #include <linux/bug.h>
5843 +#include <asm/desc.h>
5846 #define DEBUGP printk
5848 @@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
5853 +#ifdef CONFIG_PAX_KERNEXEC
5854 + return vmalloc(size);
5856 return vmalloc_exec(size);
5861 +#ifdef CONFIG_PAX_KERNEXEC
5862 +void *module_alloc_exec(unsigned long size)
5864 + struct vm_struct *area;
5869 + area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
5871 + return area->addr;
5877 /* Free memory returned from module_alloc */
5878 void module_free(struct module *mod, void *module_region)
5879 @@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
5883 +#ifdef CONFIG_PAX_KERNEXEC
5884 +void module_free_exec(struct module *mod, void *module_region)
5886 + struct vm_struct **p, *tmp;
5888 + if (!module_region)
5891 + if ((PAGE_SIZE-1) & (unsigned long)module_region) {
5892 + printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
5897 + write_lock(&vmlist_lock);
5898 + for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
5899 + if (tmp->addr == module_region)
5903 + unsigned long cr0;
5905 + pax_open_kernel(cr0);
5906 + memset(tmp->addr, 0xCC, tmp->size);
5907 + pax_close_kernel(cr0);
5912 + write_unlock(&vmlist_lock);
5915 + printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
5922 /* We don't need anything special. */
5923 int module_frob_arch_sections(Elf_Ehdr *hdr,
5925 @@ -63,14 +125,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5927 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
5929 - uint32_t *location;
5930 + uint32_t *plocation, location;
5932 +#ifdef CONFIG_PAX_KERNEXEC
5933 + unsigned long cr0;
5936 DEBUGP("Applying relocate section %u to %u\n", relsec,
5937 sechdrs[relsec].sh_info);
5938 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
5939 /* This is where to make the change */
5940 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
5941 - + rel[i].r_offset;
5942 + plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
5943 + location = (uint32_t)plocation;
5944 + if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
5945 + plocation = ktla_ktva((void *)plocation);
5946 /* This is the symbol it is referring to. Note that all
5947 undefined symbols have been resolved. */
5948 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
5949 @@ -78,12 +146,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5951 switch (ELF32_R_TYPE(rel[i].r_info)) {
5954 +#ifdef CONFIG_PAX_KERNEXEC
5955 + pax_open_kernel(cr0);
5958 /* We add the value into the location given */
5959 - *location += sym->st_value;
5960 + *plocation += sym->st_value;
5962 +#ifdef CONFIG_PAX_KERNEXEC
5963 + pax_close_kernel(cr0);
5969 +#ifdef CONFIG_PAX_KERNEXEC
5970 + pax_open_kernel(cr0);
5973 /* Add the value, subtract its postition */
5974 - *location += sym->st_value - (uint32_t)location;
5975 + *plocation += sym->st_value - location;
5977 +#ifdef CONFIG_PAX_KERNEXEC
5978 + pax_close_kernel(cr0);
5983 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
5984 diff -urNp linux-2.6.24.4/arch/x86/kernel/module_64.c linux-2.6.24.4/arch/x86/kernel/module_64.c
5985 --- linux-2.6.24.4/arch/x86/kernel/module_64.c 2008-03-24 14:49:18.000000000 -0400
5986 +++ linux-2.6.24.4/arch/x86/kernel/module_64.c 2008-03-26 20:21:08.000000000 -0400
5987 @@ -39,7 +39,7 @@ void module_free(struct module *mod, voi
5991 -void *module_alloc(unsigned long size)
5992 +static void *__module_alloc(unsigned long size, pgprot_t prot)
5994 struct vm_struct *area;
5996 @@ -53,8 +53,31 @@ void *module_alloc(unsigned long size)
6000 - return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
6001 + return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
6004 +#ifdef CONFIG_PAX_KERNEXEC
6005 +void *module_alloc(unsigned long size)
6007 + return __module_alloc(size, PAGE_KERNEL);
6010 +void module_free_exec(struct module *mod, void *module_region)
6012 + module_free(mod, module_region);
6015 +void *module_alloc_exec(unsigned long size)
6017 + return __module_alloc(size, PAGE_KERNEL_RX);
6020 +void *module_alloc(unsigned long size)
6022 + return __module_alloc(size, PAGE_KERNEL_EXEC);
6028 /* We don't need anything special. */
6029 @@ -76,7 +99,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
6030 Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
6036 +#ifdef CONFIG_PAX_KERNEXEC
6037 + unsigned long cr0;
6040 DEBUGP("Applying relocate section %u to %u\n", relsec,
6041 sechdrs[relsec].sh_info);
6042 @@ -100,21 +127,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
6047 +#ifdef CONFIG_PAX_KERNEXEC
6048 + pax_open_kernel(cr0);
6053 +#ifdef CONFIG_PAX_KERNEXEC
6054 + pax_close_kernel(cr0);
6060 +#ifdef CONFIG_PAX_KERNEXEC
6061 + pax_open_kernel(cr0);
6066 +#ifdef CONFIG_PAX_KERNEXEC
6067 + pax_close_kernel(cr0);
6070 if (val != *(u32 *)loc)
6075 +#ifdef CONFIG_PAX_KERNEXEC
6076 + pax_open_kernel(cr0);
6081 +#ifdef CONFIG_PAX_KERNEXEC
6082 + pax_close_kernel(cr0);
6085 if ((s64)val != *(s32 *)loc)
6091 +#ifdef CONFIG_PAX_KERNEXEC
6092 + pax_open_kernel(cr0);
6097 +#ifdef CONFIG_PAX_KERNEXEC
6098 + pax_close_kernel(cr0);
6102 if ((s64)val != *(s32 *)loc)
6104 diff -urNp linux-2.6.24.4/arch/x86/kernel/paravirt_32.c linux-2.6.24.4/arch/x86/kernel/paravirt_32.c
6105 --- linux-2.6.24.4/arch/x86/kernel/paravirt_32.c 2008-03-24 14:49:18.000000000 -0400
6106 +++ linux-2.6.24.4/arch/x86/kernel/paravirt_32.c 2008-03-26 20:21:08.000000000 -0400
6107 @@ -39,7 +39,7 @@ void _paravirt_nop(void)
6111 -static void __init default_banner(void)
6112 +static void default_banner(void)
6114 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
6116 @@ -206,7 +206,7 @@ unsigned paravirt_patch_insns(void *insn
6117 if (insn_len > len || start == NULL)
6120 - memcpy(insnbuf, start, insn_len);
6121 + memcpy(insnbuf, ktla_ktva(start), insn_len);
6125 @@ -324,21 +324,21 @@ enum paravirt_lazy_mode paravirt_get_laz
6126 return x86_read_percpu(paravirt_lazy_mode);
6129 -struct pv_info pv_info = {
6130 +struct pv_info pv_info __read_only = {
6131 .name = "bare hardware",
6132 .paravirt_enabled = 0,
6134 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
6137 -struct pv_init_ops pv_init_ops = {
6138 +struct pv_init_ops pv_init_ops __read_only = {
6139 .patch = native_patch,
6140 .banner = default_banner,
6141 .arch_setup = paravirt_nop,
6142 .memory_setup = machine_specific_memory_setup,
6145 -struct pv_time_ops pv_time_ops = {
6146 +struct pv_time_ops pv_time_ops __read_only = {
6147 .time_init = hpet_time_init,
6148 .get_wallclock = native_get_wallclock,
6149 .set_wallclock = native_set_wallclock,
6150 @@ -346,7 +346,7 @@ struct pv_time_ops pv_time_ops = {
6151 .get_cpu_khz = native_calculate_cpu_khz,
6154 -struct pv_irq_ops pv_irq_ops = {
6155 +struct pv_irq_ops pv_irq_ops __read_only = {
6156 .init_IRQ = native_init_IRQ,
6157 .save_fl = native_save_fl,
6158 .restore_fl = native_restore_fl,
6159 @@ -356,7 +356,7 @@ struct pv_irq_ops pv_irq_ops = {
6160 .halt = native_halt,
6163 -struct pv_cpu_ops pv_cpu_ops = {
6164 +struct pv_cpu_ops pv_cpu_ops __read_only = {
6165 .cpuid = native_cpuid,
6166 .get_debugreg = native_get_debugreg,
6167 .set_debugreg = native_set_debugreg,
6168 @@ -396,7 +396,7 @@ struct pv_cpu_ops pv_cpu_ops = {
6172 -struct pv_apic_ops pv_apic_ops = {
6173 +struct pv_apic_ops pv_apic_ops __read_only = {
6174 #ifdef CONFIG_X86_LOCAL_APIC
6175 .apic_write = native_apic_write,
6176 .apic_write_atomic = native_apic_write_atomic,
6177 @@ -407,7 +407,7 @@ struct pv_apic_ops pv_apic_ops = {
6181 -struct pv_mmu_ops pv_mmu_ops = {
6182 +struct pv_mmu_ops pv_mmu_ops __read_only = {
6183 .pagetable_setup_start = native_pagetable_setup_start,
6184 .pagetable_setup_done = native_pagetable_setup_done,
6186 diff -urNp linux-2.6.24.4/arch/x86/kernel/process_32.c linux-2.6.24.4/arch/x86/kernel/process_32.c
6187 --- linux-2.6.24.4/arch/x86/kernel/process_32.c 2008-03-24 14:49:18.000000000 -0400
6188 +++ linux-2.6.24.4/arch/x86/kernel/process_32.c 2008-03-26 20:21:08.000000000 -0400
6189 @@ -66,15 +66,17 @@ EXPORT_SYMBOL(boot_option_idle_override)
6190 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
6191 EXPORT_PER_CPU_SYMBOL(current_task);
6194 DEFINE_PER_CPU(int, cpu_number);
6195 EXPORT_PER_CPU_SYMBOL(cpu_number);
6199 * Return saved PC of a blocked thread.
6201 unsigned long thread_saved_pc(struct task_struct *tsk)
6203 - return ((unsigned long *)tsk->thread.esp)[3];
6204 + return tsk->thread.eip;
6208 @@ -313,7 +315,7 @@ void __show_registers(struct pt_regs *re
6210 unsigned short ss, gs;
6212 - if (user_mode_vm(regs)) {
6213 + if (user_mode(regs)) {
6215 ss = regs->xss & 0xffff;
6216 savesegment(gs, gs);
6217 @@ -391,8 +393,8 @@ int kernel_thread(int (*fn)(void *), voi
6218 regs.ebx = (unsigned long) fn;
6219 regs.edx = (unsigned long) arg;
6221 - regs.xds = __USER_DS;
6222 - regs.xes = __USER_DS;
6223 + regs.xds = __KERNEL_DS;
6224 + regs.xes = __KERNEL_DS;
6225 regs.xfs = __KERNEL_PERCPU;
6227 regs.eip = (unsigned long) kernel_thread_helper;
6228 @@ -414,7 +416,7 @@ void exit_thread(void)
6229 struct task_struct *tsk = current;
6230 struct thread_struct *t = &tsk->thread;
6231 int cpu = get_cpu();
6232 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
6233 + struct tss_struct *tss = init_tss + cpu;
6235 kfree(t->io_bitmap_ptr);
6236 t->io_bitmap_ptr = NULL;
6237 @@ -435,6 +437,7 @@ void flush_thread(void)
6239 struct task_struct *tsk = current;
6241 + __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
6242 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
6243 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
6244 clear_tsk_thread_flag(tsk, TIF_DEBUG);
6245 @@ -468,7 +471,7 @@ int copy_thread(int nr, unsigned long cl
6246 struct task_struct *tsk;
6249 - childregs = task_pt_regs(p);
6250 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
6253 childregs->esp = esp;
6254 @@ -510,6 +513,11 @@ int copy_thread(int nr, unsigned long cl
6255 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6258 +#ifdef CONFIG_PAX_SEGMEXEC
6259 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6263 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
6264 desc->a = LDT_entry_a(&info);
6265 desc->b = LDT_entry_b(&info);
6266 @@ -696,7 +704,7 @@ struct task_struct fastcall * __switch_t
6267 struct thread_struct *prev = &prev_p->thread,
6268 *next = &next_p->thread;
6269 int cpu = smp_processor_id();
6270 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
6271 + struct tss_struct *tss = init_tss + cpu;
6273 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
6275 @@ -724,6 +732,11 @@ struct task_struct fastcall * __switch_t
6277 savesegment(gs, prev->gs);
6279 +#ifdef CONFIG_PAX_MEMORY_UDEREF
6280 + if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
6281 + __set_fs(task_thread_info(next_p)->addr_limit, cpu);
6285 * Load the per-thread Thread-Local Storage descriptor.
6287 @@ -888,6 +901,12 @@ asmlinkage int sys_set_thread_area(struc
6289 if (copy_from_user(&info, u_info, sizeof(info)))
6292 +#ifdef CONFIG_PAX_SEGMEXEC
6293 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6297 idx = info.entry_number;
6300 @@ -976,9 +995,27 @@ asmlinkage int sys_get_thread_area(struc
6304 -unsigned long arch_align_stack(unsigned long sp)
6305 +#ifdef CONFIG_PAX_RANDKSTACK
6306 +asmlinkage void pax_randomize_kstack(void)
6308 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6309 - sp -= get_random_int() % 8192;
6311 + struct thread_struct *thread = ¤t->thread;
6312 + unsigned long time;
6314 + if (!randomize_va_space)
6319 + /* P4 seems to return a 0 LSB, ignore it */
6320 +#ifdef CONFIG_MPENTIUM4
6328 + thread->esp0 ^= time;
6329 + load_esp0(init_tss + smp_processor_id(), thread);
6332 diff -urNp linux-2.6.24.4/arch/x86/kernel/process_64.c linux-2.6.24.4/arch/x86/kernel/process_64.c
6333 --- linux-2.6.24.4/arch/x86/kernel/process_64.c 2008-03-24 14:49:18.000000000 -0400
6334 +++ linux-2.6.24.4/arch/x86/kernel/process_64.c 2008-03-26 20:21:08.000000000 -0400
6335 @@ -210,6 +210,8 @@ static inline void play_dead(void)
6336 void cpu_idle (void)
6338 current_thread_info()->status |= TS_POLLING;
6339 + current->stack_canary = pax_get_random_long();
6340 + write_pda(stack_canary, current->stack_canary);
6341 /* endless idle loop with no priority at all */
6343 tick_nohz_stop_sched_tick();
6344 @@ -390,7 +392,7 @@ void exit_thread(void)
6345 struct thread_struct *t = &me->thread;
6347 if (me->thread.io_bitmap_ptr) {
6348 - struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
6349 + struct tss_struct *tss = init_tss + get_cpu();
6351 kfree(t->io_bitmap_ptr);
6352 t->io_bitmap_ptr = NULL;
6353 @@ -597,7 +599,7 @@ __switch_to(struct task_struct *prev_p,
6354 struct thread_struct *prev = &prev_p->thread,
6355 *next = &next_p->thread;
6356 int cpu = smp_processor_id();
6357 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
6358 + struct tss_struct *tss = init_tss + cpu;
6360 /* we're going to use this soon, after a few expensive things */
6361 if (next_p->fpu_counter>5)
6362 @@ -672,7 +674,6 @@ __switch_to(struct task_struct *prev_p,
6363 write_pda(kernelstack,
6364 (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
6365 #ifdef CONFIG_CC_STACKPROTECTOR
6366 - write_pda(stack_canary, next_p->stack_canary);
6368 * Build time only check to make sure the stack_canary is at
6369 * offset 40 in the pda; this is a gcc ABI requirement
6370 @@ -701,7 +702,7 @@ __switch_to(struct task_struct *prev_p,
6373 long sys_execve(char __user *name, char __user * __user *argv,
6374 - char __user * __user *envp, struct pt_regs regs)
6375 + char __user * __user *envp, struct pt_regs *regs)
6379 @@ -710,7 +711,7 @@ long sys_execve(char __user *name, char
6380 error = PTR_ERR(filename);
6381 if (IS_ERR(filename))
6383 - error = do_execve(filename, argv, envp, ®s);
6384 + error = do_execve(filename, argv, envp, regs);
6387 current->ptrace &= ~PT_DTRACE;
6388 @@ -906,10 +907,3 @@ int dump_task_regs(struct task_struct *t
6393 -unsigned long arch_align_stack(unsigned long sp)
6395 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6396 - sp -= get_random_int() % 8192;
6399 diff -urNp linux-2.6.24.4/arch/x86/kernel/ptrace_32.c linux-2.6.24.4/arch/x86/kernel/ptrace_32.c
6400 --- linux-2.6.24.4/arch/x86/kernel/ptrace_32.c 2008-03-24 14:49:18.000000000 -0400
6401 +++ linux-2.6.24.4/arch/x86/kernel/ptrace_32.c 2008-03-26 20:21:08.000000000 -0400
6402 @@ -160,22 +160,20 @@ static unsigned long convert_eip_to_line
6403 * and APM bios ones we just ignore here.
6405 if (seg & LDT_SEGMENT) {
6407 + struct desc_struct *desc;
6413 mutex_lock(&child->mm->context.lock);
6414 - if (unlikely((seg >> 3) >= child->mm->context.size))
6415 - addr = -1L; /* bogus selector, access would fault */
6416 + if (unlikely(seg >= child->mm->context.size))
6419 - desc = child->mm->context.ldt + seg;
6420 - base = ((desc[0] >> 16) |
6421 - ((desc[1] & 0xff) << 16) |
6422 - (desc[1] & 0xff000000));
6423 + desc = &child->mm->context.ldt[seg];
6424 + base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
6426 /* 16-bit code segment? */
6427 - if (!((desc[1] >> 22) & 1))
6428 + if (!((desc->b >> 22) & 1))
6432 @@ -190,6 +188,9 @@ static inline int is_setting_trap_flag(s
6433 unsigned char opcode[15];
6434 unsigned long addr = convert_eip_to_linear(child, regs);
6436 + if (addr == -EINVAL)
6439 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6440 for (i = 0; i < copied; i++) {
6441 switch (opcode[i]) {
6442 @@ -340,6 +341,11 @@ ptrace_set_thread_area(struct task_struc
6443 if (copy_from_user(&info, user_desc, sizeof(info)))
6446 +#ifdef CONFIG_PAX_SEGMEXEC
6447 + if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6451 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6454 @@ -419,7 +425,17 @@ long arch_ptrace(struct task_struct *chi
6455 if(addr == (long) &dummy->u_debugreg[5]) break;
6456 if(addr < (long) &dummy->u_debugreg[4] &&
6457 ((unsigned long) data) >= TASK_SIZE-3) break;
6460 +#ifdef CONFIG_GRKERNSEC
6461 + if(addr >= (long) &dummy->u_debugreg[0] &&
6462 + addr <= (long) &dummy->u_debugreg[3]) {
6463 + long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
6464 + long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
6465 + long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
6466 + if ((type & 1) && (data & align))
6470 /* Sanity-check data. Take one half-byte at once with
6471 * check = (val >> (16 + 4*i)) & 0xf. It contains the
6472 * R/Wi and LENi bits; bits 0 and 1 are R/Wi, and bits
6473 @@ -630,7 +646,7 @@ void send_sigtrap(struct task_struct *ts
6474 info.si_code = TRAP_BRKPT;
6476 /* User-mode eip? */
6477 - info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
6478 + info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
6480 /* Send us the fake SIGTRAP */
6481 force_sig_info(SIGTRAP, &info, tsk);
6482 diff -urNp linux-2.6.24.4/arch/x86/kernel/ptrace_64.c linux-2.6.24.4/arch/x86/kernel/ptrace_64.c
6483 --- linux-2.6.24.4/arch/x86/kernel/ptrace_64.c 2008-03-24 14:49:18.000000000 -0400
6484 +++ linux-2.6.24.4/arch/x86/kernel/ptrace_64.c 2008-03-26 20:21:08.000000000 -0400
6485 @@ -98,22 +98,20 @@ unsigned long convert_rip_to_linear(stru
6486 * and APM bios ones we just ignore here.
6488 if (seg & LDT_SEGMENT) {
6490 + struct desc_struct *desc;
6496 mutex_lock(&child->mm->context.lock);
6497 - if (unlikely((seg >> 3) >= child->mm->context.size))
6498 - addr = -1L; /* bogus selector, access would fault */
6499 + if (unlikely(seg >= child->mm->context.size))
6500 + addr = -EINVAL; /* bogus selector, access would fault */
6502 - desc = child->mm->context.ldt + seg;
6503 - base = ((desc[0] >> 16) |
6504 - ((desc[1] & 0xff) << 16) |
6505 - (desc[1] & 0xff000000));
6506 + desc = &child->mm->context.ldt[seg];
6507 + base = desc->base0 | (desc->base1 << 16) | (desc->base2 << 24);
6509 /* 16-bit code segment? */
6510 - if (!((desc[1] >> 22) & 1))
6515 @@ -129,6 +127,9 @@ static int is_setting_trap_flag(struct t
6516 unsigned char opcode[15];
6517 unsigned long addr = convert_rip_to_linear(child, regs);
6519 + if (addr == -EINVAL)
6522 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6523 for (i = 0; i < copied; i++) {
6524 switch (opcode[i]) {
6525 diff -urNp linux-2.6.24.4/arch/x86/kernel/reboot_32.c linux-2.6.24.4/arch/x86/kernel/reboot_32.c
6526 --- linux-2.6.24.4/arch/x86/kernel/reboot_32.c 2008-03-24 14:49:18.000000000 -0400
6527 +++ linux-2.6.24.4/arch/x86/kernel/reboot_32.c 2008-03-26 20:21:08.000000000 -0400
6529 void (*pm_power_off)(void);
6530 EXPORT_SYMBOL(pm_power_off);
6532 -static int reboot_mode;
6533 +static unsigned short reboot_mode;
6534 static int reboot_thru_bios;
6537 @@ -135,7 +135,7 @@ static struct dmi_system_id __initdata r
6538 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
6542 + { NULL, NULL, {{0, NULL}}, NULL}
6545 static int __init reboot_init(void)
6546 @@ -153,18 +153,18 @@ core_initcall(reboot_init);
6547 doesn't work with at least one type of 486 motherboard. It is easy
6548 to stop this code working; hence the copious comments. */
6550 -static unsigned long long
6551 -real_mode_gdt_entries [3] =
6552 +static struct desc_struct
6553 +real_mode_gdt_entries [3] __read_only =
6555 - 0x0000000000000000ULL, /* Null descriptor */
6556 - 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
6557 - 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
6558 + {0x00000000, 0x00000000}, /* Null descriptor */
6559 + {0x0000ffff, 0x00009b00}, /* 16-bit real-mode 64k code at 0x00000000 */
6560 + {0x0100ffff, 0x00009300} /* 16-bit real-mode 64k data at 0x00000100 */
6563 -static struct Xgt_desc_struct
6564 -real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
6565 -real_mode_idt = { 0x3ff, 0 },
6567 +static const struct Xgt_desc_struct
6568 +real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (struct desc_struct *)__pa(real_mode_gdt_entries), 0 },
6569 +real_mode_idt = { 0x3ff, NULL, 0 },
6570 +no_idt = { 0, NULL, 0 };
6573 /* This is 16-bit protected mode code to disable paging and the cache,
6574 @@ -186,7 +186,7 @@ no_idt = { 0, 0 };
6575 More could be done here to set up the registers as if a CPU reset had
6576 occurred; hopefully real BIOSs don't assume much. */
6578 -static unsigned char real_mode_switch [] =
6579 +static const unsigned char real_mode_switch [] =
6581 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
6582 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
6583 @@ -200,7 +200,7 @@ static unsigned char real_mode_switch []
6584 0x24, 0x10, /* f: andb $0x10,al */
6585 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
6587 -static unsigned char jump_to_bios [] =
6588 +static const unsigned char jump_to_bios [] =
6590 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
6592 @@ -210,7 +210,7 @@ static unsigned char jump_to_bios [] =
6593 * specified by the code and length parameters.
6594 * We assume that length will aways be less that 100!
6596 -void machine_real_restart(unsigned char *code, int length)
6597 +void machine_real_restart(const unsigned char *code, unsigned int length)
6599 local_irq_disable();
6601 @@ -232,8 +232,8 @@ void machine_real_restart(unsigned char
6602 from the kernel segment. This assumes the kernel segment starts at
6603 virtual address PAGE_OFFSET. */
6605 - memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
6606 - sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
6607 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
6608 + min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
6611 * Use `swapper_pg_dir' as our page directory.
6612 @@ -246,7 +246,7 @@ void machine_real_restart(unsigned char
6613 REBOOT.COM programs, and the previous reset routine did this
6616 - *((unsigned short *)0x472) = reboot_mode;
6617 + *(unsigned short *)(__va(0x472)) = reboot_mode;
6619 /* For the switch to real mode, copy some code to low memory. It has
6620 to be in the first 64k because it is running in 16-bit mode, and it
6621 @@ -254,9 +254,8 @@ void machine_real_restart(unsigned char
6622 off paging. Copy it near the end of the first page, out of the way
6623 of BIOS variables. */
6625 - memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
6626 - real_mode_switch, sizeof (real_mode_switch));
6627 - memcpy ((void *) (0x1000 - 100), code, length);
6628 + memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
6629 + memcpy(__va(0x1000 - 100), code, length);
6631 /* Set up the IDT for real mode. */
6633 diff -urNp linux-2.6.24.4/arch/x86/kernel/setup_32.c linux-2.6.24.4/arch/x86/kernel/setup_32.c
6634 --- linux-2.6.24.4/arch/x86/kernel/setup_32.c 2008-03-24 14:49:18.000000000 -0400
6635 +++ linux-2.6.24.4/arch/x86/kernel/setup_32.c 2008-03-26 20:21:08.000000000 -0400
6637 #include <setup_arch.h>
6638 #include <bios_ebda.h>
6639 #include <asm/cacheflush.h>
6640 +#include <asm/boot.h>
6642 /* This value is set up by the early boot code to point to the value
6643 immediately after the boot time page tables. It contains a *physical*
6644 @@ -82,7 +83,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini
6645 struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
6646 EXPORT_SYMBOL(boot_cpu_data);
6648 +#ifdef CONFIG_X86_PAE
6649 +unsigned long mmu_cr4_features = X86_CR4_PAE;
6651 unsigned long mmu_cr4_features;
6654 /* for MCA, but anyone else can use it if they want */
6655 unsigned int machine_id;
6656 @@ -436,8 +441,8 @@ void __init setup_bootmem_allocator(void
6657 * the (very unlikely) case of us accidentally initializing the
6658 * bootmem allocator with an invalid RAM area.
6660 - reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
6661 - bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
6662 + reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
6663 + bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR);
6666 * reserve physical page 0 - it's a special BIOS page on many boxes,
6667 @@ -590,14 +595,14 @@ void __init setup_arch(char **cmdline_p)
6669 if (!boot_params.hdr.root_flags)
6670 root_mountflags &= ~MS_RDONLY;
6671 - init_mm.start_code = (unsigned long) _text;
6672 - init_mm.end_code = (unsigned long) _etext;
6673 + init_mm.start_code = ktla_ktva((unsigned long) _text);
6674 + init_mm.end_code = ktla_ktva((unsigned long) _etext);
6675 init_mm.end_data = (unsigned long) _edata;
6676 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
6678 - code_resource.start = virt_to_phys(_text);
6679 - code_resource.end = virt_to_phys(_etext)-1;
6680 - data_resource.start = virt_to_phys(_etext);
6681 + code_resource.start = virt_to_phys(ktla_ktva(_text));
6682 + code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
6683 + data_resource.start = virt_to_phys(_data);
6684 data_resource.end = virt_to_phys(_edata)-1;
6685 bss_resource.start = virt_to_phys(&__bss_start);
6686 bss_resource.end = virt_to_phys(&__bss_stop)-1;
6687 @@ -692,3 +697,23 @@ void __init setup_arch(char **cmdline_p)
6692 +unsigned long __per_cpu_offset[NR_CPUS] __read_only;
6694 +EXPORT_SYMBOL(__per_cpu_offset);
6696 +void __init setup_per_cpu_areas(void)
6698 + unsigned long size, i;
6701 + /* Copy section for each CPU (we discard the original) */
6702 + size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
6703 + ptr = alloc_bootmem_pages(size * num_possible_cpus());
6705 + for_each_possible_cpu(i) {
6706 + __per_cpu_offset[i] = (unsigned long)ptr;
6707 + memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
6711 diff -urNp linux-2.6.24.4/arch/x86/kernel/setup64.c linux-2.6.24.4/arch/x86/kernel/setup64.c
6712 --- linux-2.6.24.4/arch/x86/kernel/setup64.c 2008-03-24 14:49:18.000000000 -0400
6713 +++ linux-2.6.24.4/arch/x86/kernel/setup64.c 2008-03-26 20:21:08.000000000 -0400
6714 @@ -32,12 +32,12 @@ struct x8664_pda *_cpu_pda[NR_CPUS] __re
6715 EXPORT_SYMBOL(_cpu_pda);
6716 struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
6718 -struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
6719 +const struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
6721 char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
6723 unsigned long __supported_pte_mask __read_mostly = ~0UL;
6724 -static int do_not_nx __cpuinitdata = 0;
6725 +EXPORT_SYMBOL(__supported_pte_mask);
6728 Control non executable mappings for 64bit processes.
6729 @@ -51,16 +51,14 @@ static int __init nonx_setup(char *str)
6731 if (!strncmp(str, "on", 2)) {
6732 __supported_pte_mask |= _PAGE_NX;
6734 } else if (!strncmp(str, "off", 3)) {
6736 __supported_pte_mask &= ~_PAGE_NX;
6740 early_param("noexec", nonx_setup);
6742 -int force_personality32 = 0;
6743 +int force_personality32;
6746 Control non executable heap for 32bit processes.
6747 @@ -177,7 +175,7 @@ void __cpuinit check_efer(void)
6750 rdmsrl(MSR_EFER, efer);
6751 - if (!(efer & EFER_NX) || do_not_nx) {
6752 + if (!(efer & EFER_NX)) {
6753 __supported_pte_mask &= ~_PAGE_NX;
6756 @@ -200,12 +198,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
6757 void __cpuinit cpu_init (void)
6759 int cpu = stack_smp_processor_id();
6760 - struct tss_struct *t = &per_cpu(init_tss, cpu);
6761 + struct tss_struct *t = init_tss + cpu;
6762 struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
6764 char *estacks = NULL;
6765 struct task_struct *me;
6767 + struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)cpu_gdt_table[cpu]};
6769 /* CPU 0 is initialised in head64.c */
6771 @@ -223,14 +222,12 @@ void __cpuinit cpu_init (void)
6772 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
6775 - * Initialize the per-CPU GDT with the boot GDT,
6776 - * and set up the GDT descriptor:
6777 + * Initialize the per-CPU GDT with the boot GDT:
6780 memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
6782 - cpu_gdt_descr[cpu].size = GDT_SIZE;
6783 - load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
6784 + load_gdt(&cpu_gdt_descr);
6785 load_idt((const struct desc_ptr *)&idt_descr);
6787 memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
6788 diff -urNp linux-2.6.24.4/arch/x86/kernel/signal_32.c linux-2.6.24.4/arch/x86/kernel/signal_32.c
6789 --- linux-2.6.24.4/arch/x86/kernel/signal_32.c 2008-03-24 14:49:18.000000000 -0400
6790 +++ linux-2.6.24.4/arch/x86/kernel/signal_32.c 2008-03-26 20:21:08.000000000 -0400
6791 @@ -355,9 +355,9 @@ static int setup_frame(int sig, struct k
6794 if (current->binfmt->hasvdso)
6795 - restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
6796 + restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
6798 - restorer = (void *)&frame->retcode;
6799 + restorer = (void __user *)&frame->retcode;
6800 if (ka->sa.sa_flags & SA_RESTORER)
6801 restorer = ka->sa.sa_restorer;
6803 @@ -452,7 +452,7 @@ static int setup_rt_frame(int sig, struc
6806 /* Set up to return from userspace. */
6807 - restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
6808 + restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
6809 if (ka->sa.sa_flags & SA_RESTORER)
6810 restorer = ka->sa.sa_restorer;
6811 err |= __put_user(restorer, &frame->pretcode);
6812 @@ -584,7 +584,7 @@ static void fastcall do_signal(struct pt
6813 * before reaching here, so testing against kernel
6816 - if (!user_mode(regs))
6817 + if (!user_mode_novm(regs))
6820 if (test_thread_flag(TIF_RESTORE_SIGMASK))
6821 diff -urNp linux-2.6.24.4/arch/x86/kernel/signal_64.c linux-2.6.24.4/arch/x86/kernel/signal_64.c
6822 --- linux-2.6.24.4/arch/x86/kernel/signal_64.c 2008-03-24 14:49:18.000000000 -0400
6823 +++ linux-2.6.24.4/arch/x86/kernel/signal_64.c 2008-03-26 20:21:08.000000000 -0400
6824 @@ -252,8 +252,8 @@ static int setup_rt_frame(int sig, struc
6825 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
6826 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
6827 if (sizeof(*set) == 16) {
6828 - __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6829 - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6830 + err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6831 + err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6833 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
6835 diff -urNp linux-2.6.24.4/arch/x86/kernel/smp_32.c linux-2.6.24.4/arch/x86/kernel/smp_32.c
6836 --- linux-2.6.24.4/arch/x86/kernel/smp_32.c 2008-03-24 14:49:18.000000000 -0400
6837 +++ linux-2.6.24.4/arch/x86/kernel/smp_32.c 2008-03-26 20:21:08.000000000 -0400
6839 * about nothing of note with C stepping upwards.
6842 -DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
6843 +DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
6846 * the following functions deal with sending IPIs between CPUs.
6847 diff -urNp linux-2.6.24.4/arch/x86/kernel/smpboot_32.c linux-2.6.24.4/arch/x86/kernel/smpboot_32.c
6848 --- linux-2.6.24.4/arch/x86/kernel/smpboot_32.c 2008-03-24 14:49:18.000000000 -0400
6849 +++ linux-2.6.24.4/arch/x86/kernel/smpboot_32.c 2008-03-26 20:21:08.000000000 -0400
6850 @@ -781,6 +781,10 @@ static int __cpuinit do_boot_cpu(int api
6851 unsigned long start_eip;
6852 unsigned short nmi_high = 0, nmi_low = 0;
6854 +#ifdef CONFIG_PAX_KERNEXEC
6855 + unsigned long cr0;
6859 * Save current MTRR state in case it was changed since early boot
6860 * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
6861 @@ -797,7 +801,16 @@ static int __cpuinit do_boot_cpu(int api
6864 per_cpu(current_task, cpu) = idle;
6865 - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
6867 +#ifdef CONFIG_PAX_KERNEXEC
6868 + pax_open_kernel(cr0);
6871 + early_gdt_descr.address = get_cpu_gdt_table(cpu);
6873 +#ifdef CONFIG_PAX_KERNEXEC
6874 + pax_close_kernel(cr0);
6877 idle->thread.eip = (unsigned long) start_secondary;
6878 /* start_eip had better be page-aligned! */
6879 @@ -1122,7 +1135,7 @@ static void __init smp_boot_cpus(unsigne
6880 * construct cpu_sibling_map, so that we can tell sibling CPUs
6883 - for (cpu = 0; cpu < NR_CPUS; cpu++) {
6884 + for_each_possible_cpu(cpu) {
6885 cpus_clear(per_cpu(cpu_sibling_map, cpu));
6886 cpus_clear(per_cpu(cpu_core_map, cpu));
6888 diff -urNp linux-2.6.24.4/arch/x86/kernel/smpboot_64.c linux-2.6.24.4/arch/x86/kernel/smpboot_64.c
6889 --- linux-2.6.24.4/arch/x86/kernel/smpboot_64.c 2008-03-24 14:49:18.000000000 -0400
6890 +++ linux-2.6.24.4/arch/x86/kernel/smpboot_64.c 2008-03-26 20:21:08.000000000 -0400
6891 @@ -549,13 +549,6 @@ static int __cpuinit do_boot_cpu(int cpu
6892 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
6895 - /* allocate memory for gdts of secondary cpus. Hotplug is considered */
6896 - if (!cpu_gdt_descr[cpu].address &&
6897 - !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
6898 - printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu);
6902 /* Allocate node local memory for AP pdas */
6903 if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) {
6904 struct x8664_pda *newpda, *pda;
6905 @@ -614,7 +607,7 @@ do_rest:
6906 start_rip = setup_trampoline();
6908 init_rsp = c_idle.idle->thread.rsp;
6909 - per_cpu(init_tss,cpu).rsp0 = init_rsp;
6910 + init_tss[cpu].rsp0 = init_rsp;
6911 initial_code = start_secondary;
6912 clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
6914 diff -urNp linux-2.6.24.4/arch/x86/kernel/smpcommon_32.c linux-2.6.24.4/arch/x86/kernel/smpcommon_32.c
6915 --- linux-2.6.24.4/arch/x86/kernel/smpcommon_32.c 2008-03-24 14:49:18.000000000 -0400
6916 +++ linux-2.6.24.4/arch/x86/kernel/smpcommon_32.c 2008-03-26 20:21:16.000000000 -0400
6919 #include <linux/module.h>
6920 #include <asm/smp.h>
6921 +#include <asm/sections.h>
6923 -DEFINE_PER_CPU(unsigned long, this_cpu_off);
6924 +DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
6925 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6927 /* Initialize the CPU's GDT. This is either the boot CPU doing itself
6928 @@ -14,10 +15,29 @@ __cpuinit void init_gdt(int cpu)
6930 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
6932 - pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a,
6933 - (u32 *)&gdt[GDT_ENTRY_PERCPU].b,
6934 - __per_cpu_offset[cpu], 0xFFFFF,
6935 - 0x80 | DESCTYPE_S | 0x2, 0x8);
6936 +#ifdef CONFIG_PAX_KERNEXEC
6937 + unsigned long cr0;
6939 + pax_open_kernel(cr0);
6943 + memcpy(gdt, cpu_gdt_table, GDT_SIZE);
6945 + if (PERCPU_ENOUGH_ROOM <= 64*1024*1024)
6946 + pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
6947 + (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
6948 + __per_cpu_offset[cpu], PERCPU_ENOUGH_ROOM-1,
6949 + 0x80 | DESCTYPE_S | 0x3, 0x4);
6951 + pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
6952 + (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
6953 + __per_cpu_offset[cpu], ((PERCPU_ENOUGH_ROOM-1) >> PAGE_SHIFT),
6954 + 0x80 | DESCTYPE_S | 0x3, 0xC);
6956 +#ifdef CONFIG_PAX_KERNEXEC
6957 + pax_close_kernel(cr0);
6960 per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
6961 per_cpu(cpu_number, cpu) = cpu;
6962 diff -urNp linux-2.6.24.4/arch/x86/kernel/suspend_64.c linux-2.6.24.4/arch/x86/kernel/suspend_64.c
6963 --- linux-2.6.24.4/arch/x86/kernel/suspend_64.c 2008-03-24 14:49:18.000000000 -0400
6964 +++ linux-2.6.24.4/arch/x86/kernel/suspend_64.c 2008-03-26 20:21:08.000000000 -0400
6965 @@ -116,12 +116,22 @@ void restore_processor_state(void)
6966 void fix_processor_context(void)
6968 int cpu = smp_processor_id();
6969 - struct tss_struct *t = &per_cpu(init_tss, cpu);
6970 + struct tss_struct *t = init_tss + cpu;
6972 +#ifdef CONFIG_PAX_KERNEXEC
6973 + unsigned long cr0;
6975 + pax_open_kernel(cr0);
6978 set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
6980 cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9;
6982 +#ifdef CONFIG_PAX_KERNEXEC
6983 + pax_close_kernel(cr0);
6986 syscall_init(); /* This sets MSR_*STAR and related */
6987 load_TR_desc(); /* This does ltr */
6988 load_LDT(¤t->active_mm->context); /* This does lldt */
6989 diff -urNp linux-2.6.24.4/arch/x86/kernel/syscall_table_32.S linux-2.6.24.4/arch/x86/kernel/syscall_table_32.S
6990 --- linux-2.6.24.4/arch/x86/kernel/syscall_table_32.S 2008-03-24 14:49:18.000000000 -0400
6991 +++ linux-2.6.24.4/arch/x86/kernel/syscall_table_32.S 2008-03-26 20:21:08.000000000 -0400
6993 +.section .rodata,"a",@progbits
6994 ENTRY(sys_call_table)
6995 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
6997 diff -urNp linux-2.6.24.4/arch/x86/kernel/sysenter_32.c linux-2.6.24.4/arch/x86/kernel/sysenter_32.c
6998 --- linux-2.6.24.4/arch/x86/kernel/sysenter_32.c 2008-03-24 14:49:18.000000000 -0400
6999 +++ linux-2.6.24.4/arch/x86/kernel/sysenter_32.c 2008-03-26 20:21:08.000000000 -0400
7000 @@ -175,7 +175,7 @@ static __init void relocate_vdso(Elf32_E
7001 void enable_sep_cpu(void)
7003 int cpu = get_cpu();
7004 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
7005 + struct tss_struct *tss = init_tss + cpu;
7007 if (!boot_cpu_has(X86_FEATURE_SEP)) {
7009 @@ -198,7 +198,7 @@ static int __init gate_vma_init(void)
7010 gate_vma.vm_start = FIXADDR_USER_START;
7011 gate_vma.vm_end = FIXADDR_USER_END;
7012 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
7013 - gate_vma.vm_page_prot = __P101;
7014 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
7016 * Make sure the vDSO gets into every core dump.
7017 * Dumping its contents makes post-mortem fully interpretable later
7018 @@ -281,7 +281,7 @@ int arch_setup_additional_pages(struct l
7020 addr = VDSO_HIGH_BASE;
7022 - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
7023 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
7024 if (IS_ERR_VALUE(addr)) {
7027 @@ -306,7 +306,7 @@ int arch_setup_additional_pages(struct l
7031 - current->mm->context.vdso = (void *)addr;
7032 + current->mm->context.vdso = addr;
7033 current_thread_info()->sysenter_return =
7034 (void *)VDSO_SYM(&SYSENTER_RETURN);
7036 @@ -318,8 +318,14 @@ int arch_setup_additional_pages(struct l
7038 const char *arch_vma_name(struct vm_area_struct *vma)
7040 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
7041 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
7044 +#ifdef CONFIG_PAX_SEGMEXEC
7045 + if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
7052 @@ -328,7 +334,7 @@ struct vm_area_struct *get_gate_vma(stru
7053 struct mm_struct *mm = tsk->mm;
7055 /* Check to see if this task was created in compat vdso mode */
7056 - if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
7057 + if (mm && mm->context.vdso == VDSO_HIGH_BASE)
7061 diff -urNp linux-2.6.24.4/arch/x86/kernel/sys_i386_32.c linux-2.6.24.4/arch/x86/kernel/sys_i386_32.c
7062 --- linux-2.6.24.4/arch/x86/kernel/sys_i386_32.c 2008-03-24 14:49:18.000000000 -0400
7063 +++ linux-2.6.24.4/arch/x86/kernel/sys_i386_32.c 2008-03-26 20:21:08.000000000 -0400
7064 @@ -39,6 +39,21 @@ asmlinkage int sys_pipe(unsigned long __
7068 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
7070 + unsigned long pax_task_size = TASK_SIZE;
7072 +#ifdef CONFIG_PAX_SEGMEXEC
7073 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
7074 + pax_task_size = SEGMEXEC_TASK_SIZE;
7077 + if (len > pax_task_size || addr > pax_task_size - len)
7083 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
7084 unsigned long prot, unsigned long flags,
7085 unsigned long fd, unsigned long pgoff)
7086 @@ -98,6 +113,205 @@ out:
7091 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
7092 + unsigned long len, unsigned long pgoff, unsigned long flags)
7094 + struct mm_struct *mm = current->mm;
7095 + struct vm_area_struct *vma;
7096 + unsigned long start_addr, pax_task_size = TASK_SIZE;
7098 +#ifdef CONFIG_PAX_SEGMEXEC
7099 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
7100 + pax_task_size = SEGMEXEC_TASK_SIZE;
7103 + if (len > pax_task_size)
7106 + if (flags & MAP_FIXED)
7109 +#ifdef CONFIG_PAX_RANDMMAP
7110 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7114 + addr = PAGE_ALIGN(addr);
7115 + vma = find_vma(mm, addr);
7116 + if (pax_task_size - len >= addr &&
7117 + (!vma || addr + len <= vma->vm_start))
7120 + if (len > mm->cached_hole_size) {
7121 + start_addr = addr = mm->free_area_cache;
7123 + start_addr = addr = mm->mmap_base;
7124 + mm->cached_hole_size = 0;
7127 +#ifdef CONFIG_PAX_PAGEEXEC
7128 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
7129 + start_addr = 0x00110000UL;
7131 +#ifdef CONFIG_PAX_RANDMMAP
7132 + if (mm->pax_flags & MF_PAX_RANDMMAP)
7133 + start_addr += mm->delta_mmap & 0x03FFF000UL;
7136 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
7137 + start_addr = addr = mm->mmap_base;
7139 + addr = start_addr;
7144 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
7145 + /* At this point: (!vma || addr < vma->vm_end). */
7146 + if (pax_task_size - len < addr) {
7148 + * Start a new search - just in case we missed
7151 + if (start_addr != mm->mmap_base) {
7152 + start_addr = addr = mm->mmap_base;
7153 + mm->cached_hole_size = 0;
7158 + if (!vma || addr + len <= vma->vm_start) {
7160 + * Remember the place where we stopped the search:
7162 + mm->free_area_cache = addr + len;
7165 + if (addr + mm->cached_hole_size < vma->vm_start)
7166 + mm->cached_hole_size = vma->vm_start - addr;
7167 + addr = vma->vm_end;
7168 + if (mm->start_brk <= addr && addr < mm->mmap_base) {
7169 + start_addr = addr = mm->mmap_base;
7170 + mm->cached_hole_size = 0;
7177 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
7178 + const unsigned long len, const unsigned long pgoff,
7179 + const unsigned long flags)
7181 + struct vm_area_struct *vma;
7182 + struct mm_struct *mm = current->mm;
7183 + unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
7185 +#ifdef CONFIG_PAX_SEGMEXEC
7186 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
7187 + pax_task_size = SEGMEXEC_TASK_SIZE;
7190 + /* requested length too big for entire address space */
7191 + if (len > pax_task_size)
7194 + if (flags & MAP_FIXED)
7197 +#ifdef CONFIG_PAX_PAGEEXEC
7198 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
7202 +#ifdef CONFIG_PAX_RANDMMAP
7203 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7206 + /* requesting a specific address */
7208 + addr = PAGE_ALIGN(addr);
7209 + vma = find_vma(mm, addr);
7210 + if (pax_task_size - len >= addr &&
7211 + (!vma || addr + len <= vma->vm_start))
7215 + /* check if free_area_cache is useful for us */
7216 + if (len <= mm->cached_hole_size) {
7217 + mm->cached_hole_size = 0;
7218 + mm->free_area_cache = mm->mmap_base;
7221 + /* either no address requested or can't fit in requested address hole */
7222 + addr = mm->free_area_cache;
7224 + /* make sure it can fit in the remaining address space */
7226 + vma = find_vma(mm, addr-len);
7227 + if (!vma || addr <= vma->vm_start)
7228 + /* remember the address as a hint for next time */
7229 + return (mm->free_area_cache = addr-len);
7232 + if (mm->mmap_base < len)
7235 + addr = mm->mmap_base-len;
7239 + * Lookup failure means no vma is above this address,
7240 + * else if new region fits below vma->vm_start,
7241 + * return with success:
7243 + vma = find_vma(mm, addr);
7244 + if (!vma || addr+len <= vma->vm_start)
7245 + /* remember the address as a hint for next time */
7246 + return (mm->free_area_cache = addr);
7248 + /* remember the largest hole we saw so far */
7249 + if (addr + mm->cached_hole_size < vma->vm_start)
7250 + mm->cached_hole_size = vma->vm_start - addr;
7252 + /* try just below the current vma->vm_start */
7253 + addr = vma->vm_start-len;
7254 + } while (len < vma->vm_start);
7258 + * A failed mmap() very likely causes application failure,
7259 + * so fall back to the bottom-up function here. This scenario
7260 + * can happen with large stack limits and large mmap()
7264 +#ifdef CONFIG_PAX_SEGMEXEC
7265 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
7266 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
7270 + mm->mmap_base = TASK_UNMAPPED_BASE;
7272 +#ifdef CONFIG_PAX_RANDMMAP
7273 + if (mm->pax_flags & MF_PAX_RANDMMAP)
7274 + mm->mmap_base += mm->delta_mmap;
7277 + mm->free_area_cache = mm->mmap_base;
7278 + mm->cached_hole_size = ~0UL;
7279 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
7281 + * Restore the topdown base:
7283 + mm->mmap_base = base;
7284 + mm->free_area_cache = base;
7285 + mm->cached_hole_size = ~0UL;
7290 struct sel_arg_struct {
7292 diff -urNp linux-2.6.24.4/arch/x86/kernel/sys_x86_64.c linux-2.6.24.4/arch/x86/kernel/sys_x86_64.c
7293 --- linux-2.6.24.4/arch/x86/kernel/sys_x86_64.c 2008-03-24 14:49:18.000000000 -0400
7294 +++ linux-2.6.24.4/arch/x86/kernel/sys_x86_64.c 2008-03-26 20:21:08.000000000 -0400
7295 @@ -61,8 +61,8 @@ out:
7299 -static void find_start_end(unsigned long flags, unsigned long *begin,
7300 - unsigned long *end)
7301 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
7302 + unsigned long *begin, unsigned long *end)
7304 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
7305 /* This is usually used needed to map code in small
7306 @@ -75,7 +75,7 @@ static void find_start_end(unsigned long
7307 *begin = 0x40000000;
7310 - *begin = TASK_UNMAPPED_BASE;
7311 + *begin = mm->mmap_base;
7315 @@ -92,11 +92,15 @@ arch_get_unmapped_area(struct file *filp
7316 if (flags & MAP_FIXED)
7319 - find_start_end(flags, &begin, &end);
7320 + find_start_end(mm, flags, &begin, &end);
7325 +#ifdef CONFIG_PAX_RANDMMAP
7326 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7330 addr = PAGE_ALIGN(addr);
7331 vma = find_vma(mm, addr);
7332 diff -urNp linux-2.6.24.4/arch/x86/kernel/time_32.c linux-2.6.24.4/arch/x86/kernel/time_32.c
7333 --- linux-2.6.24.4/arch/x86/kernel/time_32.c 2008-03-24 14:49:18.000000000 -0400
7334 +++ linux-2.6.24.4/arch/x86/kernel/time_32.c 2008-03-26 20:21:08.000000000 -0400
7335 @@ -130,20 +130,30 @@ unsigned long profile_pc(struct pt_regs
7336 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) &&
7337 in_lock_functions(pc)) {
7338 #ifdef CONFIG_FRAME_POINTER
7339 - return *(unsigned long *)(regs->ebp + 4);
7340 + return ktla_ktva(*(unsigned long *)(regs->ebp + 4));
7342 unsigned long *sp = (unsigned long *)®s->esp;
7344 /* Return address is either directly at stack pointer
7345 or above a saved eflags. Eflags has bits 22-31 zero,
7346 kernel addresses don't. */
7348 +#ifdef CONFIG_PAX_KERNEXEC
7349 + return ktla_ktva(sp[0]);
7361 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs))
7362 + pc = ktla_ktva(pc);
7366 EXPORT_SYMBOL(profile_pc);
7367 diff -urNp linux-2.6.24.4/arch/x86/kernel/traps_32.c linux-2.6.24.4/arch/x86/kernel/traps_32.c
7368 --- linux-2.6.24.4/arch/x86/kernel/traps_32.c 2008-03-24 14:49:18.000000000 -0400
7369 +++ linux-2.6.24.4/arch/x86/kernel/traps_32.c 2008-03-26 20:21:08.000000000 -0400
7371 #include <linux/uaccess.h>
7372 #include <linux/nmi.h>
7373 #include <linux/bug.h>
7374 +#include <linux/binfmts.h>
7377 #include <linux/ioport.h>
7378 @@ -71,12 +72,7 @@ asmlinkage int system_call(void);
7379 /* Do we ignore FPU interrupts ? */
7380 char ignore_fpu_irq = 0;
7383 - * The IDT has to be page-aligned to simplify the Pentium
7384 - * F0 0F bug workaround.. We have a special link segment
7387 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
7388 +extern struct desc_struct idt_table[256];
7390 asmlinkage void divide_error(void);
7391 asmlinkage void debug(void);
7392 @@ -306,22 +302,23 @@ void show_registers(struct pt_regs *regs
7393 * When in-kernel, we also print out the stack and code at the
7394 * time of the fault..
7396 - if (!user_mode_vm(regs)) {
7397 + if (!user_mode(regs)) {
7399 unsigned int code_prologue = code_bytes * 43 / 64;
7400 unsigned int code_len = code_bytes;
7402 + unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->xcs) >> 3]);
7404 printk("\n" KERN_EMERG "Stack: ");
7405 show_stack_log_lvl(NULL, regs, ®s->esp, KERN_EMERG);
7407 printk(KERN_EMERG "Code: ");
7409 - eip = (u8 *)regs->eip - code_prologue;
7410 + eip = (u8 *)regs->eip - code_prologue + cs_base;
7411 if (eip < (u8 *)PAGE_OFFSET ||
7412 probe_kernel_address(eip, c)) {
7413 /* try starting at EIP */
7414 - eip = (u8 *)regs->eip;
7415 + eip = (u8 *)regs->eip + cs_base;
7416 code_len = code_len - code_prologue + 1;
7418 for (i = 0; i < code_len; i++, eip++) {
7419 @@ -330,7 +327,7 @@ void show_registers(struct pt_regs *regs
7420 printk(" Bad EIP value.");
7423 - if (eip == (u8 *)regs->eip)
7424 + if (eip == (u8 *)regs->eip + cs_base)
7425 printk("<%02x> ", c);
7428 @@ -343,6 +340,7 @@ int is_valid_bugaddr(unsigned long eip)
7432 + eip = ktla_ktva(eip);
7433 if (eip < PAGE_OFFSET)
7435 if (probe_kernel_address((unsigned short *)eip, ud2))
7436 @@ -444,7 +442,7 @@ void die(const char * str, struct pt_reg
7438 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
7440 - if (!user_mode_vm(regs))
7441 + if (!user_mode(regs))
7442 die(str, regs, err);
7445 @@ -460,7 +458,7 @@ static void __kprobes do_trap(int trapnr
7449 - if (!user_mode(regs))
7450 + if (!user_mode_novm(regs))
7454 @@ -566,7 +564,7 @@ fastcall void __kprobes do_general_prote
7457 int cpu = get_cpu();
7458 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
7459 + struct tss_struct *tss = &init_tss[cpu];
7460 struct thread_struct *thread = ¤t->thread;
7463 @@ -599,9 +597,25 @@ fastcall void __kprobes do_general_prote
7464 if (regs->eflags & VM_MASK)
7467 - if (!user_mode(regs))
7468 + if (!user_mode_novm(regs))
7471 +#ifdef CONFIG_PAX_PAGEEXEC
7472 + if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
7473 + struct mm_struct *mm = current->mm;
7474 + unsigned long limit;
7476 + down_write(&mm->mmap_sem);
7477 + limit = mm->context.user_cs_limit;
7478 + if (limit < TASK_SIZE) {
7479 + track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
7480 + up_write(&mm->mmap_sem);
7483 + up_write(&mm->mmap_sem);
7487 current->thread.error_code = error_code;
7488 current->thread.trap_no = 13;
7489 if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
7490 @@ -626,6 +640,13 @@ gp_in_kernel:
7491 if (notify_die(DIE_GPF, "general protection fault", regs,
7492 error_code, 13, SIGSEGV) == NOTIFY_STOP)
7495 +#ifdef CONFIG_PAX_KERNEXEC
7496 + if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
7497 + die("PAX: suspicious general protection fault", regs, error_code);
7501 die("general protection fault", regs, error_code);
7504 @@ -715,7 +736,7 @@ void __kprobes die_nmi(struct pt_regs *r
7505 /* If we are in kernel we are probably nested up pretty bad
7506 * and might aswell get out now while we still can.
7508 - if (!user_mode_vm(regs)) {
7509 + if (!user_mode(regs)) {
7510 current->thread.trap_no = 2;
7513 @@ -866,7 +887,7 @@ fastcall void __kprobes do_debug(struct
7514 * check for kernel mode by just checking the CPL
7517 - if (!user_mode(regs))
7518 + if (!user_mode_novm(regs))
7519 goto clear_TF_reenable;
7522 @@ -1044,18 +1065,14 @@ fastcall void do_spurious_interrupt_bug(
7523 fastcall unsigned long patch_espfix_desc(unsigned long uesp,
7526 - struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
7527 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
7528 unsigned long new_kesp = kesp - base;
7529 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
7530 - __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
7533 /* Set up base for espfix segment */
7534 - desc &= 0x00f0ff0000000000ULL;
7535 - desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
7536 - ((((__u64)base) << 32) & 0xff00000000000000ULL) |
7537 - ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
7538 - (lim_pages & 0xffff);
7539 - *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
7540 + pack_descriptor(&a, &b, base, lim_pages, 0x93, 0xC);
7541 + write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, a, b);
7545 diff -urNp linux-2.6.24.4/arch/x86/kernel/tsc_32.c linux-2.6.24.4/arch/x86/kernel/tsc_32.c
7546 --- linux-2.6.24.4/arch/x86/kernel/tsc_32.c 2008-03-24 14:49:18.000000000 -0400
7547 +++ linux-2.6.24.4/arch/x86/kernel/tsc_32.c 2008-03-26 20:21:08.000000000 -0400
7548 @@ -322,7 +322,7 @@ static struct dmi_system_id __initdata b
7549 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
7553 + { NULL, NULL, {{0, NULL}}, NULL}
7557 diff -urNp linux-2.6.24.4/arch/x86/kernel/vm86_32.c linux-2.6.24.4/arch/x86/kernel/vm86_32.c
7558 --- linux-2.6.24.4/arch/x86/kernel/vm86_32.c 2008-03-24 14:49:18.000000000 -0400
7559 +++ linux-2.6.24.4/arch/x86/kernel/vm86_32.c 2008-03-26 20:21:08.000000000 -0400
7560 @@ -146,7 +146,7 @@ struct pt_regs * fastcall save_v86_state
7564 - tss = &per_cpu(init_tss, get_cpu());
7565 + tss = init_tss + get_cpu();
7566 current->thread.esp0 = current->thread.saved_esp0;
7567 current->thread.sysenter_cs = __KERNEL_CS;
7568 load_esp0(tss, ¤t->thread);
7569 @@ -322,7 +322,7 @@ static void do_sys_vm86(struct kernel_vm
7570 tsk->thread.saved_fs = info->regs32->xfs;
7571 savesegment(gs, tsk->thread.saved_gs);
7573 - tss = &per_cpu(init_tss, get_cpu());
7574 + tss = init_tss + get_cpu();
7575 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
7577 tsk->thread.sysenter_cs = 0;
7578 diff -urNp linux-2.6.24.4/arch/x86/kernel/vmi_32.c linux-2.6.24.4/arch/x86/kernel/vmi_32.c
7579 --- linux-2.6.24.4/arch/x86/kernel/vmi_32.c 2008-03-24 14:49:18.000000000 -0400
7580 +++ linux-2.6.24.4/arch/x86/kernel/vmi_32.c 2008-03-26 20:21:08.000000000 -0400
7581 @@ -98,18 +98,43 @@ static unsigned patch_internal(int call,
7584 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
7586 +#ifdef CONFIG_PAX_KERNEXEC
7587 + unsigned long cr0;
7590 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
7592 case VMI_RELOCATION_CALL_REL:
7595 +#ifdef CONFIG_PAX_KERNEXEC
7596 + pax_open_kernel(cr0);
7599 *(char *)insnbuf = MNEM_CALL;
7600 patch_offset(insnbuf, eip, (unsigned long)rel->eip);
7602 +#ifdef CONFIG_PAX_KERNEXEC
7603 + pax_close_kernel(cr0);
7608 case VMI_RELOCATION_JUMP_REL:
7611 +#ifdef CONFIG_PAX_KERNEXEC
7612 + pax_open_kernel(cr0);
7615 *(char *)insnbuf = MNEM_JMP;
7616 patch_offset(insnbuf, eip, (unsigned long)rel->eip);
7618 +#ifdef CONFIG_PAX_KERNEXEC
7619 + pax_close_kernel(cr0);
7624 case VMI_RELOCATION_NOP:
7625 @@ -492,14 +517,14 @@ static void vmi_set_pud(pud_t *pudp, pud
7627 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
7629 - const pte_t pte = { 0 };
7630 + const pte_t pte = __pte(0ULL);
7631 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
7632 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
7635 static void vmi_pmd_clear(pmd_t *pmd)
7637 - const pte_t pte = { 0 };
7638 + const pte_t pte = __pte(0ULL);
7639 vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
7640 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
7642 @@ -528,8 +553,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
7643 ap.ss = __KERNEL_DS;
7644 ap.esp = (unsigned long) start_esp;
7646 - ap.ds = __USER_DS;
7647 - ap.es = __USER_DS;
7648 + ap.ds = __KERNEL_DS;
7649 + ap.es = __KERNEL_DS;
7650 ap.fs = __KERNEL_PERCPU;
7653 @@ -724,12 +749,20 @@ static inline int __init activate_vmi(vo
7655 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
7657 +#ifdef CONFIG_PAX_KERNEXEC
7658 + unsigned long cr0;
7661 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
7662 printk(KERN_ERR "VMI ROM failed to initialize!");
7665 savesegment(cs, kernel_cs);
7667 +#ifdef CONFIG_PAX_KERNEXEC
7668 + pax_open_kernel(cr0);
7671 pv_info.paravirt_enabled = 1;
7672 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
7673 pv_info.name = "vmi";
7674 @@ -917,6 +950,10 @@ static inline int __init activate_vmi(vo
7676 para_fill(pv_irq_ops.safe_halt, Halt);
7678 +#ifdef CONFIG_PAX_KERNEXEC
7679 + pax_close_kernel(cr0);
7683 * Alternative instruction rewriting doesn't happen soon enough
7684 * to convert VMI_IRET to a call instead of a jump; so we have
7685 diff -urNp linux-2.6.24.4/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.24.4/arch/x86/kernel/vmlinux_32.lds.S
7686 --- linux-2.6.24.4/arch/x86/kernel/vmlinux_32.lds.S 2008-03-24 14:49:18.000000000 -0400
7687 +++ linux-2.6.24.4/arch/x86/kernel/vmlinux_32.lds.S 2008-03-26 20:21:08.000000000 -0400
7689 #include <asm/page.h>
7690 #include <asm/cache.h>
7691 #include <asm/boot.h>
7692 +#include <asm/segment.h>
7694 +#ifdef CONFIG_X86_PAE
7695 +#define PMD_SHIFT 21
7697 +#define PMD_SHIFT 22
7699 +#define PMD_SIZE (1 << PMD_SHIFT)
7701 +#ifdef CONFIG_PAX_KERNEXEC
7702 +#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
7704 +#define __KERNEL_TEXT_OFFSET 0
7707 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
7709 @@ -28,22 +42,125 @@ ENTRY(phys_startup_32)
7710 jiffies = jiffies_64;
7713 - text PT_LOAD FLAGS(5); /* R_E */
7714 - data PT_LOAD FLAGS(7); /* RWE */
7715 - note PT_NOTE FLAGS(0); /* ___ */
7716 + initdata PT_LOAD FLAGS(6); /* RW_ */
7717 + percpu PT_LOAD FLAGS(6); /* RW_ */
7718 + inittext PT_LOAD FLAGS(5); /* R_E */
7719 + text PT_LOAD FLAGS(5); /* R_E */
7720 + rodata PT_LOAD FLAGS(4); /* R__ */
7721 + data PT_LOAD FLAGS(6); /* RW_ */
7722 + note PT_NOTE FLAGS(0); /* ___ */
7726 - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
7727 - phys_startup_32 = startup_32 - LOAD_OFFSET;
7728 + . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
7730 + .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
7731 + __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
7732 + phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
7736 + /* might get freed after init */
7738 + .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7741 + __smp_locks_end = .;
7743 + /* will be freed after init
7744 + * Following ALIGN() is required to make sure no other data falls on the
7745 + * same page where __smp_alt_end is pointing as that page might be freed
7746 + * after boot. Always make sure that ALIGN() directive is present after
7747 + * the section which contains __smp_alt_end.
7751 + /* will be freed after init */
7752 + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
7757 + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
7758 + __setup_start = .;
7762 + .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
7763 + __initcall_start = .;
7765 + __initcall_end = .;
7767 + .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
7768 + __con_initcall_start = .;
7769 + *(.con_initcall.init)
7770 + __con_initcall_end = .;
7774 + .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
7775 + __alt_instructions = .;
7776 + *(.altinstructions)
7777 + __alt_instructions_end = .;
7779 + .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
7780 + *(.altinstr_replacement)
7783 + .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
7784 + __parainstructions = .;
7785 + *(.parainstructions)
7786 + __parainstructions_end = .;
7788 + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
7789 +#if defined(CONFIG_BLK_DEV_INITRD)
7791 + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
7792 + __initramfs_start = .;
7794 + __initramfs_end = .;
7798 + per_cpu_start = .;
7799 + .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
7800 + __per_cpu_start = . + per_cpu_start;
7803 + *(.data.percpu.shared_aligned)
7804 + __per_cpu_end = . + per_cpu_start;
7806 + . += per_cpu_start;
7810 + . = ALIGN(4096); /* Init code and data */
7811 + .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7817 + /* .exit.text is discard at runtime, not link time, to deal with references
7818 + from .altinstructions and .eh_frame */
7819 + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
7821 - .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
7822 - _text = .; /* Text and read-only data */
7823 + .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7825 + . = ALIGN(2*PMD_SIZE) - 1;
7828 + /* freed after init ends here */
7830 + .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7831 + __init_end = . + __KERNEL_TEXT_OFFSET;
7832 + KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
7833 + _text = .; /* Text and read-only data */
7838 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
7839 + .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7843 @@ -53,16 +170,17 @@ SECTIONS
7844 _etext = .; /* End of text section */
7847 - . = ALIGN(16); /* Exception table */
7848 + . += __KERNEL_TEXT_OFFSET;
7849 + . = ALIGN(4096); /* Exception table */
7850 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7851 __start___ex_table = .;
7853 __stop___ex_table = .;
7858 + NOTES :rodata :note
7864 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
7865 @@ -71,11 +189,38 @@ SECTIONS
7866 __tracedata_end = .;
7873 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
7876 + *(.empty_zero_page)
7877 + *(.swapper_pm_dir)
7878 + *(.swapper_pg_dir)
7881 +#ifdef CONFIG_PAX_KERNEXEC
7883 +#ifdef CONFIG_MODULES
7885 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
7886 + MODULES_VADDR = .;
7888 + . += (6 * 1024 * 1024);
7889 + . = ALIGN( PMD_SIZE) - 1;
7893 + . = ALIGN(PMD_SIZE) - 1;
7900 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7905 @@ -91,7 +236,6 @@ SECTIONS
7907 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7908 *(.data.page_aligned)
7913 @@ -111,86 +255,7 @@ SECTIONS
7917 - /* might get freed after init */
7919 - .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7922 - __smp_locks_end = .;
7924 - /* will be freed after init
7925 - * Following ALIGN() is required to make sure no other data falls on the
7926 - * same page where __smp_alt_end is pointing as that page might be freed
7927 - * after boot. Always make sure that ALIGN() directive is present after
7928 - * the section which contains __smp_alt_end.
7932 - /* will be freed after init */
7933 - . = ALIGN(4096); /* Init code and data */
7934 - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
7940 - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
7942 - .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
7943 - __setup_start = .;
7947 - .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
7948 - __initcall_start = .;
7950 - __initcall_end = .;
7952 - .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
7953 - __con_initcall_start = .;
7954 - *(.con_initcall.init)
7955 - __con_initcall_end = .;
7959 - .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
7960 - __alt_instructions = .;
7961 - *(.altinstructions)
7962 - __alt_instructions_end = .;
7964 - .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
7965 - *(.altinstr_replacement)
7968 - .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
7969 - __parainstructions = .;
7970 - *(.parainstructions)
7971 - __parainstructions_end = .;
7973 - /* .exit.text is discard at runtime, not link time, to deal with references
7974 - from .altinstructions and .eh_frame */
7975 - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
7976 - .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
7977 -#if defined(CONFIG_BLK_DEV_INITRD)
7979 - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
7980 - __initramfs_start = .;
7982 - __initramfs_end = .;
7986 - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
7987 - __per_cpu_start = .;
7989 - *(.data.percpu.shared_aligned)
7990 - __per_cpu_end = .;
7993 - /* freed after init ends here */
7995 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7997 __bss_start = .; /* BSS */
7998 *(.bss.page_aligned)
8000 diff -urNp linux-2.6.24.4/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.24.4/arch/x86/kernel/vmlinux_64.lds.S
8001 --- linux-2.6.24.4/arch/x86/kernel/vmlinux_64.lds.S 2008-03-24 14:49:18.000000000 -0400
8002 +++ linux-2.6.24.4/arch/x86/kernel/vmlinux_64.lds.S 2008-03-26 20:21:08.000000000 -0400
8003 @@ -16,8 +16,8 @@ jiffies_64 = jiffies;
8006 text PT_LOAD FLAGS(5); /* R_E */
8007 - data PT_LOAD FLAGS(7); /* RWE */
8008 - user PT_LOAD FLAGS(7); /* RWE */
8009 + data PT_LOAD FLAGS(6); /* RW_ */
8010 + user PT_LOAD FLAGS(7); /* RWX */
8011 data.init PT_LOAD FLAGS(7); /* RWE */
8012 note PT_NOTE FLAGS(4); /* R__ */
8014 @@ -52,7 +52,7 @@ SECTIONS
8022 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
8023 @@ -61,15 +61,18 @@ SECTIONS
8024 __tracedata_end = .;
8027 +#ifdef CONFIG_PAX_KERNEXEC
8028 + . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
8030 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
8034 .data : AT(ADDR(.data) - LOAD_OFFSET) {
8039 - _edata = .; /* End of data section */
8041 . = ALIGN(PAGE_SIZE);
8042 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
8043 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
8044 @@ -80,9 +83,27 @@ SECTIONS
8045 *(.data.read_mostly)
8048 + . = ALIGN(8192); /* init_task */
8049 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
8050 + *(.data.init_task)
8054 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
8055 + *(.data.page_aligned)
8059 + __nosave_begin = .;
8060 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
8064 + _edata = .; /* End of data section */
8066 #define VSYSCALL_ADDR (-10*1024*1024)
8067 -#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
8068 -#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
8069 +#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
8070 +#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
8072 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
8073 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
8074 @@ -130,23 +151,13 @@ SECTIONS
8078 - . = ALIGN(8192); /* init_task */
8079 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
8080 - *(.data.init_task)
8084 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
8085 - *(.data.page_aligned)
8088 /* might get freed after init */
8090 __smp_alt_begin = .;
8092 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
8096 __smp_locks_end = .;
8099 @@ -208,12 +219,6 @@ SECTIONS
8104 - __nosave_begin = .;
8105 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
8109 __bss_start = .; /* BSS */
8110 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
8111 *(.bss.page_aligned)
8112 @@ -221,6 +226,7 @@ SECTIONS
8116 + . = ALIGN(2*1024*1024);
8119 /* Sections to be discarded */
8120 diff -urNp linux-2.6.24.4/arch/x86/kernel/vsyscall_64.c linux-2.6.24.4/arch/x86/kernel/vsyscall_64.c
8121 --- linux-2.6.24.4/arch/x86/kernel/vsyscall_64.c 2008-03-24 14:49:18.000000000 -0400
8122 +++ linux-2.6.24.4/arch/x86/kernel/vsyscall_64.c 2008-03-26 20:21:08.000000000 -0400
8123 @@ -271,13 +271,13 @@ static ctl_table kernel_table2[] = {
8124 .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
8126 .proc_handler = vsyscall_sysctl_change },
8128 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
8131 static ctl_table kernel_root_table2[] = {
8132 { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
8133 .child = kernel_table2 },
8135 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
8139 @@ -288,6 +288,11 @@ static void __cpuinit vsyscall_set_cpu(i
8142 unsigned long node = 0;
8144 +#ifdef CONFIG_PAX_KERNEXEC
8145 + unsigned long cr0;
8149 node = cpu_to_node(cpu);
8151 @@ -298,10 +303,20 @@ static void __cpuinit vsyscall_set_cpu(i
8152 in user space in vgetcpu.
8153 12 bits for the CPU and 8 bits for the node. */
8154 d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU);
8156 +#ifdef CONFIG_PAX_KERNEXEC
8157 + pax_open_kernel(cr0);
8160 *d = 0x0f40000000000ULL;
8162 *d |= (node & 0xf) << 12;
8163 *d |= (node >> 4) << 48;
8165 +#ifdef CONFIG_PAX_KERNEXEC
8166 + pax_close_kernel(cr0);
8171 static void __cpuinit cpu_vsyscall_init(void *arg)
8172 diff -urNp linux-2.6.24.4/arch/x86/lib/checksum_32.S linux-2.6.24.4/arch/x86/lib/checksum_32.S
8173 --- linux-2.6.24.4/arch/x86/lib/checksum_32.S 2008-03-24 14:49:18.000000000 -0400
8174 +++ linux-2.6.24.4/arch/x86/lib/checksum_32.S 2008-03-26 20:21:08.000000000 -0400
8176 #include <linux/linkage.h>
8177 #include <asm/dwarf2.h>
8178 #include <asm/errno.h>
8180 +#include <asm/segment.h>
8183 * computes a partial checksum, e.g. for TCP/UDP fragments
8185 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
8190 -ENTRY(csum_partial_copy_generic)
8192 +ENTRY(csum_partial_copy_generic_to_user)
8194 + pushl $(__USER_DS)
8195 + CFI_ADJUST_CFA_OFFSET 4
8197 + CFI_ADJUST_CFA_OFFSET -4
8198 + jmp csum_partial_copy_generic
8200 +ENTRY(csum_partial_copy_generic_from_user)
8201 + pushl $(__USER_DS)
8202 + CFI_ADJUST_CFA_OFFSET 4
8204 + CFI_ADJUST_CFA_OFFSET -4
8206 +ENTRY(csum_partial_copy_generic)
8208 CFI_ADJUST_CFA_OFFSET 4
8210 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
8212 SRC(1: movw (%esi), %bx )
8214 -DST( movw %bx, (%edi) )
8215 +DST( movw %bx, %es:(%edi) )
8219 @@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
8220 SRC(1: movl (%esi), %ebx )
8221 SRC( movl 4(%esi), %edx )
8223 -DST( movl %ebx, (%edi) )
8224 +DST( movl %ebx, %es:(%edi) )
8226 -DST( movl %edx, 4(%edi) )
8227 +DST( movl %edx, %es:4(%edi) )
8229 SRC( movl 8(%esi), %ebx )
8230 SRC( movl 12(%esi), %edx )
8232 -DST( movl %ebx, 8(%edi) )
8233 +DST( movl %ebx, %es:8(%edi) )
8235 -DST( movl %edx, 12(%edi) )
8236 +DST( movl %edx, %es:12(%edi) )
8238 SRC( movl 16(%esi), %ebx )
8239 SRC( movl 20(%esi), %edx )
8241 -DST( movl %ebx, 16(%edi) )
8242 +DST( movl %ebx, %es:16(%edi) )
8244 -DST( movl %edx, 20(%edi) )
8245 +DST( movl %edx, %es:20(%edi) )
8247 SRC( movl 24(%esi), %ebx )
8248 SRC( movl 28(%esi), %edx )
8250 -DST( movl %ebx, 24(%edi) )
8251 +DST( movl %ebx, %es:24(%edi) )
8253 -DST( movl %edx, 28(%edi) )
8254 +DST( movl %edx, %es:28(%edi) )
8258 @@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
8259 shrl $2, %edx # This clears CF
8260 SRC(3: movl (%esi), %ebx )
8262 -DST( movl %ebx, (%edi) )
8263 +DST( movl %ebx, %es:(%edi) )
8267 @@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
8269 SRC( movw (%esi), %cx )
8271 -DST( movw %cx, (%edi) )
8272 +DST( movw %cx, %es:(%edi) )
8276 SRC(5: movb (%esi), %cl )
8277 -DST( movb %cl, (%edi) )
8278 +DST( movb %cl, %es:(%edi) )
8282 @@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
8285 movl ARGBASE+20(%esp), %ebx # src_err_ptr
8286 - movl $-EFAULT, (%ebx)
8287 + movl $-EFAULT, %ss:(%ebx)
8289 # zero the complete destination - computing the rest
8291 @@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
8294 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
8295 - movl $-EFAULT,(%ebx)
8296 + movl $-EFAULT,%ss:(%ebx)
8302 + CFI_ADJUST_CFA_OFFSET 4
8304 + CFI_ADJUST_CFA_OFFSET -4
8306 + CFI_ADJUST_CFA_OFFSET 4
8308 + CFI_ADJUST_CFA_OFFSET -4
8310 CFI_ADJUST_CFA_OFFSET -4
8312 @@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
8313 CFI_ADJUST_CFA_OFFSET -4
8316 -ENDPROC(csum_partial_copy_generic)
8317 +ENDPROC(csum_partial_copy_generic_to_user)
8321 /* Version for PentiumII/PPro */
8325 SRC(movl x(%esi), %ebx ) ; \
8327 - DST(movl %ebx, x(%edi) ) ;
8328 + DST(movl %ebx, %es:x(%edi)) ;
8332 SRC(movl x(%esi), %ebx ) ; \
8334 - DST(movl %ebx, x(%edi) ) ;
8335 + DST(movl %ebx, %es:x(%edi)) ;
8339 -ENTRY(csum_partial_copy_generic)
8341 +ENTRY(csum_partial_copy_generic_to_user)
8343 + pushl $(__USER_DS)
8344 + CFI_ADJUST_CFA_OFFSET 4
8346 + CFI_ADJUST_CFA_OFFSET -4
8347 + jmp csum_partial_copy_generic
8349 +ENTRY(csum_partial_copy_generic_from_user)
8350 + pushl $(__USER_DS)
8351 + CFI_ADJUST_CFA_OFFSET 4
8353 + CFI_ADJUST_CFA_OFFSET -4
8355 +ENTRY(csum_partial_copy_generic)
8357 CFI_ADJUST_CFA_OFFSET 4
8358 CFI_REL_OFFSET ebx, 0
8359 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
8363 - lea 3f(%ebx,%ebx), %ebx
8364 + lea 3f(%ebx,%ebx,2), %ebx
8368 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
8370 SRC( movw (%esi), %dx )
8372 -DST( movw %dx, (%edi) )
8373 +DST( movw %dx, %es:(%edi) )
8378 SRC( movb (%esi), %dl )
8379 -DST( movb %dl, (%edi) )
8380 +DST( movb %dl, %es:(%edi) )
8384 .section .fixup, "ax"
8385 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
8386 - movl $-EFAULT, (%ebx)
8387 + movl $-EFAULT, %ss:(%ebx)
8388 # zero the complete destination (computing the rest is too much work)
8389 movl ARGBASE+8(%esp),%edi # dst
8390 movl ARGBASE+12(%esp),%ecx # len
8391 @@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
8394 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
8395 - movl $-EFAULT, (%ebx)
8396 + movl $-EFAULT, %ss:(%ebx)
8401 + CFI_ADJUST_CFA_OFFSET 4
8403 + CFI_ADJUST_CFA_OFFSET -4
8405 + CFI_ADJUST_CFA_OFFSET 4
8407 + CFI_ADJUST_CFA_OFFSET -4
8409 CFI_ADJUST_CFA_OFFSET -4
8411 @@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
8415 -ENDPROC(csum_partial_copy_generic)
8416 +ENDPROC(csum_partial_copy_generic_to_user)
8420 diff -urNp linux-2.6.24.4/arch/x86/lib/clear_page_64.S linux-2.6.24.4/arch/x86/lib/clear_page_64.S
8421 --- linux-2.6.24.4/arch/x86/lib/clear_page_64.S 2008-03-24 14:49:18.000000000 -0400
8422 +++ linux-2.6.24.4/arch/x86/lib/clear_page_64.S 2008-03-26 20:21:08.000000000 -0400
8423 @@ -44,7 +44,7 @@ ENDPROC(clear_page)
8425 #include <asm/cpufeature.h>
8427 - .section .altinstr_replacement,"ax"
8428 + .section .altinstr_replacement,"a"
8429 1: .byte 0xeb /* jmp <disp8> */
8430 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
8432 diff -urNp linux-2.6.24.4/arch/x86/lib/copy_page_64.S linux-2.6.24.4/arch/x86/lib/copy_page_64.S
8433 --- linux-2.6.24.4/arch/x86/lib/copy_page_64.S 2008-03-24 14:49:18.000000000 -0400
8434 +++ linux-2.6.24.4/arch/x86/lib/copy_page_64.S 2008-03-26 20:21:08.000000000 -0400
8435 @@ -104,7 +104,7 @@ ENDPROC(copy_page)
8437 #include <asm/cpufeature.h>
8439 - .section .altinstr_replacement,"ax"
8440 + .section .altinstr_replacement,"a"
8441 1: .byte 0xeb /* jmp <disp8> */
8442 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
8444 diff -urNp linux-2.6.24.4/arch/x86/lib/copy_user_64.S linux-2.6.24.4/arch/x86/lib/copy_user_64.S
8445 --- linux-2.6.24.4/arch/x86/lib/copy_user_64.S 2008-03-24 14:49:18.000000000 -0400
8446 +++ linux-2.6.24.4/arch/x86/lib/copy_user_64.S 2008-03-26 20:21:08.000000000 -0400
8448 .byte 0xe9 /* 32bit jump */
8449 .long \orig-1f /* by default jump to orig */
8451 - .section .altinstr_replacement,"ax"
8452 + .section .altinstr_replacement,"a"
8453 2: .byte 0xe9 /* near jump with 32bit immediate */
8454 .long \alt-1b /* offset */ /* or alternatively to alt */
8456 diff -urNp linux-2.6.24.4/arch/x86/lib/getuser_32.S linux-2.6.24.4/arch/x86/lib/getuser_32.S
8457 --- linux-2.6.24.4/arch/x86/lib/getuser_32.S 2008-03-24 14:49:18.000000000 -0400
8458 +++ linux-2.6.24.4/arch/x86/lib/getuser_32.S 2008-03-26 20:21:08.000000000 -0400
8460 #include <linux/linkage.h>
8461 #include <asm/dwarf2.h>
8462 #include <asm/thread_info.h>
8464 +#include <asm/segment.h>
8468 @@ -31,7 +31,11 @@ ENTRY(__get_user_1)
8469 GET_THREAD_INFO(%edx)
8470 cmpl TI_addr_limit(%edx),%eax
8472 + pushl $(__USER_DS)
8474 1: movzbl (%eax),%edx
8480 @@ -44,7 +48,11 @@ ENTRY(__get_user_2)
8481 GET_THREAD_INFO(%edx)
8482 cmpl TI_addr_limit(%edx),%eax
8484 + pushl $(__USER_DS)
8486 2: movzwl -1(%eax),%edx
8492 @@ -57,7 +65,11 @@ ENTRY(__get_user_4)
8493 GET_THREAD_INFO(%edx)
8494 cmpl TI_addr_limit(%edx),%eax
8496 + pushl $(__USER_DS)
8498 3: movl -3(%eax),%edx
8504 @@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
8513 diff -urNp linux-2.6.24.4/arch/x86/lib/memcpy_64.S linux-2.6.24.4/arch/x86/lib/memcpy_64.S
8514 --- linux-2.6.24.4/arch/x86/lib/memcpy_64.S 2008-03-24 14:49:18.000000000 -0400
8515 +++ linux-2.6.24.4/arch/x86/lib/memcpy_64.S 2008-03-26 20:21:08.000000000 -0400
8516 @@ -114,7 +114,7 @@ ENDPROC(__memcpy)
8517 /* Some CPUs run faster using the string copy instructions.
8518 It is also a lot simpler. Use this when possible */
8520 - .section .altinstr_replacement,"ax"
8521 + .section .altinstr_replacement,"a"
8522 1: .byte 0xeb /* jmp <disp8> */
8523 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
8525 diff -urNp linux-2.6.24.4/arch/x86/lib/memset_64.S linux-2.6.24.4/arch/x86/lib/memset_64.S
8526 --- linux-2.6.24.4/arch/x86/lib/memset_64.S 2008-03-24 14:49:18.000000000 -0400
8527 +++ linux-2.6.24.4/arch/x86/lib/memset_64.S 2008-03-26 20:21:08.000000000 -0400
8528 @@ -118,7 +118,7 @@ ENDPROC(__memset)
8530 #include <asm/cpufeature.h>
8532 - .section .altinstr_replacement,"ax"
8533 + .section .altinstr_replacement,"a"
8534 1: .byte 0xeb /* jmp <disp8> */
8535 .byte (memset_c - memset) - (2f - 1b) /* offset */
8537 diff -urNp linux-2.6.24.4/arch/x86/lib/mmx_32.c linux-2.6.24.4/arch/x86/lib/mmx_32.c
8538 --- linux-2.6.24.4/arch/x86/lib/mmx_32.c 2008-03-24 14:49:18.000000000 -0400
8539 +++ linux-2.6.24.4/arch/x86/lib/mmx_32.c 2008-03-26 20:21:08.000000000 -0400
8540 @@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void *
8544 + unsigned long cr0;
8546 if (unlikely(in_interrupt()))
8547 return __memcpy(to, from, len);
8548 @@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
8551 __asm__ __volatile__ (
8552 - "1: prefetch (%0)\n" /* This set is 28 bytes */
8553 - " prefetch 64(%0)\n"
8554 - " prefetch 128(%0)\n"
8555 - " prefetch 192(%0)\n"
8556 - " prefetch 256(%0)\n"
8557 + "1: prefetch (%1)\n" /* This set is 28 bytes */
8558 + " prefetch 64(%1)\n"
8559 + " prefetch 128(%1)\n"
8560 + " prefetch 192(%1)\n"
8561 + " prefetch 256(%1)\n"
8563 ".section .fixup, \"ax\"\n"
8564 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8567 +#ifdef CONFIG_PAX_KERNEXEC
8568 + " movl %%cr0, %0\n"
8569 + " movl %0, %%eax\n"
8570 + " andl $0xFFFEFFFF, %%eax\n"
8571 + " movl %%eax, %%cr0\n"
8574 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8576 +#ifdef CONFIG_PAX_KERNEXEC
8577 + " movl %0, %%cr0\n"
8582 ".section __ex_table,\"a\"\n"
8587 + : "=&r" (cr0) : "r" (from) : "ax");
8592 __asm__ __volatile__ (
8593 - "1: prefetch 320(%0)\n"
8594 - "2: movq (%0), %%mm0\n"
8595 - " movq 8(%0), %%mm1\n"
8596 - " movq 16(%0), %%mm2\n"
8597 - " movq 24(%0), %%mm3\n"
8598 - " movq %%mm0, (%1)\n"
8599 - " movq %%mm1, 8(%1)\n"
8600 - " movq %%mm2, 16(%1)\n"
8601 - " movq %%mm3, 24(%1)\n"
8602 - " movq 32(%0), %%mm0\n"
8603 - " movq 40(%0), %%mm1\n"
8604 - " movq 48(%0), %%mm2\n"
8605 - " movq 56(%0), %%mm3\n"
8606 - " movq %%mm0, 32(%1)\n"
8607 - " movq %%mm1, 40(%1)\n"
8608 - " movq %%mm2, 48(%1)\n"
8609 - " movq %%mm3, 56(%1)\n"
8610 + "1: prefetch 320(%1)\n"
8611 + "2: movq (%1), %%mm0\n"
8612 + " movq 8(%1), %%mm1\n"
8613 + " movq 16(%1), %%mm2\n"
8614 + " movq 24(%1), %%mm3\n"
8615 + " movq %%mm0, (%2)\n"
8616 + " movq %%mm1, 8(%2)\n"
8617 + " movq %%mm2, 16(%2)\n"
8618 + " movq %%mm3, 24(%2)\n"
8619 + " movq 32(%1), %%mm0\n"
8620 + " movq 40(%1), %%mm1\n"
8621 + " movq 48(%1), %%mm2\n"
8622 + " movq 56(%1), %%mm3\n"
8623 + " movq %%mm0, 32(%2)\n"
8624 + " movq %%mm1, 40(%2)\n"
8625 + " movq %%mm2, 48(%2)\n"
8626 + " movq %%mm3, 56(%2)\n"
8627 ".section .fixup, \"ax\"\n"
8628 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8631 +#ifdef CONFIG_PAX_KERNEXEC
8632 + " movl %%cr0, %0\n"
8633 + " movl %0, %%eax\n"
8634 + " andl $0xFFFEFFFF, %%eax\n"
8635 + " movl %%eax, %%cr0\n"
8638 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8640 +#ifdef CONFIG_PAX_KERNEXEC
8641 + " movl %0, %%cr0\n"
8646 ".section __ex_table,\"a\"\n"
8650 - : : "r" (from), "r" (to) : "memory");
8651 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8655 @@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
8656 static void fast_copy_page(void *to, void *from)
8659 + unsigned long cr0;
8663 @@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
8664 * but that is for later. -AV
8666 __asm__ __volatile__ (
8667 - "1: prefetch (%0)\n"
8668 - " prefetch 64(%0)\n"
8669 - " prefetch 128(%0)\n"
8670 - " prefetch 192(%0)\n"
8671 - " prefetch 256(%0)\n"
8672 + "1: prefetch (%1)\n"
8673 + " prefetch 64(%1)\n"
8674 + " prefetch 128(%1)\n"
8675 + " prefetch 192(%1)\n"
8676 + " prefetch 256(%1)\n"
8678 ".section .fixup, \"ax\"\n"
8679 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8682 +#ifdef CONFIG_PAX_KERNEXEC
8683 + " movl %%cr0, %0\n"
8684 + " movl %0, %%eax\n"
8685 + " andl $0xFFFEFFFF, %%eax\n"
8686 + " movl %%eax, %%cr0\n"
8689 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8691 +#ifdef CONFIG_PAX_KERNEXEC
8692 + " movl %0, %%cr0\n"
8697 ".section __ex_table,\"a\"\n"
8702 + : "=&r" (cr0) : "r" (from) : "ax");
8704 for(i=0; i<(4096-320)/64; i++)
8706 __asm__ __volatile__ (
8707 - "1: prefetch 320(%0)\n"
8708 - "2: movq (%0), %%mm0\n"
8709 - " movntq %%mm0, (%1)\n"
8710 - " movq 8(%0), %%mm1\n"
8711 - " movntq %%mm1, 8(%1)\n"
8712 - " movq 16(%0), %%mm2\n"
8713 - " movntq %%mm2, 16(%1)\n"
8714 - " movq 24(%0), %%mm3\n"
8715 - " movntq %%mm3, 24(%1)\n"
8716 - " movq 32(%0), %%mm4\n"
8717 - " movntq %%mm4, 32(%1)\n"
8718 - " movq 40(%0), %%mm5\n"
8719 - " movntq %%mm5, 40(%1)\n"
8720 - " movq 48(%0), %%mm6\n"
8721 - " movntq %%mm6, 48(%1)\n"
8722 - " movq 56(%0), %%mm7\n"
8723 - " movntq %%mm7, 56(%1)\n"
8724 + "1: prefetch 320(%1)\n"
8725 + "2: movq (%1), %%mm0\n"
8726 + " movntq %%mm0, (%2)\n"
8727 + " movq 8(%1), %%mm1\n"
8728 + " movntq %%mm1, 8(%2)\n"
8729 + " movq 16(%1), %%mm2\n"
8730 + " movntq %%mm2, 16(%2)\n"
8731 + " movq 24(%1), %%mm3\n"
8732 + " movntq %%mm3, 24(%2)\n"
8733 + " movq 32(%1), %%mm4\n"
8734 + " movntq %%mm4, 32(%2)\n"
8735 + " movq 40(%1), %%mm5\n"
8736 + " movntq %%mm5, 40(%2)\n"
8737 + " movq 48(%1), %%mm6\n"
8738 + " movntq %%mm6, 48(%2)\n"
8739 + " movq 56(%1), %%mm7\n"
8740 + " movntq %%mm7, 56(%2)\n"
8741 ".section .fixup, \"ax\"\n"
8742 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8745 +#ifdef CONFIG_PAX_KERNEXEC
8746 + " movl %%cr0, %0\n"
8747 + " movl %0, %%eax\n"
8748 + " andl $0xFFFEFFFF, %%eax\n"
8749 + " movl %%eax, %%cr0\n"
8752 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8754 +#ifdef CONFIG_PAX_KERNEXEC
8755 + " movl %0, %%cr0\n"
8760 ".section __ex_table,\"a\"\n"
8764 - : : "r" (from), "r" (to) : "memory");
8765 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8769 @@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
8770 static void fast_copy_page(void *to, void *from)
8775 + unsigned long cr0;
8779 __asm__ __volatile__ (
8780 - "1: prefetch (%0)\n"
8781 - " prefetch 64(%0)\n"
8782 - " prefetch 128(%0)\n"
8783 - " prefetch 192(%0)\n"
8784 - " prefetch 256(%0)\n"
8785 + "1: prefetch (%1)\n"
8786 + " prefetch 64(%1)\n"
8787 + " prefetch 128(%1)\n"
8788 + " prefetch 192(%1)\n"
8789 + " prefetch 256(%1)\n"
8791 ".section .fixup, \"ax\"\n"
8792 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8795 +#ifdef CONFIG_PAX_KERNEXEC
8796 + " movl %%cr0, %0\n"
8797 + " movl %0, %%eax\n"
8798 + " andl $0xFFFEFFFF, %%eax\n"
8799 + " movl %%eax, %%cr0\n"
8802 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8804 +#ifdef CONFIG_PAX_KERNEXEC
8805 + " movl %0, %%cr0\n"
8810 ".section __ex_table,\"a\"\n"
8815 + : "=&r" (cr0) : "r" (from) : "ax");
8817 for(i=0; i<4096/64; i++)
8819 __asm__ __volatile__ (
8820 - "1: prefetch 320(%0)\n"
8821 - "2: movq (%0), %%mm0\n"
8822 - " movq 8(%0), %%mm1\n"
8823 - " movq 16(%0), %%mm2\n"
8824 - " movq 24(%0), %%mm3\n"
8825 - " movq %%mm0, (%1)\n"
8826 - " movq %%mm1, 8(%1)\n"
8827 - " movq %%mm2, 16(%1)\n"
8828 - " movq %%mm3, 24(%1)\n"
8829 - " movq 32(%0), %%mm0\n"
8830 - " movq 40(%0), %%mm1\n"
8831 - " movq 48(%0), %%mm2\n"
8832 - " movq 56(%0), %%mm3\n"
8833 - " movq %%mm0, 32(%1)\n"
8834 - " movq %%mm1, 40(%1)\n"
8835 - " movq %%mm2, 48(%1)\n"
8836 - " movq %%mm3, 56(%1)\n"
8837 + "1: prefetch 320(%1)\n"
8838 + "2: movq (%1), %%mm0\n"
8839 + " movq 8(%1), %%mm1\n"
8840 + " movq 16(%1), %%mm2\n"
8841 + " movq 24(%1), %%mm3\n"
8842 + " movq %%mm0, (%2)\n"
8843 + " movq %%mm1, 8(%2)\n"
8844 + " movq %%mm2, 16(%2)\n"
8845 + " movq %%mm3, 24(%2)\n"
8846 + " movq 32(%1), %%mm0\n"
8847 + " movq 40(%1), %%mm1\n"
8848 + " movq 48(%1), %%mm2\n"
8849 + " movq 56(%1), %%mm3\n"
8850 + " movq %%mm0, 32(%2)\n"
8851 + " movq %%mm1, 40(%2)\n"
8852 + " movq %%mm2, 48(%2)\n"
8853 + " movq %%mm3, 56(%2)\n"
8854 ".section .fixup, \"ax\"\n"
8855 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8858 +#ifdef CONFIG_PAX_KERNEXEC
8859 + " movl %%cr0, %0\n"
8860 + " movl %0, %%eax\n"
8861 + " andl $0xFFFEFFFF, %%eax\n"
8862 + " movl %%eax, %%cr0\n"
8865 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8867 +#ifdef CONFIG_PAX_KERNEXEC
8868 + " movl %0, %%cr0\n"
8873 ".section __ex_table,\"a\"\n"
8877 - : : "r" (from), "r" (to) : "memory");
8878 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8882 diff -urNp linux-2.6.24.4/arch/x86/lib/putuser_32.S linux-2.6.24.4/arch/x86/lib/putuser_32.S
8883 --- linux-2.6.24.4/arch/x86/lib/putuser_32.S 2008-03-24 14:49:18.000000000 -0400
8884 +++ linux-2.6.24.4/arch/x86/lib/putuser_32.S 2008-03-26 20:21:08.000000000 -0400
8886 #include <linux/linkage.h>
8887 #include <asm/dwarf2.h>
8888 #include <asm/thread_info.h>
8890 +#include <asm/segment.h>
8894 @@ -41,7 +41,11 @@ ENTRY(__put_user_1)
8896 cmpl TI_addr_limit(%ebx),%ecx
8898 + pushl $(__USER_DS)
8905 ENDPROC(__put_user_1)
8906 @@ -52,7 +56,11 @@ ENTRY(__put_user_2)
8910 + pushl $(__USER_DS)
8917 ENDPROC(__put_user_2)
8918 @@ -63,7 +71,11 @@ ENTRY(__put_user_4)
8922 + pushl $(__USER_DS)
8929 ENDPROC(__put_user_4)
8930 @@ -74,8 +86,12 @@ ENTRY(__put_user_8)
8934 + pushl $(__USER_DS)
8937 5: movl %edx,4(%ecx)
8942 ENDPROC(__put_user_8)
8943 @@ -85,6 +101,10 @@ bad_put_user:
8944 CFI_DEF_CFA esp, 2*4
8945 CFI_OFFSET eip, -1*4
8946 CFI_OFFSET ebx, -2*4
8948 + CFI_ADJUST_CFA_OFFSET 4
8950 + CFI_ADJUST_CFA_OFFSET -4
8954 diff -urNp linux-2.6.24.4/arch/x86/lib/usercopy_32.c linux-2.6.24.4/arch/x86/lib/usercopy_32.c
8955 --- linux-2.6.24.4/arch/x86/lib/usercopy_32.c 2008-03-24 14:49:18.000000000 -0400
8956 +++ linux-2.6.24.4/arch/x86/lib/usercopy_32.c 2008-03-26 20:21:08.000000000 -0400
8957 @@ -29,34 +29,41 @@ static inline int __movsl_is_ok(unsigned
8958 * Copy a null terminated string from userspace.
8961 -#define __do_strncpy_from_user(dst,src,count,res) \
8963 - int __d0, __d1, __d2; \
8965 - __asm__ __volatile__( \
8966 - " testl %1,%1\n" \
8970 - " testb %%al,%%al\n" \
8974 - "1: subl %1,%0\n" \
8976 - ".section .fixup,\"ax\"\n" \
8977 - "3: movl %5,%0\n" \
8980 - ".section __ex_table,\"a\"\n" \
8982 - " .long 0b,3b\n" \
8984 - : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
8986 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
8989 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
8991 + int __d0, __d1, __d2;
8992 + long res = -EFAULT;
8995 + __asm__ __volatile__(
8996 + " movw %w10,%%ds\n"
9001 + " testb %%al,%%al\n"
9009 + ".section .fixup,\"ax\"\n"
9013 + ".section __ex_table,\"a\"\n"
9017 + : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
9019 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
9026 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
9027 @@ -81,9 +88,7 @@ do { \
9029 __strncpy_from_user(char *dst, const char __user *src, long count)
9032 - __do_strncpy_from_user(dst, src, count, res);
9034 + return __do_strncpy_from_user(dst, src, count);
9036 EXPORT_SYMBOL(__strncpy_from_user);
9038 @@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char
9041 if (access_ok(VERIFY_READ, src, 1))
9042 - __do_strncpy_from_user(dst, src, count, res);
9043 + res = __do_strncpy_from_user(dst, src, count);
9046 EXPORT_SYMBOL(strncpy_from_user);
9047 @@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user);
9051 -#define __do_clear_user(addr,size) \
9055 - __asm__ __volatile__( \
9056 - "0: rep; stosl\n" \
9058 - "1: rep; stosb\n" \
9060 - ".section .fixup,\"ax\"\n" \
9061 - "3: lea 0(%2,%0,4),%0\n" \
9064 - ".section __ex_table,\"a\"\n" \
9066 - " .long 0b,3b\n" \
9067 - " .long 1b,2b\n" \
9069 - : "=&c"(size), "=&D" (__d0) \
9070 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
9072 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
9077 + __asm__ __volatile__(
9078 + " movw %w6,%%es\n"
9085 + ".section .fixup,\"ax\"\n"
9086 + "3: lea 0(%2,%0,4),%0\n"
9089 + ".section __ex_table,\"a\"\n"
9094 + : "=&c"(size), "=&D" (__d0)
9095 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
9101 * clear_user: - Zero a block of memory in user space.
9102 @@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon
9105 if (access_ok(VERIFY_WRITE, to, n))
9106 - __do_clear_user(to, n);
9107 + n = __do_clear_user(to, n);
9110 EXPORT_SYMBOL(clear_user);
9111 @@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user);
9113 __clear_user(void __user *to, unsigned long n)
9115 - __do_clear_user(to, n);
9117 + return __do_clear_user(to, n);
9119 EXPORT_SYMBOL(__clear_user);
9121 @@ -199,14 +209,17 @@ long strnlen_user(const char __user *s,
9124 __asm__ __volatile__(
9125 + " movw %w8,%%es\n"
9128 - " andl %0,%%ecx\n"
9129 + " movl %0,%%ecx\n"
9137 ".section .fixup,\"ax\"\n"
9138 "2: xorl %%eax,%%eax\n"
9140 @@ -218,7 +231,7 @@ long strnlen_user(const char __user *s,
9143 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
9144 - :"0" (n), "1" (s), "2" (0), "3" (mask)
9145 + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
9149 @@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user);
9151 #ifdef CONFIG_X86_INTEL_USERCOPY
9152 static unsigned long
9153 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
9154 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
9157 + __asm__ __volatile__(
9158 + " movw %w6, %%es\n"
9159 + " .align 2,0x90\n"
9160 + "1: movl 32(%4), %%eax\n"
9163 + "2: movl 64(%4), %%eax\n"
9164 + " .align 2,0x90\n"
9165 + "3: movl 0(%4), %%eax\n"
9166 + "4: movl 4(%4), %%edx\n"
9167 + "5: movl %%eax, %%es:0(%3)\n"
9168 + "6: movl %%edx, %%es:4(%3)\n"
9169 + "7: movl 8(%4), %%eax\n"
9170 + "8: movl 12(%4),%%edx\n"
9171 + "9: movl %%eax, %%es:8(%3)\n"
9172 + "10: movl %%edx, %%es:12(%3)\n"
9173 + "11: movl 16(%4), %%eax\n"
9174 + "12: movl 20(%4), %%edx\n"
9175 + "13: movl %%eax, %%es:16(%3)\n"
9176 + "14: movl %%edx, %%es:20(%3)\n"
9177 + "15: movl 24(%4), %%eax\n"
9178 + "16: movl 28(%4), %%edx\n"
9179 + "17: movl %%eax, %%es:24(%3)\n"
9180 + "18: movl %%edx, %%es:28(%3)\n"
9181 + "19: movl 32(%4), %%eax\n"
9182 + "20: movl 36(%4), %%edx\n"
9183 + "21: movl %%eax, %%es:32(%3)\n"
9184 + "22: movl %%edx, %%es:36(%3)\n"
9185 + "23: movl 40(%4), %%eax\n"
9186 + "24: movl 44(%4), %%edx\n"
9187 + "25: movl %%eax, %%es:40(%3)\n"
9188 + "26: movl %%edx, %%es:44(%3)\n"
9189 + "27: movl 48(%4), %%eax\n"
9190 + "28: movl 52(%4), %%edx\n"
9191 + "29: movl %%eax, %%es:48(%3)\n"
9192 + "30: movl %%edx, %%es:52(%3)\n"
9193 + "31: movl 56(%4), %%eax\n"
9194 + "32: movl 60(%4), %%edx\n"
9195 + "33: movl %%eax, %%es:56(%3)\n"
9196 + "34: movl %%edx, %%es:60(%3)\n"
9197 + " addl $-64, %0\n"
9202 + "35: movl %0, %%eax\n"
9204 + " andl $3, %%eax\n"
9206 + "99: rep; movsl\n"
9207 + "36: movl %%eax, %0\n"
9208 + "37: rep; movsb\n"
9212 + ".section .fixup,\"ax\"\n"
9213 + "101: lea 0(%%eax,%0,4),%0\n"
9216 + ".section __ex_table,\"a\"\n"
9218 + " .long 1b,100b\n"
9219 + " .long 2b,100b\n"
9220 + " .long 3b,100b\n"
9221 + " .long 4b,100b\n"
9222 + " .long 5b,100b\n"
9223 + " .long 6b,100b\n"
9224 + " .long 7b,100b\n"
9225 + " .long 8b,100b\n"
9226 + " .long 9b,100b\n"
9227 + " .long 10b,100b\n"
9228 + " .long 11b,100b\n"
9229 + " .long 12b,100b\n"
9230 + " .long 13b,100b\n"
9231 + " .long 14b,100b\n"
9232 + " .long 15b,100b\n"
9233 + " .long 16b,100b\n"
9234 + " .long 17b,100b\n"
9235 + " .long 18b,100b\n"
9236 + " .long 19b,100b\n"
9237 + " .long 20b,100b\n"
9238 + " .long 21b,100b\n"
9239 + " .long 22b,100b\n"
9240 + " .long 23b,100b\n"
9241 + " .long 24b,100b\n"
9242 + " .long 25b,100b\n"
9243 + " .long 26b,100b\n"
9244 + " .long 27b,100b\n"
9245 + " .long 28b,100b\n"
9246 + " .long 29b,100b\n"
9247 + " .long 30b,100b\n"
9248 + " .long 31b,100b\n"
9249 + " .long 32b,100b\n"
9250 + " .long 33b,100b\n"
9251 + " .long 34b,100b\n"
9252 + " .long 35b,100b\n"
9253 + " .long 36b,100b\n"
9254 + " .long 37b,100b\n"
9255 + " .long 99b,101b\n"
9257 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
9258 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9259 + : "eax", "edx", "memory");
9263 +static unsigned long
9264 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
9267 __asm__ __volatile__(
9268 + " movw %w6, %%ds\n"
9270 "1: movl 32(%4), %%eax\n"
9272 @@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const
9274 "3: movl 0(%4), %%eax\n"
9275 "4: movl 4(%4), %%edx\n"
9276 - "5: movl %%eax, 0(%3)\n"
9277 - "6: movl %%edx, 4(%3)\n"
9278 + "5: movl %%eax, %%es:0(%3)\n"
9279 + "6: movl %%edx, %%es:4(%3)\n"
9280 "7: movl 8(%4), %%eax\n"
9281 "8: movl 12(%4),%%edx\n"
9282 - "9: movl %%eax, 8(%3)\n"
9283 - "10: movl %%edx, 12(%3)\n"
9284 + "9: movl %%eax, %%es:8(%3)\n"
9285 + "10: movl %%edx, %%es:12(%3)\n"
9286 "11: movl 16(%4), %%eax\n"
9287 "12: movl 20(%4), %%edx\n"
9288 - "13: movl %%eax, 16(%3)\n"
9289 - "14: movl %%edx, 20(%3)\n"
9290 + "13: movl %%eax, %%es:16(%3)\n"
9291 + "14: movl %%edx, %%es:20(%3)\n"
9292 "15: movl 24(%4), %%eax\n"
9293 "16: movl 28(%4), %%edx\n"
9294 - "17: movl %%eax, 24(%3)\n"
9295 - "18: movl %%edx, 28(%3)\n"
9296 + "17: movl %%eax, %%es:24(%3)\n"
9297 + "18: movl %%edx, %%es:28(%3)\n"
9298 "19: movl 32(%4), %%eax\n"
9299 "20: movl 36(%4), %%edx\n"
9300 - "21: movl %%eax, 32(%3)\n"
9301 - "22: movl %%edx, 36(%3)\n"
9302 + "21: movl %%eax, %%es:32(%3)\n"
9303 + "22: movl %%edx, %%es:36(%3)\n"
9304 "23: movl 40(%4), %%eax\n"
9305 "24: movl 44(%4), %%edx\n"
9306 - "25: movl %%eax, 40(%3)\n"
9307 - "26: movl %%edx, 44(%3)\n"
9308 + "25: movl %%eax, %%es:40(%3)\n"
9309 + "26: movl %%edx, %%es:44(%3)\n"
9310 "27: movl 48(%4), %%eax\n"
9311 "28: movl 52(%4), %%edx\n"
9312 - "29: movl %%eax, 48(%3)\n"
9313 - "30: movl %%edx, 52(%3)\n"
9314 + "29: movl %%eax, %%es:48(%3)\n"
9315 + "30: movl %%edx, %%es:52(%3)\n"
9316 "31: movl 56(%4), %%eax\n"
9317 "32: movl 60(%4), %%edx\n"
9318 - "33: movl %%eax, 56(%3)\n"
9319 - "34: movl %%edx, 60(%3)\n"
9320 + "33: movl %%eax, %%es:56(%3)\n"
9321 + "34: movl %%edx, %%es:60(%3)\n"
9325 @@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const
9326 "36: movl %%eax, %0\n"
9331 ".section .fixup,\"ax\"\n"
9332 "101: lea 0(%%eax,%0,4),%0\n"
9334 @@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const
9337 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9338 - : "1"(to), "2"(from), "0"(size)
9339 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9340 : "eax", "edx", "memory");
9343 @@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons
9346 __asm__ __volatile__(
9347 + " movw %w6, %%ds\n"
9349 "0: movl 32(%4), %%eax\n"
9351 @@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons
9353 "2: movl 0(%4), %%eax\n"
9354 "21: movl 4(%4), %%edx\n"
9355 - " movl %%eax, 0(%3)\n"
9356 - " movl %%edx, 4(%3)\n"
9357 + " movl %%eax, %%es:0(%3)\n"
9358 + " movl %%edx, %%es:4(%3)\n"
9359 "3: movl 8(%4), %%eax\n"
9360 "31: movl 12(%4),%%edx\n"
9361 - " movl %%eax, 8(%3)\n"
9362 - " movl %%edx, 12(%3)\n"
9363 + " movl %%eax, %%es:8(%3)\n"
9364 + " movl %%edx, %%es:12(%3)\n"
9365 "4: movl 16(%4), %%eax\n"
9366 "41: movl 20(%4), %%edx\n"
9367 - " movl %%eax, 16(%3)\n"
9368 - " movl %%edx, 20(%3)\n"
9369 + " movl %%eax, %%es:16(%3)\n"
9370 + " movl %%edx, %%es:20(%3)\n"
9371 "10: movl 24(%4), %%eax\n"
9372 "51: movl 28(%4), %%edx\n"
9373 - " movl %%eax, 24(%3)\n"
9374 - " movl %%edx, 28(%3)\n"
9375 + " movl %%eax, %%es:24(%3)\n"
9376 + " movl %%edx, %%es:28(%3)\n"
9377 "11: movl 32(%4), %%eax\n"
9378 "61: movl 36(%4), %%edx\n"
9379 - " movl %%eax, 32(%3)\n"
9380 - " movl %%edx, 36(%3)\n"
9381 + " movl %%eax, %%es:32(%3)\n"
9382 + " movl %%edx, %%es:36(%3)\n"
9383 "12: movl 40(%4), %%eax\n"
9384 "71: movl 44(%4), %%edx\n"
9385 - " movl %%eax, 40(%3)\n"
9386 - " movl %%edx, 44(%3)\n"
9387 + " movl %%eax, %%es:40(%3)\n"
9388 + " movl %%edx, %%es:44(%3)\n"
9389 "13: movl 48(%4), %%eax\n"
9390 "81: movl 52(%4), %%edx\n"
9391 - " movl %%eax, 48(%3)\n"
9392 - " movl %%edx, 52(%3)\n"
9393 + " movl %%eax, %%es:48(%3)\n"
9394 + " movl %%edx, %%es:52(%3)\n"
9395 "14: movl 56(%4), %%eax\n"
9396 "91: movl 60(%4), %%edx\n"
9397 - " movl %%eax, 56(%3)\n"
9398 - " movl %%edx, 60(%3)\n"
9399 + " movl %%eax, %%es:56(%3)\n"
9400 + " movl %%edx, %%es:60(%3)\n"
9404 @@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons
9410 ".section .fixup,\"ax\"\n"
9411 "9: lea 0(%%eax,%0,4),%0\n"
9413 @@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons
9416 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9417 - : "1"(to), "2"(from), "0"(size)
9418 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9419 : "eax", "edx", "memory");
9422 @@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing
9425 __asm__ __volatile__(
9426 + " movw %w6, %%ds\n"
9428 "0: movl 32(%4), %%eax\n"
9430 @@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing
9432 "2: movl 0(%4), %%eax\n"
9433 "21: movl 4(%4), %%edx\n"
9434 - " movnti %%eax, 0(%3)\n"
9435 - " movnti %%edx, 4(%3)\n"
9436 + " movnti %%eax, %%es:0(%3)\n"
9437 + " movnti %%edx, %%es:4(%3)\n"
9438 "3: movl 8(%4), %%eax\n"
9439 "31: movl 12(%4),%%edx\n"
9440 - " movnti %%eax, 8(%3)\n"
9441 - " movnti %%edx, 12(%3)\n"
9442 + " movnti %%eax, %%es:8(%3)\n"
9443 + " movnti %%edx, %%es:12(%3)\n"
9444 "4: movl 16(%4), %%eax\n"
9445 "41: movl 20(%4), %%edx\n"
9446 - " movnti %%eax, 16(%3)\n"
9447 - " movnti %%edx, 20(%3)\n"
9448 + " movnti %%eax, %%es:16(%3)\n"
9449 + " movnti %%edx, %%es:20(%3)\n"
9450 "10: movl 24(%4), %%eax\n"
9451 "51: movl 28(%4), %%edx\n"
9452 - " movnti %%eax, 24(%3)\n"
9453 - " movnti %%edx, 28(%3)\n"
9454 + " movnti %%eax, %%es:24(%3)\n"
9455 + " movnti %%edx, %%es:28(%3)\n"
9456 "11: movl 32(%4), %%eax\n"
9457 "61: movl 36(%4), %%edx\n"
9458 - " movnti %%eax, 32(%3)\n"
9459 - " movnti %%edx, 36(%3)\n"
9460 + " movnti %%eax, %%es:32(%3)\n"
9461 + " movnti %%edx, %%es:36(%3)\n"
9462 "12: movl 40(%4), %%eax\n"
9463 "71: movl 44(%4), %%edx\n"
9464 - " movnti %%eax, 40(%3)\n"
9465 - " movnti %%edx, 44(%3)\n"
9466 + " movnti %%eax, %%es:40(%3)\n"
9467 + " movnti %%edx, %%es:44(%3)\n"
9468 "13: movl 48(%4), %%eax\n"
9469 "81: movl 52(%4), %%edx\n"
9470 - " movnti %%eax, 48(%3)\n"
9471 - " movnti %%edx, 52(%3)\n"
9472 + " movnti %%eax, %%es:48(%3)\n"
9473 + " movnti %%edx, %%es:52(%3)\n"
9474 "14: movl 56(%4), %%eax\n"
9475 "91: movl 60(%4), %%edx\n"
9476 - " movnti %%eax, 56(%3)\n"
9477 - " movnti %%edx, 60(%3)\n"
9478 + " movnti %%eax, %%es:56(%3)\n"
9479 + " movnti %%edx, %%es:60(%3)\n"
9483 @@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing
9489 ".section .fixup,\"ax\"\n"
9490 "9: lea 0(%%eax,%0,4),%0\n"
9492 @@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing
9495 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9496 - : "1"(to), "2"(from), "0"(size)
9497 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9498 : "eax", "edx", "memory");
9501 @@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n
9504 __asm__ __volatile__(
9505 + " movw %w6, %%ds\n"
9507 "0: movl 32(%4), %%eax\n"
9509 @@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_n
9511 "2: movl 0(%4), %%eax\n"
9512 "21: movl 4(%4), %%edx\n"
9513 - " movnti %%eax, 0(%3)\n"
9514 - " movnti %%edx, 4(%3)\n"
9515 + " movnti %%eax, %%es:0(%3)\n"
9516 + " movnti %%edx, %%es:4(%3)\n"
9517 "3: movl 8(%4), %%eax\n"
9518 "31: movl 12(%4),%%edx\n"
9519 - " movnti %%eax, 8(%3)\n"
9520 - " movnti %%edx, 12(%3)\n"
9521 + " movnti %%eax, %%es:8(%3)\n"
9522 + " movnti %%edx, %%es:12(%3)\n"
9523 "4: movl 16(%4), %%eax\n"
9524 "41: movl 20(%4), %%edx\n"
9525 - " movnti %%eax, 16(%3)\n"
9526 - " movnti %%edx, 20(%3)\n"
9527 + " movnti %%eax, %%es:16(%3)\n"
9528 + " movnti %%edx, %%es:20(%3)\n"
9529 "10: movl 24(%4), %%eax\n"
9530 "51: movl 28(%4), %%edx\n"
9531 - " movnti %%eax, 24(%3)\n"
9532 - " movnti %%edx, 28(%3)\n"
9533 + " movnti %%eax, %%es:24(%3)\n"
9534 + " movnti %%edx, %%es:28(%3)\n"
9535 "11: movl 32(%4), %%eax\n"
9536 "61: movl 36(%4), %%edx\n"
9537 - " movnti %%eax, 32(%3)\n"
9538 - " movnti %%edx, 36(%3)\n"
9539 + " movnti %%eax, %%es:32(%3)\n"
9540 + " movnti %%edx, %%es:36(%3)\n"
9541 "12: movl 40(%4), %%eax\n"
9542 "71: movl 44(%4), %%edx\n"
9543 - " movnti %%eax, 40(%3)\n"
9544 - " movnti %%edx, 44(%3)\n"
9545 + " movnti %%eax, %%es:40(%3)\n"
9546 + " movnti %%edx, %%es:44(%3)\n"
9547 "13: movl 48(%4), %%eax\n"
9548 "81: movl 52(%4), %%edx\n"
9549 - " movnti %%eax, 48(%3)\n"
9550 - " movnti %%edx, 52(%3)\n"
9551 + " movnti %%eax, %%es:48(%3)\n"
9552 + " movnti %%edx, %%es:52(%3)\n"
9553 "14: movl 56(%4), %%eax\n"
9554 "91: movl 60(%4), %%edx\n"
9555 - " movnti %%eax, 56(%3)\n"
9556 - " movnti %%edx, 60(%3)\n"
9557 + " movnti %%eax, %%es:56(%3)\n"
9558 + " movnti %%edx, %%es:60(%3)\n"
9562 @@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n
9568 ".section .fixup,\"ax\"\n"
9569 "9: lea 0(%%eax,%0,4),%0\n"
9571 @@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n
9574 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9575 - : "1"(to), "2"(from), "0"(size)
9576 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9577 : "eax", "edx", "memory");
9580 @@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n
9582 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
9583 unsigned long size);
9584 -unsigned long __copy_user_intel(void __user *to, const void *from,
9585 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
9586 + unsigned long size);
9587 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
9588 unsigned long size);
9589 unsigned long __copy_user_zeroing_intel_nocache(void *to,
9590 const void __user *from, unsigned long size);
9591 #endif /* CONFIG_X86_INTEL_USERCOPY */
9593 /* Generic arbitrary sized copy. */
9594 -#define __copy_user(to,from,size) \
9596 - int __d0, __d1, __d2; \
9597 - __asm__ __volatile__( \
9604 - "4: rep; movsb\n" \
9608 - " .align 2,0x90\n" \
9609 - "0: rep; movsl\n" \
9611 - "1: rep; movsb\n" \
9613 - ".section .fixup,\"ax\"\n" \
9614 - "5: addl %3,%0\n" \
9616 - "3: lea 0(%3,%0,4),%0\n" \
9619 - ".section __ex_table,\"a\"\n" \
9621 - " .long 4b,5b\n" \
9622 - " .long 0b,3b\n" \
9623 - " .long 1b,2b\n" \
9625 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9626 - : "3"(size), "0"(size), "1"(to), "2"(from) \
9630 -#define __copy_user_zeroing(to,from,size) \
9632 - int __d0, __d1, __d2; \
9633 - __asm__ __volatile__( \
9640 - "4: rep; movsb\n" \
9644 - " .align 2,0x90\n" \
9645 - "0: rep; movsl\n" \
9647 - "1: rep; movsb\n" \
9649 - ".section .fixup,\"ax\"\n" \
9650 - "5: addl %3,%0\n" \
9652 - "3: lea 0(%3,%0,4),%0\n" \
9654 - " pushl %%eax\n" \
9655 - " xorl %%eax,%%eax\n" \
9661 - ".section __ex_table,\"a\"\n" \
9663 - " .long 4b,5b\n" \
9664 - " .long 0b,3b\n" \
9665 - " .long 1b,6b\n" \
9667 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9668 - : "3"(size), "0"(size), "1"(to), "2"(from) \
9671 +static unsigned long
9672 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
9674 + int __d0, __d1, __d2;
9676 + __asm__ __volatile__(
9677 + " movw %w8,%%es\n"
9688 + " .align 2,0x90\n"
9695 + ".section .fixup,\"ax\"\n"
9698 + "3: lea 0(%3,%0,4),%0\n"
9701 + ".section __ex_table,\"a\"\n"
9707 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9708 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9713 +static unsigned long
9714 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
9716 + int __d0, __d1, __d2;
9718 + __asm__ __volatile__(
9719 + " movw %w8,%%ds\n"
9730 + " .align 2,0x90\n"
9737 + ".section .fixup,\"ax\"\n"
9740 + "3: lea 0(%3,%0,4),%0\n"
9743 + ".section __ex_table,\"a\"\n"
9749 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9750 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9755 +static unsigned long
9756 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
9758 + int __d0, __d1, __d2;
9760 + __asm__ __volatile__(
9761 + " movw %w8,%%ds\n"
9772 + " .align 2,0x90\n"
9779 + ".section .fixup,\"ax\"\n"
9782 + "3: lea 0(%3,%0,4),%0\n"
9785 + " xorl %%eax,%%eax\n"
9791 + ".section __ex_table,\"a\"\n"
9797 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9798 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9803 unsigned long __copy_to_user_ll(void __user *to, const void *from,
9805 @@ -774,9 +965,9 @@ survive:
9808 if (movsl_is_ok(to, from, n))
9809 - __copy_user(to, from, n);
9810 + n = __generic_copy_to_user(to, from, n);
9812 - n = __copy_user_intel(to, from, n);
9813 + n = __generic_copy_to_user_intel(to, from, n);
9816 EXPORT_SYMBOL(__copy_to_user_ll);
9817 @@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void *
9820 if (movsl_is_ok(to, from, n))
9821 - __copy_user_zeroing(to, from, n);
9822 + n = __copy_user_zeroing(to, from, n);
9824 n = __copy_user_zeroing_intel(to, from, n);
9826 @@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero
9829 if (movsl_is_ok(to, from, n))
9830 - __copy_user(to, from, n);
9831 + n = __generic_copy_from_user(to, from, n);
9833 - n = __copy_user_intel((void __user *)to,
9834 + n = __generic_copy_from_user_intel((void __user *)to,
9835 (const void *)from, n);
9838 @@ -809,9 +1000,9 @@ unsigned long __copy_from_user_ll_nocach
9840 #ifdef CONFIG_X86_INTEL_USERCOPY
9841 if ( n > 64 && cpu_has_xmm2)
9842 - n = __copy_user_zeroing_intel_nocache(to, from, n);
9843 + n = __copy_user_zeroing_intel_nocache(to, from, n);
9845 - __copy_user_zeroing(to, from, n);
9846 + n = __copy_user_zeroing(to, from, n);
9848 __copy_user_zeroing(to, from, n);
9850 @@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach
9852 #ifdef CONFIG_X86_INTEL_USERCOPY
9853 if ( n > 64 && cpu_has_xmm2)
9854 - n = __copy_user_intel_nocache(to, from, n);
9855 + n = __copy_user_intel_nocache(to, from, n);
9857 - __copy_user(to, from, n);
9858 + n = __generic_copy_from_user(to, from, n);
9860 - __copy_user(to, from, n);
9861 + n = __generic_copy_from_user(to, from, n);
9865 @@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us
9868 EXPORT_SYMBOL(copy_from_user);
9870 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9871 +void __set_fs(mm_segment_t x, int cpu)
9873 + unsigned long limit = x.seg;
9876 + current_thread_info()->addr_limit = x;
9877 + if (likely(limit))
9878 + limit = (limit - 1UL) >> PAGE_SHIFT;
9879 + pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
9880 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
9883 +void set_fs(mm_segment_t x)
9885 + __set_fs(x, get_cpu());
9886 + put_cpu_no_resched();
9889 +void set_fs(mm_segment_t x)
9891 + current_thread_info()->addr_limit = x;
9895 +EXPORT_SYMBOL(set_fs);
9896 diff -urNp linux-2.6.24.4/arch/x86/mach-voyager/voyager_basic.c linux-2.6.24.4/arch/x86/mach-voyager/voyager_basic.c
9897 --- linux-2.6.24.4/arch/x86/mach-voyager/voyager_basic.c 2008-03-24 14:49:18.000000000 -0400
9898 +++ linux-2.6.24.4/arch/x86/mach-voyager/voyager_basic.c 2008-03-26 20:21:08.000000000 -0400
9899 @@ -130,7 +130,7 @@ voyager_memory_detect(int region, __u32
9902 unsigned long map_addr;
9903 - unsigned long old;
9906 if(region >= CLICK_ENTRIES) {
9907 printk("Voyager: Illegal ClickMap region %d\n", region);
9908 @@ -144,7 +144,7 @@ voyager_memory_detect(int region, __u32
9910 /* steal page 0 for this */
9912 - pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9913 + pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9915 /* now clear everything out but page 0 */
9916 map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
9917 diff -urNp linux-2.6.24.4/arch/x86/mach-voyager/voyager_smp.c linux-2.6.24.4/arch/x86/mach-voyager/voyager_smp.c
9918 --- linux-2.6.24.4/arch/x86/mach-voyager/voyager_smp.c 2008-03-24 14:49:18.000000000 -0400
9919 +++ linux-2.6.24.4/arch/x86/mach-voyager/voyager_smp.c 2008-03-26 20:21:08.000000000 -0400
9920 @@ -554,6 +554,10 @@ do_boot_cpu(__u8 cpu)
9921 __u32 *hijack_vector;
9922 __u32 start_phys_address = setup_trampoline();
9924 +#ifdef CONFIG_PAX_KERNEXEC
9925 + unsigned long cr0;
9928 /* There's a clever trick to this: The linux trampoline is
9929 * compiled to begin at absolute location zero, so make the
9930 * address zero but have the data segment selector compensate
9931 @@ -573,7 +577,17 @@ do_boot_cpu(__u8 cpu)
9934 per_cpu(current_task, cpu) = idle;
9935 - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9937 +#ifdef CONFIG_PAX_KERNEXEC
9938 + pax_open_kernel(cr0);
9941 + early_gdt_descr.address = get_cpu_gdt_table(cpu);
9943 +#ifdef CONFIG_PAX_KERNEXEC
9944 + pax_close_kernel(cr0);
9949 /* Note: Don't modify initial ss override */
9950 @@ -1277,7 +1291,7 @@ smp_local_timer_interrupt(void)
9951 per_cpu(prof_counter, cpu);
9954 - update_process_times(user_mode_vm(get_irq_regs()));
9955 + update_process_times(user_mode(get_irq_regs()));
9958 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
9959 diff -urNp linux-2.6.24.4/arch/x86/mm/boot_ioremap_32.c linux-2.6.24.4/arch/x86/mm/boot_ioremap_32.c
9960 --- linux-2.6.24.4/arch/x86/mm/boot_ioremap_32.c 2008-03-24 14:49:18.000000000 -0400
9961 +++ linux-2.6.24.4/arch/x86/mm/boot_ioremap_32.c 2008-03-26 20:21:08.000000000 -0400
9963 * Written by Dave Hansen <haveblue@us.ibm.com>
9968 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
9969 - * keeps that from happening. If anyone has a better way, I'm listening.
9971 - * boot_pte_t is defined only if this all works correctly
9974 -#undef CONFIG_X86_PAE
9975 #undef CONFIG_PARAVIRT
9976 #include <asm/page.h>
9977 #include <asm/pgtable.h>
9978 #include <asm/tlbflush.h>
9979 #include <linux/init.h>
9980 #include <linux/stddef.h>
9983 - * I'm cheating here. It is known that the two boot PTE pages are
9984 - * allocated next to each other. I'm pretending that they're just
9988 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
9990 -static unsigned long boot_pte_index(unsigned long vaddr)
9992 - return __pa(vaddr) >> PAGE_SHIFT;
9995 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
9997 - boot_pte_t* boot_pg = (boot_pte_t*)pg0;
9998 - return &boot_pg[boot_pte_index((unsigned long)address)];
10000 +#include <linux/sched.h>
10003 * This is only for a caller who is clever enough to page-align
10004 * phys_addr and virtual_source, and who also has a preference
10005 * about which virtual address from which to steal ptes
10007 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
10008 - void* virtual_source)
10009 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
10010 + char* virtual_source)
10014 - char *vaddr = virtual_source;
10020 + unsigned long vaddr = (unsigned long)virtual_source;
10022 + pgd = pgd_offset_k(vaddr);
10023 + pud = pud_offset(pgd, vaddr);
10024 + pmd = pmd_offset(pud, vaddr);
10025 + pte = pte_offset_kernel(pmd, vaddr);
10027 - pte = boot_vaddr_to_pte(virtual_source);
10028 for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
10029 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
10030 - __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
10031 + __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
10035 diff -urNp linux-2.6.24.4/arch/x86/mm/extable_32.c linux-2.6.24.4/arch/x86/mm/extable_32.c
10036 --- linux-2.6.24.4/arch/x86/mm/extable_32.c 2008-03-24 14:49:18.000000000 -0400
10037 +++ linux-2.6.24.4/arch/x86/mm/extable_32.c 2008-03-26 20:21:08.000000000 -0400
10040 #include <linux/module.h>
10041 #include <linux/spinlock.h>
10042 +#include <linux/sort.h>
10043 #include <asm/uaccess.h>
10046 + * The exception table needs to be sorted so that the binary
10047 + * search that we use to find entries in it works properly.
10048 + * This is used both for the kernel exception table and for
10049 + * the exception tables of modules that get loaded.
10051 +static int cmp_ex(const void *a, const void *b)
10053 + const struct exception_table_entry *x = a, *y = b;
10055 + /* avoid overflow */
10056 + if (x->insn > y->insn)
10058 + if (x->insn < y->insn)
10063 +static void swap_ex(void *a, void *b, int size)
10065 + struct exception_table_entry t, *x = a, *y = b;
10067 +#ifdef CONFIG_PAX_KERNEXEC
10068 + unsigned long cr0;
10073 +#ifdef CONFIG_PAX_KERNEXEC
10074 + pax_open_kernel(cr0);
10080 +#ifdef CONFIG_PAX_KERNEXEC
10081 + pax_close_kernel(cr0);
10086 +void sort_extable(struct exception_table_entry *start,
10087 + struct exception_table_entry *finish)
10089 + sort(start, finish - start, sizeof(struct exception_table_entry),
10090 + cmp_ex, swap_ex);
10093 int fixup_exception(struct pt_regs *regs)
10095 const struct exception_table_entry *fixup;
10097 #ifdef CONFIG_PNPBIOS
10098 - if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
10099 + if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
10101 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
10102 extern u32 pnp_bios_is_utter_crap;
10103 diff -urNp linux-2.6.24.4/arch/x86/mm/extable_64.c linux-2.6.24.4/arch/x86/mm/extable_64.c
10104 --- linux-2.6.24.4/arch/x86/mm/extable_64.c 2008-03-24 14:49:18.000000000 -0400
10105 +++ linux-2.6.24.4/arch/x86/mm/extable_64.c 2008-03-26 20:21:08.000000000 -0400
10108 #include <linux/module.h>
10109 #include <linux/spinlock.h>
10110 +#include <linux/sort.h>
10111 #include <linux/init.h>
10112 #include <asm/uaccess.h>
10115 + * The exception table needs to be sorted so that the binary
10116 + * search that we use to find entries in it works properly.
10117 + * This is used both for the kernel exception table and for
10118 + * the exception tables of modules that get loaded.
10120 +static int cmp_ex(const void *a, const void *b)
10122 + const struct exception_table_entry *x = a, *y = b;
10124 + /* avoid overflow */
10125 + if (x->insn > y->insn)
10127 + if (x->insn < y->insn)
10132 +static void swap_ex(void *a, void *b, int size)
10134 + struct exception_table_entry t, *x = a, *y = b;
10136 +#ifdef CONFIG_PAX_KERNEXEC
10137 + unsigned long cr0;
10142 +#ifdef CONFIG_PAX_KERNEXEC
10143 + pax_open_kernel(cr0);
10149 +#ifdef CONFIG_PAX_KERNEXEC
10150 + pax_close_kernel(cr0);
10155 +void sort_extable(struct exception_table_entry *start,
10156 + struct exception_table_entry *finish)
10158 + sort(start, finish - start, sizeof(struct exception_table_entry),
10159 + cmp_ex, swap_ex);
10162 /* Simple binary search */
10163 const struct exception_table_entry *
10164 search_extable(const struct exception_table_entry *first,
10165 diff -urNp linux-2.6.24.4/arch/x86/mm/fault_32.c linux-2.6.24.4/arch/x86/mm/fault_32.c
10166 --- linux-2.6.24.4/arch/x86/mm/fault_32.c 2008-03-24 14:49:18.000000000 -0400
10167 +++ linux-2.6.24.4/arch/x86/mm/fault_32.c 2008-03-26 20:21:16.000000000 -0400
10168 @@ -26,10 +26,14 @@
10169 #include <linux/uaccess.h>
10170 #include <linux/kdebug.h>
10171 #include <linux/kprobes.h>
10172 +#include <linux/unistd.h>
10173 +#include <linux/compiler.h>
10174 +#include <linux/binfmts.h>
10176 #include <asm/system.h>
10177 #include <asm/desc.h>
10178 #include <asm/segment.h>
10179 +#include <asm/tlbflush.h>
10181 extern void die(const char *,struct pt_regs *,long);
10183 @@ -39,7 +43,7 @@ static inline int notify_page_fault(stru
10186 /* kprobe_running() needs smp_processor_id() */
10187 - if (!user_mode_vm(regs)) {
10188 + if (!user_mode(regs)) {
10190 if (kprobe_running() && kprobe_fault_handler(regs, 14))
10192 @@ -74,7 +78,8 @@ static inline unsigned long get_segment_
10194 unsigned long eip = regs->eip;
10195 unsigned seg = regs->xcs & 0xffff;
10196 - u32 seg_ar, seg_limit, base, *desc;
10197 + u32 seg_ar, seg_limit, base;
10198 + struct desc_struct *desc;
10200 /* Unlikely, but must come before segment checks. */
10201 if (unlikely(regs->eflags & VM_MASK)) {
10202 @@ -88,7 +93,7 @@ static inline unsigned long get_segment_
10204 /* By far the most common cases. */
10205 if (likely(SEGMENT_IS_FLAT_CODE(seg)))
10207 + return seg == __KERNEL_CS ? ktla_ktva(eip) : eip;
10209 /* Check the segment exists, is within the current LDT/GDT size,
10210 that kernel/user (ring 0..3) has the appropriate privilege,
10211 @@ -103,21 +108,24 @@ static inline unsigned long get_segment_
10212 /* Get the GDT/LDT descriptor base.
10213 When you look for races in this code remember that
10214 LDT and other horrors are only used in user space. */
10215 - if (seg & (1<<2)) {
10216 + if (seg & SEGMENT_LDT) {
10217 /* Must lock the LDT while reading it. */
10218 mutex_lock(¤t->mm->context.lock);
10219 - desc = current->mm->context.ldt;
10220 - desc = (void *)desc + (seg & ~7);
10221 + if ((seg >> 3) >= current->mm->context.size) {
10222 + mutex_unlock(¤t->mm->context.lock);
10224 + return 1; /* So that returned eip > *eip_limit. */
10226 + desc = ¤t->mm->context.ldt[seg >> 3];
10228 /* Must disable preemption while reading the GDT. */
10229 - desc = (u32 *)get_cpu_gdt_table(get_cpu());
10230 - desc = (void *)desc + (seg & ~7);
10231 + desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
10234 /* Decode the code segment base from the descriptor */
10235 - base = get_desc_base((unsigned long *)desc);
10236 + base = get_desc_base(desc);
10238 - if (seg & (1<<2)) {
10239 + if (seg & SEGMENT_LDT) {
10240 mutex_unlock(¤t->mm->context.lock);
10243 @@ -216,6 +224,30 @@ static noinline void force_sig_info_faul
10245 fastcall void do_invalid_op(struct pt_regs *, unsigned long);
10247 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10248 +static int pax_handle_fetch_fault(struct pt_regs *regs);
10251 +#ifdef CONFIG_PAX_PAGEEXEC
10252 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
10258 + pgd = pgd_offset(mm, address);
10259 + if (!pgd_present(*pgd))
10261 + pud = pud_offset(pgd, address);
10262 + if (!pud_present(*pud))
10264 + pmd = pmd_offset(pud, address);
10265 + if (!pmd_present(*pmd))
10271 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
10273 unsigned index = pgd_index(address);
10274 @@ -299,19 +331,26 @@ fastcall void __kprobes do_page_fault(st
10275 struct task_struct *tsk;
10276 struct mm_struct *mm;
10277 struct vm_area_struct * vma;
10278 - unsigned long address;
10279 int write, si_code;
10283 +#ifdef CONFIG_PAX_PAGEEXEC
10286 + unsigned char pte_mask;
10289 + /* get the address */
10290 + const unsigned long address = read_cr2();
10293 * We can fault from pretty much anywhere, with unknown IRQ state.
10295 trace_hardirqs_fixup();
10297 - /* get the address */
10298 - address = read_cr2();
10303 si_code = SEGV_MAPERR;
10305 @@ -348,14 +387,12 @@ fastcall void __kprobes do_page_fault(st
10306 if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
10307 local_irq_enable();
10312 * If we're in an interrupt, have no user context or are running in an
10313 * atomic region then we must not take the fault..
10315 if (in_atomic() || !mm)
10316 - goto bad_area_nosemaphore;
10317 + goto bad_area_nopax;
10319 /* When running in the kernel we expect faults to occur only to
10320 * addresses in user space. All other faults represent errors in the
10321 @@ -375,10 +412,104 @@ fastcall void __kprobes do_page_fault(st
10322 if (!down_read_trylock(&mm->mmap_sem)) {
10323 if ((error_code & 4) == 0 &&
10324 !search_exception_tables(regs->eip))
10325 - goto bad_area_nosemaphore;
10326 + goto bad_area_nopax;
10327 down_read(&mm->mmap_sem);
10330 +#ifdef CONFIG_PAX_PAGEEXEC
10331 + if (nx_enabled || (error_code & 5) != 5 || (regs->eflags & X86_EFLAGS_VM) ||
10332 + !(mm->pax_flags & MF_PAX_PAGEEXEC))
10333 + goto not_pax_fault;
10335 + /* PaX: it's our fault, let's handle it if we can */
10337 + /* PaX: take a look at read faults before acquiring any locks */
10338 + if (unlikely(!(error_code & 2) && (regs->eip == address))) {
10339 + /* instruction fetch attempt from a protected page in user mode */
10340 + up_read(&mm->mmap_sem);
10342 +#ifdef CONFIG_PAX_EMUTRAMP
10343 + switch (pax_handle_fetch_fault(regs)) {
10349 + pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
10350 + do_group_exit(SIGKILL);
10353 + pmd = pax_get_pmd(mm, address);
10354 + if (unlikely(!pmd))
10355 + goto not_pax_fault;
10357 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
10358 + if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
10359 + pte_unmap_unlock(pte, ptl);
10360 + goto not_pax_fault;
10363 + if (unlikely((error_code & 2) && !pte_write(*pte))) {
10364 + /* write attempt to a protected page in user mode */
10365 + pte_unmap_unlock(pte, ptl);
10366 + goto not_pax_fault;
10370 + if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
10372 + if (likely(address > get_limit(regs->xcs)))
10375 + set_pte(pte, pte_mkread(*pte));
10376 + __flush_tlb_one(address);
10377 + pte_unmap_unlock(pte, ptl);
10378 + up_read(&mm->mmap_sem);
10382 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
10385 + * PaX: fill DTLB with user rights and retry
10387 + __asm__ __volatile__ (
10388 +#ifdef CONFIG_PAX_MEMORY_UDEREF
10389 + "movw %w4,%%es\n"
10392 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
10394 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
10395 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
10396 + * page fault when examined during a TLB load attempt. this is true not only
10397 + * for PTEs holding a non-present entry but also present entries that will
10398 + * raise a page fault (such as those set up by PaX, or the copy-on-write
10399 + * mechanism). in effect it means that we do *not* need to flush the TLBs
10400 + * for our target pages since their PTEs are simply not in the TLBs at all.
10402 + * the best thing in omitting it is that we gain around 15-20% speed in the
10403 + * fast path of the page fault handler and can get rid of tracing since we
10404 + * can no longer flush unintended entries.
10408 + "testb $0,%%es:(%0)\n"
10410 +#ifdef CONFIG_PAX_MEMORY_UDEREF
10415 + : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
10416 + : "memory", "cc");
10417 + pte_unmap_unlock(pte, ptl);
10418 + up_read(&mm->mmap_sem);
10424 vma = find_vma(mm, address);
10427 @@ -396,6 +527,12 @@ fastcall void __kprobes do_page_fault(st
10428 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
10432 +#ifdef CONFIG_PAX_SEGMEXEC
10433 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
10437 if (expand_stack(vma, address))
10440 @@ -405,6 +542,8 @@ fastcall void __kprobes do_page_fault(st
10442 si_code = SEGV_ACCERR;
10444 + if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC))
10446 switch (error_code & 3) {
10447 default: /* 3: write, present */
10449 @@ -458,6 +597,49 @@ bad_area:
10450 up_read(&mm->mmap_sem);
10452 bad_area_nosemaphore:
10454 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10455 + if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
10457 + * It's possible to have interrupts off here.
10459 + local_irq_enable();
10461 +#ifdef CONFIG_PAX_PAGEEXEC
10462 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
10463 + ((nx_enabled && ((error_code & 16) || !(error_code & 3)) && (regs->eip == address)))) {
10465 +#ifdef CONFIG_PAX_EMUTRAMP
10466 + switch (pax_handle_fetch_fault(regs)) {
10472 + pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
10473 + do_group_exit(SIGKILL);
10477 +#ifdef CONFIG_PAX_SEGMEXEC
10478 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
10480 +#ifdef CONFIG_PAX_EMUTRAMP
10481 + switch (pax_handle_fetch_fault(regs)) {
10487 + pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
10488 + do_group_exit(SIGKILL);
10496 /* User mode accesses just cause a SIGSEGV */
10497 if (error_code & 4) {
10499 @@ -495,7 +677,7 @@ bad_area_nosemaphore:
10500 if (boot_cpu_data.f00f_bug) {
10503 - nr = (address - idt_descr.address) >> 3;
10504 + nr = (address - (unsigned long)idt_descr.address) >> 3;
10507 do_invalid_op(regs, 0);
10508 @@ -528,18 +710,34 @@ no_context:
10509 __typeof__(pte_val(__pte(0))) page;
10511 #ifdef CONFIG_X86_PAE
10512 - if (error_code & 16) {
10513 - pte_t *pte = lookup_address(address);
10514 + if (nx_enabled && (error_code & 16)) {
10515 + pte = lookup_address(address);
10517 if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
10518 printk(KERN_CRIT "kernel tried to execute "
10519 "NX-protected page - exploit attempt? "
10520 - "(uid: %d)\n", current->uid);
10521 + "(uid: %d, task: %s, pid: %d)\n",
10522 + tsk->uid, tsk->comm, task_pid_nr(tsk));
10525 if (address < PAGE_SIZE)
10526 printk(KERN_ALERT "BUG: unable to handle kernel NULL "
10527 "pointer dereference");
10529 +#ifdef CONFIG_PAX_KERNEXEC
10530 +#ifdef CONFIG_MODULES
10531 + else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
10533 + else if (init_mm.start_code <= address && address < init_mm.end_code)
10535 + if (tsk->signal->curr_ip)
10536 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
10537 + NIPQUAD(tsk->signal->curr_ip), tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid);
10539 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
10540 + tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid);
10544 printk(KERN_ALERT "BUG: unable to handle kernel paging"
10546 @@ -585,19 +783,18 @@ no_context:
10547 tsk->thread.error_code = error_code;
10548 die("Oops", regs, error_code);
10550 - do_exit(SIGKILL);
10551 + do_group_exit(SIGKILL);
10554 * We ran out of memory, or some other thing happened to us that made
10555 * us unable to handle the page fault gracefully.
10558 - up_read(&mm->mmap_sem);
10559 if (is_global_init(tsk)) {
10561 - down_read(&mm->mmap_sem);
10564 + up_read(&mm->mmap_sem);
10565 printk("VM: killing process %s\n", tsk->comm);
10566 if (error_code & 4)
10567 do_group_exit(SIGKILL);
10568 @@ -657,3 +854,92 @@ void vmalloc_sync_all(void)
10569 start = address + PGDIR_SIZE;
10573 +#ifdef CONFIG_PAX_EMUTRAMP
10575 + * PaX: decide what to do with offenders (regs->eip = fault address)
10577 + * returns 1 when task should be killed
10578 + * 2 when gcc trampoline was detected
10580 +static int pax_handle_fetch_fault(struct pt_regs *regs)
10584 + if (regs->eflags & X86_EFLAGS_VM)
10587 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10590 + do { /* PaX: gcc trampoline emulation #1 */
10591 + unsigned char mov1, mov2;
10592 + unsigned short jmp;
10593 + unsigned long addr1, addr2;
10595 + err = get_user(mov1, (unsigned char __user *)regs->eip);
10596 + err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
10597 + err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
10598 + err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
10599 + err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
10604 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10605 + regs->ecx = addr1;
10606 + regs->eax = addr2;
10607 + regs->eip = addr2;
10612 + do { /* PaX: gcc trampoline emulation #2 */
10613 + unsigned char mov, jmp;
10614 + unsigned long addr1, addr2;
10616 + err = get_user(mov, (unsigned char __user *)regs->eip);
10617 + err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
10618 + err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
10619 + err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
10624 + if (mov == 0xB9 && jmp == 0xE9) {
10625 + regs->ecx = addr1;
10626 + regs->eip += addr2 + 10;
10631 + return 1; /* PaX in action */
10635 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10636 +void pax_report_insns(void *pc, void *sp)
10640 + printk(KERN_ERR "PAX: bytes at PC: ");
10641 + for (i = 0; i < 20; i++) {
10643 + if (get_user(c, (unsigned char __user *)pc+i))
10646 + printk("%02x ", c);
10650 + printk(KERN_ERR "PAX: bytes at SP-4: ");
10651 + for (i = -1; i < 20; i++) {
10653 + if (get_user(c, (unsigned long __user *)sp+i))
10654 + printk("???????? ");
10656 + printk("%08lx ", c);
10661 diff -urNp linux-2.6.24.4/arch/x86/mm/fault_64.c linux-2.6.24.4/arch/x86/mm/fault_64.c
10662 --- linux-2.6.24.4/arch/x86/mm/fault_64.c 2008-03-24 14:49:18.000000000 -0400
10663 +++ linux-2.6.24.4/arch/x86/mm/fault_64.c 2008-03-26 20:21:08.000000000 -0400
10665 #include <linux/uaccess.h>
10666 #include <linux/kdebug.h>
10667 #include <linux/kprobes.h>
10668 +#include <linux/binfmts.h>
10670 #include <asm/system.h>
10671 #include <asm/pgalloc.h>
10672 @@ -285,6 +286,163 @@ static int vmalloc_fault(unsigned long a
10676 +#ifdef CONFIG_PAX_EMUTRAMP
10677 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
10681 + do { /* PaX: gcc trampoline emulation #1 */
10682 + unsigned char mov1, mov2;
10683 + unsigned short jmp;
10684 + unsigned int addr1, addr2;
10686 + if ((regs->rip + 11) >> 32)
10689 + err = get_user(mov1, (unsigned char __user *)regs->rip);
10690 + err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1));
10691 + err |= get_user(mov2, (unsigned char __user *)(regs->rip + 5));
10692 + err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6));
10693 + err |= get_user(jmp, (unsigned short __user *)(regs->rip + 10));
10698 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10699 + regs->rcx = addr1;
10700 + regs->rax = addr2;
10701 + regs->rip = addr2;
10706 + do { /* PaX: gcc trampoline emulation #2 */
10707 + unsigned char mov, jmp;
10708 + unsigned int addr1, addr2;
10710 + if ((regs->rip + 9) >> 32)
10713 + err = get_user(mov, (unsigned char __user *)regs->rip);
10714 + err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1));
10715 + err |= get_user(jmp, (unsigned char __user *)(regs->rip + 5));
10716 + err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6));
10721 + if (mov == 0xB9 && jmp == 0xE9) {
10722 + regs->rcx = addr1;
10723 + regs->rip = (unsigned int)(regs->rip + addr2 + 10);
10728 + return 1; /* PaX in action */
10731 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
10735 + do { /* PaX: gcc trampoline emulation #1 */
10736 + unsigned short mov1, mov2, jmp1;
10737 + unsigned char jmp2;
10738 + unsigned int addr1;
10739 + unsigned long addr2;
10741 + err = get_user(mov1, (unsigned short __user *)regs->rip);
10742 + err |= get_user(addr1, (unsigned int __user *)(regs->rip + 2));
10743 + err |= get_user(mov2, (unsigned short __user *)(regs->rip + 6));
10744 + err |= get_user(addr2, (unsigned long __user *)(regs->rip + 8));
10745 + err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 16));
10746 + err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 18));
10751 + if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10752 + regs->r11 = addr1;
10753 + regs->r10 = addr2;
10754 + regs->rip = addr1;
10759 + do { /* PaX: gcc trampoline emulation #2 */
10760 + unsigned short mov1, mov2, jmp1;
10761 + unsigned char jmp2;
10762 + unsigned long addr1, addr2;
10764 + err = get_user(mov1, (unsigned short __user *)regs->rip);
10765 + err |= get_user(addr1, (unsigned long __user *)(regs->rip + 2));
10766 + err |= get_user(mov2, (unsigned short __user *)(regs->rip + 10));
10767 + err |= get_user(addr2, (unsigned long __user *)(regs->rip + 12));
10768 + err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 20));
10769 + err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 22));
10774 + if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10775 + regs->r11 = addr1;
10776 + regs->r10 = addr2;
10777 + regs->rip = addr1;
10782 + return 1; /* PaX in action */
10786 + * PaX: decide what to do with offenders (regs->rip = fault address)
10788 + * returns 1 when task should be killed
10789 + * 2 when gcc trampoline was detected
10791 +static int pax_handle_fetch_fault(struct pt_regs *regs)
10793 + if (regs->eflags & X86_EFLAGS_VM)
10796 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10799 + if (regs->cs == __USER32_CS || (regs->cs & (1<<2)))
10800 + return pax_handle_fetch_fault_32(regs);
10802 + return pax_handle_fetch_fault_64(regs);
10806 +#ifdef CONFIG_PAX_PAGEEXEC
10807 +void pax_report_insns(void *pc, void *sp)
10811 + printk(KERN_ERR "PAX: bytes at PC: ");
10812 + for (i = 0; i < 20; i++) {
10814 + if (get_user(c, (unsigned char __user *)pc+i))
10817 + printk("%02x ", c);
10821 + printk(KERN_ERR "PAX: bytes at SP-8: ");
10822 + for (i = -1; i < 10; i++) {
10824 + if (get_user(c, (unsigned long __user *)sp+i))
10825 + printk("???????????????? ");
10827 + printk("%016lx ", c);
10833 int show_unhandled_signals = 1;
10836 @@ -405,7 +563,7 @@ asmlinkage void __kprobes do_page_fault(
10838 if (!(vma->vm_flags & VM_GROWSDOWN))
10840 - if (error_code & 4) {
10841 + if (error_code & PF_USER) {
10842 /* Allow userspace just enough access below the stack pointer
10843 * to let the 'enter' instruction work.
10845 @@ -421,6 +579,8 @@ asmlinkage void __kprobes do_page_fault(
10847 info.si_code = SEGV_ACCERR;
10849 + if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
10851 switch (error_code & (PF_PROT|PF_WRITE)) {
10852 default: /* 3: write, present */
10854 @@ -472,6 +632,21 @@ bad_area_nosemaphore:
10856 local_irq_enable();
10858 +#ifdef CONFIG_PAX_PAGEEXEC
10859 + if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & PF_INSTR)) {
10861 +#ifdef CONFIG_PAX_EMUTRAMP
10862 + switch (pax_handle_fetch_fault(regs)) {
10868 + pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
10869 + do_group_exit(SIGKILL);
10873 if (is_prefetch(regs, address, error_code))
10876 @@ -489,8 +664,8 @@ bad_area_nosemaphore:
10877 printk_ratelimit()) {
10879 "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
10880 - tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
10881 - tsk->comm, tsk->pid, address, regs->rip,
10882 + task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
10883 + tsk->comm, task_pid_nr(tsk), address, regs->rip,
10884 regs->rsp, error_code);
10887 @@ -534,6 +709,9 @@ no_context:
10889 if (address < PAGE_SIZE)
10890 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
10891 + else if (error_code & PF_INSTR)
10892 + printk(KERN_ALERT "PAX: %s:%d, uid/euid: %u/%u, invalid execution attempt",
10893 + tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid);
10895 printk(KERN_ALERT "Unable to handle kernel paging request");
10896 printk(" at %016lx RIP: \n" KERN_ALERT,address);
10897 @@ -546,7 +724,7 @@ no_context:
10898 /* Executive summary in case the body of the oops scrolled away */
10899 printk(KERN_EMERG "CR2: %016lx\n", address);
10901 - do_exit(SIGKILL);
10902 + do_group_exit(SIGKILL);
10905 * We ran out of memory, or some other thing happened to us that made
10906 diff -urNp linux-2.6.24.4/arch/x86/mm/highmem_32.c linux-2.6.24.4/arch/x86/mm/highmem_32.c
10907 --- linux-2.6.24.4/arch/x86/mm/highmem_32.c 2008-03-24 14:49:18.000000000 -0400
10908 +++ linux-2.6.24.4/arch/x86/mm/highmem_32.c 2008-03-26 20:21:08.000000000 -0400
10909 @@ -31,6 +31,10 @@ void *kmap_atomic_prot(struct page *page
10910 enum fixed_addresses idx;
10911 unsigned long vaddr;
10913 +#ifdef CONFIG_PAX_KERNEXEC
10914 + unsigned long cr0;
10917 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
10918 pagefault_disable();
10920 @@ -40,7 +44,17 @@ void *kmap_atomic_prot(struct page *page
10921 idx = type + KM_TYPE_NR*smp_processor_id();
10922 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10923 BUG_ON(!pte_none(*(kmap_pte-idx)));
10925 +#ifdef CONFIG_PAX_KERNEXEC
10926 + pax_open_kernel(cr0);
10929 set_pte(kmap_pte-idx, mk_pte(page, prot));
10931 +#ifdef CONFIG_PAX_KERNEXEC
10932 + pax_close_kernel(cr0);
10935 arch_flush_lazy_mmu_mode();
10937 return (void *)vaddr;
10938 @@ -56,15 +70,29 @@ void kunmap_atomic(void *kvaddr, enum km
10939 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
10940 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
10942 +#ifdef CONFIG_PAX_KERNEXEC
10943 + unsigned long cr0;
10947 * Force other mappings to Oops if they'll try to access this pte
10948 * without first remap it. Keeping stale mappings around is a bad idea
10949 * also, in case the page changes cacheability attributes or becomes
10950 * a protected page in a hypervisor.
10952 - if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
10953 + if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
10955 +#ifdef CONFIG_PAX_KERNEXEC
10956 + pax_open_kernel(cr0);
10959 kpte_clear_flush(kmap_pte-idx, vaddr);
10962 +#ifdef CONFIG_PAX_KERNEXEC
10963 + pax_close_kernel(cr0);
10967 #ifdef CONFIG_DEBUG_HIGHMEM
10968 BUG_ON(vaddr < PAGE_OFFSET);
10969 BUG_ON(vaddr >= (unsigned long)high_memory);
10970 @@ -83,11 +111,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
10971 enum fixed_addresses idx;
10972 unsigned long vaddr;
10974 +#ifdef CONFIG_PAX_KERNEXEC
10975 + unsigned long cr0;
10978 pagefault_disable();
10980 idx = type + KM_TYPE_NR*smp_processor_id();
10981 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10983 +#ifdef CONFIG_PAX_KERNEXEC
10984 + pax_open_kernel(cr0);
10987 set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
10989 +#ifdef CONFIG_PAX_KERNEXEC
10990 + pax_close_kernel(cr0);
10993 arch_flush_lazy_mmu_mode();
10995 return (void*) vaddr;
10996 diff -urNp linux-2.6.24.4/arch/x86/mm/hugetlbpage.c linux-2.6.24.4/arch/x86/mm/hugetlbpage.c
10997 --- linux-2.6.24.4/arch/x86/mm/hugetlbpage.c 2008-03-24 14:49:18.000000000 -0400
10998 +++ linux-2.6.24.4/arch/x86/mm/hugetlbpage.c 2008-03-26 20:21:08.000000000 -0400
10999 @@ -229,13 +229,18 @@ static unsigned long hugetlb_get_unmappe
11001 struct mm_struct *mm = current->mm;
11002 struct vm_area_struct *vma;
11003 - unsigned long start_addr;
11004 + unsigned long start_addr, pax_task_size = TASK_SIZE;
11006 +#ifdef CONFIG_PAX_SEGMEXEC
11007 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11008 + pax_task_size = SEGMEXEC_TASK_SIZE;
11011 if (len > mm->cached_hole_size) {
11012 - start_addr = mm->free_area_cache;
11013 + start_addr = mm->free_area_cache;
11015 - start_addr = TASK_UNMAPPED_BASE;
11016 - mm->cached_hole_size = 0;
11017 + start_addr = mm->mmap_base;
11018 + mm->cached_hole_size = 0;
11022 @@ -243,13 +248,13 @@ full_search:
11024 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
11025 /* At this point: (!vma || addr < vma->vm_end). */
11026 - if (TASK_SIZE - len < addr) {
11027 + if (pax_task_size - len < addr) {
11029 * Start a new search - just in case we missed
11032 - if (start_addr != TASK_UNMAPPED_BASE) {
11033 - start_addr = TASK_UNMAPPED_BASE;
11034 + if (start_addr != mm->mmap_base) {
11035 + start_addr = mm->mmap_base;
11036 mm->cached_hole_size = 0;
11039 @@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe
11041 struct mm_struct *mm = current->mm;
11042 struct vm_area_struct *vma, *prev_vma;
11043 - unsigned long base = mm->mmap_base, addr = addr0;
11044 + unsigned long base = mm->mmap_base, addr;
11045 unsigned long largest_hole = mm->cached_hole_size;
11046 - int first_time = 1;
11048 /* don't allow allocations above current base */
11049 if (mm->free_area_cache > base)
11050 @@ -283,7 +287,7 @@ static unsigned long hugetlb_get_unmappe
11052 mm->free_area_cache = base;
11056 /* make sure it can fit in the remaining address space */
11057 if (mm->free_area_cache < len)
11059 @@ -325,22 +329,26 @@ try_again:
11063 - * if hint left us with no space for the requested
11064 - * mapping then try again:
11066 - if (first_time) {
11067 - mm->free_area_cache = base;
11068 - largest_hole = 0;
11073 * A failed mmap() very likely causes application failure,
11074 * so fall back to the bottom-up function here. This scenario
11075 * can happen with large stack limits and large mmap()
11078 - mm->free_area_cache = TASK_UNMAPPED_BASE;
11080 +#ifdef CONFIG_PAX_SEGMEXEC
11081 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11082 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
11086 + mm->mmap_base = TASK_UNMAPPED_BASE;
11088 +#ifdef CONFIG_PAX_RANDMMAP
11089 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11090 + mm->mmap_base += mm->delta_mmap;
11093 + mm->free_area_cache = mm->mmap_base;
11094 mm->cached_hole_size = ~0UL;
11095 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
11096 len, pgoff, flags);
11097 @@ -348,6 +356,7 @@ fail:
11099 * Restore the topdown base:
11101 + mm->mmap_base = base;
11102 mm->free_area_cache = base;
11103 mm->cached_hole_size = ~0UL;
11105 @@ -360,10 +369,17 @@ hugetlb_get_unmapped_area(struct file *f
11107 struct mm_struct *mm = current->mm;
11108 struct vm_area_struct *vma;
11109 + unsigned long pax_task_size = TASK_SIZE;
11111 if (len & ~HPAGE_MASK)
11113 - if (len > TASK_SIZE)
11115 +#ifdef CONFIG_PAX_SEGMEXEC
11116 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11117 + pax_task_size = SEGMEXEC_TASK_SIZE;
11120 + if (len > pax_task_size)
11123 if (flags & MAP_FIXED) {
11124 @@ -375,7 +391,7 @@ hugetlb_get_unmapped_area(struct file *f
11126 addr = ALIGN(addr, HPAGE_SIZE);
11127 vma = find_vma(mm, addr);
11128 - if (TASK_SIZE - len >= addr &&
11129 + if (pax_task_size - len >= addr &&
11130 (!vma || addr + len <= vma->vm_start))
11133 diff -urNp linux-2.6.24.4/arch/x86/mm/init_32.c linux-2.6.24.4/arch/x86/mm/init_32.c
11134 --- linux-2.6.24.4/arch/x86/mm/init_32.c 2008-03-24 14:49:18.000000000 -0400
11135 +++ linux-2.6.24.4/arch/x86/mm/init_32.c 2008-03-26 20:21:08.000000000 -0400
11137 #include <asm/tlbflush.h>
11138 #include <asm/sections.h>
11139 #include <asm/paravirt.h>
11140 +#include <asm/desc.h>
11142 unsigned int __VMALLOC_RESERVE = 128 << 20;
11144 @@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn
11145 static int noinline do_test_wp_bit(void);
11148 - * Creates a middle page table and puts a pointer to it in the
11149 - * given global directory entry. This only returns the gd entry
11150 - * in non-PAE compilation mode, since the middle layer is folded.
11152 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
11155 - pmd_t *pmd_table;
11157 -#ifdef CONFIG_X86_PAE
11158 - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
11159 - pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
11161 - paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT);
11162 - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
11163 - pud = pud_offset(pgd, 0);
11164 - if (pmd_table != pmd_offset(pud, 0))
11168 - pud = pud_offset(pgd, 0);
11169 - pmd_table = pmd_offset(pud, 0);
11170 - return pmd_table;
11174 * Create a page table and place a pointer to it in a middle page
11177 @@ -95,7 +70,11 @@ static pte_t * __init one_page_table_ini
11178 (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
11180 paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
11181 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
11182 + set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
11184 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
11186 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
11189 @@ -116,6 +95,7 @@ static pte_t * __init one_page_table_ini
11190 static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
11195 int pgd_idx, pmd_idx;
11196 unsigned long vaddr;
11197 @@ -126,8 +106,13 @@ static void __init page_table_range_init
11198 pgd = pgd_base + pgd_idx;
11200 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
11201 - pmd = one_md_table_init(pgd);
11202 - pmd = pmd + pmd_index(vaddr);
11203 + pud = pud_offset(pgd, vaddr);
11204 + pmd = pmd_offset(pud, vaddr);
11206 +#ifdef CONFIG_X86_PAE
11207 + paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
11210 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
11211 one_page_table_init(pmd);
11213 @@ -137,11 +122,23 @@ static void __init page_table_range_init
11217 -static inline int is_kernel_text(unsigned long addr)
11218 +static inline int is_kernel_text(unsigned long start, unsigned long end)
11220 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
11223 + unsigned long etext;
11225 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
11226 + etext = ktva_ktla((unsigned long)&MODULES_END);
11228 + etext = (unsigned long)&_etext;
11231 + if ((start > ktla_ktva(etext) ||
11232 + end <= ktla_ktva((unsigned long)_stext)) &&
11233 + (start > ktla_ktva((unsigned long)_einittext) ||
11234 + end <= ktla_ktva((unsigned long)_sinittext)) &&
11235 + (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
11241 @@ -153,25 +150,29 @@ static void __init kernel_physical_mappi
11248 - int pgd_idx, pmd_idx, pte_ofs;
11249 + unsigned int pgd_idx, pmd_idx, pte_ofs;
11251 pgd_idx = pgd_index(PAGE_OFFSET);
11252 pgd = pgd_base + pgd_idx;
11255 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
11256 - pmd = one_md_table_init(pgd);
11257 - if (pfn >= max_low_pfn)
11259 + for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
11260 + pud = pud_offset(pgd, 0);
11261 + pmd = pmd_offset(pud, 0);
11263 +#ifdef CONFIG_X86_PAE
11264 + paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
11267 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
11268 - unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
11269 + unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
11271 /* Map with big pages if possible, otherwise create normal page tables. */
11272 - if (cpu_has_pse) {
11273 - unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
11274 - if (is_kernel_text(address) || is_kernel_text(address2))
11275 + if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
11276 + if (is_kernel_text(address, address + PMD_SIZE))
11277 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
11279 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
11280 @@ -183,7 +184,7 @@ static void __init kernel_physical_mappi
11282 pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
11283 pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
11284 - if (is_kernel_text(address))
11285 + if (is_kernel_text(address, address + PAGE_SIZE))
11286 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
11288 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
11289 @@ -338,9 +339,9 @@ static void __init set_highmem_pages_ini
11290 #define set_highmem_pages_init(bad_ppro) do { } while (0)
11291 #endif /* CONFIG_HIGHMEM */
11293 -unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
11294 +unsigned long long __PAGE_KERNEL __read_only = _PAGE_KERNEL;
11295 EXPORT_SYMBOL(__PAGE_KERNEL);
11296 -unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
11297 +unsigned long long __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
11300 extern void __init remap_numa_kva(void);
11301 @@ -351,26 +352,10 @@ extern void __init remap_numa_kva(void);
11302 void __init native_pagetable_setup_start(pgd_t *base)
11304 #ifdef CONFIG_X86_PAE
11308 - * Init entries of the first-level page table to the
11309 - * zero page, if they haven't already been set up.
11311 - * In a normal native boot, we'll be running on a
11312 - * pagetable rooted in swapper_pg_dir, but not in PAE
11313 - * mode, so this will end up clobbering the mappings
11314 - * for the lower 24Mbytes of the address space,
11315 - * without affecting the kernel address space.
11317 - for (i = 0; i < USER_PTRS_PER_PGD; i++)
11318 - set_pgd(&base[i],
11319 - __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
11322 - /* Make sure kernel address space is empty so that a pagetable
11323 - will be allocated for it. */
11324 - memset(&base[USER_PTRS_PER_PGD], 0,
11325 - KERNEL_PGD_PTRS * sizeof(pgd_t));
11326 + for (i = 0; i < PTRS_PER_PGD; i++)
11327 + paravirt_alloc_pd(__pa(swapper_pm_dir + i) >> PAGE_SHIFT);
11329 paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT);
11331 @@ -378,16 +363,6 @@ void __init native_pagetable_setup_start
11333 void __init native_pagetable_setup_done(pgd_t *base)
11335 -#ifdef CONFIG_X86_PAE
11337 - * Add low memory identity-mappings - SMP needs it when
11338 - * starting up on an AP from real-mode. In the non-PAE
11339 - * case we already have these mappings through head.S.
11340 - * All user-space mappings are explicitly cleared after
11343 - set_pgd(&base[0], base[USER_PTRS_PER_PGD]);
11348 @@ -449,12 +424,12 @@ static void __init pagetable_init (void)
11349 * Swap suspend & friends need this for resume because things like the intel-agp
11350 * driver might have split up a kernel 4MB mapping.
11352 -char __nosavedata swsusp_pg_dir[PAGE_SIZE]
11353 +pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
11354 __attribute__ ((aligned (PAGE_SIZE)));
11356 static inline void save_pg_dir(void)
11358 - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
11359 + clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
11362 static inline void save_pg_dir(void)
11363 @@ -483,12 +458,11 @@ void zap_low_mappings (void)
11367 -int nx_enabled = 0;
11370 #ifdef CONFIG_X86_PAE
11372 -static int disable_nx __initdata = 0;
11373 -u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
11374 +u64 __supported_pte_mask __read_only = ~_PAGE_NX;
11375 EXPORT_SYMBOL_GPL(__supported_pte_mask);
11378 @@ -499,36 +473,31 @@ EXPORT_SYMBOL_GPL(__supported_pte_mask);
11382 +#if !defined(CONFIG_PAX_PAGEEXEC)
11383 static int __init noexec_setup(char *str)
11385 if (!str || !strcmp(str, "on")) {
11386 - if (cpu_has_nx) {
11387 - __supported_pte_mask |= _PAGE_NX;
11392 } else if (!strcmp(str,"off")) {
11394 - __supported_pte_mask &= ~_PAGE_NX;
11401 early_param("noexec", noexec_setup);
11404 static void __init set_nx(void)
11406 - unsigned int v[4], l, h;
11407 + if (!nx_enabled && cpu_has_nx) {
11410 - if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
11411 - cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
11412 - if ((v[3] & (1 << 20)) && !disable_nx) {
11413 - rdmsr(MSR_EFER, l, h);
11415 - wrmsr(MSR_EFER, l, h);
11417 - __supported_pte_mask |= _PAGE_NX;
11419 + __supported_pte_mask &= ~_PAGE_NX;
11420 + rdmsr(MSR_EFER, l, h);
11422 + wrmsr(MSR_EFER, l, h);
11426 @@ -581,14 +550,6 @@ void __init paging_init(void)
11428 load_cr3(swapper_pg_dir);
11430 -#ifdef CONFIG_X86_PAE
11432 - * We will bail out later - printk doesn't work right now so
11433 - * the user would just see a hanging kernel.
11436 - set_in_cr4(X86_CR4_PAE);
11441 @@ -659,7 +620,7 @@ void __init mem_init(void)
11442 set_highmem_pages_init(bad_ppro);
11444 codesize = (unsigned long) &_etext - (unsigned long) &_text;
11445 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
11446 + datasize = (unsigned long) &_edata - (unsigned long) &_data;
11447 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
11449 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
11450 @@ -704,10 +665,10 @@ void __init mem_init(void)
11451 (unsigned long)&__init_begin, (unsigned long)&__init_end,
11452 ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
11454 - (unsigned long)&_etext, (unsigned long)&_edata,
11455 - ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
11456 + (unsigned long)&_data, (unsigned long)&_edata,
11457 + ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
11459 - (unsigned long)&_text, (unsigned long)&_etext,
11460 + ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
11461 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
11463 #ifdef CONFIG_HIGHMEM
11464 @@ -718,10 +679,6 @@ void __init mem_init(void)
11465 BUG_ON((unsigned long)high_memory > VMALLOC_START);
11466 #endif /* double-sanity-check paranoia */
11468 -#ifdef CONFIG_X86_PAE
11469 - if (!cpu_has_pae)
11470 - panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
11472 if (boot_cpu_data.wp_works_ok < 0)
11475 @@ -839,6 +796,46 @@ void free_init_pages(char *what, unsigne
11477 void free_initmem(void)
11480 +#ifdef CONFIG_PAX_KERNEXEC
11481 + /* PaX: limit KERNEL_CS to actual size */
11482 + unsigned long addr, limit;
11489 +#ifdef CONFIG_MODULES
11490 + limit = ktva_ktla((unsigned long)&MODULES_END);
11492 + limit = (unsigned long)&_etext;
11494 + limit = (limit - 1UL) >> PAGE_SHIFT;
11496 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
11497 + pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
11498 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b);
11501 + /* PaX: make KERNEL_CS read-only */
11502 + for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
11503 + pgd = pgd_offset_k(addr);
11504 + pud = pud_offset(pgd, addr);
11505 + pmd = pmd_offset(pud, addr);
11506 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
11508 +#ifdef CONFIG_X86_PAE
11509 + for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
11510 + pgd = pgd_offset_k(addr);
11511 + pud = pud_offset(pgd, addr);
11512 + pmd = pmd_offset(pud, addr);
11513 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11519 free_init_pages("unused kernel memory",
11520 (unsigned long)(&__init_begin),
11521 (unsigned long)(&__init_end));
11522 diff -urNp linux-2.6.24.4/arch/x86/mm/init_64.c linux-2.6.24.4/arch/x86/mm/init_64.c
11523 --- linux-2.6.24.4/arch/x86/mm/init_64.c 2008-03-24 14:49:18.000000000 -0400
11524 +++ linux-2.6.24.4/arch/x86/mm/init_64.c 2008-03-26 20:21:08.000000000 -0400
11526 #include <asm/sections.h>
11529 -#define Dprintk(x...)
11530 +#define Dprintk(x...) do {} while (0)
11533 const struct dma_mapping_ops* dma_ops;
11534 @@ -121,6 +121,10 @@ static __init void set_pte_phys(unsigned
11536 pte_t *pte, new_pte;
11538 +#ifdef CONFIG_PAX_KERNEXEC
11539 + unsigned long cr0;
11542 Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
11544 pgd = pgd_offset_k(vaddr);
11545 @@ -131,7 +135,7 @@ static __init void set_pte_phys(unsigned
11546 pud = pud_offset(pgd, vaddr);
11547 if (pud_none(*pud)) {
11548 pmd = (pmd_t *) spp_getpage();
11549 - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
11550 + set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
11551 if (pmd != pmd_offset(pud, 0)) {
11552 printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
11554 @@ -140,7 +144,7 @@ static __init void set_pte_phys(unsigned
11555 pmd = pmd_offset(pud, vaddr);
11556 if (pmd_none(*pmd)) {
11557 pte = (pte_t *) spp_getpage();
11558 - set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
11559 + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
11560 if (pte != pte_offset_kernel(pmd, 0)) {
11561 printk("PAGETABLE BUG #02!\n");
11563 @@ -152,8 +156,17 @@ static __init void set_pte_phys(unsigned
11564 if (!pte_none(*pte) &&
11565 pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
11568 +#ifdef CONFIG_PAX_KERNEXEC
11569 + pax_open_kernel(cr0);
11572 set_pte(pte, new_pte);
11574 +#ifdef CONFIG_PAX_KERNEXEC
11575 + pax_close_kernel(cr0);
11579 * It's enough to flush this one mapping.
11580 * (PGE mappings get flushed as well)
11581 @@ -225,7 +238,7 @@ __meminit void *early_ioremap(unsigned l
11583 for (i = 0; i < pmds; i++, addr += PMD_SIZE)
11584 set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE));
11586 + __flush_tlb_all();
11587 return (void *)vaddr;
11590 @@ -246,7 +259,7 @@ __meminit void early_iounmap(void *addr,
11591 pmd = level2_kernel_pgt + pmd_index(vaddr);
11592 for (i = 0; i < pmds; i++)
11593 pmd_clear(pmd + i);
11595 + __flush_tlb_all();
11598 static void __meminit
11599 @@ -314,7 +327,7 @@ static void __meminit phys_pud_init(pud_
11600 spin_unlock(&init_mm.page_table_lock);
11601 unmap_low_page(pmd);
11604 + __flush_tlb_all();
11607 static void __init find_early_table_space(unsigned long end)
11608 @@ -583,6 +596,39 @@ void free_init_pages(char *what, unsigne
11610 void free_initmem(void)
11613 +#ifdef CONFIG_PAX_KERNEXEC
11614 + unsigned long addr, end;
11619 + /* PaX: make kernel code/rodata read-only, rest non-executable */
11620 + for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_TEXT_SIZE; addr += PMD_SIZE) {
11621 + pgd = pgd_offset_k(addr);
11622 + pud = pud_offset(pgd, addr);
11623 + pmd = pmd_offset(pud, addr);
11624 + if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
11625 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
11627 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11630 + addr = (unsigned long)__va(__pa(__START_KERNEL_map));
11631 + end = addr + KERNEL_TEXT_SIZE;
11632 + for (; addr < end; addr += PMD_SIZE) {
11633 + pgd = pgd_offset_k(addr);
11634 + pud = pud_offset(pgd, addr);
11635 + pmd = pmd_offset(pud, addr);
11636 + if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
11637 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
11639 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11645 free_init_pages("unused kernel memory",
11646 (unsigned long)(&__init_begin),
11647 (unsigned long)(&__init_end));
11648 @@ -730,7 +776,7 @@ int in_gate_area_no_task(unsigned long a
11650 const char *arch_vma_name(struct vm_area_struct *vma)
11652 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
11653 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
11655 if (vma == &gate_vma)
11656 return "[vsyscall]";
11657 diff -urNp linux-2.6.24.4/arch/x86/mm/ioremap_32.c linux-2.6.24.4/arch/x86/mm/ioremap_32.c
11658 --- linux-2.6.24.4/arch/x86/mm/ioremap_32.c 2008-03-24 14:49:18.000000000 -0400
11659 +++ linux-2.6.24.4/arch/x86/mm/ioremap_32.c 2008-03-26 20:21:08.000000000 -0400
11660 @@ -67,8 +67,11 @@ void __iomem * __ioremap(unsigned long p
11664 - prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY
11665 - | _PAGE_ACCESSED | flags);
11666 +#ifdef CONFIG_X86_PAE
11667 + prot = __pgprot((__PAGE_KERNEL | _PAGE_GLOBAL | flags) & __supported_pte_mask);
11669 + prot = __pgprot(__PAGE_KERNEL | _PAGE_GLOBAL | flags);
11673 * Mappings have to be page-aligned
11674 diff -urNp linux-2.6.24.4/arch/x86/mm/ioremap_64.c linux-2.6.24.4/arch/x86/mm/ioremap_64.c
11675 --- linux-2.6.24.4/arch/x86/mm/ioremap_64.c 2008-03-24 14:49:18.000000000 -0400
11676 +++ linux-2.6.24.4/arch/x86/mm/ioremap_64.c 2008-03-26 20:21:08.000000000 -0400
11677 @@ -48,7 +48,7 @@ ioremap_change_attr(unsigned long phys_a
11678 * Must use a address here and not struct page because the phys addr
11679 * can be a in hole between nodes and not have an memmap entry.
11681 - err = change_page_attr_addr(vaddr,npages,__pgprot(__PAGE_KERNEL|flags));
11682 + err = change_page_attr_addr(vaddr,npages,__pgprot((__PAGE_KERNEL|_PAGE_GLOBAL|flags) & __supported_pte_mask));
11684 global_flush_tlb();
11686 @@ -103,8 +103,8 @@ void __iomem * __ioremap(unsigned long p
11690 - pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_GLOBAL
11691 - | _PAGE_DIRTY | _PAGE_ACCESSED | flags);
11692 + pgprot = __pgprot((__PAGE_KERNEL | _PAGE_GLOBAL | flags) & __supported_pte_mask);
11695 * Mappings have to be page-aligned
11697 @@ -126,7 +126,7 @@ void __iomem * __ioremap(unsigned long p
11700 if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) {
11701 - area->flags &= 0xffffff;
11702 + area->flags &= 0xfffff;
11706 @@ -199,7 +199,7 @@ void iounmap(volatile void __iomem *addr
11708 /* Reset the direct mapping. Can block */
11709 if (p->flags >> 20)
11710 - ioremap_change_attr(p->phys_addr, p->size, 0);
11711 + ioremap_change_attr(p->phys_addr, p->size - PAGE_SIZE, 0);
11713 /* Finally remove it */
11714 o = remove_vm_area((void *)addr);
11715 diff -urNp linux-2.6.24.4/arch/x86/mm/mmap_32.c linux-2.6.24.4/arch/x86/mm/mmap_32.c
11716 --- linux-2.6.24.4/arch/x86/mm/mmap_32.c 2008-03-24 14:49:18.000000000 -0400
11717 +++ linux-2.6.24.4/arch/x86/mm/mmap_32.c 2008-03-26 20:21:08.000000000 -0400
11718 @@ -35,12 +35,18 @@
11719 * Leave an at least ~128 MB hole.
11721 #define MIN_GAP (128*1024*1024)
11722 -#define MAX_GAP (TASK_SIZE/6*5)
11723 +#define MAX_GAP (pax_task_size/6*5)
11725 static inline unsigned long mmap_base(struct mm_struct *mm)
11727 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
11728 unsigned long random_factor = 0;
11729 + unsigned long pax_task_size = TASK_SIZE;
11731 +#ifdef CONFIG_PAX_SEGMEXEC
11732 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11733 + pax_task_size = SEGMEXEC_TASK_SIZE;
11736 if (current->flags & PF_RANDOMIZE)
11737 random_factor = get_random_int() % (1024*1024);
11738 @@ -50,7 +56,7 @@ static inline unsigned long mmap_base(st
11739 else if (gap > MAX_GAP)
11742 - return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
11743 + return PAGE_ALIGN(pax_task_size - gap - random_factor);
11747 @@ -66,11 +72,30 @@ void arch_pick_mmap_layout(struct mm_str
11748 if (sysctl_legacy_va_layout ||
11749 (current->personality & ADDR_COMPAT_LAYOUT) ||
11750 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
11752 +#ifdef CONFIG_PAX_SEGMEXEC
11753 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11754 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
11758 mm->mmap_base = TASK_UNMAPPED_BASE;
11760 +#ifdef CONFIG_PAX_RANDMMAP
11761 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11762 + mm->mmap_base += mm->delta_mmap;
11765 mm->get_unmapped_area = arch_get_unmapped_area;
11766 mm->unmap_area = arch_unmap_area;
11768 mm->mmap_base = mmap_base(mm);
11770 +#ifdef CONFIG_PAX_RANDMMAP
11771 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11772 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
11775 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
11776 mm->unmap_area = arch_unmap_area_topdown;
11778 diff -urNp linux-2.6.24.4/arch/x86/mm/mmap_64.c linux-2.6.24.4/arch/x86/mm/mmap_64.c
11779 --- linux-2.6.24.4/arch/x86/mm/mmap_64.c 2008-03-24 14:49:18.000000000 -0400
11780 +++ linux-2.6.24.4/arch/x86/mm/mmap_64.c 2008-03-26 20:21:08.000000000 -0400
11781 @@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
11782 unsigned rnd = get_random_int() & 0xfffffff;
11783 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
11786 +#ifdef CONFIG_PAX_RANDMMAP
11787 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11788 + mm->mmap_base += mm->delta_mmap;
11791 mm->get_unmapped_area = arch_get_unmapped_area;
11792 mm->unmap_area = arch_unmap_area;
11794 diff -urNp linux-2.6.24.4/arch/x86/mm/numa_64.c linux-2.6.24.4/arch/x86/mm/numa_64.c
11795 --- linux-2.6.24.4/arch/x86/mm/numa_64.c 2008-03-24 14:49:18.000000000 -0400
11796 +++ linux-2.6.24.4/arch/x86/mm/numa_64.c 2008-03-26 20:21:08.000000000 -0400
11798 #include <asm/acpi.h>
11801 -#define Dprintk(x...)
11802 +#define Dprintk(x...) do {} while (0)
11805 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
11806 diff -urNp linux-2.6.24.4/arch/x86/mm/pageattr_32.c linux-2.6.24.4/arch/x86/mm/pageattr_32.c
11807 --- linux-2.6.24.4/arch/x86/mm/pageattr_32.c 2008-03-24 14:49:18.000000000 -0400
11808 +++ linux-2.6.24.4/arch/x86/mm/pageattr_32.c 2008-03-26 20:21:08.000000000 -0400
11810 #include <asm/tlbflush.h>
11811 #include <asm/pgalloc.h>
11812 #include <asm/sections.h>
11813 +#include <asm/desc.h>
11815 static DEFINE_SPINLOCK(cpa_lock);
11816 static struct list_head df_list = LIST_HEAD_INIT(df_list);
11817 @@ -37,16 +38,16 @@ pte_t *lookup_address(unsigned long addr
11820 static struct page *split_large_page(unsigned long address, pgprot_t prot,
11821 - pgprot_t ref_prot)
11822 + pgprot_t ref_prot, unsigned long flags)
11825 unsigned long addr;
11829 - spin_unlock_irq(&cpa_lock);
11830 + spin_unlock_irqrestore(&cpa_lock, flags);
11831 base = alloc_pages(GFP_KERNEL, 0);
11832 - spin_lock_irq(&cpa_lock);
11833 + spin_lock_irqsave(&cpa_lock, flags);
11837 @@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns
11839 unsigned long flags;
11841 +#ifdef CONFIG_PAX_KERNEXEC
11842 + unsigned long cr0;
11844 + pax_open_kernel(cr0);
11847 set_pte_atomic(kpte, pte); /* change init_mm */
11849 +#ifdef CONFIG_PAX_KERNEXEC
11850 + pax_close_kernel(cr0);
11853 if (SHARED_KERNEL_PMD)
11856 @@ -126,7 +138,7 @@ static inline void revert_page(struct pa
11860 - ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
11861 + ((address & LARGE_PAGE_MASK) < ktla_ktva((unsigned long)&_etext))
11862 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
11865 @@ -143,7 +155,7 @@ static inline void save_page(struct page
11869 -__change_page_attr(struct page *page, pgprot_t prot)
11870 +__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags)
11873 unsigned long address;
11874 @@ -167,13 +179,20 @@ __change_page_attr(struct page *page, pg
11875 struct page *split;
11878 - ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
11879 + ((address & LARGE_PAGE_MASK) < ktla_ktva((unsigned long)&_etext))
11880 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
11881 - split = split_large_page(address, prot, ref_prot);
11882 + split = split_large_page(address, prot, ref_prot, flags);
11885 - set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
11886 - kpte_page = split;
11887 + if (pte_huge(*kpte)) {
11888 + set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
11889 + kpte_page = split;
11891 + __free_pages(split, 0);
11892 + kpte = lookup_address(address);
11893 + kpte_page = virt_to_page(kpte);
11894 + set_pte_atomic(kpte, mk_pte(page, prot));
11897 page_private(kpte_page)++;
11898 } else if (!pte_huge(*kpte)) {
11899 @@ -225,7 +244,7 @@ int change_page_attr(struct page *page,
11901 spin_lock_irqsave(&cpa_lock, flags);
11902 for (i = 0; i < numpages; i++, page++) {
11903 - err = __change_page_attr(page, prot);
11904 + err = __change_page_attr(page, prot, flags);
11908 diff -urNp linux-2.6.24.4/arch/x86/mm/pageattr_64.c linux-2.6.24.4/arch/x86/mm/pageattr_64.c
11909 --- linux-2.6.24.4/arch/x86/mm/pageattr_64.c 2008-03-24 14:49:18.000000000 -0400
11910 +++ linux-2.6.24.4/arch/x86/mm/pageattr_64.c 2008-03-26 20:21:08.000000000 -0400
11911 @@ -110,6 +110,10 @@ static void revert_page(unsigned long ad
11915 +#ifdef CONFIG_PAX_KERNEXEC
11916 + unsigned long cr0;
11919 pgd = pgd_offset_k(address);
11920 BUG_ON(pgd_none(*pgd));
11921 pud = pud_offset(pgd,address);
11922 @@ -119,8 +123,18 @@ static void revert_page(unsigned long ad
11923 pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT;
11924 large_pte = pfn_pte(pfn, ref_prot);
11925 large_pte = pte_mkhuge(large_pte);
11927 +#ifdef CONFIG_PAX_KERNEXEC
11928 + pax_open_kernel(cr0);
11931 set_pte((pte_t *)pmd, large_pte);
11934 +#ifdef CONFIG_PAX_KERNEXEC
11935 + pax_close_kernel(cr0);
11941 __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
11942 @@ -136,22 +150,36 @@ __change_page_attr(unsigned long address
11943 BUG_ON(PageLRU(kpte_page));
11944 BUG_ON(PageCompound(kpte_page));
11945 if (pgprot_val(prot) != pgprot_val(ref_prot)) {
11946 - if (!pte_huge(*kpte)) {
11947 - set_pte(kpte, pfn_pte(pfn, prot));
11949 + if (pte_huge(*kpte)) {
11951 * split_large_page will take the reference for this
11952 * change_page_attr on the split page.
11954 struct page *split;
11956 +#ifdef CONFIG_PAX_KERNEXEC
11957 + unsigned long cr0;
11960 ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
11961 split = split_large_page(address, prot, ref_prot2);
11964 pgprot_val(ref_prot2) &= ~_PAGE_NX;
11966 +#ifdef CONFIG_PAX_KERNEXEC
11967 + pax_open_kernel(cr0);
11970 set_pte(kpte, mk_pte(split, ref_prot2));
11972 +#ifdef CONFIG_PAX_KERNEXEC
11973 + pax_close_kernel(cr0);
11979 + set_pte(kpte, pfn_pte(pfn, prot));
11980 page_private(kpte_page)++;
11981 } else if (!pte_huge(*kpte)) {
11982 set_pte(kpte, pfn_pte(pfn, ref_prot));
11983 diff -urNp linux-2.6.24.4/arch/x86/mm/pgtable_32.c linux-2.6.24.4/arch/x86/mm/pgtable_32.c
11984 --- linux-2.6.24.4/arch/x86/mm/pgtable_32.c 2008-03-24 14:49:18.000000000 -0400
11985 +++ linux-2.6.24.4/arch/x86/mm/pgtable_32.c 2008-03-26 20:21:08.000000000 -0400
11986 @@ -83,6 +83,10 @@ static void set_pte_pfn(unsigned long va
11990 +#ifdef CONFIG_PAX_KERNEXEC
11991 + unsigned long cr0;
11994 pgd = swapper_pg_dir + pgd_index(vaddr);
11995 if (pgd_none(*pgd)) {
11997 @@ -99,11 +103,20 @@ static void set_pte_pfn(unsigned long va
12000 pte = pte_offset_kernel(pmd, vaddr);
12002 +#ifdef CONFIG_PAX_KERNEXEC
12003 + pax_open_kernel(cr0);
12006 if (pgprot_val(flags))
12007 set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
12009 pte_clear(&init_mm, vaddr, pte);
12011 +#ifdef CONFIG_PAX_KERNEXEC
12012 + pax_close_kernel(cr0);
12016 * It's enough to flush this one mapping.
12017 * (PGE mappings get flushed as well)
12018 diff -urNp linux-2.6.24.4/arch/x86/oprofile/backtrace.c linux-2.6.24.4/arch/x86/oprofile/backtrace.c
12019 --- linux-2.6.24.4/arch/x86/oprofile/backtrace.c 2008-03-24 14:49:18.000000000 -0400
12020 +++ linux-2.6.24.4/arch/x86/oprofile/backtrace.c 2008-03-26 20:21:08.000000000 -0400
12021 @@ -37,7 +37,7 @@ static void backtrace_address(void *data
12022 unsigned int *depth = data;
12025 - oprofile_add_trace(addr);
12026 + oprofile_add_trace(ktla_ktva(addr));
12029 static struct stacktrace_ops backtrace_ops = {
12030 @@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
12031 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
12032 unsigned long stack = stack_pointer(regs);
12034 - if (!user_mode_vm(regs)) {
12035 + if (!user_mode(regs)) {
12037 dump_trace(NULL, regs, (unsigned long *)stack,
12038 &backtrace_ops, &depth);
12039 diff -urNp linux-2.6.24.4/arch/x86/oprofile/op_model_p4.c linux-2.6.24.4/arch/x86/oprofile/op_model_p4.c
12040 --- linux-2.6.24.4/arch/x86/oprofile/op_model_p4.c 2008-03-24 14:49:18.000000000 -0400
12041 +++ linux-2.6.24.4/arch/x86/oprofile/op_model_p4.c 2008-03-26 20:21:08.000000000 -0400
12042 @@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
12046 -static int inline addr_increment(void)
12047 +static inline int addr_increment(void)
12050 return smp_num_siblings == 2 ? 2 : 1;
12051 diff -urNp linux-2.6.24.4/arch/x86/pci/common.c linux-2.6.24.4/arch/x86/pci/common.c
12052 --- linux-2.6.24.4/arch/x86/pci/common.c 2008-03-24 14:49:18.000000000 -0400
12053 +++ linux-2.6.24.4/arch/x86/pci/common.c 2008-03-26 20:21:08.000000000 -0400
12054 @@ -331,7 +331,7 @@ static struct dmi_system_id __devinitdat
12055 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
12059 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
12062 struct pci_bus * __devinit pcibios_scan_root(int busnum)
12063 diff -urNp linux-2.6.24.4/arch/x86/pci/early.c linux-2.6.24.4/arch/x86/pci/early.c
12064 --- linux-2.6.24.4/arch/x86/pci/early.c 2008-03-24 14:49:18.000000000 -0400
12065 +++ linux-2.6.24.4/arch/x86/pci/early.c 2008-03-26 20:21:08.000000000 -0400
12067 /* Direct PCI access. This is used for PCI accesses in early boot before
12068 the PCI subsystem works. */
12070 -#define PDprintk(x...)
12071 +#define PDprintk(x...) do {} while (0)
12073 u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
12075 diff -urNp linux-2.6.24.4/arch/x86/pci/fixup.c linux-2.6.24.4/arch/x86/pci/fixup.c
12076 --- linux-2.6.24.4/arch/x86/pci/fixup.c 2008-03-24 14:49:18.000000000 -0400
12077 +++ linux-2.6.24.4/arch/x86/pci/fixup.c 2008-03-26 20:21:08.000000000 -0400
12078 @@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat
12079 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
12083 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12087 @@ -433,7 +433,7 @@ static struct dmi_system_id __devinitdat
12088 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
12092 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12095 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
12096 diff -urNp linux-2.6.24.4/arch/x86/pci/irq.c linux-2.6.24.4/arch/x86/pci/irq.c
12097 --- linux-2.6.24.4/arch/x86/pci/irq.c 2008-03-24 14:49:18.000000000 -0400
12098 +++ linux-2.6.24.4/arch/x86/pci/irq.c 2008-03-26 20:21:08.000000000 -0400
12099 @@ -528,7 +528,7 @@ static __init int intel_router_probe(str
12100 static struct pci_device_id __initdata pirq_440gx[] = {
12101 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
12102 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
12104 + { PCI_DEVICE(0, 0) }
12107 /* 440GX has a proprietary PIRQ router -- don't use it */
12108 @@ -1090,7 +1090,7 @@ static struct dmi_system_id __initdata p
12109 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
12113 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12116 static int __init pcibios_irq_init(void)
12117 diff -urNp linux-2.6.24.4/arch/x86/pci/pcbios.c linux-2.6.24.4/arch/x86/pci/pcbios.c
12118 --- linux-2.6.24.4/arch/x86/pci/pcbios.c 2008-03-24 14:49:18.000000000 -0400
12119 +++ linux-2.6.24.4/arch/x86/pci/pcbios.c 2008-03-26 20:21:08.000000000 -0400
12120 @@ -57,50 +57,124 @@ union bios32 {
12122 unsigned long address;
12123 unsigned short segment;
12124 -} bios32_indirect = { 0, __KERNEL_CS };
12125 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
12128 * Returns the entry point for the given service, NULL on error
12131 -static unsigned long bios32_service(unsigned long service)
12132 +static unsigned long __devinit bios32_service(unsigned long service)
12134 unsigned char return_code; /* %al */
12135 unsigned long address; /* %ebx */
12136 unsigned long length; /* %ecx */
12137 unsigned long entry; /* %edx */
12138 unsigned long flags;
12139 + struct desc_struct *gdt;
12141 +#ifdef CONFIG_PAX_KERNEXEC
12142 + unsigned long cr0;
12145 local_irq_save(flags);
12146 - __asm__("lcall *(%%edi); cld"
12148 + gdt = get_cpu_gdt_table(smp_processor_id());
12150 +#ifdef CONFIG_PAX_KERNEXEC
12151 + pax_open_kernel(cr0);
12154 + pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
12155 + (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
12156 + 0UL, 0xFFFFFUL, 0x9B, 0xC);
12157 + pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
12158 + (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
12159 + 0UL, 0xFFFFFUL, 0x93, 0xC);
12161 +#ifdef CONFIG_PAX_KERNEXEC
12162 + pax_close_kernel(cr0);
12165 + __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
12166 : "=a" (return_code),
12172 - "D" (&bios32_indirect));
12173 + "D" (&bios32_indirect),
12174 + "r"(__PCIBIOS_DS)
12177 +#ifdef CONFIG_PAX_KERNEXEC
12178 + pax_open_kernel(cr0);
12181 + gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
12182 + gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
12183 + gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
12184 + gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
12186 +#ifdef CONFIG_PAX_KERNEXEC
12187 + pax_close_kernel(cr0);
12190 local_irq_restore(flags);
12192 switch (return_code) {
12194 - return address + entry;
12195 - case 0x80: /* Not present */
12196 - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
12198 - default: /* Shouldn't happen */
12199 - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
12200 - service, return_code);
12203 + unsigned char flags;
12205 + printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
12206 + if (address >= 0xFFFF0 || length >= 0xFFFF0 - address || length <= entry) {
12207 + printk(KERN_WARNING "bios32_service: not valid\n");
12210 + address = address + PAGE_OFFSET;
12211 + length += 16UL; /* some BIOSs underreport this... */
12213 + if (length >= 64*1024*1024) {
12214 + length >>= PAGE_SHIFT;
12218 +#ifdef CONFIG_PAX_KERNEXEC
12219 + pax_open_kernel(cr0);
12222 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
12223 + gdt = get_cpu_gdt_table(cpu);
12224 + pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
12225 + (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
12226 + address, length, 0x9b, flags);
12227 + pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
12228 + (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
12229 + address, length, 0x93, flags);
12232 +#ifdef CONFIG_PAX_KERNEXEC
12233 + pax_close_kernel(cr0);
12238 + case 0x80: /* Not present */
12239 + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
12241 + default: /* Shouldn't happen */
12242 + printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
12243 + service, return_code);
12249 unsigned long address;
12250 unsigned short segment;
12251 -} pci_indirect = { 0, __KERNEL_CS };
12252 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
12254 -static int pci_bios_present;
12255 +static int pci_bios_present __read_only;
12257 static int __devinit check_pcibios(void)
12259 @@ -109,11 +183,13 @@ static int __devinit check_pcibios(void)
12260 unsigned long flags, pcibios_entry;
12262 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
12263 - pci_indirect.address = pcibios_entry + PAGE_OFFSET;
12264 + pci_indirect.address = pcibios_entry;
12266 local_irq_save(flags);
12268 - "lcall *(%%edi); cld\n\t"
12269 + __asm__("movw %w6, %%ds\n\t"
12270 + "lcall *%%ss:(%%edi); cld\n\t"
12276 @@ -122,7 +198,8 @@ static int __devinit check_pcibios(void)
12279 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
12280 - "D" (&pci_indirect)
12281 + "D" (&pci_indirect),
12282 + "r" (__PCIBIOS_DS)
12284 local_irq_restore(flags);
12286 @@ -158,7 +235,10 @@ static int __devinit pci_bios_find_devic
12288 unsigned short ret;
12290 - __asm__("lcall *(%%edi); cld\n\t"
12291 + __asm__("movw %w7, %%ds\n\t"
12292 + "lcall *%%ss:(%%edi); cld\n\t"
12298 @@ -168,7 +248,8 @@ static int __devinit pci_bios_find_devic
12302 - "D" (&pci_indirect));
12303 + "D" (&pci_indirect),
12304 + "r" (__PCIBIOS_DS));
12305 *bus = (bx >> 8) & 0xff;
12306 *device_fn = bx & 0xff;
12307 return (int) (ret & 0xff00) >> 8;
12308 @@ -188,7 +269,10 @@ static int pci_bios_read(unsigned int se
12312 - __asm__("lcall *(%%esi); cld\n\t"
12313 + __asm__("movw %w6, %%ds\n\t"
12314 + "lcall *%%ss:(%%esi); cld\n\t"
12320 @@ -197,10 +281,14 @@ static int pci_bios_read(unsigned int se
12321 : "1" (PCIBIOS_READ_CONFIG_BYTE),
12324 - "S" (&pci_indirect));
12325 + "S" (&pci_indirect),
12326 + "r" (__PCIBIOS_DS));
12329 - __asm__("lcall *(%%esi); cld\n\t"
12330 + __asm__("movw %w6, %%ds\n\t"
12331 + "lcall *%%ss:(%%esi); cld\n\t"
12337 @@ -209,10 +297,14 @@ static int pci_bios_read(unsigned int se
12338 : "1" (PCIBIOS_READ_CONFIG_WORD),
12341 - "S" (&pci_indirect));
12342 + "S" (&pci_indirect),
12343 + "r" (__PCIBIOS_DS));
12346 - __asm__("lcall *(%%esi); cld\n\t"
12347 + __asm__("movw %w6, %%ds\n\t"
12348 + "lcall *%%ss:(%%esi); cld\n\t"
12354 @@ -221,7 +313,8 @@ static int pci_bios_read(unsigned int se
12355 : "1" (PCIBIOS_READ_CONFIG_DWORD),
12358 - "S" (&pci_indirect));
12359 + "S" (&pci_indirect),
12360 + "r" (__PCIBIOS_DS));
12364 @@ -244,7 +337,10 @@ static int pci_bios_write(unsigned int s
12368 - __asm__("lcall *(%%esi); cld\n\t"
12369 + __asm__("movw %w6, %%ds\n\t"
12370 + "lcall *%%ss:(%%esi); cld\n\t"
12376 @@ -253,10 +349,14 @@ static int pci_bios_write(unsigned int s
12380 - "S" (&pci_indirect));
12381 + "S" (&pci_indirect),
12382 + "r" (__PCIBIOS_DS));
12385 - __asm__("lcall *(%%esi); cld\n\t"
12386 + __asm__("movw %w6, %%ds\n\t"
12387 + "lcall *%%ss:(%%esi); cld\n\t"
12393 @@ -265,10 +365,14 @@ static int pci_bios_write(unsigned int s
12397 - "S" (&pci_indirect));
12398 + "S" (&pci_indirect),
12399 + "r" (__PCIBIOS_DS));
12402 - __asm__("lcall *(%%esi); cld\n\t"
12403 + __asm__("movw %w6, %%ds\n\t"
12404 + "lcall *%%ss:(%%esi); cld\n\t"
12410 @@ -277,7 +381,8 @@ static int pci_bios_write(unsigned int s
12414 - "S" (&pci_indirect));
12415 + "S" (&pci_indirect),
12416 + "r" (__PCIBIOS_DS));
12420 @@ -430,10 +535,13 @@ struct irq_routing_table * pcibios_get_i
12422 DBG("PCI: Fetching IRQ routing table... ");
12423 __asm__("push %%es\n\t"
12424 + "movw %w8, %%ds\n\t"
12427 - "lcall *(%%esi); cld\n\t"
12428 + "lcall *%%ss:(%%esi); cld\n\t"
12435 @@ -444,7 +552,8 @@ struct irq_routing_table * pcibios_get_i
12438 "S" (&pci_indirect),
12441 + "r" (__PCIBIOS_DS)
12443 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
12445 @@ -468,7 +577,10 @@ int pcibios_set_irq_routing(struct pci_d
12449 - __asm__("lcall *(%%esi); cld\n\t"
12450 + __asm__("movw %w5, %%ds\n\t"
12451 + "lcall *%%ss:(%%esi); cld\n\t"
12457 @@ -476,7 +588,8 @@ int pcibios_set_irq_routing(struct pci_d
12458 : "0" (PCIBIOS_SET_PCI_HW_INT),
12459 "b" ((dev->bus->number << 8) | dev->devfn),
12460 "c" ((irq << 8) | (pin + 10)),
12461 - "S" (&pci_indirect));
12462 + "S" (&pci_indirect),
12463 + "r" (__PCIBIOS_DS));
12464 return !(ret & 0xff00);
12466 EXPORT_SYMBOL(pcibios_set_irq_routing);
12467 diff -urNp linux-2.6.24.4/arch/x86/power/cpu.c linux-2.6.24.4/arch/x86/power/cpu.c
12468 --- linux-2.6.24.4/arch/x86/power/cpu.c 2008-03-24 14:49:18.000000000 -0400
12469 +++ linux-2.6.24.4/arch/x86/power/cpu.c 2008-03-26 20:21:08.000000000 -0400
12470 @@ -64,10 +64,20 @@ static void do_fpu_end(void)
12471 static void fix_processor_context(void)
12473 int cpu = smp_processor_id();
12474 - struct tss_struct * t = &per_cpu(init_tss, cpu);
12475 + struct tss_struct *t = init_tss + cpu;
12477 +#ifdef CONFIG_PAX_KERNEXEC
12478 + unsigned long cr0;
12480 + pax_open_kernel(cr0);
12483 set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
12485 +#ifdef CONFIG_PAX_KERNEXEC
12486 + pax_close_kernel(cr0);
12489 load_TR_desc(); /* This does ltr */
12490 load_LDT(¤t->active_mm->context); /* This does lldt */
12492 diff -urNp linux-2.6.24.4/arch/x86/vdso/vma.c linux-2.6.24.4/arch/x86/vdso/vma.c
12493 --- linux-2.6.24.4/arch/x86/vdso/vma.c 2008-03-24 14:49:18.000000000 -0400
12494 +++ linux-2.6.24.4/arch/x86/vdso/vma.c 2008-03-26 20:21:08.000000000 -0400
12495 @@ -126,7 +126,7 @@ int arch_setup_additional_pages(struct l
12499 - current->mm->context.vdso = (void *)addr;
12500 + current->mm->context.vdso = addr;
12502 up_write(&mm->mmap_sem);
12504 diff -urNp linux-2.6.24.4/arch/x86/xen/enlighten.c linux-2.6.24.4/arch/x86/xen/enlighten.c
12505 --- linux-2.6.24.4/arch/x86/xen/enlighten.c 2008-03-24 14:49:18.000000000 -0400
12506 +++ linux-2.6.24.4/arch/x86/xen/enlighten.c 2008-03-26 20:21:08.000000000 -0400
12507 @@ -298,7 +298,7 @@ static void xen_set_ldt(const void *addr
12508 static void xen_load_gdt(const struct Xgt_desc_struct *dtr)
12510 unsigned long *frames;
12511 - unsigned long va = dtr->address;
12512 + unsigned long va = (unsigned long)dtr->address;
12513 unsigned int size = dtr->size + 1;
12514 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
12516 @@ -313,7 +313,7 @@ static void xen_load_gdt(const struct Xg
12517 mcs = xen_mc_entry(sizeof(*frames) * pages);
12520 - for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
12521 + for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
12522 frames[f] = virt_to_mfn(va);
12523 make_lowmem_page_readonly((void *)va);
12525 @@ -407,7 +407,7 @@ static void xen_write_idt_entry(struct d
12529 - start = __get_cpu_var(idt_desc).address;
12530 + start = (unsigned long)__get_cpu_var(idt_desc).address;
12531 end = start + __get_cpu_var(idt_desc).size + 1;
12534 diff -urNp linux-2.6.24.4/arch/x86/xen/smp.c linux-2.6.24.4/arch/x86/xen/smp.c
12535 --- linux-2.6.24.4/arch/x86/xen/smp.c 2008-03-24 14:49:18.000000000 -0400
12536 +++ linux-2.6.24.4/arch/x86/xen/smp.c 2008-03-26 20:21:08.000000000 -0400
12537 @@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi
12539 /* We've switched to the "real" per-cpu gdt, so make sure the
12540 old memory can be recycled */
12541 - make_lowmem_page_readwrite(&per_cpu__gdt_page);
12542 + make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
12544 for (cpu = 0; cpu < NR_CPUS; cpu++) {
12545 cpus_clear(per_cpu(cpu_sibling_map, cpu));
12546 @@ -208,7 +208,7 @@ static __cpuinit int
12547 cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
12549 struct vcpu_guest_context *ctxt;
12550 - struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
12551 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
12553 if (cpu_test_and_set(cpu, cpu_initialized_map))
12555 @@ -218,8 +218,8 @@ cpu_initialize_context(unsigned int cpu,
12558 ctxt->flags = VGCF_IN_KERNEL;
12559 - ctxt->user_regs.ds = __USER_DS;
12560 - ctxt->user_regs.es = __USER_DS;
12561 + ctxt->user_regs.ds = __KERNEL_DS;
12562 + ctxt->user_regs.es = __KERNEL_DS;
12563 ctxt->user_regs.fs = __KERNEL_PERCPU;
12564 ctxt->user_regs.gs = 0;
12565 ctxt->user_regs.ss = __KERNEL_DS;
12566 @@ -232,11 +232,11 @@ cpu_initialize_context(unsigned int cpu,
12568 ctxt->ldt_ents = 0;
12570 - BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
12571 - make_lowmem_page_readonly(gdt->gdt);
12572 + BUG_ON((unsigned long)gdt & ~PAGE_MASK);
12573 + make_lowmem_page_readonly(gdt);
12575 - ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
12576 - ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
12577 + ctxt->gdt_frames[0] = virt_to_mfn(gdt);
12578 + ctxt->gdt_ents = GDT_ENTRIES;
12580 ctxt->user_regs.cs = __KERNEL_CS;
12581 ctxt->user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs);
12582 diff -urNp linux-2.6.24.4/crypto/async_tx/async_tx.c linux-2.6.24.4/crypto/async_tx/async_tx.c
12583 --- linux-2.6.24.4/crypto/async_tx/async_tx.c 2008-03-24 14:49:18.000000000 -0400
12584 +++ linux-2.6.24.4/crypto/async_tx/async_tx.c 2008-03-26 20:21:08.000000000 -0400
12585 @@ -342,8 +342,8 @@ async_tx_init(void)
12587 printk(KERN_ERR "async_tx: initialization failure\n");
12589 - while (--cap >= 0)
12590 - free_percpu(channel_table[cap]);
12592 + free_percpu(channel_table[--cap]);
12596 diff -urNp linux-2.6.24.4/crypto/lrw.c linux-2.6.24.4/crypto/lrw.c
12597 --- linux-2.6.24.4/crypto/lrw.c 2008-03-24 14:49:18.000000000 -0400
12598 +++ linux-2.6.24.4/crypto/lrw.c 2008-03-26 20:21:08.000000000 -0400
12599 @@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
12600 struct priv *ctx = crypto_tfm_ctx(parent);
12601 struct crypto_cipher *child = ctx->child;
12603 - be128 tmp = { 0 };
12604 + be128 tmp = { 0, 0 };
12605 int bsize = crypto_cipher_blocksize(child);
12607 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
12608 diff -urNp linux-2.6.24.4/Documentation/dontdiff linux-2.6.24.4/Documentation/dontdiff
12609 --- linux-2.6.24.4/Documentation/dontdiff 2008-03-24 14:49:18.000000000 -0400
12610 +++ linux-2.6.24.4/Documentation/dontdiff 2008-03-26 20:21:08.000000000 -0400
12619 @@ -183,11 +184,14 @@ version.h*
12636 diff -urNp linux-2.6.24.4/drivers/acpi/blacklist.c linux-2.6.24.4/drivers/acpi/blacklist.c
12637 --- linux-2.6.24.4/drivers/acpi/blacklist.c 2008-03-24 14:49:18.000000000 -0400
12638 +++ linux-2.6.24.4/drivers/acpi/blacklist.c 2008-03-26 20:21:08.000000000 -0400
12639 @@ -73,7 +73,7 @@ static struct acpi_blacklist_item acpi_b
12640 {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions,
12641 "Bogus PCI routing", 1},
12644 + {"", "", 0, 0, 0, all_versions, 0}
12647 #if CONFIG_ACPI_BLACKLIST_YEAR
12648 diff -urNp linux-2.6.24.4/drivers/acpi/osl.c linux-2.6.24.4/drivers/acpi/osl.c
12649 --- linux-2.6.24.4/drivers/acpi/osl.c 2008-03-24 14:49:18.000000000 -0400
12650 +++ linux-2.6.24.4/drivers/acpi/osl.c 2008-03-26 20:21:08.000000000 -0400
12651 @@ -470,6 +470,8 @@ acpi_os_read_memory(acpi_physical_addres
12652 void __iomem *virt_addr;
12654 virt_addr = ioremap(phys_addr, width);
12656 + return AE_NO_MEMORY;
12660 @@ -498,6 +500,8 @@ acpi_os_write_memory(acpi_physical_addre
12661 void __iomem *virt_addr;
12663 virt_addr = ioremap(phys_addr, width);
12665 + return AE_NO_MEMORY;
12669 @@ -520,7 +524,7 @@ acpi_os_write_memory(acpi_physical_addre
12672 acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
12673 - void *value, u32 width)
12674 + u32 *value, u32 width)
12678 @@ -592,7 +596,7 @@ static void acpi_os_derive_pci_id_2(acpi
12679 acpi_status status;
12680 unsigned long temp;
12681 acpi_object_type type;
12685 acpi_get_parent(chandle, &handle);
12686 if (handle != rhandle) {
12687 diff -urNp linux-2.6.24.4/drivers/acpi/processor_core.c linux-2.6.24.4/drivers/acpi/processor_core.c
12688 --- linux-2.6.24.4/drivers/acpi/processor_core.c 2008-03-24 14:49:18.000000000 -0400
12689 +++ linux-2.6.24.4/drivers/acpi/processor_core.c 2008-03-26 20:21:08.000000000 -0400
12690 @@ -632,7 +632,7 @@ static int __cpuinit acpi_processor_star
12694 - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
12695 + BUG_ON(pr->id >= nr_cpu_ids);
12699 diff -urNp linux-2.6.24.4/drivers/acpi/processor_idle.c linux-2.6.24.4/drivers/acpi/processor_idle.c
12700 --- linux-2.6.24.4/drivers/acpi/processor_idle.c 2008-03-24 14:49:18.000000000 -0400
12701 +++ linux-2.6.24.4/drivers/acpi/processor_idle.c 2008-03-26 20:21:08.000000000 -0400
12702 @@ -178,7 +178,7 @@ static struct dmi_system_id __cpuinitdat
12703 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
12704 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
12707 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
12710 static inline u32 ticks_elapsed(u32 t1, u32 t2)
12711 diff -urNp linux-2.6.24.4/drivers/acpi/sleep/main.c linux-2.6.24.4/drivers/acpi/sleep/main.c
12712 --- linux-2.6.24.4/drivers/acpi/sleep/main.c 2008-03-24 14:49:18.000000000 -0400
12713 +++ linux-2.6.24.4/drivers/acpi/sleep/main.c 2008-03-26 20:21:08.000000000 -0400
12714 @@ -224,7 +224,7 @@ static struct dmi_system_id __initdata a
12715 .ident = "Toshiba Satellite 4030cdt",
12716 .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
12719 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
12721 #endif /* CONFIG_SUSPEND */
12723 diff -urNp linux-2.6.24.4/drivers/acpi/tables/tbfadt.c linux-2.6.24.4/drivers/acpi/tables/tbfadt.c
12724 --- linux-2.6.24.4/drivers/acpi/tables/tbfadt.c 2008-03-24 14:49:18.000000000 -0400
12725 +++ linux-2.6.24.4/drivers/acpi/tables/tbfadt.c 2008-03-26 20:21:08.000000000 -0400
12727 ACPI_MODULE_NAME("tbfadt")
12729 /* Local prototypes */
12730 -static void inline
12731 +static inline void
12732 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12733 u8 bit_width, u64 address);
12735 @@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
12737 ******************************************************************************/
12739 -static void inline
12740 +static inline void
12741 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12742 u8 bit_width, u64 address)
12744 diff -urNp linux-2.6.24.4/drivers/acpi/tables/tbxface.c linux-2.6.24.4/drivers/acpi/tables/tbxface.c
12745 --- linux-2.6.24.4/drivers/acpi/tables/tbxface.c 2008-03-24 14:49:18.000000000 -0400
12746 +++ linux-2.6.24.4/drivers/acpi/tables/tbxface.c 2008-03-26 20:21:08.000000000 -0400
12747 @@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespac
12748 acpi_tb_print_table_header(0, table);
12750 if (no_auto_ssdt == 0) {
12751 - printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
12752 + printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
12756 diff -urNp linux-2.6.24.4/drivers/ata/ahci.c linux-2.6.24.4/drivers/ata/ahci.c
12757 --- linux-2.6.24.4/drivers/ata/ahci.c 2008-03-24 14:49:18.000000000 -0400
12758 +++ linux-2.6.24.4/drivers/ata/ahci.c 2008-03-26 20:21:08.000000000 -0400
12759 @@ -563,7 +563,7 @@ static const struct pci_device_id ahci_p
12760 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
12761 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
12763 - { } /* terminate list */
12764 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12768 diff -urNp linux-2.6.24.4/drivers/ata/ata_piix.c linux-2.6.24.4/drivers/ata/ata_piix.c
12769 --- linux-2.6.24.4/drivers/ata/ata_piix.c 2008-03-24 14:49:18.000000000 -0400
12770 +++ linux-2.6.24.4/drivers/ata/ata_piix.c 2008-03-26 20:21:08.000000000 -0400
12771 @@ -264,7 +264,7 @@ static const struct pci_device_id piix_p
12772 /* SATA Controller IDE (Tolapai) */
12773 { 0x8086, 0x5028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, tolapai_sata_ahci },
12775 - { } /* terminate list */
12776 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12779 static struct pci_driver piix_pci_driver = {
12780 @@ -701,7 +701,7 @@ static const struct ich_laptop ich_lapto
12781 { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
12782 { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
12789 @@ -1097,7 +1097,7 @@ static int piix_broken_suspend(void)
12793 - { } /* terminate list */
12794 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
12796 static const char *oemstrs[] = {
12798 diff -urNp linux-2.6.24.4/drivers/ata/libata-core.c linux-2.6.24.4/drivers/ata/libata-core.c
12799 --- linux-2.6.24.4/drivers/ata/libata-core.c 2008-03-24 14:49:18.000000000 -0400
12800 +++ linux-2.6.24.4/drivers/ata/libata-core.c 2008-03-26 20:21:08.000000000 -0400
12801 @@ -489,7 +489,7 @@ static const struct ata_xfer_ent {
12802 { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
12803 { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
12804 { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
12810 @@ -2814,7 +2814,7 @@ static const struct ata_timing ata_timin
12812 /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
12815 + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
12818 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
12819 @@ -4178,7 +4178,7 @@ static const struct ata_blacklist_entry
12820 { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
12824 + { NULL, NULL, 0 }
12827 static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
12828 diff -urNp linux-2.6.24.4/drivers/char/agp/frontend.c linux-2.6.24.4/drivers/char/agp/frontend.c
12829 --- linux-2.6.24.4/drivers/char/agp/frontend.c 2008-03-24 14:49:18.000000000 -0400
12830 +++ linux-2.6.24.4/drivers/char/agp/frontend.c 2008-03-26 20:21:08.000000000 -0400
12831 @@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
12832 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
12835 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
12836 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
12839 client = agp_find_client_by_pid(reserve.pid);
12840 diff -urNp linux-2.6.24.4/drivers/char/agp/intel-agp.c linux-2.6.24.4/drivers/char/agp/intel-agp.c
12841 --- linux-2.6.24.4/drivers/char/agp/intel-agp.c 2008-03-24 14:49:18.000000000 -0400
12842 +++ linux-2.6.24.4/drivers/char/agp/intel-agp.c 2008-03-26 20:21:08.000000000 -0400
12843 @@ -2080,7 +2080,7 @@ static struct pci_device_id agp_intel_pc
12844 ID(PCI_DEVICE_ID_INTEL_G33_HB),
12845 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
12846 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
12848 + { 0, 0, 0, 0, 0, 0, 0 }
12851 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
12852 diff -urNp linux-2.6.24.4/drivers/char/drm/drm_pciids.h linux-2.6.24.4/drivers/char/drm/drm_pciids.h
12853 --- linux-2.6.24.4/drivers/char/drm/drm_pciids.h 2008-03-24 14:49:18.000000000 -0400
12854 +++ linux-2.6.24.4/drivers/char/drm/drm_pciids.h 2008-03-26 20:21:08.000000000 -0400
12855 @@ -249,7 +249,7 @@
12856 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
12857 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
12858 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
12860 + {0, 0, 0, 0, 0, 0, 0 }
12862 #define i830_PCI_IDS \
12863 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
12864 diff -urNp linux-2.6.24.4/drivers/char/hpet.c linux-2.6.24.4/drivers/char/hpet.c
12865 --- linux-2.6.24.4/drivers/char/hpet.c 2008-03-24 14:49:18.000000000 -0400
12866 +++ linux-2.6.24.4/drivers/char/hpet.c 2008-03-26 20:21:08.000000000 -0400
12867 @@ -1028,7 +1028,7 @@ static struct acpi_driver hpet_acpi_driv
12871 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
12872 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
12874 static int __init hpet_init(void)
12876 diff -urNp linux-2.6.24.4/drivers/char/keyboard.c linux-2.6.24.4/drivers/char/keyboard.c
12877 --- linux-2.6.24.4/drivers/char/keyboard.c 2008-03-24 14:49:18.000000000 -0400
12878 +++ linux-2.6.24.4/drivers/char/keyboard.c 2008-03-26 20:21:08.000000000 -0400
12879 @@ -631,6 +631,16 @@ static void k_spec(struct vc_data *vc, u
12880 kbd->kbdmode == VC_MEDIUMRAW) &&
12881 value != KVAL(K_SAK))
12882 return; /* SAK is allowed even in raw mode */
12884 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
12886 + void *func = fn_handler[value];
12887 + if (func == fn_show_state || func == fn_show_ptregs ||
12888 + func == fn_show_mem)
12893 fn_handler[value](vc);
12896 @@ -1385,7 +1395,7 @@ static const struct input_device_id kbd_
12897 .evbit = { BIT_MASK(EV_SND) },
12900 - { }, /* Terminating entry */
12901 + { 0 }, /* Terminating entry */
12904 MODULE_DEVICE_TABLE(input, kbd_ids);
12905 diff -urNp linux-2.6.24.4/drivers/char/mem.c linux-2.6.24.4/drivers/char/mem.c
12906 --- linux-2.6.24.4/drivers/char/mem.c 2008-03-24 14:49:18.000000000 -0400
12907 +++ linux-2.6.24.4/drivers/char/mem.c 2008-03-26 20:21:08.000000000 -0400
12909 #include <linux/bootmem.h>
12910 #include <linux/splice.h>
12911 #include <linux/pfn.h>
12912 +#include <linux/grsecurity.h>
12914 #include <asm/uaccess.h>
12915 #include <asm/io.h>
12917 # include <linux/efi.h>
12920 +#ifdef CONFIG_GRKERNSEC
12921 +extern struct file_operations grsec_fops;
12925 * Architectures vary in how they handle caching for addresses
12926 * outside of main memory.
12927 @@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f
12928 if (!valid_phys_addr_range(p, count))
12931 +#ifdef CONFIG_GRKERNSEC_KMEM
12932 + gr_handle_mem_write();
12938 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
12939 @@ -281,6 +291,11 @@ static int mmap_mem(struct file * file,
12940 if (!private_mapping_ok(vma))
12943 +#ifdef CONFIG_GRKERNSEC_KMEM
12944 + if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
12948 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
12950 vma->vm_page_prot);
12951 @@ -512,6 +527,11 @@ static ssize_t write_kmem(struct file *
12953 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
12955 +#ifdef CONFIG_GRKERNSEC_KMEM
12956 + gr_handle_kmem_write();
12960 if (p < (unsigned long) high_memory) {
12963 @@ -714,6 +734,16 @@ static loff_t memory_lseek(struct file *
12965 static int open_port(struct inode * inode, struct file * filp)
12967 +#ifdef CONFIG_GRKERNSEC_KMEM
12968 + gr_handle_open_port();
12972 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12975 +static int open_mem(struct inode * inode, struct file * filp)
12977 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12980 @@ -721,7 +751,6 @@ static int open_port(struct inode * inod
12981 #define full_lseek null_lseek
12982 #define write_zero write_null
12983 #define read_full read_zero
12984 -#define open_mem open_port
12985 #define open_kmem open_mem
12986 #define open_oldmem open_mem
12988 @@ -854,6 +883,11 @@ static int memory_open(struct inode * in
12989 filp->f_op = &oldmem_fops;
12992 +#ifdef CONFIG_GRKERNSEC
12994 + filp->f_op = &grsec_fops;
13000 @@ -886,6 +920,9 @@ static const struct {
13001 #ifdef CONFIG_CRASH_DUMP
13002 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
13004 +#ifdef CONFIG_GRKERNSEC
13005 + {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
13009 static struct class *mem_class;
13010 diff -urNp linux-2.6.24.4/drivers/char/nvram.c linux-2.6.24.4/drivers/char/nvram.c
13011 --- linux-2.6.24.4/drivers/char/nvram.c 2008-03-24 14:49:18.000000000 -0400
13012 +++ linux-2.6.24.4/drivers/char/nvram.c 2008-03-26 20:21:08.000000000 -0400
13013 @@ -430,7 +430,10 @@ static const struct file_operations nvra
13014 static struct miscdevice nvram_dev = {
13025 diff -urNp linux-2.6.24.4/drivers/char/random.c linux-2.6.24.4/drivers/char/random.c
13026 --- linux-2.6.24.4/drivers/char/random.c 2008-03-24 14:49:18.000000000 -0400
13027 +++ linux-2.6.24.4/drivers/char/random.c 2008-03-26 20:21:08.000000000 -0400
13028 @@ -248,8 +248,13 @@
13030 * Configuration information
13032 +#ifdef CONFIG_GRKERNSEC_RANDNET
13033 +#define INPUT_POOL_WORDS 512
13034 +#define OUTPUT_POOL_WORDS 128
13036 #define INPUT_POOL_WORDS 128
13037 #define OUTPUT_POOL_WORDS 32
13039 #define SEC_XFER_SIZE 512
13042 @@ -286,10 +291,17 @@ static struct poolinfo {
13044 int tap1, tap2, tap3, tap4, tap5;
13045 } poolinfo_table[] = {
13046 +#ifdef CONFIG_GRKERNSEC_RANDNET
13047 + /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
13048 + { 512, 411, 308, 208, 104, 1 },
13049 + /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
13050 + { 128, 103, 76, 51, 25, 1 },
13052 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
13053 { 128, 103, 76, 51, 25, 1 },
13054 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
13055 { 32, 26, 20, 14, 7, 1 },
13058 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
13059 { 2048, 1638, 1231, 819, 411, 1 },
13060 @@ -1172,7 +1184,7 @@ EXPORT_SYMBOL(generate_random_uuid);
13061 #include <linux/sysctl.h>
13063 static int min_read_thresh = 8, min_write_thresh;
13064 -static int max_read_thresh = INPUT_POOL_WORDS * 32;
13065 +static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
13066 static int max_write_thresh = INPUT_POOL_WORDS * 32;
13067 static char sysctl_bootid[16];
13069 diff -urNp linux-2.6.24.4/drivers/char/vt_ioctl.c linux-2.6.24.4/drivers/char/vt_ioctl.c
13070 --- linux-2.6.24.4/drivers/char/vt_ioctl.c 2008-03-24 14:49:18.000000000 -0400
13071 +++ linux-2.6.24.4/drivers/char/vt_ioctl.c 2008-03-26 20:21:08.000000000 -0400
13072 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
13077 +#ifdef CONFIG_GRKERNSEC
13078 + if (!capable(CAP_SYS_TTY_CONFIG))
13082 if (!i && v == K_NOSUCHMAP) {
13083 /* deallocate map */
13084 key_map = key_maps[s];
13085 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
13089 +#ifdef CONFIG_GRKERNSEC
13090 + if (!capable(CAP_SYS_TTY_CONFIG)) {
13097 first_free = funcbufptr + (funcbufsize - funcbufleft);
13098 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
13099 diff -urNp linux-2.6.24.4/drivers/edac/edac_core.h linux-2.6.24.4/drivers/edac/edac_core.h
13100 --- linux-2.6.24.4/drivers/edac/edac_core.h 2008-03-24 14:49:18.000000000 -0400
13101 +++ linux-2.6.24.4/drivers/edac/edac_core.h 2008-03-26 20:21:08.000000000 -0400
13102 @@ -86,11 +86,11 @@ extern int edac_debug_level;
13104 #else /* !CONFIG_EDAC_DEBUG */
13106 -#define debugf0( ... )
13107 -#define debugf1( ... )
13108 -#define debugf2( ... )
13109 -#define debugf3( ... )
13110 -#define debugf4( ... )
13111 +#define debugf0( ... ) do {} while (0)
13112 +#define debugf1( ... ) do {} while (0)
13113 +#define debugf2( ... ) do {} while (0)
13114 +#define debugf3( ... ) do {} while (0)
13115 +#define debugf4( ... ) do {} while (0)
13117 #endif /* !CONFIG_EDAC_DEBUG */
13119 diff -urNp linux-2.6.24.4/drivers/firmware/dmi_scan.c linux-2.6.24.4/drivers/firmware/dmi_scan.c
13120 --- linux-2.6.24.4/drivers/firmware/dmi_scan.c 2008-03-24 14:49:18.000000000 -0400
13121 +++ linux-2.6.24.4/drivers/firmware/dmi_scan.c 2008-03-26 20:21:08.000000000 -0400
13122 @@ -318,21 +318,19 @@ void __init dmi_scan_machine(void)
13127 - * no iounmap() for that ioremap(); it would be a no-op, but
13128 - * it's so early in setup that sucker gets confused into doing
13129 - * what it shouldn't if we actually call it.
13131 p = dmi_ioremap(0xF0000, 0x10000);
13135 for (q = p; q < p + 0x10000; q += 16) {
13136 rc = dmi_present(q);
13138 - dmi_available = 1;
13144 + dmi_iounmap(p, 0x10000);
13146 + dmi_available = 1;
13150 out: printk(KERN_INFO "DMI not present or invalid.\n");
13151 diff -urNp linux-2.6.24.4/drivers/hwmon/fscpos.c linux-2.6.24.4/drivers/hwmon/fscpos.c
13152 --- linux-2.6.24.4/drivers/hwmon/fscpos.c 2008-03-24 14:49:18.000000000 -0400
13153 +++ linux-2.6.24.4/drivers/hwmon/fscpos.c 2008-03-26 20:21:08.000000000 -0400
13154 @@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
13155 unsigned long v = simple_strtoul(buf, NULL, 10);
13157 /* Range: 0..255 */
13158 - if (v < 0) v = 0;
13159 if (v > 255) v = 255;
13161 mutex_lock(&data->update_lock);
13162 diff -urNp linux-2.6.24.4/drivers/hwmon/k8temp.c linux-2.6.24.4/drivers/hwmon/k8temp.c
13163 --- linux-2.6.24.4/drivers/hwmon/k8temp.c 2008-03-24 14:49:18.000000000 -0400
13164 +++ linux-2.6.24.4/drivers/hwmon/k8temp.c 2008-03-26 20:21:08.000000000 -0400
13165 @@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
13167 static struct pci_device_id k8temp_ids[] = {
13168 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
13170 + { 0, 0, 0, 0, 0, 0, 0 },
13173 MODULE_DEVICE_TABLE(pci, k8temp_ids);
13174 diff -urNp linux-2.6.24.4/drivers/hwmon/sis5595.c linux-2.6.24.4/drivers/hwmon/sis5595.c
13175 --- linux-2.6.24.4/drivers/hwmon/sis5595.c 2008-03-24 14:49:18.000000000 -0400
13176 +++ linux-2.6.24.4/drivers/hwmon/sis5595.c 2008-03-26 20:21:08.000000000 -0400
13177 @@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
13179 static struct pci_device_id sis5595_pci_ids[] = {
13180 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
13182 + { 0, 0, 0, 0, 0, 0, 0 }
13185 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
13186 diff -urNp linux-2.6.24.4/drivers/hwmon/thmc50.c linux-2.6.24.4/drivers/hwmon/thmc50.c
13187 --- linux-2.6.24.4/drivers/hwmon/thmc50.c 2008-03-24 14:49:18.000000000 -0400
13188 +++ linux-2.6.24.4/drivers/hwmon/thmc50.c 2008-03-26 20:21:08.000000000 -0400
13189 @@ -52,9 +52,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "L
13191 #define THMC50_REG_INTR 0x41
13193 -const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
13194 -const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
13195 -const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
13196 +static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
13197 +static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
13198 +static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
13200 #define THMC50_REG_CONF_nFANOFF 0x20
13202 diff -urNp linux-2.6.24.4/drivers/hwmon/via686a.c linux-2.6.24.4/drivers/hwmon/via686a.c
13203 --- linux-2.6.24.4/drivers/hwmon/via686a.c 2008-03-24 14:49:18.000000000 -0400
13204 +++ linux-2.6.24.4/drivers/hwmon/via686a.c 2008-03-26 20:21:08.000000000 -0400
13205 @@ -740,7 +740,7 @@ static struct via686a_data *via686a_upda
13207 static struct pci_device_id via686a_pci_ids[] = {
13208 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
13210 + { 0, 0, 0, 0, 0, 0, 0 }
13213 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
13214 diff -urNp linux-2.6.24.4/drivers/hwmon/vt8231.c linux-2.6.24.4/drivers/hwmon/vt8231.c
13215 --- linux-2.6.24.4/drivers/hwmon/vt8231.c 2008-03-24 14:49:18.000000000 -0400
13216 +++ linux-2.6.24.4/drivers/hwmon/vt8231.c 2008-03-26 20:21:08.000000000 -0400
13217 @@ -662,7 +662,7 @@ static struct platform_driver vt8231_dri
13219 static struct pci_device_id vt8231_pci_ids[] = {
13220 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
13222 + { 0, 0, 0, 0, 0, 0, 0 }
13225 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
13226 diff -urNp linux-2.6.24.4/drivers/hwmon/w83791d.c linux-2.6.24.4/drivers/hwmon/w83791d.c
13227 --- linux-2.6.24.4/drivers/hwmon/w83791d.c 2008-03-24 14:49:18.000000000 -0400
13228 +++ linux-2.6.24.4/drivers/hwmon/w83791d.c 2008-03-26 20:21:08.000000000 -0400
13229 @@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct
13230 static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
13231 static int w83791d_detach_client(struct i2c_client *client);
13233 -static int w83791d_read(struct i2c_client *client, u8 register);
13234 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
13235 +static int w83791d_read(struct i2c_client *client, u8 reg);
13236 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
13237 static struct w83791d_data *w83791d_update_device(struct device *dev);
13240 diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-i801.c linux-2.6.24.4/drivers/i2c/busses/i2c-i801.c
13241 --- linux-2.6.24.4/drivers/i2c/busses/i2c-i801.c 2008-03-24 14:49:18.000000000 -0400
13242 +++ linux-2.6.24.4/drivers/i2c/busses/i2c-i801.c 2008-03-26 20:21:08.000000000 -0400
13243 @@ -545,7 +545,7 @@ static struct pci_device_id i801_ids[] =
13244 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
13245 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
13246 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
13248 + { 0, 0, 0, 0, 0, 0, 0 }
13251 MODULE_DEVICE_TABLE (pci, i801_ids);
13252 diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-i810.c linux-2.6.24.4/drivers/i2c/busses/i2c-i810.c
13253 --- linux-2.6.24.4/drivers/i2c/busses/i2c-i810.c 2008-03-24 14:49:18.000000000 -0400
13254 +++ linux-2.6.24.4/drivers/i2c/busses/i2c-i810.c 2008-03-26 20:21:08.000000000 -0400
13255 @@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
13256 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
13257 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
13258 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
13260 + { 0, 0, 0, 0, 0, 0, 0 },
13263 MODULE_DEVICE_TABLE (pci, i810_ids);
13264 diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-piix4.c linux-2.6.24.4/drivers/i2c/busses/i2c-piix4.c
13265 --- linux-2.6.24.4/drivers/i2c/busses/i2c-piix4.c 2008-03-24 14:49:18.000000000 -0400
13266 +++ linux-2.6.24.4/drivers/i2c/busses/i2c-piix4.c 2008-03-26 20:21:08.000000000 -0400
13267 @@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat
13269 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
13272 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
13275 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
13276 @@ -411,7 +411,7 @@ static struct pci_device_id piix4_ids[]
13277 .driver_data = 3 },
13278 { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
13279 .driver_data = 0 },
13281 + { 0, 0, 0, 0, 0, 0, 0 }
13284 MODULE_DEVICE_TABLE (pci, piix4_ids);
13285 diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-sis630.c linux-2.6.24.4/drivers/i2c/busses/i2c-sis630.c
13286 --- linux-2.6.24.4/drivers/i2c/busses/i2c-sis630.c 2008-03-24 14:49:18.000000000 -0400
13287 +++ linux-2.6.24.4/drivers/i2c/busses/i2c-sis630.c 2008-03-26 20:21:08.000000000 -0400
13288 @@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
13289 static struct pci_device_id sis630_ids[] __devinitdata = {
13290 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
13291 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
13293 + { 0, 0, 0, 0, 0, 0, 0 }
13296 MODULE_DEVICE_TABLE (pci, sis630_ids);
13297 diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-sis96x.c linux-2.6.24.4/drivers/i2c/busses/i2c-sis96x.c
13298 --- linux-2.6.24.4/drivers/i2c/busses/i2c-sis96x.c 2008-03-24 14:49:18.000000000 -0400
13299 +++ linux-2.6.24.4/drivers/i2c/busses/i2c-sis96x.c 2008-03-26 20:21:08.000000000 -0400
13300 @@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
13302 static struct pci_device_id sis96x_ids[] = {
13303 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
13305 + { 0, 0, 0, 0, 0, 0, 0 }
13308 MODULE_DEVICE_TABLE (pci, sis96x_ids);
13309 diff -urNp linux-2.6.24.4/drivers/ide/ide-cd.c linux-2.6.24.4/drivers/ide/ide-cd.c
13310 --- linux-2.6.24.4/drivers/ide/ide-cd.c 2008-03-24 14:49:18.000000000 -0400
13311 +++ linux-2.6.24.4/drivers/ide/ide-cd.c 2008-03-26 20:21:08.000000000 -0400
13312 @@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
13313 sector &= ~(bio_sectors -1);
13314 valid = (sector - failed_command->sector) << 9;
13318 if (sector < get_capacity(info->disk) &&
13319 drive->probed_capacity - sector < 4 * 75) {
13320 set_capacity(info->disk, sector);
13321 diff -urNp linux-2.6.24.4/drivers/ieee1394/dv1394.c linux-2.6.24.4/drivers/ieee1394/dv1394.c
13322 --- linux-2.6.24.4/drivers/ieee1394/dv1394.c 2008-03-24 14:49:18.000000000 -0400
13323 +++ linux-2.6.24.4/drivers/ieee1394/dv1394.c 2008-03-26 20:21:08.000000000 -0400
13324 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
13325 based upon DIF section and sequence
13328 -static void inline
13329 +static inline void
13330 frame_put_packet (struct frame *f, struct packet *p)
13332 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
13333 @@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
13334 /* default SYT offset is 3 cycles */
13335 init->syt_offset = 3;
13337 - if ( (init->channel > 63) || (init->channel < 0) )
13338 + if (init->channel > 63)
13339 init->channel = 63;
13341 chan_mask = (u64)1 << init->channel;
13342 @@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
13343 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
13344 .version = AVC_SW_VERSION_ENTRY & 0xffffff
13347 + { 0, 0, 0, 0, 0, 0 }
13350 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
13351 diff -urNp linux-2.6.24.4/drivers/ieee1394/eth1394.c linux-2.6.24.4/drivers/ieee1394/eth1394.c
13352 --- linux-2.6.24.4/drivers/ieee1394/eth1394.c 2008-03-24 14:49:18.000000000 -0400
13353 +++ linux-2.6.24.4/drivers/ieee1394/eth1394.c 2008-03-26 20:21:08.000000000 -0400
13354 @@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
13355 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
13356 .version = ETHER1394_GASP_VERSION,
13359 + { 0, 0, 0, 0, 0, 0 }
13362 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
13363 diff -urNp linux-2.6.24.4/drivers/ieee1394/hosts.c linux-2.6.24.4/drivers/ieee1394/hosts.c
13364 --- linux-2.6.24.4/drivers/ieee1394/hosts.c 2008-03-24 14:49:18.000000000 -0400
13365 +++ linux-2.6.24.4/drivers/ieee1394/hosts.c 2008-03-26 20:21:08.000000000 -0400
13366 @@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
13369 static struct hpsb_host_driver dummy_driver = {
13371 .transmit_packet = dummy_transmit_packet,
13372 .devctl = dummy_devctl,
13373 .isoctl = dummy_isoctl
13374 diff -urNp linux-2.6.24.4/drivers/ieee1394/ohci1394.c linux-2.6.24.4/drivers/ieee1394/ohci1394.c
13375 --- linux-2.6.24.4/drivers/ieee1394/ohci1394.c 2008-03-24 14:49:18.000000000 -0400
13376 +++ linux-2.6.24.4/drivers/ieee1394/ohci1394.c 2008-03-26 20:21:08.000000000 -0400
13377 @@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
13378 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
13380 /* Module Parameters */
13381 -static int phys_dma = 1;
13382 +static int phys_dma;
13383 module_param(phys_dma, int, 0444);
13384 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
13385 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
13387 static void dma_trm_tasklet(unsigned long data);
13388 static void dma_trm_reset(struct dma_trm_ctx *d);
13389 @@ -3396,7 +3396,7 @@ static struct pci_device_id ohci1394_pci
13390 .subvendor = PCI_ANY_ID,
13391 .subdevice = PCI_ANY_ID,
13394 + { 0, 0, 0, 0, 0, 0, 0 },
13397 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
13398 diff -urNp linux-2.6.24.4/drivers/ieee1394/raw1394.c linux-2.6.24.4/drivers/ieee1394/raw1394.c
13399 --- linux-2.6.24.4/drivers/ieee1394/raw1394.c 2008-03-24 14:49:18.000000000 -0400
13400 +++ linux-2.6.24.4/drivers/ieee1394/raw1394.c 2008-03-26 20:21:08.000000000 -0400
13401 @@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394
13402 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
13403 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
13404 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
13406 + { 0, 0, 0, 0, 0, 0 }
13409 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
13410 diff -urNp linux-2.6.24.4/drivers/ieee1394/sbp2.c linux-2.6.24.4/drivers/ieee1394/sbp2.c
13411 --- linux-2.6.24.4/drivers/ieee1394/sbp2.c 2008-03-24 14:49:18.000000000 -0400
13412 +++ linux-2.6.24.4/drivers/ieee1394/sbp2.c 2008-03-26 20:21:08.000000000 -0400
13413 @@ -274,7 +274,7 @@ static struct ieee1394_device_id sbp2_id
13414 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
13415 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
13416 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
13418 + { 0, 0, 0, 0, 0, 0 }
13420 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
13422 @@ -2078,7 +2078,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
13423 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
13424 MODULE_LICENSE("GPL");
13426 -static int sbp2_module_init(void)
13427 +static int __init sbp2_module_init(void)
13431 diff -urNp linux-2.6.24.4/drivers/ieee1394/video1394.c linux-2.6.24.4/drivers/ieee1394/video1394.c
13432 --- linux-2.6.24.4/drivers/ieee1394/video1394.c 2008-03-24 14:49:18.000000000 -0400
13433 +++ linux-2.6.24.4/drivers/ieee1394/video1394.c 2008-03-26 20:21:08.000000000 -0400
13434 @@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
13435 if (unlikely(d == NULL))
13438 - if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
13439 + if (unlikely(v.buffer>=d->num_desc - 1)) {
13440 PRINT(KERN_ERR, ohci->host->id,
13441 "Buffer %d out of range",v.buffer);
13443 @@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
13444 if (unlikely(d == NULL))
13447 - if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
13448 + if (unlikely(v.buffer>d->num_desc - 1)) {
13449 PRINT(KERN_ERR, ohci->host->id,
13450 "Buffer %d out of range",v.buffer);
13452 @@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
13453 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
13454 if (d == NULL) return -EFAULT;
13456 - if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
13457 + if (v.buffer>=d->num_desc - 1) {
13458 PRINT(KERN_ERR, ohci->host->id,
13459 "Buffer %d out of range",v.buffer);
13461 @@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
13462 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
13463 if (d == NULL) return -EFAULT;
13465 - if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
13466 + if (v.buffer>=d->num_desc-1) {
13467 PRINT(KERN_ERR, ohci->host->id,
13468 "Buffer %d out of range",v.buffer);
13470 @@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
13471 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
13472 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
13475 + { 0, 0, 0, 0, 0, 0 }
13478 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
13479 diff -urNp linux-2.6.24.4/drivers/input/keyboard/atkbd.c linux-2.6.24.4/drivers/input/keyboard/atkbd.c
13480 --- linux-2.6.24.4/drivers/input/keyboard/atkbd.c 2008-03-24 14:49:18.000000000 -0400
13481 +++ linux-2.6.24.4/drivers/input/keyboard/atkbd.c 2008-03-26 20:21:08.000000000 -0400
13482 @@ -1080,7 +1080,7 @@ static struct serio_device_id atkbd_seri
13484 .extra = SERIO_ANY,
13490 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
13491 diff -urNp linux-2.6.24.4/drivers/input/mouse/lifebook.c linux-2.6.24.4/drivers/input/mouse/lifebook.c
13492 --- linux-2.6.24.4/drivers/input/mouse/lifebook.c 2008-03-24 14:49:18.000000000 -0400
13493 +++ linux-2.6.24.4/drivers/input/mouse/lifebook.c 2008-03-26 20:21:08.000000000 -0400
13494 @@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
13495 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
13499 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
13502 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
13503 diff -urNp linux-2.6.24.4/drivers/input/mouse/psmouse-base.c linux-2.6.24.4/drivers/input/mouse/psmouse-base.c
13504 --- linux-2.6.24.4/drivers/input/mouse/psmouse-base.c 2008-03-24 14:49:18.000000000 -0400
13505 +++ linux-2.6.24.4/drivers/input/mouse/psmouse-base.c 2008-03-26 20:21:08.000000000 -0400
13506 @@ -1329,7 +1329,7 @@ static struct serio_device_id psmouse_se
13508 .extra = SERIO_ANY,
13514 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
13515 diff -urNp linux-2.6.24.4/drivers/input/mouse/synaptics.c linux-2.6.24.4/drivers/input/mouse/synaptics.c
13516 --- linux-2.6.24.4/drivers/input/mouse/synaptics.c 2008-03-24 14:49:18.000000000 -0400
13517 +++ linux-2.6.24.4/drivers/input/mouse/synaptics.c 2008-03-26 20:21:08.000000000 -0400
13518 @@ -417,7 +417,7 @@ static void synaptics_process_packet(str
13521 if (SYN_MODEL_PEN(priv->model_id))
13522 - ; /* Nothing, treat a pen as a single finger */
13523 + break; /* Nothing, treat a pen as a single finger */
13526 if (SYN_CAP_PALMDETECT(priv->capabilities))
13527 @@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
13528 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
13532 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13536 diff -urNp linux-2.6.24.4/drivers/input/mousedev.c linux-2.6.24.4/drivers/input/mousedev.c
13537 --- linux-2.6.24.4/drivers/input/mousedev.c 2008-03-24 14:49:18.000000000 -0400
13538 +++ linux-2.6.24.4/drivers/input/mousedev.c 2008-03-26 20:21:08.000000000 -0400
13539 @@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han
13541 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
13542 static struct miscdevice psaux_mouse = {
13543 - PSMOUSE_MINOR, "psaux", &mousedev_fops
13544 + PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
13546 static int psaux_registered;
13548 diff -urNp linux-2.6.24.4/drivers/input/serio/i8042-x86ia64io.h linux-2.6.24.4/drivers/input/serio/i8042-x86ia64io.h
13549 --- linux-2.6.24.4/drivers/input/serio/i8042-x86ia64io.h 2008-03-24 14:49:18.000000000 -0400
13550 +++ linux-2.6.24.4/drivers/input/serio/i8042-x86ia64io.h 2008-03-26 20:21:08.000000000 -0400
13551 @@ -118,7 +118,7 @@ static struct dmi_system_id __initdata i
13552 DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
13556 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13560 @@ -270,7 +270,7 @@ static struct dmi_system_id __initdata i
13561 DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
13565 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13569 diff -urNp linux-2.6.24.4/drivers/input/serio/serio_raw.c linux-2.6.24.4/drivers/input/serio/serio_raw.c
13570 --- linux-2.6.24.4/drivers/input/serio/serio_raw.c 2008-03-24 14:49:18.000000000 -0400
13571 +++ linux-2.6.24.4/drivers/input/serio/serio_raw.c 2008-03-26 20:21:08.000000000 -0400
13572 @@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
13574 .extra = SERIO_ANY,
13580 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
13581 diff -urNp linux-2.6.24.4/drivers/kvm/kvm_main.c linux-2.6.24.4/drivers/kvm/kvm_main.c
13582 --- linux-2.6.24.4/drivers/kvm/kvm_main.c 2008-03-24 14:49:18.000000000 -0400
13583 +++ linux-2.6.24.4/drivers/kvm/kvm_main.c 2008-03-26 20:21:08.000000000 -0400
13584 @@ -67,22 +67,22 @@ static struct kvm_stats_debugfs_item {
13586 struct dentry *dentry;
13587 } debugfs_entries[] = {
13588 - { "pf_fixed", STAT_OFFSET(pf_fixed) },
13589 - { "pf_guest", STAT_OFFSET(pf_guest) },
13590 - { "tlb_flush", STAT_OFFSET(tlb_flush) },
13591 - { "invlpg", STAT_OFFSET(invlpg) },
13592 - { "exits", STAT_OFFSET(exits) },
13593 - { "io_exits", STAT_OFFSET(io_exits) },
13594 - { "mmio_exits", STAT_OFFSET(mmio_exits) },
13595 - { "signal_exits", STAT_OFFSET(signal_exits) },
13596 - { "irq_window", STAT_OFFSET(irq_window_exits) },
13597 - { "halt_exits", STAT_OFFSET(halt_exits) },
13598 - { "halt_wakeup", STAT_OFFSET(halt_wakeup) },
13599 - { "request_irq", STAT_OFFSET(request_irq_exits) },
13600 - { "irq_exits", STAT_OFFSET(irq_exits) },
13601 - { "light_exits", STAT_OFFSET(light_exits) },
13602 - { "efer_reload", STAT_OFFSET(efer_reload) },
13604 + { "pf_fixed", STAT_OFFSET(pf_fixed), NULL },
13605 + { "pf_guest", STAT_OFFSET(pf_guest), NULL },
13606 + { "tlb_flush", STAT_OFFSET(tlb_flush), NULL },
13607 + { "invlpg", STAT_OFFSET(invlpg), NULL },
13608 + { "exits", STAT_OFFSET(exits), NULL },
13609 + { "io_exits", STAT_OFFSET(io_exits), NULL },
13610 + { "mmio_exits", STAT_OFFSET(mmio_exits), NULL },
13611 + { "signal_exits", STAT_OFFSET(signal_exits), NULL },
13612 + { "irq_window", STAT_OFFSET(irq_window_exits), NULL },
13613 + { "halt_exits", STAT_OFFSET(halt_exits), NULL },
13614 + { "halt_wakeup", STAT_OFFSET(halt_wakeup), NULL },
13615 + { "request_irq", STAT_OFFSET(request_irq_exits), NULL },
13616 + { "irq_exits", STAT_OFFSET(irq_exits), NULL },
13617 + { "light_exits", STAT_OFFSET(light_exits), NULL },
13618 + { "efer_reload", STAT_OFFSET(efer_reload), NULL },
13619 + { NULL, 0, NULL }
13622 static struct dentry *debugfs_dir;
13623 @@ -2505,7 +2505,7 @@ static int kvm_vcpu_ioctl_translate(stru
13624 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
13625 struct kvm_interrupt *irq)
13627 - if (irq->irq < 0 || irq->irq >= 256)
13628 + if (irq->irq >= 256)
13630 if (irqchip_in_kernel(vcpu->kvm))
13632 @@ -3250,6 +3250,9 @@ static struct miscdevice kvm_dev = {
13642 diff -urNp linux-2.6.24.4/drivers/kvm/svm.c linux-2.6.24.4/drivers/kvm/svm.c
13643 --- linux-2.6.24.4/drivers/kvm/svm.c 2008-03-24 14:49:18.000000000 -0400
13644 +++ linux-2.6.24.4/drivers/kvm/svm.c 2008-03-26 20:21:08.000000000 -0400
13645 @@ -1307,8 +1307,20 @@ static void reload_tss(struct kvm_vcpu *
13646 int cpu = raw_smp_processor_id();
13648 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
13650 +#ifdef CONFIG_PAX_KERNEXEC
13651 + unsigned long cr0;
13653 + pax_open_kernel(cr0);
13656 svm_data->tss_desc->type = 9; //available 32/64-bit TSS
13659 +#ifdef CONFIG_PAX_KERNEXEC
13660 + pax_close_kernel(cr0);
13665 static void pre_svm_run(struct vcpu_svm *svm)
13666 diff -urNp linux-2.6.24.4/drivers/kvm/vmx.c linux-2.6.24.4/drivers/kvm/vmx.c
13667 --- linux-2.6.24.4/drivers/kvm/vmx.c 2008-03-24 14:49:18.000000000 -0400
13668 +++ linux-2.6.24.4/drivers/kvm/vmx.c 2008-03-26 20:21:08.000000000 -0400
13669 @@ -335,10 +335,24 @@ static void reload_tss(void)
13670 struct descriptor_table gdt;
13671 struct segment_descriptor *descs;
13673 +#ifdef CONFIG_PAX_KERNEXEC
13674 + unsigned long cr0;
13678 descs = (void *)gdt.base;
13680 +#ifdef CONFIG_PAX_KERNEXEC
13681 + pax_open_kernel(cr0);
13684 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
13687 +#ifdef CONFIG_PAX_KERNEXEC
13688 + pax_close_kernel(cr0);
13694 @@ -2322,7 +2336,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
13696 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
13698 - asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
13699 + asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
13702 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
13703 diff -urNp linux-2.6.24.4/drivers/md/bitmap.c linux-2.6.24.4/drivers/md/bitmap.c
13704 --- linux-2.6.24.4/drivers/md/bitmap.c 2008-03-24 14:49:18.000000000 -0400
13705 +++ linux-2.6.24.4/drivers/md/bitmap.c 2008-03-26 20:21:08.000000000 -0400
13708 # define PRINTK(x...) printk(KERN_DEBUG x)
13710 -# define PRINTK(x...)
13711 +# define PRINTK(x...) do {} while (0)
13715 diff -urNp linux-2.6.24.4/drivers/mtd/devices/doc2000.c linux-2.6.24.4/drivers/mtd/devices/doc2000.c
13716 --- linux-2.6.24.4/drivers/mtd/devices/doc2000.c 2008-03-24 14:49:18.000000000 -0400
13717 +++ linux-2.6.24.4/drivers/mtd/devices/doc2000.c 2008-03-26 20:21:08.000000000 -0400
13718 @@ -632,7 +632,7 @@ static int doc_read(struct mtd_info *mtd
13719 len = ((from | 0x1ff) + 1) - from;
13721 /* The ECC will not be calculated correctly if less than 512 is read */
13722 - if (len != 0x200 && eccbuf)
13723 + if (len != 0x200)
13724 printk(KERN_WARNING
13725 "ECC needs a full sector read (adr: %lx size %lx)\n",
13726 (long) from, (long) len);
13727 diff -urNp linux-2.6.24.4/drivers/mtd/devices/doc2001.c linux-2.6.24.4/drivers/mtd/devices/doc2001.c
13728 --- linux-2.6.24.4/drivers/mtd/devices/doc2001.c 2008-03-24 14:49:18.000000000 -0400
13729 +++ linux-2.6.24.4/drivers/mtd/devices/doc2001.c 2008-03-26 20:21:08.000000000 -0400
13730 @@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt
13731 /* Don't allow read past end of device */
13732 if (from >= this->totlen)
13737 /* Don't allow a single read to cross a 512-byte block boundary */
13738 if (from + len > ((from | 0x1ff) + 1))
13739 diff -urNp linux-2.6.24.4/drivers/mtd/devices/doc2001plus.c linux-2.6.24.4/drivers/mtd/devices/doc2001plus.c
13740 --- linux-2.6.24.4/drivers/mtd/devices/doc2001plus.c 2008-03-24 14:49:18.000000000 -0400
13741 +++ linux-2.6.24.4/drivers/mtd/devices/doc2001plus.c 2008-03-26 20:21:08.000000000 -0400
13742 @@ -748,7 +748,7 @@ static int doc_write(struct mtd_info *mt
13743 WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
13745 /* On interleaved devices the flags for 2nd half 512 are before data */
13746 - if (eccbuf && before)
13750 /* issue the Serial Data In command to initial the Page Program process */
13751 diff -urNp linux-2.6.24.4/drivers/mtd/devices/slram.c linux-2.6.24.4/drivers/mtd/devices/slram.c
13752 --- linux-2.6.24.4/drivers/mtd/devices/slram.c 2008-03-24 14:49:18.000000000 -0400
13753 +++ linux-2.6.24.4/drivers/mtd/devices/slram.c 2008-03-26 20:21:08.000000000 -0400
13754 @@ -270,7 +270,7 @@ static int parse_cmdline(char *devname,
13756 T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
13757 devname, devstart, devlength);
13758 - if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
13759 + if (devlength % SLRAM_BLK_SZ != 0) {
13760 E("slram: Illegal start / length parameter.\n");
13763 diff -urNp linux-2.6.24.4/drivers/mtd/ubi/build.c linux-2.6.24.4/drivers/mtd/ubi/build.c
13764 --- linux-2.6.24.4/drivers/mtd/ubi/build.c 2008-03-24 14:49:18.000000000 -0400
13765 +++ linux-2.6.24.4/drivers/mtd/ubi/build.c 2008-03-26 20:21:08.000000000 -0400
13766 @@ -753,7 +753,7 @@ static int __init bytes_str_to_int(const
13767 unsigned long result;
13769 result = simple_strtoul(str, &endp, 0);
13770 - if (str == endp || result < 0) {
13771 + if (str == endp) {
13772 printk("UBI error: incorrect bytes count: \"%s\"\n", str);
13775 diff -urNp linux-2.6.24.4/drivers/net/eepro100.c linux-2.6.24.4/drivers/net/eepro100.c
13776 --- linux-2.6.24.4/drivers/net/eepro100.c 2008-03-24 14:49:18.000000000 -0400
13777 +++ linux-2.6.24.4/drivers/net/eepro100.c 2008-03-26 20:21:08.000000000 -0400
13778 @@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
13779 # define rx_align(skb) skb_reserve((skb), 2)
13780 # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
13782 -# define rx_align(skb)
13783 +# define rx_align(skb) do {} while (0)
13784 # define RxFD_ALIGNMENT
13787 @@ -2340,33 +2340,33 @@ static void __devexit eepro100_remove_on
13790 static struct pci_device_id eepro100_pci_tbl[] = {
13791 - { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
13792 - { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
13793 - { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
13794 - { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
13795 - { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
13796 - { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
13797 - { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
13798 - { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
13799 - { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
13800 - { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
13801 - { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
13802 - { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
13803 - { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
13804 - { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
13805 - { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
13806 - { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
13807 - { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
13808 - { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
13809 - { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
13810 - { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
13811 - { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
13812 - { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
13813 - { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
13814 - { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
13815 - { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
13816 - { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
13818 + { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13819 + { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13820 + { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13821 + { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13822 + { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13823 + { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13824 + { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13825 + { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13826 + { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13827 + { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13828 + { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13829 + { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13830 + { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13831 + { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13832 + { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13833 + { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13834 + { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13835 + { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13836 + { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13837 + { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13838 + { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13839 + { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13840 + { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13841 + { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13842 + { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13843 + { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13844 + { 0, 0, 0, 0, 0, 0, 0 }
13846 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
13848 diff -urNp linux-2.6.24.4/drivers/net/irda/vlsi_ir.c linux-2.6.24.4/drivers/net/irda/vlsi_ir.c
13849 --- linux-2.6.24.4/drivers/net/irda/vlsi_ir.c 2008-03-24 14:49:18.000000000 -0400
13850 +++ linux-2.6.24.4/drivers/net/irda/vlsi_ir.c 2008-03-26 20:21:08.000000000 -0400
13851 @@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
13852 /* no race - tx-ring already empty */
13853 vlsi_set_baud(idev, iobase);
13854 netif_wake_queue(ndev);
13859 /* keep the speed change pending like it would
13860 * for any len>0 packet. tx completion interrupt
13861 * will apply it when the tx ring becomes empty.
13864 spin_unlock_irqrestore(&idev->lock, flags);
13865 dev_kfree_skb_any(skb);
13867 diff -urNp linux-2.6.24.4/drivers/net/pcnet32.c linux-2.6.24.4/drivers/net/pcnet32.c
13868 --- linux-2.6.24.4/drivers/net/pcnet32.c 2008-03-24 14:49:18.000000000 -0400
13869 +++ linux-2.6.24.4/drivers/net/pcnet32.c 2008-03-26 20:21:08.000000000 -0400
13870 @@ -82,7 +82,7 @@ static int cards_found;
13872 * VLB I/O addresses
13874 -static unsigned int pcnet32_portlist[] __initdata =
13875 +static unsigned int pcnet32_portlist[] __devinitdata =
13876 { 0x300, 0x320, 0x340, 0x360, 0 };
13878 static int pcnet32_debug = 0;
13879 diff -urNp linux-2.6.24.4/drivers/net/tg3.h linux-2.6.24.4/drivers/net/tg3.h
13880 --- linux-2.6.24.4/drivers/net/tg3.h 2008-03-24 14:49:18.000000000 -0400
13881 +++ linux-2.6.24.4/drivers/net/tg3.h 2008-03-26 20:21:08.000000000 -0400
13882 @@ -102,6 +102,7 @@
13883 #define CHIPREV_ID_5750_A0 0x4000
13884 #define CHIPREV_ID_5750_A1 0x4001
13885 #define CHIPREV_ID_5750_A3 0x4003
13886 +#define CHIPREV_ID_5750_C1 0x4201
13887 #define CHIPREV_ID_5750_C2 0x4202
13888 #define CHIPREV_ID_5752_A0_HW 0x5000
13889 #define CHIPREV_ID_5752_A0 0x6000
13890 diff -urNp linux-2.6.24.4/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.24.4/drivers/pci/hotplug/cpqphp_nvram.c
13891 --- linux-2.6.24.4/drivers/pci/hotplug/cpqphp_nvram.c 2008-03-24 14:49:18.000000000 -0400
13892 +++ linux-2.6.24.4/drivers/pci/hotplug/cpqphp_nvram.c 2008-03-26 20:21:08.000000000 -0400
13893 @@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
13895 void compaq_nvram_init (void __iomem *rom_start)
13898 +#ifndef CONFIG_PAX_KERNEXEC
13900 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
13904 dbg("int15 entry = %p\n", compaq_int15_entry_point);
13906 /* initialize our int15 lock */
13907 diff -urNp linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv.c linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv.c
13908 --- linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv.c 2008-03-24 14:49:18.000000000 -0400
13909 +++ linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv.c 2008-03-26 20:21:08.000000000 -0400
13910 @@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
13911 .port_type = PCIE_RC_PORT,
13912 .service_type = PCIE_PORT_SERVICE_AER,
13914 - { /* end: all zeroes */ }
13915 + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13918 static struct pci_error_handlers aer_error_handlers = {
13919 diff -urNp linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv_core.c
13920 --- linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv_core.c 2008-03-24 14:49:18.000000000 -0400
13921 +++ linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv_core.c 2008-03-26 20:21:08.000000000 -0400
13922 @@ -661,7 +661,7 @@ static void aer_isr_one_error(struct pci
13923 struct aer_err_source *e_src)
13925 struct device *s_device;
13926 - struct aer_err_info e_info = {0, 0, 0,};
13927 + struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
13931 diff -urNp linux-2.6.24.4/drivers/pci/pcie/portdrv_pci.c linux-2.6.24.4/drivers/pci/pcie/portdrv_pci.c
13932 --- linux-2.6.24.4/drivers/pci/pcie/portdrv_pci.c 2008-03-24 14:49:18.000000000 -0400
13933 +++ linux-2.6.24.4/drivers/pci/pcie/portdrv_pci.c 2008-03-26 20:21:08.000000000 -0400
13934 @@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
13935 static const struct pci_device_id port_pci_ids[] = { {
13936 /* handle any PCI-Express port */
13937 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
13938 - }, { /* end: all zeroes */ }
13939 + }, { 0, 0, 0, 0, 0, 0, 0 }
13941 MODULE_DEVICE_TABLE(pci, port_pci_ids);
13943 diff -urNp linux-2.6.24.4/drivers/pci/proc.c linux-2.6.24.4/drivers/pci/proc.c
13944 --- linux-2.6.24.4/drivers/pci/proc.c 2008-03-24 14:49:18.000000000 -0400
13945 +++ linux-2.6.24.4/drivers/pci/proc.c 2008-03-26 20:21:08.000000000 -0400
13946 @@ -467,7 +467,15 @@ static int __init pci_proc_init(void)
13948 struct proc_dir_entry *entry;
13949 struct pci_dev *dev = NULL;
13950 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
13951 +#ifdef CONFIG_GRKERNSEC_PROC_USER
13952 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
13953 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
13954 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
13957 proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
13959 entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
13961 entry->proc_fops = &proc_bus_pci_dev_operations;
13962 diff -urNp linux-2.6.24.4/drivers/pcmcia/ti113x.h linux-2.6.24.4/drivers/pcmcia/ti113x.h
13963 --- linux-2.6.24.4/drivers/pcmcia/ti113x.h 2008-03-24 14:49:18.000000000 -0400
13964 +++ linux-2.6.24.4/drivers/pcmcia/ti113x.h 2008-03-26 20:21:08.000000000 -0400
13965 @@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
13966 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
13967 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
13970 + { 0, 0, 0, 0, 0, 0, 0 }
13973 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
13974 diff -urNp linux-2.6.24.4/drivers/pcmcia/yenta_socket.c linux-2.6.24.4/drivers/pcmcia/yenta_socket.c
13975 --- linux-2.6.24.4/drivers/pcmcia/yenta_socket.c 2008-03-24 14:49:18.000000000 -0400
13976 +++ linux-2.6.24.4/drivers/pcmcia/yenta_socket.c 2008-03-26 20:21:08.000000000 -0400
13977 @@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
13979 /* match any cardbus bridge */
13980 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
13981 - { /* all zeroes */ }
13982 + { 0, 0, 0, 0, 0, 0, 0 }
13984 MODULE_DEVICE_TABLE(pci, yenta_table);
13986 diff -urNp linux-2.6.24.4/drivers/pnp/pnpbios/bioscalls.c linux-2.6.24.4/drivers/pnp/pnpbios/bioscalls.c
13987 --- linux-2.6.24.4/drivers/pnp/pnpbios/bioscalls.c 2008-03-24 14:49:18.000000000 -0400
13988 +++ linux-2.6.24.4/drivers/pnp/pnpbios/bioscalls.c 2008-03-26 20:21:08.000000000 -0400
13989 @@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
13990 set_limit(gdt[(selname) >> 3], size); \
13993 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
13994 +static struct desc_struct bad_bios_desc __read_only = { 0, 0x00409300 };
13997 * At some point we want to use this stack frame pointer to unwind
13998 @@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func
13999 struct desc_struct save_desc_40;
14002 +#ifdef CONFIG_PAX_KERNEXEC
14003 + unsigned long cr0;
14007 * PnP BIOSes are generally not terribly re-entrant.
14008 * Also, don't rely on them to save everything correctly.
14009 @@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func
14012 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
14014 +#ifdef CONFIG_PAX_KERNEXEC
14015 + pax_open_kernel(cr0);
14018 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
14020 +#ifdef CONFIG_PAX_KERNEXEC
14021 + pax_close_kernel(cr0);
14024 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
14025 spin_lock_irqsave(&pnp_bios_lock, flags);
14027 @@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func
14029 spin_unlock_irqrestore(&pnp_bios_lock, flags);
14031 +#ifdef CONFIG_PAX_KERNEXEC
14032 + pax_open_kernel(cr0);
14035 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
14037 +#ifdef CONFIG_PAX_KERNEXEC
14038 + pax_close_kernel(cr0);
14043 /* If we get here and this is set then the PnP BIOS faulted on us. */
14044 @@ -469,14 +491,22 @@ int pnp_bios_read_escd(char *data, u32 n
14048 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
14049 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
14053 +#ifdef CONFIG_PAX_KERNEXEC
14054 + unsigned long cr0;
14057 spin_lock_init(&pnp_bios_lock);
14058 pnp_bios_callpoint.offset = header->fields.pm16offset;
14059 pnp_bios_callpoint.segment = PNP_CS16;
14061 +#ifdef CONFIG_PAX_KERNEXEC
14062 + pax_open_kernel(cr0);
14065 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
14066 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
14067 for (i = 0; i < NR_CPUS; i++) {
14068 @@ -489,4 +519,9 @@ void pnpbios_calls_init(union pnp_bios_i
14069 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
14070 __va(header->fields.pm16dseg));
14073 +#ifdef CONFIG_PAX_KERNEXEC
14074 + pax_close_kernel(cr0);
14078 diff -urNp linux-2.6.24.4/drivers/pnp/quirks.c linux-2.6.24.4/drivers/pnp/quirks.c
14079 --- linux-2.6.24.4/drivers/pnp/quirks.c 2008-03-24 14:49:18.000000000 -0400
14080 +++ linux-2.6.24.4/drivers/pnp/quirks.c 2008-03-26 20:21:08.000000000 -0400
14081 @@ -128,7 +128,7 @@ static struct pnp_fixup pnp_fixups[] = {
14082 {"CTL0043", quirk_sb16audio_resources},
14083 {"CTL0044", quirk_sb16audio_resources},
14084 {"CTL0045", quirk_sb16audio_resources},
14089 void pnp_fixup_device(struct pnp_dev *dev)
14090 diff -urNp linux-2.6.24.4/drivers/pnp/resource.c linux-2.6.24.4/drivers/pnp/resource.c
14091 --- linux-2.6.24.4/drivers/pnp/resource.c 2008-03-24 14:49:18.000000000 -0400
14092 +++ linux-2.6.24.4/drivers/pnp/resource.c 2008-03-26 20:21:08.000000000 -0400
14093 @@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i
14096 /* check if the resource is valid */
14097 - if (*irq < 0 || *irq > 15)
14101 /* check if the resource is reserved */
14102 @@ -414,7 +414,7 @@ int pnp_check_dma(struct pnp_dev *dev, i
14105 /* check if the resource is valid */
14106 - if (*dma < 0 || *dma == 4 || *dma > 7)
14107 + if (*dma == 4 || *dma > 7)
14110 /* check if the resource is reserved */
14111 diff -urNp linux-2.6.24.4/drivers/scsi/scsi_logging.h linux-2.6.24.4/drivers/scsi/scsi_logging.h
14112 --- linux-2.6.24.4/drivers/scsi/scsi_logging.h 2008-03-24 14:49:18.000000000 -0400
14113 +++ linux-2.6.24.4/drivers/scsi/scsi_logging.h 2008-03-26 20:21:08.000000000 -0400
14114 @@ -51,7 +51,7 @@ do { \
14118 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
14119 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
14120 #endif /* CONFIG_SCSI_LOGGING */
14123 diff -urNp linux-2.6.24.4/drivers/serial/8250_pci.c linux-2.6.24.4/drivers/serial/8250_pci.c
14124 --- linux-2.6.24.4/drivers/serial/8250_pci.c 2008-03-24 14:49:18.000000000 -0400
14125 +++ linux-2.6.24.4/drivers/serial/8250_pci.c 2008-03-26 20:21:08.000000000 -0400
14126 @@ -2712,7 +2712,7 @@ static struct pci_device_id serial_pci_t
14127 PCI_ANY_ID, PCI_ANY_ID,
14128 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
14129 0xffff00, pbn_default },
14131 + { 0, 0, 0, 0, 0, 0, 0 }
14134 static struct pci_driver serial_pci_driver = {
14135 diff -urNp linux-2.6.24.4/drivers/usb/class/cdc-acm.c linux-2.6.24.4/drivers/usb/class/cdc-acm.c
14136 --- linux-2.6.24.4/drivers/usb/class/cdc-acm.c 2008-03-24 14:49:18.000000000 -0400
14137 +++ linux-2.6.24.4/drivers/usb/class/cdc-acm.c 2008-03-26 20:21:08.000000000 -0400
14138 @@ -1199,7 +1199,7 @@ static struct usb_device_id acm_ids[] =
14139 USB_CDC_ACM_PROTO_AT_CDMA) },
14141 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
14143 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
14146 MODULE_DEVICE_TABLE (usb, acm_ids);
14147 diff -urNp linux-2.6.24.4/drivers/usb/class/usblp.c linux-2.6.24.4/drivers/usb/class/usblp.c
14148 --- linux-2.6.24.4/drivers/usb/class/usblp.c 2008-03-24 14:49:18.000000000 -0400
14149 +++ linux-2.6.24.4/drivers/usb/class/usblp.c 2008-03-26 20:21:08.000000000 -0400
14150 @@ -227,7 +227,7 @@ static const struct quirk_printer_struct
14151 { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
14152 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
14153 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
14158 static int usblp_wwait(struct usblp *usblp, int nonblock);
14159 @@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
14160 { USB_INTERFACE_INFO(7, 1, 2) },
14161 { USB_INTERFACE_INFO(7, 1, 3) },
14162 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
14163 - { } /* Terminating entry */
14164 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
14167 MODULE_DEVICE_TABLE (usb, usblp_ids);
14168 diff -urNp linux-2.6.24.4/drivers/usb/core/hub.c linux-2.6.24.4/drivers/usb/core/hub.c
14169 --- linux-2.6.24.4/drivers/usb/core/hub.c 2008-03-24 14:49:18.000000000 -0400
14170 +++ linux-2.6.24.4/drivers/usb/core/hub.c 2008-03-26 20:21:08.000000000 -0400
14171 @@ -2884,7 +2884,7 @@ static struct usb_device_id hub_id_table
14172 .bDeviceClass = USB_CLASS_HUB},
14173 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
14174 .bInterfaceClass = USB_CLASS_HUB},
14175 - { } /* Terminating entry */
14176 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
14179 MODULE_DEVICE_TABLE (usb, hub_id_table);
14180 diff -urNp linux-2.6.24.4/drivers/usb/host/ehci-pci.c linux-2.6.24.4/drivers/usb/host/ehci-pci.c
14181 --- linux-2.6.24.4/drivers/usb/host/ehci-pci.c 2008-03-24 14:49:18.000000000 -0400
14182 +++ linux-2.6.24.4/drivers/usb/host/ehci-pci.c 2008-03-26 20:21:08.000000000 -0400
14183 @@ -374,7 +374,7 @@ static const struct pci_device_id pci_id
14184 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
14185 .driver_data = (unsigned long) &ehci_pci_hc_driver,
14187 - { /* end: all zeroes */ }
14188 + { 0, 0, 0, 0, 0, 0, 0 }
14190 MODULE_DEVICE_TABLE(pci, pci_ids);
14192 diff -urNp linux-2.6.24.4/drivers/usb/host/uhci-hcd.c linux-2.6.24.4/drivers/usb/host/uhci-hcd.c
14193 --- linux-2.6.24.4/drivers/usb/host/uhci-hcd.c 2008-03-24 14:49:18.000000000 -0400
14194 +++ linux-2.6.24.4/drivers/usb/host/uhci-hcd.c 2008-03-26 20:21:08.000000000 -0400
14195 @@ -893,7 +893,7 @@ static const struct pci_device_id uhci_p
14196 /* handle any USB UHCI controller */
14197 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
14198 .driver_data = (unsigned long) &uhci_driver,
14199 - }, { /* end: all zeroes */ }
14200 + }, { 0, 0, 0, 0, 0, 0, 0 }
14203 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
14204 diff -urNp linux-2.6.24.4/drivers/usb/storage/debug.h linux-2.6.24.4/drivers/usb/storage/debug.h
14205 --- linux-2.6.24.4/drivers/usb/storage/debug.h 2008-03-24 14:49:18.000000000 -0400
14206 +++ linux-2.6.24.4/drivers/usb/storage/debug.h 2008-03-26 20:21:08.000000000 -0400
14207 @@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
14208 #define US_DEBUGPX(x...) printk( x )
14209 #define US_DEBUG(x) x
14211 -#define US_DEBUGP(x...)
14212 -#define US_DEBUGPX(x...)
14213 -#define US_DEBUG(x)
14214 +#define US_DEBUGP(x...) do {} while (0)
14215 +#define US_DEBUGPX(x...) do {} while (0)
14216 +#define US_DEBUG(x) do {} while (0)
14220 diff -urNp linux-2.6.24.4/drivers/usb/storage/usb.c linux-2.6.24.4/drivers/usb/storage/usb.c
14221 --- linux-2.6.24.4/drivers/usb/storage/usb.c 2008-03-24 14:49:18.000000000 -0400
14222 +++ linux-2.6.24.4/drivers/usb/storage/usb.c 2008-03-26 20:21:08.000000000 -0400
14223 @@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_
14226 /* Terminating entry */
14228 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
14231 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
14232 @@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_
14235 /* Terminating entry */
14237 + { NULL, NULL, 0, 0, NULL }
14241 diff -urNp linux-2.6.24.4/drivers/video/fbcmap.c linux-2.6.24.4/drivers/video/fbcmap.c
14242 --- linux-2.6.24.4/drivers/video/fbcmap.c 2008-03-24 14:49:18.000000000 -0400
14243 +++ linux-2.6.24.4/drivers/video/fbcmap.c 2008-03-26 20:21:08.000000000 -0400
14244 @@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
14245 int rc, size = cmap->len * sizeof(u16);
14246 struct fb_cmap umap;
14248 - if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
14249 - !info->fbops->fb_setcmap))
14250 + if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
14253 memset(&umap, 0, sizeof(struct fb_cmap));
14254 diff -urNp linux-2.6.24.4/drivers/video/fbmem.c linux-2.6.24.4/drivers/video/fbmem.c
14255 --- linux-2.6.24.4/drivers/video/fbmem.c 2008-03-24 14:49:18.000000000 -0400
14256 +++ linux-2.6.24.4/drivers/video/fbmem.c 2008-03-26 20:21:08.000000000 -0400
14257 @@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in
14258 image->dx += image->width + 8;
14260 } else if (rotate == FB_ROTATE_UD) {
14261 - for (x = 0; x < num && image->dx >= 0; x++) {
14262 + for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
14263 info->fbops->fb_imageblit(info, image);
14264 image->dx -= image->width + 8;
14266 @@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in
14267 image->dy += image->height + 8;
14269 } else if (rotate == FB_ROTATE_CCW) {
14270 - for (x = 0; x < num && image->dy >= 0; x++) {
14271 + for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
14272 info->fbops->fb_imageblit(info, image);
14273 image->dy -= image->height + 8;
14275 @@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil
14276 case FBIOPUT_CON2FBMAP:
14277 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
14279 - if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
14280 + if (con2fb.console > MAX_NR_CONSOLES)
14282 - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
14283 + if (con2fb.framebuffer >= FB_MAX)
14286 if (!registered_fb[con2fb.framebuffer])
14287 diff -urNp linux-2.6.24.4/drivers/video/fbmon.c linux-2.6.24.4/drivers/video/fbmon.c
14288 --- linux-2.6.24.4/drivers/video/fbmon.c 2008-03-24 14:49:18.000000000 -0400
14289 +++ linux-2.6.24.4/drivers/video/fbmon.c 2008-03-26 20:21:08.000000000 -0400
14292 #define DPRINTK(fmt, args...) printk(fmt,## args)
14294 -#define DPRINTK(fmt, args...)
14295 +#define DPRINTK(fmt, args...) do {} while (0)
14298 #define FBMON_FIX_HEADER 1
14299 diff -urNp linux-2.6.24.4/drivers/video/i810/i810_accel.c linux-2.6.24.4/drivers/video/i810/i810_accel.c
14300 --- linux-2.6.24.4/drivers/video/i810/i810_accel.c 2008-03-24 14:49:18.000000000 -0400
14301 +++ linux-2.6.24.4/drivers/video/i810/i810_accel.c 2008-03-26 20:21:08.000000000 -0400
14302 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct
14305 printk("ringbuffer lockup!!!\n");
14306 + printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
14307 i810_report_error(mmio);
14308 par->dev_flags |= LOCKUP;
14309 info->pixmap.scan_align = 1;
14310 diff -urNp linux-2.6.24.4/drivers/video/i810/i810_main.c linux-2.6.24.4/drivers/video/i810/i810_main.c
14311 --- linux-2.6.24.4/drivers/video/i810/i810_main.c 2008-03-24 14:49:18.000000000 -0400
14312 +++ linux-2.6.24.4/drivers/video/i810/i810_main.c 2008-03-26 20:21:08.000000000 -0400
14313 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
14314 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
14315 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
14316 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
14318 + { 0, 0, 0, 0, 0, 0, 0 },
14321 static struct pci_driver i810fb_driver = {
14322 @@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
14323 int size = ((cursor->image.width + 7) >> 3) *
14324 cursor->image.height;
14326 - u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
14327 + u8 *data = kmalloc(64 * 8, GFP_KERNEL);
14331 diff -urNp linux-2.6.24.4/drivers/video/modedb.c linux-2.6.24.4/drivers/video/modedb.c
14332 --- linux-2.6.24.4/drivers/video/modedb.c 2008-03-24 14:49:18.000000000 -0400
14333 +++ linux-2.6.24.4/drivers/video/modedb.c 2008-03-26 20:21:08.000000000 -0400
14334 @@ -37,232 +37,232 @@ static const struct fb_videomode modedb[
14336 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
14337 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
14338 - 0, FB_VMODE_NONINTERLACED
14339 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14341 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
14342 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
14343 - 0, FB_VMODE_NONINTERLACED
14344 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14346 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
14347 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
14348 - 0, FB_VMODE_NONINTERLACED
14349 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14351 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
14352 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
14353 - 0, FB_VMODE_INTERLACED
14354 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
14356 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
14357 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
14358 - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14359 + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14361 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
14362 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
14363 - 0, FB_VMODE_NONINTERLACED
14364 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14366 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
14367 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
14368 - 0, FB_VMODE_NONINTERLACED
14369 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14371 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
14372 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
14373 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14374 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14376 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
14377 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
14378 - 0, FB_VMODE_NONINTERLACED
14379 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14381 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
14382 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
14383 - 0, FB_VMODE_INTERLACED
14384 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
14386 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
14387 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
14388 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14389 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14391 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
14392 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
14393 - 0, FB_VMODE_NONINTERLACED
14394 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14396 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
14397 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
14398 - 0, FB_VMODE_NONINTERLACED
14399 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14401 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
14402 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
14403 - 0, FB_VMODE_NONINTERLACED
14404 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14406 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
14407 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
14408 - 0, FB_VMODE_NONINTERLACED
14409 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14411 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
14412 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
14413 - 0, FB_VMODE_NONINTERLACED
14414 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14416 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
14417 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
14418 - 0, FB_VMODE_INTERLACED
14419 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
14421 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
14422 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
14423 - 0, FB_VMODE_NONINTERLACED
14424 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14426 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
14427 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
14428 - 0, FB_VMODE_NONINTERLACED
14429 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14431 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
14432 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
14433 - 0, FB_VMODE_NONINTERLACED
14434 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14436 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
14437 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
14438 - 0, FB_VMODE_NONINTERLACED
14439 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14441 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
14442 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
14443 - 0, FB_VMODE_NONINTERLACED
14444 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14446 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
14447 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
14448 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14449 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14451 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
14452 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
14453 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14454 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14456 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
14457 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
14458 - 0, FB_VMODE_NONINTERLACED
14459 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14461 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
14462 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
14463 - 0, FB_VMODE_NONINTERLACED
14464 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14466 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
14467 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
14468 - 0, FB_VMODE_NONINTERLACED
14469 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14471 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
14472 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
14473 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14474 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14476 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
14477 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
14478 - 0, FB_VMODE_NONINTERLACED
14479 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14481 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
14482 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
14483 - 0, FB_VMODE_NONINTERLACED
14484 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14486 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
14487 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
14488 - 0, FB_VMODE_NONINTERLACED
14489 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14491 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
14492 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
14493 - 0, FB_VMODE_NONINTERLACED
14494 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14496 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
14497 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
14498 - 0, FB_VMODE_NONINTERLACED
14499 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14501 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
14502 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
14503 - 0, FB_VMODE_NONINTERLACED
14504 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14506 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
14507 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
14508 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14509 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14511 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
14512 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
14513 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14514 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14516 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
14517 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
14518 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14519 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14521 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
14522 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
14523 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14524 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14526 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
14527 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
14528 - 0, FB_VMODE_NONINTERLACED
14529 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14531 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
14532 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
14533 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14534 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14536 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
14537 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
14538 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14539 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14541 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
14542 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
14543 - 0, FB_VMODE_NONINTERLACED
14544 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14546 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
14547 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
14548 - 0, FB_VMODE_NONINTERLACED
14549 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14551 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
14552 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
14553 - 0, FB_VMODE_DOUBLE
14554 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14556 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
14557 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
14558 - 0, FB_VMODE_DOUBLE
14559 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14561 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
14562 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
14563 - 0, FB_VMODE_DOUBLE
14564 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14566 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
14567 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
14568 - 0, FB_VMODE_DOUBLE
14569 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14571 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
14572 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
14573 - 0, FB_VMODE_DOUBLE
14574 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14576 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
14577 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
14578 - 0, FB_VMODE_DOUBLE
14579 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14581 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
14582 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
14583 - 0, FB_VMODE_DOUBLE
14584 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14586 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
14587 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
14588 - 0, FB_VMODE_DOUBLE
14589 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14591 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
14592 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
14593 - 0, FB_VMODE_DOUBLE
14594 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14596 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
14597 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
14598 - 0, FB_VMODE_DOUBLE
14599 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14601 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
14602 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
14603 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
14604 - FB_VMODE_NONINTERLACED
14605 + FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14607 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
14608 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
14609 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14610 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14612 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
14613 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
14614 - 0, FB_VMODE_NONINTERLACED
14615 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14617 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
14618 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
14619 - 0, FB_VMODE_NONINTERLACED
14620 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14624 diff -urNp linux-2.6.24.4/drivers/video/uvesafb.c linux-2.6.24.4/drivers/video/uvesafb.c
14625 --- linux-2.6.24.4/drivers/video/uvesafb.c 2008-03-24 14:49:18.000000000 -0400
14626 +++ linux-2.6.24.4/drivers/video/uvesafb.c 2008-03-26 20:21:08.000000000 -0400
14627 @@ -117,7 +117,7 @@ static int uvesafb_helper_start(void)
14631 - return call_usermodehelper(v86d_path, argv, envp, 1);
14632 + return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
14636 diff -urNp linux-2.6.24.4/drivers/video/vesafb.c linux-2.6.24.4/drivers/video/vesafb.c
14637 --- linux-2.6.24.4/drivers/video/vesafb.c 2008-03-24 14:49:18.000000000 -0400
14638 +++ linux-2.6.24.4/drivers/video/vesafb.c 2008-03-26 20:21:08.000000000 -0400
14642 #include <linux/module.h>
14643 +#include <linux/moduleloader.h>
14644 #include <linux/kernel.h>
14645 #include <linux/errno.h>
14646 #include <linux/string.h>
14647 @@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
14648 static int vram_total __initdata; /* Set total amount of memory */
14649 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
14650 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
14651 -static void (*pmi_start)(void) __read_mostly;
14652 -static void (*pmi_pal) (void) __read_mostly;
14653 +static void (*pmi_start)(void) __read_only;
14654 +static void (*pmi_pal) (void) __read_only;
14655 static int depth __read_mostly;
14656 static int vga_compat __read_mostly;
14657 /* --------------------------------------------------------------------- */
14658 @@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
14659 unsigned int size_vmode;
14660 unsigned int size_remap;
14661 unsigned int size_total;
14662 + void *pmi_code = NULL;
14664 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
14666 @@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
14667 size_remap = size_total;
14668 vesafb_fix.smem_len = size_remap;
14671 - screen_info.vesapm_seg = 0;
14674 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
14675 printk(KERN_WARNING
14676 "vesafb: cannot reserve video memory at 0x%lx\n",
14677 @@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
14678 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
14679 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
14683 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14684 + pmi_code = module_alloc_exec(screen_info.vesapm_size);
14686 +#elif !defined(CONFIG_PAX_KERNEXEC)
14691 + screen_info.vesapm_seg = 0;
14693 if (screen_info.vesapm_seg) {
14694 - printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
14695 - screen_info.vesapm_seg,screen_info.vesapm_off);
14696 + printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
14697 + screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
14700 if (screen_info.vesapm_seg < 0xc000)
14701 @@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
14703 if (ypan || pmi_setpal) {
14704 unsigned short *pmi_base;
14705 - pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
14706 - pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
14707 - pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
14709 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14710 + unsigned long cr0;
14713 + pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
14715 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14716 + pax_open_kernel(cr0);
14717 + memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
14719 + pmi_code = pmi_base;
14722 + pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
14723 + pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
14725 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14726 + pmi_start = ktva_ktla(pmi_start);
14727 + pmi_pal = ktva_ktla(pmi_pal);
14728 + pax_close_kernel(cr0);
14731 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
14733 printk(KERN_INFO "vesafb: pmi: ports = ");
14734 @@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
14735 info->node, info->fix.id);
14739 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14740 + module_free_exec(NULL, pmi_code);
14743 if (info->screen_base)
14744 iounmap(info->screen_base);
14745 framebuffer_release(info);
14746 diff -urNp linux-2.6.24.4/fs/9p/vfs_inode.c linux-2.6.24.4/fs/9p/vfs_inode.c
14747 --- linux-2.6.24.4/fs/9p/vfs_inode.c 2008-03-24 14:49:18.000000000 -0400
14748 +++ linux-2.6.24.4/fs/9p/vfs_inode.c 2008-03-26 20:21:08.000000000 -0400
14749 @@ -996,7 +996,7 @@ static void *v9fs_vfs_follow_link(struct
14751 static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
14753 - char *s = nd_get_link(nd);
14754 + const char *s = nd_get_link(nd);
14756 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
14758 diff -urNp linux-2.6.24.4/fs/aio.c linux-2.6.24.4/fs/aio.c
14759 --- linux-2.6.24.4/fs/aio.c 2008-03-24 14:49:18.000000000 -0400
14760 +++ linux-2.6.24.4/fs/aio.c 2008-03-26 20:21:08.000000000 -0400
14761 @@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
14762 size += sizeof(struct io_event) * nr_events;
14763 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
14765 - if (nr_pages < 0)
14766 + if (nr_pages <= 0)
14769 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
14770 diff -urNp linux-2.6.24.4/fs/autofs4/symlink.c linux-2.6.24.4/fs/autofs4/symlink.c
14771 --- linux-2.6.24.4/fs/autofs4/symlink.c 2008-03-24 14:49:18.000000000 -0400
14772 +++ linux-2.6.24.4/fs/autofs4/symlink.c 2008-03-26 20:21:08.000000000 -0400
14774 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
14776 struct autofs_info *ino = autofs4_dentry_ino(dentry);
14777 - nd_set_link(nd, (char *)ino->u.symlink);
14778 + nd_set_link(nd, ino->u.symlink);
14782 diff -urNp linux-2.6.24.4/fs/befs/linuxvfs.c linux-2.6.24.4/fs/befs/linuxvfs.c
14783 --- linux-2.6.24.4/fs/befs/linuxvfs.c 2008-03-24 14:49:18.000000000 -0400
14784 +++ linux-2.6.24.4/fs/befs/linuxvfs.c 2008-03-26 20:21:08.000000000 -0400
14785 @@ -482,7 +482,7 @@ static void befs_put_link(struct dentry
14787 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
14788 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
14789 - char *p = nd_get_link(nd);
14790 + const char *p = nd_get_link(nd);
14794 diff -urNp linux-2.6.24.4/fs/binfmt_aout.c linux-2.6.24.4/fs/binfmt_aout.c
14795 --- linux-2.6.24.4/fs/binfmt_aout.c 2008-03-24 14:49:18.000000000 -0400
14796 +++ linux-2.6.24.4/fs/binfmt_aout.c 2008-03-26 20:21:08.000000000 -0400
14798 #include <linux/personality.h>
14799 #include <linux/init.h>
14800 #include <linux/vs_memory.h>
14801 +#include <linux/grsecurity.h>
14803 #include <asm/system.h>
14804 #include <asm/uaccess.h>
14805 @@ -123,18 +124,22 @@ static int aout_core_dump(long signr, st
14806 /* If the size of the dump file exceeds the rlimit, then see what would happen
14807 if we wrote the stack, but not the data area. */
14809 + gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
14810 if ((dump.u_dsize + dump.u_ssize) > limit)
14813 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
14814 if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
14818 /* Make sure we have enough room to write the stack and data areas. */
14820 + gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
14821 if (dump.u_ssize > limit)
14824 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
14825 if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
14828 @@ -290,6 +295,8 @@ static int load_aout_binary(struct linux
14829 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
14830 if (rlim >= RLIM_INFINITY)
14833 + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
14834 if (ex.a_data + ex.a_bss > rlim)
14837 @@ -321,6 +328,28 @@ static int load_aout_binary(struct linux
14839 compute_creds(bprm);
14840 current->flags &= ~PF_FORKNOEXEC;
14842 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14843 + current->mm->pax_flags = 0UL;
14846 +#ifdef CONFIG_PAX_PAGEEXEC
14847 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
14848 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
14850 +#ifdef CONFIG_PAX_EMUTRAMP
14851 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
14852 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
14855 +#ifdef CONFIG_PAX_MPROTECT
14856 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
14857 + current->mm->pax_flags |= MF_PAX_MPROTECT;
14864 if (N_MAGIC(ex) == NMAGIC) {
14865 loff_t pos = fd_offset;
14866 @@ -416,7 +445,7 @@ static int load_aout_binary(struct linux
14868 down_write(¤t->mm->mmap_sem);
14869 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
14870 - PROT_READ | PROT_WRITE | PROT_EXEC,
14871 + PROT_READ | PROT_WRITE,
14872 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
14873 fd_offset + ex.a_text);
14874 up_write(¤t->mm->mmap_sem);
14875 diff -urNp linux-2.6.24.4/fs/binfmt_elf.c linux-2.6.24.4/fs/binfmt_elf.c
14876 --- linux-2.6.24.4/fs/binfmt_elf.c 2008-03-24 14:49:18.000000000 -0400
14877 +++ linux-2.6.24.4/fs/binfmt_elf.c 2008-03-26 20:21:08.000000000 -0400
14878 @@ -39,10 +39,16 @@
14879 #include <linux/elf.h>
14880 #include <linux/utsname.h>
14881 #include <linux/vs_memory.h>
14882 +#include <linux/grsecurity.h>
14884 #include <asm/uaccess.h>
14885 #include <asm/param.h>
14886 #include <asm/page.h>
14888 +#ifdef CONFIG_PAX_SEGMEXEC
14889 +#include <asm/desc.h>
14892 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
14893 static int load_elf_library(struct file *);
14894 static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
14895 @@ -84,6 +90,8 @@ static struct linux_binfmt elf_format =
14897 static int set_brk(unsigned long start, unsigned long end)
14899 + unsigned long e = end;
14901 start = ELF_PAGEALIGN(start);
14902 end = ELF_PAGEALIGN(end);
14904 @@ -94,7 +102,7 @@ static int set_brk(unsigned long start,
14905 if (BAD_ADDR(addr))
14908 - current->mm->start_brk = current->mm->brk = end;
14909 + current->mm->start_brk = current->mm->brk = e;
14913 @@ -328,10 +336,9 @@ static unsigned long load_elf_interp(str
14915 struct elf_phdr *elf_phdata;
14916 struct elf_phdr *eppnt;
14917 - unsigned long load_addr = 0;
14918 - int load_addr_set = 0;
14919 + unsigned long load_addr = 0, min_addr, max_addr, pax_task_size = TASK_SIZE;
14920 unsigned long last_bss = 0, elf_bss = 0;
14921 - unsigned long error = ~0UL;
14922 + unsigned long error = -EINVAL;
14923 int retval, i, size;
14925 /* First of all, some simple consistency checks */
14926 @@ -370,66 +377,86 @@ static unsigned long load_elf_interp(str
14930 +#ifdef CONFIG_PAX_SEGMEXEC
14931 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
14932 + pax_task_size = SEGMEXEC_TASK_SIZE;
14935 eppnt = elf_phdata;
14936 + min_addr = pax_task_size;
14940 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
14941 - if (eppnt->p_type == PT_LOAD) {
14942 - int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
14943 - int elf_prot = 0;
14944 - unsigned long vaddr = 0;
14945 - unsigned long k, map_addr;
14947 - if (eppnt->p_flags & PF_R)
14948 - elf_prot = PROT_READ;
14949 - if (eppnt->p_flags & PF_W)
14950 - elf_prot |= PROT_WRITE;
14951 - if (eppnt->p_flags & PF_X)
14952 - elf_prot |= PROT_EXEC;
14953 - vaddr = eppnt->p_vaddr;
14954 - if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
14955 - elf_type |= MAP_FIXED;
14957 - map_addr = elf_map(interpreter, load_addr + vaddr,
14958 - eppnt, elf_prot, elf_type);
14959 - error = map_addr;
14960 - if (BAD_ADDR(map_addr))
14963 - if (!load_addr_set &&
14964 - interp_elf_ex->e_type == ET_DYN) {
14965 - load_addr = map_addr - ELF_PAGESTART(vaddr);
14966 - load_addr_set = 1;
14968 + if (eppnt->p_type != PT_LOAD)
14972 - * Check to see if the section's size will overflow the
14973 - * allowed task size. Note that p_filesz must always be
14974 - * <= p_memsize so it's only necessary to check p_memsz.
14976 - k = load_addr + eppnt->p_vaddr;
14977 - if (BAD_ADDR(k) ||
14978 - eppnt->p_filesz > eppnt->p_memsz ||
14979 - eppnt->p_memsz > TASK_SIZE ||
14980 - TASK_SIZE - eppnt->p_memsz < k) {
14985 + * Check to see if the section's size will overflow the
14986 + * allowed task size. Note that p_filesz must always be
14987 + * <= p_memsize so it is only necessary to check p_memsz.
14989 + if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
14993 - * Find the end of the file mapping for this phdr, and
14994 - * keep track of the largest address we see for this.
14996 - k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
14999 + if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
15000 + min_addr = ELF_PAGESTART(eppnt->p_vaddr);
15001 + if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
15002 + max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
15004 + if (min_addr >= max_addr || max_addr > pax_task_size)
15008 - * Do the same thing for the memory mapping - between
15009 - * elf_bss and last_bss is the bss section.
15011 - k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
15012 - if (k > last_bss)
15015 + if (interp_elf_ex->e_type == ET_DYN) {
15016 + load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
15018 + if (load_addr >= pax_task_size)
15021 + load_addr -= min_addr;
15024 + eppnt = elf_phdata;
15025 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
15026 + int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
15027 + int elf_prot = 0;
15028 + unsigned long vaddr = 0;
15029 + unsigned long k, map_addr;
15031 + if (eppnt->p_type != PT_LOAD)
15034 + if (eppnt->p_flags & PF_R)
15035 + elf_prot = PROT_READ;
15036 + if (eppnt->p_flags & PF_W)
15037 + elf_prot |= PROT_WRITE;
15038 + if (eppnt->p_flags & PF_X)
15039 + elf_prot |= PROT_EXEC;
15040 + vaddr = eppnt->p_vaddr;
15042 + map_addr = elf_map(interpreter, load_addr + vaddr,
15043 + eppnt, elf_prot, elf_type);
15044 + error = map_addr;
15045 + if (BAD_ADDR(map_addr))
15048 + k = load_addr + eppnt->p_vaddr;
15051 + * Find the end of the file mapping for this phdr, and
15052 + * keep track of the largest address we see for this.
15054 + k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
15059 + * Do the same thing for the memory mapping - between
15060 + * elf_bss and last_bss is the bss section.
15062 + k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
15063 + if (k > last_bss)
15068 @@ -457,6 +484,8 @@ static unsigned long load_elf_interp(str
15070 *interp_load_addr = load_addr;
15071 error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
15072 + if (BAD_ADDR(error))
15077 @@ -467,7 +496,7 @@ out:
15078 static unsigned long load_aout_interp(struct exec *interp_ex,
15079 struct file *interpreter)
15081 - unsigned long text_data, elf_entry = ~0UL;
15082 + unsigned long text_data, elf_entry = -EINVAL;
15083 char __user * addr;
15086 @@ -510,6 +539,177 @@ out:
15090 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
15091 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
15093 + unsigned long pax_flags = 0UL;
15095 +#ifdef CONFIG_PAX_PAGEEXEC
15096 + if (elf_phdata->p_flags & PF_PAGEEXEC)
15097 + pax_flags |= MF_PAX_PAGEEXEC;
15100 +#ifdef CONFIG_PAX_SEGMEXEC
15101 + if (elf_phdata->p_flags & PF_SEGMEXEC)
15102 + pax_flags |= MF_PAX_SEGMEXEC;
15105 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
15106 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
15108 + pax_flags &= ~MF_PAX_SEGMEXEC;
15110 + pax_flags &= ~MF_PAX_PAGEEXEC;
15114 +#ifdef CONFIG_PAX_EMUTRAMP
15115 + if (elf_phdata->p_flags & PF_EMUTRAMP)
15116 + pax_flags |= MF_PAX_EMUTRAMP;
15119 +#ifdef CONFIG_PAX_MPROTECT
15120 + if (elf_phdata->p_flags & PF_MPROTECT)
15121 + pax_flags |= MF_PAX_MPROTECT;
15124 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
15125 + if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
15126 + pax_flags |= MF_PAX_RANDMMAP;
15129 + return pax_flags;
15133 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
15134 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
15136 + unsigned long pax_flags = 0UL;
15138 +#ifdef CONFIG_PAX_PAGEEXEC
15139 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
15140 + pax_flags |= MF_PAX_PAGEEXEC;
15143 +#ifdef CONFIG_PAX_SEGMEXEC
15144 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
15145 + pax_flags |= MF_PAX_SEGMEXEC;
15148 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
15149 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
15151 + pax_flags &= ~MF_PAX_SEGMEXEC;
15153 + pax_flags &= ~MF_PAX_PAGEEXEC;
15157 +#ifdef CONFIG_PAX_EMUTRAMP
15158 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
15159 + pax_flags |= MF_PAX_EMUTRAMP;
15162 +#ifdef CONFIG_PAX_MPROTECT
15163 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
15164 + pax_flags |= MF_PAX_MPROTECT;
15167 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
15168 + if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
15169 + pax_flags |= MF_PAX_RANDMMAP;
15172 + return pax_flags;
15176 +#ifdef CONFIG_PAX_EI_PAX
15177 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
15179 + unsigned long pax_flags = 0UL;
15181 +#ifdef CONFIG_PAX_PAGEEXEC
15182 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
15183 + pax_flags |= MF_PAX_PAGEEXEC;
15186 +#ifdef CONFIG_PAX_SEGMEXEC
15187 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
15188 + pax_flags |= MF_PAX_SEGMEXEC;
15191 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
15192 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
15194 + pax_flags &= ~MF_PAX_SEGMEXEC;
15196 + pax_flags &= ~MF_PAX_PAGEEXEC;
15200 +#ifdef CONFIG_PAX_EMUTRAMP
15201 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
15202 + pax_flags |= MF_PAX_EMUTRAMP;
15205 +#ifdef CONFIG_PAX_MPROTECT
15206 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
15207 + pax_flags |= MF_PAX_MPROTECT;
15210 +#ifdef CONFIG_PAX_ASLR
15211 + if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
15212 + pax_flags |= MF_PAX_RANDMMAP;
15215 + return pax_flags;
15219 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
15220 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
15222 + unsigned long pax_flags = 0UL;
15224 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
15228 +#ifdef CONFIG_PAX_EI_PAX
15229 + pax_flags = pax_parse_ei_pax(elf_ex);
15232 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
15233 + for (i = 0UL; i < elf_ex->e_phnum; i++)
15234 + if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
15235 + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
15236 + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
15237 + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
15238 + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
15239 + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
15242 +#ifdef CONFIG_PAX_SOFTMODE
15243 + if (pax_softmode)
15244 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
15248 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
15253 + if (0 > pax_check_flags(&pax_flags))
15256 + current->mm->pax_flags = pax_flags;
15262 * These are the functions used to load ELF style executables and shared
15263 * libraries. There is no binary dependent code anywhere else.
15264 @@ -547,7 +747,7 @@ static int load_elf_binary(struct linux_
15265 char * elf_interpreter = NULL;
15266 unsigned int interpreter_type = INTERPRETER_NONE;
15267 unsigned char ibcs2_interpreter = 0;
15268 - unsigned long error;
15269 + unsigned long error = 0;
15270 struct elf_phdr *elf_ppnt, *elf_phdata;
15271 unsigned long elf_bss, elf_brk;
15272 int elf_exec_fileno;
15273 @@ -559,12 +759,12 @@ static int load_elf_binary(struct linux_
15274 char passed_fileno[6];
15275 struct files_struct *files;
15276 int executable_stack = EXSTACK_DEFAULT;
15277 - unsigned long def_flags = 0;
15279 struct elfhdr elf_ex;
15280 struct elfhdr interp_elf_ex;
15281 struct exec interp_ex;
15283 + unsigned long pax_task_size = TASK_SIZE;
15285 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
15287 @@ -799,14 +999,89 @@ static int load_elf_binary(struct linux_
15289 /* OK, This is the point of no return */
15290 current->flags &= ~PF_FORKNOEXEC;
15291 - current->mm->def_flags = def_flags;
15293 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
15294 + current->mm->pax_flags = 0UL;
15297 +#ifdef CONFIG_PAX_DLRESOLVE
15298 + current->mm->call_dl_resolve = 0UL;
15301 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
15302 + current->mm->call_syscall = 0UL;
15305 +#ifdef CONFIG_PAX_ASLR
15306 + current->mm->delta_mmap = 0UL;
15307 + current->mm->delta_stack = 0UL;
15310 + current->mm->def_flags = 0;
15312 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
15313 + if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
15314 + send_sig(SIGKILL, current, 0);
15315 + goto out_free_dentry;
15319 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
15320 + pax_set_initial_flags(bprm);
15321 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
15322 + if (pax_set_initial_flags_func)
15323 + (pax_set_initial_flags_func)(bprm);
15326 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
15327 + if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
15328 + current->mm->context.user_cs_limit = PAGE_SIZE;
15329 + current->mm->def_flags |= VM_PAGEEXEC;
15333 +#ifdef CONFIG_PAX_SEGMEXEC
15334 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
15335 + current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
15336 + current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
15337 + pax_task_size = SEGMEXEC_TASK_SIZE;
15341 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
15342 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
15343 + set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
15344 + put_cpu_no_resched();
15348 +#ifdef CONFIG_PAX_ASLR
15349 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
15350 + current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
15351 + current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
15355 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15356 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15357 + executable_stack = EXSTACK_DEFAULT;
15360 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
15361 may depend on the personality. */
15362 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
15364 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15365 + if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
15368 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
15369 current->personality |= READ_IMPLIES_EXEC;
15371 +#ifdef CONFIG_PAX_ASLR
15372 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
15375 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
15376 current->flags |= PF_RANDOMIZE;
15377 arch_pick_mmap_layout(current->mm);
15378 @@ -882,6 +1157,20 @@ static int load_elf_binary(struct linux_
15379 * might try to exec. This is because the brk will
15380 * follow the loader, and is not movable. */
15381 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
15383 +#ifdef CONFIG_PAX_RANDMMAP
15384 + /* PaX: randomize base address at the default exe base if requested */
15385 + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
15386 +#ifdef CONFIG_SPARC64
15387 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
15389 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
15391 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
15392 + elf_flags |= MAP_FIXED;
15398 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
15399 @@ -914,9 +1203,9 @@ static int load_elf_binary(struct linux_
15400 * allowed task size. Note that p_filesz must always be
15401 * <= p_memsz so it is only necessary to check p_memsz.
15403 - if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
15404 - elf_ppnt->p_memsz > TASK_SIZE ||
15405 - TASK_SIZE - elf_ppnt->p_memsz < k) {
15406 + if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
15407 + elf_ppnt->p_memsz > pax_task_size ||
15408 + pax_task_size - elf_ppnt->p_memsz < k) {
15409 /* set_brk can never work. Avoid overflows. */
15410 send_sig(SIGKILL, current, 0);
15412 @@ -944,6 +1233,11 @@ static int load_elf_binary(struct linux_
15413 start_data += load_bias;
15414 end_data += load_bias;
15416 +#ifdef CONFIG_PAX_RANDMMAP
15417 + if (current->mm->pax_flags & MF_PAX_RANDMMAP)
15418 + elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
15421 /* Calling set_brk effectively mmaps the pages that we need
15422 * for the bss and break sections. We must do this before
15423 * mapping in the interpreter, to make sure it doesn't wind
15424 @@ -955,9 +1249,11 @@ static int load_elf_binary(struct linux_
15425 goto out_free_dentry;
15427 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
15428 - send_sig(SIGSEGV, current, 0);
15429 - retval = -EFAULT; /* Nobody gets to see this, but.. */
15430 - goto out_free_dentry;
15432 + * This bss-zeroing can fail if the ELF
15433 + * file specifies odd protections. So
15434 + * we don't check the return value
15438 if (elf_interpreter) {
15439 @@ -1194,8 +1490,10 @@ static int dump_seek(struct file *file,
15440 unsigned long n = off;
15443 - if (!dump_write(file, buf, n))
15444 + if (!dump_write(file, buf, n)) {
15445 + free_page((unsigned long)buf);
15450 free_page((unsigned long)buf);
15451 @@ -1207,7 +1505,7 @@ static int dump_seek(struct file *file,
15452 * Decide what to dump of a segment, part, all or none.
15454 static unsigned long vma_dump_size(struct vm_area_struct *vma,
15455 - unsigned long mm_flags)
15456 + unsigned long mm_flags, long signr)
15458 /* The vma can be set up to tell us the answer directly. */
15459 if (vma->vm_flags & VM_ALWAYSDUMP)
15460 @@ -1233,7 +1531,7 @@ static unsigned long vma_dump_size(struc
15461 if (vma->vm_file == NULL)
15464 - if (FILTER(MAPPED_PRIVATE))
15465 + if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
15469 @@ -1319,8 +1617,11 @@ static int writenote(struct memelfnote *
15472 #define DUMP_WRITE(addr, nr) \
15474 + gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
15475 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
15476 - goto end_coredump;
15477 + goto end_coredump; \
15479 #define DUMP_SEEK(off) \
15480 if (!dump_seek(file, (off))) \
15482 @@ -1710,7 +2011,7 @@ static int elf_core_dump(long signr, str
15483 phdr.p_offset = offset;
15484 phdr.p_vaddr = vma->vm_start;
15486 - phdr.p_filesz = vma_dump_size(vma, mm_flags);
15487 + phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
15488 phdr.p_memsz = vma->vm_end - vma->vm_start;
15489 offset += phdr.p_filesz;
15490 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
15491 @@ -1753,7 +2054,7 @@ static int elf_core_dump(long signr, str
15492 unsigned long addr;
15495 - end = vma->vm_start + vma_dump_size(vma, mm_flags);
15496 + end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
15498 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
15500 @@ -1773,6 +2074,7 @@ static int elf_core_dump(long signr, str
15501 flush_cache_page(vma, addr,
15502 page_to_pfn(page));
15503 kaddr = kmap(page);
15504 + gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
15505 if ((size += PAGE_SIZE) > limit ||
15506 !dump_write(file, kaddr,
15508 diff -urNp linux-2.6.24.4/fs/binfmt_flat.c linux-2.6.24.4/fs/binfmt_flat.c
15509 --- linux-2.6.24.4/fs/binfmt_flat.c 2008-03-24 14:49:18.000000000 -0400
15510 +++ linux-2.6.24.4/fs/binfmt_flat.c 2008-03-26 20:21:08.000000000 -0400
15511 @@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
15512 realdatastart = (unsigned long) -ENOMEM;
15513 printk("Unable to allocate RAM for process data, errno %d\n",
15514 (int)-realdatastart);
15515 + down_write(¤t->mm->mmap_sem);
15516 do_munmap(current->mm, textpos, text_len);
15517 + up_write(¤t->mm->mmap_sem);
15518 ret = realdatastart;
15521 @@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
15523 if (result >= (unsigned long)-4096) {
15524 printk("Unable to read data+bss, errno %d\n", (int)-result);
15525 + down_write(¤t->mm->mmap_sem);
15526 do_munmap(current->mm, textpos, text_len);
15527 do_munmap(current->mm, realdatastart, data_len + extra);
15528 + up_write(¤t->mm->mmap_sem);
15532 @@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
15534 if (result >= (unsigned long)-4096) {
15535 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
15536 + down_write(¤t->mm->mmap_sem);
15537 do_munmap(current->mm, textpos, text_len + data_len + extra +
15538 MAX_SHARED_LIBS * sizeof(unsigned long));
15539 + up_write(¤t->mm->mmap_sem);
15543 diff -urNp linux-2.6.24.4/fs/binfmt_misc.c linux-2.6.24.4/fs/binfmt_misc.c
15544 --- linux-2.6.24.4/fs/binfmt_misc.c 2008-03-24 14:49:18.000000000 -0400
15545 +++ linux-2.6.24.4/fs/binfmt_misc.c 2008-03-26 20:21:08.000000000 -0400
15546 @@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
15547 struct files_struct *files = NULL;
15551 + if (!enabled || bprm->misc)
15556 /* to keep locking time low, we copy the interpreter string */
15557 read_lock(&entries_lock);
15558 fmt = check_file(bprm);
15559 @@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl
15560 static struct tree_descr bm_files[] = {
15561 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
15562 [3] = {"register", &bm_register_operations, S_IWUSR},
15563 - /* last one */ {""}
15564 + /* last one */ {"", NULL, 0}
15566 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
15568 diff -urNp linux-2.6.24.4/fs/buffer.c linux-2.6.24.4/fs/buffer.c
15569 --- linux-2.6.24.4/fs/buffer.c 2008-03-24 14:49:18.000000000 -0400
15570 +++ linux-2.6.24.4/fs/buffer.c 2008-03-26 20:21:08.000000000 -0400
15572 #include <linux/bitops.h>
15573 #include <linux/mpage.h>
15574 #include <linux/bit_spinlock.h>
15575 +#include <linux/grsecurity.h>
15577 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
15579 @@ -2170,6 +2171,7 @@ int generic_cont_expand_simple(struct in
15582 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
15583 + gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
15584 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
15585 send_sig(SIGXFSZ, current, 0);
15587 diff -urNp linux-2.6.24.4/fs/cifs/cifs_uniupr.h linux-2.6.24.4/fs/cifs/cifs_uniupr.h
15588 --- linux-2.6.24.4/fs/cifs/cifs_uniupr.h 2008-03-24 14:49:18.000000000 -0400
15589 +++ linux-2.6.24.4/fs/cifs/cifs_uniupr.h 2008-03-26 20:21:08.000000000 -0400
15590 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
15591 {0x0490, 0x04cc, UniCaseRangeU0490},
15592 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
15593 {0xff40, 0xff5a, UniCaseRangeUff40},
15599 diff -urNp linux-2.6.24.4/fs/cifs/link.c linux-2.6.24.4/fs/cifs/link.c
15600 --- linux-2.6.24.4/fs/cifs/link.c 2008-03-24 14:49:18.000000000 -0400
15601 +++ linux-2.6.24.4/fs/cifs/link.c 2008-03-26 20:21:08.000000000 -0400
15602 @@ -355,7 +355,7 @@ cifs_readlink(struct dentry *direntry, c
15604 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
15606 - char *p = nd_get_link(nd);
15607 + const char *p = nd_get_link(nd);
15611 diff -urNp linux-2.6.24.4/fs/compat.c linux-2.6.24.4/fs/compat.c
15612 --- linux-2.6.24.4/fs/compat.c 2008-03-24 14:49:18.000000000 -0400
15613 +++ linux-2.6.24.4/fs/compat.c 2008-03-26 20:21:08.000000000 -0400
15615 #include <linux/poll.h>
15616 #include <linux/mm.h>
15617 #include <linux/eventpoll.h>
15618 +#include <linux/grsecurity.h>
15620 #include <asm/uaccess.h>
15621 #include <asm/mmu_context.h>
15622 @@ -1300,14 +1301,12 @@ static int compat_copy_strings(int argc,
15623 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
15626 -#ifdef CONFIG_STACK_GROWSUP
15627 ret = expand_stack_downwards(bprm->vma, pos);
15629 /* We've exceed the stack rlimit. */
15634 ret = get_user_pages(current, bprm->mm, pos,
15635 1, 1, 1, &page, NULL);
15637 @@ -1353,6 +1352,11 @@ int compat_do_execve(char * filename,
15638 compat_uptr_t __user *envp,
15639 struct pt_regs * regs)
15641 +#ifdef CONFIG_GRKERNSEC
15642 + struct file *old_exec_file;
15643 + struct acl_subject_label *old_acl;
15644 + struct rlimit old_rlim[RLIM_NLIMITS];
15646 struct linux_binprm *bprm;
15649 @@ -1373,6 +1377,14 @@ int compat_do_execve(char * filename,
15650 bprm->filename = filename;
15651 bprm->interp = filename;
15653 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
15654 + retval = -EAGAIN;
15655 + if (gr_handle_nproc())
15657 + retval = -EACCES;
15658 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
15661 retval = bprm_mm_init(bprm);
15664 @@ -1406,8 +1418,36 @@ int compat_do_execve(char * filename,
15668 + if (!gr_tpe_allow(file)) {
15669 + retval = -EACCES;
15673 + if (gr_check_crash_exec(file)) {
15674 + retval = -EACCES;
15678 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
15680 + gr_handle_exec_args(bprm, (char __user * __user *)argv);
15682 +#ifdef CONFIG_GRKERNSEC
15683 + old_acl = current->acl;
15684 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
15685 + old_exec_file = current->exec_file;
15687 + current->exec_file = file;
15690 + gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
15692 retval = search_binary_handler(bprm, regs);
15694 +#ifdef CONFIG_GRKERNSEC
15695 + if (old_exec_file)
15696 + fput(old_exec_file);
15698 /* execve success */
15699 security_bprm_free(bprm);
15700 acct_update_integrals(current);
15701 @@ -1415,6 +1455,13 @@ int compat_do_execve(char * filename,
15705 +#ifdef CONFIG_GRKERNSEC
15706 + current->acl = old_acl;
15707 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
15708 + fput(current->exec_file);
15709 + current->exec_file = old_exec_file;
15713 if (bprm->security)
15714 security_bprm_free(bprm);
15715 diff -urNp linux-2.6.24.4/fs/compat_ioctl.c linux-2.6.24.4/fs/compat_ioctl.c
15716 --- linux-2.6.24.4/fs/compat_ioctl.c 2008-03-24 14:49:18.000000000 -0400
15717 +++ linux-2.6.24.4/fs/compat_ioctl.c 2008-03-26 20:21:08.000000000 -0400
15718 @@ -1890,15 +1890,15 @@ struct ioctl_trans {
15721 #define HANDLE_IOCTL(cmd,handler) \
15722 - { (cmd), (ioctl_trans_handler_t)(handler) },
15723 + { (cmd), (ioctl_trans_handler_t)(handler), NULL },
15725 /* pointer to compatible structure or no argument */
15726 #define COMPATIBLE_IOCTL(cmd) \
15727 - { (cmd), do_ioctl32_pointer },
15728 + { (cmd), do_ioctl32_pointer, NULL },
15730 /* argument is an unsigned long integer, not a pointer */
15731 #define ULONG_IOCTL(cmd) \
15732 - { (cmd), (ioctl_trans_handler_t)sys_ioctl },
15733 + { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
15735 /* ioctl should not be warned about even if it's not implemented.
15736 Valid reasons to use this:
15737 diff -urNp linux-2.6.24.4/fs/debugfs/inode.c linux-2.6.24.4/fs/debugfs/inode.c
15738 --- linux-2.6.24.4/fs/debugfs/inode.c 2008-03-24 14:49:18.000000000 -0400
15739 +++ linux-2.6.24.4/fs/debugfs/inode.c 2008-03-26 20:21:08.000000000 -0400
15740 @@ -125,7 +125,7 @@ static inline int debugfs_positive(struc
15742 static int debug_fill_super(struct super_block *sb, void *data, int silent)
15744 - static struct tree_descr debug_files[] = {{""}};
15745 + static struct tree_descr debug_files[] = {{"", NULL, 0}};
15747 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
15749 diff -urNp linux-2.6.24.4/fs/exec.c linux-2.6.24.4/fs/exec.c
15750 --- linux-2.6.24.4/fs/exec.c 2008-03-24 14:49:18.000000000 -0400
15751 +++ linux-2.6.24.4/fs/exec.c 2008-03-26 20:21:08.000000000 -0400
15753 #include <linux/tsacct_kern.h>
15754 #include <linux/cn_proc.h>
15755 #include <linux/audit.h>
15756 +#include <linux/random.h>
15757 +#include <linux/grsecurity.h>
15759 #include <asm/uaccess.h>
15760 #include <asm/mmu_context.h>
15762 #include <linux/kmod.h>
15765 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
15766 +void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
15767 +EXPORT_SYMBOL(pax_set_initial_flags_func);
15771 char core_pattern[CORENAME_MAX_SIZE] = "core";
15772 int suid_dumpable = 0;
15773 @@ -158,18 +165,10 @@ static struct page *get_arg_page(struct
15779 -#ifdef CONFIG_STACK_GROWSUP
15781 - ret = expand_stack_downwards(bprm->vma, pos);
15786 - ret = get_user_pages(current, bprm->mm, pos,
15787 - 1, write, 1, &page, NULL);
15789 + if (0 > expand_stack_downwards(bprm->vma, pos))
15791 + if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
15795 @@ -234,6 +233,11 @@ static int __bprm_mm_init(struct linux_b
15796 vma->vm_start = vma->vm_end - PAGE_SIZE;
15798 vma->vm_flags = VM_STACK_FLAGS;
15800 +#ifdef CONFIG_PAX_SEGMEXEC
15801 + vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
15804 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
15805 err = insert_vm_struct(mm, vma);
15807 @@ -246,6 +250,11 @@ static int __bprm_mm_init(struct linux_b
15809 bprm->p = vma->vm_end - sizeof(void *);
15811 +#ifdef CONFIG_PAX_RANDUSTACK
15812 + if (randomize_va_space)
15813 + bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
15819 @@ -369,7 +378,7 @@ static int count(char __user * __user *
15828 @@ -509,6 +518,10 @@ static int shift_arg_pages(struct vm_are
15829 if (vma != find_vma(mm, new_start))
15832 +#ifdef CONFIG_PAX_SEGMEXEC
15833 + BUG_ON(pax_find_mirror_vma(vma));
15837 * cover the whole range: [new_start, old_end)
15839 @@ -597,6 +610,14 @@ int setup_arg_pages(struct linux_binprm
15840 bprm->exec -= stack_shift;
15842 down_write(&mm->mmap_sem);
15844 + /* Move stack pages down in memory. */
15845 + if (stack_shift) {
15846 + ret = shift_arg_pages(vma, stack_shift);
15851 vm_flags = vma->vm_flags;
15854 @@ -608,23 +629,28 @@ int setup_arg_pages(struct linux_binprm
15855 vm_flags |= VM_EXEC;
15856 else if (executable_stack == EXSTACK_DISABLE_X)
15857 vm_flags &= ~VM_EXEC;
15859 + vm_flags = VM_STACK_FLAGS;
15860 vm_flags |= mm->def_flags;
15862 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15863 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
15864 + vm_flags &= ~VM_EXEC;
15866 +#ifdef CONFIG_PAX_MPROTECT
15867 + if (mm->pax_flags & MF_PAX_MPROTECT)
15868 + vm_flags &= ~VM_MAYEXEC;
15874 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
15878 BUG_ON(prev != vma);
15880 - /* Move stack pages down in memory. */
15881 - if (stack_shift) {
15882 - ret = shift_arg_pages(vma, stack_shift);
15884 - up_write(&mm->mmap_sem);
15889 #ifdef CONFIG_STACK_GROWSUP
15890 stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
15892 @@ -636,7 +662,7 @@ int setup_arg_pages(struct linux_binprm
15895 up_write(&mm->mmap_sem);
15899 EXPORT_SYMBOL(setup_arg_pages);
15901 @@ -655,7 +681,7 @@ struct file *open_exec(const char *name)
15902 struct inode *inode = nd.dentry->d_inode;
15903 file = ERR_PTR(-EACCES);
15904 if (S_ISREG(inode->i_mode)) {
15905 - int err = vfs_permission(&nd, MAY_EXEC);
15906 + err = vfs_permission(&nd, MAY_EXEC);
15907 file = ERR_PTR(err);
15909 file = nameidata_to_filp(&nd, O_RDONLY);
15910 @@ -1293,6 +1319,11 @@ int do_execve(char * filename,
15911 char __user *__user *envp,
15912 struct pt_regs * regs)
15914 +#ifdef CONFIG_GRKERNSEC
15915 + struct file *old_exec_file;
15916 + struct acl_subject_label *old_acl;
15917 + struct rlimit old_rlim[RLIM_NLIMITS];
15919 struct linux_binprm *bprm;
15921 unsigned long env_p;
15922 @@ -1308,6 +1339,20 @@ int do_execve(char * filename,
15926 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
15928 + if (gr_handle_nproc()) {
15929 + allow_write_access(file);
15934 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
15935 + allow_write_access(file);
15943 @@ -1349,8 +1394,38 @@ int do_execve(char * filename,
15945 bprm->argv_len = env_p - bprm->p;
15947 + if (!gr_tpe_allow(file)) {
15948 + retval = -EACCES;
15952 + if (gr_check_crash_exec(file)) {
15953 + retval = -EACCES;
15957 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
15959 + gr_handle_exec_args(bprm, argv);
15961 +#ifdef CONFIG_GRKERNSEC
15962 + old_acl = current->acl;
15963 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
15964 + old_exec_file = current->exec_file;
15966 + current->exec_file = file;
15969 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
15973 retval = search_binary_handler(bprm,regs);
15975 +#ifdef CONFIG_GRKERNSEC
15976 + if (old_exec_file)
15977 + fput(old_exec_file);
15979 /* execve success */
15980 free_arg_pages(bprm);
15981 security_bprm_free(bprm);
15982 @@ -1359,6 +1434,14 @@ int do_execve(char * filename,
15987 +#ifdef CONFIG_GRKERNSEC
15988 + current->acl = old_acl;
15989 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
15990 + fput(current->exec_file);
15991 + current->exec_file = old_exec_file;
15995 free_arg_pages(bprm);
15996 if (bprm->security)
15997 @@ -1523,6 +1606,114 @@ out:
16001 +int pax_check_flags(unsigned long *flags)
16005 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
16006 + if (*flags & MF_PAX_SEGMEXEC)
16008 + *flags &= ~MF_PAX_SEGMEXEC;
16009 + retval = -EINVAL;
16013 + if ((*flags & MF_PAX_PAGEEXEC)
16015 +#ifdef CONFIG_PAX_PAGEEXEC
16016 + && (*flags & MF_PAX_SEGMEXEC)
16021 + *flags &= ~MF_PAX_PAGEEXEC;
16022 + retval = -EINVAL;
16025 + if ((*flags & MF_PAX_MPROTECT)
16027 +#ifdef CONFIG_PAX_MPROTECT
16028 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
16033 + *flags &= ~MF_PAX_MPROTECT;
16034 + retval = -EINVAL;
16037 + if ((*flags & MF_PAX_EMUTRAMP)
16039 +#ifdef CONFIG_PAX_EMUTRAMP
16040 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
16045 + *flags &= ~MF_PAX_EMUTRAMP;
16046 + retval = -EINVAL;
16052 +EXPORT_SYMBOL(pax_check_flags);
16054 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
16055 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
16057 + struct task_struct *tsk = current;
16058 + struct mm_struct *mm = current->mm;
16059 + char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
16060 + char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
16061 + char *path_exec = NULL;
16062 + char *path_fault = NULL;
16063 + unsigned long start = 0UL, end = 0UL, offset = 0UL;
16065 + if (buffer_exec && buffer_fault) {
16066 + struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
16068 + down_read(&mm->mmap_sem);
16070 + while (vma && (!vma_exec || !vma_fault)) {
16071 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
16073 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
16075 + vma = vma->vm_next;
16078 + path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE);
16079 + if (IS_ERR(path_exec))
16080 + path_exec = "<path too long>";
16083 + start = vma_fault->vm_start;
16084 + end = vma_fault->vm_end;
16085 + offset = vma_fault->vm_pgoff << PAGE_SHIFT;
16086 + if (vma_fault->vm_file) {
16087 + path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE);
16088 + if (IS_ERR(path_fault))
16089 + path_fault = "<path too long>";
16091 + path_fault = "<anonymous mapping>";
16093 + up_read(&mm->mmap_sem);
16095 + if (tsk->signal->curr_ip)
16096 + 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);
16098 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
16099 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
16100 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
16101 + tsk->uid, tsk->euid, pc, sp);
16102 + free_page((unsigned long)buffer_exec);
16103 + free_page((unsigned long)buffer_fault);
16104 + pax_report_insns(pc, sp);
16105 + do_coredump(SIGKILL, SIGKILL, regs);
16109 static void zap_process(struct task_struct *start)
16111 struct task_struct *t;
16112 @@ -1720,6 +1911,10 @@ int do_coredump(long signr, int exit_cod
16114 clear_thread_flag(TIF_SIGPENDING);
16116 + if (signr == SIGKILL || signr == SIGILL)
16117 + gr_handle_brute_attach(current);
16118 + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
16121 * lock_kernel() because format_corename() is controlled by sysctl, which
16122 * uses lock_kernel()
16123 @@ -1740,6 +1935,8 @@ int do_coredump(long signr, int exit_cod
16126 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
16127 + if (!helper_argv)
16128 + goto fail_unlock;
16129 /* Terminate the string before the first option */
16130 delimit = strchr(corename, ' ');
16132 diff -urNp linux-2.6.24.4/fs/ext2/balloc.c linux-2.6.24.4/fs/ext2/balloc.c
16133 --- linux-2.6.24.4/fs/ext2/balloc.c 2008-03-24 14:49:18.000000000 -0400
16134 +++ linux-2.6.24.4/fs/ext2/balloc.c 2008-03-26 20:21:08.000000000 -0400
16135 @@ -1127,7 +1127,7 @@ static int ext2_has_free_blocks(struct e
16137 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
16138 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
16139 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
16140 + if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
16141 sbi->s_resuid != current->fsuid &&
16142 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
16144 diff -urNp linux-2.6.24.4/fs/ext3/balloc.c linux-2.6.24.4/fs/ext3/balloc.c
16145 --- linux-2.6.24.4/fs/ext3/balloc.c 2008-03-24 14:49:18.000000000 -0400
16146 +++ linux-2.6.24.4/fs/ext3/balloc.c 2008-03-26 20:21:08.000000000 -0400
16147 @@ -1359,7 +1359,7 @@ static int ext3_has_free_blocks(struct e
16148 DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
16150 cond = (free_blocks < root_blocks + 1 &&
16151 - !capable(CAP_SYS_RESOURCE) &&
16152 + !capable_nolog(CAP_SYS_RESOURCE) &&
16153 sbi->s_resuid != current->fsuid &&
16154 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
16156 diff -urNp linux-2.6.24.4/fs/ext3/namei.c linux-2.6.24.4/fs/ext3/namei.c
16157 --- linux-2.6.24.4/fs/ext3/namei.c 2008-03-24 14:49:18.000000000 -0400
16158 +++ linux-2.6.24.4/fs/ext3/namei.c 2008-03-26 20:21:08.000000000 -0400
16159 @@ -1181,9 +1181,9 @@ static struct ext3_dir_entry_2 *do_split
16161 struct dx_map_entry *map;
16162 char *data1 = (*bh)->b_data, *data2;
16163 - unsigned split, move, size, i;
16164 + unsigned split, move, size;
16165 struct ext3_dir_entry_2 *de = NULL, *de2;
16169 bh2 = ext3_append (handle, dir, &newblock, &err);
16171 diff -urNp linux-2.6.24.4/fs/ext3/xattr.c linux-2.6.24.4/fs/ext3/xattr.c
16172 --- linux-2.6.24.4/fs/ext3/xattr.c 2008-03-24 14:49:18.000000000 -0400
16173 +++ linux-2.6.24.4/fs/ext3/xattr.c 2008-03-26 20:21:08.000000000 -0400
16178 -# define ea_idebug(f...)
16179 -# define ea_bdebug(f...)
16180 +# define ea_idebug(f...) do {} while (0)
16181 +# define ea_bdebug(f...) do {} while (0)
16184 static void ext3_xattr_cache_insert(struct buffer_head *);
16185 diff -urNp linux-2.6.24.4/fs/ext4/balloc.c linux-2.6.24.4/fs/ext4/balloc.c
16186 --- linux-2.6.24.4/fs/ext4/balloc.c 2008-03-24 14:49:18.000000000 -0400
16187 +++ linux-2.6.24.4/fs/ext4/balloc.c 2008-03-26 20:21:08.000000000 -0400
16188 @@ -1479,7 +1479,7 @@ static int ext4_has_free_blocks(struct e
16189 DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
16191 cond = (free_blocks < root_blocks + 1 &&
16192 - !capable(CAP_SYS_RESOURCE) &&
16193 + !capable_nolog(CAP_SYS_RESOURCE) &&
16194 sbi->s_resuid != current->fsuid &&
16195 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
16197 diff -urNp linux-2.6.24.4/fs/ext4/namei.c linux-2.6.24.4/fs/ext4/namei.c
16198 --- linux-2.6.24.4/fs/ext4/namei.c 2008-03-24 14:49:18.000000000 -0400
16199 +++ linux-2.6.24.4/fs/ext4/namei.c 2008-03-26 20:21:08.000000000 -0400
16200 @@ -1178,9 +1178,9 @@ static struct ext4_dir_entry_2 *do_split
16202 struct dx_map_entry *map;
16203 char *data1 = (*bh)->b_data, *data2;
16204 - unsigned split, move, size, i;
16205 + unsigned split, move, size;
16206 struct ext4_dir_entry_2 *de = NULL, *de2;
16210 bh2 = ext4_append (handle, dir, &newblock, &err);
16212 diff -urNp linux-2.6.24.4/fs/fcntl.c linux-2.6.24.4/fs/fcntl.c
16213 --- linux-2.6.24.4/fs/fcntl.c 2008-03-24 14:49:18.000000000 -0400
16214 +++ linux-2.6.24.4/fs/fcntl.c 2008-03-26 20:21:08.000000000 -0400
16216 #include <linux/rcupdate.h>
16217 #include <linux/pid_namespace.h>
16218 #include <linux/vs_limit.h>
16219 +#include <linux/grsecurity.h>
16221 #include <asm/poll.h>
16222 #include <asm/siginfo.h>
16223 @@ -64,6 +65,7 @@ static int locate_fd(struct files_struct
16224 struct fdtable *fdt;
16227 + gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
16228 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
16231 @@ -83,6 +85,7 @@ repeat:
16232 fdt->max_fds, start);
16235 + gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
16236 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
16239 @@ -144,6 +147,8 @@ asmlinkage long sys_dup2(unsigned int ol
16240 struct files_struct * files = current->files;
16241 struct fdtable *fdt;
16243 + gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
16245 spin_lock(&files->file_lock);
16246 if (!(file = fcheck(oldfd)))
16248 @@ -463,7 +468,8 @@ static inline int sigio_perm(struct task
16249 return (((fown->euid == 0) ||
16250 (fown->euid == p->suid) || (fown->euid == p->uid) ||
16251 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
16252 - !security_file_send_sigiotask(p, fown, sig));
16253 + !security_file_send_sigiotask(p, fown, sig) &&
16254 + !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
16257 static void send_sigio_to_task(struct task_struct *p,
16258 diff -urNp linux-2.6.24.4/fs/fuse/control.c linux-2.6.24.4/fs/fuse/control.c
16259 --- linux-2.6.24.4/fs/fuse/control.c 2008-03-24 14:49:18.000000000 -0400
16260 +++ linux-2.6.24.4/fs/fuse/control.c 2008-03-26 20:21:08.000000000 -0400
16261 @@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
16263 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
16265 - struct tree_descr empty_descr = {""};
16266 + struct tree_descr empty_descr = {"", NULL, 0};
16267 struct fuse_conn *fc;
16270 diff -urNp linux-2.6.24.4/fs/fuse/dir.c linux-2.6.24.4/fs/fuse/dir.c
16271 --- linux-2.6.24.4/fs/fuse/dir.c 2008-03-24 14:49:18.000000000 -0400
16272 +++ linux-2.6.24.4/fs/fuse/dir.c 2008-03-26 20:21:08.000000000 -0400
16273 @@ -1030,7 +1030,7 @@ static char *read_link(struct dentry *de
16277 -static void free_link(char *link)
16278 +static void free_link(const char *link)
16281 free_page((unsigned long) link);
16282 diff -urNp linux-2.6.24.4/fs/hfs/inode.c linux-2.6.24.4/fs/hfs/inode.c
16283 --- linux-2.6.24.4/fs/hfs/inode.c 2008-03-24 14:49:18.000000000 -0400
16284 +++ linux-2.6.24.4/fs/hfs/inode.c 2008-03-26 20:21:08.000000000 -0400
16285 @@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
16287 if (S_ISDIR(main_inode->i_mode)) {
16288 if (fd.entrylength < sizeof(struct hfs_cat_dir))
16291 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
16292 sizeof(struct hfs_cat_dir));
16293 if (rec.type != HFS_CDR_DIR ||
16294 @@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
16295 sizeof(struct hfs_cat_file));
16297 if (fd.entrylength < sizeof(struct hfs_cat_file))
16300 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
16301 sizeof(struct hfs_cat_file));
16302 if (rec.type != HFS_CDR_FIL ||
16303 diff -urNp linux-2.6.24.4/fs/hfsplus/inode.c linux-2.6.24.4/fs/hfsplus/inode.c
16304 --- linux-2.6.24.4/fs/hfsplus/inode.c 2008-03-24 14:49:18.000000000 -0400
16305 +++ linux-2.6.24.4/fs/hfsplus/inode.c 2008-03-26 20:21:08.000000000 -0400
16306 @@ -422,7 +422,7 @@ int hfsplus_cat_read_inode(struct inode
16307 struct hfsplus_cat_folder *folder = &entry.folder;
16309 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
16312 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
16313 sizeof(struct hfsplus_cat_folder));
16314 hfsplus_get_perms(inode, &folder->permissions, 1);
16315 @@ -439,7 +439,7 @@ int hfsplus_cat_read_inode(struct inode
16316 struct hfsplus_cat_file *file = &entry.file;
16318 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
16321 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
16322 sizeof(struct hfsplus_cat_file));
16324 @@ -495,7 +495,7 @@ int hfsplus_cat_write_inode(struct inode
16325 struct hfsplus_cat_folder *folder = &entry.folder;
16327 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
16330 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
16331 sizeof(struct hfsplus_cat_folder));
16332 /* simple node checks? */
16333 @@ -517,7 +517,7 @@ int hfsplus_cat_write_inode(struct inode
16334 struct hfsplus_cat_file *file = &entry.file;
16336 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
16339 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
16340 sizeof(struct hfsplus_cat_file));
16341 hfsplus_inode_write_fork(inode, &file->data_fork);
16342 diff -urNp linux-2.6.24.4/fs/jffs2/debug.h linux-2.6.24.4/fs/jffs2/debug.h
16343 --- linux-2.6.24.4/fs/jffs2/debug.h 2008-03-24 14:49:18.000000000 -0400
16344 +++ linux-2.6.24.4/fs/jffs2/debug.h 2008-03-26 20:21:08.000000000 -0400
16345 @@ -51,13 +51,13 @@
16346 #if CONFIG_JFFS2_FS_DEBUG > 0
16350 +#define D1(x) do {} while (0);
16353 #if CONFIG_JFFS2_FS_DEBUG > 1
16357 +#define D2(x) do {} while (0);
16360 /* The prefixes of JFFS2 messages */
16361 @@ -113,68 +113,68 @@
16362 #ifdef JFFS2_DBG_READINODE_MESSAGES
16363 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16365 -#define dbg_readinode(fmt, ...)
16366 +#define dbg_readinode(fmt, ...) do {} while (0)
16369 /* Fragtree build debugging messages */
16370 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
16371 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16373 -#define dbg_fragtree(fmt, ...)
16374 +#define dbg_fragtree(fmt, ...) do {} while (0)
16376 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
16377 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16379 -#define dbg_fragtree2(fmt, ...)
16380 +#define dbg_fragtree2(fmt, ...) do {} while (0)
16383 /* Directory entry list manilulation debugging messages */
16384 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
16385 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16387 -#define dbg_dentlist(fmt, ...)
16388 +#define dbg_dentlist(fmt, ...) do {} while (0)
16391 /* Print the messages about manipulating node_refs */
16392 #ifdef JFFS2_DBG_NODEREF_MESSAGES
16393 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16395 -#define dbg_noderef(fmt, ...)
16396 +#define dbg_noderef(fmt, ...) do {} while (0)
16399 /* Manipulations with the list of inodes (JFFS2 inocache) */
16400 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
16401 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16403 -#define dbg_inocache(fmt, ...)
16404 +#define dbg_inocache(fmt, ...) do {} while (0)
16407 /* Summary debugging messages */
16408 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
16409 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16411 -#define dbg_summary(fmt, ...)
16412 +#define dbg_summary(fmt, ...) do {} while (0)
16415 /* File system build messages */
16416 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
16417 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16419 -#define dbg_fsbuild(fmt, ...)
16420 +#define dbg_fsbuild(fmt, ...) do {} while (0)
16423 /* Watch the object allocations */
16424 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
16425 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16427 -#define dbg_memalloc(fmt, ...)
16428 +#define dbg_memalloc(fmt, ...) do {} while (0)
16431 /* Watch the XATTR subsystem */
16432 #ifdef JFFS2_DBG_XATTR_MESSAGES
16433 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
16435 -#define dbg_xattr(fmt, ...)
16436 +#define dbg_xattr(fmt, ...) do {} while (0)
16439 /* "Sanity" checks */
16440 diff -urNp linux-2.6.24.4/fs/jffs2/erase.c linux-2.6.24.4/fs/jffs2/erase.c
16441 --- linux-2.6.24.4/fs/jffs2/erase.c 2008-03-24 14:49:18.000000000 -0400
16442 +++ linux-2.6.24.4/fs/jffs2/erase.c 2008-03-26 20:21:08.000000000 -0400
16443 @@ -428,7 +428,8 @@ static void jffs2_mark_erased_block(stru
16444 struct jffs2_unknown_node marker = {
16445 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
16446 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
16447 - .totlen = cpu_to_je32(c->cleanmarker_size)
16448 + .totlen = cpu_to_je32(c->cleanmarker_size),
16449 + .hdr_crc = cpu_to_je32(0)
16452 jffs2_prealloc_raw_node_refs(c, jeb, 1);
16453 diff -urNp linux-2.6.24.4/fs/jffs2/summary.h linux-2.6.24.4/fs/jffs2/summary.h
16454 --- linux-2.6.24.4/fs/jffs2/summary.h 2008-03-24 14:49:18.000000000 -0400
16455 +++ linux-2.6.24.4/fs/jffs2/summary.h 2008-03-26 20:21:08.000000000 -0400
16456 @@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
16458 #define jffs2_sum_active() (0)
16459 #define jffs2_sum_init(a) (0)
16460 -#define jffs2_sum_exit(a)
16461 -#define jffs2_sum_disable_collecting(a)
16462 +#define jffs2_sum_exit(a) do {} while (0)
16463 +#define jffs2_sum_disable_collecting(a) do {} while (0)
16464 #define jffs2_sum_is_disabled(a) (0)
16465 -#define jffs2_sum_reset_collected(a)
16466 +#define jffs2_sum_reset_collected(a) do {} while (0)
16467 #define jffs2_sum_add_kvec(a,b,c,d) (0)
16468 -#define jffs2_sum_move_collected(a,b)
16469 +#define jffs2_sum_move_collected(a,b) do {} while (0)
16470 #define jffs2_sum_write_sumnode(a) (0)
16471 -#define jffs2_sum_add_padding_mem(a,b)
16472 -#define jffs2_sum_add_inode_mem(a,b,c)
16473 -#define jffs2_sum_add_dirent_mem(a,b,c)
16474 -#define jffs2_sum_add_xattr_mem(a,b,c)
16475 -#define jffs2_sum_add_xref_mem(a,b,c)
16476 +#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
16477 +#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
16478 +#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
16479 +#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
16480 +#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
16481 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
16483 #endif /* CONFIG_JFFS2_SUMMARY */
16484 diff -urNp linux-2.6.24.4/fs/jffs2/wbuf.c linux-2.6.24.4/fs/jffs2/wbuf.c
16485 --- linux-2.6.24.4/fs/jffs2/wbuf.c 2008-03-24 14:49:18.000000000 -0400
16486 +++ linux-2.6.24.4/fs/jffs2/wbuf.c 2008-03-26 20:21:08.000000000 -0400
16487 @@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
16489 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
16490 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
16491 - .totlen = constant_cpu_to_je32(8)
16492 + .totlen = constant_cpu_to_je32(8),
16493 + .hdr_crc = constant_cpu_to_je32(0)
16497 diff -urNp linux-2.6.24.4/fs/Kconfig linux-2.6.24.4/fs/Kconfig
16498 --- linux-2.6.24.4/fs/Kconfig 2008-03-24 14:49:18.000000000 -0400
16499 +++ linux-2.6.24.4/fs/Kconfig 2008-03-26 20:21:08.000000000 -0400
16500 @@ -937,7 +937,7 @@ config PROC_FS
16503 bool "/proc/kcore support" if !ARM
16504 - depends on PROC_FS && MMU
16505 + depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
16508 bool "/proc/vmcore support (EXPERIMENTAL)"
16509 diff -urNp linux-2.6.24.4/fs/namei.c linux-2.6.24.4/fs/namei.c
16510 --- linux-2.6.24.4/fs/namei.c 2008-03-24 14:49:18.000000000 -0400
16511 +++ linux-2.6.24.4/fs/namei.c 2008-03-26 20:21:08.000000000 -0400
16513 #include <linux/vs_tag.h>
16514 #include <linux/vs_cowbl.h>
16515 #include <linux/vs_context.h>
16516 +#include <linux/grsecurity.h>
16517 #include <asm/namei.h>
16518 #include <asm/uaccess.h>
16520 @@ -621,7 +622,7 @@ static __always_inline int __do_follow_l
16521 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
16522 error = PTR_ERR(cookie);
16523 if (!IS_ERR(cookie)) {
16524 - char *s = nd_get_link(nd);
16525 + const char *s = nd_get_link(nd);
16528 error = __vfs_follow_link(nd, s);
16529 @@ -653,6 +654,13 @@ static inline int do_follow_link(struct
16530 err = security_inode_follow_link(path->dentry, nd);
16534 + if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
16535 + path->dentry->d_inode, path->dentry, nd->mnt)) {
16540 current->link_count++;
16541 current->total_link_count++;
16543 @@ -998,11 +1006,18 @@ return_reval:
16547 + if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
16548 + path_release(nd);
16553 dput_path(&next, nd);
16556 + if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
16562 @@ -1680,9 +1695,17 @@ static int open_namei_create(struct name
16564 struct dentry *dir = nd->dentry;
16566 + if (!gr_acl_handle_creat(path->dentry, nd->dentry, nd->mnt, flag, mode)) {
16568 + goto out_unlock_dput;
16571 if (!IS_POSIXACL(dir->d_inode))
16572 mode &= ~current->fs->umask;
16573 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
16575 + gr_handle_create(path->dentry, nd->mnt);
16577 mutex_unlock(&dir->d_inode->i_mutex);
16579 nd->dentry = path->dentry;
16580 @@ -1733,6 +1756,17 @@ int open_namei(int dfd, const char *path
16585 + if (gr_handle_rawio(nd->dentry->d_inode)) {
16590 + if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
16598 @@ -1782,6 +1816,23 @@ do_last:
16600 * It already exists.
16603 + if (gr_handle_rawio(path.dentry->d_inode)) {
16604 + mutex_unlock(&dir->d_inode->i_mutex);
16608 + if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
16609 + mutex_unlock(&dir->d_inode->i_mutex);
16613 + if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
16614 + mutex_unlock(&dir->d_inode->i_mutex);
16619 mutex_unlock(&dir->d_inode->i_mutex);
16620 audit_inode(pathname, path.dentry);
16622 @@ -1837,6 +1888,13 @@ do_link:
16623 error = security_inode_follow_link(path.dentry, nd);
16627 + if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
16628 + path.dentry, nd->mnt)) {
16633 error = __do_follow_link(&path, nd);
16635 /* Does someone understand code flow here? Or it is only
16636 @@ -1965,6 +2023,22 @@ asmlinkage long sys_mknodat(int dfd, con
16637 if (!IS_POSIXACL(nd.dentry->d_inode))
16638 mode &= ~current->fs->umask;
16639 if (!IS_ERR(dentry)) {
16640 + if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
16643 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
16644 + path_release(&nd);
16648 + if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
16651 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
16652 + path_release(&nd);
16656 switch (mode & S_IFMT) {
16657 case 0: case S_IFREG:
16658 error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
16659 @@ -1982,6 +2056,10 @@ asmlinkage long sys_mknodat(int dfd, con
16665 + gr_handle_create(dentry, nd.mnt);
16669 mutex_unlock(&nd.dentry->d_inode->i_mutex);
16670 @@ -2039,9 +2117,18 @@ asmlinkage long sys_mkdirat(int dfd, con
16671 if (IS_ERR(dentry))
16674 + if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) {
16676 + goto out_unlock_dput;
16679 if (!IS_POSIXACL(nd.dentry->d_inode))
16680 mode &= ~current->fs->umask;
16681 error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
16684 + gr_handle_create(dentry, nd.mnt);
16688 mutex_unlock(&nd.dentry->d_inode->i_mutex);
16689 @@ -2123,6 +2210,8 @@ static long do_rmdir(int dfd, const char
16691 struct dentry *dentry;
16692 struct nameidata nd;
16693 + ino_t saved_ino = 0;
16694 + dev_t saved_dev = 0;
16696 name = getname(pathname);
16698 @@ -2148,7 +2237,22 @@ static long do_rmdir(int dfd, const char
16699 error = PTR_ERR(dentry);
16700 if (IS_ERR(dentry))
16703 + if (dentry->d_inode != NULL) {
16704 + if (dentry->d_inode->i_nlink <= 1) {
16705 + saved_ino = dentry->d_inode->i_ino;
16706 + saved_dev = dentry->d_inode->i_sb->s_dev;
16709 + if (!gr_acl_handle_rmdir(dentry, nd.mnt)) {
16714 error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
16715 + if (!error && (saved_dev || saved_ino))
16716 + gr_handle_delete(saved_ino, saved_dev);
16720 mutex_unlock(&nd.dentry->d_inode->i_mutex);
16721 @@ -2207,6 +2311,8 @@ static long do_unlinkat(int dfd, const c
16722 struct dentry *dentry;
16723 struct nameidata nd;
16724 struct inode *inode = NULL;
16725 + ino_t saved_ino = 0;
16726 + dev_t saved_dev = 0;
16728 name = getname(pathname);
16730 @@ -2222,13 +2328,26 @@ static long do_unlinkat(int dfd, const c
16731 dentry = lookup_hash(&nd);
16732 error = PTR_ERR(dentry);
16733 if (!IS_ERR(dentry)) {
16735 /* Why not before? Because we want correct error value */
16736 if (nd.last.name[nd.last.len])
16738 inode = dentry->d_inode;
16741 + if (inode->i_nlink <= 1) {
16742 + saved_ino = inode->i_ino;
16743 + saved_dev = inode->i_sb->s_dev;
16746 + if (!gr_acl_handle_unlink(dentry, nd.mnt))
16749 atomic_inc(&inode->i_count);
16750 - error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
16753 + error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
16754 + if (!error && (saved_ino || saved_dev))
16755 + gr_handle_delete(saved_ino, saved_dev);
16759 @@ -2309,7 +2428,16 @@ asmlinkage long sys_symlinkat(const char
16760 if (IS_ERR(dentry))
16763 + if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) {
16765 + goto out_dput_unlock;
16768 error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
16771 + gr_handle_create(dentry, nd.mnt);
16775 mutex_unlock(&nd.dentry->d_inode->i_mutex);
16776 @@ -2404,7 +2532,25 @@ asmlinkage long sys_linkat(int olddfd, c
16777 error = PTR_ERR(new_dentry);
16778 if (IS_ERR(new_dentry))
16781 + if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
16782 + old_nd.dentry->d_inode,
16783 + old_nd.dentry->d_inode->i_mode, to)) {
16785 + goto out_unlock_dput;
16788 + if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
16789 + old_nd.dentry, old_nd.mnt, to)) {
16791 + goto out_unlock_dput;
16794 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
16797 + gr_handle_create(new_dentry, nd.mnt);
16801 mutex_unlock(&nd.dentry->d_inode->i_mutex);
16802 @@ -2630,8 +2776,16 @@ static int do_rename(int olddfd, const c
16803 if (new_dentry == trap)
16806 - error = vfs_rename(old_dir->d_inode, old_dentry,
16807 + error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
16808 + old_dentry, old_dir->d_inode, oldnd.mnt,
16812 + error = vfs_rename(old_dir->d_inode, old_dentry,
16813 new_dir->d_inode, new_dentry);
16815 + gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry,
16816 + new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
16820 diff -urNp linux-2.6.24.4/fs/namespace.c linux-2.6.24.4/fs/namespace.c
16821 --- linux-2.6.24.4/fs/namespace.c 2008-03-24 14:49:18.000000000 -0400
16822 +++ linux-2.6.24.4/fs/namespace.c 2008-03-26 20:21:08.000000000 -0400
16824 #include <linux/vs_tag.h>
16825 #include <linux/vserver/space.h>
16826 #include <linux/vserver/global.h>
16827 +#include <linux/grsecurity.h>
16828 #include <asm/uaccess.h>
16829 #include <asm/unistd.h>
16831 @@ -597,6 +598,8 @@ static int do_umount(struct vfsmount *mn
16833 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
16836 + gr_log_remount(mnt->mnt_devname, retval);
16838 up_write(&sb->s_umount);
16840 @@ -617,6 +620,9 @@ static int do_umount(struct vfsmount *mn
16841 security_sb_umount_busy(mnt);
16842 up_write(&namespace_sem);
16843 release_mounts(&umount_list);
16845 + gr_log_unmount(mnt->mnt_devname, retval);
16850 @@ -1442,6 +1448,11 @@ long do_mount(char *dev_name, char *dir_
16854 + if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
16859 if (flags & MS_REMOUNT)
16860 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
16862 @@ -1456,6 +1467,9 @@ long do_mount(char *dev_name, char *dir_
16863 dev_name, data_page);
16867 + gr_log_mount(dev_name, dir_name, retval);
16872 @@ -1693,6 +1707,9 @@ asmlinkage long sys_pivot_root(const cha
16873 if (!capable(CAP_SYS_ADMIN))
16876 + if (gr_handle_chroot_pivot())
16881 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
16882 diff -urNp linux-2.6.24.4/fs/nfs/callback_xdr.c linux-2.6.24.4/fs/nfs/callback_xdr.c
16883 --- linux-2.6.24.4/fs/nfs/callback_xdr.c 2008-03-24 14:49:18.000000000 -0400
16884 +++ linux-2.6.24.4/fs/nfs/callback_xdr.c 2008-03-26 20:21:08.000000000 -0400
16885 @@ -139,7 +139,7 @@ static __be32 decode_compound_hdr_arg(st
16886 if (unlikely(status != 0))
16888 /* We do not like overly long tags! */
16889 - if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) {
16890 + if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12) {
16891 printk("NFSv4 CALLBACK %s: client sent tag of length %u\n",
16892 __FUNCTION__, hdr->taglen);
16893 return htonl(NFS4ERR_RESOURCE);
16894 diff -urNp linux-2.6.24.4/fs/nfs/nfs4proc.c linux-2.6.24.4/fs/nfs/nfs4proc.c
16895 --- linux-2.6.24.4/fs/nfs/nfs4proc.c 2008-03-24 14:49:18.000000000 -0400
16896 +++ linux-2.6.24.4/fs/nfs/nfs4proc.c 2008-03-26 20:21:08.000000000 -0400
16897 @@ -656,7 +656,7 @@ static int _nfs4_do_open_reclaim(struct
16898 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
16900 struct nfs_server *server = NFS_SERVER(state->inode);
16901 - struct nfs4_exception exception = { };
16902 + struct nfs4_exception exception = {0, 0};
16905 err = _nfs4_do_open_reclaim(ctx, state);
16906 @@ -698,7 +698,7 @@ static int _nfs4_open_delegation_recall(
16908 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
16910 - struct nfs4_exception exception = { };
16911 + struct nfs4_exception exception = {0, 0};
16912 struct nfs_server *server = NFS_SERVER(state->inode);
16915 @@ -987,7 +987,7 @@ static int _nfs4_open_expired(struct nfs
16916 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
16918 struct nfs_server *server = NFS_SERVER(state->inode);
16919 - struct nfs4_exception exception = { };
16920 + struct nfs4_exception exception = {0, 0};
16924 @@ -1089,7 +1089,7 @@ out_err:
16926 static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
16928 - struct nfs4_exception exception = { };
16929 + struct nfs4_exception exception = {0, 0};
16930 struct nfs4_state *res;
16933 @@ -1178,7 +1178,7 @@ static int nfs4_do_setattr(struct inode
16934 struct iattr *sattr, struct nfs4_state *state)
16936 struct nfs_server *server = NFS_SERVER(inode);
16937 - struct nfs4_exception exception = { };
16938 + struct nfs4_exception exception = {0, 0};
16941 err = nfs4_handle_exception(server,
16942 @@ -1484,7 +1484,7 @@ static int _nfs4_server_capabilities(str
16944 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
16946 - struct nfs4_exception exception = { };
16947 + struct nfs4_exception exception = {0, 0};
16950 err = nfs4_handle_exception(server,
16951 @@ -1517,7 +1517,7 @@ static int _nfs4_lookup_root(struct nfs_
16952 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
16953 struct nfs_fsinfo *info)
16955 - struct nfs4_exception exception = { };
16956 + struct nfs4_exception exception = {0, 0};
16959 err = nfs4_handle_exception(server,
16960 @@ -1606,7 +1606,7 @@ static int _nfs4_proc_getattr(struct nfs
16962 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
16964 - struct nfs4_exception exception = { };
16965 + struct nfs4_exception exception = {0, 0};
16968 err = nfs4_handle_exception(server,
16969 @@ -1696,7 +1696,7 @@ static int nfs4_proc_lookupfh(struct nfs
16970 struct qstr *name, struct nfs_fh *fhandle,
16971 struct nfs_fattr *fattr)
16973 - struct nfs4_exception exception = { };
16974 + struct nfs4_exception exception = {0, 0};
16977 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
16978 @@ -1725,7 +1725,7 @@ static int _nfs4_proc_lookup(struct inod
16980 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
16982 - struct nfs4_exception exception = { };
16983 + struct nfs4_exception exception = {0, 0};
16986 err = nfs4_handle_exception(NFS_SERVER(dir),
16987 @@ -1789,7 +1789,7 @@ static int _nfs4_proc_access(struct inod
16989 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
16991 - struct nfs4_exception exception = { };
16992 + struct nfs4_exception exception = {0, 0};
16995 err = nfs4_handle_exception(NFS_SERVER(inode),
16996 @@ -1844,7 +1844,7 @@ static int _nfs4_proc_readlink(struct in
16997 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
16998 unsigned int pgbase, unsigned int pglen)
17000 - struct nfs4_exception exception = { };
17001 + struct nfs4_exception exception = {0, 0};
17004 err = nfs4_handle_exception(NFS_SERVER(inode),
17005 @@ -1940,7 +1940,7 @@ static int _nfs4_proc_remove(struct inod
17007 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
17009 - struct nfs4_exception exception = { };
17010 + struct nfs4_exception exception = {0, 0};
17013 err = nfs4_handle_exception(NFS_SERVER(dir),
17014 @@ -2012,7 +2012,7 @@ static int _nfs4_proc_rename(struct inod
17015 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
17016 struct inode *new_dir, struct qstr *new_name)
17018 - struct nfs4_exception exception = { };
17019 + struct nfs4_exception exception = {0, 0};
17022 err = nfs4_handle_exception(NFS_SERVER(old_dir),
17023 @@ -2059,7 +2059,7 @@ static int _nfs4_proc_link(struct inode
17025 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
17027 - struct nfs4_exception exception = { };
17028 + struct nfs4_exception exception = {0, 0};
17031 err = nfs4_handle_exception(NFS_SERVER(inode),
17032 @@ -2116,7 +2116,7 @@ static int _nfs4_proc_symlink(struct ino
17033 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
17034 struct page *page, unsigned int len, struct iattr *sattr)
17036 - struct nfs4_exception exception = { };
17037 + struct nfs4_exception exception = {0, 0};
17040 err = nfs4_handle_exception(NFS_SERVER(dir),
17041 @@ -2169,7 +2169,7 @@ static int _nfs4_proc_mkdir(struct inode
17042 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
17043 struct iattr *sattr)
17045 - struct nfs4_exception exception = { };
17046 + struct nfs4_exception exception = {0, 0};
17049 err = nfs4_handle_exception(NFS_SERVER(dir),
17050 @@ -2218,7 +2218,7 @@ static int _nfs4_proc_readdir(struct den
17051 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
17052 u64 cookie, struct page *page, unsigned int count, int plus)
17054 - struct nfs4_exception exception = { };
17055 + struct nfs4_exception exception = {0, 0};
17058 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
17059 @@ -2288,7 +2288,7 @@ static int _nfs4_proc_mknod(struct inode
17060 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
17061 struct iattr *sattr, dev_t rdev)
17063 - struct nfs4_exception exception = { };
17064 + struct nfs4_exception exception = {0, 0};
17067 err = nfs4_handle_exception(NFS_SERVER(dir),
17068 @@ -2317,7 +2317,7 @@ static int _nfs4_proc_statfs(struct nfs_
17070 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
17072 - struct nfs4_exception exception = { };
17073 + struct nfs4_exception exception = {0, 0};
17076 err = nfs4_handle_exception(server,
17077 @@ -2345,7 +2345,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
17079 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
17081 - struct nfs4_exception exception = { };
17082 + struct nfs4_exception exception = {0, 0};
17086 @@ -2388,7 +2388,7 @@ static int _nfs4_proc_pathconf(struct nf
17087 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
17088 struct nfs_pathconf *pathconf)
17090 - struct nfs4_exception exception = { };
17091 + struct nfs4_exception exception = {0, 0};
17095 @@ -2708,7 +2708,7 @@ out_free:
17097 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
17099 - struct nfs4_exception exception = { };
17100 + struct nfs4_exception exception = {0, 0};
17103 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
17104 @@ -2762,7 +2762,7 @@ static int __nfs4_proc_set_acl(struct in
17106 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
17108 - struct nfs4_exception exception = { };
17109 + struct nfs4_exception exception = {0, 0};
17112 err = nfs4_handle_exception(NFS_SERVER(inode),
17113 @@ -3059,7 +3059,7 @@ static int _nfs4_proc_delegreturn(struct
17114 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
17116 struct nfs_server *server = NFS_SERVER(inode);
17117 - struct nfs4_exception exception = { };
17118 + struct nfs4_exception exception = {0, 0};
17121 err = _nfs4_proc_delegreturn(inode, cred, stateid);
17122 @@ -3134,7 +3134,7 @@ out:
17124 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
17126 - struct nfs4_exception exception = { };
17127 + struct nfs4_exception exception = {0, 0};
17131 @@ -3476,7 +3476,7 @@ static int _nfs4_do_setlk(struct nfs4_st
17132 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
17134 struct nfs_server *server = NFS_SERVER(state->inode);
17135 - struct nfs4_exception exception = { };
17136 + struct nfs4_exception exception = {0, 0};
17140 @@ -3494,7 +3494,7 @@ static int nfs4_lock_reclaim(struct nfs4
17141 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
17143 struct nfs_server *server = NFS_SERVER(state->inode);
17144 - struct nfs4_exception exception = { };
17145 + struct nfs4_exception exception = {0, 0};
17148 err = nfs4_set_lock_state(state, request);
17149 @@ -3555,7 +3555,7 @@ out:
17151 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
17153 - struct nfs4_exception exception = { };
17154 + struct nfs4_exception exception = {0, 0};
17158 @@ -3605,7 +3605,7 @@ nfs4_proc_lock(struct file *filp, int cm
17159 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
17161 struct nfs_server *server = NFS_SERVER(state->inode);
17162 - struct nfs4_exception exception = { };
17163 + struct nfs4_exception exception = {0, 0};
17166 err = nfs4_set_lock_state(state, fl);
17167 diff -urNp linux-2.6.24.4/fs/nfsd/export.c linux-2.6.24.4/fs/nfsd/export.c
17168 --- linux-2.6.24.4/fs/nfsd/export.c 2008-03-24 14:49:18.000000000 -0400
17169 +++ linux-2.6.24.4/fs/nfsd/export.c 2008-03-26 20:21:08.000000000 -0400
17170 @@ -476,7 +476,7 @@ static int secinfo_parse(char **mesg, ch
17171 * probably discover the problem when someone fails to
17174 - if (f->pseudoflavor < 0)
17175 + if ((s32)f->pseudoflavor < 0)
17177 err = get_int(mesg, &f->flags);
17179 diff -urNp linux-2.6.24.4/fs/nfsd/nfs4state.c linux-2.6.24.4/fs/nfsd/nfs4state.c
17180 --- linux-2.6.24.4/fs/nfsd/nfs4state.c 2008-03-24 14:49:18.000000000 -0400
17181 +++ linux-2.6.24.4/fs/nfsd/nfs4state.c 2008-03-26 20:21:08.000000000 -0400
17182 @@ -1233,7 +1233,7 @@ static int access_valid(u32 x)
17184 static int deny_valid(u32 x)
17186 - return (x >= 0 && x < 5);
17191 diff -urNp linux-2.6.24.4/fs/nls/nls_base.c linux-2.6.24.4/fs/nls/nls_base.c
17192 --- linux-2.6.24.4/fs/nls/nls_base.c 2008-03-24 14:49:18.000000000 -0400
17193 +++ linux-2.6.24.4/fs/nls/nls_base.c 2008-03-26 20:21:08.000000000 -0400
17194 @@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
17195 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
17196 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
17197 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
17198 - {0, /* end of table */}
17199 + {0, 0, 0, 0, 0, /* end of table */}
17203 diff -urNp linux-2.6.24.4/fs/ntfs/file.c linux-2.6.24.4/fs/ntfs/file.c
17204 --- linux-2.6.24.4/fs/ntfs/file.c 2008-03-24 14:49:18.000000000 -0400
17205 +++ linux-2.6.24.4/fs/ntfs/file.c 2008-03-26 20:21:08.000000000 -0400
17206 @@ -2293,6 +2293,6 @@ const struct inode_operations ntfs_file_
17207 #endif /* NTFS_RW */
17210 -const struct file_operations ntfs_empty_file_ops = {};
17211 +const struct file_operations ntfs_empty_file_ops;
17213 -const struct inode_operations ntfs_empty_inode_ops = {};
17214 +const struct inode_operations ntfs_empty_inode_ops;
17215 diff -urNp linux-2.6.24.4/fs/open.c linux-2.6.24.4/fs/open.c
17216 --- linux-2.6.24.4/fs/open.c 2008-03-24 14:49:18.000000000 -0400
17217 +++ linux-2.6.24.4/fs/open.c 2008-03-26 20:21:08.000000000 -0400
17219 #include <linux/vs_dlimit.h>
17220 #include <linux/vs_tag.h>
17221 #include <linux/vs_cowbl.h>
17222 +#include <linux/grsecurity.h>
17224 int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
17226 @@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
17230 + if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
17233 newattrs.ia_size = length;
17234 newattrs.ia_valid = ATTR_SIZE | time_attrs;
17236 @@ -461,6 +465,9 @@ asmlinkage long sys_faccessat(int dfd, c
17237 if(IS_RDONLY(nd.dentry->d_inode))
17240 + if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
17246 @@ -490,6 +497,8 @@ asmlinkage long sys_chdir(const char __u
17250 + gr_log_chdir(nd.dentry, nd.mnt);
17252 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
17255 @@ -520,6 +529,13 @@ asmlinkage long sys_fchdir(unsigned int
17258 error = file_permission(file, MAY_EXEC);
17260 + if (!error && !gr_chroot_fchdir(dentry, mnt))
17264 + gr_log_chdir(dentry, mnt);
17267 set_fs_pwd(current->fs, mnt, dentry);
17269 @@ -545,8 +561,16 @@ asmlinkage long sys_chroot(const char __
17270 if (!capable(CAP_SYS_CHROOT))
17273 + if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
17274 + goto dput_and_out;
17276 set_fs_root(current->fs, nd.mnt, nd.dentry);
17279 + gr_handle_chroot_caps(current);
17281 + gr_handle_chroot_chdir(nd.dentry, nd.mnt);
17286 @@ -577,9 +601,22 @@ asmlinkage long sys_fchmod(unsigned int
17288 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
17291 + if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
17296 mutex_lock(&inode->i_mutex);
17297 if (mode == (mode_t) -1)
17298 mode = inode->i_mode;
17300 + if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
17302 + mutex_unlock(&inode->i_mutex);
17306 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
17307 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
17308 err = notify_change(dentry, &newattrs);
17309 @@ -612,9 +649,21 @@ asmlinkage long sys_fchmodat(int dfd, co
17310 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
17313 + if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
17315 + goto dput_and_out;
17318 mutex_lock(&inode->i_mutex);
17319 if (mode == (mode_t) -1)
17320 mode = inode->i_mode;
17322 + if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
17324 + mutex_unlock(&inode->i_mutex);
17325 + goto dput_and_out;
17328 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
17329 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
17330 error = notify_change(nd.dentry, &newattrs);
17331 @@ -648,6 +697,12 @@ static int chown_common(struct dentry *
17333 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
17336 + if (!gr_acl_handle_chown(dentry, mnt)) {
17341 newattrs.ia_valid = ATTR_CTIME;
17342 if (user != (uid_t) -1) {
17343 newattrs.ia_valid |= ATTR_UID;
17344 @@ -939,6 +994,7 @@ repeat:
17345 * N.B. For clone tasks sharing a files structure, this test
17346 * will limit the total number of files that can be opened.
17348 + gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
17349 if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
17352 diff -urNp linux-2.6.24.4/fs/partitions/efi.c linux-2.6.24.4/fs/partitions/efi.c
17353 --- linux-2.6.24.4/fs/partitions/efi.c 2008-03-24 14:49:18.000000000 -0400
17354 +++ linux-2.6.24.4/fs/partitions/efi.c 2008-03-26 20:21:08.000000000 -0400
17357 #define Dprintk(x...) printk(KERN_DEBUG x)
17359 -#define Dprintk(x...)
17360 +#define Dprintk(x...) do {} while (0)
17363 /* This allows a kernel command line option 'gpt' to override
17364 diff -urNp linux-2.6.24.4/fs/pipe.c linux-2.6.24.4/fs/pipe.c
17365 --- linux-2.6.24.4/fs/pipe.c 2008-03-24 14:49:18.000000000 -0400
17366 +++ linux-2.6.24.4/fs/pipe.c 2008-03-26 20:21:08.000000000 -0400
17367 @@ -887,7 +887,7 @@ void free_pipe_info(struct inode *inode)
17368 inode->i_pipe = NULL;
17371 -static struct vfsmount *pipe_mnt __read_mostly;
17372 +struct vfsmount *pipe_mnt __read_mostly;
17373 static int pipefs_delete_dentry(struct dentry *dentry)
17376 diff -urNp linux-2.6.24.4/fs/proc/array.c linux-2.6.24.4/fs/proc/array.c
17377 --- linux-2.6.24.4/fs/proc/array.c 2008-03-24 14:49:18.000000000 -0400
17378 +++ linux-2.6.24.4/fs/proc/array.c 2008-03-26 20:21:08.000000000 -0400
17379 @@ -305,6 +305,21 @@ static inline char *task_context_switch_
17383 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
17384 +static inline char *task_pax(struct task_struct *p, char *buffer)
17387 + return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
17388 + p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
17389 + p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
17390 + p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
17391 + p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
17392 + p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
17394 + return buffer + sprintf(buffer, "PaX:\t-----\n");
17398 int proc_pid_status(struct task_struct *task, char *buffer)
17400 char *orig = buffer;
17401 @@ -324,6 +339,11 @@ int proc_pid_status(struct task_struct *
17402 buffer = task_show_regs(task, buffer);
17404 buffer = task_context_switch_counts(task, buffer);
17406 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
17407 + buffer = task_pax(task, buffer);
17410 return buffer - orig;
17413 @@ -386,6 +406,12 @@ static cputime_t task_gtime(struct task_
17417 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17418 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
17419 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
17420 + _mm->pax_flags & MF_PAX_SEGMEXEC))
17423 static int do_task_stat(struct task_struct *task, char *buffer, int whole)
17425 unsigned long vsize, eip, esp, wchan = ~0UL;
17426 @@ -481,6 +507,19 @@ static int do_task_stat(struct task_stru
17427 gtime = task_gtime(task);
17430 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17431 + if (PAX_RAND_FLAGS(mm)) {
17437 +#ifdef CONFIG_GRKERNSEC_HIDESYM
17443 /* scale priority and nice values from timeslices to -20..20 */
17444 /* to make it look like a "normal" Unix priority/nice value */
17445 priority = task_prio(task);
17446 @@ -521,9 +560,15 @@ static int do_task_stat(struct task_stru
17448 mm ? get_mm_rss(mm) : 0,
17450 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17451 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
17452 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
17453 + PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
17455 mm ? mm->start_code : 0,
17456 mm ? mm->end_code : 0,
17457 mm ? mm->start_stack : 0,
17461 /* The signal information here is obsolete.
17462 @@ -572,3 +617,14 @@ int proc_pid_statm(struct task_struct *t
17463 return sprintf(buffer, "%d %d %d %d %d %d %d\n",
17464 size, resident, shared, text, lib, data, 0);
17467 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
17468 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
17472 + len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
17477 diff -urNp linux-2.6.24.4/fs/proc/base.c linux-2.6.24.4/fs/proc/base.c
17478 --- linux-2.6.24.4/fs/proc/base.c 2008-03-24 14:49:18.000000000 -0400
17479 +++ linux-2.6.24.4/fs/proc/base.c 2008-03-26 20:21:08.000000000 -0400
17481 #include <linux/pid_namespace.h>
17482 #include <linux/vs_context.h>
17483 #include <linux/vs_network.h>
17484 +#include <linux/grsecurity.h>
17486 #include "internal.h"
17489 @@ -126,7 +128,7 @@ struct pid_entry {
17490 NULL, &proc_info_file_operations, \
17491 { .proc_read = &proc_##OTYPE } )
17494 +int maps_protect = 1;
17495 EXPORT_SYMBOL(maps_protect);
17497 static struct fs_struct *get_fs_struct(struct task_struct *task)
17498 @@ -200,7 +202,7 @@ static int proc_root_link(struct inode *
17499 (task->parent == current && \
17500 (task->ptrace & PT_PTRACED) && \
17501 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
17502 - security_ptrace(current,task) == 0))
17503 + security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
17505 struct mm_struct *mm_for_maps(struct task_struct *task)
17507 @@ -265,9 +267,9 @@ static int proc_pid_auxv(struct task_str
17508 struct mm_struct *mm = get_task_mm(task);
17510 unsigned int nwords = 0;
17514 - while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
17515 + } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
17516 res = nwords * sizeof(mm->saved_auxv[0]);
17517 if (res > PAGE_SIZE)
17519 @@ -609,7 +611,7 @@ static ssize_t mem_read(struct file * fi
17523 - if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
17524 + if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
17528 @@ -679,7 +681,7 @@ static ssize_t mem_write(struct file * f
17532 - if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
17533 + if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
17537 @@ -1202,7 +1204,11 @@ static struct inode *proc_pid_make_inode
17539 if (task_dumpable(task)) {
17540 inode->i_uid = task->euid;
17541 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
17542 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
17544 inode->i_gid = task->egid;
17547 security_task_to_inode(task, inode);
17549 @@ -1218,17 +1224,45 @@ static int pid_getattr(struct vfsmount *
17551 struct inode *inode = dentry->d_inode;
17552 struct task_struct *task;
17553 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17554 + struct task_struct *tmp = current;
17557 generic_fillattr(inode, stat);
17562 task = pid_task(proc_pid(inode), PIDTYPE_PID);
17565 + if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
17566 + rcu_read_unlock();
17572 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17573 + && (!tmp->uid || (tmp->uid == task->uid)
17574 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
17575 + || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
17580 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
17581 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17582 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
17583 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17584 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
17586 task_dumpable(task)) {
17587 stat->uid = task->euid;
17588 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
17589 + stat->gid = CONFIG_GRKERNSEC_PROC_GID;
17591 stat->gid = task->egid;
17596 @@ -1256,11 +1290,21 @@ static int pid_revalidate(struct dentry
17598 struct inode *inode = dentry->d_inode;
17599 struct task_struct *task = get_proc_task(inode);
17602 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
17603 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17604 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
17605 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17606 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
17608 task_dumpable(task)) {
17609 inode->i_uid = task->euid;
17610 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
17611 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
17613 inode->i_gid = task->egid;
17618 @@ -1633,12 +1677,22 @@ static int proc_fd_permission(struct ino
17619 struct nameidata *nd)
17622 + struct task_struct *task;
17624 rv = generic_permission(inode, mask, NULL);
17628 if (task_pid(current) == proc_pid(inode))
17631 + task = get_proc_task(inode);
17632 + if (task == NULL)
17635 + if (gr_acl_handle_procpidmem(task))
17638 + put_task_struct(task);
17643 @@ -1749,6 +1803,9 @@ static struct dentry *proc_pident_lookup
17647 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
17651 * Yes, it does not scale. And it should not. Don't add
17652 * new entries into /proc/<tgid>/ without very good reasons.
17653 @@ -1793,6 +1850,9 @@ static int proc_pident_readdir(struct fi
17657 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
17663 @@ -2147,6 +2207,9 @@ static struct dentry *proc_base_lookup(s
17667 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
17670 error = proc_base_instantiate(dir, dentry, task, p);
17673 @@ -2250,6 +2313,9 @@ static const struct pid_entry tgid_base_
17674 INF("io", S_IRUGO, pid_io_accounting),
17676 INF("nsproxy", S_IRUGO, pid_nsproxy),
17677 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
17678 + INF("ipaddr", S_IRUSR, pid_ipaddr),
17682 static int proc_tgid_base_readdir(struct file * filp,
17683 @@ -2378,7 +2444,14 @@ static struct dentry *proc_pid_instantia
17687 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17688 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
17689 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17690 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
17691 + inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
17693 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
17695 inode->i_op = &proc_tgid_base_inode_operations;
17696 inode->i_fop = &proc_tgid_base_operations;
17697 inode->i_flags|=S_IMMUTABLE;
17698 @@ -2421,7 +2494,11 @@ struct dentry *proc_pid_lookup(struct in
17702 + if (gr_check_hidden_task(task))
17703 + goto out_put_task;
17705 result = proc_pid_instantiate(dir, dentry, task, NULL);
17707 put_task_struct(task);
17710 @@ -2486,6 +2563,9 @@ int proc_pid_readdir(struct file * filp,
17712 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
17713 struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
17714 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17715 + struct task_struct *tmp = current;
17717 struct tgid_iter iter;
17718 struct pid_namespace *ns;
17720 @@ -2504,6 +2584,17 @@ int proc_pid_readdir(struct file * filp,
17721 for (iter = next_tgid(ns, iter);
17723 iter.tgid += 1, iter = next_tgid(ns, iter)) {
17724 + if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
17725 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17726 + || (tmp->uid && (iter.task->uid != tmp->uid)
17727 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
17728 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
17735 filp->f_pos = iter.tgid + TGID_OFFSET;
17736 if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
17737 put_task_struct(iter.task);
17738 diff -urNp linux-2.6.24.4/fs/proc/inode.c linux-2.6.24.4/fs/proc/inode.c
17739 --- linux-2.6.24.4/fs/proc/inode.c 2008-03-24 14:49:18.000000000 -0400
17740 +++ linux-2.6.24.4/fs/proc/inode.c 2008-03-26 20:21:08.000000000 -0400
17741 @@ -411,7 +411,11 @@ struct inode *proc_get_inode(struct supe
17743 inode->i_mode = de->mode;
17744 inode->i_uid = de->uid;
17745 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
17746 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
17748 inode->i_gid = de->gid;
17752 inode->i_size = de->size;
17753 diff -urNp linux-2.6.24.4/fs/proc/internal.h linux-2.6.24.4/fs/proc/internal.h
17754 --- linux-2.6.24.4/fs/proc/internal.h 2008-03-24 14:49:18.000000000 -0400
17755 +++ linux-2.6.24.4/fs/proc/internal.h 2008-03-26 20:21:08.000000000 -0400
17756 @@ -52,6 +52,9 @@ extern int proc_tid_stat(struct task_str
17757 extern int proc_pid_status(struct task_struct *, char *);
17758 extern int proc_pid_statm(struct task_struct *, char *);
17759 extern int proc_pid_nsproxy(struct task_struct *, char *);
17760 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
17761 +extern int proc_pid_ipaddr(struct task_struct*,char*);
17764 extern const struct file_operations proc_maps_operations;
17765 extern const struct file_operations proc_numa_maps_operations;
17766 diff -urNp linux-2.6.24.4/fs/proc/proc_misc.c linux-2.6.24.4/fs/proc/proc_misc.c
17767 --- linux-2.6.24.4/fs/proc/proc_misc.c 2008-03-24 14:49:18.000000000 -0400
17768 +++ linux-2.6.24.4/fs/proc/proc_misc.c 2008-03-26 20:21:08.000000000 -0400
17769 @@ -687,6 +687,8 @@ void create_seq_entry(char *name, mode_t
17771 void __init proc_misc_init(void)
17777 int (*read_proc)(char*,char**,off_t,int,int*,void*);
17778 @@ -702,13 +704,24 @@ void __init proc_misc_init(void)
17779 {"stram", stram_read_proc},
17781 {"filesystems", filesystems_read_proc},
17782 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
17783 {"cmdline", cmdline_read_proc},
17785 {"execdomains", execdomains_read_proc},
17788 for (p = simple_ones; p->name; p++)
17789 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
17791 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17792 + gr_mode = S_IRUSR;
17793 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17794 + gr_mode = S_IRUSR | S_IRGRP;
17796 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17797 + create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
17800 proc_symlink("mounts", NULL, "self/mounts");
17802 /* And now for trickier ones */
17803 @@ -721,7 +734,11 @@ void __init proc_misc_init(void)
17806 create_seq_entry("locks", 0, &proc_locks_operations);
17807 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17808 + create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
17810 create_seq_entry("devices", 0, &proc_devinfo_operations);
17812 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
17813 #ifdef CONFIG_BLOCK
17814 create_seq_entry("partitions", 0, &proc_partitions_operations);
17815 @@ -729,7 +746,11 @@ void __init proc_misc_init(void)
17816 create_seq_entry("stat", 0, &proc_stat_operations);
17817 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
17818 #ifdef CONFIG_SLABINFO
17819 +#ifdef CONFIG_GRKRENSEC_PROC_ADD
17820 + create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
17822 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
17824 #ifdef CONFIG_DEBUG_SLAB_LEAK
17825 create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
17827 @@ -747,7 +768,7 @@ void __init proc_misc_init(void)
17828 #ifdef CONFIG_SCHEDSTATS
17829 create_seq_entry("schedstat", 0, &proc_schedstat_operations);
17831 -#ifdef CONFIG_PROC_KCORE
17832 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
17833 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
17834 if (proc_root_kcore) {
17835 proc_root_kcore->proc_fops = &proc_kcore_operations;
17836 diff -urNp linux-2.6.24.4/fs/proc/proc_net.c linux-2.6.24.4/fs/proc/proc_net.c
17837 --- linux-2.6.24.4/fs/proc/proc_net.c 2008-03-24 14:49:18.000000000 -0400
17838 +++ linux-2.6.24.4/fs/proc/proc_net.c 2008-03-26 20:21:08.000000000 -0400
17839 @@ -69,7 +69,13 @@ static __net_init int proc_net_ns_init(s
17843 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17844 + netd = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, root);
17845 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17846 + netd = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, root);
17848 netd = proc_mkdir("net", root);
17853 diff -urNp linux-2.6.24.4/fs/proc/proc_sysctl.c linux-2.6.24.4/fs/proc/proc_sysctl.c
17854 --- linux-2.6.24.4/fs/proc/proc_sysctl.c 2008-03-24 14:49:18.000000000 -0400
17855 +++ linux-2.6.24.4/fs/proc/proc_sysctl.c 2008-03-26 20:21:08.000000000 -0400
17857 #include <linux/security.h>
17858 #include "internal.h"
17860 +extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
17862 static struct dentry_operations proc_sys_dentry_operations;
17863 static const struct file_operations proc_sys_file_operations;
17864 static struct inode_operations proc_sys_inode_operations;
17865 @@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st
17869 + if (gr_handle_sysctl(table, 001))
17872 err = ERR_PTR(-ENOMEM);
17873 inode = proc_sys_make_inode(dir, table);
17875 @@ -360,6 +365,9 @@ static int proc_sys_readdir(struct file
17876 if (pos < filp->f_pos)
17879 + if (gr_handle_sysctl(table, 0))
17882 if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
17884 filp->f_pos = pos + 1;
17885 @@ -422,6 +430,30 @@ out:
17889 +/* Eric Biederman is to blame */
17890 +static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
17893 + struct ctl_table_header *head;
17894 + struct ctl_table *table;
17896 + table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
17897 + /* Has the sysctl entry disappeared on us? */
17901 + if (gr_handle_sysctl(table, 001)) {
17907 + sysctl_head_finish(head);
17909 + generic_fillattr(dentry->d_inode, stat);
17913 static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
17915 struct inode *inode = dentry->d_inode;
17916 @@ -450,6 +482,7 @@ static struct inode_operations proc_sys_
17917 .lookup = proc_sys_lookup,
17918 .permission = proc_sys_permission,
17919 .setattr = proc_sys_setattr,
17920 + .getattr = proc_sys_getattr,
17923 static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
17924 diff -urNp linux-2.6.24.4/fs/proc/root.c linux-2.6.24.4/fs/proc/root.c
17925 --- linux-2.6.24.4/fs/proc/root.c 2008-03-24 14:49:18.000000000 -0400
17926 +++ linux-2.6.24.4/fs/proc/root.c 2008-03-26 20:21:08.000000000 -0400
17927 @@ -137,7 +137,15 @@ void __init proc_root_init(void)
17928 #ifdef CONFIG_PROC_DEVICETREE
17929 proc_device_tree_init();
17931 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17932 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17933 + proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
17934 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17935 + proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
17938 proc_bus = proc_mkdir("bus", NULL);
17944 diff -urNp linux-2.6.24.4/fs/proc/task_mmu.c linux-2.6.24.4/fs/proc/task_mmu.c
17945 --- linux-2.6.24.4/fs/proc/task_mmu.c 2008-03-24 14:49:18.000000000 -0400
17946 +++ linux-2.6.24.4/fs/proc/task_mmu.c 2008-03-26 20:21:08.000000000 -0400
17947 @@ -44,15 +44,27 @@ char *task_mem(struct mm_struct *mm, cha
17948 "VmStk:\t%8lu kB\n"
17949 "VmExe:\t%8lu kB\n"
17950 "VmLib:\t%8lu kB\n"
17951 - "VmPTE:\t%8lu kB\n",
17952 - hiwater_vm << (PAGE_SHIFT-10),
17953 + "VmPTE:\t%8lu kB\n"
17955 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
17956 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
17959 + ,hiwater_vm << (PAGE_SHIFT-10),
17960 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
17961 mm->locked_vm << (PAGE_SHIFT-10),
17962 hiwater_rss << (PAGE_SHIFT-10),
17963 total_rss << (PAGE_SHIFT-10),
17964 data << (PAGE_SHIFT-10),
17965 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
17966 - (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
17967 + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
17969 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
17970 + , mm->context.user_cs_base, mm->context.user_cs_limit
17978 @@ -131,6 +143,12 @@ struct pmd_walker {
17979 unsigned long, void *);
17982 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17983 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
17984 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
17985 + _mm->pax_flags & MF_PAX_SEGMEXEC))
17988 static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
17990 struct proc_maps_private *priv = m->private;
17991 @@ -153,13 +171,22 @@ static int show_map_internal(struct seq_
17994 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
17995 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17996 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
17997 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
18002 flags & VM_READ ? 'r' : '-',
18003 flags & VM_WRITE ? 'w' : '-',
18004 flags & VM_EXEC ? 'x' : '-',
18005 flags & VM_MAYSHARE ? 's' : 'p',
18006 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
18007 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
18009 vma->vm_pgoff << PAGE_SHIFT,
18011 MAJOR(dev), MINOR(dev), ino, &len);
18014 @@ -173,11 +200,11 @@ static int show_map_internal(struct seq_
18015 const char *name = arch_vma_name(vma);
18018 - if (vma->vm_start <= mm->start_brk &&
18019 - vma->vm_end >= mm->brk) {
18020 + if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
18022 - } else if (vma->vm_start <= mm->start_stack &&
18023 - vma->vm_end >= mm->start_stack) {
18024 + } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
18025 + (vma->vm_start <= mm->start_stack &&
18026 + vma->vm_end >= mm->start_stack)) {
18030 @@ -191,7 +218,27 @@ static int show_map_internal(struct seq_
18037 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
18038 + if (PAX_RAND_FLAGS(mm))
18040 + "Size: %8lu kB\n"
18042 + "Shared_Clean: %8lu kB\n"
18043 + "Shared_Dirty: %8lu kB\n"
18044 + "Private_Clean: %8lu kB\n"
18045 + "Private_Dirty: %8lu kB\n",
18046 + "Referenced: %8lu kB\n",
18059 @@ -207,6 +254,7 @@ static int show_map_internal(struct seq_
18060 mss->private_clean >> 10,
18061 mss->private_dirty >> 10,
18062 mss->referenced >> 10);
18065 if (m->count < m->size) /* vma is copied successfully */
18066 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
18067 diff -urNp linux-2.6.24.4/fs/readdir.c linux-2.6.24.4/fs/readdir.c
18068 --- linux-2.6.24.4/fs/readdir.c 2008-03-24 14:49:18.000000000 -0400
18069 +++ linux-2.6.24.4/fs/readdir.c 2008-03-26 20:21:08.000000000 -0400
18071 #include <linux/security.h>
18072 #include <linux/syscalls.h>
18073 #include <linux/unistd.h>
18074 +#include <linux/namei.h>
18075 +#include <linux/grsecurity.h>
18077 #include <asm/uaccess.h>
18079 @@ -64,6 +66,7 @@ struct old_linux_dirent {
18081 struct readdir_callback {
18082 struct old_linux_dirent __user * dirent;
18083 + struct file * file;
18087 @@ -79,6 +82,10 @@ static int fillonedir(void * __buf, cons
18089 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
18092 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
18096 dirent = buf->dirent;
18097 if (!access_ok(VERIFY_WRITE, dirent,
18098 @@ -110,6 +117,7 @@ asmlinkage long old_readdir(unsigned int
18101 buf.dirent = dirent;
18104 error = vfs_readdir(file, fillonedir, &buf);
18106 @@ -136,6 +144,7 @@ struct linux_dirent {
18107 struct getdents_callback {
18108 struct linux_dirent __user * current_dir;
18109 struct linux_dirent __user * previous;
18110 + struct file * file;
18114 @@ -154,6 +163,10 @@ static int filldir(void * __buf, const c
18116 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
18119 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
18122 dirent = buf->previous;
18124 if (__put_user(offset, &dirent->d_off))
18125 @@ -200,6 +213,7 @@ asmlinkage long sys_getdents(unsigned in
18126 buf.previous = NULL;
18131 error = vfs_readdir(file, filldir, &buf);
18133 @@ -222,6 +236,7 @@ out:
18134 struct getdents_callback64 {
18135 struct linux_dirent64 __user * current_dir;
18136 struct linux_dirent64 __user * previous;
18137 + struct file *file;
18141 @@ -236,6 +251,10 @@ static int filldir64(void * __buf, const
18142 buf->error = -EINVAL; /* only used if we fail.. */
18143 if (reclen > buf->count)
18146 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
18149 dirent = buf->previous;
18151 if (__put_user(offset, &dirent->d_off))
18152 @@ -282,6 +301,7 @@ asmlinkage long sys_getdents64(unsigned
18154 buf.current_dir = dirent;
18155 buf.previous = NULL;
18160 diff -urNp linux-2.6.24.4/fs/smbfs/symlink.c linux-2.6.24.4/fs/smbfs/symlink.c
18161 --- linux-2.6.24.4/fs/smbfs/symlink.c 2008-03-24 14:49:18.000000000 -0400
18162 +++ linux-2.6.24.4/fs/smbfs/symlink.c 2008-03-26 20:21:08.000000000 -0400
18163 @@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
18165 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
18167 - char *s = nd_get_link(nd);
18168 + const char *s = nd_get_link(nd);
18172 diff -urNp linux-2.6.24.4/fs/sysfs/symlink.c linux-2.6.24.4/fs/sysfs/symlink.c
18173 --- linux-2.6.24.4/fs/sysfs/symlink.c 2008-03-24 14:49:18.000000000 -0400
18174 +++ linux-2.6.24.4/fs/sysfs/symlink.c 2008-03-26 20:21:08.000000000 -0400
18175 @@ -172,7 +172,7 @@ static void *sysfs_follow_link(struct de
18177 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
18179 - char *page = nd_get_link(nd);
18180 + const char *page = nd_get_link(nd);
18182 free_page((unsigned long)page);
18184 diff -urNp linux-2.6.24.4/fs/udf/balloc.c linux-2.6.24.4/fs/udf/balloc.c
18185 --- linux-2.6.24.4/fs/udf/balloc.c 2008-03-24 14:49:18.000000000 -0400
18186 +++ linux-2.6.24.4/fs/udf/balloc.c 2008-03-26 20:21:08.000000000 -0400
18187 @@ -154,8 +154,7 @@ static void udf_bitmap_free_blocks(struc
18188 unsigned long overflow;
18190 mutex_lock(&sbi->s_alloc_mutex);
18191 - if (bloc.logicalBlockNum < 0 ||
18192 - (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
18193 + if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
18194 udf_debug("%d < %d || %d + %d > %d\n",
18195 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
18196 UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
18197 @@ -221,7 +220,7 @@ static int udf_bitmap_prealloc_blocks(st
18198 struct buffer_head *bh;
18200 mutex_lock(&sbi->s_alloc_mutex);
18201 - if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
18202 + if (first_block >= UDF_SB_PARTLEN(sb, partition))
18205 if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
18206 @@ -287,7 +286,7 @@ static int udf_bitmap_new_block(struct s
18207 mutex_lock(&sbi->s_alloc_mutex);
18210 - if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
18211 + if (goal >= UDF_SB_PARTLEN(sb, partition))
18214 nr_groups = bitmap->s_nr_groups;
18215 @@ -420,8 +419,7 @@ static void udf_table_free_blocks(struct
18218 mutex_lock(&sbi->s_alloc_mutex);
18219 - if (bloc.logicalBlockNum < 0 ||
18220 - (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
18221 + if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
18222 udf_debug("%d < %d || %d + %d > %d\n",
18223 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
18224 UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
18225 @@ -627,7 +625,7 @@ static int udf_table_prealloc_blocks(str
18226 struct extent_position epos;
18229 - if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
18230 + if (first_block >= UDF_SB_PARTLEN(sb, partition))
18233 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
18234 @@ -703,7 +701,7 @@ static int udf_table_new_block(struct su
18237 mutex_lock(&sbi->s_alloc_mutex);
18238 - if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
18239 + if (goal >= UDF_SB_PARTLEN(sb, partition))
18242 /* We search for the closest matching block to goal. If we find a exact hit,
18243 diff -urNp linux-2.6.24.4/fs/udf/inode.c linux-2.6.24.4/fs/udf/inode.c
18244 --- linux-2.6.24.4/fs/udf/inode.c 2008-03-24 14:49:18.000000000 -0400
18245 +++ linux-2.6.24.4/fs/udf/inode.c 2008-03-26 20:21:08.000000000 -0400
18246 @@ -311,9 +311,6 @@ static int udf_get_block(struct inode *i
18251 - goto abort_negative;
18253 if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) {
18254 UDF_I_NEXT_ALLOC_BLOCK(inode)++;
18255 UDF_I_NEXT_ALLOC_GOAL(inode)++;
18256 @@ -334,10 +331,6 @@ static int udf_get_block(struct inode *i
18262 - udf_warning(inode->i_sb, "udf_get_block", "block < 0");
18266 static struct buffer_head *udf_getblk(struct inode *inode, long block,
18267 diff -urNp linux-2.6.24.4/fs/ufs/inode.c linux-2.6.24.4/fs/ufs/inode.c
18268 --- linux-2.6.24.4/fs/ufs/inode.c 2008-03-24 14:49:18.000000000 -0400
18269 +++ linux-2.6.24.4/fs/ufs/inode.c 2008-03-26 20:21:08.000000000 -0400
18270 @@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
18273 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
18274 - if (i_block < 0) {
18275 - ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
18276 - } else if (i_block < direct_blocks) {
18277 + if (i_block < direct_blocks) {
18278 offsets[n++] = i_block;
18279 } else if ((i_block -= direct_blocks) < indirect_blocks) {
18280 offsets[n++] = UFS_IND_BLOCK;
18281 @@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
18284 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
18285 - if (fragment < 0)
18286 - goto abort_negative;
18288 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
18289 << uspi->s_fpbshift))
18290 @@ -504,10 +500,6 @@ abort:
18295 - ufs_warning(sb, "ufs_get_block", "block < 0");
18299 ufs_warning(sb, "ufs_get_block", "block > big");
18301 diff -urNp linux-2.6.24.4/fs/utimes.c linux-2.6.24.4/fs/utimes.c
18302 --- linux-2.6.24.4/fs/utimes.c 2008-03-24 14:49:18.000000000 -0400
18303 +++ linux-2.6.24.4/fs/utimes.c 2008-03-26 20:21:08.000000000 -0400
18305 #include <linux/utime.h>
18306 #include <linux/mount.h>
18307 #include <linux/vs_cowbl.h>
18308 +#include <linux/grsecurity.h>
18309 #include <asm/uaccess.h>
18310 #include <asm/unistd.h>
18312 @@ -55,6 +56,7 @@ long do_utimes(int dfd, char __user *fil
18314 struct nameidata nd;
18315 struct dentry *dentry;
18316 + struct vfsmount *mnt;
18317 struct inode *inode;
18318 struct iattr newattrs;
18319 struct file *f = NULL;
18320 @@ -78,6 +80,7 @@ long do_utimes(int dfd, char __user *fil
18323 dentry = f->f_path.dentry;
18324 + mnt = f->f_path.mnt;
18326 error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
18328 @@ -86,6 +90,7 @@ long do_utimes(int dfd, char __user *fil
18331 dentry = nd.dentry;
18335 inode = dentry->d_inode;
18336 @@ -130,6 +134,12 @@ long do_utimes(int dfd, char __user *fil
18341 + if (!gr_acl_handle_utime(dentry, mnt)) {
18343 + goto dput_and_out;
18346 mutex_lock(&inode->i_mutex);
18347 error = notify_change(dentry, &newattrs);
18348 mutex_unlock(&inode->i_mutex);
18349 diff -urNp linux-2.6.24.4/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.24.4/fs/xfs/linux-2.6/xfs_iops.c
18350 --- linux-2.6.24.4/fs/xfs/linux-2.6/xfs_iops.c 2008-03-24 14:49:18.000000000 -0400
18351 +++ linux-2.6.24.4/fs/xfs/linux-2.6/xfs_iops.c 2008-03-26 20:21:09.000000000 -0400
18352 @@ -534,7 +534,7 @@ xfs_vn_put_link(
18353 struct nameidata *nd,
18356 - char *s = nd_get_link(nd);
18357 + const char *s = nd_get_link(nd);
18361 diff -urNp linux-2.6.24.4/fs/xfs/xfs_bmap.c linux-2.6.24.4/fs/xfs/xfs_bmap.c
18362 --- linux-2.6.24.4/fs/xfs/xfs_bmap.c 2008-03-24 14:49:18.000000000 -0400
18363 +++ linux-2.6.24.4/fs/xfs/xfs_bmap.c 2008-03-26 20:21:09.000000000 -0400
18364 @@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
18368 -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
18369 +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
18372 #if defined(XFS_RW_TRACE)
18373 diff -urNp linux-2.6.24.4/grsecurity/gracl_alloc.c linux-2.6.24.4/grsecurity/gracl_alloc.c
18374 --- linux-2.6.24.4/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
18375 +++ linux-2.6.24.4/grsecurity/gracl_alloc.c 2008-03-26 20:21:09.000000000 -0400
18377 +#include <linux/kernel.h>
18378 +#include <linux/mm.h>
18379 +#include <linux/slab.h>
18380 +#include <linux/vmalloc.h>
18381 +#include <linux/gracl.h>
18382 +#include <linux/grsecurity.h>
18384 +static unsigned long alloc_stack_next = 1;
18385 +static unsigned long alloc_stack_size = 1;
18386 +static void **alloc_stack;
18388 +static __inline__ int
18391 + if (alloc_stack_next == 1)
18394 + kfree(alloc_stack[alloc_stack_next - 2]);
18396 + alloc_stack_next--;
18401 +static __inline__ void
18402 +alloc_push(void *buf)
18404 + if (alloc_stack_next >= alloc_stack_size)
18407 + alloc_stack[alloc_stack_next - 1] = buf;
18409 + alloc_stack_next++;
18415 +acl_alloc(unsigned long len)
18419 + if (len > PAGE_SIZE)
18422 + ret = kmalloc(len, GFP_KERNEL);
18431 +acl_free_all(void)
18433 + if (gr_acl_is_enabled() || !alloc_stack)
18436 + while (alloc_pop()) ;
18438 + if (alloc_stack) {
18439 + if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
18440 + kfree(alloc_stack);
18442 + vfree(alloc_stack);
18445 + alloc_stack = NULL;
18446 + alloc_stack_size = 1;
18447 + alloc_stack_next = 1;
18453 +acl_alloc_stack_init(unsigned long size)
18455 + if ((size * sizeof (void *)) <= PAGE_SIZE)
18457 + (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
18459 + alloc_stack = (void **) vmalloc(size * sizeof (void *));
18461 + alloc_stack_size = size;
18463 + if (!alloc_stack)
18468 diff -urNp linux-2.6.24.4/grsecurity/gracl.c linux-2.6.24.4/grsecurity/gracl.c
18469 --- linux-2.6.24.4/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
18470 +++ linux-2.6.24.4/grsecurity/gracl.c 2008-03-26 20:21:09.000000000 -0400
18472 +#include <linux/kernel.h>
18473 +#include <linux/module.h>
18474 +#include <linux/sched.h>
18475 +#include <linux/mm.h>
18476 +#include <linux/file.h>
18477 +#include <linux/fs.h>
18478 +#include <linux/namei.h>
18479 +#include <linux/mount.h>
18480 +#include <linux/tty.h>
18481 +#include <linux/proc_fs.h>
18482 +#include <linux/smp_lock.h>
18483 +#include <linux/slab.h>
18484 +#include <linux/vmalloc.h>
18485 +#include <linux/types.h>
18486 +#include <linux/capability.h>
18487 +#include <linux/sysctl.h>
18488 +#include <linux/netdevice.h>
18489 +#include <linux/ptrace.h>
18490 +#include <linux/gracl.h>
18491 +#include <linux/gralloc.h>
18492 +#include <linux/grsecurity.h>
18493 +#include <linux/grinternal.h>
18494 +#include <linux/pid_namespace.h>
18495 +#include <linux/percpu.h>
18497 +#include <asm/uaccess.h>
18498 +#include <asm/errno.h>
18499 +#include <asm/mman.h>
18501 +static struct acl_role_db acl_role_set;
18502 +static struct name_db name_set;
18503 +static struct inodev_db inodev_set;
18505 +/* for keeping track of userspace pointers used for subjects, so we
18506 + can share references in the kernel as well
18509 +static struct dentry *real_root;
18510 +static struct vfsmount *real_root_mnt;
18512 +static struct acl_subj_map_db subj_map_set;
18514 +static struct acl_role_label *default_role;
18516 +static u16 acl_sp_role_value;
18518 +extern char *gr_shared_page[4];
18519 +static DECLARE_MUTEX(gr_dev_sem);
18520 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
18522 +struct gr_arg *gr_usermode;
18524 +static unsigned int gr_status = GR_STATUS_INIT;
18526 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
18527 +extern void gr_clear_learn_entries(void);
18529 +#ifdef CONFIG_GRKERNSEC_RESLOG
18530 +extern void gr_log_resource(const struct task_struct *task,
18531 + const int res, const unsigned long wanted, const int gt);
18534 +unsigned char *gr_system_salt;
18535 +unsigned char *gr_system_sum;
18537 +static struct sprole_pw **acl_special_roles = NULL;
18538 +static __u16 num_sprole_pws = 0;
18540 +static struct acl_role_label *kernel_role = NULL;
18542 +static unsigned int gr_auth_attempts = 0;
18543 +static unsigned long gr_auth_expires = 0UL;
18545 +extern struct vfsmount *sock_mnt;
18546 +extern struct vfsmount *pipe_mnt;
18547 +extern struct vfsmount *shm_mnt;
18548 +static struct acl_object_label *fakefs_obj;
18550 +extern int gr_init_uidset(void);
18551 +extern void gr_free_uidset(void);
18552 +extern void gr_remove_uid(uid_t uid);
18553 +extern int gr_find_uid(uid_t uid);
18556 +gr_acl_is_enabled(void)
18558 + return (gr_status & GR_READY);
18561 +char gr_roletype_to_char(void)
18563 + switch (current->role->roletype &
18564 + (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
18565 + GR_ROLE_SPECIAL)) {
18566 + case GR_ROLE_DEFAULT:
18568 + case GR_ROLE_USER:
18570 + case GR_ROLE_GROUP:
18572 + case GR_ROLE_SPECIAL:
18580 +gr_acl_tpe_check(void)
18582 + if (unlikely(!(gr_status & GR_READY)))
18584 + if (current->role->roletype & GR_ROLE_TPE)
18591 +gr_handle_rawio(const struct inode *inode)
18593 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
18594 + if (inode && S_ISBLK(inode->i_mode) &&
18595 + grsec_enable_chroot_caps && proc_is_chrooted(current) &&
18596 + !capable(CAP_SYS_RAWIO))
18603 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
18606 + unsigned long *l1;
18607 + unsigned long *l2;
18608 + unsigned char *c1;
18609 + unsigned char *c2;
18612 + if (likely(lena != lenb))
18615 + l1 = (unsigned long *)a;
18616 + l2 = (unsigned long *)b;
18618 + num_longs = lena / sizeof(unsigned long);
18620 + for (i = num_longs; i--; l1++, l2++) {
18621 + if (unlikely(*l1 != *l2))
18625 + c1 = (unsigned char *) l1;
18626 + c2 = (unsigned char *) l2;
18628 + i = lena - (num_longs * sizeof(unsigned long));
18630 + for (; i--; c1++, c2++) {
18631 + if (unlikely(*c1 != *c2))
18638 +static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
18639 + struct dentry *root, struct vfsmount *rootmnt,
18640 + char *buffer, int buflen)
18642 + char * end = buffer+buflen;
18651 + /* Get '/' right */
18656 + struct dentry * parent;
18658 + if (dentry == root && vfsmnt == rootmnt)
18660 + if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
18661 + /* Global root? */
18662 + spin_lock(&vfsmount_lock);
18663 + if (vfsmnt->mnt_parent == vfsmnt) {
18664 + spin_unlock(&vfsmount_lock);
18665 + goto global_root;
18667 + dentry = vfsmnt->mnt_mountpoint;
18668 + vfsmnt = vfsmnt->mnt_parent;
18669 + spin_unlock(&vfsmount_lock);
18672 + parent = dentry->d_parent;
18673 + prefetch(parent);
18674 + namelen = dentry->d_name.len;
18675 + buflen -= namelen + 1;
18679 + memcpy(end, dentry->d_name.name, namelen);
18688 + namelen = dentry->d_name.len;
18689 + buflen -= namelen;
18692 + retval -= namelen-1; /* hit the slash */
18693 + memcpy(retval, dentry->d_name.name, namelen);
18696 + return ERR_PTR(-ENAMETOOLONG);
18700 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
18701 + struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
18705 + retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
18706 + if (unlikely(IS_ERR(retval)))
18707 + retval = strcpy(buf, "<path too long>");
18708 + else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
18709 + retval[1] = '\0';
18715 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
18716 + char *buf, int buflen)
18720 + /* we can use real_root, real_root_mnt, because this is only called
18721 + by the RBAC system */
18722 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
18728 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
18729 + char *buf, int buflen)
18732 + struct dentry *root;
18733 + struct vfsmount *rootmnt;
18734 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
18736 + /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
18737 + read_lock(&reaper->fs->lock);
18738 + root = dget(reaper->fs->root);
18739 + rootmnt = mntget(reaper->fs->rootmnt);
18740 + read_unlock(&reaper->fs->lock);
18742 + spin_lock(&dcache_lock);
18743 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
18744 + spin_unlock(&dcache_lock);
18752 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
18755 + spin_lock(&dcache_lock);
18756 + ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
18758 + spin_unlock(&dcache_lock);
18763 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
18765 + return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
18770 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
18772 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
18777 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
18779 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
18784 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
18786 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
18791 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
18793 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
18798 +to_gr_audit(const __u32 reqmode)
18800 + /* masks off auditable permission flags, then shifts them to create
18801 + auditing flags, and adds the special case of append auditing if
18802 + we're requesting write */
18803 + return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
18806 +struct acl_subject_label *
18807 +lookup_subject_map(const struct acl_subject_label *userp)
18809 + unsigned int index = shash(userp, subj_map_set.s_size);
18810 + struct subject_map *match;
18812 + match = subj_map_set.s_hash[index];
18814 + while (match && match->user != userp)
18815 + match = match->next;
18817 + if (match != NULL)
18818 + return match->kernel;
18824 +insert_subj_map_entry(struct subject_map *subjmap)
18826 + unsigned int index = shash(subjmap->user, subj_map_set.s_size);
18827 + struct subject_map **curr;
18829 + subjmap->prev = NULL;
18831 + curr = &subj_map_set.s_hash[index];
18832 + if (*curr != NULL)
18833 + (*curr)->prev = subjmap;
18835 + subjmap->next = *curr;
18841 +static struct acl_role_label *
18842 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
18845 + unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
18846 + struct acl_role_label *match;
18847 + struct role_allowed_ip *ipp;
18850 + match = acl_role_set.r_hash[index];
18853 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
18854 + for (x = 0; x < match->domain_child_num; x++) {
18855 + if (match->domain_children[x] == uid)
18858 + } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
18860 + match = match->next;
18863 + if (match == NULL) {
18865 + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
18866 + match = acl_role_set.r_hash[index];
18869 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
18870 + for (x = 0; x < match->domain_child_num; x++) {
18871 + if (match->domain_children[x] == gid)
18874 + } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
18876 + match = match->next;
18879 + if (match == NULL)
18880 + match = default_role;
18881 + if (match->allowed_ips == NULL)
18884 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
18886 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
18887 + (ntohl(ipp->addr) & ipp->netmask)))
18890 + match = default_role;
18892 + } else if (match->allowed_ips == NULL) {
18895 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
18897 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
18898 + (ntohl(ipp->addr) & ipp->netmask)))
18907 +struct acl_subject_label *
18908 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
18909 + const struct acl_role_label *role)
18911 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
18912 + struct acl_subject_label *match;
18914 + match = role->subj_hash[index];
18916 + while (match && (match->inode != ino || match->device != dev ||
18917 + (match->mode & GR_DELETED))) {
18918 + match = match->next;
18921 + if (match && !(match->mode & GR_DELETED))
18927 +static struct acl_object_label *
18928 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
18929 + const struct acl_subject_label *subj)
18931 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
18932 + struct acl_object_label *match;
18934 + match = subj->obj_hash[index];
18936 + while (match && (match->inode != ino || match->device != dev ||
18937 + (match->mode & GR_DELETED))) {
18938 + match = match->next;
18941 + if (match && !(match->mode & GR_DELETED))
18947 +static struct acl_object_label *
18948 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
18949 + const struct acl_subject_label *subj)
18951 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
18952 + struct acl_object_label *match;
18954 + match = subj->obj_hash[index];
18956 + while (match && (match->inode != ino || match->device != dev ||
18957 + !(match->mode & GR_DELETED))) {
18958 + match = match->next;
18961 + if (match && (match->mode & GR_DELETED))
18964 + match = subj->obj_hash[index];
18966 + while (match && (match->inode != ino || match->device != dev ||
18967 + (match->mode & GR_DELETED))) {
18968 + match = match->next;
18971 + if (match && !(match->mode & GR_DELETED))
18977 +static struct name_entry *
18978 +lookup_name_entry(const char *name)
18980 + unsigned int len = strlen(name);
18981 + unsigned int key = full_name_hash(name, len);
18982 + unsigned int index = key % name_set.n_size;
18983 + struct name_entry *match;
18985 + match = name_set.n_hash[index];
18987 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
18988 + match = match->next;
18993 +static struct name_entry *
18994 +lookup_name_entry_create(const char *name)
18996 + unsigned int len = strlen(name);
18997 + unsigned int key = full_name_hash(name, len);
18998 + unsigned int index = key % name_set.n_size;
18999 + struct name_entry *match;
19001 + match = name_set.n_hash[index];
19003 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
19004 + !match->deleted))
19005 + match = match->next;
19007 + if (match && match->deleted)
19010 + match = name_set.n_hash[index];
19012 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
19014 + match = match->next;
19016 + if (match && !match->deleted)
19022 +static struct inodev_entry *
19023 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
19025 + unsigned int index = fhash(ino, dev, inodev_set.i_size);
19026 + struct inodev_entry *match;
19028 + match = inodev_set.i_hash[index];
19030 + while (match && (match->nentry->inode != ino || match->nentry->device != dev))
19031 + match = match->next;
19037 +insert_inodev_entry(struct inodev_entry *entry)
19039 + unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
19040 + inodev_set.i_size);
19041 + struct inodev_entry **curr;
19043 + entry->prev = NULL;
19045 + curr = &inodev_set.i_hash[index];
19046 + if (*curr != NULL)
19047 + (*curr)->prev = entry;
19049 + entry->next = *curr;
19056 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
19058 + unsigned int index =
19059 + rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
19060 + struct acl_role_label **curr;
19062 + role->prev = NULL;
19064 + curr = &acl_role_set.r_hash[index];
19065 + if (*curr != NULL)
19066 + (*curr)->prev = role;
19068 + role->next = *curr;
19075 +insert_acl_role_label(struct acl_role_label *role)
19079 + if (role->roletype & GR_ROLE_DOMAIN) {
19080 + for (i = 0; i < role->domain_child_num; i++)
19081 + __insert_acl_role_label(role, role->domain_children[i]);
19083 + __insert_acl_role_label(role, role->uidgid);
19087 +insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
19089 + struct name_entry **curr, *nentry;
19090 + struct inodev_entry *ientry;
19091 + unsigned int len = strlen(name);
19092 + unsigned int key = full_name_hash(name, len);
19093 + unsigned int index = key % name_set.n_size;
19095 + curr = &name_set.n_hash[index];
19097 + while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
19098 + curr = &((*curr)->next);
19100 + if (*curr != NULL)
19103 + nentry = acl_alloc(sizeof (struct name_entry));
19104 + if (nentry == NULL)
19106 + ientry = acl_alloc(sizeof (struct inodev_entry));
19107 + if (ientry == NULL)
19109 + ientry->nentry = nentry;
19111 + nentry->key = key;
19112 + nentry->name = name;
19113 + nentry->inode = inode;
19114 + nentry->device = device;
19115 + nentry->len = len;
19116 + nentry->deleted = deleted;
19118 + nentry->prev = NULL;
19119 + curr = &name_set.n_hash[index];
19120 + if (*curr != NULL)
19121 + (*curr)->prev = nentry;
19122 + nentry->next = *curr;
19125 + /* insert us into the table searchable by inode/dev */
19126 + insert_inodev_entry(ientry);
19132 +insert_acl_obj_label(struct acl_object_label *obj,
19133 + struct acl_subject_label *subj)
19135 + unsigned int index =
19136 + fhash(obj->inode, obj->device, subj->obj_hash_size);
19137 + struct acl_object_label **curr;
19140 + obj->prev = NULL;
19142 + curr = &subj->obj_hash[index];
19143 + if (*curr != NULL)
19144 + (*curr)->prev = obj;
19146 + obj->next = *curr;
19153 +insert_acl_subj_label(struct acl_subject_label *obj,
19154 + struct acl_role_label *role)
19156 + unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
19157 + struct acl_subject_label **curr;
19159 + obj->prev = NULL;
19161 + curr = &role->subj_hash[index];
19162 + if (*curr != NULL)
19163 + (*curr)->prev = obj;
19165 + obj->next = *curr;
19171 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
19174 +create_table(__u32 * len, int elementsize)
19176 + unsigned int table_sizes[] = {
19177 + 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
19178 + 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
19179 + 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
19180 + 268435399, 536870909, 1073741789, 2147483647
19182 + void *newtable = NULL;
19183 + unsigned int pwr = 0;
19185 + while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
19186 + table_sizes[pwr] <= *len)
19189 + if (table_sizes[pwr] <= *len)
19192 + if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
19194 + kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
19196 + newtable = vmalloc(table_sizes[pwr] * elementsize);
19198 + *len = table_sizes[pwr];
19204 +init_variables(const struct gr_arg *arg)
19206 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
19207 + unsigned int stacksize;
19209 + subj_map_set.s_size = arg->role_db.num_subjects;
19210 + acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
19211 + name_set.n_size = arg->role_db.num_objects;
19212 + inodev_set.i_size = arg->role_db.num_objects;
19214 + if (!subj_map_set.s_size || !acl_role_set.r_size ||
19215 + !name_set.n_size || !inodev_set.i_size)
19218 + if (!gr_init_uidset())
19221 + /* set up the stack that holds allocation info */
19223 + stacksize = arg->role_db.num_pointers + 5;
19225 + if (!acl_alloc_stack_init(stacksize))
19228 + /* grab reference for the real root dentry and vfsmount */
19229 + read_lock(&reaper->fs->lock);
19230 + real_root_mnt = mntget(reaper->fs->rootmnt);
19231 + real_root = dget(reaper->fs->root);
19232 + read_unlock(&reaper->fs->lock);
19234 + fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
19235 + if (fakefs_obj == NULL)
19237 + fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
19239 + subj_map_set.s_hash =
19240 + (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
19241 + acl_role_set.r_hash =
19242 + (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
19243 + name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
19244 + inodev_set.i_hash =
19245 + (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
19247 + if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
19248 + !name_set.n_hash || !inodev_set.i_hash)
19251 + memset(subj_map_set.s_hash, 0,
19252 + sizeof(struct subject_map *) * subj_map_set.s_size);
19253 + memset(acl_role_set.r_hash, 0,
19254 + sizeof (struct acl_role_label *) * acl_role_set.r_size);
19255 + memset(name_set.n_hash, 0,
19256 + sizeof (struct name_entry *) * name_set.n_size);
19257 + memset(inodev_set.i_hash, 0,
19258 + sizeof (struct inodev_entry *) * inodev_set.i_size);
19263 +/* free information not needed after startup
19264 + currently contains user->kernel pointer mappings for subjects
19268 +free_init_variables(void)
19272 + if (subj_map_set.s_hash) {
19273 + for (i = 0; i < subj_map_set.s_size; i++) {
19274 + if (subj_map_set.s_hash[i]) {
19275 + kfree(subj_map_set.s_hash[i]);
19276 + subj_map_set.s_hash[i] = NULL;
19280 + if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
19282 + kfree(subj_map_set.s_hash);
19284 + vfree(subj_map_set.s_hash);
19291 +free_variables(void)
19293 + struct acl_subject_label *s;
19294 + struct acl_role_label *r;
19295 + struct task_struct *task, *task2;
19296 + unsigned int i, x;
19298 + gr_clear_learn_entries();
19300 + read_lock(&tasklist_lock);
19301 + do_each_thread(task2, task) {
19302 + task->acl_sp_role = 0;
19303 + task->acl_role_id = 0;
19304 + task->acl = NULL;
19305 + task->role = NULL;
19306 + } while_each_thread(task2, task);
19307 + read_unlock(&tasklist_lock);
19309 + /* release the reference to the real root dentry and vfsmount */
19312 + real_root = NULL;
19313 + if (real_root_mnt)
19314 + mntput(real_root_mnt);
19315 + real_root_mnt = NULL;
19317 + /* free all object hash tables */
19319 + FOR_EACH_ROLE_START(r, i)
19320 + if (r->subj_hash == NULL)
19322 + FOR_EACH_SUBJECT_START(r, s, x)
19323 + if (s->obj_hash == NULL)
19325 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
19326 + kfree(s->obj_hash);
19328 + vfree(s->obj_hash);
19329 + FOR_EACH_SUBJECT_END(s, x)
19330 + FOR_EACH_NESTED_SUBJECT_START(r, s)
19331 + if (s->obj_hash == NULL)
19333 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
19334 + kfree(s->obj_hash);
19336 + vfree(s->obj_hash);
19337 + FOR_EACH_NESTED_SUBJECT_END(s)
19338 + if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
19339 + kfree(r->subj_hash);
19341 + vfree(r->subj_hash);
19342 + r->subj_hash = NULL;
19343 + FOR_EACH_ROLE_END(r,i)
19347 + if (acl_role_set.r_hash) {
19348 + if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
19350 + kfree(acl_role_set.r_hash);
19352 + vfree(acl_role_set.r_hash);
19354 + if (name_set.n_hash) {
19355 + if ((name_set.n_size * sizeof (struct name_entry *)) <=
19357 + kfree(name_set.n_hash);
19359 + vfree(name_set.n_hash);
19362 + if (inodev_set.i_hash) {
19363 + if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
19365 + kfree(inodev_set.i_hash);
19367 + vfree(inodev_set.i_hash);
19370 + gr_free_uidset();
19372 + memset(&name_set, 0, sizeof (struct name_db));
19373 + memset(&inodev_set, 0, sizeof (struct inodev_db));
19374 + memset(&acl_role_set, 0, sizeof (struct acl_role_db));
19375 + memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
19377 + default_role = NULL;
19383 +count_user_objs(struct acl_object_label *userp)
19385 + struct acl_object_label o_tmp;
19389 + if (copy_from_user(&o_tmp, userp,
19390 + sizeof (struct acl_object_label)))
19393 + userp = o_tmp.prev;
19400 +static struct acl_subject_label *
19401 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
19404 +copy_user_glob(struct acl_object_label *obj)
19406 + struct acl_object_label *g_tmp, **guser;
19407 + unsigned int len;
19410 + if (obj->globbed == NULL)
19413 + guser = &obj->globbed;
19415 + g_tmp = (struct acl_object_label *)
19416 + acl_alloc(sizeof (struct acl_object_label));
19417 + if (g_tmp == NULL)
19420 + if (copy_from_user(g_tmp, *guser,
19421 + sizeof (struct acl_object_label)))
19424 + len = strnlen_user(g_tmp->filename, PATH_MAX);
19426 + if (!len || len >= PATH_MAX)
19429 + if ((tmp = (char *) acl_alloc(len)) == NULL)
19432 + if (copy_from_user(tmp, g_tmp->filename, len))
19435 + g_tmp->filename = tmp;
19438 + guser = &(g_tmp->next);
19445 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
19446 + struct acl_role_label *role)
19448 + struct acl_object_label *o_tmp;
19449 + unsigned int len;
19454 + if ((o_tmp = (struct acl_object_label *)
19455 + acl_alloc(sizeof (struct acl_object_label))) == NULL)
19458 + if (copy_from_user(o_tmp, userp,
19459 + sizeof (struct acl_object_label)))
19462 + userp = o_tmp->prev;
19464 + len = strnlen_user(o_tmp->filename, PATH_MAX);
19466 + if (!len || len >= PATH_MAX)
19469 + if ((tmp = (char *) acl_alloc(len)) == NULL)
19472 + if (copy_from_user(tmp, o_tmp->filename, len))
19475 + o_tmp->filename = tmp;
19477 + insert_acl_obj_label(o_tmp, subj);
19478 + if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
19479 + o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
19482 + ret = copy_user_glob(o_tmp);
19486 + if (o_tmp->nested) {
19487 + o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
19488 + if (IS_ERR(o_tmp->nested))
19489 + return PTR_ERR(o_tmp->nested);
19491 + /* insert into nested subject list */
19492 + o_tmp->nested->next = role->hash->first;
19493 + role->hash->first = o_tmp->nested;
19501 +count_user_subjs(struct acl_subject_label *userp)
19503 + struct acl_subject_label s_tmp;
19507 + if (copy_from_user(&s_tmp, userp,
19508 + sizeof (struct acl_subject_label)))
19511 + userp = s_tmp.prev;
19512 + /* do not count nested subjects against this count, since
19513 + they are not included in the hash table, but are
19514 + attached to objects. We have already counted
19515 + the subjects in userspace for the allocation
19518 + if (!(s_tmp.mode & GR_NESTED))
19526 +copy_user_allowedips(struct acl_role_label *rolep)
19528 + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
19530 + ruserip = rolep->allowed_ips;
19532 + while (ruserip) {
19535 + if ((rtmp = (struct role_allowed_ip *)
19536 + acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
19539 + if (copy_from_user(rtmp, ruserip,
19540 + sizeof (struct role_allowed_ip)))
19543 + ruserip = rtmp->prev;
19546 + rtmp->prev = NULL;
19547 + rolep->allowed_ips = rtmp;
19549 + rlast->next = rtmp;
19550 + rtmp->prev = rlast;
19554 + rtmp->next = NULL;
19561 +copy_user_transitions(struct acl_role_label *rolep)
19563 + struct role_transition *rusertp, *rtmp = NULL, *rlast;
19565 + unsigned int len;
19568 + rusertp = rolep->transitions;
19570 + while (rusertp) {
19573 + if ((rtmp = (struct role_transition *)
19574 + acl_alloc(sizeof (struct role_transition))) == NULL)
19577 + if (copy_from_user(rtmp, rusertp,
19578 + sizeof (struct role_transition)))
19581 + rusertp = rtmp->prev;
19583 + len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
19585 + if (!len || len >= GR_SPROLE_LEN)
19588 + if ((tmp = (char *) acl_alloc(len)) == NULL)
19591 + if (copy_from_user(tmp, rtmp->rolename, len))
19594 + rtmp->rolename = tmp;
19597 + rtmp->prev = NULL;
19598 + rolep->transitions = rtmp;
19600 + rlast->next = rtmp;
19601 + rtmp->prev = rlast;
19605 + rtmp->next = NULL;
19611 +static struct acl_subject_label *
19612 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
19614 + struct acl_subject_label *s_tmp = NULL, *s_tmp2;
19615 + unsigned int len;
19618 + struct acl_ip_label **i_tmp, *i_utmp2;
19619 + struct gr_hash_struct ghash;
19620 + struct subject_map *subjmap;
19621 + unsigned int i_num;
19624 + s_tmp = lookup_subject_map(userp);
19626 + /* we've already copied this subject into the kernel, just return
19627 + the reference to it, and don't copy it over again
19632 + if ((s_tmp = (struct acl_subject_label *)
19633 + acl_alloc(sizeof (struct acl_subject_label))) == NULL)
19634 + return ERR_PTR(-ENOMEM);
19636 + subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
19637 + if (subjmap == NULL)
19638 + return ERR_PTR(-ENOMEM);
19640 + subjmap->user = userp;
19641 + subjmap->kernel = s_tmp;
19642 + insert_subj_map_entry(subjmap);
19644 + if (copy_from_user(s_tmp, userp,
19645 + sizeof (struct acl_subject_label)))
19646 + return ERR_PTR(-EFAULT);
19648 + len = strnlen_user(s_tmp->filename, PATH_MAX);
19650 + if (!len || len >= PATH_MAX)
19651 + return ERR_PTR(-EINVAL);
19653 + if ((tmp = (char *) acl_alloc(len)) == NULL)
19654 + return ERR_PTR(-ENOMEM);
19656 + if (copy_from_user(tmp, s_tmp->filename, len))
19657 + return ERR_PTR(-EFAULT);
19659 + s_tmp->filename = tmp;
19661 + if (!strcmp(s_tmp->filename, "/"))
19662 + role->root_label = s_tmp;
19664 + if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
19665 + return ERR_PTR(-EFAULT);
19667 + /* copy user and group transition tables */
19669 + if (s_tmp->user_trans_num) {
19672 + uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
19673 + if (uidlist == NULL)
19674 + return ERR_PTR(-ENOMEM);
19675 + if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
19676 + return ERR_PTR(-EFAULT);
19678 + s_tmp->user_transitions = uidlist;
19681 + if (s_tmp->group_trans_num) {
19684 + gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
19685 + if (gidlist == NULL)
19686 + return ERR_PTR(-ENOMEM);
19687 + if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
19688 + return ERR_PTR(-EFAULT);
19690 + s_tmp->group_transitions = gidlist;
19693 + /* set up object hash table */
19694 + num_objs = count_user_objs(ghash.first);
19696 + s_tmp->obj_hash_size = num_objs;
19697 + s_tmp->obj_hash =
19698 + (struct acl_object_label **)
19699 + create_table(&(s_tmp->obj_hash_size), sizeof(void *));
19701 + if (!s_tmp->obj_hash)
19702 + return ERR_PTR(-ENOMEM);
19704 + memset(s_tmp->obj_hash, 0,
19705 + s_tmp->obj_hash_size *
19706 + sizeof (struct acl_object_label *));
19708 + /* add in objects */
19709 + err = copy_user_objs(ghash.first, s_tmp, role);
19712 + return ERR_PTR(err);
19714 + /* set pointer for parent subject */
19715 + if (s_tmp->parent_subject) {
19716 + s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
19718 + if (IS_ERR(s_tmp2))
19721 + s_tmp->parent_subject = s_tmp2;
19724 + /* add in ip acls */
19726 + if (!s_tmp->ip_num) {
19727 + s_tmp->ips = NULL;
19732 + (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
19734 + acl_ip_label *));
19737 + return ERR_PTR(-ENOMEM);
19739 + for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
19740 + *(i_tmp + i_num) =
19741 + (struct acl_ip_label *)
19742 + acl_alloc(sizeof (struct acl_ip_label));
19743 + if (!*(i_tmp + i_num))
19744 + return ERR_PTR(-ENOMEM);
19746 + if (copy_from_user
19747 + (&i_utmp2, s_tmp->ips + i_num,
19748 + sizeof (struct acl_ip_label *)))
19749 + return ERR_PTR(-EFAULT);
19751 + if (copy_from_user
19752 + (*(i_tmp + i_num), i_utmp2,
19753 + sizeof (struct acl_ip_label)))
19754 + return ERR_PTR(-EFAULT);
19756 + if ((*(i_tmp + i_num))->iface == NULL)
19759 + len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
19760 + if (!len || len >= IFNAMSIZ)
19761 + return ERR_PTR(-EINVAL);
19762 + tmp = acl_alloc(len);
19764 + return ERR_PTR(-ENOMEM);
19765 + if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
19766 + return ERR_PTR(-EFAULT);
19767 + (*(i_tmp + i_num))->iface = tmp;
19770 + s_tmp->ips = i_tmp;
19773 + if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
19774 + s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
19775 + return ERR_PTR(-ENOMEM);
19781 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
19783 + struct acl_subject_label s_pre;
19784 + struct acl_subject_label * ret;
19788 + if (copy_from_user(&s_pre, userp,
19789 + sizeof (struct acl_subject_label)))
19792 + /* do not add nested subjects here, add
19793 + while parsing objects
19796 + if (s_pre.mode & GR_NESTED) {
19797 + userp = s_pre.prev;
19801 + ret = do_copy_user_subj(userp, role);
19803 + err = PTR_ERR(ret);
19807 + insert_acl_subj_label(ret, role);
19809 + userp = s_pre.prev;
19816 +copy_user_acl(struct gr_arg *arg)
19818 + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
19819 + struct sprole_pw *sptmp;
19820 + struct gr_hash_struct *ghash;
19821 + uid_t *domainlist;
19822 + unsigned int r_num;
19823 + unsigned int len;
19829 + /* we need a default and kernel role */
19830 + if (arg->role_db.num_roles < 2)
19833 + /* copy special role authentication info from userspace */
19835 + num_sprole_pws = arg->num_sprole_pws;
19836 + acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
19838 + if (!acl_special_roles) {
19843 + for (i = 0; i < num_sprole_pws; i++) {
19844 + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
19849 + if (copy_from_user(sptmp, arg->sprole_pws + i,
19850 + sizeof (struct sprole_pw))) {
19856 + strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
19858 + if (!len || len >= GR_SPROLE_LEN) {
19863 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
19868 + if (copy_from_user(tmp, sptmp->rolename, len)) {
19873 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19874 + printk(KERN_ALERT "Copying special role %s\n", tmp);
19876 + sptmp->rolename = tmp;
19877 + acl_special_roles[i] = sptmp;
19880 + r_utmp = (struct acl_role_label **) arg->role_db.r_table;
19882 + for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
19883 + r_tmp = acl_alloc(sizeof (struct acl_role_label));
19890 + if (copy_from_user(&r_utmp2, r_utmp + r_num,
19891 + sizeof (struct acl_role_label *))) {
19896 + if (copy_from_user(r_tmp, r_utmp2,
19897 + sizeof (struct acl_role_label))) {
19902 + len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
19904 + if (!len || len >= PATH_MAX) {
19909 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
19913 + if (copy_from_user(tmp, r_tmp->rolename, len)) {
19917 + r_tmp->rolename = tmp;
19919 + if (!strcmp(r_tmp->rolename, "default")
19920 + && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
19921 + default_role = r_tmp;
19922 + } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
19923 + kernel_role = r_tmp;
19926 + if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
19930 + if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
19935 + r_tmp->hash = ghash;
19937 + num_subjs = count_user_subjs(r_tmp->hash->first);
19939 + r_tmp->subj_hash_size = num_subjs;
19940 + r_tmp->subj_hash =
19941 + (struct acl_subject_label **)
19942 + create_table(&(r_tmp->subj_hash_size), sizeof(void *));
19944 + if (!r_tmp->subj_hash) {
19949 + err = copy_user_allowedips(r_tmp);
19953 + /* copy domain info */
19954 + if (r_tmp->domain_children != NULL) {
19955 + domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
19956 + if (domainlist == NULL) {
19960 + if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
19964 + r_tmp->domain_children = domainlist;
19967 + err = copy_user_transitions(r_tmp);
19971 + memset(r_tmp->subj_hash, 0,
19972 + r_tmp->subj_hash_size *
19973 + sizeof (struct acl_subject_label *));
19975 + err = copy_user_subjs(r_tmp->hash->first, r_tmp);
19980 + /* set nested subject list to null */
19981 + r_tmp->hash->first = NULL;
19983 + insert_acl_role_label(r_tmp);
19988 + free_variables();
19995 +gracl_init(struct gr_arg *args)
19999 + memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
20000 + memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
20002 + if (init_variables(args)) {
20003 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
20005 + free_variables();
20009 + error = copy_user_acl(args);
20010 + free_init_variables();
20012 + free_variables();
20016 + if ((error = gr_set_acls(0))) {
20017 + free_variables();
20021 + gr_status |= GR_READY;
20026 +/* derived from glibc fnmatch() 0: match, 1: no match*/
20029 +glob_match(const char *p, const char *n)
20033 + while ((c = *p++) != '\0') {
20038 + else if (*n == '/')
20046 + for (c = *p++; c == '?' || c == '*'; c = *p++) {
20049 + else if (c == '?') {
20059 + const char *endp;
20061 + if ((endp = strchr(n, '/')) == NULL)
20062 + endp = n + strlen(n);
20065 + for (--p; n < endp; ++n)
20066 + if (!glob_match(p, n))
20068 + } else if (c == '/') {
20069 + while (*n != '\0' && *n != '/')
20071 + if (*n == '/' && !glob_match(p, n + 1))
20074 + for (--p; n < endp; ++n)
20075 + if (*n == c && !glob_match(p, n))
20086 + if (*n == '\0' || *n == '/')
20089 + not = (*p == '!' || *p == '^');
20095 + unsigned char fn = (unsigned char)*n;
20105 + if (c == '-' && *p != ']') {
20106 + unsigned char cend = *p++;
20108 + if (cend == '\0')
20111 + if (cold <= fn && fn <= cend)
20125 + while (c != ']') {
20152 +static struct acl_object_label *
20153 +chk_glob_label(struct acl_object_label *globbed,
20154 + struct dentry *dentry, struct vfsmount *mnt, char **path)
20156 + struct acl_object_label *tmp;
20158 + if (*path == NULL)
20159 + *path = gr_to_filename_nolock(dentry, mnt);
20164 + if (!glob_match(tmp->filename, *path))
20172 +static struct acl_object_label *
20173 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
20174 + const ino_t curr_ino, const dev_t curr_dev,
20175 + const struct acl_subject_label *subj, char **path)
20177 + struct acl_subject_label *tmpsubj;
20178 + struct acl_object_label *retval;
20179 + struct acl_object_label *retval2;
20181 + tmpsubj = (struct acl_subject_label *) subj;
20182 + read_lock(&gr_inode_lock);
20184 + retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
20186 + if (retval->globbed) {
20187 + retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
20188 + (struct vfsmount *)orig_mnt, path);
20190 + retval = retval2;
20194 + } while ((tmpsubj = tmpsubj->parent_subject));
20195 + read_unlock(&gr_inode_lock);
20200 +static __inline__ struct acl_object_label *
20201 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
20202 + const struct dentry *curr_dentry,
20203 + const struct acl_subject_label *subj, char **path)
20205 + return __full_lookup(orig_dentry, orig_mnt,
20206 + curr_dentry->d_inode->i_ino,
20207 + curr_dentry->d_inode->i_sb->s_dev, subj, path);
20210 +static struct acl_object_label *
20211 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
20212 + const struct acl_subject_label *subj, char *path)
20214 + struct dentry *dentry = (struct dentry *) l_dentry;
20215 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
20216 + struct acl_object_label *retval;
20218 + spin_lock(&dcache_lock);
20220 + if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
20221 + /* ignore Eric Biederman */
20222 + IS_PRIVATE(l_dentry->d_inode))) {
20223 + retval = fakefs_obj;
20228 + if (dentry == real_root && mnt == real_root_mnt)
20231 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
20232 + if (mnt->mnt_parent == mnt)
20235 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
20236 + if (retval != NULL)
20239 + dentry = mnt->mnt_mountpoint;
20240 + mnt = mnt->mnt_parent;
20244 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
20245 + if (retval != NULL)
20248 + dentry = dentry->d_parent;
20251 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
20253 + if (retval == NULL)
20254 + retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
20256 + spin_unlock(&dcache_lock);
20260 +static __inline__ struct acl_object_label *
20261 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
20262 + const struct acl_subject_label *subj)
20264 + char *path = NULL;
20265 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
20268 +static __inline__ struct acl_object_label *
20269 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
20270 + const struct acl_subject_label *subj, char *path)
20272 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
20275 +static struct acl_subject_label *
20276 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
20277 + const struct acl_role_label *role)
20279 + struct dentry *dentry = (struct dentry *) l_dentry;
20280 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
20281 + struct acl_subject_label *retval;
20283 + spin_lock(&dcache_lock);
20286 + if (dentry == real_root && mnt == real_root_mnt)
20288 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
20289 + if (mnt->mnt_parent == mnt)
20292 + read_lock(&gr_inode_lock);
20294 + lookup_acl_subj_label(dentry->d_inode->i_ino,
20295 + dentry->d_inode->i_sb->s_dev, role);
20296 + read_unlock(&gr_inode_lock);
20297 + if (retval != NULL)
20300 + dentry = mnt->mnt_mountpoint;
20301 + mnt = mnt->mnt_parent;
20305 + read_lock(&gr_inode_lock);
20306 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
20307 + dentry->d_inode->i_sb->s_dev, role);
20308 + read_unlock(&gr_inode_lock);
20309 + if (retval != NULL)
20312 + dentry = dentry->d_parent;
20315 + read_lock(&gr_inode_lock);
20316 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
20317 + dentry->d_inode->i_sb->s_dev, role);
20318 + read_unlock(&gr_inode_lock);
20320 + if (unlikely(retval == NULL)) {
20321 + read_lock(&gr_inode_lock);
20322 + retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
20323 + real_root->d_inode->i_sb->s_dev, role);
20324 + read_unlock(&gr_inode_lock);
20327 + spin_unlock(&dcache_lock);
20333 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
20335 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
20336 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
20337 + task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
20338 + 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
20344 +gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
20346 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
20347 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
20348 + task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
20349 + 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
20355 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
20356 + const unsigned int effective, const unsigned int fs)
20358 + security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
20359 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
20360 + task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
20361 + type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
20367 +gr_check_link(const struct dentry * new_dentry,
20368 + const struct dentry * parent_dentry,
20369 + const struct vfsmount * parent_mnt,
20370 + const struct dentry * old_dentry, const struct vfsmount * old_mnt)
20372 + struct acl_object_label *obj;
20373 + __u32 oldmode, newmode;
20376 + if (unlikely(!(gr_status & GR_READY)))
20377 + return (GR_CREATE | GR_LINK);
20379 + obj = chk_obj_label(old_dentry, old_mnt, current->acl);
20380 + oldmode = obj->mode;
20382 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
20383 + oldmode |= (GR_CREATE | GR_LINK);
20385 + needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
20386 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
20387 + needmode |= GR_SETID | GR_AUDIT_SETID;
20390 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
20391 + oldmode | needmode);
20393 + needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
20394 + GR_SETID | GR_READ | GR_FIND | GR_DELETE |
20395 + GR_INHERIT | GR_AUDIT_INHERIT);
20397 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
20400 + if ((oldmode & needmode) != needmode)
20403 + needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
20404 + if ((newmode & needmode) != needmode)
20407 + if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
20410 + needmode = oldmode;
20411 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
20412 + needmode |= GR_SETID;
20414 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
20415 + gr_log_learn(current, old_dentry, old_mnt, needmode);
20416 + return (GR_CREATE | GR_LINK);
20417 + } else if (newmode & GR_SUPPRESS)
20418 + return GR_SUPPRESS;
20424 +gr_search_file(const struct dentry * dentry, const __u32 mode,
20425 + const struct vfsmount * mnt)
20427 + __u32 retval = mode;
20428 + struct acl_subject_label *curracl;
20429 + struct acl_object_label *currobj;
20431 + if (unlikely(!(gr_status & GR_READY)))
20432 + return (mode & ~GR_AUDITS);
20434 + curracl = current->acl;
20436 + currobj = chk_obj_label(dentry, mnt, curracl);
20437 + retval = currobj->mode & mode;
20440 + ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
20441 + && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
20442 + __u32 new_mode = mode;
20444 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
20446 + retval = new_mode;
20448 + if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
20449 + new_mode |= GR_INHERIT;
20451 + if (!(mode & GR_NOLEARN))
20452 + gr_log_learn(current, dentry, mnt, new_mode);
20459 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
20460 + const struct vfsmount * mnt, const __u32 mode)
20462 + struct name_entry *match;
20463 + struct acl_object_label *matchpo;
20464 + struct acl_subject_label *curracl;
20468 + if (unlikely(!(gr_status & GR_READY)))
20469 + return (mode & ~GR_AUDITS);
20471 + preempt_disable();
20472 + path = gr_to_filename_rbac(new_dentry, mnt);
20473 + match = lookup_name_entry_create(path);
20476 + goto check_parent;
20478 + curracl = current->acl;
20480 + read_lock(&gr_inode_lock);
20481 + matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
20482 + read_unlock(&gr_inode_lock);
20485 + if ((matchpo->mode & mode) !=
20486 + (mode & ~(GR_AUDITS | GR_SUPPRESS))
20487 + && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
20488 + __u32 new_mode = mode;
20490 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
20492 + gr_log_learn(current, new_dentry, mnt, new_mode);
20494 + preempt_enable();
20497 + preempt_enable();
20498 + return (matchpo->mode & mode);
20502 + curracl = current->acl;
20504 + matchpo = chk_obj_create_label(parent, mnt, curracl, path);
20505 + retval = matchpo->mode & mode;
20507 + if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
20508 + && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
20509 + __u32 new_mode = mode;
20511 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
20513 + gr_log_learn(current, new_dentry, mnt, new_mode);
20514 + preempt_enable();
20518 + preempt_enable();
20523 +gr_check_hidden_task(const struct task_struct *task)
20525 + if (unlikely(!(gr_status & GR_READY)))
20528 + if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
20535 +gr_check_protected_task(const struct task_struct *task)
20537 + if (unlikely(!(gr_status & GR_READY) || !task))
20540 + if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
20541 + task->acl != current->acl)
20548 +gr_copy_label(struct task_struct *tsk)
20550 + tsk->signal->used_accept = 0;
20551 + tsk->acl_sp_role = 0;
20552 + tsk->acl_role_id = current->acl_role_id;
20553 + tsk->acl = current->acl;
20554 + tsk->role = current->role;
20555 + tsk->signal->curr_ip = current->signal->curr_ip;
20556 + if (current->exec_file)
20557 + get_file(current->exec_file);
20558 + tsk->exec_file = current->exec_file;
20559 + tsk->is_writable = current->is_writable;
20560 + if (unlikely(current->signal->used_accept))
20561 + current->signal->curr_ip = 0;
20567 +gr_set_proc_res(struct task_struct *task)
20569 + struct acl_subject_label *proc;
20570 + unsigned short i;
20572 + proc = task->acl;
20574 + if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
20577 + for (i = 0; i < (GR_NLIMITS - 1); i++) {
20578 + if (!(proc->resmask & (1 << i)))
20581 + task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
20582 + task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
20589 +gr_check_user_change(int real, int effective, int fs)
20596 + int effectiveok = 0;
20599 + if (unlikely(!(gr_status & GR_READY)))
20602 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
20603 + gr_log_learn_id_change(current, 'u', real, effective, fs);
20605 + num = current->acl->user_trans_num;
20606 + uidlist = current->acl->user_transitions;
20608 + if (uidlist == NULL)
20613 + if (effective == -1)
20618 + if (current->acl->user_trans_type & GR_ID_ALLOW) {
20619 + for (i = 0; i < num; i++) {
20620 + curuid = (int)uidlist[i];
20621 + if (real == curuid)
20623 + if (effective == curuid)
20625 + if (fs == curuid)
20628 + } else if (current->acl->user_trans_type & GR_ID_DENY) {
20629 + for (i = 0; i < num; i++) {
20630 + curuid = (int)uidlist[i];
20631 + if (real == curuid)
20633 + if (effective == curuid)
20635 + if (fs == curuid)
20638 + /* not in deny list */
20646 + if (realok && effectiveok && fsok)
20649 + gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
20655 +gr_check_group_change(int real, int effective, int fs)
20662 + int effectiveok = 0;
20665 + if (unlikely(!(gr_status & GR_READY)))
20668 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
20669 + gr_log_learn_id_change(current, 'g', real, effective, fs);
20671 + num = current->acl->group_trans_num;
20672 + gidlist = current->acl->group_transitions;
20674 + if (gidlist == NULL)
20679 + if (effective == -1)
20684 + if (current->acl->group_trans_type & GR_ID_ALLOW) {
20685 + for (i = 0; i < num; i++) {
20686 + curgid = (int)gidlist[i];
20687 + if (real == curgid)
20689 + if (effective == curgid)
20691 + if (fs == curgid)
20694 + } else if (current->acl->group_trans_type & GR_ID_DENY) {
20695 + for (i = 0; i < num; i++) {
20696 + curgid = (int)gidlist[i];
20697 + if (real == curgid)
20699 + if (effective == curgid)
20701 + if (fs == curgid)
20704 + /* not in deny list */
20712 + if (realok && effectiveok && fsok)
20715 + gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
20721 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
20723 + struct acl_role_label *role = task->role;
20724 + struct acl_subject_label *subj = NULL;
20725 + struct acl_object_label *obj;
20726 + struct file *filp;
20728 + if (unlikely(!(gr_status & GR_READY)))
20731 + filp = task->exec_file;
20733 + /* kernel process, we'll give them the kernel role */
20734 + if (unlikely(!filp)) {
20735 + task->role = kernel_role;
20736 + task->acl = kernel_role->root_label;
20738 + } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
20739 + role = lookup_acl_role_label(task, uid, gid);
20741 + /* perform subject lookup in possibly new role
20742 + we can use this result below in the case where role == task->role
20744 + subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
20746 + /* if we changed uid/gid, but result in the same role
20747 + and are using inheritance, don't lose the inherited subject
20748 + if current subject is other than what normal lookup
20749 + would result in, we arrived via inheritance, don't
20752 + if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
20753 + (subj == task->acl)))
20754 + task->acl = subj;
20756 + task->role = role;
20758 + task->is_writable = 0;
20760 + /* ignore additional mmap checks for processes that are writable
20761 + by the default ACL */
20762 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
20763 + if (unlikely(obj->mode & GR_WRITE))
20764 + task->is_writable = 1;
20765 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
20766 + if (unlikely(obj->mode & GR_WRITE))
20767 + task->is_writable = 1;
20769 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20770 + printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
20773 + gr_set_proc_res(task);
20779 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
20781 + struct task_struct *task = current;
20782 + struct acl_subject_label *newacl;
20783 + struct acl_object_label *obj;
20786 + if (unlikely(!(gr_status & GR_READY)))
20789 + newacl = chk_subj_label(dentry, mnt, task->role);
20792 + if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
20793 + GR_POVERRIDE) && (task->acl != newacl) &&
20794 + !(task->role->roletype & GR_ROLE_GOD) &&
20795 + !gr_search_file(dentry, GR_PTRACERD, mnt) &&
20796 + !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
20797 + (atomic_read(&task->fs->count) > 1 ||
20798 + atomic_read(&task->files->count) > 1 ||
20799 + atomic_read(&task->sighand->count) > 1)) {
20800 + task_unlock(task);
20801 + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
20804 + task_unlock(task);
20806 + obj = chk_obj_label(dentry, mnt, task->acl);
20807 + retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
20809 + if (!(task->acl->mode & GR_INHERITLEARN) &&
20810 + ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
20812 + task->acl = obj->nested;
20814 + task->acl = newacl;
20815 + } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
20816 + gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
20818 + task->is_writable = 0;
20820 + /* ignore additional mmap checks for processes that are writable
20821 + by the default ACL */
20822 + obj = chk_obj_label(dentry, mnt, default_role->root_label);
20823 + if (unlikely(obj->mode & GR_WRITE))
20824 + task->is_writable = 1;
20825 + obj = chk_obj_label(dentry, mnt, task->role->root_label);
20826 + if (unlikely(obj->mode & GR_WRITE))
20827 + task->is_writable = 1;
20829 + gr_set_proc_res(task);
20831 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20832 + printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
20837 +/* always called with valid inodev ptr */
20839 +do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
20841 + struct acl_object_label *matchpo;
20842 + struct acl_subject_label *matchps;
20843 + struct acl_subject_label *subj;
20844 + struct acl_role_label *role;
20845 + unsigned int i, x;
20847 + FOR_EACH_ROLE_START(role, i)
20848 + FOR_EACH_SUBJECT_START(role, subj, x)
20849 + if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
20850 + matchpo->mode |= GR_DELETED;
20851 + FOR_EACH_SUBJECT_END(subj,x)
20852 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
20853 + if (subj->inode == ino && subj->device == dev)
20854 + subj->mode |= GR_DELETED;
20855 + FOR_EACH_NESTED_SUBJECT_END(subj)
20856 + if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
20857 + matchps->mode |= GR_DELETED;
20858 + FOR_EACH_ROLE_END(role,i)
20860 + inodev->nentry->deleted = 1;
20866 +gr_handle_delete(const ino_t ino, const dev_t dev)
20868 + struct inodev_entry *inodev;
20870 + if (unlikely(!(gr_status & GR_READY)))
20873 + write_lock(&gr_inode_lock);
20874 + inodev = lookup_inodev_entry(ino, dev);
20875 + if (inodev != NULL)
20876 + do_handle_delete(inodev, ino, dev);
20877 + write_unlock(&gr_inode_lock);
20883 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
20884 + const ino_t newinode, const dev_t newdevice,
20885 + struct acl_subject_label *subj)
20887 + unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
20888 + struct acl_object_label *match;
20890 + match = subj->obj_hash[index];
20892 + while (match && (match->inode != oldinode ||
20893 + match->device != olddevice ||
20894 + !(match->mode & GR_DELETED)))
20895 + match = match->next;
20897 + if (match && (match->inode == oldinode)
20898 + && (match->device == olddevice)
20899 + && (match->mode & GR_DELETED)) {
20900 + if (match->prev == NULL) {
20901 + subj->obj_hash[index] = match->next;
20902 + if (match->next != NULL)
20903 + match->next->prev = NULL;
20905 + match->prev->next = match->next;
20906 + if (match->next != NULL)
20907 + match->next->prev = match->prev;
20909 + match->prev = NULL;
20910 + match->next = NULL;
20911 + match->inode = newinode;
20912 + match->device = newdevice;
20913 + match->mode &= ~GR_DELETED;
20915 + insert_acl_obj_label(match, subj);
20922 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
20923 + const ino_t newinode, const dev_t newdevice,
20924 + struct acl_role_label *role)
20926 + unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
20927 + struct acl_subject_label *match;
20929 + match = role->subj_hash[index];
20931 + while (match && (match->inode != oldinode ||
20932 + match->device != olddevice ||
20933 + !(match->mode & GR_DELETED)))
20934 + match = match->next;
20936 + if (match && (match->inode == oldinode)
20937 + && (match->device == olddevice)
20938 + && (match->mode & GR_DELETED)) {
20939 + if (match->prev == NULL) {
20940 + role->subj_hash[index] = match->next;
20941 + if (match->next != NULL)
20942 + match->next->prev = NULL;
20944 + match->prev->next = match->next;
20945 + if (match->next != NULL)
20946 + match->next->prev = match->prev;
20948 + match->prev = NULL;
20949 + match->next = NULL;
20950 + match->inode = newinode;
20951 + match->device = newdevice;
20952 + match->mode &= ~GR_DELETED;
20954 + insert_acl_subj_label(match, role);
20961 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
20962 + const ino_t newinode, const dev_t newdevice)
20964 + unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
20965 + struct inodev_entry *match;
20967 + match = inodev_set.i_hash[index];
20969 + while (match && (match->nentry->inode != oldinode ||
20970 + match->nentry->device != olddevice || !match->nentry->deleted))
20971 + match = match->next;
20973 + if (match && (match->nentry->inode == oldinode)
20974 + && (match->nentry->device == olddevice) &&
20975 + match->nentry->deleted) {
20976 + if (match->prev == NULL) {
20977 + inodev_set.i_hash[index] = match->next;
20978 + if (match->next != NULL)
20979 + match->next->prev = NULL;
20981 + match->prev->next = match->next;
20982 + if (match->next != NULL)
20983 + match->next->prev = match->prev;
20985 + match->prev = NULL;
20986 + match->next = NULL;
20987 + match->nentry->inode = newinode;
20988 + match->nentry->device = newdevice;
20989 + match->nentry->deleted = 0;
20991 + insert_inodev_entry(match);
20998 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
20999 + const struct vfsmount *mnt)
21001 + struct acl_subject_label *subj;
21002 + struct acl_role_label *role;
21003 + unsigned int i, x;
21005 + FOR_EACH_ROLE_START(role, i)
21006 + update_acl_subj_label(matchn->inode, matchn->device,
21007 + dentry->d_inode->i_ino,
21008 + dentry->d_inode->i_sb->s_dev, role);
21010 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
21011 + if ((subj->inode == dentry->d_inode->i_ino) &&
21012 + (subj->device == dentry->d_inode->i_sb->s_dev)) {
21013 + subj->inode = dentry->d_inode->i_ino;
21014 + subj->device = dentry->d_inode->i_sb->s_dev;
21016 + FOR_EACH_NESTED_SUBJECT_END(subj)
21017 + FOR_EACH_SUBJECT_START(role, subj, x)
21018 + update_acl_obj_label(matchn->inode, matchn->device,
21019 + dentry->d_inode->i_ino,
21020 + dentry->d_inode->i_sb->s_dev, subj);
21021 + FOR_EACH_SUBJECT_END(subj,x)
21022 + FOR_EACH_ROLE_END(role,i)
21024 + update_inodev_entry(matchn->inode, matchn->device,
21025 + dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
21031 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
21033 + struct name_entry *matchn;
21035 + if (unlikely(!(gr_status & GR_READY)))
21038 + preempt_disable();
21039 + matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
21041 + if (unlikely((unsigned long)matchn)) {
21042 + write_lock(&gr_inode_lock);
21043 + do_handle_create(matchn, dentry, mnt);
21044 + write_unlock(&gr_inode_lock);
21046 + preempt_enable();
21052 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
21053 + struct dentry *old_dentry,
21054 + struct dentry *new_dentry,
21055 + struct vfsmount *mnt, const __u8 replace)
21057 + struct name_entry *matchn;
21058 + struct inodev_entry *inodev;
21060 + /* vfs_rename swaps the name and parent link for old_dentry and
21062 + at this point, old_dentry has the new name, parent link, and inode
21063 + for the renamed file
21064 + if a file is being replaced by a rename, new_dentry has the inode
21065 + and name for the replaced file
21068 + if (unlikely(!(gr_status & GR_READY)))
21071 + preempt_disable();
21072 + matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
21074 + /* we wouldn't have to check d_inode if it weren't for
21075 + NFS silly-renaming
21078 + write_lock(&gr_inode_lock);
21079 + if (unlikely(replace && new_dentry->d_inode)) {
21080 + inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
21081 + new_dentry->d_inode->i_sb->s_dev);
21082 + if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
21083 + do_handle_delete(inodev, new_dentry->d_inode->i_ino,
21084 + new_dentry->d_inode->i_sb->s_dev);
21087 + inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
21088 + old_dentry->d_inode->i_sb->s_dev);
21089 + if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
21090 + do_handle_delete(inodev, old_dentry->d_inode->i_ino,
21091 + old_dentry->d_inode->i_sb->s_dev);
21093 + if (unlikely((unsigned long)matchn))
21094 + do_handle_create(matchn, old_dentry, mnt);
21096 + write_unlock(&gr_inode_lock);
21097 + preempt_enable();
21103 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
21104 + unsigned char **sum)
21106 + struct acl_role_label *r;
21107 + struct role_allowed_ip *ipp;
21108 + struct role_transition *trans;
21112 + /* check transition table */
21114 + for (trans = current->role->transitions; trans; trans = trans->next) {
21115 + if (!strcmp(rolename, trans->rolename)) {
21124 + /* handle special roles that do not require authentication
21127 + FOR_EACH_ROLE_START(r, i)
21128 + if (!strcmp(rolename, r->rolename) &&
21129 + (r->roletype & GR_ROLE_SPECIAL)) {
21131 + if (r->allowed_ips != NULL) {
21132 + for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
21133 + if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
21134 + (ntohl(ipp->addr) & ipp->netmask))
21142 + if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
21143 + ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
21149 + FOR_EACH_ROLE_END(r,i)
21151 + for (i = 0; i < num_sprole_pws; i++) {
21152 + if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
21153 + *salt = acl_special_roles[i]->salt;
21154 + *sum = acl_special_roles[i]->sum;
21163 +assign_special_role(char *rolename)
21165 + struct acl_object_label *obj;
21166 + struct acl_role_label *r;
21167 + struct acl_role_label *assigned = NULL;
21168 + struct task_struct *tsk;
21169 + struct file *filp;
21172 + FOR_EACH_ROLE_START(r, i)
21173 + if (!strcmp(rolename, r->rolename) &&
21174 + (r->roletype & GR_ROLE_SPECIAL))
21176 + FOR_EACH_ROLE_END(r,i)
21181 + read_lock(&tasklist_lock);
21182 + read_lock(&grsec_exec_file_lock);
21184 + tsk = current->parent;
21188 + filp = tsk->exec_file;
21189 + if (filp == NULL)
21192 + tsk->is_writable = 0;
21194 + tsk->acl_sp_role = 1;
21195 + tsk->acl_role_id = ++acl_sp_role_value;
21196 + tsk->role = assigned;
21197 + tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
21199 + /* ignore additional mmap checks for processes that are writable
21200 + by the default ACL */
21201 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
21202 + if (unlikely(obj->mode & GR_WRITE))
21203 + tsk->is_writable = 1;
21204 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
21205 + if (unlikely(obj->mode & GR_WRITE))
21206 + tsk->is_writable = 1;
21208 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
21209 + printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
21213 + read_unlock(&grsec_exec_file_lock);
21214 + read_unlock(&tasklist_lock);
21218 +int gr_check_secure_terminal(struct task_struct *task)
21220 + struct task_struct *p, *p2, *p3;
21221 + struct files_struct *files;
21222 + struct fdtable *fdt;
21223 + struct file *our_file = NULL, *file;
21226 + if (task->signal->tty == NULL)
21229 + files = get_files_struct(task);
21230 + if (files != NULL) {
21232 + fdt = files_fdtable(files);
21233 + for (i=0; i < fdt->max_fds; i++) {
21234 + file = fcheck_files(files, i);
21235 + if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
21240 + rcu_read_unlock();
21241 + put_files_struct(files);
21244 + if (our_file == NULL)
21247 + read_lock(&tasklist_lock);
21248 + do_each_thread(p2, p) {
21249 + files = get_files_struct(p);
21250 + if (files == NULL ||
21251 + (p->signal && p->signal->tty == task->signal->tty)) {
21252 + if (files != NULL)
21253 + put_files_struct(files);
21257 + fdt = files_fdtable(files);
21258 + for (i=0; i < fdt->max_fds; i++) {
21259 + file = fcheck_files(files, i);
21260 + if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
21261 + file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
21263 + while (p3->pid > 0) {
21270 + gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
21271 + gr_handle_alertkill(p);
21272 + rcu_read_unlock();
21273 + put_files_struct(files);
21274 + read_unlock(&tasklist_lock);
21279 + rcu_read_unlock();
21280 + put_files_struct(files);
21281 + } while_each_thread(p2, p);
21282 + read_unlock(&tasklist_lock);
21289 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
21291 + struct gr_arg_wrapper uwrap;
21292 + unsigned char *sprole_salt;
21293 + unsigned char *sprole_sum;
21294 + int error = sizeof (struct gr_arg_wrapper);
21297 + down(&gr_dev_sem);
21299 + if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
21304 + if (count != sizeof (struct gr_arg_wrapper)) {
21305 + gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
21311 + if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
21312 + gr_auth_expires = 0;
21313 + gr_auth_attempts = 0;
21316 + if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
21321 + if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
21326 + if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
21331 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
21332 + gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
21333 + time_after(gr_auth_expires, get_seconds())) {
21338 + /* if non-root trying to do anything other than use a special role,
21339 + do not attempt authentication, do not count towards authentication
21343 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
21344 + gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
21350 + /* ensure pw and special role name are null terminated */
21352 + gr_usermode->pw[GR_PW_LEN - 1] = '\0';
21353 + gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
21356 + * We have our enough of the argument structure..(we have yet
21357 + * to copy_from_user the tables themselves) . Copy the tables
21358 + * only if we need them, i.e. for loading operations. */
21360 + switch (gr_usermode->mode) {
21362 + if (gr_status & GR_READY) {
21364 + if (!gr_check_secure_terminal(current))
21370 + if ((gr_status & GR_READY)
21371 + && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
21372 + gr_status &= ~GR_READY;
21373 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
21374 + free_variables();
21375 + memset(gr_usermode, 0, sizeof (struct gr_arg));
21376 + memset(gr_system_salt, 0, GR_SALT_LEN);
21377 + memset(gr_system_sum, 0, GR_SHA_LEN);
21378 + } else if (gr_status & GR_READY) {
21379 + gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
21382 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
21387 + if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
21388 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
21390 + if (gr_status & GR_READY)
21394 + gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
21398 + if (!(gr_status & GR_READY)) {
21399 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
21401 + } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
21403 + gr_status &= ~GR_READY;
21404 + free_variables();
21405 + if (!(error2 = gracl_init(gr_usermode))) {
21407 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
21411 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
21414 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
21419 + if (unlikely(!(gr_status & GR_READY))) {
21420 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
21425 + if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
21426 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
21427 + if (gr_usermode->segv_device && gr_usermode->segv_inode) {
21428 + struct acl_subject_label *segvacl;
21430 + lookup_acl_subj_label(gr_usermode->segv_inode,
21431 + gr_usermode->segv_device,
21434 + segvacl->crashes = 0;
21435 + segvacl->expires = 0;
21437 + } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
21438 + gr_remove_uid(gr_usermode->segv_uid);
21441 + gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
21447 + if (unlikely(!(gr_status & GR_READY))) {
21448 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
21453 + if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
21454 + current->role->expires = 0;
21455 + current->role->auth_attempts = 0;
21458 + if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
21459 + time_after(current->role->expires, get_seconds())) {
21464 + if (lookup_special_role_auth
21465 + (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
21466 + && ((!sprole_salt && !sprole_sum)
21467 + || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
21469 + assign_special_role(gr_usermode->sp_role);
21470 + read_lock(&tasklist_lock);
21471 + if (current->parent)
21472 + p = current->parent->role->rolename;
21473 + read_unlock(&tasklist_lock);
21474 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
21475 + p, acl_sp_role_value);
21477 + gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
21479 + if(!(current->role->auth_attempts++))
21480 + current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
21486 + if (unlikely(!(gr_status & GR_READY))) {
21487 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
21492 + if (current->role->roletype & GR_ROLE_SPECIAL) {
21496 + read_lock(&tasklist_lock);
21497 + if (current->parent) {
21498 + p = current->parent->role->rolename;
21499 + i = current->parent->acl_role_id;
21501 + read_unlock(&tasklist_lock);
21503 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
21506 + gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
21512 + gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
21517 + if (error != -EPERM)
21520 + if(!(gr_auth_attempts++))
21521 + gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
21529 +gr_set_acls(const int type)
21531 + struct acl_object_label *obj;
21532 + struct task_struct *task, *task2;
21533 + struct file *filp;
21534 + struct acl_role_label *role = current->role;
21535 + __u16 acl_role_id = current->acl_role_id;
21537 + read_lock(&tasklist_lock);
21538 + read_lock(&grsec_exec_file_lock);
21539 + do_each_thread(task2, task) {
21540 + /* check to see if we're called from the exit handler,
21541 + if so, only replace ACLs that have inherited the admin
21544 + if (type && (task->role != role ||
21545 + task->acl_role_id != acl_role_id))
21548 + task->acl_role_id = 0;
21549 + task->acl_sp_role = 0;
21551 + if ((filp = task->exec_file)) {
21552 + task->role = lookup_acl_role_label(task, task->uid, task->gid);
21555 + chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
21558 + struct acl_subject_label *curr;
21559 + curr = task->acl;
21561 + task->is_writable = 0;
21562 + /* ignore additional mmap checks for processes that are writable
21563 + by the default ACL */
21564 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
21565 + if (unlikely(obj->mode & GR_WRITE))
21566 + task->is_writable = 1;
21567 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
21568 + if (unlikely(obj->mode & GR_WRITE))
21569 + task->is_writable = 1;
21571 + gr_set_proc_res(task);
21573 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
21574 + printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
21577 + read_unlock(&grsec_exec_file_lock);
21578 + read_unlock(&tasklist_lock);
21579 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
21583 + // it's a kernel process
21584 + task->role = kernel_role;
21585 + task->acl = kernel_role->root_label;
21586 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
21587 + task->acl->mode &= ~GR_PROCFIND;
21590 + } while_each_thread(task2, task);
21591 + read_unlock(&grsec_exec_file_lock);
21592 + read_unlock(&tasklist_lock);
21597 +gr_learn_resource(const struct task_struct *task,
21598 + const int res, const unsigned long wanted, const int gt)
21600 + struct acl_subject_label *acl;
21602 + if (unlikely((gr_status & GR_READY) &&
21603 + task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
21604 + goto skip_reslog;
21606 +#ifdef CONFIG_GRKERNSEC_RESLOG
21607 + gr_log_resource(task, res, wanted, gt);
21611 + if (unlikely(!(gr_status & GR_READY) || !wanted))
21616 + if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
21617 + !(acl->resmask & (1 << (unsigned short) res))))
21620 + if (wanted >= acl->res[res].rlim_cur) {
21621 + unsigned long res_add;
21623 + res_add = wanted;
21626 + res_add += GR_RLIM_CPU_BUMP;
21628 + case RLIMIT_FSIZE:
21629 + res_add += GR_RLIM_FSIZE_BUMP;
21631 + case RLIMIT_DATA:
21632 + res_add += GR_RLIM_DATA_BUMP;
21634 + case RLIMIT_STACK:
21635 + res_add += GR_RLIM_STACK_BUMP;
21637 + case RLIMIT_CORE:
21638 + res_add += GR_RLIM_CORE_BUMP;
21641 + res_add += GR_RLIM_RSS_BUMP;
21643 + case RLIMIT_NPROC:
21644 + res_add += GR_RLIM_NPROC_BUMP;
21646 + case RLIMIT_NOFILE:
21647 + res_add += GR_RLIM_NOFILE_BUMP;
21649 + case RLIMIT_MEMLOCK:
21650 + res_add += GR_RLIM_MEMLOCK_BUMP;
21653 + res_add += GR_RLIM_AS_BUMP;
21655 + case RLIMIT_LOCKS:
21656 + res_add += GR_RLIM_LOCKS_BUMP;
21660 + acl->res[res].rlim_cur = res_add;
21662 + if (wanted > acl->res[res].rlim_max)
21663 + acl->res[res].rlim_max = res_add;
21665 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
21666 + task->role->roletype, acl->filename,
21667 + acl->res[res].rlim_cur, acl->res[res].rlim_max,
21668 + "", (unsigned long) res);
21674 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
21676 +pax_set_initial_flags(struct linux_binprm *bprm)
21678 + struct task_struct *task = current;
21679 + struct acl_subject_label *proc;
21680 + unsigned long flags;
21682 + if (unlikely(!(gr_status & GR_READY)))
21685 + flags = pax_get_flags(task);
21687 + proc = task->acl;
21689 + if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
21690 + flags &= ~MF_PAX_PAGEEXEC;
21691 + if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
21692 + flags &= ~MF_PAX_SEGMEXEC;
21693 + if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
21694 + flags &= ~MF_PAX_RANDMMAP;
21695 + if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
21696 + flags &= ~MF_PAX_EMUTRAMP;
21697 + if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
21698 + flags &= ~MF_PAX_MPROTECT;
21700 + if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
21701 + flags |= MF_PAX_PAGEEXEC;
21702 + if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
21703 + flags |= MF_PAX_SEGMEXEC;
21704 + if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
21705 + flags |= MF_PAX_RANDMMAP;
21706 + if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
21707 + flags |= MF_PAX_EMUTRAMP;
21708 + if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
21709 + flags |= MF_PAX_MPROTECT;
21711 + pax_set_flags(task, flags);
21717 +#ifdef CONFIG_SYSCTL
21718 +/* Eric Biederman likes breaking userland ABI and every inode-based security
21719 + system to save 35kb of memory */
21721 +/* we modify the passed in filename, but adjust it back before returning */
21722 +static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
21724 + struct name_entry *nmatch;
21725 + char *p, *lastp = NULL;
21726 + struct acl_object_label *obj = NULL, *tmp;
21727 + struct acl_subject_label *tmpsubj;
21730 + read_lock(&gr_inode_lock);
21732 + p = name + len - 1;
21734 + nmatch = lookup_name_entry(name);
21735 + if (lastp != NULL)
21738 + if (nmatch == NULL)
21739 + goto next_component;
21740 + tmpsubj = current->acl;
21742 + obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
21743 + if (obj != NULL) {
21744 + tmp = obj->globbed;
21746 + if (!glob_match(tmp->filename, name)) {
21754 + } while ((tmpsubj = tmpsubj->parent_subject));
21760 + while (*p != '/')
21772 + read_unlock(&gr_inode_lock);
21773 + /* obj returned will always be non-null */
21777 +/* returns 0 when allowing, non-zero on error
21778 + op of 0 is used for readdir, so we don't log the names of hidden files
21781 +gr_handle_sysctl(const struct ctl_table *table, const int op)
21784 + const char *proc_sys = "/proc/sys";
21786 + struct acl_object_label *obj;
21787 + unsigned short len = 0, pos = 0, depth = 0, i;
21791 + if (unlikely(!(gr_status & GR_READY)))
21794 + /* for now, ignore operations on non-sysctl entries if it's not a
21796 + if (table->child != NULL && op != 0)
21800 + /* it's only a read if it's an entry, read on dirs is for readdir */
21804 + mode |= GR_WRITE;
21806 + preempt_disable();
21808 + path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
21810 + /* it's only a read/write if it's an actual entry, not a dir
21811 + (which are opened for readdir)
21814 + /* convert the requested sysctl entry into a pathname */
21816 + for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
21817 + len += strlen(tmp->procname);
21822 + if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
21827 + memset(path, 0, PAGE_SIZE);
21829 + memcpy(path, proc_sys, strlen(proc_sys));
21831 + pos += strlen(proc_sys);
21833 + for (; depth > 0; depth--) {
21836 + for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
21837 + if (depth == i) {
21838 + memcpy(path + pos, tmp->procname,
21839 + strlen(tmp->procname));
21840 + pos += strlen(tmp->procname);
21846 + obj = gr_lookup_by_name(path, pos);
21847 + err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
21849 + if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
21850 + ((err & mode) != mode))) {
21851 + __u32 new_mode = mode;
21853 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21856 + gr_log_learn_sysctl(current, path, new_mode);
21857 + } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
21858 + gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
21860 + } else if (!(err & GR_FIND)) {
21862 + } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
21863 + gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
21864 + path, (mode & GR_READ) ? " reading" : "",
21865 + (mode & GR_WRITE) ? " writing" : "");
21867 + } else if ((err & mode) != mode) {
21869 + } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
21870 + gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
21871 + path, (mode & GR_READ) ? " reading" : "",
21872 + (mode & GR_WRITE) ? " writing" : "");
21878 + preempt_enable();
21885 +gr_handle_proc_ptrace(struct task_struct *task)
21887 + struct file *filp;
21888 + struct task_struct *tmp = task;
21889 + struct task_struct *curtemp = current;
21892 + if (unlikely(!(gr_status & GR_READY)))
21895 + read_lock(&tasklist_lock);
21896 + read_lock(&grsec_exec_file_lock);
21897 + filp = task->exec_file;
21899 + while (tmp->pid > 0) {
21900 + if (tmp == curtemp)
21902 + tmp = tmp->parent;
21905 + if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
21906 + read_unlock(&grsec_exec_file_lock);
21907 + read_unlock(&tasklist_lock);
21911 + retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
21912 + read_unlock(&grsec_exec_file_lock);
21913 + read_unlock(&tasklist_lock);
21915 + if (retmode & GR_NOPTRACE)
21918 + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
21919 + && (current->acl != task->acl || (current->acl != current->role->root_label
21920 + && current->pid != task->pid)))
21927 +gr_handle_ptrace(struct task_struct *task, const long request)
21929 + struct task_struct *tmp = task;
21930 + struct task_struct *curtemp = current;
21933 + if (unlikely(!(gr_status & GR_READY)))
21936 + read_lock(&tasklist_lock);
21937 + while (tmp->pid > 0) {
21938 + if (tmp == curtemp)
21940 + tmp = tmp->parent;
21943 + if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
21944 + read_unlock(&tasklist_lock);
21945 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21948 + read_unlock(&tasklist_lock);
21950 + read_lock(&grsec_exec_file_lock);
21951 + if (unlikely(!task->exec_file)) {
21952 + read_unlock(&grsec_exec_file_lock);
21956 + retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
21957 + read_unlock(&grsec_exec_file_lock);
21959 + if (retmode & GR_NOPTRACE) {
21960 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21964 + if (retmode & GR_PTRACERD) {
21965 + switch (request) {
21966 + case PTRACE_POKETEXT:
21967 + case PTRACE_POKEDATA:
21968 + case PTRACE_POKEUSR:
21969 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
21970 + case PTRACE_SETREGS:
21971 + case PTRACE_SETFPREGS:
21974 + case PTRACE_SETFPXREGS:
21976 +#ifdef CONFIG_ALTIVEC
21977 + case PTRACE_SETVRREGS:
21983 + } else if (!(current->acl->mode & GR_POVERRIDE) &&
21984 + !(current->role->roletype & GR_ROLE_GOD) &&
21985 + (current->acl != task->acl)) {
21986 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21993 +static int is_writable_mmap(const struct file *filp)
21995 + struct task_struct *task = current;
21996 + struct acl_object_label *obj, *obj2;
21998 + if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
21999 + !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
22000 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
22001 + obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
22002 + task->role->root_label);
22003 + if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
22004 + gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
22012 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
22016 + if (unlikely(!file || !(prot & PROT_EXEC)))
22019 + if (is_writable_mmap(file))
22023 + gr_search_file(file->f_dentry,
22024 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
22027 + if (!gr_tpe_allow(file))
22030 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
22031 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
22033 + } else if (unlikely(!(mode & GR_EXEC))) {
22035 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
22036 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
22044 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
22048 + if (unlikely(!file || !(prot & PROT_EXEC)))
22051 + if (is_writable_mmap(file))
22055 + gr_search_file(file->f_dentry,
22056 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
22059 + if (!gr_tpe_allow(file))
22062 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
22063 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
22065 + } else if (unlikely(!(mode & GR_EXEC))) {
22067 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
22068 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
22076 +gr_acl_handle_psacct(struct task_struct *task, const long code)
22078 + unsigned long runtime;
22079 + unsigned long cputime;
22080 + unsigned int wday, cday;
22084 + struct timespec timeval;
22086 + if (unlikely(!(gr_status & GR_READY) || !task->acl ||
22087 + !(task->acl->mode & GR_PROCACCT)))
22090 + do_posix_clock_monotonic_gettime(&timeval);
22091 + runtime = timeval.tv_sec - task->start_time.tv_sec;
22092 + wday = runtime / (3600 * 24);
22093 + runtime -= wday * (3600 * 24);
22094 + whr = runtime / 3600;
22095 + runtime -= whr * 3600;
22096 + wmin = runtime / 60;
22097 + runtime -= wmin * 60;
22100 + cputime = (task->utime + task->stime) / HZ;
22101 + cday = cputime / (3600 * 24);
22102 + cputime -= cday * (3600 * 24);
22103 + chr = cputime / 3600;
22104 + cputime -= chr * 3600;
22105 + cmin = cputime / 60;
22106 + cputime -= cmin * 60;
22109 + gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
22114 +void gr_set_kernel_label(struct task_struct *task)
22116 + if (gr_status & GR_READY) {
22117 + task->role = kernel_role;
22118 + task->acl = kernel_role->root_label;
22123 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
22125 + struct task_struct *task = current;
22126 + struct dentry *dentry = file->f_dentry;
22127 + struct vfsmount *mnt = file->f_vfsmnt;
22128 + struct acl_object_label *obj, *tmp;
22129 + struct acl_subject_label *subj;
22130 + unsigned int bufsize;
22134 + if (unlikely(!(gr_status & GR_READY)))
22137 + if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22140 + /* ignore Eric Biederman */
22141 + if (IS_PRIVATE(dentry->d_inode))
22144 + subj = task->acl;
22146 + obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
22148 + return (obj->mode & GR_FIND) ? 1 : 0;
22149 + } while ((subj = subj->parent_subject));
22151 + obj = chk_obj_label(dentry, mnt, task->acl);
22152 + if (obj->globbed == NULL)
22153 + return (obj->mode & GR_FIND) ? 1 : 0;
22155 + is_not_root = ((obj->filename[0] == '/') &&
22156 + (obj->filename[1] == '\0')) ? 0 : 1;
22157 + bufsize = PAGE_SIZE - namelen - is_not_root;
22159 + /* check bufsize > PAGE_SIZE || bufsize == 0 */
22160 + if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
22163 + preempt_disable();
22164 + path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
22167 + bufsize = strlen(path);
22169 + /* if base is "/", don't append an additional slash */
22171 + *(path + bufsize) = '/';
22172 + memcpy(path + bufsize + is_not_root, name, namelen);
22173 + *(path + bufsize + namelen + is_not_root) = '\0';
22175 + tmp = obj->globbed;
22177 + if (!glob_match(tmp->filename, path)) {
22178 + preempt_enable();
22179 + return (tmp->mode & GR_FIND) ? 1 : 0;
22183 + preempt_enable();
22184 + return (obj->mode & GR_FIND) ? 1 : 0;
22187 +EXPORT_SYMBOL(gr_learn_resource);
22188 +EXPORT_SYMBOL(gr_set_kernel_label);
22189 +#ifdef CONFIG_SECURITY
22190 +EXPORT_SYMBOL(gr_check_user_change);
22191 +EXPORT_SYMBOL(gr_check_group_change);
22194 diff -urNp linux-2.6.24.4/grsecurity/gracl_cap.c linux-2.6.24.4/grsecurity/gracl_cap.c
22195 --- linux-2.6.24.4/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
22196 +++ linux-2.6.24.4/grsecurity/gracl_cap.c 2008-03-26 23:01:12.000000000 -0400
22198 +#include <linux/kernel.h>
22199 +#include <linux/module.h>
22200 +#include <linux/sched.h>
22201 +#include <linux/capability.h>
22202 +#include <linux/gracl.h>
22203 +#include <linux/grsecurity.h>
22204 +#include <linux/grinternal.h>
22206 +static const char *captab_log[] = {
22208 + "CAP_DAC_OVERRIDE",
22209 + "CAP_DAC_READ_SEARCH",
22216 + "CAP_LINUX_IMMUTABLE",
22217 + "CAP_NET_BIND_SERVICE",
22218 + "CAP_NET_BROADCAST",
22223 + "CAP_SYS_MODULE",
22225 + "CAP_SYS_CHROOT",
22226 + "CAP_SYS_PTRACE",
22231 + "CAP_SYS_RESOURCE",
22233 + "CAP_SYS_TTY_CONFIG",
22236 + "CAP_AUDIT_WRITE",
22237 + "CAP_AUDIT_CONTROL",
22241 +EXPORT_SYMBOL(gr_task_is_capable);
22242 +EXPORT_SYMBOL(gr_is_capable_nolog);
22245 +gr_task_is_capable(struct task_struct *task, const int cap)
22247 + struct acl_subject_label *curracl;
22248 + __u32 cap_drop = 0, cap_mask = 0;
22250 + if (!gr_acl_is_enabled())
22253 + curracl = task->acl;
22255 + cap_drop = curracl->cap_lower;
22256 + cap_mask = curracl->cap_mask;
22258 + while ((curracl = curracl->parent_subject)) {
22259 + if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
22260 + cap_drop |= curracl->cap_lower & (1 << cap);
22261 + cap_mask |= curracl->cap_mask;
22264 + if (!cap_raised(cap_drop, cap))
22267 + curracl = task->acl;
22269 + if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
22270 + && cap_raised(task->cap_effective, cap)) {
22271 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
22272 + task->role->roletype, task->uid,
22273 + task->gid, task->exec_file ?
22274 + gr_to_filename(task->exec_file->f_dentry,
22275 + task->exec_file->f_vfsmnt) : curracl->filename,
22276 + curracl->filename, 0UL,
22277 + 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
22281 + if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
22282 + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
22287 +gr_is_capable_nolog(const int cap)
22289 + struct acl_subject_label *curracl;
22290 + __u32 cap_drop = 0, cap_mask = 0;
22292 + if (!gr_acl_is_enabled())
22295 + curracl = current->acl;
22297 + cap_drop = curracl->cap_lower;
22298 + cap_mask = curracl->cap_mask;
22300 + while ((curracl = curracl->parent_subject)) {
22301 + cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
22302 + cap_mask |= curracl->cap_mask;
22305 + if (!cap_raised(cap_drop, cap))
22311 diff -urNp linux-2.6.24.4/grsecurity/gracl_fs.c linux-2.6.24.4/grsecurity/gracl_fs.c
22312 --- linux-2.6.24.4/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
22313 +++ linux-2.6.24.4/grsecurity/gracl_fs.c 2008-03-26 20:21:09.000000000 -0400
22315 +#include <linux/kernel.h>
22316 +#include <linux/sched.h>
22317 +#include <linux/types.h>
22318 +#include <linux/fs.h>
22319 +#include <linux/file.h>
22320 +#include <linux/stat.h>
22321 +#include <linux/grsecurity.h>
22322 +#include <linux/grinternal.h>
22323 +#include <linux/gracl.h>
22326 +gr_acl_handle_hidden_file(const struct dentry * dentry,
22327 + const struct vfsmount * mnt)
22331 + if (unlikely(!dentry->d_inode))
22335 + gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
22337 + if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
22338 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
22340 + } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
22341 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
22343 + } else if (unlikely(!(mode & GR_FIND)))
22350 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
22353 + __u32 reqmode = GR_FIND;
22356 + if (unlikely(!dentry->d_inode))
22359 + if (unlikely(fmode & O_APPEND))
22360 + reqmode |= GR_APPEND;
22361 + else if (unlikely(fmode & FMODE_WRITE))
22362 + reqmode |= GR_WRITE;
22363 + if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
22364 + reqmode |= GR_READ;
22367 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
22370 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
22371 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
22372 + reqmode & GR_READ ? " reading" : "",
22373 + reqmode & GR_WRITE ? " writing" : reqmode &
22374 + GR_APPEND ? " appending" : "");
22377 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
22379 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
22380 + reqmode & GR_READ ? " reading" : "",
22381 + reqmode & GR_WRITE ? " writing" : reqmode &
22382 + GR_APPEND ? " appending" : "");
22384 + } else if (unlikely((mode & reqmode) != reqmode))
22391 +gr_acl_handle_creat(const struct dentry * dentry,
22392 + const struct dentry * p_dentry,
22393 + const struct vfsmount * p_mnt, const int fmode,
22396 + __u32 reqmode = GR_WRITE | GR_CREATE;
22399 + if (unlikely(fmode & O_APPEND))
22400 + reqmode |= GR_APPEND;
22401 + if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
22402 + reqmode |= GR_READ;
22403 + if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
22404 + reqmode |= GR_SETID;
22407 + gr_check_create(dentry, p_dentry, p_mnt,
22408 + reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
22410 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
22411 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
22412 + reqmode & GR_READ ? " reading" : "",
22413 + reqmode & GR_WRITE ? " writing" : reqmode &
22414 + GR_APPEND ? " appending" : "");
22417 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
22419 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
22420 + reqmode & GR_READ ? " reading" : "",
22421 + reqmode & GR_WRITE ? " writing" : reqmode &
22422 + GR_APPEND ? " appending" : "");
22424 + } else if (unlikely((mode & reqmode) != reqmode))
22431 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
22434 + __u32 mode, reqmode = GR_FIND;
22436 + if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
22437 + reqmode |= GR_EXEC;
22438 + if (fmode & S_IWOTH)
22439 + reqmode |= GR_WRITE;
22440 + if (fmode & S_IROTH)
22441 + reqmode |= GR_READ;
22444 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
22447 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
22448 + gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
22449 + reqmode & GR_READ ? " reading" : "",
22450 + reqmode & GR_WRITE ? " writing" : "",
22451 + reqmode & GR_EXEC ? " executing" : "");
22454 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
22456 + gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
22457 + reqmode & GR_READ ? " reading" : "",
22458 + reqmode & GR_WRITE ? " writing" : "",
22459 + reqmode & GR_EXEC ? " executing" : "");
22461 + } else if (unlikely((mode & reqmode) != reqmode))
22467 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
22471 + mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
22473 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
22474 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
22476 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
22477 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
22479 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
22482 + return (reqmode);
22486 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
22488 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
22492 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
22494 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
22498 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
22500 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
22504 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
22506 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
22510 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
22513 + if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
22516 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
22517 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
22518 + GR_FCHMOD_ACL_MSG);
22520 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
22525 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
22528 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
22529 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
22530 + GR_CHMOD_ACL_MSG);
22532 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
22537 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
22539 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
22543 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
22545 + return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
22549 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
22551 + return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
22552 + GR_UNIXCONNECT_ACL_MSG);
22555 +/* hardlinks require at minimum create permission,
22556 + any additional privilege required is based on the
22557 + privilege of the file being linked to
22560 +gr_acl_handle_link(const struct dentry * new_dentry,
22561 + const struct dentry * parent_dentry,
22562 + const struct vfsmount * parent_mnt,
22563 + const struct dentry * old_dentry,
22564 + const struct vfsmount * old_mnt, const char *to)
22567 + __u32 needmode = GR_CREATE | GR_LINK;
22568 + __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
22571 + gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
22574 + if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
22575 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
22577 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
22578 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
22580 + } else if (unlikely((mode & needmode) != needmode))
22587 +gr_acl_handle_symlink(const struct dentry * new_dentry,
22588 + const struct dentry * parent_dentry,
22589 + const struct vfsmount * parent_mnt, const char *from)
22591 + __u32 needmode = GR_WRITE | GR_CREATE;
22595 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
22596 + GR_CREATE | GR_AUDIT_CREATE |
22597 + GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
22599 + if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
22600 + gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
22602 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
22603 + gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
22605 + } else if (unlikely((mode & needmode) != needmode))
22608 + return (GR_WRITE | GR_CREATE);
22611 +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)
22615 + mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
22617 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
22618 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
22620 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
22621 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
22623 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
22626 + return (reqmode);
22630 +gr_acl_handle_mknod(const struct dentry * new_dentry,
22631 + const struct dentry * parent_dentry,
22632 + const struct vfsmount * parent_mnt,
22635 + __u32 reqmode = GR_WRITE | GR_CREATE;
22636 + if (unlikely(mode & (S_ISUID | S_ISGID)))
22637 + reqmode |= GR_SETID;
22639 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
22640 + reqmode, GR_MKNOD_ACL_MSG);
22644 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
22645 + const struct dentry *parent_dentry,
22646 + const struct vfsmount *parent_mnt)
22648 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
22649 + GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
22652 +#define RENAME_CHECK_SUCCESS(old, new) \
22653 + (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
22654 + ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
22657 +gr_acl_handle_rename(struct dentry *new_dentry,
22658 + struct dentry *parent_dentry,
22659 + const struct vfsmount *parent_mnt,
22660 + struct dentry *old_dentry,
22661 + struct inode *old_parent_inode,
22662 + struct vfsmount *old_mnt, const char *newname)
22664 + __u32 comp1, comp2;
22667 + if (unlikely(!gr_acl_is_enabled()))
22670 + if (!new_dentry->d_inode) {
22671 + comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
22672 + GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
22673 + GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
22674 + comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
22675 + GR_DELETE | GR_AUDIT_DELETE |
22676 + GR_AUDIT_READ | GR_AUDIT_WRITE |
22677 + GR_SUPPRESS, old_mnt);
22679 + comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
22680 + GR_CREATE | GR_DELETE |
22681 + GR_AUDIT_CREATE | GR_AUDIT_DELETE |
22682 + GR_AUDIT_READ | GR_AUDIT_WRITE |
22683 + GR_SUPPRESS, parent_mnt);
22685 + gr_search_file(old_dentry,
22686 + GR_READ | GR_WRITE | GR_AUDIT_READ |
22687 + GR_DELETE | GR_AUDIT_DELETE |
22688 + GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
22691 + if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
22692 + ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
22693 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
22694 + else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
22695 + && !(comp2 & GR_SUPPRESS)) {
22696 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
22698 + } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
22705 +gr_acl_handle_exit(void)
22709 + struct file *exec_file;
22711 + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
22712 + id = current->acl_role_id;
22713 + rolename = current->role->rolename;
22715 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
22718 + write_lock(&grsec_exec_file_lock);
22719 + exec_file = current->exec_file;
22720 + current->exec_file = NULL;
22721 + write_unlock(&grsec_exec_file_lock);
22728 +gr_acl_handle_procpidmem(const struct task_struct *task)
22730 + if (unlikely(!gr_acl_is_enabled()))
22733 + if (task != current && task->acl->mode & GR_PROTPROCFD)
22738 diff -urNp linux-2.6.24.4/grsecurity/gracl_ip.c linux-2.6.24.4/grsecurity/gracl_ip.c
22739 --- linux-2.6.24.4/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
22740 +++ linux-2.6.24.4/grsecurity/gracl_ip.c 2008-03-26 20:21:09.000000000 -0400
22742 +#include <linux/kernel.h>
22743 +#include <asm/uaccess.h>
22744 +#include <asm/errno.h>
22745 +#include <net/sock.h>
22746 +#include <linux/file.h>
22747 +#include <linux/fs.h>
22748 +#include <linux/net.h>
22749 +#include <linux/in.h>
22750 +#include <linux/skbuff.h>
22751 +#include <linux/ip.h>
22752 +#include <linux/udp.h>
22753 +#include <linux/smp_lock.h>
22754 +#include <linux/types.h>
22755 +#include <linux/sched.h>
22756 +#include <linux/netdevice.h>
22757 +#include <linux/inetdevice.h>
22758 +#include <linux/gracl.h>
22759 +#include <linux/grsecurity.h>
22760 +#include <linux/grinternal.h>
22762 +#define GR_BIND 0x01
22763 +#define GR_CONNECT 0x02
22764 +#define GR_INVERT 0x04
22766 +static const char * gr_protocols[256] = {
22767 + "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
22768 + "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
22769 + "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
22770 + "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
22771 + "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
22772 + "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
22773 + "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
22774 + "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
22775 + "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
22776 + "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
22777 + "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
22778 + "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
22779 + "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
22780 + "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
22781 + "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
22782 + "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
22783 + "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
22784 + "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
22785 + "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
22786 + "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
22787 + "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
22788 + "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
22789 + "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
22790 + "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
22791 + "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
22792 + "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
22793 + "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
22794 + "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
22795 + "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
22796 + "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
22797 + "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
22798 + "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
22801 +static const char * gr_socktypes[11] = {
22802 + "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
22803 + "unknown:7", "unknown:8", "unknown:9", "packet"
22807 +gr_proto_to_name(unsigned char proto)
22809 + return gr_protocols[proto];
22813 +gr_socktype_to_name(unsigned char type)
22815 + return gr_socktypes[type];
22819 +gr_search_socket(const int domain, const int type, const int protocol)
22821 + struct acl_subject_label *curr;
22823 + if (unlikely(!gr_acl_is_enabled()))
22826 + if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
22827 + || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
22828 + goto exit; // let the kernel handle it
22830 + curr = current->acl;
22835 + if ((curr->ip_type & (1 << type)) &&
22836 + (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
22839 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
22840 + /* we don't place acls on raw sockets , and sometimes
22841 + dgram/ip sockets are opened for ioctl and not
22842 + bind/connect, so we'll fake a bind learn log */
22843 + if (type == SOCK_RAW || type == SOCK_PACKET) {
22844 + __u32 fakeip = 0;
22845 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22846 + current->role->roletype, current->uid,
22847 + current->gid, current->exec_file ?
22848 + gr_to_filename(current->exec_file->f_dentry,
22849 + current->exec_file->f_vfsmnt) :
22850 + curr->filename, curr->filename,
22851 + NIPQUAD(fakeip), 0, type,
22852 + protocol, GR_CONNECT,
22853 +NIPQUAD(current->signal->curr_ip));
22854 + } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
22855 + __u32 fakeip = 0;
22856 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22857 + current->role->roletype, current->uid,
22858 + current->gid, current->exec_file ?
22859 + gr_to_filename(current->exec_file->f_dentry,
22860 + current->exec_file->f_vfsmnt) :
22861 + curr->filename, curr->filename,
22862 + NIPQUAD(fakeip), 0, type,
22863 + protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
22865 + /* we'll log when they use connect or bind */
22869 + gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
22870 + gr_socktype_to_name(type), gr_proto_to_name(protocol));
22877 +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)
22879 + if ((ip->mode & mode) &&
22880 + (ip_port >= ip->low) &&
22881 + (ip_port <= ip->high) &&
22882 + ((ntohl(ip_addr) & our_netmask) ==
22883 + (ntohl(our_addr) & our_netmask))
22884 + && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
22885 + && (ip->type & (1 << type))) {
22886 + if (ip->mode & GR_INVERT)
22887 + return 2; // specifically denied
22889 + return 1; // allowed
22892 + return 0; // not specifically allowed, may continue parsing
22896 +gr_search_connectbind(const int mode, const struct sock *sk,
22897 + const struct sockaddr_in *addr, const int type)
22899 + char iface[IFNAMSIZ] = {0};
22900 + struct acl_subject_label *curr;
22901 + struct acl_ip_label *ip;
22902 + struct net_device *dev;
22903 + struct in_device *idev;
22906 + __u32 ip_addr = 0;
22908 + __u32 our_netmask;
22910 + __u16 ip_port = 0;
22912 + if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
22915 + curr = current->acl;
22920 + ip_addr = addr->sin_addr.s_addr;
22921 + ip_port = ntohs(addr->sin_port);
22923 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
22924 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22925 + current->role->roletype, current->uid,
22926 + current->gid, current->exec_file ?
22927 + gr_to_filename(current->exec_file->f_dentry,
22928 + current->exec_file->f_vfsmnt) :
22929 + curr->filename, curr->filename,
22930 + NIPQUAD(ip_addr), ip_port, type,
22931 + sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
22935 + for (i = 0; i < curr->ip_num; i++) {
22936 + ip = *(curr->ips + i);
22937 + if (ip->iface != NULL) {
22938 + strncpy(iface, ip->iface, IFNAMSIZ - 1);
22939 + p = strchr(iface, ':');
22942 + dev = dev_get_by_name(sk->sk_net, iface);
22945 + idev = in_dev_get(dev);
22946 + if (idev == NULL) {
22952 + if (!strcmp(ip->iface, ifa->ifa_label)) {
22953 + our_addr = ifa->ifa_address;
22954 + our_netmask = 0xffffffff;
22955 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
22957 + rcu_read_unlock();
22958 + in_dev_put(idev);
22961 + } else if (ret == 2) {
22962 + rcu_read_unlock();
22963 + in_dev_put(idev);
22968 + } endfor_ifa(idev);
22969 + rcu_read_unlock();
22970 + in_dev_put(idev);
22973 + our_addr = ip->addr;
22974 + our_netmask = ip->netmask;
22975 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
22978 + else if (ret == 2)
22984 + if (mode == GR_BIND)
22985 + 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));
22986 + else if (mode == GR_CONNECT)
22987 + 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));
22993 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
22995 + return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
22999 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
23001 + return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
23004 +int gr_search_listen(const struct socket *sock)
23006 + struct sock *sk = sock->sk;
23007 + struct sockaddr_in addr;
23009 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
23010 + addr.sin_port = inet_sk(sk)->sport;
23012 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
23015 +int gr_search_accept(const struct socket *sock)
23017 + struct sock *sk = sock->sk;
23018 + struct sockaddr_in addr;
23020 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
23021 + addr.sin_port = inet_sk(sk)->sport;
23023 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
23027 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
23030 + return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
23032 + struct sockaddr_in sin;
23033 + const struct inet_sock *inet = inet_sk(sk);
23035 + sin.sin_addr.s_addr = inet->daddr;
23036 + sin.sin_port = inet->dport;
23038 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
23043 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
23045 + struct sockaddr_in sin;
23047 + if (unlikely(skb->len < sizeof (struct udphdr)))
23048 + return 1; // skip this packet
23050 + sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
23051 + sin.sin_port = udp_hdr(skb)->source;
23053 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
23055 diff -urNp linux-2.6.24.4/grsecurity/gracl_learn.c linux-2.6.24.4/grsecurity/gracl_learn.c
23056 --- linux-2.6.24.4/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
23057 +++ linux-2.6.24.4/grsecurity/gracl_learn.c 2008-03-26 20:21:09.000000000 -0400
23059 +#include <linux/kernel.h>
23060 +#include <linux/mm.h>
23061 +#include <linux/sched.h>
23062 +#include <linux/poll.h>
23063 +#include <linux/smp_lock.h>
23064 +#include <linux/string.h>
23065 +#include <linux/file.h>
23066 +#include <linux/types.h>
23067 +#include <linux/vmalloc.h>
23068 +#include <linux/grinternal.h>
23070 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
23071 + size_t count, loff_t *ppos);
23072 +extern int gr_acl_is_enabled(void);
23074 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
23075 +static int gr_learn_attached;
23077 +/* use a 512k buffer */
23078 +#define LEARN_BUFFER_SIZE (512 * 1024)
23080 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
23081 +static DECLARE_MUTEX(gr_learn_user_sem);
23083 +/* we need to maintain two buffers, so that the kernel context of grlearn
23084 + uses a semaphore around the userspace copying, and the other kernel contexts
23085 + use a spinlock when copying into the buffer, since they cannot sleep
23087 +static char *learn_buffer;
23088 +static char *learn_buffer_user;
23089 +static int learn_buffer_len;
23090 +static int learn_buffer_user_len;
23093 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
23095 + DECLARE_WAITQUEUE(wait, current);
23096 + ssize_t retval = 0;
23098 + add_wait_queue(&learn_wait, &wait);
23099 + set_current_state(TASK_INTERRUPTIBLE);
23101 + down(&gr_learn_user_sem);
23102 + spin_lock(&gr_learn_lock);
23103 + if (learn_buffer_len)
23105 + spin_unlock(&gr_learn_lock);
23106 + up(&gr_learn_user_sem);
23107 + if (file->f_flags & O_NONBLOCK) {
23108 + retval = -EAGAIN;
23111 + if (signal_pending(current)) {
23112 + retval = -ERESTARTSYS;
23119 + memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
23120 + learn_buffer_user_len = learn_buffer_len;
23121 + retval = learn_buffer_len;
23122 + learn_buffer_len = 0;
23124 + spin_unlock(&gr_learn_lock);
23126 + if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
23127 + retval = -EFAULT;
23129 + up(&gr_learn_user_sem);
23131 + set_current_state(TASK_RUNNING);
23132 + remove_wait_queue(&learn_wait, &wait);
23136 +static unsigned int
23137 +poll_learn(struct file * file, poll_table * wait)
23139 + poll_wait(file, &learn_wait, wait);
23141 + if (learn_buffer_len)
23142 + return (POLLIN | POLLRDNORM);
23148 +gr_clear_learn_entries(void)
23152 + down(&gr_learn_user_sem);
23153 + if (learn_buffer != NULL) {
23154 + spin_lock(&gr_learn_lock);
23155 + tmp = learn_buffer;
23156 + learn_buffer = NULL;
23157 + spin_unlock(&gr_learn_lock);
23158 + vfree(learn_buffer);
23160 + if (learn_buffer_user != NULL) {
23161 + vfree(learn_buffer_user);
23162 + learn_buffer_user = NULL;
23164 + learn_buffer_len = 0;
23165 + up(&gr_learn_user_sem);
23171 +gr_add_learn_entry(const char *fmt, ...)
23174 + unsigned int len;
23176 + if (!gr_learn_attached)
23179 + spin_lock(&gr_learn_lock);
23181 + /* leave a gap at the end so we know when it's "full" but don't have to
23182 + compute the exact length of the string we're trying to append
23184 + if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
23185 + spin_unlock(&gr_learn_lock);
23186 + wake_up_interruptible(&learn_wait);
23189 + if (learn_buffer == NULL) {
23190 + spin_unlock(&gr_learn_lock);
23194 + va_start(args, fmt);
23195 + len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
23198 + learn_buffer_len += len + 1;
23200 + spin_unlock(&gr_learn_lock);
23201 + wake_up_interruptible(&learn_wait);
23207 +open_learn(struct inode *inode, struct file *file)
23209 + if (file->f_mode & FMODE_READ && gr_learn_attached)
23211 + if (file->f_mode & FMODE_READ) {
23213 + down(&gr_learn_user_sem);
23214 + if (learn_buffer == NULL)
23215 + learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
23216 + if (learn_buffer_user == NULL)
23217 + learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
23218 + if (learn_buffer == NULL) {
23219 + retval = -ENOMEM;
23222 + if (learn_buffer_user == NULL) {
23223 + retval = -ENOMEM;
23226 + learn_buffer_len = 0;
23227 + learn_buffer_user_len = 0;
23228 + gr_learn_attached = 1;
23230 + up(&gr_learn_user_sem);
23237 +close_learn(struct inode *inode, struct file *file)
23241 + if (file->f_mode & FMODE_READ) {
23242 + down(&gr_learn_user_sem);
23243 + if (learn_buffer != NULL) {
23244 + spin_lock(&gr_learn_lock);
23245 + tmp = learn_buffer;
23246 + learn_buffer = NULL;
23247 + spin_unlock(&gr_learn_lock);
23250 + if (learn_buffer_user != NULL) {
23251 + vfree(learn_buffer_user);
23252 + learn_buffer_user = NULL;
23254 + learn_buffer_len = 0;
23255 + learn_buffer_user_len = 0;
23256 + gr_learn_attached = 0;
23257 + up(&gr_learn_user_sem);
23263 +struct file_operations grsec_fops = {
23264 + .read = read_learn,
23265 + .write = write_grsec_handler,
23266 + .open = open_learn,
23267 + .release = close_learn,
23268 + .poll = poll_learn,
23270 diff -urNp linux-2.6.24.4/grsecurity/gracl_res.c linux-2.6.24.4/grsecurity/gracl_res.c
23271 --- linux-2.6.24.4/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
23272 +++ linux-2.6.24.4/grsecurity/gracl_res.c 2008-03-26 20:21:09.000000000 -0400
23274 +#include <linux/kernel.h>
23275 +#include <linux/sched.h>
23276 +#include <linux/gracl.h>
23277 +#include <linux/grinternal.h>
23279 +static const char *restab_log[] = {
23280 + [RLIMIT_CPU] = "RLIMIT_CPU",
23281 + [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
23282 + [RLIMIT_DATA] = "RLIMIT_DATA",
23283 + [RLIMIT_STACK] = "RLIMIT_STACK",
23284 + [RLIMIT_CORE] = "RLIMIT_CORE",
23285 + [RLIMIT_RSS] = "RLIMIT_RSS",
23286 + [RLIMIT_NPROC] = "RLIMIT_NPROC",
23287 + [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
23288 + [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
23289 + [RLIMIT_AS] = "RLIMIT_AS",
23290 + [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
23291 + [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
23295 +gr_log_resource(const struct task_struct *task,
23296 + const int res, const unsigned long wanted, const int gt)
23298 + if (res == RLIMIT_NPROC &&
23299 + (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
23300 + cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
23302 + else if (res == RLIMIT_MEMLOCK &&
23303 + cap_raised(task->cap_effective, CAP_IPC_LOCK))
23306 + if (!gr_acl_is_enabled() && !grsec_resource_logging)
23309 + preempt_disable();
23311 + if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
23312 + (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
23313 + task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
23314 + gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
23315 + preempt_enable_no_resched();
23319 diff -urNp linux-2.6.24.4/grsecurity/gracl_segv.c linux-2.6.24.4/grsecurity/gracl_segv.c
23320 --- linux-2.6.24.4/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
23321 +++ linux-2.6.24.4/grsecurity/gracl_segv.c 2008-03-26 20:21:09.000000000 -0400
23323 +#include <linux/kernel.h>
23324 +#include <linux/mm.h>
23325 +#include <asm/uaccess.h>
23326 +#include <asm/errno.h>
23327 +#include <asm/mman.h>
23328 +#include <net/sock.h>
23329 +#include <linux/file.h>
23330 +#include <linux/fs.h>
23331 +#include <linux/net.h>
23332 +#include <linux/in.h>
23333 +#include <linux/smp_lock.h>
23334 +#include <linux/slab.h>
23335 +#include <linux/types.h>
23336 +#include <linux/sched.h>
23337 +#include <linux/timer.h>
23338 +#include <linux/gracl.h>
23339 +#include <linux/grsecurity.h>
23340 +#include <linux/grinternal.h>
23342 +static struct crash_uid *uid_set;
23343 +static unsigned short uid_used;
23344 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
23345 +extern rwlock_t gr_inode_lock;
23346 +extern struct acl_subject_label *
23347 + lookup_acl_subj_label(const ino_t inode, const dev_t dev,
23348 + struct acl_role_label *role);
23349 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
23352 +gr_init_uidset(void)
23355 + kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
23358 + return uid_set ? 1 : 0;
23362 +gr_free_uidset(void)
23371 +gr_find_uid(const uid_t uid)
23373 + struct crash_uid *tmp = uid_set;
23375 + int low = 0, high = uid_used - 1, mid;
23377 + while (high >= low) {
23378 + mid = (low + high) >> 1;
23379 + buid = tmp[mid].uid;
23391 +static __inline__ void
23392 +gr_insertsort(void)
23394 + unsigned short i, j;
23395 + struct crash_uid index;
23397 + for (i = 1; i < uid_used; i++) {
23398 + index = uid_set[i];
23400 + while ((j > 0) && uid_set[j - 1].uid > index.uid) {
23401 + uid_set[j] = uid_set[j - 1];
23404 + uid_set[j] = index;
23410 +static __inline__ void
23411 +gr_insert_uid(const uid_t uid, const unsigned long expires)
23415 + if (uid_used == GR_UIDTABLE_MAX)
23418 + loc = gr_find_uid(uid);
23421 + uid_set[loc].expires = expires;
23425 + uid_set[uid_used].uid = uid;
23426 + uid_set[uid_used].expires = expires;
23435 +gr_remove_uid(const unsigned short loc)
23437 + unsigned short i;
23439 + for (i = loc + 1; i < uid_used; i++)
23440 + uid_set[i - 1] = uid_set[i];
23448 +gr_check_crash_uid(const uid_t uid)
23453 + if (unlikely(!gr_acl_is_enabled()))
23456 + spin_lock(&gr_uid_lock);
23457 + loc = gr_find_uid(uid);
23462 + if (time_before_eq(uid_set[loc].expires, get_seconds()))
23463 + gr_remove_uid(loc);
23468 + spin_unlock(&gr_uid_lock);
23472 +static __inline__ int
23473 +proc_is_setxid(const struct task_struct *task)
23475 + if (task->uid != task->euid || task->uid != task->suid ||
23476 + task->uid != task->fsuid)
23478 + if (task->gid != task->egid || task->gid != task->sgid ||
23479 + task->gid != task->fsgid)
23484 +static __inline__ int
23485 +gr_fake_force_sig(int sig, struct task_struct *t)
23487 + unsigned long int flags;
23488 + int ret, blocked, ignored;
23489 + struct k_sigaction *action;
23491 + spin_lock_irqsave(&t->sighand->siglock, flags);
23492 + action = &t->sighand->action[sig-1];
23493 + ignored = action->sa.sa_handler == SIG_IGN;
23494 + blocked = sigismember(&t->blocked, sig);
23495 + if (blocked || ignored) {
23496 + action->sa.sa_handler = SIG_DFL;
23498 + sigdelset(&t->blocked, sig);
23499 + recalc_sigpending_and_wake(t);
23502 + ret = specific_send_sig_info(sig, (void*)1L, t);
23503 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
23509 +gr_handle_crash(struct task_struct *task, const int sig)
23511 + struct acl_subject_label *curr;
23512 + struct acl_subject_label *curr2;
23513 + struct task_struct *tsk, *tsk2;
23515 + if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
23518 + if (unlikely(!gr_acl_is_enabled()))
23521 + curr = task->acl;
23523 + if (!(curr->resmask & (1 << GR_CRASH_RES)))
23526 + if (time_before_eq(curr->expires, get_seconds())) {
23527 + curr->expires = 0;
23528 + curr->crashes = 0;
23533 + if (!curr->expires)
23534 + curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
23536 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
23537 + time_after(curr->expires, get_seconds())) {
23538 + if (task->uid && proc_is_setxid(task)) {
23539 + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
23540 + spin_lock(&gr_uid_lock);
23541 + gr_insert_uid(task->uid, curr->expires);
23542 + spin_unlock(&gr_uid_lock);
23543 + curr->expires = 0;
23544 + curr->crashes = 0;
23545 + read_lock(&tasklist_lock);
23546 + do_each_thread(tsk2, tsk) {
23547 + if (tsk != task && tsk->uid == task->uid)
23548 + gr_fake_force_sig(SIGKILL, tsk);
23549 + } while_each_thread(tsk2, tsk);
23550 + read_unlock(&tasklist_lock);
23552 + gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
23553 + read_lock(&tasklist_lock);
23554 + do_each_thread(tsk2, tsk) {
23555 + if (likely(tsk != task)) {
23556 + curr2 = tsk->acl;
23558 + if (curr2->device == curr->device &&
23559 + curr2->inode == curr->inode)
23560 + gr_fake_force_sig(SIGKILL, tsk);
23562 + } while_each_thread(tsk2, tsk);
23563 + read_unlock(&tasklist_lock);
23571 +gr_check_crash_exec(const struct file *filp)
23573 + struct acl_subject_label *curr;
23575 + if (unlikely(!gr_acl_is_enabled()))
23578 + read_lock(&gr_inode_lock);
23579 + curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
23580 + filp->f_dentry->d_inode->i_sb->s_dev,
23582 + read_unlock(&gr_inode_lock);
23584 + if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
23585 + (!curr->crashes && !curr->expires))
23588 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
23589 + time_after(curr->expires, get_seconds()))
23591 + else if (time_before_eq(curr->expires, get_seconds())) {
23592 + curr->crashes = 0;
23593 + curr->expires = 0;
23600 +gr_handle_alertkill(struct task_struct *task)
23602 + struct acl_subject_label *curracl;
23604 + struct task_struct *p, *p2;
23606 + if (unlikely(!gr_acl_is_enabled()))
23609 + curracl = task->acl;
23610 + curr_ip = task->signal->curr_ip;
23612 + if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
23613 + read_lock(&tasklist_lock);
23614 + do_each_thread(p2, p) {
23615 + if (p->signal->curr_ip == curr_ip)
23616 + gr_fake_force_sig(SIGKILL, p);
23617 + } while_each_thread(p2, p);
23618 + read_unlock(&tasklist_lock);
23619 + } else if (curracl->mode & GR_KILLPROC)
23620 + gr_fake_force_sig(SIGKILL, task);
23624 diff -urNp linux-2.6.24.4/grsecurity/gracl_shm.c linux-2.6.24.4/grsecurity/gracl_shm.c
23625 --- linux-2.6.24.4/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
23626 +++ linux-2.6.24.4/grsecurity/gracl_shm.c 2008-03-26 20:21:09.000000000 -0400
23628 +#include <linux/kernel.h>
23629 +#include <linux/mm.h>
23630 +#include <linux/sched.h>
23631 +#include <linux/file.h>
23632 +#include <linux/ipc.h>
23633 +#include <linux/gracl.h>
23634 +#include <linux/grsecurity.h>
23635 +#include <linux/grinternal.h>
23638 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23639 + const time_t shm_createtime, const uid_t cuid, const int shmid)
23641 + struct task_struct *task;
23643 + if (!gr_acl_is_enabled())
23646 + task = find_task_by_pid(shm_cprid);
23648 + if (unlikely(!task))
23649 + task = find_task_by_pid(shm_lapid);
23651 + if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
23652 + (task->pid == shm_lapid)) &&
23653 + (task->acl->mode & GR_PROTSHM) &&
23654 + (task->acl != current->acl))) {
23655 + gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
23661 diff -urNp linux-2.6.24.4/grsecurity/grsec_chdir.c linux-2.6.24.4/grsecurity/grsec_chdir.c
23662 --- linux-2.6.24.4/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
23663 +++ linux-2.6.24.4/grsecurity/grsec_chdir.c 2008-03-26 20:21:09.000000000 -0400
23665 +#include <linux/kernel.h>
23666 +#include <linux/sched.h>
23667 +#include <linux/fs.h>
23668 +#include <linux/file.h>
23669 +#include <linux/grsecurity.h>
23670 +#include <linux/grinternal.h>
23673 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
23675 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
23676 + if ((grsec_enable_chdir && grsec_enable_group &&
23677 + in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
23678 + !grsec_enable_group)) {
23679 + gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
23684 diff -urNp linux-2.6.24.4/grsecurity/grsec_chroot.c linux-2.6.24.4/grsecurity/grsec_chroot.c
23685 --- linux-2.6.24.4/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
23686 +++ linux-2.6.24.4/grsecurity/grsec_chroot.c 2008-03-26 20:21:09.000000000 -0400
23688 +#include <linux/kernel.h>
23689 +#include <linux/module.h>
23690 +#include <linux/sched.h>
23691 +#include <linux/file.h>
23692 +#include <linux/fs.h>
23693 +#include <linux/mount.h>
23694 +#include <linux/types.h>
23695 +#include <linux/pid_namespace.h>
23696 +#include <linux/grsecurity.h>
23697 +#include <linux/grinternal.h>
23700 +gr_handle_chroot_unix(const pid_t pid)
23702 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23703 + struct pid *spid = NULL;
23705 + if (unlikely(!grsec_enable_chroot_unix))
23708 + if (likely(!proc_is_chrooted(current)))
23711 + read_lock(&tasklist_lock);
23713 + spid = find_pid(pid);
23715 + struct task_struct *p;
23716 + p = pid_task(spid, PIDTYPE_PID);
23718 + if (unlikely(!have_same_root(current, p))) {
23720 + read_unlock(&tasklist_lock);
23721 + gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
23726 + read_unlock(&tasklist_lock);
23732 +gr_handle_chroot_nice(void)
23734 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23735 + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
23736 + gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
23744 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
23746 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23747 + if (grsec_enable_chroot_nice && (niceval < task_nice(p))
23748 + && proc_is_chrooted(current)) {
23749 + gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
23757 +gr_handle_chroot_rawio(const struct inode *inode)
23759 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23760 + if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
23761 + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
23768 +gr_pid_is_chrooted(struct task_struct *p)
23770 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
23771 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
23775 + if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
23776 + !have_same_root(current, p)) {
23785 +EXPORT_SYMBOL(gr_pid_is_chrooted);
23787 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
23788 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
23790 + struct dentry *dentry = (struct dentry *)u_dentry;
23791 + struct vfsmount *mnt = (struct vfsmount *)u_mnt;
23792 + struct dentry *realroot;
23793 + struct vfsmount *realrootmnt;
23794 + struct dentry *currentroot;
23795 + struct vfsmount *currentmnt;
23796 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
23799 + read_lock(&reaper->fs->lock);
23800 + realrootmnt = mntget(reaper->fs->rootmnt);
23801 + realroot = dget(reaper->fs->root);
23802 + read_unlock(&reaper->fs->lock);
23804 + read_lock(¤t->fs->lock);
23805 + currentmnt = mntget(current->fs->rootmnt);
23806 + currentroot = dget(current->fs->root);
23807 + read_unlock(¤t->fs->lock);
23809 + spin_lock(&dcache_lock);
23811 + if (unlikely((dentry == realroot && mnt == realrootmnt)
23812 + || (dentry == currentroot && mnt == currentmnt)))
23814 + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
23815 + if (mnt->mnt_parent == mnt)
23817 + dentry = mnt->mnt_mountpoint;
23818 + mnt = mnt->mnt_parent;
23821 + dentry = dentry->d_parent;
23823 + spin_unlock(&dcache_lock);
23825 + dput(currentroot);
23826 + mntput(currentmnt);
23828 + /* access is outside of chroot */
23829 + if (dentry == realroot && mnt == realrootmnt)
23833 + mntput(realrootmnt);
23839 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
23841 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23842 + if (!grsec_enable_chroot_fchdir)
23845 + if (!proc_is_chrooted(current))
23847 + else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
23848 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
23856 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23857 + const time_t shm_createtime)
23859 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23860 + struct pid *pid = NULL;
23861 + time_t starttime;
23863 + if (unlikely(!grsec_enable_chroot_shmat))
23866 + if (likely(!proc_is_chrooted(current)))
23869 + read_lock(&tasklist_lock);
23871 + pid = find_pid(shm_cprid);
23873 + struct task_struct *p;
23874 + p = pid_task(pid, PIDTYPE_PID);
23876 + starttime = p->start_time.tv_sec;
23877 + if (unlikely(!have_same_root(current, p) &&
23878 + time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
23880 + read_unlock(&tasklist_lock);
23881 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
23886 + pid = find_pid(shm_lapid);
23888 + struct task_struct *p;
23889 + p = pid_task(pid, PIDTYPE_PID);
23891 + if (unlikely(!have_same_root(current, p))) {
23893 + read_unlock(&tasklist_lock);
23894 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
23901 + read_unlock(&tasklist_lock);
23907 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
23909 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23910 + if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
23911 + gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
23917 +gr_handle_chroot_mknod(const struct dentry *dentry,
23918 + const struct vfsmount *mnt, const int mode)
23920 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23921 + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
23922 + proc_is_chrooted(current)) {
23923 + gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
23931 +gr_handle_chroot_mount(const struct dentry *dentry,
23932 + const struct vfsmount *mnt, const char *dev_name)
23934 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23935 + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
23936 + gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
23944 +gr_handle_chroot_pivot(void)
23946 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23947 + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
23948 + gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
23956 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
23958 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23959 + if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
23960 + !gr_is_outside_chroot(dentry, mnt)) {
23961 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
23969 +gr_handle_chroot_caps(struct task_struct *task)
23971 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23972 + if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
23973 + task->cap_permitted =
23974 + cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
23975 + task->cap_inheritable =
23976 + cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
23977 + task->cap_effective =
23978 + cap_drop(task->cap_effective, GR_CHROOT_CAPS);
23985 +gr_handle_chroot_sysctl(const int op)
23987 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23988 + if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
23996 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
23998 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23999 + if (grsec_enable_chroot_chdir)
24000 + set_fs_pwd(current->fs, mnt, dentry);
24006 +gr_handle_chroot_chmod(const struct dentry *dentry,
24007 + const struct vfsmount *mnt, const int mode)
24009 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
24010 + if (grsec_enable_chroot_chmod &&
24011 + ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
24012 + proc_is_chrooted(current)) {
24013 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
24020 +#ifdef CONFIG_SECURITY
24021 +EXPORT_SYMBOL(gr_handle_chroot_caps);
24023 diff -urNp linux-2.6.24.4/grsecurity/grsec_disabled.c linux-2.6.24.4/grsecurity/grsec_disabled.c
24024 --- linux-2.6.24.4/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
24025 +++ linux-2.6.24.4/grsecurity/grsec_disabled.c 2008-03-26 20:21:09.000000000 -0400
24027 +#include <linux/kernel.h>
24028 +#include <linux/module.h>
24029 +#include <linux/sched.h>
24030 +#include <linux/file.h>
24031 +#include <linux/fs.h>
24032 +#include <linux/kdev_t.h>
24033 +#include <linux/net.h>
24034 +#include <linux/in.h>
24035 +#include <linux/ip.h>
24036 +#include <linux/skbuff.h>
24037 +#include <linux/sysctl.h>
24039 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
24041 +pax_set_initial_flags(struct linux_binprm *bprm)
24047 +#ifdef CONFIG_SYSCTL
24049 +gr_handle_sysctl(const struct ctl_table * table, const int op)
24056 +gr_acl_is_enabled(void)
24062 +gr_handle_rawio(const struct inode *inode)
24068 +gr_acl_handle_psacct(struct task_struct *task, const long code)
24074 +gr_handle_ptrace(struct task_struct *task, const long request)
24080 +gr_handle_proc_ptrace(struct task_struct *task)
24086 +gr_learn_resource(const struct task_struct *task,
24087 + const int res, const unsigned long wanted, const int gt)
24093 +gr_set_acls(const int type)
24099 +gr_check_hidden_task(const struct task_struct *tsk)
24105 +gr_check_protected_task(const struct task_struct *task)
24111 +gr_copy_label(struct task_struct *tsk)
24117 +gr_set_pax_flags(struct task_struct *task)
24123 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
24129 +gr_handle_delete(const ino_t ino, const dev_t dev)
24135 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
24141 +gr_handle_crash(struct task_struct *task, const int sig)
24147 +gr_check_crash_exec(const struct file *filp)
24153 +gr_check_crash_uid(const uid_t uid)
24159 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
24160 + struct dentry *old_dentry,
24161 + struct dentry *new_dentry,
24162 + struct vfsmount *mnt, const __u8 replace)
24168 +gr_search_socket(const int family, const int type, const int protocol)
24174 +gr_search_connectbind(const int mode, const struct socket *sock,
24175 + const struct sockaddr_in *addr)
24181 +gr_task_is_capable(struct task_struct *task, const int cap)
24187 +gr_is_capable_nolog(const int cap)
24193 +gr_handle_alertkill(struct task_struct *task)
24199 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
24205 +gr_acl_handle_hidden_file(const struct dentry * dentry,
24206 + const struct vfsmount * mnt)
24212 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
24219 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
24225 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
24231 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
24232 + unsigned int *vm_flags)
24238 +gr_acl_handle_truncate(const struct dentry * dentry,
24239 + const struct vfsmount * mnt)
24245 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
24251 +gr_acl_handle_access(const struct dentry * dentry,
24252 + const struct vfsmount * mnt, const int fmode)
24258 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
24265 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
24272 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
24278 +grsecurity_init(void)
24284 +gr_acl_handle_mknod(const struct dentry * new_dentry,
24285 + const struct dentry * parent_dentry,
24286 + const struct vfsmount * parent_mnt,
24293 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
24294 + const struct dentry * parent_dentry,
24295 + const struct vfsmount * parent_mnt)
24301 +gr_acl_handle_symlink(const struct dentry * new_dentry,
24302 + const struct dentry * parent_dentry,
24303 + const struct vfsmount * parent_mnt, const char *from)
24309 +gr_acl_handle_link(const struct dentry * new_dentry,
24310 + const struct dentry * parent_dentry,
24311 + const struct vfsmount * parent_mnt,
24312 + const struct dentry * old_dentry,
24313 + const struct vfsmount * old_mnt, const char *to)
24319 +gr_acl_handle_rename(const struct dentry *new_dentry,
24320 + const struct dentry *parent_dentry,
24321 + const struct vfsmount *parent_mnt,
24322 + const struct dentry *old_dentry,
24323 + const struct inode *old_parent_inode,
24324 + const struct vfsmount *old_mnt, const char *newname)
24330 +gr_acl_handle_filldir(const struct file *file, const char *name,
24331 + const int namelen, const ino_t ino)
24337 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
24338 + const time_t shm_createtime, const uid_t cuid, const int shmid)
24344 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
24350 +gr_search_accept(const struct socket *sock)
24356 +gr_search_listen(const struct socket *sock)
24362 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
24368 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
24374 +gr_acl_handle_creat(const struct dentry * dentry,
24375 + const struct dentry * p_dentry,
24376 + const struct vfsmount * p_mnt, const int fmode,
24383 +gr_acl_handle_exit(void)
24389 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
24395 +gr_set_role_label(const uid_t uid, const gid_t gid)
24401 +gr_acl_handle_procpidmem(const struct task_struct *task)
24407 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
24413 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
24419 +gr_set_kernel_label(struct task_struct *task)
24425 +gr_check_user_change(int real, int effective, int fs)
24431 +gr_check_group_change(int real, int effective, int fs)
24437 +EXPORT_SYMBOL(gr_task_is_capable);
24438 +EXPORT_SYMBOL(gr_is_capable_nolog);
24439 +EXPORT_SYMBOL(gr_learn_resource);
24440 +EXPORT_SYMBOL(gr_set_kernel_label);
24441 +#ifdef CONFIG_SECURITY
24442 +EXPORT_SYMBOL(gr_check_user_change);
24443 +EXPORT_SYMBOL(gr_check_group_change);
24445 diff -urNp linux-2.6.24.4/grsecurity/grsec_exec.c linux-2.6.24.4/grsecurity/grsec_exec.c
24446 --- linux-2.6.24.4/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
24447 +++ linux-2.6.24.4/grsecurity/grsec_exec.c 2008-03-26 20:21:09.000000000 -0400
24449 +#include <linux/kernel.h>
24450 +#include <linux/sched.h>
24451 +#include <linux/file.h>
24452 +#include <linux/binfmts.h>
24453 +#include <linux/smp_lock.h>
24454 +#include <linux/fs.h>
24455 +#include <linux/types.h>
24456 +#include <linux/grdefs.h>
24457 +#include <linux/grinternal.h>
24458 +#include <linux/capability.h>
24460 +#include <asm/uaccess.h>
24462 +#ifdef CONFIG_GRKERNSEC_EXECLOG
24463 +static char gr_exec_arg_buf[132];
24464 +static DECLARE_MUTEX(gr_exec_arg_sem);
24468 +gr_handle_nproc(void)
24470 +#ifdef CONFIG_GRKERNSEC_EXECVE
24471 + if (grsec_enable_execve && current->user &&
24472 + (atomic_read(¤t->user->processes) >
24473 + current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
24474 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
24475 + gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
24483 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
24485 +#ifdef CONFIG_GRKERNSEC_EXECLOG
24486 + char *grarg = gr_exec_arg_buf;
24487 + unsigned int i, x, execlen = 0;
24490 + if (!((grsec_enable_execlog && grsec_enable_group &&
24491 + in_group_p(grsec_audit_gid))
24492 + || (grsec_enable_execlog && !grsec_enable_group)))
24495 + down(&gr_exec_arg_sem);
24496 + memset(grarg, 0, sizeof(gr_exec_arg_buf));
24498 + if (unlikely(argv == NULL))
24501 + for (i = 0; i < bprm->argc && execlen < 128; i++) {
24502 + const char __user *p;
24503 + unsigned int len;
24505 + if (copy_from_user(&p, argv + i, sizeof(p)))
24509 + len = strnlen_user(p, 128 - execlen);
24510 + if (len > 128 - execlen)
24511 + len = 128 - execlen;
24512 + else if (len > 0)
24514 + if (copy_from_user(grarg + execlen, p, len))
24517 + /* rewrite unprintable characters */
24518 + for (x = 0; x < len; x++) {
24519 + c = *(grarg + execlen + x);
24520 + if (c < 32 || c > 126)
24521 + *(grarg + execlen + x) = ' ';
24525 + *(grarg + execlen) = ' ';
24526 + *(grarg + execlen + 1) = '\0';
24531 + gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
24532 + bprm->file->f_vfsmnt, grarg);
24533 + up(&gr_exec_arg_sem);
24537 diff -urNp linux-2.6.24.4/grsecurity/grsec_fifo.c linux-2.6.24.4/grsecurity/grsec_fifo.c
24538 --- linux-2.6.24.4/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
24539 +++ linux-2.6.24.4/grsecurity/grsec_fifo.c 2008-03-26 20:21:09.000000000 -0400
24541 +#include <linux/kernel.h>
24542 +#include <linux/sched.h>
24543 +#include <linux/fs.h>
24544 +#include <linux/file.h>
24545 +#include <linux/grinternal.h>
24548 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
24549 + const struct dentry *dir, const int flag, const int acc_mode)
24551 +#ifdef CONFIG_GRKERNSEC_FIFO
24552 + if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
24553 + !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
24554 + (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
24555 + (current->fsuid != dentry->d_inode->i_uid)) {
24556 + if (!generic_permission(dentry->d_inode, acc_mode, NULL))
24557 + gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
24563 diff -urNp linux-2.6.24.4/grsecurity/grsec_fork.c linux-2.6.24.4/grsecurity/grsec_fork.c
24564 --- linux-2.6.24.4/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
24565 +++ linux-2.6.24.4/grsecurity/grsec_fork.c 2008-03-26 20:21:09.000000000 -0400
24567 +#include <linux/kernel.h>
24568 +#include <linux/sched.h>
24569 +#include <linux/grsecurity.h>
24570 +#include <linux/grinternal.h>
24571 +#include <linux/errno.h>
24574 +gr_log_forkfail(const int retval)
24576 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
24577 + if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
24578 + gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
24582 diff -urNp linux-2.6.24.4/grsecurity/grsec_init.c linux-2.6.24.4/grsecurity/grsec_init.c
24583 --- linux-2.6.24.4/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
24584 +++ linux-2.6.24.4/grsecurity/grsec_init.c 2008-03-26 20:21:09.000000000 -0400
24586 +#include <linux/kernel.h>
24587 +#include <linux/sched.h>
24588 +#include <linux/mm.h>
24589 +#include <linux/smp_lock.h>
24590 +#include <linux/gracl.h>
24591 +#include <linux/slab.h>
24592 +#include <linux/vmalloc.h>
24593 +#include <linux/percpu.h>
24595 +int grsec_enable_link;
24596 +int grsec_enable_dmesg;
24597 +int grsec_enable_fifo;
24598 +int grsec_enable_execve;
24599 +int grsec_enable_execlog;
24600 +int grsec_enable_signal;
24601 +int grsec_enable_forkfail;
24602 +int grsec_enable_time;
24603 +int grsec_enable_audit_textrel;
24604 +int grsec_enable_group;
24605 +int grsec_audit_gid;
24606 +int grsec_enable_chdir;
24607 +int grsec_enable_audit_ipc;
24608 +int grsec_enable_mount;
24609 +int grsec_enable_chroot_findtask;
24610 +int grsec_enable_chroot_mount;
24611 +int grsec_enable_chroot_shmat;
24612 +int grsec_enable_chroot_fchdir;
24613 +int grsec_enable_chroot_double;
24614 +int grsec_enable_chroot_pivot;
24615 +int grsec_enable_chroot_chdir;
24616 +int grsec_enable_chroot_chmod;
24617 +int grsec_enable_chroot_mknod;
24618 +int grsec_enable_chroot_nice;
24619 +int grsec_enable_chroot_execlog;
24620 +int grsec_enable_chroot_caps;
24621 +int grsec_enable_chroot_sysctl;
24622 +int grsec_enable_chroot_unix;
24623 +int grsec_enable_tpe;
24624 +int grsec_tpe_gid;
24625 +int grsec_enable_tpe_all;
24626 +int grsec_enable_socket_all;
24627 +int grsec_socket_all_gid;
24628 +int grsec_enable_socket_client;
24629 +int grsec_socket_client_gid;
24630 +int grsec_enable_socket_server;
24631 +int grsec_socket_server_gid;
24632 +int grsec_resource_logging;
24635 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
24636 +unsigned long grsec_alert_wtime = 0;
24637 +unsigned long grsec_alert_fyet = 0;
24639 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
24641 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
24643 +char *gr_shared_page[4];
24645 +char *gr_alert_log_fmt;
24646 +char *gr_audit_log_fmt;
24647 +char *gr_alert_log_buf;
24648 +char *gr_audit_log_buf;
24650 +extern struct gr_arg *gr_usermode;
24651 +extern unsigned char *gr_system_salt;
24652 +extern unsigned char *gr_system_sum;
24655 +grsecurity_init(void)
24658 + /* create the per-cpu shared pages */
24660 + for (j = 0; j < 4; j++) {
24661 + gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
24662 + if (gr_shared_page[j] == NULL) {
24663 + panic("Unable to allocate grsecurity shared page");
24668 + /* allocate log buffers */
24669 + gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
24670 + if (!gr_alert_log_fmt) {
24671 + panic("Unable to allocate grsecurity alert log format buffer");
24674 + gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
24675 + if (!gr_audit_log_fmt) {
24676 + panic("Unable to allocate grsecurity audit log format buffer");
24679 + gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
24680 + if (!gr_alert_log_buf) {
24681 + panic("Unable to allocate grsecurity alert log buffer");
24684 + gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
24685 + if (!gr_audit_log_buf) {
24686 + panic("Unable to allocate grsecurity audit log buffer");
24690 + /* allocate memory for authentication structure */
24691 + gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
24692 + gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
24693 + gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
24695 + if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
24696 + panic("Unable to allocate grsecurity authentication structure");
24700 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
24701 +#ifndef CONFIG_GRKERNSEC_SYSCTL
24704 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
24705 + grsec_enable_audit_textrel = 1;
24707 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
24708 + grsec_enable_group = 1;
24709 + grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
24711 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
24712 + grsec_enable_chdir = 1;
24714 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24715 + grsec_enable_audit_ipc = 1;
24717 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24718 + grsec_enable_mount = 1;
24720 +#ifdef CONFIG_GRKERNSEC_LINK
24721 + grsec_enable_link = 1;
24723 +#ifdef CONFIG_GRKERNSEC_DMESG
24724 + grsec_enable_dmesg = 1;
24726 +#ifdef CONFIG_GRKERNSEC_FIFO
24727 + grsec_enable_fifo = 1;
24729 +#ifdef CONFIG_GRKERNSEC_EXECVE
24730 + grsec_enable_execve = 1;
24732 +#ifdef CONFIG_GRKERNSEC_EXECLOG
24733 + grsec_enable_execlog = 1;
24735 +#ifdef CONFIG_GRKERNSEC_SIGNAL
24736 + grsec_enable_signal = 1;
24738 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
24739 + grsec_enable_forkfail = 1;
24741 +#ifdef CONFIG_GRKERNSEC_TIME
24742 + grsec_enable_time = 1;
24744 +#ifdef CONFIG_GRKERNSEC_RESLOG
24745 + grsec_resource_logging = 1;
24747 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
24748 + grsec_enable_chroot_findtask = 1;
24750 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
24751 + grsec_enable_chroot_unix = 1;
24753 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
24754 + grsec_enable_chroot_mount = 1;
24756 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
24757 + grsec_enable_chroot_fchdir = 1;
24759 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
24760 + grsec_enable_chroot_shmat = 1;
24762 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
24763 + grsec_enable_chroot_double = 1;
24765 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
24766 + grsec_enable_chroot_pivot = 1;
24768 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
24769 + grsec_enable_chroot_chdir = 1;
24771 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
24772 + grsec_enable_chroot_chmod = 1;
24774 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
24775 + grsec_enable_chroot_mknod = 1;
24777 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
24778 + grsec_enable_chroot_nice = 1;
24780 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
24781 + grsec_enable_chroot_execlog = 1;
24783 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
24784 + grsec_enable_chroot_caps = 1;
24786 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
24787 + grsec_enable_chroot_sysctl = 1;
24789 +#ifdef CONFIG_GRKERNSEC_TPE
24790 + grsec_enable_tpe = 1;
24791 + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
24792 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
24793 + grsec_enable_tpe_all = 1;
24796 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24797 + grsec_enable_socket_all = 1;
24798 + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
24800 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24801 + grsec_enable_socket_client = 1;
24802 + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
24804 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24805 + grsec_enable_socket_server = 1;
24806 + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
24812 diff -urNp linux-2.6.24.4/grsecurity/grsec_ipc.c linux-2.6.24.4/grsecurity/grsec_ipc.c
24813 --- linux-2.6.24.4/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
24814 +++ linux-2.6.24.4/grsecurity/grsec_ipc.c 2008-03-26 20:21:09.000000000 -0400
24816 +#include <linux/kernel.h>
24817 +#include <linux/sched.h>
24818 +#include <linux/types.h>
24819 +#include <linux/ipc.h>
24820 +#include <linux/grsecurity.h>
24821 +#include <linux/grinternal.h>
24824 +gr_log_msgget(const int ret, const int msgflg)
24826 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24827 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24828 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24829 + !grsec_enable_group)) && (ret >= 0)
24830 + && (msgflg & IPC_CREAT))
24831 + gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
24837 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
24839 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24840 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24841 + grsec_enable_audit_ipc) ||
24842 + (grsec_enable_audit_ipc && !grsec_enable_group))
24843 + gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
24849 +gr_log_semget(const int err, const int semflg)
24851 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24852 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24853 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24854 + !grsec_enable_group)) && (err >= 0)
24855 + && (semflg & IPC_CREAT))
24856 + gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
24862 +gr_log_semrm(const uid_t uid, const uid_t cuid)
24864 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24865 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24866 + grsec_enable_audit_ipc) ||
24867 + (grsec_enable_audit_ipc && !grsec_enable_group))
24868 + gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
24874 +gr_log_shmget(const int err, const int shmflg, const size_t size)
24876 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24877 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24878 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24879 + !grsec_enable_group)) && (err >= 0)
24880 + && (shmflg & IPC_CREAT))
24881 + gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
24887 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
24889 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24890 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24891 + grsec_enable_audit_ipc) ||
24892 + (grsec_enable_audit_ipc && !grsec_enable_group))
24893 + gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
24897 diff -urNp linux-2.6.24.4/grsecurity/grsec_link.c linux-2.6.24.4/grsecurity/grsec_link.c
24898 --- linux-2.6.24.4/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
24899 +++ linux-2.6.24.4/grsecurity/grsec_link.c 2008-03-26 20:21:09.000000000 -0400
24901 +#include <linux/kernel.h>
24902 +#include <linux/sched.h>
24903 +#include <linux/fs.h>
24904 +#include <linux/file.h>
24905 +#include <linux/grinternal.h>
24908 +gr_handle_follow_link(const struct inode *parent,
24909 + const struct inode *inode,
24910 + const struct dentry *dentry, const struct vfsmount *mnt)
24912 +#ifdef CONFIG_GRKERNSEC_LINK
24913 + if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
24914 + (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
24915 + (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
24916 + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
24924 +gr_handle_hardlink(const struct dentry *dentry,
24925 + const struct vfsmount *mnt,
24926 + struct inode *inode, const int mode, const char *to)
24928 +#ifdef CONFIG_GRKERNSEC_LINK
24929 + if (grsec_enable_link && current->fsuid != inode->i_uid &&
24930 + (!S_ISREG(mode) || (mode & S_ISUID) ||
24931 + ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
24932 + (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
24933 + !capable(CAP_FOWNER) && current->uid) {
24934 + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
24940 diff -urNp linux-2.6.24.4/grsecurity/grsec_log.c linux-2.6.24.4/grsecurity/grsec_log.c
24941 --- linux-2.6.24.4/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
24942 +++ linux-2.6.24.4/grsecurity/grsec_log.c 2008-03-26 20:21:09.000000000 -0400
24944 +#include <linux/kernel.h>
24945 +#include <linux/sched.h>
24946 +#include <linux/file.h>
24947 +#include <linux/tty.h>
24948 +#include <linux/fs.h>
24949 +#include <linux/grinternal.h>
24951 +#define BEGIN_LOCKS(x) \
24952 + read_lock(&tasklist_lock); \
24953 + read_lock(&grsec_exec_file_lock); \
24954 + if (x != GR_DO_AUDIT) \
24955 + spin_lock(&grsec_alert_lock); \
24957 + spin_lock(&grsec_audit_lock)
24959 +#define END_LOCKS(x) \
24960 + if (x != GR_DO_AUDIT) \
24961 + spin_unlock(&grsec_alert_lock); \
24963 + spin_unlock(&grsec_audit_lock); \
24964 + read_unlock(&grsec_exec_file_lock); \
24965 + read_unlock(&tasklist_lock); \
24966 + if (x == GR_DONT_AUDIT) \
24967 + gr_handle_alertkill(current)
24974 +extern char *gr_alert_log_fmt;
24975 +extern char *gr_audit_log_fmt;
24976 +extern char *gr_alert_log_buf;
24977 +extern char *gr_audit_log_buf;
24979 +static int gr_log_start(int audit)
24981 + char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
24982 + char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
24983 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24985 + if (audit == GR_DO_AUDIT)
24988 + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
24989 + grsec_alert_wtime = jiffies;
24990 + grsec_alert_fyet = 0;
24991 + } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
24992 + grsec_alert_fyet++;
24993 + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
24994 + grsec_alert_wtime = jiffies;
24995 + grsec_alert_fyet++;
24996 + printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
24998 + } else return FLOODING;
25001 + memset(buf, 0, PAGE_SIZE);
25002 + if (current->signal->curr_ip && gr_acl_is_enabled()) {
25003 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
25004 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
25005 + } else if (current->signal->curr_ip) {
25006 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
25007 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
25008 + } else if (gr_acl_is_enabled()) {
25009 + sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
25010 + snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
25012 + sprintf(fmt, "%s%s", loglevel, "grsec: ");
25013 + strcpy(buf, fmt);
25016 + return NO_FLOODING;
25019 +static void gr_log_middle(int audit, const char *msg, va_list ap)
25021 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
25022 + unsigned int len = strlen(buf);
25024 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
25029 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
25031 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
25032 + unsigned int len = strlen(buf);
25035 + va_start(ap, msg);
25036 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
25042 +static void gr_log_end(int audit)
25044 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
25045 + unsigned int len = strlen(buf);
25047 + snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
25048 + printk("%s\n", buf);
25053 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
25056 + char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
25057 + char *str1, *str2, *str3;
25059 + unsigned long ulong1, ulong2;
25060 + struct dentry *dentry;
25061 + struct vfsmount *mnt;
25062 + struct file *file;
25063 + struct task_struct *task;
25066 + BEGIN_LOCKS(audit);
25067 + logtype = gr_log_start(audit);
25068 + if (logtype == FLOODING) {
25069 + END_LOCKS(audit);
25072 + va_start(ap, argtypes);
25073 + switch (argtypes) {
25074 + case GR_TTYSNIFF:
25075 + task = va_arg(ap, struct task_struct *);
25076 + 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);
25078 + case GR_SYSCTL_HIDDEN:
25079 + str1 = va_arg(ap, char *);
25080 + gr_log_middle_varargs(audit, msg, result, str1);
25083 + dentry = va_arg(ap, struct dentry *);
25084 + mnt = va_arg(ap, struct vfsmount *);
25085 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
25087 + case GR_RBAC_STR:
25088 + dentry = va_arg(ap, struct dentry *);
25089 + mnt = va_arg(ap, struct vfsmount *);
25090 + str1 = va_arg(ap, char *);
25091 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
25093 + case GR_STR_RBAC:
25094 + str1 = va_arg(ap, char *);
25095 + dentry = va_arg(ap, struct dentry *);
25096 + mnt = va_arg(ap, struct vfsmount *);
25097 + gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
25099 + case GR_RBAC_MODE2:
25100 + dentry = va_arg(ap, struct dentry *);
25101 + mnt = va_arg(ap, struct vfsmount *);
25102 + str1 = va_arg(ap, char *);
25103 + str2 = va_arg(ap, char *);
25104 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
25106 + case GR_RBAC_MODE3:
25107 + dentry = va_arg(ap, struct dentry *);
25108 + mnt = va_arg(ap, struct vfsmount *);
25109 + str1 = va_arg(ap, char *);
25110 + str2 = va_arg(ap, char *);
25111 + str3 = va_arg(ap, char *);
25112 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
25114 + case GR_FILENAME:
25115 + dentry = va_arg(ap, struct dentry *);
25116 + mnt = va_arg(ap, struct vfsmount *);
25117 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
25119 + case GR_STR_FILENAME:
25120 + str1 = va_arg(ap, char *);
25121 + dentry = va_arg(ap, struct dentry *);
25122 + mnt = va_arg(ap, struct vfsmount *);
25123 + gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
25125 + case GR_FILENAME_STR:
25126 + dentry = va_arg(ap, struct dentry *);
25127 + mnt = va_arg(ap, struct vfsmount *);
25128 + str1 = va_arg(ap, char *);
25129 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
25131 + case GR_FILENAME_TWO_INT:
25132 + dentry = va_arg(ap, struct dentry *);
25133 + mnt = va_arg(ap, struct vfsmount *);
25134 + num1 = va_arg(ap, int);
25135 + num2 = va_arg(ap, int);
25136 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
25138 + case GR_FILENAME_TWO_INT_STR:
25139 + dentry = va_arg(ap, struct dentry *);
25140 + mnt = va_arg(ap, struct vfsmount *);
25141 + num1 = va_arg(ap, int);
25142 + num2 = va_arg(ap, int);
25143 + str1 = va_arg(ap, char *);
25144 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
25147 + file = va_arg(ap, struct file *);
25148 + ulong1 = va_arg(ap, unsigned long);
25149 + ulong2 = va_arg(ap, unsigned long);
25150 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
25153 + task = va_arg(ap, struct task_struct *);
25154 + gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt) : "(none)", task->comm, task->pid);
25156 + case GR_RESOURCE:
25157 + task = va_arg(ap, struct task_struct *);
25158 + ulong1 = va_arg(ap, unsigned long);
25159 + str1 = va_arg(ap, char *);
25160 + ulong2 = va_arg(ap, unsigned long);
25161 + gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
25164 + task = va_arg(ap, struct task_struct *);
25165 + str1 = va_arg(ap, char *);
25166 + gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
25169 + task = va_arg(ap, struct task_struct *);
25170 + num1 = va_arg(ap, int);
25171 + gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
25174 + task = va_arg(ap, struct task_struct *);
25175 + ulong1 = va_arg(ap, unsigned long);
25176 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, task->uid, ulong1);
25179 + task = va_arg(ap, struct task_struct *);
25180 + ulong1 = va_arg(ap, unsigned long);
25181 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, ulong1);
25185 + unsigned int wday, cday;
25189 + char cur_tty[64] = { 0 };
25190 + char parent_tty[64] = { 0 };
25192 + task = va_arg(ap, struct task_struct *);
25193 + wday = va_arg(ap, unsigned int);
25194 + cday = va_arg(ap, unsigned int);
25195 + whr = va_arg(ap, int);
25196 + chr = va_arg(ap, int);
25197 + wmin = va_arg(ap, int);
25198 + cmin = va_arg(ap, int);
25199 + wsec = va_arg(ap, int);
25200 + csec = va_arg(ap, int);
25201 + ulong1 = va_arg(ap, unsigned long);
25203 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, NIPQUAD(task->signal->curr_ip), tty_name(task->signal->tty, cur_tty), task->uid, task->euid, task->gid, task->egid, wday, whr, wmin, wsec, cday, chr, cmin, csec, (task->flags & PF_SIGNALED) ? "killed by signal" : "exited", ulong1, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, NIPQUAD(task->parent->signal->curr_ip), tty_name(task->parent->signal->tty, parent_tty), task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
25207 + gr_log_middle(audit, msg, ap);
25210 + gr_log_end(audit);
25211 + END_LOCKS(audit);
25213 diff -urNp linux-2.6.24.4/grsecurity/grsec_mem.c linux-2.6.24.4/grsecurity/grsec_mem.c
25214 --- linux-2.6.24.4/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
25215 +++ linux-2.6.24.4/grsecurity/grsec_mem.c 2008-03-26 20:21:09.000000000 -0400
25217 +#include <linux/kernel.h>
25218 +#include <linux/sched.h>
25219 +#include <linux/mm.h>
25220 +#include <linux/mman.h>
25221 +#include <linux/grinternal.h>
25224 +gr_handle_ioperm(void)
25226 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
25231 +gr_handle_iopl(void)
25233 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
25238 +gr_handle_mem_write(void)
25240 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
25245 +gr_handle_kmem_write(void)
25247 + gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
25252 +gr_handle_open_port(void)
25254 + gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
25259 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
25261 + unsigned long start, end;
25264 + end = start + vma->vm_end - vma->vm_start;
25266 + if (start > end) {
25267 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
25271 + /* allowed ranges : ISA I/O BIOS */
25272 + if ((start >= __pa(high_memory))
25274 + || (start >= 0x000a0000 && end <= 0x00100000)
25275 + || (start >= 0x00000000 && end <= 0x00001000)
25280 + if (vma->vm_flags & VM_WRITE) {
25281 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
25284 + vma->vm_flags &= ~VM_MAYWRITE;
25288 diff -urNp linux-2.6.24.4/grsecurity/grsec_mount.c linux-2.6.24.4/grsecurity/grsec_mount.c
25289 --- linux-2.6.24.4/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
25290 +++ linux-2.6.24.4/grsecurity/grsec_mount.c 2008-03-26 20:21:09.000000000 -0400
25292 +#include <linux/kernel.h>
25293 +#include <linux/sched.h>
25294 +#include <linux/grsecurity.h>
25295 +#include <linux/grinternal.h>
25298 +gr_log_remount(const char *devname, const int retval)
25300 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25301 + if (grsec_enable_mount && (retval >= 0))
25302 + gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
25308 +gr_log_unmount(const char *devname, const int retval)
25310 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25311 + if (grsec_enable_mount && (retval >= 0))
25312 + gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
25318 +gr_log_mount(const char *from, const char *to, const int retval)
25320 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25321 + if (grsec_enable_mount && (retval >= 0))
25322 + gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
25326 diff -urNp linux-2.6.24.4/grsecurity/grsec_sig.c linux-2.6.24.4/grsecurity/grsec_sig.c
25327 --- linux-2.6.24.4/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
25328 +++ linux-2.6.24.4/grsecurity/grsec_sig.c 2008-03-26 20:21:09.000000000 -0400
25330 +#include <linux/kernel.h>
25331 +#include <linux/sched.h>
25332 +#include <linux/delay.h>
25333 +#include <linux/grsecurity.h>
25334 +#include <linux/grinternal.h>
25337 +gr_log_signal(const int sig, const struct task_struct *t)
25339 +#ifdef CONFIG_GRKERNSEC_SIGNAL
25340 + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
25341 + (sig == SIGABRT) || (sig == SIGBUS))) {
25342 + if (t->pid == current->pid) {
25343 + gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
25345 + gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
25353 +gr_handle_signal(const struct task_struct *p, const int sig)
25355 +#ifdef CONFIG_GRKERNSEC
25356 + if (current->pid > 1 && gr_check_protected_task(p)) {
25357 + gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
25359 + } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
25366 +void gr_handle_brute_attach(struct task_struct *p)
25368 +#ifdef CONFIG_GRKERNSEC_BRUTE
25369 + read_lock(&tasklist_lock);
25370 + read_lock(&grsec_exec_file_lock);
25371 + if (p->parent && p->parent->exec_file == p->exec_file)
25372 + p->parent->brute = 1;
25373 + read_unlock(&grsec_exec_file_lock);
25374 + read_unlock(&tasklist_lock);
25379 +void gr_handle_brute_check(void)
25381 +#ifdef CONFIG_GRKERNSEC_BRUTE
25382 + if (current->brute)
25383 + msleep(30 * 1000);
25388 diff -urNp linux-2.6.24.4/grsecurity/grsec_sock.c linux-2.6.24.4/grsecurity/grsec_sock.c
25389 --- linux-2.6.24.4/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
25390 +++ linux-2.6.24.4/grsecurity/grsec_sock.c 2008-03-26 20:21:09.000000000 -0400
25392 +#include <linux/kernel.h>
25393 +#include <linux/module.h>
25394 +#include <linux/sched.h>
25395 +#include <linux/file.h>
25396 +#include <linux/net.h>
25397 +#include <linux/in.h>
25398 +#include <linux/ip.h>
25399 +#include <net/sock.h>
25400 +#include <net/inet_sock.h>
25401 +#include <linux/grsecurity.h>
25402 +#include <linux/grinternal.h>
25403 +#include <linux/gracl.h>
25405 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
25406 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
25407 +EXPORT_SYMBOL(udp_v4_lookup);
25410 +__u32 gr_cap_rtnetlink(struct sock *sock);
25411 +EXPORT_SYMBOL(gr_cap_rtnetlink);
25413 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
25414 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
25416 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
25417 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
25419 +#ifdef CONFIG_UNIX_MODULE
25420 +EXPORT_SYMBOL(gr_acl_handle_unix);
25421 +EXPORT_SYMBOL(gr_acl_handle_mknod);
25422 +EXPORT_SYMBOL(gr_handle_chroot_unix);
25423 +EXPORT_SYMBOL(gr_handle_create);
25426 +#ifdef CONFIG_GRKERNSEC
25427 +#define gr_conn_table_size 32749
25428 +struct conn_table_entry {
25429 + struct conn_table_entry *next;
25430 + struct signal_struct *sig;
25433 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
25434 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
25436 +extern const char * gr_socktype_to_name(unsigned char type);
25437 +extern const char * gr_proto_to_name(unsigned char proto);
25439 +static __inline__ int
25440 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
25442 + return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
25445 +static __inline__ int
25446 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
25447 + __u16 sport, __u16 dport)
25449 + if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
25450 + sig->gr_sport == sport && sig->gr_dport == dport))
25456 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
25458 + struct conn_table_entry **match;
25459 + unsigned int index;
25461 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
25462 + sig->gr_sport, sig->gr_dport,
25463 + gr_conn_table_size);
25465 + newent->sig = sig;
25467 + match = &gr_conn_table[index];
25468 + newent->next = *match;
25474 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
25476 + struct conn_table_entry *match, *last = NULL;
25477 + unsigned int index;
25479 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
25480 + sig->gr_sport, sig->gr_dport,
25481 + gr_conn_table_size);
25483 + match = gr_conn_table[index];
25484 + while (match && !conn_match(match->sig,
25485 + sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
25486 + sig->gr_dport)) {
25488 + match = match->next;
25493 + last->next = match->next;
25495 + gr_conn_table[index] = NULL;
25502 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
25503 + __u16 sport, __u16 dport)
25505 + struct conn_table_entry *match;
25506 + unsigned int index;
25508 + index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
25510 + match = gr_conn_table[index];
25511 + while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
25512 + match = match->next;
25515 + return match->sig;
25522 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
25524 +#ifdef CONFIG_GRKERNSEC
25525 + struct signal_struct *sig = task->signal;
25526 + struct conn_table_entry *newent;
25528 + newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
25529 + if (newent == NULL)
25531 + /* no bh lock needed since we are called with bh disabled */
25532 + spin_lock(&gr_conn_table_lock);
25533 + gr_del_task_from_ip_table_nolock(sig);
25534 + sig->gr_saddr = inet->rcv_saddr;
25535 + sig->gr_daddr = inet->daddr;
25536 + sig->gr_sport = inet->sport;
25537 + sig->gr_dport = inet->dport;
25538 + gr_add_to_task_ip_table_nolock(sig, newent);
25539 + spin_unlock(&gr_conn_table_lock);
25544 +void gr_del_task_from_ip_table(struct task_struct *task)
25546 +#ifdef CONFIG_GRKERNSEC
25547 + spin_lock(&gr_conn_table_lock);
25548 + gr_del_task_from_ip_table_nolock(task->signal);
25549 + spin_unlock(&gr_conn_table_lock);
25555 +gr_attach_curr_ip(const struct sock *sk)
25557 +#ifdef CONFIG_GRKERNSEC
25558 + struct signal_struct *p, *set;
25559 + const struct inet_sock *inet = inet_sk(sk);
25561 + if (unlikely(sk->sk_protocol != IPPROTO_TCP))
25564 + set = current->signal;
25566 + spin_lock_bh(&gr_conn_table_lock);
25567 + p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
25568 + inet->dport, inet->sport);
25569 + if (unlikely(p != NULL)) {
25570 + set->curr_ip = p->curr_ip;
25571 + set->used_accept = 1;
25572 + gr_del_task_from_ip_table_nolock(p);
25573 + spin_unlock_bh(&gr_conn_table_lock);
25576 + spin_unlock_bh(&gr_conn_table_lock);
25578 + set->curr_ip = inet->daddr;
25579 + set->used_accept = 1;
25585 +gr_handle_sock_all(const int family, const int type, const int protocol)
25587 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
25588 + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
25589 + (family != AF_UNIX) && (family != AF_LOCAL)) {
25590 + gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
25598 +gr_handle_sock_server(const struct sockaddr *sck)
25600 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
25601 + if (grsec_enable_socket_server &&
25602 + in_group_p(grsec_socket_server_gid) &&
25603 + sck && (sck->sa_family != AF_UNIX) &&
25604 + (sck->sa_family != AF_LOCAL)) {
25605 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
25613 +gr_handle_sock_server_other(const struct sock *sck)
25615 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
25616 + if (grsec_enable_socket_server &&
25617 + in_group_p(grsec_socket_server_gid) &&
25618 + sck && (sck->sk_family != AF_UNIX) &&
25619 + (sck->sk_family != AF_LOCAL)) {
25620 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
25628 +gr_handle_sock_client(const struct sockaddr *sck)
25630 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
25631 + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
25632 + sck && (sck->sa_family != AF_UNIX) &&
25633 + (sck->sa_family != AF_LOCAL)) {
25634 + gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
25642 +gr_cap_rtnetlink(struct sock *sock)
25644 +#ifdef CONFIG_GRKERNSEC
25645 + if (!gr_acl_is_enabled())
25646 + return current->cap_effective;
25647 + else if (sock->sk_protocol == NETLINK_ISCSI &&
25648 + cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
25649 + gr_task_is_capable(current, CAP_SYS_ADMIN))
25650 + return current->cap_effective;
25651 + else if (sock->sk_protocol == NETLINK_AUDIT &&
25652 + cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
25653 + gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
25654 + cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
25655 + gr_task_is_capable(current, CAP_AUDIT_CONTROL))
25656 + return current->cap_effective;
25657 + else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
25658 + gr_task_is_capable(current, CAP_NET_ADMIN))
25659 + return current->cap_effective;
25663 + return current->cap_effective;
25666 diff -urNp linux-2.6.24.4/grsecurity/grsec_sysctl.c linux-2.6.24.4/grsecurity/grsec_sysctl.c
25667 --- linux-2.6.24.4/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
25668 +++ linux-2.6.24.4/grsecurity/grsec_sysctl.c 2008-03-26 20:21:09.000000000 -0400
25670 +#include <linux/kernel.h>
25671 +#include <linux/sched.h>
25672 +#include <linux/sysctl.h>
25673 +#include <linux/grsecurity.h>
25674 +#include <linux/grinternal.h>
25676 +#ifdef CONFIG_GRKERNSEC_MODSTOP
25677 +int grsec_modstop;
25681 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
25683 +#ifdef CONFIG_GRKERNSEC_SYSCTL
25684 + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
25685 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
25689 +#ifdef CONFIG_GRKERNSEC_MODSTOP
25690 + if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
25691 + grsec_modstop && (op & 002)) {
25692 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
25699 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
25700 +ctl_table grsecurity_table[] = {
25701 +#ifdef CONFIG_GRKERNSEC_SYSCTL
25702 +#ifdef CONFIG_GRKERNSEC_LINK
25704 + .ctl_name = CTL_UNNUMBERED,
25705 + .procname = "linking_restrictions",
25706 + .data = &grsec_enable_link,
25707 + .maxlen = sizeof(int),
25709 + .proc_handler = &proc_dointvec,
25712 +#ifdef CONFIG_GRKERNSEC_FIFO
25714 + .ctl_name = CTL_UNNUMBERED,
25715 + .procname = "fifo_restrictions",
25716 + .data = &grsec_enable_fifo,
25717 + .maxlen = sizeof(int),
25719 + .proc_handler = &proc_dointvec,
25722 +#ifdef CONFIG_GRKERNSEC_EXECVE
25724 + .ctl_name = CTL_UNNUMBERED,
25725 + .procname = "execve_limiting",
25726 + .data = &grsec_enable_execve,
25727 + .maxlen = sizeof(int),
25729 + .proc_handler = &proc_dointvec,
25732 +#ifdef CONFIG_GRKERNSEC_EXECLOG
25734 + .ctl_name = CTL_UNNUMBERED,
25735 + .procname = "exec_logging",
25736 + .data = &grsec_enable_execlog,
25737 + .maxlen = sizeof(int),
25739 + .proc_handler = &proc_dointvec,
25742 +#ifdef CONFIG_GRKERNSEC_SIGNAL
25744 + .ctl_name = CTL_UNNUMBERED,
25745 + .procname = "signal_logging",
25746 + .data = &grsec_enable_signal,
25747 + .maxlen = sizeof(int),
25749 + .proc_handler = &proc_dointvec,
25752 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
25754 + .ctl_name = CTL_UNNUMBERED,
25755 + .procname = "forkfail_logging",
25756 + .data = &grsec_enable_forkfail,
25757 + .maxlen = sizeof(int),
25759 + .proc_handler = &proc_dointvec,
25762 +#ifdef CONFIG_GRKERNSEC_TIME
25764 + .ctl_name = CTL_UNNUMBERED,
25765 + .procname = "timechange_logging",
25766 + .data = &grsec_enable_time,
25767 + .maxlen = sizeof(int),
25769 + .proc_handler = &proc_dointvec,
25772 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
25774 + .ctl_name = CTL_UNNUMBERED,
25775 + .procname = "chroot_deny_shmat",
25776 + .data = &grsec_enable_chroot_shmat,
25777 + .maxlen = sizeof(int),
25779 + .proc_handler = &proc_dointvec,
25782 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
25784 + .ctl_name = CTL_UNNUMBERED,
25785 + .procname = "chroot_deny_unix",
25786 + .data = &grsec_enable_chroot_unix,
25787 + .maxlen = sizeof(int),
25789 + .proc_handler = &proc_dointvec,
25792 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
25794 + .ctl_name = CTL_UNNUMBERED,
25795 + .procname = "chroot_deny_mount",
25796 + .data = &grsec_enable_chroot_mount,
25797 + .maxlen = sizeof(int),
25799 + .proc_handler = &proc_dointvec,
25802 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
25804 + .ctl_name = CTL_UNNUMBERED,
25805 + .procname = "chroot_deny_fchdir",
25806 + .data = &grsec_enable_chroot_fchdir,
25807 + .maxlen = sizeof(int),
25809 + .proc_handler = &proc_dointvec,
25812 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
25814 + .ctl_name = CTL_UNNUMBERED,
25815 + .procname = "chroot_deny_chroot",
25816 + .data = &grsec_enable_chroot_double,
25817 + .maxlen = sizeof(int),
25819 + .proc_handler = &proc_dointvec,
25822 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
25824 + .ctl_name = CTL_UNNUMBERED,
25825 + .procname = "chroot_deny_pivot",
25826 + .data = &grsec_enable_chroot_pivot,
25827 + .maxlen = sizeof(int),
25829 + .proc_handler = &proc_dointvec,
25832 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
25834 + .ctl_name = CTL_UNNUMBERED,
25835 + .procname = "chroot_enforce_chdir",
25836 + .data = &grsec_enable_chroot_chdir,
25837 + .maxlen = sizeof(int),
25839 + .proc_handler = &proc_dointvec,
25842 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
25844 + .ctl_name = CTL_UNNUMBERED,
25845 + .procname = "chroot_deny_chmod",
25846 + .data = &grsec_enable_chroot_chmod,
25847 + .maxlen = sizeof(int),
25849 + .proc_handler = &proc_dointvec,
25852 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
25854 + .ctl_name = CTL_UNNUMBERED,
25855 + .procname = "chroot_deny_mknod",
25856 + .data = &grsec_enable_chroot_mknod,
25857 + .maxlen = sizeof(int),
25859 + .proc_handler = &proc_dointvec,
25862 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25864 + .ctl_name = CTL_UNNUMBERED,
25865 + .procname = "chroot_restrict_nice",
25866 + .data = &grsec_enable_chroot_nice,
25867 + .maxlen = sizeof(int),
25869 + .proc_handler = &proc_dointvec,
25872 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
25874 + .ctl_name = CTL_UNNUMBERED,
25875 + .procname = "chroot_execlog",
25876 + .data = &grsec_enable_chroot_execlog,
25877 + .maxlen = sizeof(int),
25879 + .proc_handler = &proc_dointvec,
25882 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25884 + .ctl_name = CTL_UNNUMBERED,
25885 + .procname = "chroot_caps",
25886 + .data = &grsec_enable_chroot_caps,
25887 + .maxlen = sizeof(int),
25889 + .proc_handler = &proc_dointvec,
25892 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
25894 + .ctl_name = CTL_UNNUMBERED,
25895 + .procname = "chroot_deny_sysctl",
25896 + .data = &grsec_enable_chroot_sysctl,
25897 + .maxlen = sizeof(int),
25899 + .proc_handler = &proc_dointvec,
25902 +#ifdef CONFIG_GRKERNSEC_TPE
25904 + .ctl_name = CTL_UNNUMBERED,
25905 + .procname = "tpe",
25906 + .data = &grsec_enable_tpe,
25907 + .maxlen = sizeof(int),
25909 + .proc_handler = &proc_dointvec,
25912 + .ctl_name = CTL_UNNUMBERED,
25913 + .procname = "tpe_gid",
25914 + .data = &grsec_tpe_gid,
25915 + .maxlen = sizeof(int),
25917 + .proc_handler = &proc_dointvec,
25920 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
25922 + .ctl_name = CTL_UNNUMBERED,
25923 + .procname = "tpe_restrict_all",
25924 + .data = &grsec_enable_tpe_all,
25925 + .maxlen = sizeof(int),
25927 + .proc_handler = &proc_dointvec,
25930 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
25932 + .ctl_name = CTL_UNNUMBERED,
25933 + .procname = "socket_all",
25934 + .data = &grsec_enable_socket_all,
25935 + .maxlen = sizeof(int),
25937 + .proc_handler = &proc_dointvec,
25940 + .ctl_name = CTL_UNNUMBERED,
25941 + .procname = "socket_all_gid",
25942 + .data = &grsec_socket_all_gid,
25943 + .maxlen = sizeof(int),
25945 + .proc_handler = &proc_dointvec,
25948 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
25950 + .ctl_name = CTL_UNNUMBERED,
25951 + .procname = "socket_client",
25952 + .data = &grsec_enable_socket_client,
25953 + .maxlen = sizeof(int),
25955 + .proc_handler = &proc_dointvec,
25958 + .ctl_name = CTL_UNNUMBERED,
25959 + .procname = "socket_client_gid",
25960 + .data = &grsec_socket_client_gid,
25961 + .maxlen = sizeof(int),
25963 + .proc_handler = &proc_dointvec,
25966 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
25968 + .ctl_name = CTL_UNNUMBERED,
25969 + .procname = "socket_server",
25970 + .data = &grsec_enable_socket_server,
25971 + .maxlen = sizeof(int),
25973 + .proc_handler = &proc_dointvec,
25976 + .ctl_name = CTL_UNNUMBERED,
25977 + .procname = "socket_server_gid",
25978 + .data = &grsec_socket_server_gid,
25979 + .maxlen = sizeof(int),
25981 + .proc_handler = &proc_dointvec,
25984 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
25986 + .ctl_name = CTL_UNNUMBERED,
25987 + .procname = "audit_group",
25988 + .data = &grsec_enable_group,
25989 + .maxlen = sizeof(int),
25991 + .proc_handler = &proc_dointvec,
25994 + .ctl_name = CTL_UNNUMBERED,
25995 + .procname = "audit_gid",
25996 + .data = &grsec_audit_gid,
25997 + .maxlen = sizeof(int),
25999 + .proc_handler = &proc_dointvec,
26002 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
26004 + .ctl_name = CTL_UNNUMBERED,
26005 + .procname = "audit_chdir",
26006 + .data = &grsec_enable_chdir,
26007 + .maxlen = sizeof(int),
26009 + .proc_handler = &proc_dointvec,
26012 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26014 + .ctl_name = CTL_UNNUMBERED,
26015 + .procname = "audit_mount",
26016 + .data = &grsec_enable_mount,
26017 + .maxlen = sizeof(int),
26019 + .proc_handler = &proc_dointvec,
26022 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26024 + .ctl_name = CTL_UNNUMBERED,
26025 + .procname = "audit_ipc",
26026 + .data = &grsec_enable_audit_ipc,
26027 + .maxlen = sizeof(int),
26029 + .proc_handler = &proc_dointvec,
26032 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
26034 + .ctl_name = CTL_UNNUMBERED,
26035 + .procname = "audit_textrel",
26036 + .data = &grsec_enable_audit_textrel,
26037 + .maxlen = sizeof(int),
26039 + .proc_handler = &proc_dointvec,
26042 +#ifdef CONFIG_GRKERNSEC_DMESG
26044 + .ctl_name = CTL_UNNUMBERED,
26045 + .procname = "dmesg",
26046 + .data = &grsec_enable_dmesg,
26047 + .maxlen = sizeof(int),
26049 + .proc_handler = &proc_dointvec,
26052 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
26054 + .ctl_name = CTL_UNNUMBERED,
26055 + .procname = "chroot_findtask",
26056 + .data = &grsec_enable_chroot_findtask,
26057 + .maxlen = sizeof(int),
26059 + .proc_handler = &proc_dointvec,
26062 +#ifdef CONFIG_GRKERNSEC_RESLOG
26064 + .ctl_name = CTL_UNNUMBERED,
26065 + .procname = "resource_logging",
26066 + .data = &grsec_resource_logging,
26067 + .maxlen = sizeof(int),
26069 + .proc_handler = &proc_dointvec,
26073 + .ctl_name = CTL_UNNUMBERED,
26074 + .procname = "grsec_lock",
26075 + .data = &grsec_lock,
26076 + .maxlen = sizeof(int),
26078 + .proc_handler = &proc_dointvec,
26081 +#ifdef CONFIG_GRKERNSEC_MODSTOP
26083 + .ctl_name = CTL_UNNUMBERED,
26084 + .procname = "disable_modules",
26085 + .data = &grsec_modstop,
26086 + .maxlen = sizeof(int),
26088 + .proc_handler = &proc_dointvec,
26091 + { .ctl_name = 0 }
26095 +int gr_check_modstop(void)
26097 +#ifdef CONFIG_GRKERNSEC_MODSTOP
26098 + if (grsec_modstop == 1) {
26099 + gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
26105 diff -urNp linux-2.6.24.4/grsecurity/grsec_textrel.c linux-2.6.24.4/grsecurity/grsec_textrel.c
26106 --- linux-2.6.24.4/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
26107 +++ linux-2.6.24.4/grsecurity/grsec_textrel.c 2008-03-26 20:21:09.000000000 -0400
26109 +#include <linux/kernel.h>
26110 +#include <linux/sched.h>
26111 +#include <linux/mm.h>
26112 +#include <linux/file.h>
26113 +#include <linux/grinternal.h>
26114 +#include <linux/grsecurity.h>
26117 +gr_log_textrel(struct vm_area_struct * vma)
26119 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
26120 + if (grsec_enable_audit_textrel)
26121 + gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
26125 diff -urNp linux-2.6.24.4/grsecurity/grsec_time.c linux-2.6.24.4/grsecurity/grsec_time.c
26126 --- linux-2.6.24.4/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
26127 +++ linux-2.6.24.4/grsecurity/grsec_time.c 2008-03-26 20:21:09.000000000 -0400
26129 +#include <linux/kernel.h>
26130 +#include <linux/sched.h>
26131 +#include <linux/grinternal.h>
26134 +gr_log_timechange(void)
26136 +#ifdef CONFIG_GRKERNSEC_TIME
26137 + if (grsec_enable_time)
26138 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
26142 diff -urNp linux-2.6.24.4/grsecurity/grsec_tpe.c linux-2.6.24.4/grsecurity/grsec_tpe.c
26143 --- linux-2.6.24.4/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
26144 +++ linux-2.6.24.4/grsecurity/grsec_tpe.c 2008-03-26 20:21:09.000000000 -0400
26146 +#include <linux/kernel.h>
26147 +#include <linux/sched.h>
26148 +#include <linux/file.h>
26149 +#include <linux/fs.h>
26150 +#include <linux/grinternal.h>
26152 +extern int gr_acl_tpe_check(void);
26155 +gr_tpe_allow(const struct file *file)
26157 +#ifdef CONFIG_GRKERNSEC
26158 + struct inode *inode = file->f_dentry->d_parent->d_inode;
26160 + if (current->uid && ((grsec_enable_tpe &&
26161 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
26162 + !in_group_p(grsec_tpe_gid)
26164 + in_group_p(grsec_tpe_gid)
26166 + ) || gr_acl_tpe_check()) &&
26167 + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
26168 + (inode->i_mode & S_IWOTH))))) {
26169 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
26172 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
26173 + if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
26174 + ((inode->i_uid && (inode->i_uid != current->uid)) ||
26175 + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
26176 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
26183 diff -urNp linux-2.6.24.4/grsecurity/grsum.c linux-2.6.24.4/grsecurity/grsum.c
26184 --- linux-2.6.24.4/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
26185 +++ linux-2.6.24.4/grsecurity/grsum.c 2008-03-26 20:21:09.000000000 -0400
26187 +#include <linux/err.h>
26188 +#include <linux/kernel.h>
26189 +#include <linux/sched.h>
26190 +#include <linux/mm.h>
26191 +#include <linux/scatterlist.h>
26192 +#include <linux/crypto.h>
26193 +#include <linux/gracl.h>
26196 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
26197 +#error "crypto and sha256 must be built into the kernel"
26201 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
26204 + struct crypto_hash *tfm;
26205 + struct hash_desc desc;
26206 + struct scatterlist sg;
26207 + unsigned char temp_sum[GR_SHA_LEN];
26208 + volatile int retval = 0;
26209 + volatile int dummy = 0;
26212 + tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
26213 + if (IS_ERR(tfm)) {
26214 + /* should never happen, since sha256 should be built in */
26221 + crypto_hash_init(&desc);
26224 + sg_set_buf(&sg, p, GR_SALT_LEN);
26225 + crypto_hash_update(&desc, &sg, sg.length);
26228 + sg_set_buf(&sg, p, strlen(p));
26230 + crypto_hash_update(&desc, &sg, sg.length);
26232 + crypto_hash_final(&desc, temp_sum);
26234 + memset(entry->pw, 0, GR_PW_LEN);
26236 + for (i = 0; i < GR_SHA_LEN; i++)
26237 + if (sum[i] != temp_sum[i])
26240 + dummy = 1; // waste a cycle
26242 + crypto_free_hash(tfm);
26246 diff -urNp linux-2.6.24.4/grsecurity/Kconfig linux-2.6.24.4/grsecurity/Kconfig
26247 --- linux-2.6.24.4/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
26248 +++ linux-2.6.24.4/grsecurity/Kconfig 2008-03-26 20:21:09.000000000 -0400
26251 +# grecurity configuration
26257 + bool "Grsecurity"
26259 + select CRYPTO_SHA256
26261 + select SECURITY_CAPABILITIES
26263 + If you say Y here, you will be able to configure many features
26264 + that will enhance the security of your system. It is highly
26265 + recommended that you say Y here and read through the help
26266 + for each option so that you fully understand the features and
26267 + can evaluate their usefulness for your machine.
26270 + prompt "Security Level"
26271 + depends on GRKERNSEC
26272 + default GRKERNSEC_CUSTOM
26274 +config GRKERNSEC_LOW
26276 + select GRKERNSEC_LINK
26277 + select GRKERNSEC_FIFO
26278 + select GRKERNSEC_EXECVE
26279 + select GRKERNSEC_RANDNET
26280 + select GRKERNSEC_DMESG
26281 + select GRKERNSEC_CHROOT_CHDIR
26282 + select GRKERNSEC_MODSTOP if (MODULES)
26285 + If you choose this option, several of the grsecurity options will
26286 + be enabled that will give you greater protection against a number
26287 + of attacks, while assuring that none of your software will have any
26288 + conflicts with the additional security measures. If you run a lot
26289 + of unusual software, or you are having problems with the higher
26290 + security levels, you should say Y here. With this option, the
26291 + following features are enabled:
26293 + - Linking restrictions
26294 + - FIFO restrictions
26295 + - Enforcing RLIMIT_NPROC on execve
26296 + - Restricted dmesg
26297 + - Enforced chdir("/") on chroot
26298 + - Runtime module disabling
26300 +config GRKERNSEC_MEDIUM
26303 + select PAX_EI_PAX
26304 + select PAX_PT_PAX_FLAGS
26305 + select PAX_HAVE_ACL_FLAGS
26306 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
26307 + select GRKERNSEC_CHROOT_SYSCTL
26308 + select GRKERNSEC_LINK
26309 + select GRKERNSEC_FIFO
26310 + select GRKERNSEC_EXECVE
26311 + select GRKERNSEC_DMESG
26312 + select GRKERNSEC_RANDNET
26313 + select GRKERNSEC_FORKFAIL
26314 + select GRKERNSEC_TIME
26315 + select GRKERNSEC_SIGNAL
26316 + select GRKERNSEC_CHROOT
26317 + select GRKERNSEC_CHROOT_UNIX
26318 + select GRKERNSEC_CHROOT_MOUNT
26319 + select GRKERNSEC_CHROOT_PIVOT
26320 + select GRKERNSEC_CHROOT_DOUBLE
26321 + select GRKERNSEC_CHROOT_CHDIR
26322 + select GRKERNSEC_CHROOT_MKNOD
26323 + select GRKERNSEC_PROC
26324 + select GRKERNSEC_PROC_USERGROUP
26325 + select GRKERNSEC_MODSTOP if (MODULES)
26326 + select PAX_RANDUSTACK
26328 + select PAX_RANDMMAP
26331 + If you say Y here, several features in addition to those included
26332 + in the low additional security level will be enabled. These
26333 + features provide even more security to your system, though in rare
26334 + cases they may be incompatible with very old or poorly written
26335 + software. If you enable this option, make sure that your auth
26336 + service (identd) is running as gid 1001. With this option,
26337 + the following features (in addition to those provided in the
26338 + low additional security level) will be enabled:
26340 + - Failed fork logging
26341 + - Time change logging
26343 + - Deny mounts in chroot
26344 + - Deny double chrooting
26345 + - Deny sysctl writes in chroot
26346 + - Deny mknod in chroot
26347 + - Deny access to abstract AF_UNIX sockets out of chroot
26348 + - Deny pivot_root in chroot
26349 + - Denied writes of /dev/kmem, /dev/mem, and /dev/port
26350 + - /proc restrictions with special GID set to 10 (usually wheel)
26351 + - Address Space Layout Randomization (ASLR)
26353 +config GRKERNSEC_HIGH
26355 + select GRKERNSEC_LINK
26356 + select GRKERNSEC_FIFO
26357 + select GRKERNSEC_EXECVE
26358 + select GRKERNSEC_DMESG
26359 + select GRKERNSEC_FORKFAIL
26360 + select GRKERNSEC_TIME
26361 + select GRKERNSEC_SIGNAL
26362 + select GRKERNSEC_CHROOT_SHMAT
26363 + select GRKERNSEC_CHROOT_UNIX
26364 + select GRKERNSEC_CHROOT_MOUNT
26365 + select GRKERNSEC_CHROOT_FCHDIR
26366 + select GRKERNSEC_CHROOT_PIVOT
26367 + select GRKERNSEC_CHROOT_DOUBLE
26368 + select GRKERNSEC_CHROOT_CHDIR
26369 + select GRKERNSEC_CHROOT_MKNOD
26370 + select GRKERNSEC_CHROOT_CAPS
26371 + select GRKERNSEC_CHROOT_SYSCTL
26372 + select GRKERNSEC_CHROOT_FINDTASK
26373 + select GRKERNSEC_PROC
26374 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
26375 + select GRKERNSEC_HIDESYM
26376 + select GRKERNSEC_BRUTE
26377 + select GRKERNSEC_PROC_USERGROUP
26378 + select GRKERNSEC_KMEM
26379 + select GRKERNSEC_RESLOG
26380 + select GRKERNSEC_RANDNET
26381 + select GRKERNSEC_PROC_ADD
26382 + select GRKERNSEC_CHROOT_CHMOD
26383 + select GRKERNSEC_CHROOT_NICE
26384 + select GRKERNSEC_AUDIT_MOUNT
26385 + select GRKERNSEC_MODSTOP if (MODULES)
26387 + select PAX_RANDUSTACK
26389 + select PAX_RANDMMAP
26390 + select PAX_NOEXEC
26391 + select PAX_MPROTECT
26392 + select PAX_EI_PAX
26393 + select PAX_PT_PAX_FLAGS
26394 + select PAX_HAVE_ACL_FLAGS
26395 + select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
26396 + select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
26397 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
26398 + select PAX_SEGMEXEC if (X86 && !X86_64)
26399 + select PAX_PAGEEXEC if (!X86)
26400 + select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
26401 + select PAX_DLRESOLVE if (SPARC32 || SPARC64)
26402 + select PAX_SYSCALL if (PPC32)
26403 + select PAX_EMUTRAMP if (PARISC)
26404 + select PAX_EMUSIGRT if (PARISC)
26405 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
26407 + If you say Y here, many of the features of grsecurity will be
26408 + enabled, which will protect you against many kinds of attacks
26409 + against your system. The heightened security comes at a cost
26410 + of an increased chance of incompatibilities with rare software
26411 + on your machine. Since this security level enables PaX, you should
26412 + view <http://pax.grsecurity.net> and read about the PaX
26413 + project. While you are there, download chpax and run it on
26414 + binaries that cause problems with PaX. Also remember that
26415 + since the /proc restrictions are enabled, you must run your
26416 + identd as gid 1001. This security level enables the following
26417 + features in addition to those listed in the low and medium
26420 + - Additional /proc restrictions
26421 + - Chmod restrictions in chroot
26422 + - No signals, ptrace, or viewing of processes outside of chroot
26423 + - Capability restrictions in chroot
26424 + - Deny fchdir out of chroot
26425 + - Priority restrictions in chroot
26426 + - Segmentation-based implementation of PaX
26427 + - Mprotect restrictions
26428 + - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
26429 + - Kernel stack randomization
26430 + - Mount/unmount/remount logging
26431 + - Kernel symbol hiding
26432 + - Prevention of memory exhaustion-based exploits
26433 +config GRKERNSEC_CUSTOM
26436 + If you say Y here, you will be able to configure every grsecurity
26437 + option, which allows you to enable many more features that aren't
26438 + covered in the basic security levels. These additional features
26439 + include TPE, socket restrictions, and the sysctl system for
26440 + grsecurity. It is advised that you read through the help for
26441 + each option to determine its usefulness in your situation.
26445 +menu "Address Space Protection"
26446 +depends on GRKERNSEC
26448 +config GRKERNSEC_KMEM
26449 + bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
26451 + If you say Y here, /dev/kmem and /dev/mem won't be allowed to
26452 + be written to via mmap or otherwise to modify the running kernel.
26453 + /dev/port will also not be allowed to be opened. If you have module
26454 + support disabled, enabling this will close up four ways that are
26455 + currently used to insert malicious code into the running kernel.
26456 + Even with all these features enabled, we still highly recommend that
26457 + you use the RBAC system, as it is still possible for an attacker to
26458 + modify the running kernel through privileged I/O granted by ioperm/iopl.
26459 + If you are not using XFree86, you may be able to stop this additional
26460 + case by enabling the 'Disable privileged I/O' option. Though nothing
26461 + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
26462 + but only to video memory, which is the only writing we allow in this
26463 + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
26464 + not be allowed to mprotect it with PROT_WRITE later.
26465 + It is highly recommended that you say Y here if you meet all the
26466 + conditions above.
26468 +config GRKERNSEC_IO
26469 + bool "Disable privileged I/O"
26473 + If you say Y here, all ioperm and iopl calls will return an error.
26474 + Ioperm and iopl can be used to modify the running kernel.
26475 + Unfortunately, some programs need this access to operate properly,
26476 + the most notable of which are XFree86 and hwclock. hwclock can be
26477 + remedied by having RTC support in the kernel, so CONFIG_RTC is
26478 + enabled if this option is enabled, to ensure that hwclock operates
26479 + correctly. XFree86 still will not operate correctly with this option
26480 + enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
26481 + and you still want to protect your kernel against modification,
26482 + use the RBAC system.
26484 +config GRKERNSEC_PROC_MEMMAP
26485 + bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
26486 + depends on PAX_NOEXEC || PAX_ASLR
26488 + If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
26489 + give no information about the addresses of its mappings if
26490 + PaX features that rely on random addresses are enabled on the task.
26491 + If you use PaX it is greatly recommended that you say Y here as it
26492 + closes up a hole that makes the full ASLR useless for suid
26495 +config GRKERNSEC_BRUTE
26496 + bool "Deter exploit bruteforcing"
26498 + If you say Y here, attempts to bruteforce exploits against forking
26499 + daemons such as apache or sshd will be deterred. When a child of a
26500 + forking daemon is killed by PaX or crashes due to an illegal
26501 + instruction, the parent process will be delayed 30 seconds upon every
26502 + subsequent fork until the administrator is able to assess the
26503 + situation and restart the daemon. It is recommended that you also
26504 + enable signal logging in the auditing section so that logs are
26505 + generated when a process performs an illegal instruction.
26507 +config GRKERNSEC_MODSTOP
26508 + bool "Runtime module disabling"
26509 + depends on MODULES
26511 + If you say Y here, you will be able to disable the ability to (un)load
26512 + modules at runtime. This feature is useful if you need the ability
26513 + to load kernel modules at boot time, but do not want to allow an
26514 + attacker to load a rootkit kernel module into the system, or to remove
26515 + a loaded kernel module important to system functioning. You should
26516 + enable the /dev/mem protection feature as well, since rootkits can be
26517 + inserted into the kernel via other methods than kernel modules. Since
26518 + an untrusted module could still be loaded by modifying init scripts and
26519 + rebooting the system, it is also recommended that you enable the RBAC
26520 + system. If you enable this option, a sysctl option with name
26521 + "disable_modules" will be created. Setting this option to "1" disables
26522 + module loading. After this option is set, no further writes to it are
26523 + allowed until the system is rebooted.
26525 +config GRKERNSEC_HIDESYM
26526 + bool "Hide kernel symbols"
26528 + If you say Y here, getting information on loaded modules, and
26529 + displaying all kernel symbols through a syscall will be restricted
26530 + to users with CAP_SYS_MODULE. This option is only effective
26531 + provided the following conditions are met:
26532 + 1) The kernel using grsecurity is not precompiled by some distribution
26533 + 2) You are using the RBAC system and hiding other files such as your
26534 + kernel image and System.map
26535 + 3) You have the additional /proc restrictions enabled, which removes
26537 + If the above conditions are met, this option will aid to provide a
26538 + useful protection against local and remote kernel exploitation of
26539 + overflows and arbitrary read/write vulnerabilities.
26542 +menu "Role Based Access Control Options"
26543 +depends on GRKERNSEC
26545 +config GRKERNSEC_ACL_HIDEKERN
26546 + bool "Hide kernel processes"
26548 + If you say Y here, all kernel threads will be hidden to all
26549 + processes but those whose subject has the "view hidden processes"
26552 +config GRKERNSEC_ACL_MAXTRIES
26553 + int "Maximum tries before password lockout"
26556 + This option enforces the maximum number of times a user can attempt
26557 + to authorize themselves with the grsecurity RBAC system before being
26558 + denied the ability to attempt authorization again for a specified time.
26559 + The lower the number, the harder it will be to brute-force a password.
26561 +config GRKERNSEC_ACL_TIMEOUT
26562 + int "Time to wait after max password tries, in seconds"
26565 + This option specifies the time the user must wait after attempting to
26566 + authorize to the RBAC system with the maximum number of invalid
26567 + passwords. The higher the number, the harder it will be to brute-force
26571 +menu "Filesystem Protections"
26572 +depends on GRKERNSEC
26574 +config GRKERNSEC_PROC
26575 + bool "Proc restrictions"
26577 + If you say Y here, the permissions of the /proc filesystem
26578 + will be altered to enhance system security and privacy. You MUST
26579 + choose either a user only restriction or a user and group restriction.
26580 + Depending upon the option you choose, you can either restrict users to
26581 + see only the processes they themselves run, or choose a group that can
26582 + view all processes and files normally restricted to root if you choose
26583 + the "restrict to user only" option. NOTE: If you're running identd as
26584 + a non-root user, you will have to run it as the group you specify here.
26586 +config GRKERNSEC_PROC_USER
26587 + bool "Restrict /proc to user only"
26588 + depends on GRKERNSEC_PROC
26590 + If you say Y here, non-root users will only be able to view their own
26591 + processes, and restricts them from viewing network-related information,
26592 + and viewing kernel symbol and module information.
26594 +config GRKERNSEC_PROC_USERGROUP
26595 + bool "Allow special group"
26596 + depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
26598 + If you say Y here, you will be able to select a group that will be
26599 + able to view all processes, network-related information, and
26600 + kernel and symbol information. This option is useful if you want
26601 + to run identd as a non-root user.
26603 +config GRKERNSEC_PROC_GID
26604 + int "GID for special group"
26605 + depends on GRKERNSEC_PROC_USERGROUP
26608 +config GRKERNSEC_PROC_ADD
26609 + bool "Additional restrictions"
26610 + depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
26612 + If you say Y here, additional restrictions will be placed on
26613 + /proc that keep normal users from viewing device information and
26614 + slabinfo information that could be useful for exploits.
26616 +config GRKERNSEC_LINK
26617 + bool "Linking restrictions"
26619 + If you say Y here, /tmp race exploits will be prevented, since users
26620 + will no longer be able to follow symlinks owned by other users in
26621 + world-writable +t directories (i.e. /tmp), unless the owner of the
26622 + symlink is the owner of the directory. users will also not be
26623 + able to hardlink to files they do not own. If the sysctl option is
26624 + enabled, a sysctl option with name "linking_restrictions" is created.
26626 +config GRKERNSEC_FIFO
26627 + bool "FIFO restrictions"
26629 + If you say Y here, users will not be able to write to FIFOs they don't
26630 + own in world-writable +t directories (i.e. /tmp), unless the owner of
26631 + the FIFO is the same owner of the directory it's held in. If the sysctl
26632 + option is enabled, a sysctl option with name "fifo_restrictions" is
26635 +config GRKERNSEC_CHROOT
26636 + bool "Chroot jail restrictions"
26638 + If you say Y here, you will be able to choose several options that will
26639 + make breaking out of a chrooted jail much more difficult. If you
26640 + encounter no software incompatibilities with the following options, it
26641 + is recommended that you enable each one.
26643 +config GRKERNSEC_CHROOT_MOUNT
26644 + bool "Deny mounts"
26645 + depends on GRKERNSEC_CHROOT
26647 + If you say Y here, processes inside a chroot will not be able to
26648 + mount or remount filesystems. If the sysctl option is enabled, a
26649 + sysctl option with name "chroot_deny_mount" is created.
26651 +config GRKERNSEC_CHROOT_DOUBLE
26652 + bool "Deny double-chroots"
26653 + depends on GRKERNSEC_CHROOT
26655 + If you say Y here, processes inside a chroot will not be able to chroot
26656 + again outside the chroot. This is a widely used method of breaking
26657 + out of a chroot jail and should not be allowed. If the sysctl
26658 + option is enabled, a sysctl option with name
26659 + "chroot_deny_chroot" is created.
26661 +config GRKERNSEC_CHROOT_PIVOT
26662 + bool "Deny pivot_root in chroot"
26663 + depends on GRKERNSEC_CHROOT
26665 + If you say Y here, processes inside a chroot will not be able to use
26666 + a function called pivot_root() that was introduced in Linux 2.3.41. It
26667 + works similar to chroot in that it changes the root filesystem. This
26668 + function could be misused in a chrooted process to attempt to break out
26669 + of the chroot, and therefore should not be allowed. If the sysctl
26670 + option is enabled, a sysctl option with name "chroot_deny_pivot" is
26673 +config GRKERNSEC_CHROOT_CHDIR
26674 + bool "Enforce chdir(\"/\") on all chroots"
26675 + depends on GRKERNSEC_CHROOT
26677 + If you say Y here, the current working directory of all newly-chrooted
26678 + applications will be set to the the root directory of the chroot.
26679 + The man page on chroot(2) states:
26680 + Note that this call does not change the current working
26681 + directory, so that `.' can be outside the tree rooted at
26682 + `/'. In particular, the super-user can escape from a
26683 + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
26685 + It is recommended that you say Y here, since it's not known to break
26686 + any software. If the sysctl option is enabled, a sysctl option with
26687 + name "chroot_enforce_chdir" is created.
26689 +config GRKERNSEC_CHROOT_CHMOD
26690 + bool "Deny (f)chmod +s"
26691 + depends on GRKERNSEC_CHROOT
26693 + If you say Y here, processes inside a chroot will not be able to chmod
26694 + or fchmod files to make them have suid or sgid bits. This protects
26695 + against another published method of breaking a chroot. If the sysctl
26696 + option is enabled, a sysctl option with name "chroot_deny_chmod" is
26699 +config GRKERNSEC_CHROOT_FCHDIR
26700 + bool "Deny fchdir out of chroot"
26701 + depends on GRKERNSEC_CHROOT
26703 + If you say Y here, a well-known method of breaking chroots by fchdir'ing
26704 + to a file descriptor of the chrooting process that points to a directory
26705 + outside the filesystem will be stopped. If the sysctl option
26706 + is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
26708 +config GRKERNSEC_CHROOT_MKNOD
26709 + bool "Deny mknod"
26710 + depends on GRKERNSEC_CHROOT
26712 + If you say Y here, processes inside a chroot will not be allowed to
26713 + mknod. The problem with using mknod inside a chroot is that it
26714 + would allow an attacker to create a device entry that is the same
26715 + as one on the physical root of your system, which could range from
26716 + anything from the console device to a device for your harddrive (which
26717 + they could then use to wipe the drive or steal data). It is recommended
26718 + that you say Y here, unless you run into software incompatibilities.
26719 + If the sysctl option is enabled, a sysctl option with name
26720 + "chroot_deny_mknod" is created.
26722 +config GRKERNSEC_CHROOT_SHMAT
26723 + bool "Deny shmat() out of chroot"
26724 + depends on GRKERNSEC_CHROOT
26726 + If you say Y here, processes inside a chroot will not be able to attach
26727 + to shared memory segments that were created outside of the chroot jail.
26728 + It is recommended that you say Y here. If the sysctl option is enabled,
26729 + a sysctl option with name "chroot_deny_shmat" is created.
26731 +config GRKERNSEC_CHROOT_UNIX
26732 + bool "Deny access to abstract AF_UNIX sockets out of chroot"
26733 + depends on GRKERNSEC_CHROOT
26735 + If you say Y here, processes inside a chroot will not be able to
26736 + connect to abstract (meaning not belonging to a filesystem) Unix
26737 + domain sockets that were bound outside of a chroot. It is recommended
26738 + that you say Y here. If the sysctl option is enabled, a sysctl option
26739 + with name "chroot_deny_unix" is created.
26741 +config GRKERNSEC_CHROOT_FINDTASK
26742 + bool "Protect outside processes"
26743 + depends on GRKERNSEC_CHROOT
26745 + If you say Y here, processes inside a chroot will not be able to
26746 + kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
26747 + or view any process outside of the chroot. If the sysctl
26748 + option is enabled, a sysctl option with name "chroot_findtask" is
26751 +config GRKERNSEC_CHROOT_NICE
26752 + bool "Restrict priority changes"
26753 + depends on GRKERNSEC_CHROOT
26755 + If you say Y here, processes inside a chroot will not be able to raise
26756 + the priority of processes in the chroot, or alter the priority of
26757 + processes outside the chroot. This provides more security than simply
26758 + removing CAP_SYS_NICE from the process' capability set. If the
26759 + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
26762 +config GRKERNSEC_CHROOT_SYSCTL
26763 + bool "Deny sysctl writes"
26764 + depends on GRKERNSEC_CHROOT
26766 + If you say Y here, an attacker in a chroot will not be able to
26767 + write to sysctl entries, either by sysctl(2) or through a /proc
26768 + interface. It is strongly recommended that you say Y here. If the
26769 + sysctl option is enabled, a sysctl option with name
26770 + "chroot_deny_sysctl" is created.
26772 +config GRKERNSEC_CHROOT_CAPS
26773 + bool "Capability restrictions"
26774 + depends on GRKERNSEC_CHROOT
26776 + If you say Y here, the capabilities on all root processes within a
26777 + chroot jail will be lowered to stop module insertion, raw i/o,
26778 + system and net admin tasks, rebooting the system, modifying immutable
26779 + files, modifying IPC owned by another, and changing the system time.
26780 + This is left an option because it can break some apps. Disable this
26781 + if your chrooted apps are having problems performing those kinds of
26782 + tasks. If the sysctl option is enabled, a sysctl option with
26783 + name "chroot_caps" is created.
26786 +menu "Kernel Auditing"
26787 +depends on GRKERNSEC
26789 +config GRKERNSEC_AUDIT_GROUP
26790 + bool "Single group for auditing"
26792 + If you say Y here, the exec, chdir, (un)mount, and ipc logging features
26793 + will only operate on a group you specify. This option is recommended
26794 + if you only want to watch certain users instead of having a large
26795 + amount of logs from the entire system. If the sysctl option is enabled,
26796 + a sysctl option with name "audit_group" is created.
26798 +config GRKERNSEC_AUDIT_GID
26799 + int "GID for auditing"
26800 + depends on GRKERNSEC_AUDIT_GROUP
26803 +config GRKERNSEC_EXECLOG
26804 + bool "Exec logging"
26806 + If you say Y here, all execve() calls will be logged (since the
26807 + other exec*() calls are frontends to execve(), all execution
26808 + will be logged). Useful for shell-servers that like to keep track
26809 + of their users. If the sysctl option is enabled, a sysctl option with
26810 + name "exec_logging" is created.
26811 + WARNING: This option when enabled will produce a LOT of logs, especially
26812 + on an active system.
26814 +config GRKERNSEC_RESLOG
26815 + bool "Resource logging"
26817 + If you say Y here, all attempts to overstep resource limits will
26818 + be logged with the resource name, the requested size, and the current
26819 + limit. It is highly recommended that you say Y here. If the sysctl
26820 + option is enabled, a sysctl option with name "resource_logging" is
26821 + created. If the RBAC system is enabled, the sysctl value is ignored.
26823 +config GRKERNSEC_CHROOT_EXECLOG
26824 + bool "Log execs within chroot"
26826 + If you say Y here, all executions inside a chroot jail will be logged
26827 + to syslog. This can cause a large amount of logs if certain
26828 + applications (eg. djb's daemontools) are installed on the system, and
26829 + is therefore left as an option. If the sysctl option is enabled, a
26830 + sysctl option with name "chroot_execlog" is created.
26832 +config GRKERNSEC_AUDIT_CHDIR
26833 + bool "Chdir logging"
26835 + If you say Y here, all chdir() calls will be logged. If the sysctl
26836 + option is enabled, a sysctl option with name "audit_chdir" is created.
26838 +config GRKERNSEC_AUDIT_MOUNT
26839 + bool "(Un)Mount logging"
26841 + If you say Y here, all mounts and unmounts will be logged. If the
26842 + sysctl option is enabled, a sysctl option with name "audit_mount" is
26845 +config GRKERNSEC_AUDIT_IPC
26846 + bool "IPC logging"
26848 + If you say Y here, creation and removal of message queues, semaphores,
26849 + and shared memory will be logged. If the sysctl option is enabled, a
26850 + sysctl option with name "audit_ipc" is created.
26852 +config GRKERNSEC_SIGNAL
26853 + bool "Signal logging"
26855 + If you say Y here, certain important signals will be logged, such as
26856 + SIGSEGV, which will as a result inform you of when a error in a program
26857 + occurred, which in some cases could mean a possible exploit attempt.
26858 + If the sysctl option is enabled, a sysctl option with name
26859 + "signal_logging" is created.
26861 +config GRKERNSEC_FORKFAIL
26862 + bool "Fork failure logging"
26864 + If you say Y here, all failed fork() attempts will be logged.
26865 + This could suggest a fork bomb, or someone attempting to overstep
26866 + their process limit. If the sysctl option is enabled, a sysctl option
26867 + with name "forkfail_logging" is created.
26869 +config GRKERNSEC_TIME
26870 + bool "Time change logging"
26872 + If you say Y here, any changes of the system clock will be logged.
26873 + If the sysctl option is enabled, a sysctl option with name
26874 + "timechange_logging" is created.
26876 +config GRKERNSEC_PROC_IPADDR
26877 + bool "/proc/<pid>/ipaddr support"
26879 + If you say Y here, a new entry will be added to each /proc/<pid>
26880 + directory that contains the IP address of the person using the task.
26881 + The IP is carried across local TCP and AF_UNIX stream sockets.
26882 + This information can be useful for IDS/IPSes to perform remote response
26883 + to a local attack. The entry is readable by only the owner of the
26884 + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
26885 + the RBAC system), and thus does not create privacy concerns.
26887 +config GRKERNSEC_AUDIT_TEXTREL
26888 + bool 'ELF text relocations logging (READ HELP)'
26889 + depends on PAX_MPROTECT
26891 + If you say Y here, text relocations will be logged with the filename
26892 + of the offending library or binary. The purpose of the feature is
26893 + to help Linux distribution developers get rid of libraries and
26894 + binaries that need text relocations which hinder the future progress
26895 + of PaX. Only Linux distribution developers should say Y here, and
26896 + never on a production machine, as this option creates an information
26897 + leak that could aid an attacker in defeating the randomization of
26898 + a single memory region. If the sysctl option is enabled, a sysctl
26899 + option with name "audit_textrel" is created.
26903 +menu "Executable Protections"
26904 +depends on GRKERNSEC
26906 +config GRKERNSEC_EXECVE
26907 + bool "Enforce RLIMIT_NPROC on execs"
26909 + If you say Y here, users with a resource limit on processes will
26910 + have the value checked during execve() calls. The current system
26911 + only checks the system limit during fork() calls. If the sysctl option
26912 + is enabled, a sysctl option with name "execve_limiting" is created.
26914 +config GRKERNSEC_DMESG
26915 + bool "Dmesg(8) restriction"
26917 + If you say Y here, non-root users will not be able to use dmesg(8)
26918 + to view up to the last 4kb of messages in the kernel's log buffer.
26919 + If the sysctl option is enabled, a sysctl option with name "dmesg" is
26922 +config GRKERNSEC_TPE
26923 + bool "Trusted Path Execution (TPE)"
26925 + If you say Y here, you will be able to choose a gid to add to the
26926 + supplementary groups of users you want to mark as "untrusted."
26927 + These users will not be able to execute any files that are not in
26928 + root-owned directories writable only by root. If the sysctl option
26929 + is enabled, a sysctl option with name "tpe" is created.
26931 +config GRKERNSEC_TPE_ALL
26932 + bool "Partially restrict non-root users"
26933 + depends on GRKERNSEC_TPE
26935 + If you say Y here, All non-root users other than the ones in the
26936 + group specified in the main TPE option will only be allowed to
26937 + execute files in directories they own that are not group or
26938 + world-writable, or in directories owned by root and writable only by
26939 + root. If the sysctl option is enabled, a sysctl option with name
26940 + "tpe_restrict_all" is created.
26942 +config GRKERNSEC_TPE_INVERT
26943 + bool "Invert GID option"
26944 + depends on GRKERNSEC_TPE
26946 + If you say Y here, the group you specify in the TPE configuration will
26947 + decide what group TPE restrictions will be *disabled* for. This
26948 + option is useful if you want TPE restrictions to be applied to most
26949 + users on the system.
26951 +config GRKERNSEC_TPE_GID
26952 + int "GID for untrusted users"
26953 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
26956 + If you have selected the "Invert GID option" above, setting this
26957 + GID determines what group TPE restrictions will be *disabled* for.
26958 + If you have not selected the "Invert GID option" above, setting this
26959 + GID determines what group TPE restrictions will be *enabled* for.
26960 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
26963 +config GRKERNSEC_TPE_GID
26964 + int "GID for trusted users"
26965 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
26968 + If you have selected the "Invert GID option" above, setting this
26969 + GID determines what group TPE restrictions will be *disabled* for.
26970 + If you have not selected the "Invert GID option" above, setting this
26971 + GID determines what group TPE restrictions will be *enabled* for.
26972 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
26976 +menu "Network Protections"
26977 +depends on GRKERNSEC
26979 +config GRKERNSEC_RANDNET
26980 + bool "Larger entropy pools"
26982 + If you say Y here, the entropy pools used for many features of Linux
26983 + and grsecurity will be doubled in size. Since several grsecurity
26984 + features use additional randomness, it is recommended that you say Y
26985 + here. Saying Y here has a similar effect as modifying
26986 + /proc/sys/kernel/random/poolsize.
26988 +config GRKERNSEC_SOCKET
26989 + bool "Socket restrictions"
26991 + If you say Y here, you will be able to choose from several options.
26992 + If you assign a GID on your system and add it to the supplementary
26993 + groups of users you want to restrict socket access to, this patch
26994 + will perform up to three things, based on the option(s) you choose.
26996 +config GRKERNSEC_SOCKET_ALL
26997 + bool "Deny any sockets to group"
26998 + depends on GRKERNSEC_SOCKET
27000 + If you say Y here, you will be able to choose a GID of whose users will
27001 + be unable to connect to other hosts from your machine or run server
27002 + applications from your machine. If the sysctl option is enabled, a
27003 + sysctl option with name "socket_all" is created.
27005 +config GRKERNSEC_SOCKET_ALL_GID
27006 + int "GID to deny all sockets for"
27007 + depends on GRKERNSEC_SOCKET_ALL
27010 + Here you can choose the GID to disable socket access for. Remember to
27011 + add the users you want socket access disabled for to the GID
27012 + specified here. If the sysctl option is enabled, a sysctl option
27013 + with name "socket_all_gid" is created.
27015 +config GRKERNSEC_SOCKET_CLIENT
27016 + bool "Deny client sockets to group"
27017 + depends on GRKERNSEC_SOCKET
27019 + If you say Y here, you will be able to choose a GID of whose users will
27020 + be unable to connect to other hosts from your machine, but will be
27021 + able to run servers. If this option is enabled, all users in the group
27022 + you specify will have to use passive mode when initiating ftp transfers
27023 + from the shell on your machine. If the sysctl option is enabled, a
27024 + sysctl option with name "socket_client" is created.
27026 +config GRKERNSEC_SOCKET_CLIENT_GID
27027 + int "GID to deny client sockets for"
27028 + depends on GRKERNSEC_SOCKET_CLIENT
27031 + Here you can choose the GID to disable client socket access for.
27032 + Remember to add the users you want client socket access disabled for to
27033 + the GID specified here. If the sysctl option is enabled, a sysctl
27034 + option with name "socket_client_gid" is created.
27036 +config GRKERNSEC_SOCKET_SERVER
27037 + bool "Deny server sockets to group"
27038 + depends on GRKERNSEC_SOCKET
27040 + If you say Y here, you will be able to choose a GID of whose users will
27041 + be unable to run server applications from your machine. If the sysctl
27042 + option is enabled, a sysctl option with name "socket_server" is created.
27044 +config GRKERNSEC_SOCKET_SERVER_GID
27045 + int "GID to deny server sockets for"
27046 + depends on GRKERNSEC_SOCKET_SERVER
27049 + Here you can choose the GID to disable server socket access for.
27050 + Remember to add the users you want server socket access disabled for to
27051 + the GID specified here. If the sysctl option is enabled, a sysctl
27052 + option with name "socket_server_gid" is created.
27055 +menu "Sysctl support"
27056 +depends on GRKERNSEC && SYSCTL
27058 +config GRKERNSEC_SYSCTL
27059 + bool "Sysctl support"
27061 + If you say Y here, you will be able to change the options that
27062 + grsecurity runs with at bootup, without having to recompile your
27063 + kernel. You can echo values to files in /proc/sys/kernel/grsecurity
27064 + to enable (1) or disable (0) various features. All the sysctl entries
27065 + are mutable until the "grsec_lock" entry is set to a non-zero value.
27066 + All features enabled in the kernel configuration are disabled at boot
27067 + if you do not say Y to the "Turn on features by default" option.
27068 + All options should be set at startup, and the grsec_lock entry should
27069 + be set to a non-zero value after all the options are set.
27070 + *THIS IS EXTREMELY IMPORTANT*
27072 +config GRKERNSEC_SYSCTL_ON
27073 + bool "Turn on features by default"
27074 + depends on GRKERNSEC_SYSCTL
27076 + If you say Y here, instead of having all features enabled in the
27077 + kernel configuration disabled at boot time, the features will be
27078 + enabled at boot time. It is recommended you say Y here unless
27079 + there is some reason you would want all sysctl-tunable features to
27080 + be disabled by default. As mentioned elsewhere, it is important
27081 + to enable the grsec_lock entry once you have finished modifying
27082 + the sysctl entries.
27085 +menu "Logging Options"
27086 +depends on GRKERNSEC
27088 +config GRKERNSEC_FLOODTIME
27089 + int "Seconds in between log messages (minimum)"
27092 + This option allows you to enforce the number of seconds between
27093 + grsecurity log messages. The default should be suitable for most
27094 + people, however, if you choose to change it, choose a value small enough
27095 + to allow informative logs to be produced, but large enough to
27096 + prevent flooding.
27098 +config GRKERNSEC_FLOODBURST
27099 + int "Number of messages in a burst (maximum)"
27102 + This option allows you to choose the maximum number of messages allowed
27103 + within the flood time interval you chose in a separate option. The
27104 + default should be suitable for most people, however if you find that
27105 + many of your logs are being interpreted as flooding, you may want to
27106 + raise this value.
27111 diff -urNp linux-2.6.24.4/grsecurity/Makefile linux-2.6.24.4/grsecurity/Makefile
27112 --- linux-2.6.24.4/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
27113 +++ linux-2.6.24.4/grsecurity/Makefile 2008-03-26 20:21:09.000000000 -0400
27115 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
27116 +# during 2001-2005 it has been completely redesigned by Brad Spengler
27117 +# into an RBAC system
27119 +# All code in this directory and various hooks inserted throughout the kernel
27120 +# are copyright Brad Spengler, and released under the GPL v2 or higher
27122 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
27123 + grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
27124 + grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
27126 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
27127 + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
27128 + gracl_learn.o grsec_log.o
27129 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
27131 +ifndef CONFIG_GRKERNSEC
27132 +obj-y += grsec_disabled.o
27135 diff -urNp linux-2.6.24.4/include/acpi/acpiosxf.h linux-2.6.24.4/include/acpi/acpiosxf.h
27136 --- linux-2.6.24.4/include/acpi/acpiosxf.h 2008-03-24 14:49:18.000000000 -0400
27137 +++ linux-2.6.24.4/include/acpi/acpiosxf.h 2008-03-26 20:21:09.000000000 -0400
27138 @@ -219,7 +219,7 @@ acpi_os_write_memory(acpi_physical_addre
27141 acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
27142 - u32 reg, void *value, u32 width);
27143 + u32 reg, u32 *value, u32 width);
27146 acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
27147 diff -urNp linux-2.6.24.4/include/asm-alpha/a.out.h linux-2.6.24.4/include/asm-alpha/a.out.h
27148 --- linux-2.6.24.4/include/asm-alpha/a.out.h 2008-03-24 14:49:18.000000000 -0400
27149 +++ linux-2.6.24.4/include/asm-alpha/a.out.h 2008-03-26 20:21:09.000000000 -0400
27150 @@ -98,7 +98,7 @@ struct exec
27151 set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
27152 ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
27154 -#define STACK_TOP \
27155 +#define __STACK_TOP \
27156 (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
27158 #define STACK_TOP_MAX 0x00120000000UL
27159 diff -urNp linux-2.6.24.4/include/asm-alpha/elf.h linux-2.6.24.4/include/asm-alpha/elf.h
27160 --- linux-2.6.24.4/include/asm-alpha/elf.h 2008-03-24 14:49:18.000000000 -0400
27161 +++ linux-2.6.24.4/include/asm-alpha/elf.h 2008-03-26 20:21:09.000000000 -0400
27162 @@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
27164 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
27166 +#ifdef CONFIG_PAX_ASLR
27167 +#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
27169 +#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
27170 +#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
27173 /* $0 is set by ld.so to a pointer to a function which might be
27174 registered using atexit. This provides a mean for the dynamic
27175 linker to call DT_FINI functions for shared libraries that have
27176 diff -urNp linux-2.6.24.4/include/asm-alpha/kmap_types.h linux-2.6.24.4/include/asm-alpha/kmap_types.h
27177 --- linux-2.6.24.4/include/asm-alpha/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27178 +++ linux-2.6.24.4/include/asm-alpha/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27179 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
27184 +D(13) KM_CLEARPAGE,
27189 diff -urNp linux-2.6.24.4/include/asm-alpha/pgtable.h linux-2.6.24.4/include/asm-alpha/pgtable.h
27190 --- linux-2.6.24.4/include/asm-alpha/pgtable.h 2008-03-24 14:49:18.000000000 -0400
27191 +++ linux-2.6.24.4/include/asm-alpha/pgtable.h 2008-03-26 20:21:09.000000000 -0400
27192 @@ -101,6 +101,17 @@ struct vm_area_struct;
27193 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
27194 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
27195 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
27197 +#ifdef CONFIG_PAX_PAGEEXEC
27198 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
27199 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
27200 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
27202 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
27203 +# define PAGE_COPY_NOEXEC PAGE_COPY
27204 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
27207 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
27209 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
27210 diff -urNp linux-2.6.24.4/include/asm-arm/a.out.h linux-2.6.24.4/include/asm-arm/a.out.h
27211 --- linux-2.6.24.4/include/asm-arm/a.out.h 2008-03-24 14:49:18.000000000 -0400
27212 +++ linux-2.6.24.4/include/asm-arm/a.out.h 2008-03-26 20:21:09.000000000 -0400
27213 @@ -28,7 +28,7 @@ struct exec
27217 -#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
27218 +#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
27219 TASK_SIZE : TASK_SIZE_26)
27220 #define STACK_TOP_MAX TASK_SIZE
27222 diff -urNp linux-2.6.24.4/include/asm-arm/elf.h linux-2.6.24.4/include/asm-arm/elf.h
27223 --- linux-2.6.24.4/include/asm-arm/elf.h 2008-03-24 14:49:18.000000000 -0400
27224 +++ linux-2.6.24.4/include/asm-arm/elf.h 2008-03-26 20:21:09.000000000 -0400
27225 @@ -88,7 +88,14 @@ extern char elf_platform[];
27226 the loader. We need to make sure that it is out of the way of the program
27227 that it will "exec", and that there is sufficient room for the brk. */
27229 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
27230 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
27232 +#ifdef CONFIG_PAX_ASLR
27233 +#define PAX_ELF_ET_DYN_BASE 0x00008000UL
27235 +#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
27236 +#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
27239 /* When the program starts, a1 contains a pointer to a function to be
27240 registered with atexit, as per the SVR4 ABI. A value of 0 means we
27241 diff -urNp linux-2.6.24.4/include/asm-arm/kmap_types.h linux-2.6.24.4/include/asm-arm/kmap_types.h
27242 --- linux-2.6.24.4/include/asm-arm/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27243 +++ linux-2.6.24.4/include/asm-arm/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27244 @@ -18,6 +18,7 @@ enum km_type {
27252 diff -urNp linux-2.6.24.4/include/asm-avr32/a.out.h linux-2.6.24.4/include/asm-avr32/a.out.h
27253 --- linux-2.6.24.4/include/asm-avr32/a.out.h 2008-03-24 14:49:18.000000000 -0400
27254 +++ linux-2.6.24.4/include/asm-avr32/a.out.h 2008-03-26 20:21:09.000000000 -0400
27255 @@ -19,8 +19,8 @@ struct exec
27259 -#define STACK_TOP TASK_SIZE
27260 -#define STACK_TOP_MAX STACK_TOP
27261 +#define __STACK_TOP TASK_SIZE
27262 +#define STACK_TOP_MAX __STACK_TOP
27266 diff -urNp linux-2.6.24.4/include/asm-avr32/elf.h linux-2.6.24.4/include/asm-avr32/elf.h
27267 --- linux-2.6.24.4/include/asm-avr32/elf.h 2008-03-24 14:49:18.000000000 -0400
27268 +++ linux-2.6.24.4/include/asm-avr32/elf.h 2008-03-26 20:21:09.000000000 -0400
27269 @@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
27270 the loader. We need to make sure that it is out of the way of the program
27271 that it will "exec", and that there is sufficient room for the brk. */
27273 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
27274 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
27276 +#ifdef CONFIG_PAX_ASLR
27277 +#define PAX_ELF_ET_DYN_BASE 0x00001000UL
27279 +#define PAX_DELTA_MMAP_LEN 15
27280 +#define PAX_DELTA_STACK_LEN 15
27283 /* This yields a mask that user programs can use to figure out what
27284 instruction set this CPU supports. This could be done in user space,
27285 diff -urNp linux-2.6.24.4/include/asm-avr32/kmap_types.h linux-2.6.24.4/include/asm-avr32/kmap_types.h
27286 --- linux-2.6.24.4/include/asm-avr32/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27287 +++ linux-2.6.24.4/include/asm-avr32/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27288 @@ -22,7 +22,8 @@ D(10) KM_IRQ0,
27293 +D(14) KM_CLEARPAGE,
27298 diff -urNp linux-2.6.24.4/include/asm-blackfin/kmap_types.h linux-2.6.24.4/include/asm-blackfin/kmap_types.h
27299 --- linux-2.6.24.4/include/asm-blackfin/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27300 +++ linux-2.6.24.4/include/asm-blackfin/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27301 @@ -15,6 +15,7 @@ enum km_type {
27309 diff -urNp linux-2.6.24.4/include/asm-cris/kmap_types.h linux-2.6.24.4/include/asm-cris/kmap_types.h
27310 --- linux-2.6.24.4/include/asm-cris/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27311 +++ linux-2.6.24.4/include/asm-cris/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27312 @@ -19,6 +19,7 @@ enum km_type {
27320 diff -urNp linux-2.6.24.4/include/asm-frv/kmap_types.h linux-2.6.24.4/include/asm-frv/kmap_types.h
27321 --- linux-2.6.24.4/include/asm-frv/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27322 +++ linux-2.6.24.4/include/asm-frv/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27323 @@ -23,6 +23,7 @@ enum km_type {
27331 diff -urNp linux-2.6.24.4/include/asm-generic/futex.h linux-2.6.24.4/include/asm-generic/futex.h
27332 --- linux-2.6.24.4/include/asm-generic/futex.h 2008-03-24 14:49:18.000000000 -0400
27333 +++ linux-2.6.24.4/include/asm-generic/futex.h 2008-03-26 20:21:09.000000000 -0400
27335 #include <asm/uaccess.h>
27338 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
27339 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
27341 int op = (encoded_op >> 28) & 7;
27342 int cmp = (encoded_op >> 24) & 15;
27343 @@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op,
27347 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
27348 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
27352 diff -urNp linux-2.6.24.4/include/asm-generic/vmlinux.lds.h linux-2.6.24.4/include/asm-generic/vmlinux.lds.h
27353 --- linux-2.6.24.4/include/asm-generic/vmlinux.lds.h 2008-03-24 14:49:18.000000000 -0400
27354 +++ linux-2.6.24.4/include/asm-generic/vmlinux.lds.h 2008-03-26 20:21:09.000000000 -0400
27356 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
27357 VMLINUX_SYMBOL(__start_rodata) = .; \
27358 *(.rodata) *(.rodata.*) \
27359 + *(.data.read_only) \
27360 *(__vermagic) /* Kernel version magic */ \
27361 *(__markers_strings) /* Markers: strings */ \
27363 diff -urNp linux-2.6.24.4/include/asm-h8300/kmap_types.h linux-2.6.24.4/include/asm-h8300/kmap_types.h
27364 --- linux-2.6.24.4/include/asm-h8300/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27365 +++ linux-2.6.24.4/include/asm-h8300/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27366 @@ -15,6 +15,7 @@ enum km_type {
27374 diff -urNp linux-2.6.24.4/include/asm-ia64/elf.h linux-2.6.24.4/include/asm-ia64/elf.h
27375 --- linux-2.6.24.4/include/asm-ia64/elf.h 2008-03-24 14:49:18.000000000 -0400
27376 +++ linux-2.6.24.4/include/asm-ia64/elf.h 2008-03-26 20:21:09.000000000 -0400
27377 @@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
27378 typedef struct ia64_fpreg elf_fpreg_t;
27379 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
27381 +#ifdef CONFIG_PAX_ASLR
27382 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
27384 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
27385 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
27388 struct pt_regs; /* forward declaration... */
27389 extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
27390 diff -urNp linux-2.6.24.4/include/asm-ia64/kmap_types.h linux-2.6.24.4/include/asm-ia64/kmap_types.h
27391 --- linux-2.6.24.4/include/asm-ia64/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27392 +++ linux-2.6.24.4/include/asm-ia64/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27393 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
27398 +D(13) KM_CLEARPAGE,
27403 diff -urNp linux-2.6.24.4/include/asm-ia64/pgtable.h linux-2.6.24.4/include/asm-ia64/pgtable.h
27404 --- linux-2.6.24.4/include/asm-ia64/pgtable.h 2008-03-24 14:49:18.000000000 -0400
27405 +++ linux-2.6.24.4/include/asm-ia64/pgtable.h 2008-03-26 20:21:09.000000000 -0400
27406 @@ -143,6 +143,17 @@
27407 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
27408 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
27409 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
27411 +#ifdef CONFIG_PAX_PAGEEXEC
27412 +# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
27413 +# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
27414 +# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
27416 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
27417 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
27418 +# define PAGE_COPY_NOEXEC PAGE_COPY
27421 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
27422 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
27423 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
27424 diff -urNp linux-2.6.24.4/include/asm-ia64/processor.h linux-2.6.24.4/include/asm-ia64/processor.h
27425 --- linux-2.6.24.4/include/asm-ia64/processor.h 2008-03-24 14:49:18.000000000 -0400
27426 +++ linux-2.6.24.4/include/asm-ia64/processor.h 2008-03-26 20:21:09.000000000 -0400
27427 @@ -275,7 +275,7 @@ struct thread_struct {
27430 .map_base = DEFAULT_MAP_BASE, \
27431 - .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
27432 + .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \
27433 .task_size = DEFAULT_TASK_SIZE, \
27434 .last_fph_cpu = -1, \
27436 diff -urNp linux-2.6.24.4/include/asm-ia64/ustack.h linux-2.6.24.4/include/asm-ia64/ustack.h
27437 --- linux-2.6.24.4/include/asm-ia64/ustack.h 2008-03-24 14:49:18.000000000 -0400
27438 +++ linux-2.6.24.4/include/asm-ia64/ustack.h 2008-03-26 20:21:09.000000000 -0400
27441 /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
27442 #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
27443 -#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
27444 -#define STACK_TOP_MAX STACK_TOP
27445 +#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
27446 +#define STACK_TOP_MAX __STACK_TOP
27449 /* Make a default stack size of 2GiB */
27450 diff -urNp linux-2.6.24.4/include/asm-m32r/kmap_types.h linux-2.6.24.4/include/asm-m32r/kmap_types.h
27451 --- linux-2.6.24.4/include/asm-m32r/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27452 +++ linux-2.6.24.4/include/asm-m32r/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27453 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
27458 +D(13) KM_CLEARPAGE,
27463 diff -urNp linux-2.6.24.4/include/asm-m68k/kmap_types.h linux-2.6.24.4/include/asm-m68k/kmap_types.h
27464 --- linux-2.6.24.4/include/asm-m68k/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27465 +++ linux-2.6.24.4/include/asm-m68k/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27466 @@ -15,6 +15,7 @@ enum km_type {
27474 diff -urNp linux-2.6.24.4/include/asm-m68knommu/kmap_types.h linux-2.6.24.4/include/asm-m68knommu/kmap_types.h
27475 --- linux-2.6.24.4/include/asm-m68knommu/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27476 +++ linux-2.6.24.4/include/asm-m68knommu/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27477 @@ -15,6 +15,7 @@ enum km_type {
27485 diff -urNp linux-2.6.24.4/include/asm-mips/a.out.h linux-2.6.24.4/include/asm-mips/a.out.h
27486 --- linux-2.6.24.4/include/asm-mips/a.out.h 2008-03-24 14:49:18.000000000 -0400
27487 +++ linux-2.6.24.4/include/asm-mips/a.out.h 2008-03-26 20:21:09.000000000 -0400
27488 @@ -35,10 +35,10 @@ struct exec
27491 #ifdef CONFIG_32BIT
27492 -#define STACK_TOP TASK_SIZE
27493 +#define __STACK_TOP TASK_SIZE
27495 #ifdef CONFIG_64BIT
27496 -#define STACK_TOP \
27497 +#define __STACK_TOP \
27498 (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
27500 #define STACK_TOP_MAX TASK_SIZE
27501 diff -urNp linux-2.6.24.4/include/asm-mips/elf.h linux-2.6.24.4/include/asm-mips/elf.h
27502 --- linux-2.6.24.4/include/asm-mips/elf.h 2008-03-24 14:49:18.000000000 -0400
27503 +++ linux-2.6.24.4/include/asm-mips/elf.h 2008-03-26 20:21:09.000000000 -0400
27504 @@ -372,4 +372,11 @@ extern int dump_task_fpu(struct task_str
27505 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
27508 +#ifdef CONFIG_PAX_ASLR
27509 +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
27511 +#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
27512 +#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
27515 #endif /* _ASM_ELF_H */
27516 diff -urNp linux-2.6.24.4/include/asm-mips/kmap_types.h linux-2.6.24.4/include/asm-mips/kmap_types.h
27517 --- linux-2.6.24.4/include/asm-mips/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27518 +++ linux-2.6.24.4/include/asm-mips/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27519 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
27524 +D(13) KM_CLEARPAGE,
27529 diff -urNp linux-2.6.24.4/include/asm-mips/page.h linux-2.6.24.4/include/asm-mips/page.h
27530 --- linux-2.6.24.4/include/asm-mips/page.h 2008-03-24 14:49:18.000000000 -0400
27531 +++ linux-2.6.24.4/include/asm-mips/page.h 2008-03-26 20:21:09.000000000 -0400
27532 @@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
27533 #ifdef CONFIG_CPU_MIPS32
27534 typedef struct { unsigned long pte_low, pte_high; } pte_t;
27535 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
27536 - #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
27537 + #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
27539 typedef struct { unsigned long long pte; } pte_t;
27540 #define pte_val(x) ((x).pte)
27541 diff -urNp linux-2.6.24.4/include/asm-mips/system.h linux-2.6.24.4/include/asm-mips/system.h
27542 --- linux-2.6.24.4/include/asm-mips/system.h 2008-03-24 14:49:18.000000000 -0400
27543 +++ linux-2.6.24.4/include/asm-mips/system.h 2008-03-26 20:21:09.000000000 -0400
27544 @@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
27546 #define __ARCH_WANT_UNLOCKED_CTXSW
27548 -extern unsigned long arch_align_stack(unsigned long sp);
27549 +#define arch_align_stack(x) (x)
27551 #endif /* _ASM_SYSTEM_H */
27552 diff -urNp linux-2.6.24.4/include/asm-parisc/a.out.h linux-2.6.24.4/include/asm-parisc/a.out.h
27553 --- linux-2.6.24.4/include/asm-parisc/a.out.h 2008-03-24 14:49:18.000000000 -0400
27554 +++ linux-2.6.24.4/include/asm-parisc/a.out.h 2008-03-26 20:21:09.000000000 -0400
27555 @@ -22,7 +22,7 @@ struct exec
27556 /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
27559 -#define STACK_TOP TASK_SIZE
27560 +#define __STACK_TOP TASK_SIZE
27561 #define STACK_TOP_MAX DEFAULT_TASK_SIZE
27564 diff -urNp linux-2.6.24.4/include/asm-parisc/elf.h linux-2.6.24.4/include/asm-parisc/elf.h
27565 --- linux-2.6.24.4/include/asm-parisc/elf.h 2008-03-24 14:49:18.000000000 -0400
27566 +++ linux-2.6.24.4/include/asm-parisc/elf.h 2008-03-26 20:21:09.000000000 -0400
27567 @@ -337,6 +337,13 @@ struct pt_regs; /* forward declaration..
27569 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
27571 +#ifdef CONFIG_PAX_ASLR
27572 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
27574 +#define PAX_DELTA_MMAP_LEN 16
27575 +#define PAX_DELTA_STACK_LEN 16
27578 /* This yields a mask that user programs can use to figure out what
27579 instruction set this CPU supports. This could be done in user space,
27580 but it's not easy, and we've already done it here. */
27581 diff -urNp linux-2.6.24.4/include/asm-parisc/kmap_types.h linux-2.6.24.4/include/asm-parisc/kmap_types.h
27582 --- linux-2.6.24.4/include/asm-parisc/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27583 +++ linux-2.6.24.4/include/asm-parisc/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27584 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
27589 +D(13) KM_CLEARPAGE,
27594 diff -urNp linux-2.6.24.4/include/asm-parisc/pgtable.h linux-2.6.24.4/include/asm-parisc/pgtable.h
27595 --- linux-2.6.24.4/include/asm-parisc/pgtable.h 2008-03-24 14:49:18.000000000 -0400
27596 +++ linux-2.6.24.4/include/asm-parisc/pgtable.h 2008-03-26 20:21:09.000000000 -0400
27597 @@ -210,6 +210,17 @@ extern void *vmalloc_start;
27598 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
27599 #define PAGE_COPY PAGE_EXECREAD
27600 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
27602 +#ifdef CONFIG_PAX_PAGEEXEC
27603 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
27604 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
27605 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
27607 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
27608 +# define PAGE_COPY_NOEXEC PAGE_COPY
27609 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
27612 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
27613 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
27614 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
27615 diff -urNp linux-2.6.24.4/include/asm-powerpc/a.out.h linux-2.6.24.4/include/asm-powerpc/a.out.h
27616 --- linux-2.6.24.4/include/asm-powerpc/a.out.h 2008-03-24 14:49:18.000000000 -0400
27617 +++ linux-2.6.24.4/include/asm-powerpc/a.out.h 2008-03-26 20:21:09.000000000 -0400
27618 @@ -23,15 +23,15 @@ struct exec
27619 #define STACK_TOP_USER64 TASK_SIZE_USER64
27620 #define STACK_TOP_USER32 TASK_SIZE_USER32
27622 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
27623 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
27624 STACK_TOP_USER32 : STACK_TOP_USER64)
27626 #define STACK_TOP_MAX STACK_TOP_USER64
27628 #else /* __powerpc64__ */
27630 -#define STACK_TOP TASK_SIZE
27631 -#define STACK_TOP_MAX STACK_TOP
27632 +#define __STACK_TOP TASK_SIZE
27633 +#define STACK_TOP_MAX __STACK_TOP
27635 #endif /* __powerpc64__ */
27636 #endif /* __KERNEL__ */
27637 diff -urNp linux-2.6.24.4/include/asm-powerpc/elf.h linux-2.6.24.4/include/asm-powerpc/elf.h
27638 --- linux-2.6.24.4/include/asm-powerpc/elf.h 2008-03-24 14:49:18.000000000 -0400
27639 +++ linux-2.6.24.4/include/asm-powerpc/elf.h 2008-03-26 20:21:09.000000000 -0400
27640 @@ -160,6 +160,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
27641 typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
27644 +#ifdef CONFIG_PAX_ASLR
27645 +#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
27647 +#ifdef __powerpc64__
27648 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
27649 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
27651 +#define PAX_DELTA_MMAP_LEN 15
27652 +#define PAX_DELTA_STACK_LEN 15
27658 * This is used to ensure we don't load something for the wrong architecture.
27659 diff -urNp linux-2.6.24.4/include/asm-powerpc/kmap_types.h linux-2.6.24.4/include/asm-powerpc/kmap_types.h
27660 --- linux-2.6.24.4/include/asm-powerpc/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27661 +++ linux-2.6.24.4/include/asm-powerpc/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27662 @@ -26,6 +26,7 @@ enum km_type {
27665 KM_PPC_SYNC_ICACHE,
27670 diff -urNp linux-2.6.24.4/include/asm-powerpc/page_64.h linux-2.6.24.4/include/asm-powerpc/page_64.h
27671 --- linux-2.6.24.4/include/asm-powerpc/page_64.h 2008-03-24 14:49:18.000000000 -0400
27672 +++ linux-2.6.24.4/include/asm-powerpc/page_64.h 2008-03-26 20:21:09.000000000 -0400
27673 @@ -171,15 +171,18 @@ do { \
27674 * stack by default, so in the absense of a PT_GNU_STACK program header
27675 * we turn execute permission off.
27677 -#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
27678 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27679 +#define VM_STACK_DEFAULT_FLAGS32 \
27680 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
27681 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27683 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
27684 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27686 +#ifndef CONFIG_PAX_PAGEEXEC
27687 #define VM_STACK_DEFAULT_FLAGS \
27688 (test_thread_flag(TIF_32BIT) ? \
27689 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
27692 #include <asm-generic/page.h>
27694 diff -urNp linux-2.6.24.4/include/asm-powerpc/page.h linux-2.6.24.4/include/asm-powerpc/page.h
27695 --- linux-2.6.24.4/include/asm-powerpc/page.h 2008-03-24 14:49:18.000000000 -0400
27696 +++ linux-2.6.24.4/include/asm-powerpc/page.h 2008-03-26 20:21:09.000000000 -0400
27698 * and needs to be executable. This means the whole heap ends
27699 * up being executable.
27701 -#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
27702 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27703 +#define VM_DATA_DEFAULT_FLAGS32 \
27704 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
27705 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27707 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
27708 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27709 diff -urNp linux-2.6.24.4/include/asm-ppc/mmu_context.h linux-2.6.24.4/include/asm-ppc/mmu_context.h
27710 --- linux-2.6.24.4/include/asm-ppc/mmu_context.h 2008-03-24 14:49:18.000000000 -0400
27711 +++ linux-2.6.24.4/include/asm-ppc/mmu_context.h 2008-03-26 20:21:09.000000000 -0400
27712 @@ -146,7 +146,8 @@ static inline void get_mmu_context(struc
27713 static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
27715 mm->context.id = NO_CONTEXT;
27716 - mm->context.vdso_base = 0;
27717 + if (t == current)
27718 + mm->context.vdso_base = ~0UL;
27722 diff -urNp linux-2.6.24.4/include/asm-ppc/pgtable.h linux-2.6.24.4/include/asm-ppc/pgtable.h
27723 --- linux-2.6.24.4/include/asm-ppc/pgtable.h 2008-03-24 14:49:18.000000000 -0400
27724 +++ linux-2.6.24.4/include/asm-ppc/pgtable.h 2008-03-26 20:21:09.000000000 -0400
27725 @@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
27727 #define PAGE_NONE __pgprot(_PAGE_BASE)
27728 #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
27729 -#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
27730 +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
27731 #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
27732 -#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
27733 +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
27734 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
27735 -#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
27736 +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
27738 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
27739 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
27740 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
27741 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
27743 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
27744 +# define PAGE_COPY_NOEXEC PAGE_COPY
27745 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
27748 #define PAGE_KERNEL __pgprot(_PAGE_RAM)
27749 #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
27750 @@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
27751 * This is the closest we can get..
27753 #define __P000 PAGE_NONE
27754 -#define __P001 PAGE_READONLY_X
27755 -#define __P010 PAGE_COPY
27756 -#define __P011 PAGE_COPY_X
27757 -#define __P100 PAGE_READONLY
27758 +#define __P001 PAGE_READONLY_NOEXEC
27759 +#define __P010 PAGE_COPY_NOEXEC
27760 +#define __P011 PAGE_COPY_NOEXEC
27761 +#define __P100 PAGE_READONLY_X
27762 #define __P101 PAGE_READONLY_X
27763 -#define __P110 PAGE_COPY
27764 +#define __P110 PAGE_COPY_X
27765 #define __P111 PAGE_COPY_X
27767 #define __S000 PAGE_NONE
27768 -#define __S001 PAGE_READONLY_X
27769 -#define __S010 PAGE_SHARED
27770 -#define __S011 PAGE_SHARED_X
27771 -#define __S100 PAGE_READONLY
27772 +#define __S001 PAGE_READONLY_NOEXEC
27773 +#define __S010 PAGE_SHARED_NOEXEC
27774 +#define __S011 PAGE_SHARED_NOEXEC
27775 +#define __S100 PAGE_READONLY_X
27776 #define __S101 PAGE_READONLY_X
27777 -#define __S110 PAGE_SHARED
27778 +#define __S110 PAGE_SHARED_X
27779 #define __S111 PAGE_SHARED_X
27781 #ifndef __ASSEMBLY__
27782 diff -urNp linux-2.6.24.4/include/asm-s390/kmap_types.h linux-2.6.24.4/include/asm-s390/kmap_types.h
27783 --- linux-2.6.24.4/include/asm-s390/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27784 +++ linux-2.6.24.4/include/asm-s390/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27785 @@ -16,6 +16,7 @@ enum km_type {
27793 diff -urNp linux-2.6.24.4/include/asm-sh/kmap_types.h linux-2.6.24.4/include/asm-sh/kmap_types.h
27794 --- linux-2.6.24.4/include/asm-sh/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27795 +++ linux-2.6.24.4/include/asm-sh/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27796 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
27801 +D(13) KM_CLEARPAGE,
27806 diff -urNp linux-2.6.24.4/include/asm-sparc/a.out.h linux-2.6.24.4/include/asm-sparc/a.out.h
27807 --- linux-2.6.24.4/include/asm-sparc/a.out.h 2008-03-24 14:49:18.000000000 -0400
27808 +++ linux-2.6.24.4/include/asm-sparc/a.out.h 2008-03-26 20:21:09.000000000 -0400
27809 @@ -91,8 +91,8 @@ struct relocation_info /* used when head
27811 #include <asm/page.h>
27813 -#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
27814 -#define STACK_TOP_MAX STACK_TOP
27815 +#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
27816 +#define STACK_TOP_MAX __STACK_TOP
27818 #endif /* __KERNEL__ */
27820 diff -urNp linux-2.6.24.4/include/asm-sparc/elf.h linux-2.6.24.4/include/asm-sparc/elf.h
27821 --- linux-2.6.24.4/include/asm-sparc/elf.h 2008-03-24 14:49:18.000000000 -0400
27822 +++ linux-2.6.24.4/include/asm-sparc/elf.h 2008-03-26 20:21:09.000000000 -0400
27823 @@ -143,6 +143,13 @@ do { unsigned long *dest = &(__elf_regs[
27825 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
27827 +#ifdef CONFIG_PAX_ASLR
27828 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
27830 +#define PAX_DELTA_MMAP_LEN 16
27831 +#define PAX_DELTA_STACK_LEN 16
27834 /* This yields a mask that user programs can use to figure out what
27835 instruction set this cpu supports. This can NOT be done in userspace
27837 diff -urNp linux-2.6.24.4/include/asm-sparc/kmap_types.h linux-2.6.24.4/include/asm-sparc/kmap_types.h
27838 --- linux-2.6.24.4/include/asm-sparc/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27839 +++ linux-2.6.24.4/include/asm-sparc/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27840 @@ -15,6 +15,7 @@ enum km_type {
27848 diff -urNp linux-2.6.24.4/include/asm-sparc/pgtable.h linux-2.6.24.4/include/asm-sparc/pgtable.h
27849 --- linux-2.6.24.4/include/asm-sparc/pgtable.h 2008-03-24 14:49:18.000000000 -0400
27850 +++ linux-2.6.24.4/include/asm-sparc/pgtable.h 2008-03-26 20:21:09.000000000 -0400
27851 @@ -69,6 +69,16 @@ extern pgprot_t PAGE_SHARED;
27852 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
27853 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
27855 +#ifdef CONFIG_PAX_PAGEEXEC
27856 +extern pgprot_t PAGE_SHARED_NOEXEC;
27857 +# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
27858 +# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
27860 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
27861 +# define PAGE_COPY_NOEXEC PAGE_COPY
27862 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
27865 extern unsigned long page_kernel;
27868 diff -urNp linux-2.6.24.4/include/asm-sparc/pgtsrmmu.h linux-2.6.24.4/include/asm-sparc/pgtsrmmu.h
27869 --- linux-2.6.24.4/include/asm-sparc/pgtsrmmu.h 2008-03-24 14:49:18.000000000 -0400
27870 +++ linux-2.6.24.4/include/asm-sparc/pgtsrmmu.h 2008-03-26 20:21:09.000000000 -0400
27871 @@ -115,6 +115,16 @@
27872 SRMMU_EXEC | SRMMU_REF)
27873 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
27874 SRMMU_EXEC | SRMMU_REF)
27876 +#ifdef CONFIG_PAX_PAGEEXEC
27877 +#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
27878 + SRMMU_WRITE | SRMMU_REF)
27879 +#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
27881 +#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
27885 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
27886 SRMMU_DIRTY | SRMMU_REF)
27888 diff -urNp linux-2.6.24.4/include/asm-sparc/uaccess.h linux-2.6.24.4/include/asm-sparc/uaccess.h
27889 --- linux-2.6.24.4/include/asm-sparc/uaccess.h 2008-03-24 14:49:18.000000000 -0400
27890 +++ linux-2.6.24.4/include/asm-sparc/uaccess.h 2008-03-26 20:21:09.000000000 -0400
27892 * No one can read/write anything from userland in the kernel space by setting
27893 * large size and address near to PAGE_OFFSET - a fault will break his intentions.
27895 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
27896 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
27897 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
27898 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
27899 #define access_ok(type, addr, size) \
27900 diff -urNp linux-2.6.24.4/include/asm-sparc64/a.out.h linux-2.6.24.4/include/asm-sparc64/a.out.h
27901 --- linux-2.6.24.4/include/asm-sparc64/a.out.h 2008-03-24 14:49:18.000000000 -0400
27902 +++ linux-2.6.24.4/include/asm-sparc64/a.out.h 2008-03-26 20:21:09.000000000 -0400
27903 @@ -98,7 +98,7 @@ struct relocation_info /* used when head
27904 #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
27905 #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL))
27907 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
27908 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
27909 STACK_TOP32 : STACK_TOP64)
27911 #define STACK_TOP_MAX STACK_TOP64
27912 diff -urNp linux-2.6.24.4/include/asm-sparc64/elf.h linux-2.6.24.4/include/asm-sparc64/elf.h
27913 --- linux-2.6.24.4/include/asm-sparc64/elf.h 2008-03-24 14:49:18.000000000 -0400
27914 +++ linux-2.6.24.4/include/asm-sparc64/elf.h 2008-03-26 20:21:09.000000000 -0400
27915 @@ -143,6 +143,12 @@ typedef struct {
27916 #define ELF_ET_DYN_BASE 0x0000010000000000UL
27919 +#ifdef CONFIG_PAX_ASLR
27920 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
27922 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
27923 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
27926 /* This yields a mask that user programs can use to figure out what
27927 instruction set this cpu supports. */
27928 diff -urNp linux-2.6.24.4/include/asm-sparc64/kmap_types.h linux-2.6.24.4/include/asm-sparc64/kmap_types.h
27929 --- linux-2.6.24.4/include/asm-sparc64/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27930 +++ linux-2.6.24.4/include/asm-sparc64/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27931 @@ -19,6 +19,7 @@ enum km_type {
27939 diff -urNp linux-2.6.24.4/include/asm-um/kmap_types.h linux-2.6.24.4/include/asm-um/kmap_types.h
27940 --- linux-2.6.24.4/include/asm-um/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27941 +++ linux-2.6.24.4/include/asm-um/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27942 @@ -23,6 +23,7 @@ enum km_type {
27950 diff -urNp linux-2.6.24.4/include/asm-v850/kmap_types.h linux-2.6.24.4/include/asm-v850/kmap_types.h
27951 --- linux-2.6.24.4/include/asm-v850/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
27952 +++ linux-2.6.24.4/include/asm-v850/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
27953 @@ -13,6 +13,7 @@ enum km_type {
27961 diff -urNp linux-2.6.24.4/include/asm-x86/alternative_32.h linux-2.6.24.4/include/asm-x86/alternative_32.h
27962 --- linux-2.6.24.4/include/asm-x86/alternative_32.h 2008-03-24 14:49:18.000000000 -0400
27963 +++ linux-2.6.24.4/include/asm-x86/alternative_32.h 2008-03-26 20:21:09.000000000 -0400
27964 @@ -54,7 +54,7 @@ static inline void alternatives_smp_swit
27965 " .byte 662b-661b\n" /* sourcelen */ \
27966 " .byte 664f-663f\n" /* replacementlen */ \
27968 - ".section .altinstr_replacement,\"ax\"\n" \
27969 + ".section .altinstr_replacement,\"a\"\n" \
27970 "663:\n\t" newinstr "\n664:\n" /* replacement */\
27971 ".previous" :: "i" (feature) : "memory")
27973 @@ -78,7 +78,7 @@ static inline void alternatives_smp_swit
27974 " .byte 662b-661b\n" /* sourcelen */ \
27975 " .byte 664f-663f\n" /* replacementlen */ \
27977 - ".section .altinstr_replacement,\"ax\"\n" \
27978 + ".section .altinstr_replacement,\"a\"\n" \
27979 "663:\n\t" newinstr "\n664:\n" /* replacement */\
27980 ".previous" :: "i" (feature), ##input)
27982 @@ -93,7 +93,7 @@ static inline void alternatives_smp_swit
27983 " .byte 662b-661b\n" /* sourcelen */ \
27984 " .byte 664f-663f\n" /* replacementlen */ \
27986 - ".section .altinstr_replacement,\"ax\"\n" \
27987 + ".section .altinstr_replacement,\"a\"\n" \
27988 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
27989 ".previous" : output : [feat] "i" (feature), ##input)
27991 diff -urNp linux-2.6.24.4/include/asm-x86/alternative_64.h linux-2.6.24.4/include/asm-x86/alternative_64.h
27992 --- linux-2.6.24.4/include/asm-x86/alternative_64.h 2008-03-24 14:49:18.000000000 -0400
27993 +++ linux-2.6.24.4/include/asm-x86/alternative_64.h 2008-03-26 20:21:09.000000000 -0400
27994 @@ -94,7 +94,7 @@ static inline void alternatives_smp_swit
27995 " .byte 662b-661b\n" /* sourcelen */ \
27996 " .byte 664f-663f\n" /* replacementlen */ \
27998 - ".section .altinstr_replacement,\"ax\"\n" \
27999 + ".section .altinstr_replacement,\"a\"\n" \
28000 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
28001 ".previous" :: "i" (feature) : "memory")
28003 @@ -118,7 +118,7 @@ static inline void alternatives_smp_swit
28004 " .byte 662b-661b\n" /* sourcelen */ \
28005 " .byte 664f-663f\n" /* replacementlen */ \
28007 - ".section .altinstr_replacement,\"ax\"\n" \
28008 + ".section .altinstr_replacement,\"a\"\n" \
28009 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
28010 ".previous" :: "i" (feature), ##input)
28012 @@ -133,7 +133,7 @@ static inline void alternatives_smp_swit
28013 " .byte 662b-661b\n" /* sourcelen */ \
28014 " .byte 664f-663f\n" /* replacementlen */ \
28016 - ".section .altinstr_replacement,\"ax\"\n" \
28017 + ".section .altinstr_replacement,\"a\"\n" \
28018 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
28019 ".previous" : output : [feat] "i" (feature), ##input)
28021 diff -urNp linux-2.6.24.4/include/asm-x86/a.out.h linux-2.6.24.4/include/asm-x86/a.out.h
28022 --- linux-2.6.24.4/include/asm-x86/a.out.h 2008-03-24 14:49:18.000000000 -0400
28023 +++ linux-2.6.24.4/include/asm-x86/a.out.h 2008-03-26 20:21:09.000000000 -0400
28024 @@ -19,9 +19,13 @@ struct exec
28027 # include <linux/thread_info.h>
28028 -# define STACK_TOP TASK_SIZE
28029 +# ifdef CONFIG_PAX_SEGMEXEC
28030 +# define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
28032 +# define __STACK_TOP TASK_SIZE
28034 # ifdef CONFIG_X86_32
28035 -# define STACK_TOP_MAX STACK_TOP
28036 +# define STACK_TOP_MAX TASK_SIZE
28038 # define STACK_TOP_MAX TASK_SIZE64
28040 diff -urNp linux-2.6.24.4/include/asm-x86/apic_32.h linux-2.6.24.4/include/asm-x86/apic_32.h
28041 --- linux-2.6.24.4/include/asm-x86/apic_32.h 2008-03-24 14:49:18.000000000 -0400
28042 +++ linux-2.6.24.4/include/asm-x86/apic_32.h 2008-03-26 20:21:09.000000000 -0400
28044 #include <asm/processor.h>
28045 #include <asm/system.h>
28047 -#define Dprintk(x...)
28048 +#define Dprintk(x...) do {} while (0)
28052 diff -urNp linux-2.6.24.4/include/asm-x86/apic_64.h linux-2.6.24.4/include/asm-x86/apic_64.h
28053 --- linux-2.6.24.4/include/asm-x86/apic_64.h 2008-03-24 14:49:18.000000000 -0400
28054 +++ linux-2.6.24.4/include/asm-x86/apic_64.h 2008-03-26 20:21:09.000000000 -0400
28056 #include <asm/apicdef.h>
28057 #include <asm/system.h>
28059 -#define Dprintk(x...)
28060 +#define Dprintk(x...) do {} while (0)
28064 diff -urNp linux-2.6.24.4/include/asm-x86/boot.h linux-2.6.24.4/include/asm-x86/boot.h
28065 --- linux-2.6.24.4/include/asm-x86/boot.h 2008-03-24 14:49:18.000000000 -0400
28066 +++ linux-2.6.24.4/include/asm-x86/boot.h 2008-03-26 20:21:09.000000000 -0400
28068 #define ASK_VGA 0xfffd /* ask for it at bootup */
28070 /* Physical address where kernel should be loaded. */
28071 -#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
28072 +#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
28073 + (CONFIG_PHYSICAL_ALIGN - 1)) \
28074 & ~(CONFIG_PHYSICAL_ALIGN - 1))
28076 +#ifndef __ASSEMBLY__
28077 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
28078 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
28081 #endif /* _ASM_BOOT_H */
28082 diff -urNp linux-2.6.24.4/include/asm-x86/cache.h linux-2.6.24.4/include/asm-x86/cache.h
28083 --- linux-2.6.24.4/include/asm-x86/cache.h 2008-03-24 14:49:18.000000000 -0400
28084 +++ linux-2.6.24.4/include/asm-x86/cache.h 2008-03-26 20:21:09.000000000 -0400
28086 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
28088 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
28089 +#define __read_only __attribute__((__section__(".data.read_only")))
28091 #ifdef CONFIG_X86_VSMP
28092 /* vSMP Internode cacheline shift */
28093 diff -urNp linux-2.6.24.4/include/asm-x86/checksum_32.h linux-2.6.24.4/include/asm-x86/checksum_32.h
28094 --- linux-2.6.24.4/include/asm-x86/checksum_32.h 2008-03-24 14:49:18.000000000 -0400
28095 +++ linux-2.6.24.4/include/asm-x86/checksum_32.h 2008-03-26 20:21:09.000000000 -0400
28096 @@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
28097 asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
28098 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
28100 +asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
28101 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
28103 +asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
28104 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
28107 * Note: when you get a NULL pointer exception here this means someone
28108 * passed in an incorrect kernel address to one of these functions.
28109 @@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
28110 int len, __wsum sum, int *err_ptr)
28113 - return csum_partial_copy_generic((__force void *)src, dst,
28114 + return csum_partial_copy_generic_from_user((__force void *)src, dst,
28115 len, sum, err_ptr, NULL);
28118 @@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
28121 if (access_ok(VERIFY_WRITE, dst, len))
28122 - return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
28123 + return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
28126 *err_ptr = -EFAULT;
28127 diff -urNp linux-2.6.24.4/include/asm-x86/desc_32.h linux-2.6.24.4/include/asm-x86/desc_32.h
28128 --- linux-2.6.24.4/include/asm-x86/desc_32.h 2008-03-24 14:49:18.000000000 -0400
28129 +++ linux-2.6.24.4/include/asm-x86/desc_32.h 2008-03-26 20:21:09.000000000 -0400
28131 #ifndef __ASSEMBLY__
28133 #include <linux/preempt.h>
28134 -#include <linux/smp.h>
28135 #include <linux/percpu.h>
28136 +#include <linux/smp.h>
28138 #include <asm/mmu.h>
28140 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
28142 struct Xgt_desc_struct {
28143 unsigned short size;
28144 - unsigned long address __attribute__((packed));
28145 + struct desc_struct *address __attribute__((packed));
28146 unsigned short pad;
28147 } __attribute__ ((packed));
28151 - struct desc_struct gdt[GDT_ENTRIES];
28152 -} __attribute__((aligned(PAGE_SIZE)));
28153 -DECLARE_PER_CPU(struct gdt_page, gdt_page);
28155 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
28157 - return per_cpu(gdt_page, cpu).gdt;
28158 + return cpu_gdt_table[cpu];
28161 extern struct Xgt_desc_struct idt_descr;
28162 -extern struct desc_struct idt_table[];
28163 +extern struct desc_struct idt_table[256];
28164 extern void set_intr_gate(unsigned int irq, void * addr);
28166 static inline void pack_descriptor(__u32 *a, __u32 *b,
28167 @@ -81,8 +77,20 @@ static inline void pack_gate(__u32 *a, _
28168 static inline void write_dt_entry(struct desc_struct *dt,
28169 int entry, u32 entry_low, u32 entry_high)
28172 +#ifdef CONFIG_PAX_KERNEXEC
28173 + unsigned long cr0;
28175 + pax_open_kernel(cr0);
28178 dt[entry].a = entry_low;
28179 dt[entry].b = entry_high;
28181 +#ifdef CONFIG_PAX_KERNEXEC
28182 + pax_close_kernel(cr0);
28187 static inline void native_set_ldt(const void *addr, unsigned int entries)
28188 @@ -139,8 +147,19 @@ static inline void native_load_tls(struc
28190 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
28192 +#ifdef CONFIG_PAX_KERNEXEC
28193 + unsigned long cr0;
28195 + pax_open_kernel(cr0);
28198 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
28199 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
28201 +#ifdef CONFIG_PAX_KERNEXEC
28202 + pax_close_kernel(cr0);
28207 static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
28208 @@ -175,7 +194,7 @@ static inline void __set_tss_desc(unsign
28209 ((info)->seg_32bit << 22) | \
28210 ((info)->limit_in_pages << 23) | \
28211 ((info)->useable << 20) | \
28215 #define LDT_empty(info) (\
28216 (info)->base_addr == 0 && \
28217 @@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t
28221 -static inline unsigned long get_desc_base(unsigned long *desc)
28222 +static inline unsigned long get_desc_base(struct desc_struct *desc)
28224 unsigned long base;
28225 - base = ((desc[0] >> 16) & 0x0000ffff) |
28226 - ((desc[1] << 16) & 0x00ff0000) |
28227 - (desc[1] & 0xff000000);
28228 + base = ((desc->a >> 16) & 0x0000ffff) |
28229 + ((desc->b << 16) & 0x00ff0000) |
28230 + (desc->b & 0xff000000);
28234 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
28238 + if (likely(limit))
28239 + limit = (limit - 1UL) >> PAGE_SHIFT;
28240 + pack_descriptor(&a, &b, base, limit, 0xFB, 0xC);
28241 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
28244 #else /* __ASSEMBLY__ */
28247 diff -urNp linux-2.6.24.4/include/asm-x86/desc_64.h linux-2.6.24.4/include/asm-x86/desc_64.h
28248 --- linux-2.6.24.4/include/asm-x86/desc_64.h 2008-03-24 14:49:18.000000000 -0400
28249 +++ linux-2.6.24.4/include/asm-x86/desc_64.h 2008-03-26 20:21:09.000000000 -0400
28251 #include <asm/segment.h>
28252 #include <asm/mmu.h>
28254 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
28255 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
28257 #define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8))
28258 #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
28259 @@ -34,12 +34,10 @@ static inline unsigned long __store_tr(v
28260 * This is the ldt that every process will get unless we need
28261 * something other than this.
28263 -extern struct desc_struct default_ldt[];
28264 extern struct gate_struct idt_table[];
28265 -extern struct desc_ptr cpu_gdt_descr[];
28267 /* the cpu gdt accessor */
28268 -#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
28269 +#define cpu_gdt(_cpu) (cpu_gdt_table[_cpu])
28271 static inline void load_gdt(const struct desc_ptr *ptr)
28273 @@ -54,6 +52,11 @@ static inline void store_gdt(struct desc
28274 static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)
28276 struct gate_struct s;
28278 +#ifdef CONFIG_PAX_KERNEXEC
28279 + unsigned long cr0;
28282 s.offset_low = PTR_LOW(func);
28283 s.segment = __KERNEL_CS;
28285 @@ -65,7 +68,17 @@ static inline void _set_gate(void *adr,
28286 s.offset_middle = PTR_MIDDLE(func);
28287 s.offset_high = PTR_HIGH(func);
28288 /* does not need to be atomic because it is only done once at setup time */
28290 +#ifdef CONFIG_PAX_KERNEXEC
28291 + pax_open_kernel(cr0);
28294 memcpy(adr, &s, 16);
28296 +#ifdef CONFIG_PAX_KERNEXEC
28297 + pax_close_kernel(cr0);
28302 static inline void set_intr_gate(int nr, void *func)
28303 @@ -105,6 +118,11 @@ static inline void set_tssldt_descriptor
28306 struct ldttss_desc d;
28308 +#ifdef CONFIG_PAX_KERNEXEC
28309 + unsigned long cr0;
28312 memset(&d,0,sizeof(d));
28313 d.limit0 = size & 0xFFFF;
28314 d.base0 = PTR_LOW(tss);
28315 @@ -114,7 +132,17 @@ static inline void set_tssldt_descriptor
28316 d.limit1 = (size >> 16) & 0xF;
28317 d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF;
28318 d.base3 = PTR_HIGH(tss);
28320 +#ifdef CONFIG_PAX_KERNEXEC
28321 + pax_open_kernel(cr0);
28324 memcpy(ptr, &d, 16);
28326 +#ifdef CONFIG_PAX_KERNEXEC
28327 + pax_close_kernel(cr0);
28332 static inline void set_tss_desc(unsigned cpu, void *addr)
28333 @@ -152,7 +180,7 @@ static inline void set_ldt_desc(unsigned
28334 ((info)->limit_in_pages << 23) | \
28335 ((info)->useable << 20) | \
28336 /* ((info)->lm << 21) | */ \
28340 #define LDT_empty(info) (\
28341 (info)->base_addr == 0 && \
28342 @@ -170,8 +198,19 @@ static inline void load_TLS(struct threa
28344 u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN);
28346 +#ifdef CONFIG_PAX_KERNEXEC
28347 + unsigned long cr0;
28349 + pax_open_kernel(cr0);
28352 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
28353 gdt[i] = t->tls_array[i];
28355 +#ifdef CONFIG_PAX_KERNEXEC
28356 + pax_close_kernel(cr0);
28362 @@ -197,7 +236,7 @@ static inline void load_LDT(mm_context_t
28366 -extern struct desc_ptr idt_descr;
28367 +extern const struct desc_ptr idt_descr;
28369 #endif /* !__ASSEMBLY__ */
28371 diff -urNp linux-2.6.24.4/include/asm-x86/elf.h linux-2.6.24.4/include/asm-x86/elf.h
28372 --- linux-2.6.24.4/include/asm-x86/elf.h 2008-03-24 14:49:18.000000000 -0400
28373 +++ linux-2.6.24.4/include/asm-x86/elf.h 2008-03-26 20:21:09.000000000 -0400
28374 @@ -206,7 +206,25 @@ extern int vdso_enabled;
28375 the loader. We need to make sure that it is out of the way of the program
28376 that it will "exec", and that there is sufficient room for the brk. */
28378 +#ifdef CONFIG_PAX_SEGMEXEC
28379 +#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
28381 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
28384 +#ifdef CONFIG_PAX_ASLR
28385 +#ifdef CONFIG_X86_32
28386 +#define PAX_ELF_ET_DYN_BASE 0x10000000UL
28388 +#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
28389 +#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
28391 +#define PAX_ELF_ET_DYN_BASE 0x400000UL
28393 +#define PAX_DELTA_MMAP_LEN 32
28394 +#define PAX_DELTA_STACK_LEN 32
28398 /* This yields a mask that user programs can use to figure out what
28399 instruction set this CPU supports. This could be done in user space,
28400 @@ -246,7 +264,7 @@ extern int dump_task_extended_fpu (struc
28401 #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
28403 #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
28404 -#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
28405 +#define VDSO_CURRENT_BASE (current->mm->context.vdso)
28406 #define VDSO_PRELINK 0
28408 #define VDSO_SYM(x) \
28409 @@ -274,7 +292,7 @@ do if (vdso_enabled) { \
28411 #define ARCH_DLINFO \
28412 do if (vdso_enabled) { \
28413 - NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
28414 + NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
28417 #endif /* !CONFIG_X86_32 */
28418 diff -urNp linux-2.6.24.4/include/asm-x86/futex_32.h linux-2.6.24.4/include/asm-x86/futex_32.h
28419 --- linux-2.6.24.4/include/asm-x86/futex_32.h 2008-03-24 14:49:18.000000000 -0400
28420 +++ linux-2.6.24.4/include/asm-x86/futex_32.h 2008-03-26 20:21:09.000000000 -0400
28423 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
28424 __asm__ __volatile ( \
28425 + "movw %w6, %%ds\n"\
28427 -"2: .section .fixup,\"ax\"\n\
28430 + .section .fixup,\"ax\"\n\
28434 @@ -21,16 +24,19 @@
28437 : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
28438 - : "i" (-EFAULT), "0" (oparg), "1" (0))
28439 + : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
28441 #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
28442 __asm__ __volatile ( \
28443 -"1: movl %2, %0\n\
28444 +" movw %w7, %%es\n\
28445 +1: movl %%es:%2, %0\n\
28448 -"2: lock ; cmpxchgl %3, %2\n\
28449 +"2: lock ; cmpxchgl %3, %%es:%2\n\
28451 -3: .section .fixup,\"ax\"\n\
28454 + .section .fixup,\"ax\"\n\
28458 @@ -40,10 +46,10 @@
28460 : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
28462 - : "r" (oparg), "i" (-EFAULT), "1" (0))
28463 + : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
28466 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
28467 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
28469 int op = (encoded_op >> 28) & 7;
28470 int cmp = (encoded_op >> 24) & 15;
28471 @@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op,
28472 pagefault_disable();
28474 if (op == FUTEX_OP_SET)
28475 - __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
28476 + __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
28478 #ifndef CONFIG_X86_BSWAP
28479 if (boot_cpu_data.x86 == 3)
28480 @@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op,
28484 - __futex_atomic_op1("lock ; xaddl %0, %2", ret,
28485 + __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret,
28486 oldval, uaddr, oparg);
28489 @@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op,
28493 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
28494 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
28496 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
28499 __asm__ __volatile__(
28500 - "1: lock ; cmpxchgl %3, %1 \n"
28502 - "2: .section .fixup, \"ax\" \n"
28503 + " movw %w5, %%ds \n"
28504 + "1: lock ; cmpxchgl %3, %%ds:%1 \n"
28505 + "2: pushl %%ss \n"
28507 + " .section .fixup, \"ax\" \n"
28511 @@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
28514 : "=a" (oldval), "+m" (*uaddr)
28515 - : "i" (-EFAULT), "r" (newval), "0" (oldval)
28516 + : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
28520 diff -urNp linux-2.6.24.4/include/asm-x86/futex_64.h linux-2.6.24.4/include/asm-x86/futex_64.h
28521 --- linux-2.6.24.4/include/asm-x86/futex_64.h 2008-03-24 14:49:18.000000000 -0400
28522 +++ linux-2.6.24.4/include/asm-x86/futex_64.h 2008-03-26 20:21:09.000000000 -0400
28524 : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0))
28527 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
28528 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
28530 int op = (encoded_op >> 28) & 7;
28531 int cmp = (encoded_op >> 24) & 15;
28532 @@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op,
28536 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
28537 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
28539 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
28541 diff -urNp linux-2.6.24.4/include/asm-x86/i387_32.h linux-2.6.24.4/include/asm-x86/i387_32.h
28542 --- linux-2.6.24.4/include/asm-x86/i387_32.h 2008-03-24 14:49:18.000000000 -0400
28543 +++ linux-2.6.24.4/include/asm-x86/i387_32.h 2008-03-26 20:21:09.000000000 -0400
28544 @@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
28545 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
28547 /* We need a safe address that is cheap to find and that is already
28548 - in L1 during context switch. The best choices are unfortunately
28549 - different for UP and SMP */
28551 -#define safe_address (__per_cpu_offset[0])
28553 -#define safe_address (kstat_cpu(0).cpustat.user)
28555 + in L1 during context switch. */
28556 +#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0)
28559 * These must be called with preempt disabled
28560 diff -urNp linux-2.6.24.4/include/asm-x86/io_64.h linux-2.6.24.4/include/asm-x86/io_64.h
28561 --- linux-2.6.24.4/include/asm-x86/io_64.h 2008-03-24 14:49:18.000000000 -0400
28562 +++ linux-2.6.24.4/include/asm-x86/io_64.h 2008-03-26 20:21:09.000000000 -0400
28563 @@ -120,6 +120,17 @@ static inline void * phys_to_virt(unsign
28567 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
28568 +static inline int valid_phys_addr_range (unsigned long addr, size_t count)
28570 + return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
28573 +static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
28575 + return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
28579 * Change "struct page" to physical address.
28581 diff -urNp linux-2.6.24.4/include/asm-x86/irqflags_32.h linux-2.6.24.4/include/asm-x86/irqflags_32.h
28582 --- linux-2.6.24.4/include/asm-x86/irqflags_32.h 2008-03-24 14:49:18.000000000 -0400
28583 +++ linux-2.6.24.4/include/asm-x86/irqflags_32.h 2008-03-26 20:21:09.000000000 -0400
28584 @@ -108,6 +108,8 @@ static inline unsigned long __raw_local_
28585 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
28586 #define INTERRUPT_RETURN iret
28587 #define GET_CR0_INTO_EAX movl %cr0, %eax
28588 +#define GET_CR0_INTO_EDX movl %cr0, %edx
28589 +#define SET_CR0_FROM_EDX movl %edx, %cr0
28590 #endif /* __ASSEMBLY__ */
28591 #endif /* CONFIG_PARAVIRT */
28593 diff -urNp linux-2.6.24.4/include/asm-x86/kmap_types.h linux-2.6.24.4/include/asm-x86/kmap_types.h
28594 --- linux-2.6.24.4/include/asm-x86/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
28595 +++ linux-2.6.24.4/include/asm-x86/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
28596 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
28601 +D(13) KM_CLEARPAGE,
28606 diff -urNp linux-2.6.24.4/include/asm-x86/mach-default/apm.h linux-2.6.24.4/include/asm-x86/mach-default/apm.h
28607 --- linux-2.6.24.4/include/asm-x86/mach-default/apm.h 2008-03-24 14:49:18.000000000 -0400
28608 +++ linux-2.6.24.4/include/asm-x86/mach-default/apm.h 2008-03-26 20:21:09.000000000 -0400
28609 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
28610 __asm__ __volatile__(APM_DO_ZERO_SEGS
28613 - "lcall *%%cs:apm_bios_entry\n\t"
28614 + "lcall *%%ss:apm_bios_entry\n\t"
28618 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
28619 __asm__ __volatile__(APM_DO_ZERO_SEGS
28622 - "lcall *%%cs:apm_bios_entry\n\t"
28623 + "lcall *%%ss:apm_bios_entry\n\t"
28627 diff -urNp linux-2.6.24.4/include/asm-x86/mman.h linux-2.6.24.4/include/asm-x86/mman.h
28628 --- linux-2.6.24.4/include/asm-x86/mman.h 2008-03-24 14:49:18.000000000 -0400
28629 +++ linux-2.6.24.4/include/asm-x86/mman.h 2008-03-26 20:21:09.000000000 -0400
28631 #define MCL_CURRENT 1 /* lock all current mappings */
28632 #define MCL_FUTURE 2 /* lock all future mappings */
28635 +#ifndef __ASSEMBLY__
28636 +#ifdef CONFIG_X86_32
28637 +#define arch_mmap_check i386_mmap_check
28638 +int i386_mmap_check(unsigned long addr, unsigned long len,
28639 + unsigned long flags);
28644 #endif /* _ASM_X86_MMAN_H */
28645 diff -urNp linux-2.6.24.4/include/asm-x86/mmu_context_32.h linux-2.6.24.4/include/asm-x86/mmu_context_32.h
28646 --- linux-2.6.24.4/include/asm-x86/mmu_context_32.h 2008-03-24 14:49:18.000000000 -0400
28647 +++ linux-2.6.24.4/include/asm-x86/mmu_context_32.h 2008-03-26 20:21:09.000000000 -0400
28648 @@ -57,6 +57,22 @@ static inline void switch_mm(struct mm_s
28650 if (unlikely(prev->context.ldt != next->context.ldt))
28651 load_LDT_nolock(&next->context);
28653 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
28654 + if (!nx_enabled) {
28655 + smp_mb__before_clear_bit();
28656 + cpu_clear(cpu, prev->context.cpu_user_cs_mask);
28657 + smp_mb__after_clear_bit();
28658 + cpu_set(cpu, next->context.cpu_user_cs_mask);
28662 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
28663 + if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
28664 + prev->context.user_cs_limit != next->context.user_cs_limit))
28665 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
28671 @@ -69,6 +85,19 @@ static inline void switch_mm(struct mm_s
28673 load_cr3(next->pgd);
28674 load_LDT_nolock(&next->context);
28676 +#ifdef CONFIG_PAX_PAGEEXEC
28678 + cpu_set(cpu, next->context.cpu_user_cs_mask);
28681 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
28682 +#ifdef CONFIG_PAX_PAGEEXEC
28683 + if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
28685 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
28691 diff -urNp linux-2.6.24.4/include/asm-x86/mmu.h linux-2.6.24.4/include/asm-x86/mmu.h
28692 --- linux-2.6.24.4/include/asm-x86/mmu.h 2008-03-24 14:49:18.000000000 -0400
28693 +++ linux-2.6.24.4/include/asm-x86/mmu.h 2008-03-26 20:21:09.000000000 -0400
28694 @@ -11,13 +11,26 @@
28695 * cpu_vm_mask is used to optimize ldt flushing.
28699 + struct desc_struct *ldt;
28700 #ifdef CONFIG_X86_64
28706 + unsigned long vdso;
28708 +#ifdef CONFIG_X86_32
28709 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
28710 + unsigned long user_cs_base;
28711 + unsigned long user_cs_limit;
28713 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
28714 + cpumask_t cpu_user_cs_mask;
28722 #endif /* _ASM_X86_MMU_H */
28723 diff -urNp linux-2.6.24.4/include/asm-x86/module_32.h linux-2.6.24.4/include/asm-x86/module_32.h
28724 --- linux-2.6.24.4/include/asm-x86/module_32.h 2008-03-24 14:49:18.000000000 -0400
28725 +++ linux-2.6.24.4/include/asm-x86/module_32.h 2008-03-26 20:21:09.000000000 -0400
28726 @@ -70,6 +70,12 @@ struct mod_arch_specific
28727 #define MODULE_STACKSIZE ""
28730 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
28731 +#ifdef CONFIG_GRKERNSEC
28732 +#define MODULE_GRSEC "GRSECURITY "
28734 +#define MODULE_GRSEC ""
28737 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
28739 #endif /* _ASM_I386_MODULE_H */
28740 diff -urNp linux-2.6.24.4/include/asm-x86/page_32.h linux-2.6.24.4/include/asm-x86/page_32.h
28741 --- linux-2.6.24.4/include/asm-x86/page_32.h 2008-03-24 14:49:18.000000000 -0400
28742 +++ linux-2.6.24.4/include/asm-x86/page_32.h 2008-03-26 20:21:09.000000000 -0400
28743 @@ -90,7 +90,6 @@ static inline pte_t native_make_pte(unsi
28744 typedef struct { unsigned long pte_low; } pte_t;
28745 typedef struct { unsigned long pgd; } pgd_t;
28746 typedef struct { unsigned long pgprot; } pgprot_t;
28747 -#define boot_pte_t pte_t /* or would you rather have a typedef */
28749 static inline unsigned long native_pgd_val(pgd_t pgd)
28751 @@ -175,6 +174,18 @@ extern int page_is_ram(unsigned long pag
28752 #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET)
28755 +#ifdef CONFIG_PAX_KERNEXEC
28756 +#ifndef __ASSEMBLY__
28757 +extern unsigned char MODULES_VADDR[];
28758 +extern unsigned char MODULES_END[];
28759 +extern unsigned char KERNEL_TEXT_OFFSET[];
28760 +#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
28761 +#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
28764 +#define ktla_ktva(addr) (addr)
28765 +#define ktva_ktla(addr) (addr)
28768 #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
28769 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
28770 @@ -197,6 +208,10 @@ extern int page_is_ram(unsigned long pag
28771 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
28772 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
28774 +#ifdef CONFIG_PAX_PAGEEXEC
28775 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
28778 #include <asm-generic/memory_model.h>
28779 #include <asm-generic/page.h>
28781 diff -urNp linux-2.6.24.4/include/asm-x86/page_64.h linux-2.6.24.4/include/asm-x86/page_64.h
28782 --- linux-2.6.24.4/include/asm-x86/page_64.h 2008-03-24 14:49:18.000000000 -0400
28783 +++ linux-2.6.24.4/include/asm-x86/page_64.h 2008-03-26 20:21:09.000000000 -0400
28784 @@ -94,6 +94,9 @@ extern unsigned long phys_base;
28785 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
28786 #define __PAGE_OFFSET _AC(0xffff810000000000, UL)
28788 +#define ktla_ktva(addr) (addr)
28789 +#define ktva_ktla(addr) (addr)
28791 /* to align the pointer to the (next) page boundary */
28792 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
28794 diff -urNp linux-2.6.24.4/include/asm-x86/paravirt.h linux-2.6.24.4/include/asm-x86/paravirt.h
28795 --- linux-2.6.24.4/include/asm-x86/paravirt.h 2008-03-24 14:49:18.000000000 -0400
28796 +++ linux-2.6.24.4/include/asm-x86/paravirt.h 2008-03-26 20:21:09.000000000 -0400
28797 @@ -1124,23 +1124,23 @@ static inline unsigned long __raw_local_
28799 #define INTERRUPT_RETURN \
28800 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \
28801 - jmp *%cs:pv_cpu_ops+PV_CPU_iret)
28802 + jmp *%ss:pv_cpu_ops+PV_CPU_iret)
28804 #define DISABLE_INTERRUPTS(clobbers) \
28805 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
28806 pushl %eax; pushl %ecx; pushl %edx; \
28807 - call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \
28808 + call *%ss:pv_irq_ops+PV_IRQ_irq_disable; \
28809 popl %edx; popl %ecx; popl %eax) \
28811 #define ENABLE_INTERRUPTS(clobbers) \
28812 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
28813 pushl %eax; pushl %ecx; pushl %edx; \
28814 - call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
28815 + call *%ss:pv_irq_ops+PV_IRQ_irq_enable; \
28816 popl %edx; popl %ecx; popl %eax)
28818 #define ENABLE_INTERRUPTS_SYSEXIT \
28819 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), CLBR_NONE,\
28820 - jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_sysexit)
28821 + jmp *%ss:pv_cpu_ops+PV_CPU_irq_enable_sysexit)
28823 #define GET_CR0_INTO_EAX \
28824 push %ecx; push %edx; \
28825 diff -urNp linux-2.6.24.4/include/asm-x86/pda.h linux-2.6.24.4/include/asm-x86/pda.h
28826 --- linux-2.6.24.4/include/asm-x86/pda.h 2008-03-24 14:49:18.000000000 -0400
28827 +++ linux-2.6.24.4/include/asm-x86/pda.h 2008-03-26 20:21:09.000000000 -0400
28828 @@ -16,11 +16,9 @@ struct x8664_pda {
28829 unsigned long oldrsp; /* 24 user rsp for system call */
28830 int irqcount; /* 32 Irq nesting counter. Starts with -1 */
28831 int cpunumber; /* 36 Logical CPU number */
28832 -#ifdef CONFIG_CC_STACKPROTECTOR
28833 unsigned long stack_canary; /* 40 stack canary value */
28834 /* gcc-ABI: this canary MUST be at
28838 int nodenumber; /* number of current node */
28839 unsigned int __softirq_pending;
28840 diff -urNp linux-2.6.24.4/include/asm-x86/percpu_32.h linux-2.6.24.4/include/asm-x86/percpu_32.h
28841 --- linux-2.6.24.4/include/asm-x86/percpu_32.h 2008-03-24 14:49:18.000000000 -0400
28842 +++ linux-2.6.24.4/include/asm-x86/percpu_32.h 2008-03-26 20:21:16.000000000 -0400
28843 @@ -42,12 +42,12 @@
28846 /* Same as generic implementation except for optimized local access. */
28847 -#define __GENERIC_PER_CPU
28849 /* This is used for other cpus to find our section. */
28850 extern unsigned long __per_cpu_offset[];
28851 +extern void setup_per_cpu_areas(void);
28853 -#define per_cpu_offset(x) (__per_cpu_offset[x])
28854 +#define per_cpu_offset(x) (__per_cpu_offset[x] - (unsigned long)__per_cpu_start)
28856 /* Separate out the type, so (int[3], foo) works. */
28857 #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
28858 @@ -64,11 +64,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
28860 /* var is in discarded region: offset to particular copy we want */
28861 #define per_cpu(var, cpu) (*({ \
28862 - extern int simple_indentifier_##var(void); \
28863 + extern int simple_identifier_##var(void); \
28864 RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
28866 #define __raw_get_cpu_var(var) (*({ \
28867 - extern int simple_indentifier_##var(void); \
28868 + extern int simple_identifier_##var(void); \
28869 RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \
28872 @@ -79,7 +79,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
28874 unsigned int __i; \
28875 for_each_possible_cpu(__i) \
28876 - memcpy((pcpudst)+__per_cpu_offset[__i], \
28877 + memcpy((pcpudst)+per_cpu_offset(__i), \
28881 diff -urNp linux-2.6.24.4/include/asm-x86/pgalloc_32.h linux-2.6.24.4/include/asm-x86/pgalloc_32.h
28882 --- linux-2.6.24.4/include/asm-x86/pgalloc_32.h 2008-03-24 14:49:18.000000000 -0400
28883 +++ linux-2.6.24.4/include/asm-x86/pgalloc_32.h 2008-03-26 20:21:09.000000000 -0400
28884 @@ -15,11 +15,19 @@
28885 #define paravirt_release_pd(pfn) do { } while (0)
28888 +#ifdef CONFIG_COMPAT_VDSO
28889 #define pmd_populate_kernel(mm, pmd, pte) \
28891 paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
28892 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \
28895 +#define pmd_populate_kernel(mm, pmd, pte) \
28897 + paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
28898 + set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); \
28902 #define pmd_populate(mm, pmd, pte) \
28904 diff -urNp linux-2.6.24.4/include/asm-x86/pgalloc_64.h linux-2.6.24.4/include/asm-x86/pgalloc_64.h
28905 --- linux-2.6.24.4/include/asm-x86/pgalloc_64.h 2008-03-24 14:49:18.000000000 -0400
28906 +++ linux-2.6.24.4/include/asm-x86/pgalloc_64.h 2008-03-26 20:21:09.000000000 -0400
28908 #include <linux/mm.h>
28910 #define pmd_populate_kernel(mm, pmd, pte) \
28911 - set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
28912 + set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
28913 #define pud_populate(mm, pud, pmd) \
28914 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
28915 #define pgd_populate(mm, pgd, pud) \
28916 diff -urNp linux-2.6.24.4/include/asm-x86/pgtable-2level.h linux-2.6.24.4/include/asm-x86/pgtable-2level.h
28917 --- linux-2.6.24.4/include/asm-x86/pgtable-2level.h 2008-03-24 14:49:18.000000000 -0400
28918 +++ linux-2.6.24.4/include/asm-x86/pgtable-2level.h 2008-03-26 20:21:09.000000000 -0400
28919 @@ -22,7 +22,19 @@ static inline void native_set_pte_at(str
28921 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
28924 +#ifdef CONFIG_PAX_KERNEXEC
28925 + unsigned long cr0;
28927 + pax_open_kernel(cr0);
28932 +#ifdef CONFIG_PAX_KERNEXEC
28933 + pax_close_kernel(cr0);
28937 #ifndef CONFIG_PARAVIRT
28938 #define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval)
28939 diff -urNp linux-2.6.24.4/include/asm-x86/pgtable_32.h linux-2.6.24.4/include/asm-x86/pgtable_32.h
28940 --- linux-2.6.24.4/include/asm-x86/pgtable_32.h 2008-03-24 14:49:18.000000000 -0400
28941 +++ linux-2.6.24.4/include/asm-x86/pgtable_32.h 2008-03-26 20:21:09.000000000 -0400
28942 @@ -31,7 +31,6 @@ struct vm_area_struct;
28944 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
28945 extern unsigned long empty_zero_page[1024];
28946 -extern pgd_t swapper_pg_dir[1024];
28947 extern struct kmem_cache *pmd_cache;
28948 extern spinlock_t pgd_lock;
28949 extern struct page *pgd_list;
28950 @@ -55,6 +54,11 @@ void paging_init(void);
28951 # include <asm/pgtable-2level-defs.h>
28954 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
28955 +#ifdef CONFIG_X86_PAE
28956 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
28959 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
28960 #define PGDIR_MASK (~(PGDIR_SIZE-1))
28962 @@ -64,9 +68,11 @@ void paging_init(void);
28963 #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
28964 #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
28966 +#ifndef CONFIG_X86_PAE
28967 #define TWOLEVEL_PGDIR_SHIFT 22
28968 #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
28969 #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
28972 /* Just any arbitrary offset to the start of the vmalloc VM area: the
28973 * current 8MB value just means that there will be a 8MB "hole" after the
28974 @@ -133,7 +139,7 @@ void paging_init(void);
28975 #define PAGE_NONE \
28976 __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
28977 #define PAGE_SHARED \
28978 - __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
28979 + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
28981 #define PAGE_SHARED_EXEC \
28982 __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
28983 @@ -199,7 +205,7 @@ extern unsigned long long __PAGE_KERNEL,
28984 #undef TEST_ACCESS_OK
28986 /* The boot page tables (all created as a single array) */
28987 -extern unsigned long pg0[];
28988 +extern pte_t pg0[];
28990 #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
28992 @@ -215,30 +221,55 @@ extern unsigned long pg0[];
28993 * The following only work if pte_present() is true.
28994 * Undefined behaviour if not..
28996 +static inline int pte_user(pte_t pte) { return (pte).pte_low & _PAGE_USER; }
28997 static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; }
28998 static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; }
28999 static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; }
29000 static inline int pte_huge(pte_t pte) { return (pte).pte_low & _PAGE_PSE; }
29002 +#ifdef CONFIG_X86_PAE
29003 +# include <asm/pgtable-3level.h>
29005 +# include <asm/pgtable-2level.h>
29009 * The following only works if pte_present() is not true.
29011 static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; }
29013 +static inline pte_t pte_exprotect(pte_t pte)
29015 +#ifdef CONFIG_X86_PAE
29016 + if (__supported_pte_mask & _PAGE_NX)
29017 + set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
29020 + set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
29024 static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
29025 static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
29026 static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; }
29027 +static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
29029 +static inline pte_t pte_mkexec(pte_t pte)
29031 +#ifdef CONFIG_X86_PAE
29032 + if (__supported_pte_mask & _PAGE_NX)
29033 + set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
29036 + set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
29040 static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; }
29041 static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
29042 static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
29043 static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; }
29045 -#ifdef CONFIG_X86_PAE
29046 -# include <asm/pgtable-3level.h>
29048 -# include <asm/pgtable-2level.h>
29051 #ifndef CONFIG_PARAVIRT
29053 * Rules for using pte_update - it must be called after any PTE update which
29054 @@ -350,7 +381,19 @@ static inline void ptep_set_wrprotect(st
29056 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
29058 - memcpy(dst, src, count * sizeof(pgd_t));
29060 +#ifdef CONFIG_PAX_KERNEXEC
29061 + unsigned long cr0;
29063 + pax_open_kernel(cr0);
29066 + memcpy(dst, src, count * sizeof(pgd_t));
29068 +#ifdef CONFIG_PAX_KERNEXEC
29069 + pax_close_kernel(cr0);
29075 @@ -497,6 +540,9 @@ static inline void paravirt_pagetable_se
29077 #endif /* !__ASSEMBLY__ */
29079 +#define HAVE_ARCH_UNMAPPED_AREA
29080 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
29082 #ifdef CONFIG_FLATMEM
29083 #define kern_addr_valid(addr) (1)
29084 #endif /* CONFIG_FLATMEM */
29085 diff -urNp linux-2.6.24.4/include/asm-x86/pgtable-3level.h linux-2.6.24.4/include/asm-x86/pgtable-3level.h
29086 --- linux-2.6.24.4/include/asm-x86/pgtable-3level.h 2008-03-24 14:49:18.000000000 -0400
29087 +++ linux-2.6.24.4/include/asm-x86/pgtable-3level.h 2008-03-26 20:21:09.000000000 -0400
29088 @@ -67,11 +67,35 @@ static inline void native_set_pte_atomic
29090 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
29093 +#ifdef CONFIG_PAX_KERNEXEC
29094 + unsigned long cr0;
29096 + pax_open_kernel(cr0);
29099 set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
29101 +#ifdef CONFIG_PAX_KERNEXEC
29102 + pax_close_kernel(cr0);
29106 static inline void native_set_pud(pud_t *pudp, pud_t pud)
29109 +#ifdef CONFIG_PAX_KERNEXEC
29110 + unsigned long cr0;
29112 + pax_open_kernel(cr0);
29117 +#ifdef CONFIG_PAX_KERNEXEC
29118 + pax_close_kernel(cr0);
29124 diff -urNp linux-2.6.24.4/include/asm-x86/pgtable_64.h linux-2.6.24.4/include/asm-x86/pgtable_64.h
29125 --- linux-2.6.24.4/include/asm-x86/pgtable_64.h 2008-03-24 14:49:18.000000000 -0400
29126 +++ linux-2.6.24.4/include/asm-x86/pgtable_64.h 2008-03-26 20:21:09.000000000 -0400
29127 @@ -79,7 +79,19 @@ static inline void set_pte(pte_t *dst, p
29129 static inline void set_pmd(pmd_t *dst, pmd_t val)
29132 +#ifdef CONFIG_PAX_KERNEXEC
29133 + unsigned long cr0;
29135 + pax_open_kernel(cr0);
29138 pmd_val(*dst) = pmd_val(val);
29140 +#ifdef CONFIG_PAX_KERNEXEC
29141 + pax_close_kernel(cr0);
29146 static inline void set_pud(pud_t *dst, pud_t val)
29147 @@ -180,6 +192,10 @@ static inline pte_t ptep_get_and_clear_f
29148 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
29149 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
29150 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
29152 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
29153 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
29155 #define __PAGE_KERNEL \
29156 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
29157 #define __PAGE_KERNEL_EXEC \
29158 @@ -188,10 +204,12 @@ static inline pte_t ptep_get_and_clear_f
29159 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX)
29160 #define __PAGE_KERNEL_RO \
29161 (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
29162 +#define __PAGE_KERNEL_RX \
29163 + (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
29164 #define __PAGE_KERNEL_VSYSCALL \
29165 (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
29166 #define __PAGE_KERNEL_VSYSCALL_NOCACHE \
29167 - (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD)
29168 + (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD | _PAGE_NX)
29169 #define __PAGE_KERNEL_LARGE \
29170 (__PAGE_KERNEL | _PAGE_PSE)
29171 #define __PAGE_KERNEL_LARGE_EXEC \
29172 @@ -202,6 +220,7 @@ static inline pte_t ptep_get_and_clear_f
29173 #define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
29174 #define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
29175 #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
29176 +#define PAGE_KERNEL_RX MAKE_GLOBAL(__PAGE_KERNEL_RX)
29177 #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
29178 #define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL)
29179 #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
29180 @@ -231,17 +250,17 @@ static inline pte_t ptep_get_and_clear_f
29182 static inline unsigned long pgd_bad(pgd_t pgd)
29184 - return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
29185 + return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
29188 static inline unsigned long pud_bad(pud_t pud)
29190 - return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
29191 + return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
29194 static inline unsigned long pmd_bad(pmd_t pmd)
29196 - return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
29197 + return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
29200 #define pte_none(x) (!pte_val(x))
29201 diff -urNp linux-2.6.24.4/include/asm-x86/processor_32.h linux-2.6.24.4/include/asm-x86/processor_32.h
29202 --- linux-2.6.24.4/include/asm-x86/processor_32.h 2008-03-24 14:49:18.000000000 -0400
29203 +++ linux-2.6.24.4/include/asm-x86/processor_32.h 2008-03-26 20:21:09.000000000 -0400
29204 @@ -100,8 +100,6 @@ struct cpuinfo_x86 {
29206 extern struct cpuinfo_x86 boot_cpu_data;
29207 extern struct cpuinfo_x86 new_cpu_data;
29208 -extern struct tss_struct doublefault_tss;
29209 -DECLARE_PER_CPU(struct tss_struct, init_tss);
29212 DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
29213 @@ -215,11 +213,19 @@ extern int bootloader_type;
29215 #define TASK_SIZE (PAGE_OFFSET)
29217 +#ifdef CONFIG_PAX_SEGMEXEC
29218 +#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
29221 /* This decides where the kernel will search for a free chunk of vm
29222 * space during mmap's.
29224 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
29226 +#ifdef CONFIG_PAX_SEGMEXEC
29227 +#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
29230 #define HAVE_ARCH_PICK_MMAP_LAYOUT
29232 extern void hard_disable_TSC(void);
29233 @@ -344,6 +350,9 @@ struct tss_struct {
29235 #define ARCH_MIN_TASKALIGN 16
29237 +extern struct tss_struct doublefault_tss;
29238 +extern struct tss_struct init_tss[NR_CPUS];
29240 struct thread_struct {
29241 /* cached TLS descriptors. */
29242 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
29243 @@ -372,7 +381,7 @@ struct thread_struct {
29246 #define INIT_THREAD { \
29247 - .esp0 = sizeof(init_stack) + (long)&init_stack, \
29248 + .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
29249 .vm86_info = NULL, \
29250 .sysenter_cs = __KERNEL_CS, \
29251 .io_bitmap_ptr = NULL, \
29252 @@ -387,7 +396,7 @@ struct thread_struct {
29254 #define INIT_TSS { \
29256 - .esp0 = sizeof(init_stack) + (long)&init_stack, \
29257 + .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
29258 .ss0 = __KERNEL_DS, \
29259 .ss1 = __KERNEL_CS, \
29260 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
29261 @@ -428,11 +437,7 @@ void show_trace(struct task_struct *task
29262 unsigned long get_wchan(struct task_struct *p);
29264 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
29265 -#define KSTK_TOP(info) \
29267 - unsigned long *__ptr = (unsigned long *)(info); \
29268 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
29270 +#define KSTK_TOP(info) ((info)->task.thread.esp0)
29273 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
29274 @@ -447,7 +452,7 @@ unsigned long get_wchan(struct task_stru
29275 #define task_pt_regs(task) \
29277 struct pt_regs *__regs__; \
29278 - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
29279 + __regs__ = (struct pt_regs *)((task)->thread.esp0); \
29283 diff -urNp linux-2.6.24.4/include/asm-x86/processor_64.h linux-2.6.24.4/include/asm-x86/processor_64.h
29284 --- linux-2.6.24.4/include/asm-x86/processor_64.h 2008-03-24 14:49:18.000000000 -0400
29285 +++ linux-2.6.24.4/include/asm-x86/processor_64.h 2008-03-26 20:21:09.000000000 -0400
29286 @@ -142,7 +142,7 @@ static inline void clear_in_cr4 (unsigne
29287 /* This decides where the kernel will search for a free chunk of vm
29288 * space during mmap's.
29290 -#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
29291 +#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFf000)
29293 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64)
29294 #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64)
29295 @@ -201,7 +201,7 @@ struct tss_struct {
29298 extern struct cpuinfo_x86 boot_cpu_data;
29299 -DECLARE_PER_CPU(struct tss_struct,init_tss);
29300 +extern struct tss_struct init_tss[NR_CPUS];
29301 /* Save the original ist values for checking stack pointers during debugging */
29303 unsigned long ist[7];
29304 diff -urNp linux-2.6.24.4/include/asm-x86/ptrace.h linux-2.6.24.4/include/asm-x86/ptrace.h
29305 --- linux-2.6.24.4/include/asm-x86/ptrace.h 2008-03-24 14:49:18.000000000 -0400
29306 +++ linux-2.6.24.4/include/asm-x86/ptrace.h 2008-03-26 20:21:09.000000000 -0400
29307 @@ -39,17 +39,18 @@ struct task_struct;
29308 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
29311 - * user_mode_vm(regs) determines whether a register set came from user mode.
29312 + * user_mode(regs) determines whether a register set came from user mode.
29313 * This is true if V8086 mode was enabled OR if the register set was from
29314 * protected mode with RPL-3 CS value. This tricky test checks that with
29315 * one comparison. Many places in the kernel can bypass this full check
29316 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
29317 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
29320 -static inline int user_mode(struct pt_regs *regs)
29321 +static inline int user_mode_novm(struct pt_regs *regs)
29323 return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
29325 -static inline int user_mode_vm(struct pt_regs *regs)
29326 +static inline int user_mode(struct pt_regs *regs)
29328 return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
29330 diff -urNp linux-2.6.24.4/include/asm-x86/reboot.h linux-2.6.24.4/include/asm-x86/reboot.h
29331 --- linux-2.6.24.4/include/asm-x86/reboot.h 2008-03-24 14:49:18.000000000 -0400
29332 +++ linux-2.6.24.4/include/asm-x86/reboot.h 2008-03-26 20:21:09.000000000 -0400
29333 @@ -15,6 +15,6 @@ struct machine_ops
29335 extern struct machine_ops machine_ops;
29337 -void machine_real_restart(unsigned char *code, int length);
29338 +void machine_real_restart(const unsigned char *code, unsigned int length);
29340 #endif /* _ASM_REBOOT_H */
29341 diff -urNp linux-2.6.24.4/include/asm-x86/segment_32.h linux-2.6.24.4/include/asm-x86/segment_32.h
29342 --- linux-2.6.24.4/include/asm-x86/segment_32.h 2008-03-24 14:49:18.000000000 -0400
29343 +++ linux-2.6.24.4/include/asm-x86/segment_32.h 2008-03-26 20:21:09.000000000 -0400
29345 #define __KERNEL_PERCPU 0
29348 +#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
29349 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
29351 +#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
29352 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
29354 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
29357 @@ -140,9 +146,9 @@
29358 #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
29360 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
29361 -#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
29362 +#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
29364 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
29365 -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
29366 +#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
29369 diff -urNp linux-2.6.24.4/include/asm-x86/system_32.h linux-2.6.24.4/include/asm-x86/system_32.h
29370 --- linux-2.6.24.4/include/asm-x86/system_32.h 2008-03-24 14:49:18.000000000 -0400
29371 +++ linux-2.6.24.4/include/asm-x86/system_32.h 2008-03-26 20:21:09.000000000 -0400
29372 @@ -188,6 +188,21 @@ static inline void clflush(volatile void
29373 /* Set the 'TS' bit */
29374 #define stts() write_cr0(8 | read_cr0())
29376 +#define pax_open_kernel(cr0) \
29378 + typecheck(unsigned long, cr0); \
29379 + preempt_disable(); \
29380 + cr0 = read_cr0(); \
29381 + write_cr0(cr0 & ~X86_CR0_WP); \
29384 +#define pax_close_kernel(cr0) \
29386 + typecheck(unsigned long, cr0); \
29387 + write_cr0(cr0); \
29388 + preempt_enable_no_resched(); \
29391 #endif /* __KERNEL__ */
29393 static inline unsigned long get_limit(unsigned long segment)
29394 @@ -195,7 +210,7 @@ static inline unsigned long get_limit(un
29395 unsigned long __limit;
29396 __asm__("lsll %1,%0"
29397 :"=r" (__limit):"r" (segment));
29398 - return __limit+1;
29402 #define nop() __asm__ __volatile__ ("nop")
29403 @@ -311,7 +326,7 @@ void enable_hlt(void);
29404 extern int es7000_plat;
29405 void cpu_idle_wait(void);
29407 -extern unsigned long arch_align_stack(unsigned long sp);
29408 +#define arch_align_stack(x) (x)
29409 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
29411 void default_idle(void);
29412 diff -urNp linux-2.6.24.4/include/asm-x86/system_64.h linux-2.6.24.4/include/asm-x86/system_64.h
29413 --- linux-2.6.24.4/include/asm-x86/system_64.h 2008-03-24 14:49:18.000000000 -0400
29414 +++ linux-2.6.24.4/include/asm-x86/system_64.h 2008-03-26 20:21:09.000000000 -0400
29416 ".globl thread_return\n" \
29417 "thread_return:\n\t" \
29418 "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
29419 + "movq %P[task_canary](%%rsi),%%r8\n\t" \
29420 + "movq %%r8,%%gs:%P[pda_canary]\n\t" \
29421 "movq %P[thread_info](%%rsi),%%r8\n\t" \
29422 LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
29423 "movq %%rax,%%rdi\n\t" \
29425 [ti_flags] "i" (offsetof(struct thread_info, flags)),\
29426 [tif_fork] "i" (TIF_FORK), \
29427 [thread_info] "i" (offsetof(struct task_struct, stack)), \
29428 - [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
29429 + [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
29430 + [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
29431 + [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary)) \
29432 : "memory", "cc" __EXTRA_CLOBBER)
29434 extern void load_gs_index(unsigned);
29435 @@ -139,6 +143,21 @@ static inline void write_cr8(unsigned lo
29437 __asm__ __volatile__ ("wbinvd": : :"memory")
29439 +#define pax_open_kernel(cr0) \
29441 + typecheck(unsigned long, cr0); \
29442 + preempt_disable(); \
29443 + cr0 = read_cr0(); \
29444 + write_cr0(cr0 & ~X86_CR0_WP); \
29447 +#define pax_close_kernel(cr0) \
29449 + typecheck(unsigned long, cr0); \
29450 + write_cr0(cr0); \
29451 + preempt_enable_no_resched(); \
29454 #endif /* __KERNEL__ */
29456 static inline void clflush(volatile void *__p)
29457 @@ -179,7 +198,7 @@ static inline void clflush(volatile void
29459 void cpu_idle_wait(void);
29461 -extern unsigned long arch_align_stack(unsigned long sp);
29462 +#define arch_align_stack(x) (x)
29463 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
29466 diff -urNp linux-2.6.24.4/include/asm-x86/uaccess_32.h linux-2.6.24.4/include/asm-x86/uaccess_32.h
29467 --- linux-2.6.24.4/include/asm-x86/uaccess_32.h 2008-03-24 14:49:18.000000000 -0400
29468 +++ linux-2.6.24.4/include/asm-x86/uaccess_32.h 2008-03-26 20:21:09.000000000 -0400
29470 #include <linux/prefetch.h>
29471 #include <linux/string.h>
29472 #include <asm/page.h>
29473 +#include <asm/segment.h>
29475 #define VERIFY_READ 0
29476 #define VERIFY_WRITE 1
29479 #define get_ds() (KERNEL_DS)
29480 #define get_fs() (current_thread_info()->addr_limit)
29481 -#define set_fs(x) (current_thread_info()->addr_limit = (x))
29482 +void __set_fs(mm_segment_t x, int cpu);
29483 +void set_fs(mm_segment_t x);
29485 #define segment_eq(a,b) ((a).seg == (b).seg)
29487 @@ -101,6 +103,7 @@ struct exception_table_entry
29490 extern int fixup_exception(struct pt_regs *regs);
29491 +#define ARCH_HAS_SORT_EXTABLE
29494 * These are the main single-value transfer routines. They automatically
29495 @@ -280,9 +283,12 @@ extern void __put_user_8(void);
29497 #define __put_user_u64(x, addr, err) \
29498 __asm__ __volatile__( \
29499 - "1: movl %%eax,0(%2)\n" \
29500 - "2: movl %%edx,4(%2)\n" \
29501 + " movw %w5,%%ds\n" \
29502 + "1: movl %%eax,%%ds:0(%2)\n" \
29503 + "2: movl %%edx,%%ds:4(%2)\n" \
29505 + " pushl %%ss\n" \
29507 ".section .fixup,\"ax\"\n" \
29508 "4: movl %3,%0\n" \
29510 @@ -293,7 +299,8 @@ extern void __put_user_8(void);
29514 - : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
29515 + : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
29518 #ifdef CONFIG_X86_WP_WORKS_OK
29520 @@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu
29522 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
29523 __asm__ __volatile__( \
29524 - "1: mov"itype" %"rtype"1,%2\n" \
29525 + " movw %w5,%%ds\n" \
29526 + "1: mov"itype" %"rtype"1,%%ds:%2\n" \
29528 + " pushl %%ss\n" \
29530 ".section .fixup,\"ax\"\n" \
29531 "3: movl %3,%0\n" \
29533 @@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu
29537 - : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
29538 + : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
29542 #define __get_user_nocheck(x,ptr,size) \
29543 @@ -371,8 +382,11 @@ do { \
29545 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
29546 __asm__ __volatile__( \
29547 - "1: mov"itype" %2,%"rtype"1\n" \
29548 + " movw %w5,%%ds\n" \
29549 + "1: mov"itype" %%ds:%2,%"rtype"1\n" \
29551 + " pushl %%ss\n" \
29553 ".section .fixup,\"ax\"\n" \
29554 "3: movl %3,%0\n" \
29555 " xor"itype" %"rtype"1,%"rtype"1\n" \
29556 @@ -383,7 +397,7 @@ do { \
29559 : "=r"(err), ltype (x) \
29560 - : "m"(__m(addr)), "i"(errret), "0"(err))
29561 + : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
29564 unsigned long __must_check __copy_to_user_ll(void __user *to,
29565 diff -urNp linux-2.6.24.4/include/asm-x86/uaccess_64.h linux-2.6.24.4/include/asm-x86/uaccess_64.h
29566 --- linux-2.6.24.4/include/asm-x86/uaccess_64.h 2008-03-24 14:49:18.000000000 -0400
29567 +++ linux-2.6.24.4/include/asm-x86/uaccess_64.h 2008-03-26 20:21:09.000000000 -0400
29568 @@ -66,6 +66,7 @@ struct exception_table_entry
29571 #define ARCH_HAS_SEARCH_EXTABLE
29572 +#define ARCH_HAS_SORT_EXTABLE
29575 * These are the main single-value transfer routines. They automatically
29576 diff -urNp linux-2.6.24.4/include/asm-xtensa/kmap_types.h linux-2.6.24.4/include/asm-xtensa/kmap_types.h
29577 --- linux-2.6.24.4/include/asm-xtensa/kmap_types.h 2008-03-24 14:49:18.000000000 -0400
29578 +++ linux-2.6.24.4/include/asm-xtensa/kmap_types.h 2008-03-26 20:21:09.000000000 -0400
29579 @@ -25,6 +25,7 @@ enum km_type {
29587 diff -urNp linux-2.6.24.4/include/linux/a.out.h linux-2.6.24.4/include/linux/a.out.h
29588 --- linux-2.6.24.4/include/linux/a.out.h 2008-03-24 14:49:18.000000000 -0400
29589 +++ linux-2.6.24.4/include/linux/a.out.h 2008-03-26 20:21:09.000000000 -0400
29592 #include <asm/a.out.h>
29594 +#ifdef CONFIG_PAX_RANDUSTACK
29595 +#define __DELTA_STACK (current->mm->delta_stack)
29597 +#define __DELTA_STACK 0UL
29601 +#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
29604 #endif /* __STRUCT_EXEC_OVERRIDE__ */
29606 /* these go in the N_MACHTYPE field */
29607 @@ -37,6 +47,14 @@ enum machine_type {
29608 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
29611 +/* Constants for the N_FLAGS field */
29612 +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29613 +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
29614 +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
29615 +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
29616 +/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29617 +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29619 #if !defined (N_MAGIC)
29620 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
29622 diff -urNp linux-2.6.24.4/include/linux/binfmts.h linux-2.6.24.4/include/linux/binfmts.h
29623 --- linux-2.6.24.4/include/linux/binfmts.h 2008-03-24 14:49:18.000000000 -0400
29624 +++ linux-2.6.24.4/include/linux/binfmts.h 2008-03-26 20:21:09.000000000 -0400
29625 @@ -49,6 +49,7 @@ struct linux_binprm{
29626 unsigned interp_data;
29627 unsigned long loader, exec;
29628 unsigned long argv_len;
29632 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
29633 @@ -100,5 +101,8 @@ extern void compute_creds(struct linux_b
29634 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
29635 extern int set_binfmt(struct linux_binfmt *new);
29637 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
29638 +void pax_report_insns(void *pc, void *sp);
29640 #endif /* __KERNEL__ */
29641 #endif /* _LINUX_BINFMTS_H */
29642 diff -urNp linux-2.6.24.4/include/linux/cache.h linux-2.6.24.4/include/linux/cache.h
29643 --- linux-2.6.24.4/include/linux/cache.h 2008-03-24 14:49:18.000000000 -0400
29644 +++ linux-2.6.24.4/include/linux/cache.h 2008-03-26 20:21:09.000000000 -0400
29646 #define __read_mostly
29649 +#ifndef __read_only
29650 +#define __read_only __read_mostly
29653 #ifndef ____cacheline_aligned
29654 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
29656 diff -urNp linux-2.6.24.4/include/linux/capability.h linux-2.6.24.4/include/linux/capability.h
29657 --- linux-2.6.24.4/include/linux/capability.h 2008-03-24 14:49:18.000000000 -0400
29658 +++ linux-2.6.24.4/include/linux/capability.h 2008-03-26 20:21:09.000000000 -0400
29659 @@ -373,6 +373,7 @@ static inline kernel_cap_t cap_invert(ke
29660 #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK)
29662 int capable(int cap);
29663 +int capable_nolog(int cap);
29664 int __capable(struct task_struct *t, int cap);
29666 #endif /* __KERNEL__ */
29667 diff -urNp linux-2.6.24.4/include/linux/elf.h linux-2.6.24.4/include/linux/elf.h
29668 --- linux-2.6.24.4/include/linux/elf.h 2008-03-24 14:49:18.000000000 -0400
29669 +++ linux-2.6.24.4/include/linux/elf.h 2008-03-26 20:21:09.000000000 -0400
29674 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
29675 +#undef elf_read_implies_exec
29678 #ifndef elf_read_implies_exec
29679 /* Executables for which elf_read_implies_exec() returns TRUE will
29680 have the READ_IMPLIES_EXEC personality flag set automatically.
29681 @@ -48,6 +52,16 @@ typedef __s64 Elf64_Sxword;
29683 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
29685 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
29687 +/* Constants for the e_flags field */
29688 +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29689 +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
29690 +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
29691 +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
29692 +/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29693 +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29695 /* These constants define the different elf file types */
29698 @@ -82,6 +96,8 @@ typedef __s64 Elf64_Sxword;
29699 #define DT_DEBUG 21
29700 #define DT_TEXTREL 22
29701 #define DT_JMPREL 23
29702 +#define DT_FLAGS 30
29703 + #define DF_TEXTREL 0x00000004
29704 #define DT_ENCODING 32
29705 #define OLD_DT_LOOS 0x60000000
29706 #define DT_LOOS 0x6000000d
29707 @@ -228,6 +244,19 @@ typedef struct elf64_hdr {
29711 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
29712 +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
29713 +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
29714 +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
29715 +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
29716 +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
29717 +/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
29718 +/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
29719 +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
29720 +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
29721 +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
29722 +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
29724 typedef struct elf32_phdr{
29726 Elf32_Off p_offset;
29727 @@ -320,6 +349,8 @@ typedef struct elf64_shdr {
29733 #define ELFMAG0 0x7f /* EI_MAG */
29734 #define ELFMAG1 'E'
29735 #define ELFMAG2 'L'
29736 @@ -378,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
29737 #define elf_phdr elf32_phdr
29738 #define elf_note elf32_note
29739 #define elf_addr_t Elf32_Off
29740 +#define elf_dyn Elf32_Dyn
29744 @@ -386,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
29745 #define elf_phdr elf64_phdr
29746 #define elf_note elf64_note
29747 #define elf_addr_t Elf64_Off
29748 +#define elf_dyn Elf64_Dyn
29752 diff -urNp linux-2.6.24.4/include/linux/ext4_fs_extents.h linux-2.6.24.4/include/linux/ext4_fs_extents.h
29753 --- linux-2.6.24.4/include/linux/ext4_fs_extents.h 2008-03-24 14:49:18.000000000 -0400
29754 +++ linux-2.6.24.4/include/linux/ext4_fs_extents.h 2008-03-26 20:21:09.000000000 -0400
29757 #define ext_debug(a...) printk(a)
29759 -#define ext_debug(a...)
29760 +#define ext_debug(a...) do {} while (0)
29764 diff -urNp linux-2.6.24.4/include/linux/gracl.h linux-2.6.24.4/include/linux/gracl.h
29765 --- linux-2.6.24.4/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
29766 +++ linux-2.6.24.4/include/linux/gracl.h 2008-03-26 20:21:09.000000000 -0400
29771 +#include <linux/grdefs.h>
29772 +#include <linux/resource.h>
29773 +#include <linux/dcache.h>
29774 +#include <asm/resource.h>
29776 +/* Major status information */
29778 +#define GR_VERSION "grsecurity 2.1.11"
29779 +#define GRSECURITY_VERSION 0x2111
29794 +/* Password setup definitions
29795 + * kernel/grhash.c */
29798 + GR_SALT_LEN = 16,
29803 + GR_SPROLE_LEN = 64,
29806 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
29808 +/* Begin Data Structures */
29810 +struct sprole_pw {
29811 + unsigned char *rolename;
29812 + unsigned char salt[GR_SALT_LEN];
29813 + unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
29816 +struct name_entry {
29823 + struct name_entry *prev;
29824 + struct name_entry *next;
29827 +struct inodev_entry {
29828 + struct name_entry *nentry;
29829 + struct inodev_entry *prev;
29830 + struct inodev_entry *next;
29833 +struct acl_role_db {
29834 + struct acl_role_label **r_hash;
29838 +struct inodev_db {
29839 + struct inodev_entry **i_hash;
29844 + struct name_entry **n_hash;
29848 +struct crash_uid {
29850 + unsigned long expires;
29853 +struct gr_hash_struct {
29855 + void **nametable;
29857 + __u32 table_size;
29862 +/* Userspace Grsecurity ACL data structures */
29864 +struct acl_subject_label {
29872 + struct rlimit res[GR_NLIMITS];
29875 + __u8 user_trans_type;
29876 + __u8 group_trans_type;
29877 + uid_t *user_transitions;
29878 + gid_t *group_transitions;
29879 + __u16 user_trans_num;
29880 + __u16 group_trans_num;
29882 + __u32 ip_proto[8];
29884 + struct acl_ip_label **ips;
29888 + unsigned long expires;
29890 + struct acl_subject_label *parent_subject;
29891 + struct gr_hash_struct *hash;
29892 + struct acl_subject_label *prev;
29893 + struct acl_subject_label *next;
29895 + struct acl_object_label **obj_hash;
29896 + __u32 obj_hash_size;
29900 +struct role_allowed_ip {
29904 + struct role_allowed_ip *prev;
29905 + struct role_allowed_ip *next;
29908 +struct role_transition {
29911 + struct role_transition *prev;
29912 + struct role_transition *next;
29915 +struct acl_role_label {
29920 + __u16 auth_attempts;
29921 + unsigned long expires;
29923 + struct acl_subject_label *root_label;
29924 + struct gr_hash_struct *hash;
29926 + struct acl_role_label *prev;
29927 + struct acl_role_label *next;
29929 + struct role_transition *transitions;
29930 + struct role_allowed_ip *allowed_ips;
29931 + uid_t *domain_children;
29932 + __u16 domain_child_num;
29934 + struct acl_subject_label **subj_hash;
29935 + __u32 subj_hash_size;
29938 +struct user_acl_role_db {
29939 + struct acl_role_label **r_table;
29940 + __u32 num_pointers; /* Number of allocations to track */
29941 + __u32 num_roles; /* Number of roles */
29942 + __u32 num_domain_children; /* Number of domain children */
29943 + __u32 num_subjects; /* Number of subjects */
29944 + __u32 num_objects; /* Number of objects */
29947 +struct acl_object_label {
29953 + struct acl_subject_label *nested;
29954 + struct acl_object_label *globbed;
29956 + /* next two structures not used */
29958 + struct acl_object_label *prev;
29959 + struct acl_object_label *next;
29962 +struct acl_ip_label {
29971 + /* next two structures not used */
29973 + struct acl_ip_label *prev;
29974 + struct acl_ip_label *next;
29978 + struct user_acl_role_db role_db;
29979 + unsigned char pw[GR_PW_LEN];
29980 + unsigned char salt[GR_SALT_LEN];
29981 + unsigned char sum[GR_SHA_LEN];
29982 + unsigned char sp_role[GR_SPROLE_LEN];
29983 + struct sprole_pw *sprole_pws;
29984 + dev_t segv_device;
29985 + ino_t segv_inode;
29987 + __u16 num_sprole_pws;
29991 +struct gr_arg_wrapper {
29992 + struct gr_arg *arg;
29997 +struct subject_map {
29998 + struct acl_subject_label *user;
29999 + struct acl_subject_label *kernel;
30000 + struct subject_map *prev;
30001 + struct subject_map *next;
30004 +struct acl_subj_map_db {
30005 + struct subject_map **s_hash;
30009 +/* End Data Structures Section */
30011 +/* Hash functions generated by empirical testing by Brad Spengler
30012 + Makes good use of the low bits of the inode. Generally 0-1 times
30013 + in loop for successful match. 0-3 for unsuccessful match.
30014 + Shift/add algorithm with modulus of table size and an XOR*/
30016 +static __inline__ unsigned int
30017 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
30019 + return (((uid << type) + (uid ^ type)) % sz);
30022 + static __inline__ unsigned int
30023 +shash(const struct acl_subject_label *userp, const unsigned int sz)
30025 + return ((const unsigned long)userp % sz);
30028 +static __inline__ unsigned int
30029 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
30031 + return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
30034 +static __inline__ unsigned int
30035 +nhash(const char *name, const __u16 len, const unsigned int sz)
30037 + return full_name_hash(name, len) % sz;
30040 +#define FOR_EACH_ROLE_START(role,iter) \
30043 + while (iter < acl_role_set.r_size) { \
30044 + if (role == NULL) \
30045 + role = acl_role_set.r_hash[iter]; \
30046 + if (role == NULL) { \
30051 +#define FOR_EACH_ROLE_END(role,iter) \
30052 + role = role->next; \
30053 + if (role == NULL) \
30057 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
30060 + while (iter < role->subj_hash_size) { \
30061 + if (subj == NULL) \
30062 + subj = role->subj_hash[iter]; \
30063 + if (subj == NULL) { \
30068 +#define FOR_EACH_SUBJECT_END(subj,iter) \
30069 + subj = subj->next; \
30070 + if (subj == NULL) \
30075 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
30076 + subj = role->hash->first; \
30077 + while (subj != NULL) {
30079 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
30080 + subj = subj->next; \
30085 diff -urNp linux-2.6.24.4/include/linux/gralloc.h linux-2.6.24.4/include/linux/gralloc.h
30086 --- linux-2.6.24.4/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
30087 +++ linux-2.6.24.4/include/linux/gralloc.h 2008-03-26 20:21:09.000000000 -0400
30089 +#ifndef __GRALLOC_H
30090 +#define __GRALLOC_H
30092 +void acl_free_all(void);
30093 +int acl_alloc_stack_init(unsigned long size);
30094 +void *acl_alloc(unsigned long len);
30097 diff -urNp linux-2.6.24.4/include/linux/grdefs.h linux-2.6.24.4/include/linux/grdefs.h
30098 --- linux-2.6.24.4/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
30099 +++ linux-2.6.24.4/include/linux/grdefs.h 2008-03-26 20:21:09.000000000 -0400
30104 +/* Begin grsecurity status declarations */
30108 + GR_STATUS_INIT = 0x00 // disabled state
30111 +/* Begin ACL declarations */
30116 + GR_ROLE_USER = 0x0001,
30117 + GR_ROLE_GROUP = 0x0002,
30118 + GR_ROLE_DEFAULT = 0x0004,
30119 + GR_ROLE_SPECIAL = 0x0008,
30120 + GR_ROLE_AUTH = 0x0010,
30121 + GR_ROLE_NOPW = 0x0020,
30122 + GR_ROLE_GOD = 0x0040,
30123 + GR_ROLE_LEARN = 0x0080,
30124 + GR_ROLE_TPE = 0x0100,
30125 + GR_ROLE_DOMAIN = 0x0200,
30126 + GR_ROLE_PAM = 0x0400
30129 +/* ACL Subject and Object mode flags */
30131 + GR_DELETED = 0x80000000
30134 +/* ACL Object-only mode flags */
30136 + GR_READ = 0x00000001,
30137 + GR_APPEND = 0x00000002,
30138 + GR_WRITE = 0x00000004,
30139 + GR_EXEC = 0x00000008,
30140 + GR_FIND = 0x00000010,
30141 + GR_INHERIT = 0x00000020,
30142 + GR_SETID = 0x00000040,
30143 + GR_CREATE = 0x00000080,
30144 + GR_DELETE = 0x00000100,
30145 + GR_LINK = 0x00000200,
30146 + GR_AUDIT_READ = 0x00000400,
30147 + GR_AUDIT_APPEND = 0x00000800,
30148 + GR_AUDIT_WRITE = 0x00001000,
30149 + GR_AUDIT_EXEC = 0x00002000,
30150 + GR_AUDIT_FIND = 0x00004000,
30151 + GR_AUDIT_INHERIT= 0x00008000,
30152 + GR_AUDIT_SETID = 0x00010000,
30153 + GR_AUDIT_CREATE = 0x00020000,
30154 + GR_AUDIT_DELETE = 0x00040000,
30155 + GR_AUDIT_LINK = 0x00080000,
30156 + GR_PTRACERD = 0x00100000,
30157 + GR_NOPTRACE = 0x00200000,
30158 + GR_SUPPRESS = 0x00400000,
30159 + GR_NOLEARN = 0x00800000
30162 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
30163 + GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
30164 + GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
30166 +/* ACL subject-only mode flags */
30168 + GR_KILL = 0x00000001,
30169 + GR_VIEW = 0x00000002,
30170 + GR_PROTECTED = 0x00000004,
30171 + GR_LEARN = 0x00000008,
30172 + GR_OVERRIDE = 0x00000010,
30173 + /* just a placeholder, this mode is only used in userspace */
30174 + GR_DUMMY = 0x00000020,
30175 + GR_PROTSHM = 0x00000040,
30176 + GR_KILLPROC = 0x00000080,
30177 + GR_KILLIPPROC = 0x00000100,
30178 + /* just a placeholder, this mode is only used in userspace */
30179 + GR_NOTROJAN = 0x00000200,
30180 + GR_PROTPROCFD = 0x00000400,
30181 + GR_PROCACCT = 0x00000800,
30182 + GR_RELAXPTRACE = 0x00001000,
30183 + GR_NESTED = 0x00002000,
30184 + GR_INHERITLEARN = 0x00004000,
30185 + GR_PROCFIND = 0x00008000,
30186 + GR_POVERRIDE = 0x00010000,
30187 + GR_KERNELAUTH = 0x00020000,
30191 + GR_PAX_ENABLE_SEGMEXEC = 0x0001,
30192 + GR_PAX_ENABLE_PAGEEXEC = 0x0002,
30193 + GR_PAX_ENABLE_MPROTECT = 0x0004,
30194 + GR_PAX_ENABLE_RANDMMAP = 0x0008,
30195 + GR_PAX_ENABLE_EMUTRAMP = 0x0010,
30196 + GR_PAX_DISABLE_SEGMEXEC = 0x0100,
30197 + GR_PAX_DISABLE_PAGEEXEC = 0x0200,
30198 + GR_PAX_DISABLE_MPROTECT = 0x0400,
30199 + GR_PAX_DISABLE_RANDMMAP = 0x0800,
30200 + GR_PAX_DISABLE_EMUTRAMP = 0x1000,
30204 + GR_ID_USER = 0x01,
30205 + GR_ID_GROUP = 0x02,
30209 + GR_ID_ALLOW = 0x01,
30210 + GR_ID_DENY = 0x02,
30213 +#define GR_CRASH_RES 11
30214 +#define GR_UIDTABLE_MAX 500
30216 +/* begin resource learning section */
30218 + GR_RLIM_CPU_BUMP = 60,
30219 + GR_RLIM_FSIZE_BUMP = 50000,
30220 + GR_RLIM_DATA_BUMP = 10000,
30221 + GR_RLIM_STACK_BUMP = 1000,
30222 + GR_RLIM_CORE_BUMP = 10000,
30223 + GR_RLIM_RSS_BUMP = 500000,
30224 + GR_RLIM_NPROC_BUMP = 1,
30225 + GR_RLIM_NOFILE_BUMP = 5,
30226 + GR_RLIM_MEMLOCK_BUMP = 50000,
30227 + GR_RLIM_AS_BUMP = 500000,
30228 + GR_RLIM_LOCKS_BUMP = 2
30232 diff -urNp linux-2.6.24.4/include/linux/grinternal.h linux-2.6.24.4/include/linux/grinternal.h
30233 --- linux-2.6.24.4/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
30234 +++ linux-2.6.24.4/include/linux/grinternal.h 2008-03-26 20:21:09.000000000 -0400
30236 +#ifndef __GRINTERNAL_H
30237 +#define __GRINTERNAL_H
30239 +#ifdef CONFIG_GRKERNSEC
30241 +#include <linux/fs.h>
30242 +#include <linux/gracl.h>
30243 +#include <linux/grdefs.h>
30244 +#include <linux/grmsg.h>
30246 +void gr_add_learn_entry(const char *fmt, ...);
30247 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
30248 + const struct vfsmount *mnt);
30249 +__u32 gr_check_create(const struct dentry *new_dentry,
30250 + const struct dentry *parent,
30251 + const struct vfsmount *mnt, const __u32 mode);
30252 +int gr_check_protected_task(const struct task_struct *task);
30253 +__u32 to_gr_audit(const __u32 reqmode);
30254 +int gr_set_acls(const int type);
30256 +int gr_acl_is_enabled(void);
30257 +char gr_roletype_to_char(void);
30259 +void gr_handle_alertkill(struct task_struct *task);
30260 +char *gr_to_filename(const struct dentry *dentry,
30261 + const struct vfsmount *mnt);
30262 +char *gr_to_filename1(const struct dentry *dentry,
30263 + const struct vfsmount *mnt);
30264 +char *gr_to_filename2(const struct dentry *dentry,
30265 + const struct vfsmount *mnt);
30266 +char *gr_to_filename3(const struct dentry *dentry,
30267 + const struct vfsmount *mnt);
30269 +extern int grsec_enable_link;
30270 +extern int grsec_enable_fifo;
30271 +extern int grsec_enable_execve;
30272 +extern int grsec_enable_shm;
30273 +extern int grsec_enable_execlog;
30274 +extern int grsec_enable_signal;
30275 +extern int grsec_enable_forkfail;
30276 +extern int grsec_enable_time;
30277 +extern int grsec_enable_chroot_shmat;
30278 +extern int grsec_enable_chroot_findtask;
30279 +extern int grsec_enable_chroot_mount;
30280 +extern int grsec_enable_chroot_double;
30281 +extern int grsec_enable_chroot_pivot;
30282 +extern int grsec_enable_chroot_chdir;
30283 +extern int grsec_enable_chroot_chmod;
30284 +extern int grsec_enable_chroot_mknod;
30285 +extern int grsec_enable_chroot_fchdir;
30286 +extern int grsec_enable_chroot_nice;
30287 +extern int grsec_enable_chroot_execlog;
30288 +extern int grsec_enable_chroot_caps;
30289 +extern int grsec_enable_chroot_sysctl;
30290 +extern int grsec_enable_chroot_unix;
30291 +extern int grsec_enable_tpe;
30292 +extern int grsec_tpe_gid;
30293 +extern int grsec_enable_tpe_all;
30294 +extern int grsec_enable_sidcaps;
30295 +extern int grsec_enable_socket_all;
30296 +extern int grsec_socket_all_gid;
30297 +extern int grsec_enable_socket_client;
30298 +extern int grsec_socket_client_gid;
30299 +extern int grsec_enable_socket_server;
30300 +extern int grsec_socket_server_gid;
30301 +extern int grsec_audit_gid;
30302 +extern int grsec_enable_group;
30303 +extern int grsec_enable_audit_ipc;
30304 +extern int grsec_enable_audit_textrel;
30305 +extern int grsec_enable_mount;
30306 +extern int grsec_enable_chdir;
30307 +extern int grsec_resource_logging;
30308 +extern int grsec_lock;
30310 +extern spinlock_t grsec_alert_lock;
30311 +extern unsigned long grsec_alert_wtime;
30312 +extern unsigned long grsec_alert_fyet;
30314 +extern spinlock_t grsec_audit_lock;
30316 +extern rwlock_t grsec_exec_file_lock;
30318 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
30319 + gr_to_filename2(tsk->exec_file->f_dentry, \
30320 + tsk->exec_file->f_vfsmnt) : "/")
30322 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
30323 + gr_to_filename3(tsk->parent->exec_file->f_dentry, \
30324 + tsk->parent->exec_file->f_vfsmnt) : "/")
30326 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
30327 + gr_to_filename(tsk->exec_file->f_dentry, \
30328 + tsk->exec_file->f_vfsmnt) : "/")
30330 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
30331 + gr_to_filename1(tsk->parent->exec_file->f_dentry, \
30332 + tsk->parent->exec_file->f_vfsmnt) : "/")
30334 +#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
30335 + ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
30336 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root->d_inode->i_sb->s_dev) || \
30337 + (tsk_a->fs->root->d_inode->i_ino != \
30338 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root->d_inode->i_ino)))
30340 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
30341 + (tsk_a->fs->root->d_inode->i_sb->s_dev == \
30342 + tsk_b->fs->root->d_inode->i_sb->s_dev) && \
30343 + (tsk_a->fs->root->d_inode->i_ino == \
30344 + tsk_b->fs->root->d_inode->i_ino))
30346 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
30347 + task->pid, task->uid, \
30348 + task->euid, task->gid, task->egid, \
30349 + gr_parent_task_fullpath(task), \
30350 + task->parent->comm, task->parent->pid, \
30351 + task->parent->uid, task->parent->euid, \
30352 + task->parent->gid, task->parent->egid
30354 +#define GR_CHROOT_CAPS ( \
30355 + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
30356 + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
30357 + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
30358 + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
30359 + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
30360 + CAP_TO_MASK(CAP_IPC_OWNER))
30362 +#define security_learn(normal_msg,args...) \
30364 + read_lock(&grsec_exec_file_lock); \
30365 + gr_add_learn_entry(normal_msg "\n", ## args); \
30366 + read_unlock(&grsec_exec_file_lock); \
30372 + GR_DONT_AUDIT_GOOD
30383 + GR_SYSCTL_HIDDEN,
30386 + GR_ONE_INT_TWO_STR,
30391 + GR_FIVE_INT_TWO_STR,
30397 + GR_FILENAME_TWO_INT,
30398 + GR_FILENAME_TWO_INT_STR,
30409 +#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
30410 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
30411 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
30412 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
30413 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
30414 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
30415 +#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)
30416 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
30417 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
30418 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
30419 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
30420 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
30421 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
30422 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
30423 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
30424 +#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)
30425 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
30426 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
30427 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
30428 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
30429 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
30430 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
30431 +#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)
30432 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
30433 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
30434 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
30435 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
30436 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
30437 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
30438 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
30439 +#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)
30441 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
30446 diff -urNp linux-2.6.24.4/include/linux/grmsg.h linux-2.6.24.4/include/linux/grmsg.h
30447 --- linux-2.6.24.4/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
30448 +++ linux-2.6.24.4/include/linux/grmsg.h 2008-03-26 20:21:09.000000000 -0400
30450 +#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"
30451 +#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"
30452 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
30453 +#define GR_STOPMOD_MSG "denied modification of module state by "
30454 +#define GR_IOPERM_MSG "denied use of ioperm() by "
30455 +#define GR_IOPL_MSG "denied use of iopl() by "
30456 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
30457 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
30458 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
30459 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
30460 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
30461 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
30462 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
30463 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
30464 +#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"
30465 +#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"
30466 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
30467 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
30468 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
30469 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
30470 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
30471 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
30472 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
30473 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
30474 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
30475 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
30476 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
30477 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
30478 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
30479 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
30480 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
30481 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
30482 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
30483 +#define GR_NPROC_MSG "denied overstep of process limit by "
30484 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
30485 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
30486 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
30487 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
30488 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
30489 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
30490 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
30491 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
30492 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
30493 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
30494 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
30495 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
30496 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
30497 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
30498 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
30499 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
30500 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
30501 +#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"
30502 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
30503 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
30504 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
30505 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
30506 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
30507 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
30508 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
30509 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
30510 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
30511 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
30512 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
30513 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
30514 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
30515 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
30516 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
30517 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
30518 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
30519 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
30520 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
30521 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
30522 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
30523 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
30524 +#define GR_NICE_CHROOT_MSG "denied priority change by "
30525 +#define GR_UNISIGLOG_MSG "signal %d sent to "
30526 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
30527 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
30528 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
30529 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
30530 +#define GR_TIME_MSG "time set by "
30531 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
30532 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
30533 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
30534 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
30535 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
30536 +#define GR_BIND_MSG "denied bind() by "
30537 +#define GR_CONNECT_MSG "denied connect() by "
30538 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
30539 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
30540 +#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"
30541 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
30542 +#define GR_CAP_ACL_MSG "use of %s denied for "
30543 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
30544 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
30545 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
30546 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
30547 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
30548 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
30549 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
30550 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
30551 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
30552 +#define GR_SEM_AUDIT_MSG "semaphore created by "
30553 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
30554 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
30555 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
30556 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
30557 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
30558 diff -urNp linux-2.6.24.4/include/linux/grsecurity.h linux-2.6.24.4/include/linux/grsecurity.h
30559 --- linux-2.6.24.4/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
30560 +++ linux-2.6.24.4/include/linux/grsecurity.h 2008-03-26 20:21:09.000000000 -0400
30562 +#ifndef GR_SECURITY_H
30563 +#define GR_SECURITY_H
30564 +#include <linux/fs.h>
30565 +#include <linux/binfmts.h>
30566 +#include <linux/gracl.h>
30568 +/* notify of brain-dead configs */
30569 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC)
30570 +#error "CONFIG_PAX_NOEXEC enabled, but neither PAGEEXEC nor SEGMEXEC are enabled."
30572 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
30573 +#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
30575 +#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
30576 +#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
30578 +#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
30579 +#error "CONFIG_PAX enabled, but no PaX options are enabled."
30582 +void gr_handle_brute_attach(struct task_struct *p);
30583 +void gr_handle_brute_check(void);
30585 +char gr_roletype_to_char(void);
30587 +int gr_check_user_change(int real, int effective, int fs);
30588 +int gr_check_group_change(int real, int effective, int fs);
30590 +void gr_del_task_from_ip_table(struct task_struct *p);
30592 +int gr_pid_is_chrooted(struct task_struct *p);
30593 +int gr_handle_chroot_nice(void);
30594 +int gr_handle_chroot_sysctl(const int op);
30595 +int gr_handle_chroot_setpriority(struct task_struct *p,
30596 + const int niceval);
30597 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
30598 +int gr_handle_chroot_chroot(const struct dentry *dentry,
30599 + const struct vfsmount *mnt);
30600 +void gr_handle_chroot_caps(struct task_struct *task);
30601 +void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
30602 +int gr_handle_chroot_chmod(const struct dentry *dentry,
30603 + const struct vfsmount *mnt, const int mode);
30604 +int gr_handle_chroot_mknod(const struct dentry *dentry,
30605 + const struct vfsmount *mnt, const int mode);
30606 +int gr_handle_chroot_mount(const struct dentry *dentry,
30607 + const struct vfsmount *mnt,
30608 + const char *dev_name);
30609 +int gr_handle_chroot_pivot(void);
30610 +int gr_handle_chroot_unix(const pid_t pid);
30612 +int gr_handle_rawio(const struct inode *inode);
30613 +int gr_handle_nproc(void);
30615 +void gr_handle_ioperm(void);
30616 +void gr_handle_iopl(void);
30618 +int gr_tpe_allow(const struct file *file);
30620 +int gr_random_pid(void);
30622 +void gr_log_forkfail(const int retval);
30623 +void gr_log_timechange(void);
30624 +void gr_log_signal(const int sig, const struct task_struct *t);
30625 +void gr_log_chdir(const struct dentry *dentry,
30626 + const struct vfsmount *mnt);
30627 +void gr_log_chroot_exec(const struct dentry *dentry,
30628 + const struct vfsmount *mnt);
30629 +void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
30630 +void gr_log_remount(const char *devname, const int retval);
30631 +void gr_log_unmount(const char *devname, const int retval);
30632 +void gr_log_mount(const char *from, const char *to, const int retval);
30633 +void gr_log_msgget(const int ret, const int msgflg);
30634 +void gr_log_msgrm(const uid_t uid, const uid_t cuid);
30635 +void gr_log_semget(const int err, const int semflg);
30636 +void gr_log_semrm(const uid_t uid, const uid_t cuid);
30637 +void gr_log_shmget(const int err, const int shmflg, const size_t size);
30638 +void gr_log_shmrm(const uid_t uid, const uid_t cuid);
30639 +void gr_log_textrel(struct vm_area_struct *vma);
30641 +int gr_handle_follow_link(const struct inode *parent,
30642 + const struct inode *inode,
30643 + const struct dentry *dentry,
30644 + const struct vfsmount *mnt);
30645 +int gr_handle_fifo(const struct dentry *dentry,
30646 + const struct vfsmount *mnt,
30647 + const struct dentry *dir, const int flag,
30648 + const int acc_mode);
30649 +int gr_handle_hardlink(const struct dentry *dentry,
30650 + const struct vfsmount *mnt,
30651 + struct inode *inode,
30652 + const int mode, const char *to);
30654 +int gr_task_is_capable(struct task_struct *task, const int cap);
30655 +int gr_is_capable_nolog(const int cap);
30656 +void gr_learn_resource(const struct task_struct *task, const int limit,
30657 + const unsigned long wanted, const int gt);
30658 +void gr_copy_label(struct task_struct *tsk);
30659 +void gr_handle_crash(struct task_struct *task, const int sig);
30660 +int gr_handle_signal(const struct task_struct *p, const int sig);
30661 +int gr_check_crash_uid(const uid_t uid);
30662 +int gr_check_protected_task(const struct task_struct *task);
30663 +int gr_acl_handle_mmap(const struct file *file,
30664 + const unsigned long prot);
30665 +int gr_acl_handle_mprotect(const struct file *file,
30666 + const unsigned long prot);
30667 +int gr_check_hidden_task(const struct task_struct *tsk);
30668 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
30669 + const struct vfsmount *mnt);
30670 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
30671 + const struct vfsmount *mnt);
30672 +__u32 gr_acl_handle_access(const struct dentry *dentry,
30673 + const struct vfsmount *mnt, const int fmode);
30674 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
30675 + const struct vfsmount *mnt, mode_t mode);
30676 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
30677 + const struct vfsmount *mnt, mode_t mode);
30678 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
30679 + const struct vfsmount *mnt);
30680 +int gr_handle_ptrace(struct task_struct *task, const long request);
30681 +int gr_handle_proc_ptrace(struct task_struct *task);
30682 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
30683 + const struct vfsmount *mnt);
30684 +int gr_check_crash_exec(const struct file *filp);
30685 +int gr_acl_is_enabled(void);
30686 +void gr_set_kernel_label(struct task_struct *task);
30687 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
30688 + const gid_t gid);
30689 +int gr_set_proc_label(const struct dentry *dentry,
30690 + const struct vfsmount *mnt);
30691 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
30692 + const struct vfsmount *mnt);
30693 +__u32 gr_acl_handle_open(const struct dentry *dentry,
30694 + const struct vfsmount *mnt, const int fmode);
30695 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
30696 + const struct dentry *p_dentry,
30697 + const struct vfsmount *p_mnt, const int fmode,
30698 + const int imode);
30699 +void gr_handle_create(const struct dentry *dentry,
30700 + const struct vfsmount *mnt);
30701 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
30702 + const struct dentry *parent_dentry,
30703 + const struct vfsmount *parent_mnt,
30705 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
30706 + const struct dentry *parent_dentry,
30707 + const struct vfsmount *parent_mnt);
30708 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
30709 + const struct vfsmount *mnt);
30710 +void gr_handle_delete(const ino_t ino, const dev_t dev);
30711 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
30712 + const struct vfsmount *mnt);
30713 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
30714 + const struct dentry *parent_dentry,
30715 + const struct vfsmount *parent_mnt,
30716 + const char *from);
30717 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
30718 + const struct dentry *parent_dentry,
30719 + const struct vfsmount *parent_mnt,
30720 + const struct dentry *old_dentry,
30721 + const struct vfsmount *old_mnt, const char *to);
30722 +int gr_acl_handle_rename(struct dentry *new_dentry,
30723 + struct dentry *parent_dentry,
30724 + const struct vfsmount *parent_mnt,
30725 + struct dentry *old_dentry,
30726 + struct inode *old_parent_inode,
30727 + struct vfsmount *old_mnt, const char *newname);
30728 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
30729 + struct dentry *old_dentry,
30730 + struct dentry *new_dentry,
30731 + struct vfsmount *mnt, const __u8 replace);
30732 +__u32 gr_check_link(const struct dentry *new_dentry,
30733 + const struct dentry *parent_dentry,
30734 + const struct vfsmount *parent_mnt,
30735 + const struct dentry *old_dentry,
30736 + const struct vfsmount *old_mnt);
30737 +int gr_acl_handle_filldir(const struct file *file, const char *name,
30738 + const unsigned int namelen, const ino_t ino);
30740 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
30741 + const struct vfsmount *mnt);
30742 +void gr_acl_handle_exit(void);
30743 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
30744 +int gr_acl_handle_procpidmem(const struct task_struct *task);
30746 +#ifdef CONFIG_GRKERNSEC
30747 +void gr_handle_mem_write(void);
30748 +void gr_handle_kmem_write(void);
30749 +void gr_handle_open_port(void);
30750 +int gr_handle_mem_mmap(const unsigned long offset,
30751 + struct vm_area_struct *vma);
30753 +extern int grsec_enable_dmesg;
30754 +extern int grsec_enable_randsrc;
30755 +extern int grsec_enable_shm;
30759 diff -urNp linux-2.6.24.4/include/linux/highmem.h linux-2.6.24.4/include/linux/highmem.h
30760 --- linux-2.6.24.4/include/linux/highmem.h 2008-03-24 14:49:18.000000000 -0400
30761 +++ linux-2.6.24.4/include/linux/highmem.h 2008-03-26 20:21:09.000000000 -0400
30762 @@ -124,6 +124,13 @@ static inline void clear_highpage(struct
30763 kunmap_atomic(kaddr, KM_USER0);
30766 +static inline void sanitize_highpage(struct page *page)
30768 + void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
30769 + clear_page(kaddr);
30770 + kunmap_atomic(kaddr, KM_CLEARPAGE);
30774 * Same but also flushes aliased cache contents to RAM.
30776 @@ -132,14 +139,14 @@ static inline void clear_highpage(struct
30778 #define zero_user_page(page, offset, size, km_type) \
30783 BUG_ON((offset) + (size) > PAGE_SIZE); \
30785 - kaddr = kmap_atomic(page, km_type); \
30786 - memset((char *)kaddr + (offset), 0, (size)); \
30787 + __kaddr = kmap_atomic(page, km_type); \
30788 + memset((char *)__kaddr + (offset), 0, (size)); \
30789 flush_dcache_page(page); \
30790 - kunmap_atomic(kaddr, (km_type)); \
30791 + kunmap_atomic(__kaddr, (km_type)); \
30794 static inline void __deprecated memclear_highpage_flush(struct page *page,
30795 diff -urNp linux-2.6.24.4/include/linux/init_task.h linux-2.6.24.4/include/linux/init_task.h
30796 --- linux-2.6.24.4/include/linux/init_task.h 2008-03-24 14:49:18.000000000 -0400
30797 +++ linux-2.6.24.4/include/linux/init_task.h 2008-03-26 20:21:09.000000000 -0400
30798 @@ -121,7 +121,7 @@ extern struct group_info init_groups;
30799 #define INIT_TASK(tsk) \
30802 - .stack = &init_thread_info, \
30803 + .stack = &init_thread_union, \
30804 .usage = ATOMIC_INIT(2), \
30806 .lock_depth = -1, \
30807 diff -urNp linux-2.6.24.4/include/linux/irqflags.h linux-2.6.24.4/include/linux/irqflags.h
30808 --- linux-2.6.24.4/include/linux/irqflags.h 2008-03-24 14:49:18.000000000 -0400
30809 +++ linux-2.6.24.4/include/linux/irqflags.h 2008-03-26 20:21:09.000000000 -0400
30810 @@ -84,10 +84,10 @@
30812 #define irqs_disabled() \
30814 - unsigned long flags; \
30815 + unsigned long __flags; \
30817 - raw_local_save_flags(flags); \
30818 - raw_irqs_disabled_flags(flags); \
30819 + raw_local_save_flags(__flags); \
30820 + raw_irqs_disabled_flags(__flags); \
30823 #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
30824 diff -urNp linux-2.6.24.4/include/linux/jbd2.h linux-2.6.24.4/include/linux/jbd2.h
30825 --- linux-2.6.24.4/include/linux/jbd2.h 2008-03-24 14:49:18.000000000 -0400
30826 +++ linux-2.6.24.4/include/linux/jbd2.h 2008-03-26 20:21:09.000000000 -0400
30827 @@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug;
30831 -#define jbd_debug(f, a...) /**/
30832 +#define jbd_debug(f, a...) do {} while (0)
30835 static inline void *jbd2_alloc(size_t size, gfp_t flags)
30836 diff -urNp linux-2.6.24.4/include/linux/jbd.h linux-2.6.24.4/include/linux/jbd.h
30837 --- linux-2.6.24.4/include/linux/jbd.h 2008-03-24 14:49:18.000000000 -0400
30838 +++ linux-2.6.24.4/include/linux/jbd.h 2008-03-26 20:21:09.000000000 -0400
30839 @@ -69,7 +69,7 @@ extern u8 journal_enable_debug;
30843 -#define jbd_debug(f, a...) /**/
30844 +#define jbd_debug(f, a...) do {} while (0)
30847 static inline void *jbd_alloc(size_t size, gfp_t flags)
30848 diff -urNp linux-2.6.24.4/include/linux/libata.h linux-2.6.24.4/include/linux/libata.h
30849 --- linux-2.6.24.4/include/linux/libata.h 2008-03-24 14:49:18.000000000 -0400
30850 +++ linux-2.6.24.4/include/linux/libata.h 2008-03-26 20:21:09.000000000 -0400
30851 @@ -62,11 +62,11 @@
30852 #ifdef ATA_VERBOSE_DEBUG
30853 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
30855 -#define VPRINTK(fmt, args...)
30856 +#define VPRINTK(fmt, args...) do {} while (0)
30857 #endif /* ATA_VERBOSE_DEBUG */
30859 -#define DPRINTK(fmt, args...)
30860 -#define VPRINTK(fmt, args...)
30861 +#define DPRINTK(fmt, args...) do {} while (0)
30862 +#define VPRINTK(fmt, args...) do {} while (0)
30863 #endif /* ATA_DEBUG */
30865 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
30866 diff -urNp linux-2.6.24.4/include/linux/mm.h linux-2.6.24.4/include/linux/mm.h
30867 --- linux-2.6.24.4/include/linux/mm.h 2008-03-24 14:49:18.000000000 -0400
30868 +++ linux-2.6.24.4/include/linux/mm.h 2008-03-26 20:21:09.000000000 -0400
30869 @@ -37,6 +37,7 @@ extern int sysctl_legacy_va_layout;
30870 #include <asm/page.h>
30871 #include <asm/pgtable.h>
30872 #include <asm/processor.h>
30873 +#include <asm/mman.h>
30875 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
30877 @@ -107,6 +108,14 @@ extern unsigned int kobjsize(const void
30879 #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
30881 +#ifdef CONFIG_PAX_PAGEEXEC
30882 +#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */
30885 +#ifdef CONFIG_PAX_MPROTECT
30886 +#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */
30889 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
30890 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
30892 @@ -792,6 +801,8 @@ struct shrinker {
30893 extern void register_shrinker(struct shrinker *);
30894 extern void unregister_shrinker(struct shrinker *);
30896 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
30898 int vma_wants_writenotify(struct vm_area_struct *vma);
30900 extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl));
30901 @@ -1018,6 +1029,7 @@ out:
30904 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
30905 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
30907 extern unsigned long do_brk(unsigned long, unsigned long);
30909 @@ -1070,6 +1082,10 @@ extern struct vm_area_struct * find_vma(
30910 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
30911 struct vm_area_struct **pprev);
30913 +extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
30914 +extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
30915 +extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
30917 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
30918 NULL if none. Assume start_addr < end_addr. */
30919 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
30920 @@ -1086,7 +1102,6 @@ static inline unsigned long vma_pages(st
30921 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
30924 -pgprot_t vm_get_page_prot(unsigned long vm_flags);
30925 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
30926 struct page *vmalloc_to_page(void *addr);
30927 unsigned long vmalloc_to_pfn(void *addr);
30928 @@ -1157,5 +1172,11 @@ int vmemmap_populate_basepages(struct pa
30929 unsigned long pages, int node);
30930 int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
30932 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
30933 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
30935 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
30938 #endif /* __KERNEL__ */
30939 #endif /* _LINUX_MM_H */
30940 diff -urNp linux-2.6.24.4/include/linux/mm_types.h linux-2.6.24.4/include/linux/mm_types.h
30941 --- linux-2.6.24.4/include/linux/mm_types.h 2008-03-24 14:49:18.000000000 -0400
30942 +++ linux-2.6.24.4/include/linux/mm_types.h 2008-03-26 20:21:09.000000000 -0400
30943 @@ -151,6 +151,8 @@ struct vm_area_struct {
30945 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
30948 + struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
30952 @@ -219,6 +221,24 @@ struct mm_struct {
30954 rwlock_t ioctx_list_lock;
30955 struct kioctx *ioctx_list;
30957 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30958 + unsigned long pax_flags;
30961 +#ifdef CONFIG_PAX_DLRESOLVE
30962 + unsigned long call_dl_resolve;
30965 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
30966 + unsigned long call_syscall;
30969 +#ifdef CONFIG_PAX_ASLR
30970 + unsigned long delta_mmap; /* randomized offset */
30971 + unsigned long delta_stack; /* randomized offset */
30976 #endif /* _LINUX_MM_TYPES_H */
30977 diff -urNp linux-2.6.24.4/include/linux/module.h linux-2.6.24.4/include/linux/module.h
30978 --- linux-2.6.24.4/include/linux/module.h 2008-03-24 14:49:18.000000000 -0400
30979 +++ linux-2.6.24.4/include/linux/module.h 2008-03-26 20:21:09.000000000 -0400
30980 @@ -296,16 +296,16 @@ struct module
30983 /* If this is non-NULL, vfree after init() returns */
30984 - void *module_init;
30985 + void *module_init_rx, *module_init_rw;
30987 /* Here is the actual code + data, vfree'd on unload. */
30988 - void *module_core;
30989 + void *module_core_rx, *module_core_rw;
30991 /* Here are the sizes of the init and core sections */
30992 - unsigned long init_size, core_size;
30993 + unsigned long init_size_rw, core_size_rw;
30995 /* The size of the executable code in each section. */
30996 - unsigned long init_text_size, core_text_size;
30997 + unsigned long init_size_rx, core_size_rx;
30999 /* The handle returned from unwind_add_table. */
31001 diff -urNp linux-2.6.24.4/include/linux/moduleloader.h linux-2.6.24.4/include/linux/moduleloader.h
31002 --- linux-2.6.24.4/include/linux/moduleloader.h 2008-03-24 14:49:18.000000000 -0400
31003 +++ linux-2.6.24.4/include/linux/moduleloader.h 2008-03-26 20:21:09.000000000 -0400
31004 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
31005 sections. Returns NULL on failure. */
31006 void *module_alloc(unsigned long size);
31008 +#ifdef CONFIG_PAX_KERNEXEC
31009 +void *module_alloc_exec(unsigned long size);
31011 +#define module_alloc_exec(x) module_alloc(x)
31014 /* Free memory returned from module_alloc. */
31015 void module_free(struct module *mod, void *module_region);
31017 +#ifdef CONFIG_PAX_KERNEXEC
31018 +void module_free_exec(struct module *mod, void *module_region);
31020 +#define module_free_exec(x, y) module_free(x, y)
31023 /* Apply the given relocation to the (simplified) ELF. Return -error
31025 int apply_relocate(Elf_Shdr *sechdrs,
31026 diff -urNp linux-2.6.24.4/include/linux/namei.h linux-2.6.24.4/include/linux/namei.h
31027 --- linux-2.6.24.4/include/linux/namei.h 2008-03-24 14:49:18.000000000 -0400
31028 +++ linux-2.6.24.4/include/linux/namei.h 2008-03-26 20:21:09.000000000 -0400
31029 @@ -21,7 +21,7 @@ struct nameidata {
31030 unsigned int flags;
31033 - char *saved_names[MAX_NESTED_LINKS + 1];
31034 + const char *saved_names[MAX_NESTED_LINKS + 1];
31038 @@ -90,12 +90,12 @@ extern int follow_up(struct vfsmount **,
31039 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
31040 extern void unlock_rename(struct dentry *, struct dentry *);
31042 -static inline void nd_set_link(struct nameidata *nd, char *path)
31043 +static inline void nd_set_link(struct nameidata *nd, const char *path)
31045 nd->saved_names[nd->depth] = path;
31048 -static inline char *nd_get_link(struct nameidata *nd)
31049 +static inline const char *nd_get_link(struct nameidata *nd)
31051 return nd->saved_names[nd->depth];
31053 diff -urNp linux-2.6.24.4/include/linux/percpu.h linux-2.6.24.4/include/linux/percpu.h
31054 --- linux-2.6.24.4/include/linux/percpu.h 2008-03-24 14:49:18.000000000 -0400
31055 +++ linux-2.6.24.4/include/linux/percpu.h 2008-03-26 20:21:09.000000000 -0400
31059 #define PERCPU_ENOUGH_ROOM \
31060 - (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
31061 + ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
31062 #endif /* PERCPU_ENOUGH_ROOM */
31065 diff -urNp linux-2.6.24.4/include/linux/poison.h linux-2.6.24.4/include/linux/poison.h
31066 --- linux-2.6.24.4/include/linux/poison.h 2008-03-24 14:49:18.000000000 -0400
31067 +++ linux-2.6.24.4/include/linux/poison.h 2008-03-26 20:21:09.000000000 -0400
31069 * under normal circumstances, used to verify that nobody uses
31070 * non-initialized list entries.
31072 -#define LIST_POISON1 ((void *) 0x00100100)
31073 -#define LIST_POISON2 ((void *) 0x00200200)
31074 +#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
31075 +#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
31077 /********** mm/slab.c **********/
31079 diff -urNp linux-2.6.24.4/include/linux/random.h linux-2.6.24.4/include/linux/random.h
31080 --- linux-2.6.24.4/include/linux/random.h 2008-03-24 14:49:18.000000000 -0400
31081 +++ linux-2.6.24.4/include/linux/random.h 2008-03-26 20:21:09.000000000 -0400
31082 @@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
31083 u32 random32(void);
31084 void srandom32(u32 seed);
31086 +static inline unsigned long pax_get_random_long(void)
31088 + return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
31091 #endif /* __KERNEL___ */
31093 #endif /* _LINUX_RANDOM_H */
31094 diff -urNp linux-2.6.24.4/include/linux/sched.h linux-2.6.24.4/include/linux/sched.h
31095 --- linux-2.6.24.4/include/linux/sched.h 2008-03-24 14:49:18.000000000 -0400
31096 +++ linux-2.6.24.4/include/linux/sched.h 2008-03-26 20:21:16.000000000 -0400
31097 @@ -94,6 +94,7 @@ struct sched_param {
31098 struct exec_domain;
31099 struct futex_pi_state;
31101 +struct linux_binprm;
31104 * List of flags we want to share for kernel threads,
31105 @@ -507,6 +508,15 @@ struct signal_struct {
31106 unsigned audit_tty;
31107 struct tty_audit_buf *tty_audit_buf;
31110 +#ifdef CONFIG_GRKERNSEC
31116 + u8 used_accept:1;
31120 /* Context switch must be unlocked if interrupts are to be enabled */
31121 @@ -916,7 +926,7 @@ struct sched_entity {
31123 struct task_struct {
31124 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
31126 + union thread_union *stack;
31128 unsigned int flags; /* per process flags, defined below */
31129 unsigned int ptrace;
31130 @@ -983,10 +993,9 @@ struct task_struct {
31134 -#ifdef CONFIG_CC_STACKPROTECTOR
31135 /* Canary value for the -fstack-protector gcc feature */
31136 unsigned long stack_canary;
31140 * pointers to (original) parent process, youngest child, younger sibling,
31141 * older sibling, respectively. (p->father can be replaced with
31142 @@ -1007,8 +1016,8 @@ struct task_struct {
31143 struct list_head thread_group;
31145 struct completion *vfork_done; /* for vfork() */
31146 - int __user *set_child_tid; /* CLONE_CHILD_SETTID */
31147 - int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
31148 + pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
31149 + pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
31151 unsigned int rt_priority;
31152 cputime_t utime, stime, utimescaled, stimescaled;
31153 @@ -1178,8 +1187,60 @@ struct task_struct {
31156 struct prop_local_single dirties;
31158 +#ifdef CONFIG_GRKERNSEC
31160 + struct acl_subject_label *acl;
31161 + struct acl_role_label *role;
31162 + struct file *exec_file;
31171 +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
31172 +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
31173 +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
31174 +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
31175 +/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
31176 +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
31178 +#ifdef CONFIG_PAX_SOFTMODE
31179 +extern unsigned int pax_softmode;
31182 +extern int pax_check_flags(unsigned long *);
31184 +/* if tsk != current then task_lock must be held on it */
31185 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
31186 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
31188 + if (likely(tsk->mm))
31189 + return tsk->mm->pax_flags;
31194 +/* if tsk != current then task_lock must be held on it */
31195 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
31197 + if (likely(tsk->mm)) {
31198 + tsk->mm->pax_flags = flags;
31205 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
31206 +extern void pax_set_initial_flags(struct linux_binprm *bprm);
31207 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
31208 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
31212 * Priority of a process goes from 0..MAX_PRIO-1, valid RT
31213 * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
31214 @@ -1677,7 +1738,7 @@ extern void __cleanup_signal(struct sign
31215 extern void __cleanup_sighand(struct sighand_struct *);
31216 extern void exit_itimers(struct signal_struct *);
31218 -extern NORET_TYPE void do_group_exit(int);
31219 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
31221 extern void daemonize(const char *, ...);
31222 extern int allow_signal(int);
31223 @@ -1779,8 +1840,8 @@ static inline void unlock_task_sighand(s
31225 #ifndef __HAVE_THREAD_FUNCTIONS
31227 -#define task_thread_info(task) ((struct thread_info *)(task)->stack)
31228 -#define task_stack_page(task) ((task)->stack)
31229 +#define task_thread_info(task) (&(task)->stack->thread_info)
31230 +#define task_stack_page(task) ((void *)(task)->stack)
31232 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
31234 @@ -1917,6 +1978,12 @@ extern void arch_pick_mmap_layout(struct
31235 static inline void arch_pick_mmap_layout(struct mm_struct *mm)
31237 mm->mmap_base = TASK_UNMAPPED_BASE;
31239 +#ifdef CONFIG_PAX_RANDMMAP
31240 + if (mm->pax_flags & MF_PAX_RANDMMAP)
31241 + mm->mmap_base += mm->delta_mmap;
31244 mm->get_unmapped_area = arch_get_unmapped_area;
31245 mm->unmap_area = arch_unmap_area;
31247 diff -urNp linux-2.6.24.4/include/linux/screen_info.h linux-2.6.24.4/include/linux/screen_info.h
31248 --- linux-2.6.24.4/include/linux/screen_info.h 2008-03-24 14:49:18.000000000 -0400
31249 +++ linux-2.6.24.4/include/linux/screen_info.h 2008-03-26 20:21:09.000000000 -0400
31250 @@ -42,7 +42,8 @@ struct screen_info {
31251 __u16 pages; /* 0x32 */
31252 __u16 vesa_attributes; /* 0x34 */
31253 __u32 capabilities; /* 0x36 */
31254 - __u8 _reserved[6]; /* 0x3a */
31255 + __u16 vesapm_size; /* 0x3a */
31256 + __u8 _reserved[4]; /* 0x3c */
31257 } __attribute__((packed));
31259 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
31260 diff -urNp linux-2.6.24.4/include/linux/security.h linux-2.6.24.4/include/linux/security.h
31261 --- linux-2.6.24.4/include/linux/security.h 2008-03-24 14:49:18.000000000 -0400
31262 +++ linux-2.6.24.4/include/linux/security.h 2008-03-26 20:21:09.000000000 -0400
31263 @@ -2266,7 +2266,7 @@ static inline struct dentry *securityfs_
31265 struct dentry *parent,
31267 - struct file_operations *fops)
31268 + const struct file_operations *fops)
31270 return ERR_PTR(-ENODEV);
31272 diff -urNp linux-2.6.24.4/include/linux/shm.h linux-2.6.24.4/include/linux/shm.h
31273 --- linux-2.6.24.4/include/linux/shm.h 2008-03-24 14:49:18.000000000 -0400
31274 +++ linux-2.6.24.4/include/linux/shm.h 2008-03-26 20:21:09.000000000 -0400
31275 @@ -87,6 +87,10 @@ struct shmid_kernel /* private to the ke
31278 struct user_struct *mlock_user;
31279 +#ifdef CONFIG_GRKERNSEC
31280 + time_t shm_createtime;
31285 /* shm_mode upper byte flags */
31286 diff -urNp linux-2.6.24.4/include/linux/sysctl.h linux-2.6.24.4/include/linux/sysctl.h
31287 --- linux-2.6.24.4/include/linux/sysctl.h 2008-03-24 14:49:18.000000000 -0400
31288 +++ linux-2.6.24.4/include/linux/sysctl.h 2008-03-26 20:21:09.000000000 -0400
31289 @@ -164,9 +164,21 @@ enum
31290 KERN_MAX_LOCK_DEPTH=74,
31291 KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
31292 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
31294 +#ifdef CONFIG_GRKERNSEC
31295 + KERN_GRSECURITY=98, /* grsecurity */
31298 +#ifdef CONFIG_PAX_SOFTMODE
31299 + KERN_PAX=99, /* PaX control */
31304 +#ifdef CONFIG_PAX_SOFTMODE
31306 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
31310 /* CTL_VM names: */
31312 diff -urNp linux-2.6.24.4/include/linux/uaccess.h linux-2.6.24.4/include/linux/uaccess.h
31313 --- linux-2.6.24.4/include/linux/uaccess.h 2008-03-24 14:49:18.000000000 -0400
31314 +++ linux-2.6.24.4/include/linux/uaccess.h 2008-03-26 20:21:09.000000000 -0400
31315 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
31317 mm_segment_t old_fs = get_fs(); \
31319 - set_fs(KERNEL_DS); \
31320 pagefault_disable(); \
31321 + set_fs(KERNEL_DS); \
31322 ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
31323 - pagefault_enable(); \
31325 + pagefault_enable(); \
31329 diff -urNp linux-2.6.24.4/include/linux/udf_fs.h linux-2.6.24.4/include/linux/udf_fs.h
31330 --- linux-2.6.24.4/include/linux/udf_fs.h 2008-03-24 14:49:18.000000000 -0400
31331 +++ linux-2.6.24.4/include/linux/udf_fs.h 2008-03-26 20:21:09.000000000 -0400
31336 -#define udf_debug(f, a...) /**/
31337 +#define udf_debug(f, a...) do {} while (0)
31340 #define udf_info(f, a...) \
31341 diff -urNp linux-2.6.24.4/include/net/sctp/sctp.h linux-2.6.24.4/include/net/sctp/sctp.h
31342 --- linux-2.6.24.4/include/net/sctp/sctp.h 2008-03-24 14:49:18.000000000 -0400
31343 +++ linux-2.6.24.4/include/net/sctp/sctp.h 2008-03-26 20:21:09.000000000 -0400
31344 @@ -316,8 +316,8 @@ extern int sctp_debug_flag;
31346 #else /* SCTP_DEBUG */
31348 -#define SCTP_DEBUG_PRINTK(whatever...)
31349 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
31350 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
31351 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
31352 #define SCTP_ENABLE_DEBUG
31353 #define SCTP_DISABLE_DEBUG
31354 #define SCTP_ASSERT(expr, str, func)
31355 diff -urNp linux-2.6.24.4/include/sound/core.h linux-2.6.24.4/include/sound/core.h
31356 --- linux-2.6.24.4/include/sound/core.h 2008-03-24 14:49:18.000000000 -0400
31357 +++ linux-2.6.24.4/include/sound/core.h 2008-03-26 20:21:09.000000000 -0400
31358 @@ -396,9 +396,9 @@ void snd_verbose_printd(const char *file
31360 #else /* !CONFIG_SND_DEBUG */
31362 -#define snd_printd(fmt, args...) /* nothing */
31363 +#define snd_printd(fmt, args...) do {} while (0)
31364 #define snd_assert(expr, args...) (void)(expr)
31365 -#define snd_BUG() /* nothing */
31366 +#define snd_BUG() do {} while (0)
31368 #endif /* CONFIG_SND_DEBUG */
31370 @@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file
31372 #define snd_printdd(format, args...) snd_printk(format, ##args)
31374 -#define snd_printdd(format, args...) /* nothing */
31375 +#define snd_printdd(format, args...) do {} while (0)
31379 diff -urNp linux-2.6.24.4/init/do_mounts.c linux-2.6.24.4/init/do_mounts.c
31380 --- linux-2.6.24.4/init/do_mounts.c 2008-03-24 14:49:18.000000000 -0400
31381 +++ linux-2.6.24.4/init/do_mounts.c 2008-03-26 20:21:09.000000000 -0400
31382 @@ -68,11 +68,12 @@ static dev_t try_name(char *name, int pa
31384 /* read device number from .../dev */
31386 - sprintf(path, "/sys/block/%s/dev", name);
31387 - fd = sys_open(path, 0, 0);
31388 + if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
31390 + fd = sys_open((char __user *)path, 0, 0);
31393 - len = sys_read(fd, buf, 32);
31394 + len = sys_read(fd, (char __user *)buf, 32);
31396 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
31398 @@ -98,11 +99,12 @@ static dev_t try_name(char *name, int pa
31401 /* otherwise read range from .../range */
31402 - sprintf(path, "/sys/block/%s/range", name);
31403 - fd = sys_open(path, 0, 0);
31404 + if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
31406 + fd = sys_open((char __user *)path, 0, 0);
31409 - len = sys_read(fd, buf, 32);
31410 + len = sys_read(fd, (char __user *)buf, 32);
31412 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
31414 @@ -145,12 +145,12 @@ dev_t name_to_dev_t(char *name)
31415 int part, mount_result;
31417 #ifdef CONFIG_SYSFS
31418 - int mkdir_err = sys_mkdir("/sys", 0700);
31419 + int mkdir_err = sys_mkdir((char __user *)"/sys", 0700);
31421 * When changing resume parameter for TuxOnIce, sysfs may
31422 * already be mounted.
31424 - mount_result = sys_mount("sysfs", "/sys", "sysfs", 0, NULL);
31425 + mount_result = sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL);
31426 if (mount_result < 0 && mount_result != -EBUSY)
31429 @@ -198,10 +200,10 @@ dev_t name_to_dev_t(char *name)
31431 #ifdef CONFIG_SYSFS
31432 if (mount_result >= 0)
31433 - sys_umount("/sys", 0);
31434 + sys_umount((char __user *)"/sys", 0);
31437 - sys_rmdir("/sys");
31438 + sys_rmdir((char __user *)"/sys");
31442 @@ -281,11 +283,11 @@ static void __init get_fs_names(char *pa
31444 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
31446 - int err = sys_mount(name, "/root", fs, flags, data);
31447 + int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
31451 - sys_chdir("/root");
31452 + sys_chdir((char __user *)"/root");
31453 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
31454 printk("VFS: Mounted root (%s filesystem)%s.\n",
31455 current->fs->pwdmnt->mnt_sb->s_type->name,
31456 @@ -371,18 +373,18 @@ void __init change_floppy(char *fmt, ...
31457 va_start(args, fmt);
31458 vsprintf(buf, fmt, args);
31460 - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
31461 + fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
31463 sys_ioctl(fd, FDEJECT, 0);
31466 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
31467 - fd = sys_open("/dev/console", O_RDWR, 0);
31468 + fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
31470 sys_ioctl(fd, TCGETS, (long)&termios);
31471 termios.c_lflag &= ~ICANON;
31472 sys_ioctl(fd, TCSETSF, (long)&termios);
31473 - sys_read(fd, &c, 1);
31474 + sys_read(fd, (char __user *)&c, 1);
31475 termios.c_lflag |= ICANON;
31476 sys_ioctl(fd, TCSETSF, (long)&termios);
31478 @@ -468,8 +470,8 @@ void __init prepare_namespace(void)
31482 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
31484 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
31485 + sys_chroot((char __user *)".");
31486 security_sb_post_mountroot();
31489 diff -urNp linux-2.6.24.4/init/do_mounts.h linux-2.6.24.4/init/do_mounts.h
31490 --- linux-2.6.24.4/init/do_mounts.h 2008-03-24 14:49:18.000000000 -0400
31491 +++ linux-2.6.24.4/init/do_mounts.h 2008-03-26 20:21:09.000000000 -0400
31492 @@ -15,15 +15,15 @@ extern char *root_device_name;
31494 static inline int create_dev(char *name, dev_t dev)
31496 - sys_unlink(name);
31497 - return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
31498 + sys_unlink((char __user *)name);
31499 + return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
31502 #if BITS_PER_LONG == 32
31503 static inline u32 bstat(char *name)
31505 struct stat64 stat;
31506 - if (sys_stat64(name, &stat) != 0)
31507 + if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
31509 if (!S_ISBLK(stat.st_mode))
31511 diff -urNp linux-2.6.24.4/init/do_mounts_md.c linux-2.6.24.4/init/do_mounts_md.c
31512 --- linux-2.6.24.4/init/do_mounts_md.c 2008-03-24 14:49:18.000000000 -0400
31513 +++ linux-2.6.24.4/init/do_mounts_md.c 2008-03-26 20:21:09.000000000 -0400
31514 @@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
31515 partitioned ? "_d" : "", minor,
31516 md_setup_args[ent].device_names);
31518 - fd = sys_open(name, 0, 0);
31519 + fd = sys_open((char __user *)name, 0, 0);
31521 printk(KERN_ERR "md: open failed - cannot start "
31522 "array %s\n", name);
31523 @@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
31527 - fd = sys_open(name, 0, 0);
31528 + fd = sys_open((char __user *)name, 0, 0);
31529 sys_ioctl(fd, BLKRRPART, 0);
31532 @@ -271,7 +271,7 @@ void __init md_run_setup(void)
31533 if (raid_noautodetect)
31534 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
31536 - int fd = sys_open("/dev/md0", 0, 0);
31537 + int fd = sys_open((char __user *)"/dev/md0", 0, 0);
31539 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
31541 diff -urNp linux-2.6.24.4/init/initramfs.c linux-2.6.24.4/init/initramfs.c
31542 --- linux-2.6.24.4/init/initramfs.c 2008-03-24 14:49:18.000000000 -0400
31543 +++ linux-2.6.24.4/init/initramfs.c 2008-03-26 20:21:09.000000000 -0400
31544 @@ -240,7 +240,7 @@ static int __init maybe_link(void)
31546 char *old = find_link(major, minor, ino, mode, collected);
31548 - return (sys_link(old, collected) < 0) ? -1 : 1;
31549 + return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
31553 @@ -249,11 +249,11 @@ static void __init clean_path(char *path
31557 - if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
31558 + if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
31559 if (S_ISDIR(st.st_mode))
31561 + sys_rmdir((char __user *)path);
31563 - sys_unlink(path);
31564 + sys_unlink((char __user *)path);
31568 @@ -276,7 +276,7 @@ static int __init do_name(void)
31569 int openflags = O_WRONLY|O_CREAT;
31571 openflags |= O_TRUNC;
31572 - wfd = sys_open(collected, openflags, mode);
31573 + wfd = sys_open((char __user *)collected, openflags, mode);
31576 sys_fchown(wfd, uid, gid);
31577 @@ -285,15 +285,15 @@ static int __init do_name(void)
31580 } else if (S_ISDIR(mode)) {
31581 - sys_mkdir(collected, mode);
31582 - sys_chown(collected, uid, gid);
31583 - sys_chmod(collected, mode);
31584 + sys_mkdir((char __user *)collected, mode);
31585 + sys_chown((char __user *)collected, uid, gid);
31586 + sys_chmod((char __user *)collected, mode);
31587 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
31588 S_ISFIFO(mode) || S_ISSOCK(mode)) {
31589 if (maybe_link() == 0) {
31590 - sys_mknod(collected, mode, rdev);
31591 - sys_chown(collected, uid, gid);
31592 - sys_chmod(collected, mode);
31593 + sys_mknod((char __user *)collected, mode, rdev);
31594 + sys_chown((char __user *)collected, uid, gid);
31595 + sys_chmod((char __user *)collected, mode);
31599 @@ -302,13 +302,13 @@ static int __init do_name(void)
31600 static int __init do_copy(void)
31602 if (count >= body_len) {
31603 - sys_write(wfd, victim, body_len);
31604 + sys_write(wfd, (char __user *)victim, body_len);
31610 - sys_write(wfd, victim, count);
31611 + sys_write(wfd, (char __user *)victim, count);
31615 @@ -319,8 +319,8 @@ static int __init do_symlink(void)
31617 collected[N_ALIGN(name_len) + body_len] = '\0';
31618 clean_path(collected, 0);
31619 - sys_symlink(collected + N_ALIGN(name_len), collected);
31620 - sys_lchown(collected, uid, gid);
31621 + sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
31622 + sys_lchown((char __user *)collected, uid, gid);
31624 next_state = Reset;
31626 diff -urNp linux-2.6.24.4/init/Kconfig linux-2.6.24.4/init/Kconfig
31627 --- linux-2.6.24.4/init/Kconfig 2008-03-24 14:49:18.000000000 -0400
31628 +++ linux-2.6.24.4/init/Kconfig 2008-03-26 20:21:09.000000000 -0400
31629 @@ -469,6 +469,7 @@ config SYSCTL_SYSCALL
31631 bool "Load all symbols for debugging/ksymoops" if EMBEDDED
31633 + depends on !GRKERNSEC_HIDESYM
31635 Say Y here to let the kernel print out symbolic crash information and
31636 symbolic stack backtraces. This increases the size of the kernel
31637 diff -urNp linux-2.6.24.4/init/main.c linux-2.6.24.4/init/main.c
31638 --- linux-2.6.24.4/init/main.c 2008-03-24 14:49:18.000000000 -0400
31639 +++ linux-2.6.24.4/init/main.c 2008-03-26 20:21:09.000000000 -0400
31640 @@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void)
31642 extern void tc_init(void);
31644 +extern void grsecurity_init(void);
31646 enum system_states system_state;
31647 EXPORT_SYMBOL(system_state);
31648 @@ -187,6 +188,17 @@ static int __init set_reset_devices(char
31650 __setup("reset_devices", set_reset_devices);
31652 +#ifdef CONFIG_PAX_SOFTMODE
31653 +unsigned int pax_softmode;
31655 +static int __init setup_pax_softmode(char *str)
31657 + get_option(&str, &pax_softmode);
31660 +__setup("pax_softmode=", setup_pax_softmode);
31663 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
31664 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
31665 static const char *panic_later, *panic_param;
31666 @@ -847,6 +859,8 @@ static int __init kernel_init(void * unu
31667 prepare_namespace();
31670 + grsecurity_init();
31673 * Ok, we have completed the initial bootup, and
31674 * we're essentially up and running. Get rid of the
31675 diff -urNp linux-2.6.24.4/init/noinitramfs.c linux-2.6.24.4/init/noinitramfs.c
31676 --- linux-2.6.24.4/init/noinitramfs.c 2008-03-24 14:49:18.000000000 -0400
31677 +++ linux-2.6.24.4/init/noinitramfs.c 2008-03-26 20:21:09.000000000 -0400
31678 @@ -29,7 +29,7 @@ static int __init default_rootfs(void)
31682 - err = sys_mkdir("/dev", 0755);
31683 + err = sys_mkdir((const char __user *)"/dev", 0755);
31687 @@ -39,7 +39,7 @@ static int __init default_rootfs(void)
31691 - err = sys_mkdir("/root", 0700);
31692 + err = sys_mkdir((const char __user *)"/root", 0700);
31696 diff -urNp linux-2.6.24.4/ipc/ipc_sysctl.c linux-2.6.24.4/ipc/ipc_sysctl.c
31697 --- linux-2.6.24.4/ipc/ipc_sysctl.c 2008-03-24 14:49:18.000000000 -0400
31698 +++ linux-2.6.24.4/ipc/ipc_sysctl.c 2008-03-26 20:21:09.000000000 -0400
31699 @@ -157,7 +157,7 @@ static struct ctl_table ipc_kern_table[]
31700 .proc_handler = proc_ipc_dointvec,
31701 .strategy = sysctl_ipc_data,
31704 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31707 static struct ctl_table ipc_root_table[] = {
31708 @@ -167,7 +167,7 @@ static struct ctl_table ipc_root_table[]
31710 .child = ipc_kern_table,
31713 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31716 static int __init ipc_sysctl_init(void)
31717 diff -urNp linux-2.6.24.4/ipc/msg.c linux-2.6.24.4/ipc/msg.c
31718 --- linux-2.6.24.4/ipc/msg.c 2008-03-24 14:49:18.000000000 -0400
31719 +++ linux-2.6.24.4/ipc/msg.c 2008-03-26 20:21:09.000000000 -0400
31721 #include <linux/rwsem.h>
31722 #include <linux/nsproxy.h>
31723 #include <linux/vs_base.h>
31724 +#include <linux/grsecurity.h>
31726 #include <asm/current.h>
31727 #include <asm/uaccess.h>
31728 @@ -315,6 +316,7 @@ asmlinkage long sys_msgget(key_t key, in
31729 struct ipc_namespace *ns;
31730 struct ipc_ops msg_ops;
31731 struct ipc_params msg_params;
31734 ns = current->nsproxy->ipc_ns;
31736 @@ -325,7 +327,11 @@ asmlinkage long sys_msgget(key_t key, in
31737 msg_params.key = key;
31738 msg_params.flg = msgflg;
31740 - return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31741 + err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31743 + gr_log_msgget(err, msgflg);
31748 static inline unsigned long
31749 @@ -586,6 +592,7 @@ asmlinkage long sys_msgctl(int msqid, in
31753 + gr_log_msgrm(ipcp->uid, ipcp->cuid);
31757 diff -urNp linux-2.6.24.4/ipc/sem.c linux-2.6.24.4/ipc/sem.c
31758 --- linux-2.6.24.4/ipc/sem.c 2008-03-24 14:49:18.000000000 -0400
31759 +++ linux-2.6.24.4/ipc/sem.c 2008-03-26 20:21:09.000000000 -0400
31761 #include <linux/nsproxy.h>
31762 #include <linux/vs_base.h>
31763 #include <linux/vs_limit.h>
31764 +#include <linux/grsecurity.h>
31766 #include <asm/uaccess.h>
31768 @@ -334,6 +335,7 @@ asmlinkage long sys_semget(key_t key, in
31769 struct ipc_namespace *ns;
31770 struct ipc_ops sem_ops;
31771 struct ipc_params sem_params;
31774 ns = current->nsproxy->ipc_ns;
31776 @@ -348,7 +350,11 @@ asmlinkage long sys_semget(key_t key, in
31777 sem_params.flg = semflg;
31778 sem_params.u.nsems = nsems;
31780 - return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31781 + err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31783 + gr_log_semget(err, semflg);
31788 /* Manage the doubly linked list sma->sem_pending as a FIFO:
31789 @@ -936,6 +942,7 @@ static int semctl_down(struct ipc_namesp
31793 + gr_log_semrm(ipcp->uid, ipcp->cuid);
31797 diff -urNp linux-2.6.24.4/ipc/shm.c linux-2.6.24.4/ipc/shm.c
31798 --- linux-2.6.24.4/ipc/shm.c 2008-03-24 14:49:18.000000000 -0400
31799 +++ linux-2.6.24.4/ipc/shm.c 2008-03-26 20:21:09.000000000 -0400
31801 #include <linux/mount.h>
31802 #include <linux/vs_context.h>
31803 #include <linux/vs_limit.h>
31804 +#include <linux/grsecurity.h>
31806 #include <asm/uaccess.h>
31808 @@ -71,6 +72,14 @@ static void shm_destroy (struct ipc_name
31809 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
31812 +#ifdef CONFIG_GRKERNSEC
31813 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31814 + const time_t shm_createtime, const uid_t cuid,
31815 + const int shmid);
31816 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31817 + const time_t shm_createtime);
31820 static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
31822 ns->ids[IPC_SHM_IDS] = ids;
31823 @@ -87,6 +96,8 @@ static void __shm_init_ns(struct ipc_nam
31825 static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
31827 + gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
31829 if (shp->shm_nattch){
31830 shp->shm_perm.mode |= SHM_DEST;
31831 /* Do not find it any more */
31832 @@ -443,6 +454,14 @@ static int newseg(struct ipc_namespace *
31833 shp->shm_lprid = 0;
31834 shp->shm_atim = shp->shm_dtim = 0;
31835 shp->shm_ctim = get_seconds();
31836 +#ifdef CONFIG_GRKERNSEC
31838 + struct timespec timeval;
31839 + do_posix_clock_monotonic_gettime(&timeval);
31841 + shp->shm_createtime = timeval.tv_sec;
31844 shp->shm_segsz = size;
31845 shp->shm_nattch = 0;
31846 shp->shm_perm.id = shm_buildid(id, shp->shm_perm.seq);
31847 @@ -497,6 +516,7 @@ asmlinkage long sys_shmget (key_t key, s
31848 struct ipc_namespace *ns;
31849 struct ipc_ops shm_ops;
31850 struct ipc_params shm_params;
31853 ns = current->nsproxy->ipc_ns;
31855 @@ -508,7 +528,11 @@ asmlinkage long sys_shmget (key_t key, s
31856 shm_params.flg = shmflg;
31857 shm_params.u.size = size;
31859 - return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31860 + err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31862 + gr_log_shmget(err, shmflg, size);
31867 static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
31868 @@ -974,9 +998,21 @@ long do_shmat(int shmid, char __user *sh
31872 +#ifdef CONFIG_GRKERNSEC
31873 + if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
31874 + shp->shm_perm.cuid, shmid) ||
31875 + !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
31881 path.dentry = dget(shp->shm_file->f_path.dentry);
31882 path.mnt = shp->shm_file->f_path.mnt;
31884 +#ifdef CONFIG_GRKERNSEC
31885 + shp->shm_lapid = current->pid;
31887 size = i_size_read(path.dentry->d_inode);
31890 diff -urNp linux-2.6.24.4/kernel/acct.c linux-2.6.24.4/kernel/acct.c
31891 --- linux-2.6.24.4/kernel/acct.c 2008-03-24 14:49:18.000000000 -0400
31892 +++ linux-2.6.24.4/kernel/acct.c 2008-03-26 20:21:09.000000000 -0400
31893 @@ -511,7 +511,7 @@ static void do_acct_process(struct file
31895 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
31896 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
31897 - file->f_op->write(file, (char *)&ac,
31898 + file->f_op->write(file, (char __user *)&ac,
31899 sizeof(acct_t), &file->f_pos);
31900 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
31902 diff -urNp linux-2.6.24.4/kernel/capability.c linux-2.6.24.4/kernel/capability.c
31903 --- linux-2.6.24.4/kernel/capability.c 2008-03-24 14:49:18.000000000 -0400
31904 +++ linux-2.6.24.4/kernel/capability.c 2008-03-26 20:21:09.000000000 -0400
31906 #include <linux/syscalls.h>
31907 #include <linux/pid_namespace.h>
31908 #include <linux/vs_context.h>
31909 +#include <linux/grsecurity.h>
31910 #include <asm/uaccess.h>
31913 @@ -233,13 +234,22 @@ out:
31915 int __capable(struct task_struct *t, int cap)
31917 - if (security_capable(t, cap) == 0) {
31918 + if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
31919 t->flags |= PF_SUPERPRIV;
31925 +int capable_nolog(int cap)
31927 + if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
31928 + current->flags |= PF_SUPERPRIV;
31934 #include <linux/vserver/base.h>
31935 int capable(int cap)
31937 @@ -252,3 +262,4 @@ int capable(int cap)
31938 return __capable(current, cap);
31940 EXPORT_SYMBOL(capable);
31941 +EXPORT_SYMBOL(capable_nolog);
31942 diff -urNp linux-2.6.24.4/kernel/configs.c linux-2.6.24.4/kernel/configs.c
31943 --- linux-2.6.24.4/kernel/configs.c 2008-03-24 14:49:18.000000000 -0400
31944 +++ linux-2.6.24.4/kernel/configs.c 2008-03-26 20:21:09.000000000 -0400
31945 @@ -79,8 +79,16 @@ static int __init ikconfig_init(void)
31946 struct proc_dir_entry *entry;
31948 /* create the current config file */
31949 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
31950 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31951 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
31952 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31953 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
31956 entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
31962 diff -urNp linux-2.6.24.4/kernel/cpu.c linux-2.6.24.4/kernel/cpu.c
31963 --- linux-2.6.24.4/kernel/cpu.c 2008-03-24 14:49:18.000000000 -0400
31964 +++ linux-2.6.24.4/kernel/cpu.c 2008-03-26 20:21:16.000000000 -0400
31966 static DEFINE_MUTEX(cpu_add_remove_lock);
31967 static DEFINE_MUTEX(cpu_bitmask_lock);
31969 -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
31970 +static RAW_NOTIFIER_HEAD(cpu_chain);
31972 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
31973 * Should always be manipulated under cpu_add_remove_lock
31974 @@ -66,7 +66,7 @@ EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
31975 #endif /* CONFIG_HOTPLUG_CPU */
31977 /* Need to know about CPUs going up/down? */
31978 -int __cpuinit register_cpu_notifier(struct notifier_block *nb)
31979 +int register_cpu_notifier(struct notifier_block *nb)
31982 mutex_lock(&cpu_add_remove_lock);
31983 diff -urNp linux-2.6.24.4/kernel/exit.c linux-2.6.24.4/kernel/exit.c
31984 --- linux-2.6.24.4/kernel/exit.c 2008-03-24 14:49:18.000000000 -0400
31985 +++ linux-2.6.24.4/kernel/exit.c 2008-03-26 20:21:09.000000000 -0400
31987 #include <linux/vs_network.h>
31988 #include <linux/vs_pid.h>
31989 #include <linux/vserver/global.h>
31990 +#include <linux/grsecurity.h>
31992 +#ifdef CONFIG_GRKERNSEC
31993 +extern rwlock_t grsec_exec_file_lock;
31996 #include <asm/uaccess.h>
31997 #include <asm/unistd.h>
31998 @@ -122,6 +127,7 @@ static void __exit_signal(struct task_st
32000 __unhash_process(tsk);
32002 + gr_del_task_from_ip_table(tsk);
32003 tsk->signal = NULL;
32004 tsk->sighand = NULL;
32005 spin_unlock(&sighand->siglock);
32006 @@ -273,12 +279,23 @@ static void reparent_to_kthreadd(void)
32008 write_lock_irq(&tasklist_lock);
32010 +#ifdef CONFIG_GRKERNSEC
32011 + write_lock(&grsec_exec_file_lock);
32012 + if (current->exec_file) {
32013 + fput(current->exec_file);
32014 + current->exec_file = NULL;
32016 + write_unlock(&grsec_exec_file_lock);
32019 ptrace_unlink(current);
32020 /* Reparent to init */
32021 remove_parent(current);
32022 current->real_parent = current->parent = kthreadd_task;
32023 add_parent(current);
32025 + gr_set_kernel_label(current);
32027 /* Set the exit signal to SIGCHLD so we signal init on exit */
32028 current->exit_signal = SIGCHLD;
32030 @@ -373,6 +390,17 @@ void daemonize(const char *name, ...)
32031 vsnprintf(current->comm, sizeof(current->comm), name, args);
32034 +#ifdef CONFIG_GRKERNSEC
32035 + write_lock(&grsec_exec_file_lock);
32036 + if (current->exec_file) {
32037 + fput(current->exec_file);
32038 + current->exec_file = NULL;
32040 + write_unlock(&grsec_exec_file_lock);
32043 + gr_set_kernel_label(current);
32046 * If we were started as result of loading a module, close all of the
32047 * user space pages. We don't need them, and if we didn't close them
32048 @@ -990,6 +1018,9 @@ fastcall NORET_TYPE void do_exit(long co
32049 tsk->exit_code = code;
32050 taskstats_exit(tsk, group_dead);
32052 + gr_acl_handle_psacct(tsk, code);
32053 + gr_acl_handle_exit();
32058 @@ -1200,7 +1231,7 @@ static int wait_task_zombie(struct task_
32059 pid_t pid = task_pid_nr_ns(p, ns);
32060 uid_t uid = p->uid;
32061 int exit_code = p->exit_code;
32065 if (unlikely(p->exit_state != EXIT_ZOMBIE))
32067 diff -urNp linux-2.6.24.4/kernel/fork.c linux-2.6.24.4/kernel/fork.c
32068 --- linux-2.6.24.4/kernel/fork.c 2008-03-24 14:49:18.000000000 -0400
32069 +++ linux-2.6.24.4/kernel/fork.c 2008-03-26 20:21:09.000000000 -0400
32071 #include <linux/vs_limit.h>
32072 #include <linux/vs_memory.h>
32073 #include <linux/vserver/global.h>
32074 +#include <linux/grsecurity.h>
32076 #include <asm/pgtable.h>
32077 #include <asm/pgalloc.h>
32078 @@ -180,7 +181,7 @@ static struct task_struct *dup_task_stru
32083 + tsk->stack = (union thread_union *)ti;
32085 err = prop_local_init_single(&tsk->dirties);
32087 @@ -192,7 +193,7 @@ static struct task_struct *dup_task_stru
32088 setup_thread_stack(tsk, orig);
32090 #ifdef CONFIG_CC_STACKPROTECTOR
32091 - tsk->stack_canary = get_random_int();
32092 + tsk->stack_canary = pax_get_random_long();
32095 /* One for us, one for whoever does the "release_task()" (usually parent) */
32096 @@ -224,8 +225,8 @@ static int dup_mmap(struct mm_struct *mm
32099 mm->mmap_cache = NULL;
32100 - mm->free_area_cache = oldmm->mmap_base;
32101 - mm->cached_hole_size = ~0UL;
32102 + mm->free_area_cache = oldmm->free_area_cache;
32103 + mm->cached_hole_size = oldmm->cached_hole_size;
32105 cpus_clear(mm->cpu_vm_mask);
32106 mm->mm_rb = RB_ROOT;
32107 @@ -262,6 +263,7 @@ static int dup_mmap(struct mm_struct *mm
32108 tmp->vm_flags &= ~VM_LOCKED;
32110 tmp->vm_next = NULL;
32111 + tmp->vm_mirror = NULL;
32112 anon_vma_link(tmp);
32113 file = tmp->vm_file;
32115 @@ -298,6 +300,31 @@ static int dup_mmap(struct mm_struct *mm
32120 +#ifdef CONFIG_PAX_SEGMEXEC
32121 + if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
32122 + struct vm_area_struct *mpnt_m;
32124 + for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
32125 + BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
32127 + if (!mpnt->vm_mirror)
32130 + if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
32131 + BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
32132 + mpnt->vm_mirror = mpnt_m;
32134 + BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
32135 + mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
32136 + mpnt_m->vm_mirror->vm_mirror = mpnt_m;
32137 + mpnt->vm_mirror->vm_mirror = mpnt;
32144 /* a new mm has just been created */
32145 arch_dup_mmap(oldmm, mm);
32147 @@ -475,7 +502,7 @@ void mm_release(struct task_struct *tsk,
32148 if (tsk->clear_child_tid
32149 && !(tsk->flags & PF_SIGNALED)
32150 && atomic_read(&mm->mm_users) > 1) {
32151 - u32 __user * tidptr = tsk->clear_child_tid;
32152 + pid_t __user * tidptr = tsk->clear_child_tid;
32153 tsk->clear_child_tid = NULL;
32156 @@ -483,7 +510,7 @@ void mm_release(struct task_struct *tsk,
32157 * not set up a proper pointer then tough luck.
32159 put_user(0, tidptr);
32160 - sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
32161 + sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
32165 @@ -1015,6 +1042,9 @@ static struct task_struct *copy_process(
32166 DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
32167 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
32170 + gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
32172 init_vx_info(&p->vx_info, current->vx_info);
32173 init_nx_info(&p->nx_info, current->nx_info);
32175 @@ -1169,6 +1199,8 @@ static struct task_struct *copy_process(
32176 if (clone_flags & CLONE_THREAD)
32177 p->tgid = current->tgid;
32179 + gr_copy_label(p);
32181 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
32183 * Clear TID on mm_release()?
32184 @@ -1356,6 +1388,8 @@ bad_fork_cleanup_count:
32188 + gr_log_forkfail(retval);
32190 return ERR_PTR(retval);
32193 @@ -1437,6 +1471,8 @@ long do_fork(unsigned long clone_flags,
32194 if (clone_flags & CLONE_PARENT_SETTID)
32195 put_user(nr, parent_tidptr);
32197 + gr_handle_brute_check();
32199 if (clone_flags & CLONE_VFORK) {
32200 p->vfork_done = &vfork;
32201 init_completion(&vfork);
32202 diff -urNp linux-2.6.24.4/kernel/futex.c linux-2.6.24.4/kernel/futex.c
32203 --- linux-2.6.24.4/kernel/futex.c 2008-03-24 14:49:18.000000000 -0400
32204 +++ linux-2.6.24.4/kernel/futex.c 2008-03-26 20:21:09.000000000 -0400
32205 @@ -192,6 +192,11 @@ static int get_futex_key(u32 __user *uad
32209 +#ifdef CONFIG_PAX_SEGMEXEC
32210 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
32215 * The futex address must be "naturally" aligned.
32217 @@ -218,8 +223,8 @@ static int get_futex_key(u32 __user *uad
32218 * The futex is hashed differently depending on whether
32219 * it's in a shared or private mapping. So check vma first.
32221 - vma = find_extend_vma(mm, address);
32222 - if (unlikely(!vma))
32223 + vma = find_vma(mm, address);
32224 + if (unlikely(!vma || address < vma->vm_start))
32228 @@ -1962,7 +1967,7 @@ retry:
32230 static inline int fetch_robust_entry(struct robust_list __user **entry,
32231 struct robust_list __user * __user *head,
32233 + unsigned int *pi)
32235 unsigned long uentry;
32237 diff -urNp linux-2.6.24.4/kernel/irq/handle.c linux-2.6.24.4/kernel/irq/handle.c
32238 --- linux-2.6.24.4/kernel/irq/handle.c 2008-03-24 14:49:18.000000000 -0400
32239 +++ linux-2.6.24.4/kernel/irq/handle.c 2008-03-26 20:21:09.000000000 -0400
32240 @@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
32242 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
32244 - .affinity = CPU_MASK_ALL
32245 + .affinity = CPU_MASK_ALL,
32250 diff -urNp linux-2.6.24.4/kernel/kallsyms.c linux-2.6.24.4/kernel/kallsyms.c
32251 --- linux-2.6.24.4/kernel/kallsyms.c 2008-03-24 14:49:18.000000000 -0400
32252 +++ linux-2.6.24.4/kernel/kallsyms.c 2008-03-26 20:21:09.000000000 -0400
32253 @@ -70,6 +70,19 @@ static inline int is_kernel_text(unsigne
32255 static inline int is_kernel(unsigned long addr)
32258 +#ifdef CONFIG_PAX_KERNEXEC
32260 +#ifdef CONFIG_MODULES
32261 + if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
32262 + ktla_ktva(addr) < (unsigned long)MODULES_END)
32266 + if (is_kernel_inittext(addr))
32270 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
32272 return in_gate_area_no_task(addr);
32273 @@ -378,7 +391,6 @@ static unsigned long get_ksymbol_core(st
32275 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
32277 - iter->name[0] = '\0';
32278 iter->nameoff = get_symbol_offset(new_pos);
32279 iter->pos = new_pos;
32281 @@ -462,7 +474,7 @@ static int kallsyms_open(struct inode *i
32282 struct kallsym_iter *iter;
32285 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
32286 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
32289 reset_iter(iter, 0);
32290 @@ -486,7 +498,15 @@ static int __init kallsyms_init(void)
32292 struct proc_dir_entry *entry;
32294 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
32295 +#ifdef CONFIG_GRKERNSEC_PROC_USER
32296 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
32297 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
32298 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
32301 entry = create_proc_entry("kallsyms", 0444, NULL);
32304 entry->proc_fops = &kallsyms_operations;
32306 diff -urNp linux-2.6.24.4/kernel/kmod.c linux-2.6.24.4/kernel/kmod.c
32307 --- linux-2.6.24.4/kernel/kmod.c 2008-03-24 14:49:18.000000000 -0400
32308 +++ linux-2.6.24.4/kernel/kmod.c 2008-03-26 20:21:09.000000000 -0400
32309 @@ -107,7 +107,7 @@ int request_module(const char *fmt, ...)
32313 - ret = call_usermodehelper(modprobe_path, argv, envp, 1);
32314 + ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
32315 atomic_dec(&kmod_concurrent);
32318 diff -urNp linux-2.6.24.4/kernel/kprobes.c linux-2.6.24.4/kernel/kprobes.c
32319 --- linux-2.6.24.4/kernel/kprobes.c 2008-03-24 14:49:18.000000000 -0400
32320 +++ linux-2.6.24.4/kernel/kprobes.c 2008-03-26 20:21:09.000000000 -0400
32321 @@ -162,7 +162,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
32322 * kernel image and loaded module images reside. This is required
32323 * so x86_64 can correctly handle the %rip-relative fixups.
32325 - kip->insns = module_alloc(PAGE_SIZE);
32326 + kip->insns = module_alloc_exec(PAGE_SIZE);
32330 @@ -194,7 +194,7 @@ static int __kprobes collect_one_slot(st
32331 hlist_add_head(&kip->hlist,
32332 &kprobe_insn_pages);
32334 - module_free(NULL, kip->insns);
32335 + module_free_exec(NULL, kip->insns);
32339 diff -urNp linux-2.6.24.4/kernel/lockdep.c linux-2.6.24.4/kernel/lockdep.c
32340 --- linux-2.6.24.4/kernel/lockdep.c 2008-03-24 14:49:18.000000000 -0400
32341 +++ linux-2.6.24.4/kernel/lockdep.c 2008-03-26 20:21:16.000000000 -0400
32342 @@ -598,6 +598,10 @@ static int static_obj(void *obj)
32346 +#ifdef CONFIG_PAX_KERNEXEC
32347 + start = (unsigned long )&_data;
32353 diff -urNp linux-2.6.24.4/kernel/module.c linux-2.6.24.4/kernel/module.c
32354 --- linux-2.6.24.4/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
32355 +++ linux-2.6.24.4/kernel/module.c 2008-03-26 20:21:09.000000000 -0400
32357 #include <asm/uaccess.h>
32358 #include <asm/semaphore.h>
32359 #include <asm/cacheflush.h>
32361 +#ifdef CONFIG_PAX_KERNEXEC
32362 +#include <asm/desc.h>
32365 #include <linux/license.h>
32367 extern int module_sysfs_initialized;
32368 @@ -69,6 +74,8 @@ static LIST_HEAD(modules);
32370 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
32372 +extern int gr_check_modstop(void);
32374 int register_module_notifier(struct notifier_block * nb)
32376 return blocking_notifier_chain_register(&module_notify_list, nb);
32377 @@ -349,7 +356,7 @@ static void *percpu_modalloc(unsigned lo
32381 - if (align > PAGE_SIZE) {
32382 + if (align-1 >= PAGE_SIZE) {
32383 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
32384 name, align, PAGE_SIZE);
32386 @@ -662,6 +669,9 @@ sys_delete_module(const char __user *nam
32387 char name[MODULE_NAME_LEN];
32388 int ret, forced = 0;
32390 + if (gr_check_modstop())
32393 if (!capable(CAP_SYS_MODULE))
32396 @@ -1310,16 +1320,19 @@ static void free_module(struct module *m
32397 module_unload_free(mod);
32399 /* This may be NULL, but that's OK */
32400 - module_free(mod, mod->module_init);
32401 + module_free(mod, mod->module_init_rw);
32402 + module_free_exec(mod, mod->module_init_rx);
32405 percpu_modfree(mod->percpu);
32407 /* Free lock-classes: */
32408 - lockdep_free_key_range(mod->module_core, mod->core_size);
32409 + lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
32410 + lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
32412 /* Finally, free the core (containing the module structure) */
32413 - module_free(mod, mod->module_core);
32414 + module_free_exec(mod, mod->module_core_rx);
32415 + module_free(mod, mod->module_core_rw);
32418 void *__symbol_get(const char *symbol)
32419 @@ -1380,10 +1393,14 @@ static int simplify_symbols(Elf_Shdr *se
32420 struct module *mod)
32422 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
32423 - unsigned long secbase;
32424 + unsigned long secbase, symbol;
32425 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32428 +#ifdef CONFIG_PAX_KERNEXEC
32429 + unsigned long cr0;
32432 for (i = 1; i < n; i++) {
32433 switch (sym[i].st_shndx) {
32435 @@ -1402,10 +1419,19 @@ static int simplify_symbols(Elf_Shdr *se
32440 - = resolve_symbol(sechdrs, versindex,
32441 + symbol = resolve_symbol(sechdrs, versindex,
32442 strtab + sym[i].st_name, mod);
32444 +#ifdef CONFIG_PAX_KERNEXEC
32445 + pax_open_kernel(cr0);
32448 + sym[i].st_value = symbol;
32450 +#ifdef CONFIG_PAX_KERNEXEC
32451 + pax_close_kernel(cr0);
32454 /* Ok if resolved. */
32455 if (sym[i].st_value != 0)
32457 @@ -1420,11 +1446,27 @@ static int simplify_symbols(Elf_Shdr *se
32460 /* Divert to percpu allocation if a percpu var. */
32461 - if (sym[i].st_shndx == pcpuindex)
32462 + if (sym[i].st_shndx == pcpuindex) {
32464 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
32465 + secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
32467 secbase = (unsigned long)mod->percpu;
32472 secbase = sechdrs[sym[i].st_shndx].sh_addr;
32474 +#ifdef CONFIG_PAX_KERNEXEC
32475 + pax_open_kernel(cr0);
32478 sym[i].st_value += secbase;
32480 +#ifdef CONFIG_PAX_KERNEXEC
32481 + pax_close_kernel(cr0);
32487 @@ -1476,11 +1518,14 @@ static void layout_sections(struct modul
32488 || strncmp(secstrings + s->sh_name,
32491 - s->sh_entsize = get_offset(&mod->core_size, s);
32492 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32493 + s->sh_entsize = get_offset(&mod->core_size_rw, s);
32495 + s->sh_entsize = get_offset(&mod->core_size_rx, s);
32496 DEBUGP("\t%s\n", secstrings + s->sh_name);
32499 - mod->core_text_size = mod->core_size;
32500 + mod->core_size_rx = mod->core_size_rx;
32503 DEBUGP("Init section allocation order:\n");
32504 @@ -1494,12 +1539,15 @@ static void layout_sections(struct modul
32505 || strncmp(secstrings + s->sh_name,
32508 - s->sh_entsize = (get_offset(&mod->init_size, s)
32509 - | INIT_OFFSET_MASK);
32510 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32511 + s->sh_entsize = get_offset(&mod->init_size_rw, s);
32513 + s->sh_entsize = get_offset(&mod->init_size_rx, s);
32514 + s->sh_entsize |= INIT_OFFSET_MASK;
32515 DEBUGP("\t%s\n", secstrings + s->sh_name);
32518 - mod->init_text_size = mod->init_size;
32519 + mod->init_size_rx = mod->init_size_rx;
32523 @@ -1626,14 +1674,31 @@ static void add_kallsyms(struct module *
32527 +#ifdef CONFIG_PAX_KERNEXEC
32528 + unsigned long cr0;
32531 mod->symtab = (void *)sechdrs[symindex].sh_addr;
32532 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32533 mod->strtab = (void *)sechdrs[strindex].sh_addr;
32535 /* Set types up while we still have access to sections. */
32536 - for (i = 0; i < mod->num_symtab; i++)
32537 - mod->symtab[i].st_info
32538 - = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32540 + for (i = 0; i < mod->num_symtab; i++) {
32541 + char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32543 +#ifdef CONFIG_PAX_KERNEXEC
32544 + pax_open_kernel(cr0);
32547 + mod->symtab[i].st_info = type;
32549 +#ifdef CONFIG_PAX_KERNEXEC
32550 + pax_close_kernel(cr0);
32557 static inline void add_kallsyms(struct module *mod,
32558 @@ -1683,6 +1748,10 @@ static struct module *load_module(void _
32559 struct exception_table_entry *extable;
32560 mm_segment_t old_fs;
32562 +#ifdef CONFIG_PAX_KERNEXEC
32563 + unsigned long cr0;
32566 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
32568 if (len < sizeof(*hdr))
32569 @@ -1841,21 +1910,57 @@ static struct module *load_module(void _
32570 layout_sections(mod, hdr, sechdrs, secstrings);
32572 /* Do the allocs. */
32573 - ptr = module_alloc(mod->core_size);
32574 + ptr = module_alloc(mod->core_size_rw);
32579 - memset(ptr, 0, mod->core_size);
32580 - mod->module_core = ptr;
32581 + memset(ptr, 0, mod->core_size_rw);
32582 + mod->module_core_rw = ptr;
32584 - ptr = module_alloc(mod->init_size);
32585 - if (!ptr && mod->init_size) {
32586 + ptr = module_alloc(mod->init_size_rw);
32587 + if (!ptr && mod->init_size_rw) {
32589 + goto free_core_rw;
32591 + memset(ptr, 0, mod->init_size_rw);
32592 + mod->module_init_rw = ptr;
32594 + ptr = module_alloc_exec(mod->core_size_rx);
32598 + goto free_init_rw;
32600 - memset(ptr, 0, mod->init_size);
32601 - mod->module_init = ptr;
32603 +#ifdef CONFIG_PAX_KERNEXEC
32604 + pax_open_kernel(cr0);
32607 + memset(ptr, 0, mod->core_size_rx);
32609 +#ifdef CONFIG_PAX_KERNEXEC
32610 + pax_close_kernel(cr0);
32613 + mod->module_core_rx = ptr;
32615 + ptr = module_alloc_exec(mod->init_size_rx);
32616 + if (!ptr && mod->init_size_rx) {
32618 + goto free_core_rx;
32621 +#ifdef CONFIG_PAX_KERNEXEC
32622 + pax_open_kernel(cr0);
32625 + memset(ptr, 0, mod->init_size_rx);
32627 +#ifdef CONFIG_PAX_KERNEXEC
32628 + pax_close_kernel(cr0);
32631 + mod->module_init_rx = ptr;
32633 /* Transfer each section which specifies SHF_ALLOC */
32634 DEBUGP("final section addresses:\n");
32635 @@ -1865,17 +1970,41 @@ static struct module *load_module(void _
32636 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
32639 - if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
32640 - dest = mod->module_init
32641 - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32643 - dest = mod->module_core + sechdrs[i].sh_entsize;
32644 + if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
32645 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32646 + dest = mod->module_init_rw
32647 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32649 + dest = mod->module_init_rx
32650 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32652 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32653 + dest = mod->module_core_rw + sechdrs[i].sh_entsize;
32655 + dest = mod->module_core_rx + sechdrs[i].sh_entsize;
32658 - if (sechdrs[i].sh_type != SHT_NOBITS)
32659 - memcpy(dest, (void *)sechdrs[i].sh_addr,
32660 - sechdrs[i].sh_size);
32661 + if (sechdrs[i].sh_type != SHT_NOBITS) {
32663 +#ifdef CONFIG_PAX_KERNEXEC
32664 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
32665 + pax_open_kernel(cr0);
32666 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32667 + pax_close_kernel(cr0);
32671 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32673 /* Update sh_addr to point to copy in image. */
32674 - sechdrs[i].sh_addr = (unsigned long)dest;
32676 +#ifdef CONFIG_PAX_KERNEXEC
32677 + if (sechdrs[i].sh_flags & SHF_EXECINSTR)
32678 + sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
32682 + sechdrs[i].sh_addr = (unsigned long)dest;
32683 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
32685 /* Module has been moved. */
32686 @@ -2009,12 +2138,12 @@ static struct module *load_module(void _
32687 * Do it before processing of module parameters, so the module
32688 * can provide parameter accessor functions of its own.
32690 - if (mod->module_init)
32691 - flush_icache_range((unsigned long)mod->module_init,
32692 - (unsigned long)mod->module_init
32693 - + mod->init_size);
32694 - flush_icache_range((unsigned long)mod->module_core,
32695 - (unsigned long)mod->module_core + mod->core_size);
32696 + if (mod->module_init_rx)
32697 + flush_icache_range((unsigned long)mod->module_init_rx,
32698 + (unsigned long)mod->module_init_rx
32699 + + mod->init_size_rx);
32700 + flush_icache_range((unsigned long)mod->module_core_rx,
32701 + (unsigned long)mod->module_core_rx + mod->core_size_rx);
32705 @@ -2058,9 +2187,13 @@ static struct module *load_module(void _
32706 module_arch_cleanup(mod);
32708 module_unload_free(mod);
32709 - module_free(mod, mod->module_init);
32711 - module_free(mod, mod->module_core);
32712 + module_free_exec(mod, mod->module_init_rx);
32714 + module_free_exec(mod, mod->module_core_rx);
32716 + module_free(mod, mod->module_init_rw);
32718 + module_free(mod, mod->module_core_rw);
32721 percpu_modfree(percpu);
32722 @@ -2096,6 +2229,9 @@ sys_init_module(void __user *umod,
32723 struct module *mod;
32726 + if (gr_check_modstop())
32729 /* Must have permission */
32730 if (!capable(CAP_SYS_MODULE))
32732 @@ -2142,10 +2278,12 @@ sys_init_module(void __user *umod,
32733 /* Drop initial reference. */
32735 unwind_remove_table(mod->unwind_info, 1);
32736 - module_free(mod, mod->module_init);
32737 - mod->module_init = NULL;
32738 - mod->init_size = 0;
32739 - mod->init_text_size = 0;
32740 + module_free(mod, mod->module_init_rw);
32741 + module_free_exec(mod, mod->module_init_rx);
32742 + mod->module_init_rw = NULL;
32743 + mod->module_init_rx = NULL;
32744 + mod->init_size_rw = 0;
32745 + mod->init_size_rx = 0;
32746 mutex_unlock(&module_mutex);
32749 @@ -2153,6 +2291,13 @@ sys_init_module(void __user *umod,
32751 static inline int within(unsigned long addr, void *start, unsigned long size)
32754 +#ifdef CONFIG_PAX_KERNEXEC
32755 + if (ktla_ktva(addr) >= (unsigned long)start &&
32756 + ktla_ktva(addr) < (unsigned long)start + size)
32760 return ((void *)addr >= start && (void *)addr < start + size);
32763 @@ -2176,10 +2321,14 @@ static const char *get_ksymbol(struct mo
32764 unsigned long nextval;
32766 /* At worse, next value is at end of module */
32767 - if (within(addr, mod->module_init, mod->init_size))
32768 - nextval = (unsigned long)mod->module_init+mod->init_text_size;
32769 + if (within(addr, mod->module_init_rx, mod->init_size_rx))
32770 + nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
32771 + else if (within(addr, mod->module_init_rw, mod->init_size_rw))
32772 + nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
32773 + else if (within(addr, mod->module_core_rx, mod->core_size_rx))
32774 + nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
32776 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
32777 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
32779 /* Scan for closest preceeding symbol, and next symbol. (ELF
32780 starts real symbols at 1). */
32781 @@ -2225,8 +2374,10 @@ const char *module_address_lookup(unsign
32784 list_for_each_entry(mod, &modules, list) {
32785 - if (within(addr, mod->module_init, mod->init_size)
32786 - || within(addr, mod->module_core, mod->core_size)) {
32787 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32788 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
32789 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
32790 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
32792 *modname = mod->name;
32793 ret = get_ksymbol(mod, addr, size, offset);
32794 @@ -2243,8 +2394,10 @@ int lookup_module_symbol_name(unsigned l
32797 list_for_each_entry(mod, &modules, list) {
32798 - if (within(addr, mod->module_init, mod->init_size) ||
32799 - within(addr, mod->module_core, mod->core_size)) {
32800 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32801 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
32802 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
32803 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
32806 sym = get_ksymbol(mod, addr, NULL, NULL);
32807 @@ -2267,8 +2420,10 @@ int lookup_module_symbol_attrs(unsigned
32810 list_for_each_entry(mod, &modules, list) {
32811 - if (within(addr, mod->module_init, mod->init_size) ||
32812 - within(addr, mod->module_core, mod->core_size)) {
32813 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32814 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
32815 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
32816 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
32819 sym = get_ksymbol(mod, addr, size, offset);
32820 @@ -2390,7 +2545,7 @@ static int m_show(struct seq_file *m, vo
32823 seq_printf(m, "%s %lu",
32824 - mod->name, mod->init_size + mod->core_size);
32825 + mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
32826 print_unload_info(m, mod);
32828 /* Informative for users. */
32829 @@ -2399,7 +2554,7 @@ static int m_show(struct seq_file *m, vo
32830 mod->state == MODULE_STATE_COMING ? "Loading":
32832 /* Used by oprofile and other similar tools. */
32833 - seq_printf(m, " 0x%p", mod->module_core);
32834 + seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
32838 @@ -2455,7 +2610,8 @@ int is_module_address(unsigned long addr
32841 list_for_each_entry(mod, &modules, list) {
32842 - if (within(addr, mod->module_core, mod->core_size)) {
32843 + if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
32844 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
32848 @@ -2473,8 +2629,8 @@ struct module *__module_text_address(uns
32849 struct module *mod;
32851 list_for_each_entry(mod, &modules, list)
32852 - if (within(addr, mod->module_init, mod->init_text_size)
32853 - || within(addr, mod->module_core, mod->core_text_size))
32854 + if (within(addr, mod->module_init_rx, mod->init_size_rx)
32855 + || within(addr, mod->module_core_rx, mod->core_size_rx))
32859 diff -urNp linux-2.6.24.4/kernel/mutex.c linux-2.6.24.4/kernel/mutex.c
32860 --- linux-2.6.24.4/kernel/mutex.c 2008-03-24 14:49:18.000000000 -0400
32861 +++ linux-2.6.24.4/kernel/mutex.c 2008-03-26 20:21:09.000000000 -0400
32862 @@ -82,7 +82,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
32864 * This function is similar to (but not equivalent to) down().
32866 -void inline fastcall __sched mutex_lock(struct mutex *lock)
32867 +inline void fastcall __sched mutex_lock(struct mutex *lock)
32871 diff -urNp linux-2.6.24.4/kernel/panic.c linux-2.6.24.4/kernel/panic.c
32872 --- linux-2.6.24.4/kernel/panic.c 2008-03-24 14:49:18.000000000 -0400
32873 +++ linux-2.6.24.4/kernel/panic.c 2008-03-26 20:21:09.000000000 -0400
32875 #include <linux/kexec.h>
32876 #include <linux/debug_locks.h>
32877 #include <linux/random.h>
32878 +#include <linux/kallsyms.h>
32882 @@ -299,6 +300,8 @@ void oops_exit(void)
32884 void __stack_chk_fail(void)
32886 + print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
32888 panic("stack-protector: Kernel stack is corrupted");
32890 EXPORT_SYMBOL(__stack_chk_fail);
32891 diff -urNp linux-2.6.24.4/kernel/params.c linux-2.6.24.4/kernel/params.c
32892 --- linux-2.6.24.4/kernel/params.c 2008-03-24 14:49:18.000000000 -0400
32893 +++ linux-2.6.24.4/kernel/params.c 2008-03-26 20:21:09.000000000 -0400
32894 @@ -272,7 +272,7 @@ static int param_array(const char *name,
32895 unsigned int min, unsigned int max,
32896 void *elem, int elemsize,
32897 int (*set)(const char *, struct kernel_param *kp),
32899 + unsigned int *num)
32902 struct kernel_param kp;
32903 diff -urNp linux-2.6.24.4/kernel/pid.c linux-2.6.24.4/kernel/pid.c
32904 --- linux-2.6.24.4/kernel/pid.c 2008-03-24 14:49:18.000000000 -0400
32905 +++ linux-2.6.24.4/kernel/pid.c 2008-03-26 20:21:09.000000000 -0400
32907 #include <linux/syscalls.h>
32908 #include <linux/vs_pid.h>
32909 #include <linux/vserver/global.h>
32910 +#include <linux/grsecurity.h>
32912 #define pid_hashfn(nr, ns) \
32913 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
32914 @@ -45,7 +46,7 @@ static struct kmem_cache *pid_ns_cachep;
32916 int pid_max = PID_MAX_DEFAULT;
32918 -#define RESERVED_PIDS 300
32919 +#define RESERVED_PIDS 500
32921 int pid_max_min = RESERVED_PIDS + 1;
32922 int pid_max_max = PID_MAX_LIMIT;
32923 @@ -375,7 +376,14 @@ struct task_struct * fastcall pid_task(s
32924 struct task_struct *find_task_by_pid_type_ns(int type, int nr,
32925 struct pid_namespace *ns)
32927 - return pid_task(find_pid_ns(nr, ns), type);
32928 + struct task_struct *task;
32930 + task = pid_task(find_pid_ns(nr, ns), type);
32932 + if (gr_pid_is_chrooted(task))
32938 EXPORT_SYMBOL(find_task_by_pid_type_ns);
32939 diff -urNp linux-2.6.24.4/kernel/posix-cpu-timers.c linux-2.6.24.4/kernel/posix-cpu-timers.c
32940 --- linux-2.6.24.4/kernel/posix-cpu-timers.c 2008-03-24 14:49:18.000000000 -0400
32941 +++ linux-2.6.24.4/kernel/posix-cpu-timers.c 2008-03-26 20:21:09.000000000 -0400
32943 #include <linux/posix-timers.h>
32944 #include <asm/uaccess.h>
32945 #include <linux/errno.h>
32946 +#include <linux/grsecurity.h>
32948 static int check_clock(const clockid_t which_clock)
32950 @@ -1144,6 +1145,7 @@ static void check_process_timers(struct
32951 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
32954 + gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
32955 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
32957 * At the soft limit, send a SIGXCPU every second.
32958 diff -urNp linux-2.6.24.4/kernel/power/poweroff.c linux-2.6.24.4/kernel/power/poweroff.c
32959 --- linux-2.6.24.4/kernel/power/poweroff.c 2008-03-24 14:49:18.000000000 -0400
32960 +++ linux-2.6.24.4/kernel/power/poweroff.c 2008-03-26 20:21:09.000000000 -0400
32961 @@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
32962 .enable_mask = SYSRQ_ENABLE_BOOT,
32965 -static int pm_sysrq_init(void)
32966 +static int __init pm_sysrq_init(void)
32968 register_sysrq_key('o', &sysrq_poweroff_op);
32970 diff -urNp linux-2.6.24.4/kernel/printk.c linux-2.6.24.4/kernel/printk.c
32971 --- linux-2.6.24.4/kernel/printk.c 2008-03-24 14:49:18.000000000 -0400
32972 +++ linux-2.6.24.4/kernel/printk.c 2008-03-26 20:21:09.000000000 -0400
32974 #include <linux/syscalls.h>
32975 #include <linux/jiffies.h>
32976 #include <linux/vs_cvirt.h>
32977 +#include <linux/grsecurity.h>
32979 #include <asm/uaccess.h>
32981 @@ -293,6 +294,11 @@ int do_syslog(int type, char __user *buf
32985 +#ifdef CONFIG_GRKERNSEC_DMESG
32986 + if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
32990 error = security_syslog(type);
32993 diff -urNp linux-2.6.24.4/kernel/ptrace.c linux-2.6.24.4/kernel/ptrace.c
32994 --- linux-2.6.24.4/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400
32995 +++ linux-2.6.24.4/kernel/ptrace.c 2008-03-26 20:21:09.000000000 -0400
32997 #include <linux/audit.h>
32998 #include <linux/pid_namespace.h>
32999 #include <linux/vs_context.h>
33000 +#include <linux/grsecurity.h>
33002 #include <asm/pgtable.h>
33003 #include <asm/uaccess.h>
33004 @@ -139,12 +140,12 @@ int __ptrace_may_attach(struct task_stru
33005 (current->uid != task->uid) ||
33006 (current->gid != task->egid) ||
33007 (current->gid != task->sgid) ||
33008 - (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
33009 + (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
33013 dumpable = get_dumpable(task->mm);
33014 - if (!dumpable && !capable(CAP_SYS_PTRACE))
33015 + if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
33018 return security_ptrace(current, task);
33019 @@ -203,7 +204,7 @@ repeat:
33021 task->ptrace |= PT_PTRACED | ((task->real_parent != current)
33022 ? PT_ATTACHED : 0);
33023 - if (capable(CAP_SYS_PTRACE))
33024 + if (capable_nolog(CAP_SYS_PTRACE))
33025 task->ptrace |= PT_PTRACE_CAP;
33027 __ptrace_link(task, current);
33028 @@ -494,6 +495,11 @@ asmlinkage long sys_ptrace(long request,
33030 goto out_put_task_struct;
33032 + if (gr_handle_ptrace(child, request)) {
33034 + goto out_put_task_struct;
33037 ret = arch_ptrace(child, request, addr, data);
33039 goto out_put_task_struct;
33040 diff -urNp linux-2.6.24.4/kernel/rcupdate.c linux-2.6.24.4/kernel/rcupdate.c
33041 --- linux-2.6.24.4/kernel/rcupdate.c 2008-03-24 14:49:18.000000000 -0400
33042 +++ linux-2.6.24.4/kernel/rcupdate.c 2008-03-26 20:21:09.000000000 -0400
33043 @@ -70,11 +70,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk
33044 .cpumask = CPU_MASK_NONE,
33047 -DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
33048 -DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
33049 +DEFINE_PER_CPU(struct rcu_data, rcu_data);
33050 +DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
33052 /* Fake initialization required by compiler */
33053 -static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
33054 +static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet);
33055 static int blimit = 10;
33056 static int qhimark = 10000;
33057 static int qlowmark = 100;
33058 diff -urNp linux-2.6.24.4/kernel/relay.c linux-2.6.24.4/kernel/relay.c
33059 --- linux-2.6.24.4/kernel/relay.c 2008-03-24 14:49:18.000000000 -0400
33060 +++ linux-2.6.24.4/kernel/relay.c 2008-03-26 20:21:09.000000000 -0400
33061 @@ -1141,7 +1141,7 @@ static int subbuf_splice_actor(struct fi
33064 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
33065 - if (ret < 0 || ret < total_len)
33066 + if ((int)ret < 0 || ret < total_len)
33069 if (read_start + ret == nonpad_end)
33070 diff -urNp linux-2.6.24.4/kernel/resource.c linux-2.6.24.4/kernel/resource.c
33071 --- linux-2.6.24.4/kernel/resource.c 2008-03-24 14:49:18.000000000 -0400
33072 +++ linux-2.6.24.4/kernel/resource.c 2008-03-26 20:21:09.000000000 -0400
33073 @@ -133,10 +133,27 @@ static int __init ioresources_init(void)
33075 struct proc_dir_entry *entry;
33077 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
33078 +#ifdef CONFIG_GRKERNSEC_PROC_USER
33079 + entry = create_proc_entry("ioports", S_IRUSR, NULL);
33080 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33081 + entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
33084 entry = create_proc_entry("ioports", 0, NULL);
33087 entry->proc_fops = &proc_ioports_operations;
33089 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
33090 +#ifdef CONFIG_GRKERNSEC_PROC_USER
33091 + entry = create_proc_entry("iomem", S_IRUSR, NULL);
33092 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
33093 + entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
33096 entry = create_proc_entry("iomem", 0, NULL);
33099 entry->proc_fops = &proc_iomem_operations;
33101 diff -urNp linux-2.6.24.4/kernel/sched.c linux-2.6.24.4/kernel/sched.c
33102 --- linux-2.6.24.4/kernel/sched.c 2008-03-24 14:49:18.000000000 -0400
33103 +++ linux-2.6.24.4/kernel/sched.c 2008-03-26 20:21:09.000000000 -0400
33105 #include <linux/pagemap.h>
33106 #include <linux/vs_sched.h>
33107 #include <linux/vs_cvirt.h>
33108 +#include <linux/grsecurity.h>
33110 #include <asm/tlb.h>
33111 #include <asm/irq_regs.h>
33112 @@ -3619,7 +3620,7 @@ pick_next_task(struct rq *rq, struct tas
33113 asmlinkage void __sched schedule(void)
33115 struct task_struct *prev, *next;
33116 - long *switch_count;
33117 + unsigned long *switch_count;
33121 @@ -4155,7 +4156,8 @@ asmlinkage long sys_nice(int increment)
33125 - if (increment < 0 && !can_nice(current, nice))
33126 + if (increment < 0 && (!can_nice(current, nice) ||
33127 + gr_handle_chroot_nice()))
33128 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
33130 retval = security_task_setnice(current, nice);
33131 @@ -5396,7 +5398,7 @@ static struct ctl_table sd_ctl_dir[] = {
33132 .procname = "sched_domain",
33136 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
33139 static struct ctl_table sd_ctl_root[] = {
33140 @@ -5406,7 +5408,7 @@ static struct ctl_table sd_ctl_root[] =
33142 .child = sd_ctl_dir,
33145 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
33148 static struct ctl_table *sd_alloc_ctl_entry(int n)
33149 diff -urNp linux-2.6.24.4/kernel/signal.c linux-2.6.24.4/kernel/signal.c
33150 --- linux-2.6.24.4/kernel/signal.c 2008-03-24 14:49:18.000000000 -0400
33151 +++ linux-2.6.24.4/kernel/signal.c 2008-03-26 20:21:09.000000000 -0400
33153 #include <linux/capability.h>
33154 #include <linux/freezer.h>
33155 #include <linux/pid_namespace.h>
33156 +#include <linux/grsecurity.h>
33157 #include <linux/nsproxy.h>
33159 #include <asm/param.h>
33160 @@ -540,7 +541,9 @@ static int check_kill_permission(int sig
33161 && (current->euid ^ t->suid) && (current->euid ^ t->uid)
33162 && (current->uid ^ t->suid) && (current->uid ^ t->uid)
33163 && !capable(CAP_KILL))
33166 + if (gr_handle_signal(t, sig))
33170 return security_task_kill(t, info, sig, 0);
33171 @@ -757,7 +760,7 @@ static int __init setup_print_fatal_sign
33173 __setup("print-fatal-signals=", setup_print_fatal_signals);
33177 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
33180 @@ -811,8 +814,12 @@ force_sig_info(int sig, struct siginfo *
33183 ret = specific_send_sig_info(sig, info, t);
33185 spin_unlock_irqrestore(&t->sighand->siglock, flags);
33187 + gr_log_signal(sig, t);
33188 + gr_handle_crash(t, sig);
33193 diff -urNp linux-2.6.24.4/kernel/softirq.c linux-2.6.24.4/kernel/softirq.c
33194 --- linux-2.6.24.4/kernel/softirq.c 2008-03-24 14:49:18.000000000 -0400
33195 +++ linux-2.6.24.4/kernel/softirq.c 2008-03-26 20:21:09.000000000 -0400
33196 @@ -467,9 +467,9 @@ void tasklet_kill(struct tasklet_struct
33197 printk("Attempt to kill tasklet from interrupt\n");
33199 while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
33203 - while (test_bit(TASKLET_STATE_SCHED, &t->state));
33204 + } while (test_bit(TASKLET_STATE_SCHED, &t->state));
33206 tasklet_unlock_wait(t);
33207 clear_bit(TASKLET_STATE_SCHED, &t->state);
33208 diff -urNp linux-2.6.24.4/kernel/sys.c linux-2.6.24.4/kernel/sys.c
33209 --- linux-2.6.24.4/kernel/sys.c 2008-03-24 14:49:18.000000000 -0400
33210 +++ linux-2.6.24.4/kernel/sys.c 2008-03-26 20:21:09.000000000 -0400
33212 #include <linux/task_io_accounting_ops.h>
33213 #include <linux/seccomp.h>
33214 #include <linux/cpu.h>
33215 +#include <linux/grsecurity.h>
33217 #include <linux/compat.h>
33218 #include <linux/syscalls.h>
33219 @@ -119,6 +120,12 @@ static int set_one_prio(struct task_stru
33224 + if (gr_handle_chroot_setpriority(p, niceval)) {
33229 no_nice = security_task_setnice(p, niceval);
33232 @@ -175,10 +182,10 @@ asmlinkage long sys_setpriority(int whic
33233 if ((who != current->uid) && !(user = find_user(who)))
33234 goto out_unlock; /* No processes for this user */
33236 - do_each_thread(g, p)
33237 + do_each_thread(g, p) {
33239 error = set_one_prio(p, niceval, error);
33240 - while_each_thread(g, p);
33241 + } while_each_thread(g, p);
33242 if (who != current->uid)
33243 free_uid(user); /* For find_user() */
33245 @@ -237,13 +244,13 @@ asmlinkage long sys_getpriority(int whic
33246 if ((who != current->uid) && !(user = find_user(who)))
33247 goto out_unlock; /* No processes for this user */
33249 - do_each_thread(g, p)
33250 + do_each_thread(g, p) {
33251 if (p->uid == who) {
33252 niceval = 20 - task_nice(p);
33253 if (niceval > retval)
33256 - while_each_thread(g, p);
33257 + } while_each_thread(g, p);
33258 if (who != current->uid)
33259 free_uid(user); /* for find_user() */
33261 @@ -515,6 +522,9 @@ asmlinkage long sys_setregid(gid_t rgid,
33262 if (rgid != (gid_t) -1 ||
33263 (egid != (gid_t) -1 && egid != old_rgid))
33264 current->sgid = new_egid;
33266 + gr_set_role_label(current, current->uid, new_rgid);
33268 current->fsgid = new_egid;
33269 current->egid = new_egid;
33270 current->gid = new_rgid;
33271 @@ -542,6 +552,9 @@ asmlinkage long sys_setgid(gid_t gid)
33272 set_dumpable(current->mm, suid_dumpable);
33276 + gr_set_role_label(current, current->uid, gid);
33278 current->gid = current->egid = current->sgid = current->fsgid = gid;
33279 } else if ((gid == current->gid) || (gid == current->sgid)) {
33280 if (old_egid != gid) {
33281 @@ -579,6 +592,9 @@ static int set_user(uid_t new_ruid, int
33282 set_dumpable(current->mm, suid_dumpable);
33286 + gr_set_role_label(current, new_ruid, current->gid);
33288 current->uid = new_ruid;
33291 @@ -681,6 +697,9 @@ asmlinkage long sys_setuid(uid_t uid)
33292 } else if ((uid != current->uid) && (uid != new_suid))
33295 + if (gr_check_crash_uid(uid))
33298 if (old_euid != uid) {
33299 set_dumpable(current->mm, suid_dumpable);
33301 @@ -783,8 +802,10 @@ asmlinkage long sys_setresgid(gid_t rgid
33302 current->egid = egid;
33304 current->fsgid = current->egid;
33305 - if (rgid != (gid_t) -1)
33306 + if (rgid != (gid_t) -1) {
33307 + gr_set_role_label(current, current->uid, rgid);
33308 current->gid = rgid;
33310 if (sgid != (gid_t) -1)
33311 current->sgid = sgid;
33313 @@ -934,7 +955,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
33314 write_lock_irq(&tasklist_lock);
33317 - p = find_task_by_pid_ns(pid, ns);
33318 + /* grsec: replaced find_task_by_pid_ns with equivalent call which
33319 + lacks the chroot restriction
33321 + p = pid_task(find_pid_ns(pid, ns), PIDTYPE_PID);
33325 @@ -1662,7 +1686,7 @@ asmlinkage long sys_prctl(int option, un
33326 error = get_dumpable(current->mm);
33328 case PR_SET_DUMPABLE:
33329 - if (arg2 < 0 || arg2 > 1) {
33334 diff -urNp linux-2.6.24.4/kernel/sysctl.c linux-2.6.24.4/kernel/sysctl.c
33335 --- linux-2.6.24.4/kernel/sysctl.c 2008-03-24 14:49:18.000000000 -0400
33336 +++ linux-2.6.24.4/kernel/sysctl.c 2008-03-26 20:21:09.000000000 -0400
33338 static int deprecated_sysctl_warning(struct __sysctl_args *args);
33340 #if defined(CONFIG_SYSCTL)
33341 +#include <linux/grsecurity.h>
33342 +#include <linux/grinternal.h>
33344 +extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
33345 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
33347 +extern int gr_handle_chroot_sysctl(const int op);
33349 /* External variables not in a header file. */
33351 @@ -154,10 +161,11 @@ static int proc_do_cad_pid(struct ctl_ta
33352 static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
33353 void __user *buffer, size_t *lenp, loff_t *ppos);
33355 +extern ctl_table grsecurity_table[];
33357 static struct ctl_table root_table[];
33358 static struct ctl_table_header root_table_header =
33359 - { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
33360 + { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry), 0, NULL };
33362 static struct ctl_table kern_table[];
33363 static struct ctl_table vm_table[];
33364 @@ -173,6 +181,21 @@ extern struct ctl_table inotify_table[];
33365 int sysctl_legacy_va_layout;
33368 +#ifdef CONFIG_PAX_SOFTMODE
33369 +static ctl_table pax_table[] = {
33371 + .ctl_name = CTL_UNNUMBERED,
33372 + .procname = "softmode",
33373 + .data = &pax_softmode,
33374 + .maxlen = sizeof(unsigned int),
33376 + .proc_handler = &proc_dointvec,
33379 + { .ctl_name = 0 }
33383 extern int prove_locking;
33384 extern int lock_stat;
33386 @@ -217,6 +240,16 @@ static struct ctl_table root_table[] = {
33388 .child = dev_table,
33391 +#ifdef CONFIG_PAX_SOFTMODE
33393 + .ctl_name = CTL_UNNUMBERED,
33394 + .procname = "pax",
33396 + .child = pax_table,
33401 * NOTE: do not add new entries to this table unless you have read
33402 * Documentation/sysctl/ctl_unnumbered.txt
33403 @@ -775,6 +808,14 @@ static struct ctl_table kern_table[] = {
33404 .proc_handler = &proc_dostring,
33405 .strategy = &sysctl_string,
33407 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
33409 + .ctl_name = CTL_UNNUMBERED,
33410 + .procname = "grsecurity",
33412 + .child = grsecurity_table,
33416 * NOTE: do not add new entries to this table unless you have read
33417 * Documentation/sysctl/ctl_unnumbered.txt
33418 @@ -1394,6 +1435,25 @@ static int test_perm(int mode, int op)
33419 int sysctl_perm(struct ctl_table *table, int op)
33422 + if (table->parent != NULL && table->parent->procname != NULL &&
33423 + table->procname != NULL &&
33424 + gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
33426 + if (gr_handle_chroot_sysctl(op))
33428 + error = gr_handle_sysctl(table, op);
33431 + error = security_sysctl(table, op);
33434 + return test_perm(table->mode, op);
33437 +int sysctl_perm_nochk(ctl_table *table, int op)
33441 error = security_sysctl(table, op);
33444 @@ -1418,13 +1478,14 @@ repeat:
33445 if (n == table->ctl_name) {
33447 if (table->child) {
33448 - if (sysctl_perm(table, 001))
33449 + if (sysctl_perm_nochk(table, 001))
33453 table = table->child;
33457 error = do_sysctl_strategy(table, name, nlen,
33460 diff -urNp linux-2.6.24.4/kernel/time.c linux-2.6.24.4/kernel/time.c
33461 --- linux-2.6.24.4/kernel/time.c 2008-03-24 14:49:18.000000000 -0400
33462 +++ linux-2.6.24.4/kernel/time.c 2008-03-26 20:21:09.000000000 -0400
33464 #include <linux/syscalls.h>
33465 #include <linux/security.h>
33466 #include <linux/fs.h>
33467 +#include <linux/grsecurity.h>
33469 #include <asm/uaccess.h>
33470 #include <asm/unistd.h>
33471 @@ -88,6 +89,9 @@ asmlinkage long sys_stime(time_t __user
33474 vx_settimeofday(&tv);
33476 + gr_log_timechange();
33481 @@ -194,6 +198,8 @@ asmlinkage long sys_settimeofday(struct
33485 + gr_log_timechange();
33487 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
33490 @@ -232,7 +238,7 @@ EXPORT_SYMBOL(current_fs_time);
33491 * Avoid unnecessary multiplications/divisions in the
33492 * two most common HZ cases:
33494 -unsigned int inline jiffies_to_msecs(const unsigned long j)
33495 +inline unsigned int jiffies_to_msecs(const unsigned long j)
33497 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
33498 return (MSEC_PER_SEC / HZ) * j;
33499 @@ -244,7 +250,7 @@ unsigned int inline jiffies_to_msecs(con
33501 EXPORT_SYMBOL(jiffies_to_msecs);
33503 -unsigned int inline jiffies_to_usecs(const unsigned long j)
33504 +inline unsigned int jiffies_to_usecs(const unsigned long j)
33506 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
33507 return (USEC_PER_SEC / HZ) * j;
33508 diff -urNp linux-2.6.24.4/kernel/utsname_sysctl.c linux-2.6.24.4/kernel/utsname_sysctl.c
33509 --- linux-2.6.24.4/kernel/utsname_sysctl.c 2008-03-24 14:49:18.000000000 -0400
33510 +++ linux-2.6.24.4/kernel/utsname_sysctl.c 2008-03-26 20:21:09.000000000 -0400
33511 @@ -125,7 +125,7 @@ static struct ctl_table uts_kern_table[]
33512 .proc_handler = proc_do_uts_string,
33513 .strategy = sysctl_uts_string,
33516 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33519 static struct ctl_table uts_root_table[] = {
33520 @@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[]
33522 .child = uts_kern_table,
33525 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33528 static int __init utsname_sysctl_init(void)
33529 diff -urNp linux-2.6.24.4/lib/radix-tree.c linux-2.6.24.4/lib/radix-tree.c
33530 --- linux-2.6.24.4/lib/radix-tree.c 2008-03-24 14:49:18.000000000 -0400
33531 +++ linux-2.6.24.4/lib/radix-tree.c 2008-03-26 20:21:09.000000000 -0400
33532 @@ -81,7 +81,7 @@ struct radix_tree_preload {
33534 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
33536 -DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
33537 +DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} };
33539 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
33541 diff -urNp linux-2.6.24.4/localversion-grsec linux-2.6.24.4/localversion-grsec
33542 --- linux-2.6.24.4/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
33543 +++ linux-2.6.24.4/localversion-grsec 2008-03-26 20:21:09.000000000 -0400
33546 diff -urNp linux-2.6.24.4/Makefile linux-2.6.24.4/Makefile
33547 --- linux-2.6.24.4/Makefile 2008-03-24 14:49:18.000000000 -0400
33548 +++ linux-2.6.24.4/Makefile 2008-03-26 20:21:09.000000000 -0400
33549 @@ -214,7 +214,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
33553 -HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
33554 +HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
33557 # Decide whether to build built-in, modular, or both.
33558 @@ -507,6 +507,9 @@ else
33559 KBUILD_CFLAGS += -O2
33562 +# Force gcc to behave correct even for buggy distributions
33563 +KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
33565 include $(srctree)/arch/$(SRCARCH)/Makefile
33567 ifdef CONFIG_FRAME_POINTER
33568 @@ -520,9 +523,6 @@ KBUILD_CFLAGS += -g
33569 KBUILD_AFLAGS += -gdwarf-2
33572 -# Force gcc to behave correct even for buggy distributions
33573 -KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
33575 # arch Makefile may override CC so keep this after arch Makefile is included
33576 NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
33577 CHECKFLAGS += $(NOSTDINC_FLAGS)
33578 @@ -597,7 +597,7 @@ export mod_strip_cmd
33581 ifeq ($(KBUILD_EXTMOD),)
33582 -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
33583 +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
33585 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
33586 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
33587 diff -urNp linux-2.6.24.4/mm/filemap.c linux-2.6.24.4/mm/filemap.c
33588 --- linux-2.6.24.4/mm/filemap.c 2008-03-24 14:49:18.000000000 -0400
33589 +++ linux-2.6.24.4/mm/filemap.c 2008-03-26 20:21:09.000000000 -0400
33591 #include <linux/syscalls.h>
33592 #include <linux/cpuset.h>
33593 #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
33594 +#include <linux/grsecurity.h>
33595 #include "internal.h"
33598 @@ -1461,7 +1462,7 @@ int generic_file_mmap(struct file * file
33599 struct address_space *mapping = file->f_mapping;
33601 if (!mapping->a_ops->readpage)
33604 file_accessed(file);
33605 vma->vm_ops = &generic_file_vm_ops;
33606 vma->vm_flags |= VM_CAN_NONLINEAR;
33607 @@ -1810,6 +1811,7 @@ inline int generic_write_checks(struct f
33608 *pos = i_size_read(inode);
33610 if (limit != RLIM_INFINITY) {
33611 + gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
33612 if (*pos >= limit) {
33613 send_sig(SIGXFSZ, current, 0);
33615 diff -urNp linux-2.6.24.4/mm/fremap.c linux-2.6.24.4/mm/fremap.c
33616 --- linux-2.6.24.4/mm/fremap.c 2008-03-24 14:49:18.000000000 -0400
33617 +++ linux-2.6.24.4/mm/fremap.c 2008-03-26 20:21:09.000000000 -0400
33618 @@ -150,6 +150,13 @@ asmlinkage long sys_remap_file_pages(uns
33620 vma = find_vma(mm, start);
33622 +#ifdef CONFIG_PAX_SEGMEXEC
33623 + if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
33624 + up_read(&mm->mmap_sem);
33630 * Make sure the vma is shared, that it supports prefaulting,
33631 * and that the remapped range is valid and fully within
33632 diff -urNp linux-2.6.24.4/mm/hugetlb.c linux-2.6.24.4/mm/hugetlb.c
33633 --- linux-2.6.24.4/mm/hugetlb.c 2008-03-24 14:49:18.000000000 -0400
33634 +++ linux-2.6.24.4/mm/hugetlb.c 2008-03-26 20:21:09.000000000 -0400
33635 @@ -797,6 +797,26 @@ void unmap_hugepage_range(struct vm_area
33639 +#ifdef CONFIG_PAX_SEGMEXEC
33640 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
33642 + struct mm_struct *mm = vma->vm_mm;
33643 + struct vm_area_struct *vma_m;
33644 + unsigned long address_m;
33647 + vma_m = pax_find_mirror_vma(vma);
33651 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33652 + address_m = address + SEGMEXEC_TASK_SIZE;
33653 + ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
33654 + get_page(page_m);
33655 + set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
33659 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
33660 unsigned long address, pte_t *ptep, pte_t pte)
33662 @@ -830,6 +850,11 @@ static int hugetlb_cow(struct mm_struct
33664 set_huge_pte_at(mm, address, ptep,
33665 make_huge_pte(vma, new_page, 1));
33667 +#ifdef CONFIG_PAX_SEGMEXEC
33668 + pax_mirror_huge_pte(vma, address, new_page);
33671 /* Make the old page be freed below */
33672 new_page = old_page;
33674 @@ -901,6 +926,10 @@ retry:
33675 && (vma->vm_flags & VM_SHARED)));
33676 set_huge_pte_at(mm, address, ptep, new_pte);
33678 +#ifdef CONFIG_PAX_SEGMEXEC
33679 + pax_mirror_huge_pte(vma, address, page);
33682 if (write_access && !(vma->vm_flags & VM_SHARED)) {
33683 /* Optimization, do the COW without a second fault */
33684 ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
33685 @@ -926,6 +955,27 @@ int hugetlb_fault(struct mm_struct *mm,
33687 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
33689 +#ifdef CONFIG_PAX_SEGMEXEC
33690 + struct vm_area_struct *vma_m;
33692 + vma_m = pax_find_mirror_vma(vma);
33694 + unsigned long address_m;
33696 + if (vma->vm_start > vma_m->vm_start) {
33697 + address_m = address;
33698 + address -= SEGMEXEC_TASK_SIZE;
33701 + address_m = address + SEGMEXEC_TASK_SIZE;
33703 + if (!huge_pte_alloc(mm, address_m))
33704 + return VM_FAULT_OOM;
33705 + address_m &= HPAGE_MASK;
33706 + unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
33710 ptep = huge_pte_alloc(mm, address);
33712 return VM_FAULT_OOM;
33713 diff -urNp linux-2.6.24.4/mm/madvise.c linux-2.6.24.4/mm/madvise.c
33714 --- linux-2.6.24.4/mm/madvise.c 2008-03-24 14:49:18.000000000 -0400
33715 +++ linux-2.6.24.4/mm/madvise.c 2008-03-26 20:21:09.000000000 -0400
33716 @@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
33718 int new_flags = vma->vm_flags;
33720 +#ifdef CONFIG_PAX_SEGMEXEC
33721 + struct vm_area_struct *vma_m;
33724 switch (behavior) {
33726 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
33727 @@ -92,6 +96,13 @@ success:
33729 * vm_flags is protected by the mmap_sem held in write mode.
33732 +#ifdef CONFIG_PAX_SEGMEXEC
33733 + vma_m = pax_find_mirror_vma(vma);
33735 + vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
33738 vma->vm_flags = new_flags;
33741 @@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
33743 case MADV_DONTNEED:
33744 error = madvise_dontneed(vma, prev, start, end);
33746 +#ifdef CONFIG_PAX_SEGMEXEC
33748 + struct vm_area_struct *vma_m, *prev_m;
33750 + vma_m = pax_find_mirror_vma(vma);
33752 + error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
33759 @@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
33763 +#ifdef CONFIG_PAX_SEGMEXEC
33764 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
33765 + if (end > SEGMEXEC_TASK_SIZE)
33770 + if (end > TASK_SIZE)
33776 diff -urNp linux-2.6.24.4/mm/memory.c linux-2.6.24.4/mm/memory.c
33777 --- linux-2.6.24.4/mm/memory.c 2008-03-24 14:49:18.000000000 -0400
33778 +++ linux-2.6.24.4/mm/memory.c 2008-03-26 20:21:16.000000000 -0400
33780 #include <linux/delayacct.h>
33781 #include <linux/init.h>
33782 #include <linux/writeback.h>
33783 +#include <linux/grsecurity.h>
33785 #include <asm/pgalloc.h>
33786 #include <asm/uaccess.h>
33787 @@ -990,11 +991,11 @@ int get_user_pages(struct task_struct *t
33788 vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
33793 struct vm_area_struct *vma;
33794 unsigned int foll_flags;
33796 - vma = find_extend_vma(mm, start);
33797 + vma = find_vma(mm, start);
33798 if (!vma && in_gate_area(tsk, start)) {
33799 unsigned long pg = start & PAGE_MASK;
33800 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
33801 @@ -1034,7 +1035,7 @@ int get_user_pages(struct task_struct *t
33805 - if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
33806 + if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
33807 || !(vm_flags & vma->vm_flags))
33808 return i ? : -EFAULT;
33810 @@ -1107,7 +1108,7 @@ int get_user_pages(struct task_struct *t
33811 start += PAGE_SIZE;
33813 } while (len && start < vma->vm_end);
33818 EXPORT_SYMBOL(get_user_pages);
33819 @@ -1526,6 +1527,186 @@ static inline void cow_user_page(struct
33820 copy_user_highpage(dst, src, va, vma);
33823 +#ifdef CONFIG_PAX_SEGMEXEC
33824 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
33826 + struct mm_struct *mm = vma->vm_mm;
33828 + pte_t *pte, entry;
33830 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
33832 + if (!pte_present(entry)) {
33833 + if (!pte_none(entry)) {
33834 + BUG_ON(pte_file(entry));
33835 + free_swap_and_cache(pte_to_swp_entry(entry));
33836 + pte_clear_not_present_full(mm, address, pte, 0);
33839 + struct page *page;
33841 + flush_cache_page(vma, address, pte_pfn(entry));
33842 + entry = ptep_clear_flush(vma, address, pte);
33843 + BUG_ON(pte_dirty(entry));
33844 + page = vm_normal_page(vma, address, entry);
33846 + update_hiwater_rss(mm);
33847 + if (PageAnon(page))
33848 + dec_mm_counter(mm, anon_rss);
33850 + dec_mm_counter(mm, file_rss);
33851 + page_remove_rmap(page, vma);
33852 + page_cache_release(page);
33855 + pte_unmap_unlock(pte, ptl);
33858 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
33860 + * the ptl of the lower mapped page is held on entry and is not released on exit
33861 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
33863 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33865 + struct mm_struct *mm = vma->vm_mm;
33866 + unsigned long address_m;
33867 + spinlock_t *ptl_m;
33868 + struct vm_area_struct *vma_m;
33870 + pte_t *pte_m, entry_m;
33872 + BUG_ON(!page_m || !PageAnon(page_m));
33874 + vma_m = pax_find_mirror_vma(vma);
33878 + BUG_ON(!PageLocked(page_m));
33879 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33880 + address_m = address + SEGMEXEC_TASK_SIZE;
33881 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33882 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33883 + ptl_m = pte_lockptr(mm, pmd_m);
33884 + if (ptl != ptl_m) {
33885 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33886 + if (!pte_none(*pte_m))
33890 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33891 + page_cache_get(page_m);
33892 + page_add_anon_rmap(page_m, vma_m, address_m);
33893 + inc_mm_counter(mm, anon_rss);
33894 + set_pte_at(mm, address_m, pte_m, entry_m);
33895 + update_mmu_cache(vma_m, address_m, entry_m);
33897 + if (ptl != ptl_m)
33898 + spin_unlock(ptl_m);
33899 + pte_unmap_nested(pte_m);
33900 + unlock_page(page_m);
33903 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33905 + struct mm_struct *mm = vma->vm_mm;
33906 + unsigned long address_m;
33907 + spinlock_t *ptl_m;
33908 + struct vm_area_struct *vma_m;
33910 + pte_t *pte_m, entry_m;
33912 + BUG_ON(!page_m || PageAnon(page_m));
33914 + vma_m = pax_find_mirror_vma(vma);
33918 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33919 + address_m = address + SEGMEXEC_TASK_SIZE;
33920 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33921 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33922 + ptl_m = pte_lockptr(mm, pmd_m);
33923 + if (ptl != ptl_m) {
33924 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33925 + if (!pte_none(*pte_m))
33929 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33930 + page_cache_get(page_m);
33931 + page_add_file_rmap(page_m);
33932 + inc_mm_counter(mm, file_rss);
33933 + set_pte_at(mm, address_m, pte_m, entry_m);
33934 + update_mmu_cache(vma_m, address_m, entry_m);
33936 + if (ptl != ptl_m)
33937 + spin_unlock(ptl_m);
33938 + pte_unmap_nested(pte_m);
33941 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
33943 + struct mm_struct *mm = vma->vm_mm;
33944 + unsigned long address_m;
33945 + spinlock_t *ptl_m;
33946 + struct vm_area_struct *vma_m;
33948 + pte_t *pte_m, entry_m;
33950 + vma_m = pax_find_mirror_vma(vma);
33954 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33955 + address_m = address + SEGMEXEC_TASK_SIZE;
33956 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33957 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33958 + ptl_m = pte_lockptr(mm, pmd_m);
33959 + if (ptl != ptl_m) {
33960 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33961 + if (!pte_none(*pte_m))
33965 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
33966 + set_pte_at(mm, address_m, pte_m, entry_m);
33968 + if (ptl != ptl_m)
33969 + spin_unlock(ptl_m);
33970 + pte_unmap_nested(pte_m);
33973 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
33975 + struct page *page_m;
33978 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
33982 + page_m = vm_normal_page(vma, address, entry);
33984 + pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
33985 + else if (PageAnon(page_m)) {
33986 + if (pax_find_mirror_vma(vma)) {
33987 + pte_unmap_unlock(pte, ptl);
33988 + lock_page(page_m);
33989 + pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
33990 + if (pte_same(entry, *pte))
33991 + pax_mirror_anon_pte(vma, address, page_m, ptl);
33993 + unlock_page(page_m);
33996 + pax_mirror_file_pte(vma, address, page_m, ptl);
33999 + pte_unmap_unlock(pte, ptl);
34004 * This routine handles present pages, when users try to write
34005 * to a shared page. It is done by copying the page to a new address
34006 @@ -1638,6 +1819,12 @@ gotten:
34008 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
34009 if (likely(pte_same(*page_table, orig_pte))) {
34011 +#ifdef CONFIG_PAX_SEGMEXEC
34012 + if (pax_find_mirror_vma(vma))
34013 + BUG_ON(TestSetPageLocked(new_page));
34017 page_remove_rmap(old_page, vma);
34018 if (!PageAnon(old_page)) {
34019 @@ -1661,6 +1848,10 @@ gotten:
34020 lru_cache_add_active(new_page);
34021 page_add_new_anon_rmap(new_page, vma, address);
34023 +#ifdef CONFIG_PAX_SEGMEXEC
34024 + pax_mirror_anon_pte(vma, address, new_page, ptl);
34027 /* Free the old page.. */
34028 new_page = old_page;
34029 ret |= VM_FAULT_WRITE;
34030 @@ -1941,6 +2132,7 @@ int vmtruncate(struct inode * inode, lof
34033 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
34034 + gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
34035 if (limit != RLIM_INFINITY && offset > limit)
34037 if (offset > inode->i_sb->s_maxbytes)
34038 @@ -2123,6 +2315,11 @@ static int do_swap_page(struct mm_struct
34040 if (vm_swap_full())
34041 remove_exclusive_swap_page(page);
34043 +#ifdef CONFIG_PAX_SEGMEXEC
34044 + if (write_access || !pax_find_mirror_vma(vma))
34049 if (write_access) {
34050 @@ -2135,6 +2332,11 @@ static int do_swap_page(struct mm_struct
34052 /* No need to invalidate - it was non-present before */
34053 update_mmu_cache(vma, address, pte);
34055 +#ifdef CONFIG_PAX_SEGMEXEC
34056 + pax_mirror_anon_pte(vma, address, page, ptl);
34060 pte_unmap_unlock(page_table, ptl);
34062 @@ -2174,6 +2376,12 @@ static int do_anonymous_page(struct mm_s
34063 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
34064 if (!pte_none(*page_table))
34067 +#ifdef CONFIG_PAX_SEGMEXEC
34068 + if (pax_find_mirror_vma(vma))
34069 + BUG_ON(TestSetPageLocked(page));
34072 inc_mm_counter(mm, anon_rss);
34073 lru_cache_add_active(page);
34074 page_add_new_anon_rmap(page, vma, address);
34075 @@ -2181,6 +2389,11 @@ static int do_anonymous_page(struct mm_s
34077 /* No need to invalidate - it was non-present before */
34078 update_mmu_cache(vma, address, entry);
34080 +#ifdef CONFIG_PAX_SEGMEXEC
34081 + pax_mirror_anon_pte(vma, address, page, ptl);
34085 pte_unmap_unlock(page_table, ptl);
34087 @@ -2313,6 +2526,12 @@ static int __do_fault(struct mm_struct *
34089 /* Only go through if we didn't race with anybody else... */
34090 if (likely(pte_same(*page_table, orig_pte))) {
34092 +#ifdef CONFIG_PAX_SEGMEXEC
34093 + if (anon && pax_find_mirror_vma(vma))
34094 + BUG_ON(TestSetPageLocked(page));
34097 flush_icache_page(vma, page);
34098 entry = mk_pte(page, vma->vm_page_prot);
34099 if (flags & FAULT_FLAG_WRITE)
34100 @@ -2333,6 +2552,14 @@ static int __do_fault(struct mm_struct *
34102 /* no need to invalidate: a not-present page won't be cached */
34103 update_mmu_cache(vma, address, entry);
34105 +#ifdef CONFIG_PAX_SEGMEXEC
34107 + pax_mirror_anon_pte(vma, address, page, ptl);
34109 + pax_mirror_file_pte(vma, address, page, ptl);
34114 page_cache_release(page);
34115 @@ -2415,6 +2642,11 @@ static noinline int do_no_pfn(struct mm_
34117 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
34118 set_pte_at(mm, address, page_table, entry);
34120 +#ifdef CONFIG_PAX_SEGMEXEC
34121 + pax_mirror_pfn_pte(vma, address, pfn, ptl);
34125 pte_unmap_unlock(page_table, ptl);
34127 @@ -2517,6 +2749,12 @@ static inline int handle_pte_fault(struc
34129 flush_tlb_page(vma, address);
34132 +#ifdef CONFIG_PAX_SEGMEXEC
34133 + pax_mirror_pte(vma, address, pte, pmd, ptl);
34138 pte_unmap_unlock(pte, ptl);
34140 @@ -2533,6 +2771,10 @@ int handle_mm_fault(struct mm_struct *mm
34144 +#ifdef CONFIG_PAX_SEGMEXEC
34145 + struct vm_area_struct *vma_m;
34148 __set_current_state(TASK_RUNNING);
34150 count_vm_event(PGFAULT);
34151 @@ -2540,6 +2782,34 @@ int handle_mm_fault(struct mm_struct *mm
34152 if (unlikely(is_vm_hugetlb_page(vma)))
34153 return hugetlb_fault(mm, vma, address, write_access);
34155 +#ifdef CONFIG_PAX_SEGMEXEC
34156 + vma_m = pax_find_mirror_vma(vma);
34158 + unsigned long address_m;
34163 + if (vma->vm_start > vma_m->vm_start) {
34164 + address_m = address;
34165 + address -= SEGMEXEC_TASK_SIZE;
34168 + address_m = address + SEGMEXEC_TASK_SIZE;
34170 + pgd_m = pgd_offset(mm, address_m);
34171 + pud_m = pud_alloc(mm, pgd_m, address_m);
34173 + return VM_FAULT_OOM;
34174 + pmd_m = pmd_alloc(mm, pud_m, address_m);
34176 + return VM_FAULT_OOM;
34177 + if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
34178 + return VM_FAULT_OOM;
34179 + pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
34183 pgd = pgd_offset(mm, address);
34184 pud = pud_alloc(mm, pgd, address);
34186 @@ -2673,7 +2943,7 @@ static int __init gate_vma_init(void)
34187 gate_vma.vm_start = FIXADDR_USER_START;
34188 gate_vma.vm_end = FIXADDR_USER_END;
34189 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
34190 - gate_vma.vm_page_prot = __P101;
34191 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
34193 * Make sure the vDSO gets into every core dump.
34194 * Dumping its contents makes post-mortem fully interpretable later
34195 diff -urNp linux-2.6.24.4/mm/mempolicy.c linux-2.6.24.4/mm/mempolicy.c
34196 --- linux-2.6.24.4/mm/mempolicy.c 2008-03-24 14:49:18.000000000 -0400
34197 +++ linux-2.6.24.4/mm/mempolicy.c 2008-03-26 20:21:09.000000000 -0400
34198 @@ -406,6 +406,10 @@ static int mbind_range(struct vm_area_st
34199 struct vm_area_struct *next;
34202 +#ifdef CONFIG_PAX_SEGMEXEC
34203 + struct vm_area_struct *vma_m;
34207 for (; vma && vma->vm_start < end; vma = next) {
34208 next = vma->vm_next;
34209 @@ -417,6 +421,16 @@ static int mbind_range(struct vm_area_st
34210 err = policy_vma(vma, new);
34214 +#ifdef CONFIG_PAX_SEGMEXEC
34215 + vma_m = pax_find_mirror_vma(vma);
34217 + err = policy_vma(vma_m, new);
34226 @@ -794,6 +808,17 @@ static long do_mbind(unsigned long start
34231 +#ifdef CONFIG_PAX_SEGMEXEC
34232 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
34233 + if (end > SEGMEXEC_TASK_SIZE)
34238 + if (end > TASK_SIZE)
34244 diff -urNp linux-2.6.24.4/mm/mlock.c linux-2.6.24.4/mm/mlock.c
34245 --- linux-2.6.24.4/mm/mlock.c 2008-03-24 14:49:18.000000000 -0400
34246 +++ linux-2.6.24.4/mm/mlock.c 2008-03-26 20:21:09.000000000 -0400
34248 #include <linux/sched.h>
34249 #include <linux/module.h>
34250 #include <linux/vs_memory.h>
34251 +#include <linux/grsecurity.h>
34253 int can_do_mlock(void)
34255 @@ -95,6 +96,17 @@ static int do_mlock(unsigned long start,
34260 +#ifdef CONFIG_PAX_SEGMEXEC
34261 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
34262 + if (end > SEGMEXEC_TASK_SIZE)
34267 + if (end > TASK_SIZE)
34270 vma = find_vma_prev(current->mm, start, &prev);
34271 if (!vma || vma->vm_start > start)
34273 @@ -152,6 +164,7 @@ asmlinkage long sys_mlock(unsigned long
34274 lock_limit >>= PAGE_SHIFT;
34276 /* check against resource limits */
34277 + gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
34278 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
34279 error = do_mlock(start, len, 1);
34281 @@ -173,10 +186,10 @@ asmlinkage long sys_munlock(unsigned lon
34282 static int do_mlockall(int flags)
34284 struct vm_area_struct * vma, * prev = NULL;
34285 - unsigned int def_flags = 0;
34286 + unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
34288 if (flags & MCL_FUTURE)
34289 - def_flags = VM_LOCKED;
34290 + def_flags |= VM_LOCKED;
34291 current->mm->def_flags = def_flags;
34292 if (flags == MCL_FUTURE)
34294 @@ -184,6 +197,12 @@ static int do_mlockall(int flags)
34295 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
34296 unsigned int newflags;
34298 +#ifdef CONFIG_PAX_SEGMEXEC
34299 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
34303 + BUG_ON(vma->vm_end > TASK_SIZE);
34304 newflags = vma->vm_flags | VM_LOCKED;
34305 if (!(flags & MCL_CURRENT))
34306 newflags &= ~VM_LOCKED;
34307 @@ -213,6 +232,7 @@ asmlinkage long sys_mlockall(int flags)
34308 lock_limit >>= PAGE_SHIFT;
34311 + gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
34312 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
34314 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
34315 diff -urNp linux-2.6.24.4/mm/mmap.c linux-2.6.24.4/mm/mmap.c
34316 --- linux-2.6.24.4/mm/mmap.c 2008-03-24 14:49:18.000000000 -0400
34317 +++ linux-2.6.24.4/mm/mmap.c 2008-03-26 20:21:09.000000000 -0400
34319 #include <linux/mount.h>
34320 #include <linux/mempolicy.h>
34321 #include <linux/rmap.h>
34322 +#include <linux/grsecurity.h>
34324 #include <asm/uaccess.h>
34325 #include <asm/cacheflush.h>
34327 #define arch_mmap_check(addr, len, flags) (0)
34330 +static inline void verify_mm_writelocked(struct mm_struct *mm)
34332 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
34333 + if (unlikely(down_read_trylock(&mm->mmap_sem))) {
34334 + up_read(&mm->mmap_sem);
34340 static void unmap_region(struct mm_struct *mm,
34341 struct vm_area_struct *vma, struct vm_area_struct *prev,
34342 unsigned long start, unsigned long end);
34343 @@ -61,15 +72,23 @@ static void unmap_region(struct mm_struc
34344 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
34347 -pgprot_t protection_map[16] = {
34348 +pgprot_t protection_map[16] __read_only = {
34349 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
34350 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
34353 pgprot_t vm_get_page_prot(unsigned long vm_flags)
34355 - return protection_map[vm_flags &
34356 - (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
34357 + pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
34359 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34360 + if (!nx_enabled &&
34361 + (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
34362 + (vm_flags & (VM_READ | VM_WRITE)))
34363 + prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
34368 EXPORT_SYMBOL(vm_get_page_prot);
34370 @@ -224,6 +243,7 @@ static struct vm_area_struct *remove_vma
34371 struct vm_area_struct *next = vma->vm_next;
34374 + BUG_ON(vma->vm_mirror);
34375 if (vma->vm_ops && vma->vm_ops->close)
34376 vma->vm_ops->close(vma);
34378 @@ -251,6 +271,7 @@ asmlinkage unsigned long sys_brk(unsigne
34379 * not page aligned -Ram Gupta
34381 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
34382 + gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
34383 if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
34386 @@ -351,8 +372,12 @@ find_vma_prepare(struct mm_struct *mm, u
34388 if (vma_tmp->vm_end > addr) {
34390 - if (vma_tmp->vm_start <= addr)
34392 + if (vma_tmp->vm_start <= addr) {
34393 +//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
34394 +//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
34395 +//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
34398 __rb_link = &__rb_parent->rb_left;
34400 rb_prev = __rb_parent;
34401 @@ -676,6 +701,12 @@ static int
34402 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
34403 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34406 +#ifdef CONFIG_PAX_SEGMEXEC
34407 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
34411 if (is_mergeable_vma(vma, file, vm_flags) &&
34412 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34413 if (vma->vm_pgoff == vm_pgoff)
34414 @@ -695,6 +726,12 @@ static int
34415 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
34416 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34419 +#ifdef CONFIG_PAX_SEGMEXEC
34420 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
34424 if (is_mergeable_vma(vma, file, vm_flags) &&
34425 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34427 @@ -737,12 +774,19 @@ can_vma_merge_after(struct vm_area_struc
34428 struct vm_area_struct *vma_merge(struct mm_struct *mm,
34429 struct vm_area_struct *prev, unsigned long addr,
34430 unsigned long end, unsigned long vm_flags,
34431 - struct anon_vma *anon_vma, struct file *file,
34432 + struct anon_vma *anon_vma, struct file *file,
34433 pgoff_t pgoff, struct mempolicy *policy)
34435 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
34436 struct vm_area_struct *area, *next;
34438 +#ifdef CONFIG_PAX_SEGMEXEC
34439 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
34440 + struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
34442 + BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
34446 * We later require that vma->vm_flags == vm_flags,
34447 * so this tests vma->vm_flags & VM_SPECIAL, too.
34448 @@ -758,6 +802,15 @@ struct vm_area_struct *vma_merge(struct
34449 if (next && next->vm_end == end) /* cases 6, 7, 8 */
34450 next = next->vm_next;
34452 +#ifdef CONFIG_PAX_SEGMEXEC
34454 + prev_m = pax_find_mirror_vma(prev);
34456 + area_m = pax_find_mirror_vma(area);
34458 + next_m = pax_find_mirror_vma(next);
34462 * Can it merge with the predecessor?
34464 @@ -777,9 +830,24 @@ struct vm_area_struct *vma_merge(struct
34466 vma_adjust(prev, prev->vm_start,
34467 next->vm_end, prev->vm_pgoff, NULL);
34468 - } else /* cases 2, 5, 7 */
34470 +#ifdef CONFIG_PAX_SEGMEXEC
34472 + vma_adjust(prev_m, prev_m->vm_start,
34473 + next_m->vm_end, prev_m->vm_pgoff, NULL);
34476 + } else { /* cases 2, 5, 7 */
34477 vma_adjust(prev, prev->vm_start,
34478 end, prev->vm_pgoff, NULL);
34480 +#ifdef CONFIG_PAX_SEGMEXEC
34482 + vma_adjust(prev_m, prev_m->vm_start,
34483 + end_m, prev_m->vm_pgoff, NULL);
34490 @@ -790,12 +858,43 @@ struct vm_area_struct *vma_merge(struct
34491 mpol_equal(policy, vma_policy(next)) &&
34492 can_vma_merge_before(next, vm_flags,
34493 anon_vma, file, pgoff+pglen)) {
34494 - if (prev && addr < prev->vm_end) /* case 4 */
34495 + if (prev && addr < prev->vm_end) { /* case 4 */
34496 vma_adjust(prev, prev->vm_start,
34497 addr, prev->vm_pgoff, NULL);
34498 - else /* cases 3, 8 */
34500 +#ifdef CONFIG_PAX_SEGMEXEC
34502 + vma_adjust(prev_m, prev_m->vm_start,
34503 + addr_m, prev_m->vm_pgoff, NULL);
34506 + } else { /* cases 3, 8 */
34507 vma_adjust(area, addr, next->vm_end,
34508 next->vm_pgoff - pglen, NULL);
34510 +#ifdef CONFIG_PAX_SEGMEXEC
34512 + vma_adjust(area_m, addr_m, next_m->vm_end,
34513 + next_m->vm_pgoff - pglen, NULL);
34514 + else if (next_m) {
34515 + vma_adjust(next_m, addr_m, next_m->vm_end,
34516 + next_m->vm_pgoff - pglen, NULL);
34517 + BUG_ON(area == next);
34518 + BUG_ON(area->vm_mirror);
34519 + BUG_ON(next_m->anon_vma && next_m->anon_vma != area->anon_vma);
34520 + BUG_ON(area->vm_file != next_m->vm_file);
34521 + BUG_ON(area->vm_end - area->vm_start != next_m->vm_end - next_m->vm_start);
34522 + BUG_ON(area->vm_pgoff != next_m->vm_pgoff);
34523 + area->vm_mirror = next_m;
34524 + next_m->vm_mirror = area;
34525 + if (area->anon_vma && !next_m->anon_vma) {
34526 + next_m->anon_vma = area->anon_vma;
34527 + anon_vma_link(next_m);
34536 @@ -870,14 +969,11 @@ none:
34537 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
34538 struct file *file, long pages)
34540 - const unsigned long stack_flags
34541 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
34544 mm->shared_vm += pages;
34545 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
34546 mm->exec_vm += pages;
34547 - } else if (flags & stack_flags)
34548 + } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
34549 mm->stack_vm += pages;
34550 if (flags & (VM_RESERVED|VM_IO))
34551 mm->reserved_vm += pages;
34552 @@ -905,7 +1001,7 @@ unsigned long do_mmap_pgoff(struct file
34553 * (the exception is when the underlying filesystem is noexec
34554 * mounted, in which case we dont add PROT_EXEC.)
34556 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
34557 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
34558 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
34561 @@ -915,15 +1011,15 @@ unsigned long do_mmap_pgoff(struct file
34562 if (!(flags & MAP_FIXED))
34563 addr = round_hint_to_min(addr);
34565 - error = arch_mmap_check(addr, len, flags);
34569 /* Careful about overflows.. */
34570 len = PAGE_ALIGN(len);
34571 if (!len || len > TASK_SIZE)
34574 + error = arch_mmap_check(addr, len, flags);
34578 /* offset overflow? */
34579 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
34581 @@ -935,7 +1031,7 @@ unsigned long do_mmap_pgoff(struct file
34582 /* Obtain the address to map to. we verify (or select) it and ensure
34583 * that it represents a valid section of the address space.
34585 - addr = get_unmapped_area(file, addr, len, pgoff, flags);
34586 + addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
34587 if (addr & ~PAGE_MASK)
34590 @@ -946,6 +1042,26 @@ unsigned long do_mmap_pgoff(struct file
34591 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
34592 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
34594 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
34595 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
34597 +#ifdef CONFIG_PAX_MPROTECT
34598 + if (mm->pax_flags & MF_PAX_MPROTECT) {
34599 + if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
34600 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
34602 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
34609 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34610 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
34611 + vm_flags &= ~VM_PAGEEXEC;
34614 if (flags & MAP_LOCKED) {
34615 if (!can_do_mlock())
34617 @@ -958,6 +1074,7 @@ unsigned long do_mmap_pgoff(struct file
34618 locked += mm->locked_vm;
34619 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
34620 lock_limit >>= PAGE_SHIFT;
34621 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34622 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
34625 @@ -1026,6 +1143,9 @@ unsigned long do_mmap_pgoff(struct file
34629 + if (!gr_acl_handle_mmap(file, prot))
34632 return mmap_region(file, addr, len, flags, vm_flags, pgoff,
34635 @@ -1039,10 +1159,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
34637 int vma_wants_writenotify(struct vm_area_struct *vma)
34639 - unsigned int vm_flags = vma->vm_flags;
34640 + unsigned long vm_flags = vma->vm_flags;
34642 /* If it was private or non-writable, the write bit is already clear */
34643 - if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
34644 + if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
34647 /* The backer wishes to know when pages are first written to? */
34648 @@ -1077,14 +1197,24 @@ unsigned long mmap_region(struct file *f
34649 unsigned long charged = 0;
34650 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
34652 +#ifdef CONFIG_PAX_SEGMEXEC
34653 + struct vm_area_struct *vma_m = NULL;
34657 + * mm->mmap_sem is required to protect against another thread
34658 + * changing the mappings in case we sleep.
34660 + verify_mm_writelocked(mm);
34662 /* Clear old maps */
34665 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34666 if (vma && vma->vm_start < addr + len) {
34667 if (do_munmap(mm, addr, len))
34669 - goto munmap_back;
34670 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34671 + BUG_ON(vma && vma->vm_start < addr + len);
34674 /* Check against address space limit. */
34675 @@ -1128,6 +1258,16 @@ munmap_back:
34679 +#ifdef CONFIG_PAX_SEGMEXEC
34680 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
34681 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34690 vma->vm_start = addr;
34691 vma->vm_end = addr + len;
34692 @@ -1150,6 +1290,27 @@ munmap_back:
34693 error = file->f_op->mmap(file, vma);
34695 goto unmap_and_free_vma;
34697 +#ifdef CONFIG_PAX_SEGMEXEC
34699 + struct mempolicy *pol;
34701 + pol = mpol_copy(vma_policy(vma));
34702 + if (IS_ERR(pol)) {
34703 + mpol_free(vma_policy(vma));
34704 + goto unmap_and_free_vma;
34706 + vma_set_policy(vma_m, pol);
34710 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34711 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
34712 + vma->vm_flags |= VM_PAGEEXEC;
34713 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
34717 } else if (vm_flags & VM_SHARED) {
34718 error = shmem_zero_setup(vma);
34720 @@ -1180,6 +1341,12 @@ munmap_back:
34721 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
34722 file = vma->vm_file;
34723 vma_link(mm, vma, prev, rb_link, rb_parent);
34725 +#ifdef CONFIG_PAX_SEGMEXEC
34727 + pax_mirror_vma(vma_m, vma);
34730 if (correct_wcount)
34731 atomic_inc(&inode->i_writecount);
34733 @@ -1190,10 +1357,20 @@ munmap_back:
34735 mpol_free(vma_policy(vma));
34736 kmem_cache_free(vm_area_cachep, vma);
34739 +#ifdef CONFIG_PAX_SEGMEXEC
34741 + mpol_free(vma_policy(vma_m));
34742 + kmem_cache_free(vm_area_cachep, vma_m);
34748 vx_vmpages_add(mm, len >> PAGE_SHIFT);
34749 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
34750 + track_exec_limit(mm, addr, addr + len, vm_flags);
34751 if (vm_flags & VM_LOCKED) {
34752 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
34753 make_pages_present(addr, addr + len);
34754 @@ -1212,6 +1389,12 @@ unmap_and_free_vma:
34755 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
34759 +#ifdef CONFIG_PAX_SEGMEXEC
34761 + kmem_cache_free(vm_area_cachep, vma_m);
34764 kmem_cache_free(vm_area_cachep, vma);
34767 @@ -1245,6 +1428,10 @@ arch_get_unmapped_area(struct file *filp
34768 if (flags & MAP_FIXED)
34771 +#ifdef CONFIG_PAX_RANDMMAP
34772 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34776 addr = PAGE_ALIGN(addr);
34777 vma = find_vma(mm, addr);
34778 @@ -1253,10 +1440,10 @@ arch_get_unmapped_area(struct file *filp
34781 if (len > mm->cached_hole_size) {
34782 - start_addr = addr = mm->free_area_cache;
34783 + start_addr = addr = mm->free_area_cache;
34785 - start_addr = addr = TASK_UNMAPPED_BASE;
34786 - mm->cached_hole_size = 0;
34787 + start_addr = addr = mm->mmap_base;
34788 + mm->cached_hole_size = 0;
34792 @@ -1267,9 +1454,8 @@ full_search:
34793 * Start a new search - just in case we missed
34796 - if (start_addr != TASK_UNMAPPED_BASE) {
34797 - addr = TASK_UNMAPPED_BASE;
34798 - start_addr = addr;
34799 + if (start_addr != mm->mmap_base) {
34800 + start_addr = addr = mm->mmap_base;
34801 mm->cached_hole_size = 0;
34804 @@ -1291,10 +1477,16 @@ full_search:
34806 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
34809 +#ifdef CONFIG_PAX_SEGMEXEC
34810 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34815 * Is this a new hole at the lowest possible address?
34817 - if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
34818 + if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
34819 mm->free_area_cache = addr;
34820 mm->cached_hole_size = ~0UL;
34822 @@ -1312,7 +1504,7 @@ arch_get_unmapped_area_topdown(struct fi
34824 struct vm_area_struct *vma;
34825 struct mm_struct *mm = current->mm;
34826 - unsigned long addr = addr0;
34827 + unsigned long base = mm->mmap_base, addr = addr0;
34829 /* requested length too big for entire address space */
34830 if (len > TASK_SIZE)
34831 @@ -1321,6 +1513,10 @@ arch_get_unmapped_area_topdown(struct fi
34832 if (flags & MAP_FIXED)
34835 +#ifdef CONFIG_PAX_RANDMMAP
34836 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34839 /* requesting a specific address */
34841 addr = PAGE_ALIGN(addr);
34842 @@ -1378,13 +1574,21 @@ bottomup:
34843 * can happen with large stack limits and large mmap()
34846 + mm->mmap_base = TASK_UNMAPPED_BASE;
34848 +#ifdef CONFIG_PAX_RANDMMAP
34849 + if (mm->pax_flags & MF_PAX_RANDMMAP)
34850 + mm->mmap_base += mm->delta_mmap;
34853 + mm->free_area_cache = mm->mmap_base;
34854 mm->cached_hole_size = ~0UL;
34855 - mm->free_area_cache = TASK_UNMAPPED_BASE;
34856 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
34858 * Restore the topdown base:
34860 - mm->free_area_cache = mm->mmap_base;
34861 + mm->mmap_base = base;
34862 + mm->free_area_cache = base;
34863 mm->cached_hole_size = ~0UL;
34866 @@ -1393,6 +1597,12 @@ bottomup:
34868 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
34871 +#ifdef CONFIG_PAX_SEGMEXEC
34872 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34877 * Is this a new hole at the highest possible address?
34879 @@ -1400,8 +1610,10 @@ void arch_unmap_area_topdown(struct mm_s
34880 mm->free_area_cache = addr;
34882 /* dont allow allocations above current base */
34883 - if (mm->free_area_cache > mm->mmap_base)
34884 + if (mm->free_area_cache > mm->mmap_base) {
34885 mm->free_area_cache = mm->mmap_base;
34886 + mm->cached_hole_size = ~0UL;
34891 @@ -1501,6 +1713,33 @@ out:
34892 return prev ? prev->vm_next : vma;
34895 +#ifdef CONFIG_PAX_SEGMEXEC
34896 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
34898 + struct vm_area_struct *vma_m;
34900 + BUG_ON(!vma || vma->vm_start >= vma->vm_end);
34901 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
34902 + BUG_ON(vma->vm_mirror);
34905 + BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
34906 + vma_m = vma->vm_mirror;
34907 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
34908 + BUG_ON(vma->vm_file != vma_m->vm_file);
34909 + BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
34910 + BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
34912 +#ifdef CONFIG_PAX_MPROTECT
34913 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
34915 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
34923 * Verify that the stack growth is acceptable and
34924 * update accounting. This is shared with both the
34925 @@ -1517,6 +1756,7 @@ static int acct_stack_growth(struct vm_a
34928 /* Stack limit test */
34929 + gr_learn_resource(current, RLIMIT_STACK, size, 1);
34930 if (size > rlim[RLIMIT_STACK].rlim_cur)
34933 @@ -1526,6 +1766,7 @@ static int acct_stack_growth(struct vm_a
34934 unsigned long limit;
34935 locked = mm->locked_vm + grow;
34936 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
34937 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34938 if (locked > limit && !capable(CAP_IPC_LOCK))
34941 @@ -1540,7 +1781,7 @@ static int acct_stack_growth(struct vm_a
34942 * Overcommit.. This must be the final test, as it will
34943 * update security statistics.
34945 - if (security_vm_enough_memory(grow))
34946 + if (security_vm_enough_memory_mm(mm, grow))
34949 /* Ok, everything looks good - let it rip */
34950 @@ -1561,35 +1802,40 @@ static inline
34952 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
34955 + int error, locknext;
34957 if (!(vma->vm_flags & VM_GROWSUP))
34960 + /* Also guard against wrapping around to address 0. */
34961 + if (address < PAGE_ALIGN(address+1))
34962 + address = PAGE_ALIGN(address+1);
34967 * We must make sure the anon_vma is allocated
34968 * so that the anon_vma locking is not a noop.
34970 if (unlikely(anon_vma_prepare(vma)))
34972 + locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
34973 + if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
34975 anon_vma_lock(vma);
34977 + anon_vma_lock(vma->vm_next);
34980 * vma->vm_start/vm_end cannot change under us because the caller
34981 * is required to hold the mmap_sem in read mode. We need the
34982 - * anon_vma lock to serialize against concurrent expand_stacks.
34983 - * Also guard against wrapping around to address 0.
34984 + * anon_vma locks to serialize against concurrent expand_stacks
34985 + * and expand_upwards.
34987 - if (address < PAGE_ALIGN(address+4))
34988 - address = PAGE_ALIGN(address+4);
34990 - anon_vma_unlock(vma);
34995 /* Somebody else might have raced and expanded it already */
34996 - if (address > vma->vm_end) {
34997 + if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
34998 unsigned long size, grow;
35000 size = address - vma->vm_start;
35001 @@ -1599,6 +1845,8 @@ int expand_upwards(struct vm_area_struct
35003 vma->vm_end = address;
35006 + anon_vma_unlock(vma->vm_next);
35007 anon_vma_unlock(vma);
35010 @@ -1610,7 +1858,8 @@ int expand_upwards(struct vm_area_struct
35011 static inline int expand_downwards(struct vm_area_struct *vma,
35012 unsigned long address)
35015 + int error, lockprev = 0;
35016 + struct vm_area_struct *prev = NULL;
35019 * We must make sure the anon_vma is allocated
35020 @@ -1624,6 +1873,15 @@ static inline int expand_downwards(struc
35024 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
35025 + find_vma_prev(address, &prev);
35026 + lockprev = prev && (prev->vm_flags & VM_GROWSUP);
35028 + if (lockprev && unlikely(anon_vma_prepare(prev)))
35031 + anon_vma_lock(prev);
35033 anon_vma_lock(vma);
35036 @@ -1633,9 +1891,15 @@ static inline int expand_downwards(struc
35039 /* Somebody else might have raced and expanded it already */
35040 - if (address < vma->vm_start) {
35041 + if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
35042 unsigned long size, grow;
35044 +#ifdef CONFIG_PAX_SEGMEXEC
35045 + struct vm_area_struct *vma_m;
35047 + vma_m = pax_find_mirror_vma(vma);
35050 size = vma->vm_end - address;
35051 grow = (vma->vm_start - address) >> PAGE_SHIFT;
35053 @@ -1643,9 +1907,20 @@ static inline int expand_downwards(struc
35055 vma->vm_start = address;
35056 vma->vm_pgoff -= grow;
35057 + track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
35059 +#ifdef CONFIG_PAX_SEGMEXEC
35061 + vma_m->vm_start -= grow << PAGE_SHIFT;
35062 + vma_m->vm_pgoff -= grow;
35068 anon_vma_unlock(vma);
35070 + anon_vma_unlock(prev);
35074 @@ -1717,6 +1992,13 @@ static void remove_vma_list(struct mm_st
35076 long nrpages = vma_pages(vma);
35078 +#ifdef CONFIG_PAX_SEGMEXEC
35079 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
35080 + vma = remove_vma(vma);
35085 vx_vmpages_sub(mm, nrpages);
35086 if (vma->vm_flags & VM_LOCKED)
35087 vx_vmlocked_sub(mm, nrpages);
35088 @@ -1763,6 +2045,16 @@ detach_vmas_to_be_unmapped(struct mm_str
35090 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
35093 +#ifdef CONFIG_PAX_SEGMEXEC
35094 + if (vma->vm_mirror) {
35095 + BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
35096 + vma->vm_mirror->vm_mirror = NULL;
35097 + vma->vm_mirror->vm_flags &= ~VM_EXEC;
35098 + vma->vm_mirror = NULL;
35102 rb_erase(&vma->vm_rb, &mm->mm_rb);
35105 @@ -1782,6 +2074,112 @@ detach_vmas_to_be_unmapped(struct mm_str
35106 * Split a vma into two pieces at address 'addr', a new vma is allocated
35107 * either for the first part or the tail.
35110 +#ifdef CONFIG_PAX_SEGMEXEC
35111 +int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
35112 + unsigned long addr, int new_below)
35114 + struct mempolicy *pol, *pol_m;
35115 + struct vm_area_struct *new, *vma_m, *new_m = NULL;
35116 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
35118 + if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
35121 + vma_m = pax_find_mirror_vma(vma);
35123 + BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
35124 + if (mm->map_count >= sysctl_max_map_count-1)
35126 + } else if (mm->map_count >= sysctl_max_map_count)
35129 + new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
35134 + new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
35136 + kmem_cache_free(vm_area_cachep, new);
35141 + /* most fields are the same, copy all, and then fixup */
35145 + new->vm_end = addr;
35147 + new->vm_start = addr;
35148 + new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
35153 + new_m->vm_mirror = new;
35154 + new->vm_mirror = new_m;
35157 + new_m->vm_end = addr_m;
35159 + new_m->vm_start = addr_m;
35160 + new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
35164 + pol = mpol_copy(vma_policy(vma));
35165 + if (IS_ERR(pol)) {
35167 + kmem_cache_free(vm_area_cachep, new_m);
35168 + kmem_cache_free(vm_area_cachep, new);
35169 + return PTR_ERR(pol);
35173 + pol_m = mpol_copy(vma_policy(vma_m));
35174 + if (IS_ERR(pol_m)) {
35176 + kmem_cache_free(vm_area_cachep, new_m);
35177 + kmem_cache_free(vm_area_cachep, new);
35178 + return PTR_ERR(pol);
35182 + vma_set_policy(new, pol);
35184 + if (new->vm_file)
35185 + get_file(new->vm_file);
35187 + if (new->vm_ops && new->vm_ops->open)
35188 + new->vm_ops->open(new);
35191 + vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
35192 + ((addr - new->vm_start) >> PAGE_SHIFT), new);
35194 + vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
35197 + vma_set_policy(new_m, pol_m);
35199 + if (new_m->vm_file)
35200 + get_file(new_m->vm_file);
35202 + if (new_m->vm_ops && new_m->vm_ops->open)
35203 + new_m->vm_ops->open(new_m);
35206 + vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
35207 + ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
35209 + vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
35215 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
35216 unsigned long addr, int new_below)
35218 @@ -1829,17 +2227,37 @@ int split_vma(struct mm_struct * mm, str
35224 /* Munmap is split into 2 main parts -- this part which finds
35225 * what needs doing, and the areas themselves, which do the
35226 * work. This now handles partial unmappings.
35227 * Jeremy Fitzhardinge <jeremy@goop.org>
35229 +#ifdef CONFIG_PAX_SEGMEXEC
35230 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35232 + int ret = __do_munmap(mm, start, len);
35233 + if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
35236 + return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
35239 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35241 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35245 struct vm_area_struct *vma, *prev, *last;
35248 + * mm->mmap_sem is required to protect against another thread
35249 + * changing the mappings in case we sleep.
35251 + verify_mm_writelocked(mm);
35253 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
35256 @@ -1889,6 +2307,8 @@ int do_munmap(struct mm_struct *mm, unsi
35257 /* Fix up all other VM information */
35258 remove_vma_list(mm, vma);
35260 + track_exec_limit(mm, start, end, 0UL);
35265 @@ -1901,22 +2321,18 @@ asmlinkage long sys_munmap(unsigned long
35267 profile_munmap(addr);
35269 +#ifdef CONFIG_PAX_SEGMEXEC
35270 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
35271 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
35275 down_write(&mm->mmap_sem);
35276 ret = do_munmap(mm, addr, len);
35277 up_write(&mm->mmap_sem);
35281 -static inline void verify_mm_writelocked(struct mm_struct *mm)
35283 -#ifdef CONFIG_DEBUG_VM
35284 - if (unlikely(down_read_trylock(&mm->mmap_sem))) {
35286 - up_read(&mm->mmap_sem);
35292 * this is really a simplified "do_mmap". it only handles
35293 * anonymous maps. eventually we may be able to do some
35294 @@ -1930,6 +2346,11 @@ unsigned long do_brk(unsigned long addr,
35295 struct rb_node ** rb_link, * rb_parent;
35296 pgoff_t pgoff = addr >> PAGE_SHIFT;
35298 + unsigned long charged;
35300 +#ifdef CONFIG_PAX_SEGMEXEC
35301 + struct vm_area_struct *vma_m = NULL;
35304 len = PAGE_ALIGN(len);
35306 @@ -1947,19 +2368,34 @@ unsigned long do_brk(unsigned long addr,
35308 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
35310 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
35311 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
35312 + flags &= ~VM_EXEC;
35314 +#ifdef CONFIG_PAX_MPROTECT
35315 + if (mm->pax_flags & MF_PAX_MPROTECT)
35316 + flags &= ~VM_MAYEXEC;
35322 error = arch_mmap_check(addr, len, flags);
35326 + charged = len >> PAGE_SHIFT;
35329 * mlock MCL_FUTURE?
35331 if (mm->def_flags & VM_LOCKED) {
35332 unsigned long locked, lock_limit;
35333 - locked = len >> PAGE_SHIFT;
35334 + locked = charged;
35335 locked += mm->locked_vm;
35336 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
35337 lock_limit >>= PAGE_SHIFT;
35338 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
35339 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
35341 if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
35342 @@ -1973,23 +2409,23 @@ unsigned long do_brk(unsigned long addr,
35344 * Clear old maps. this also does some error checking for us
35347 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35348 if (vma && vma->vm_start < addr + len) {
35349 if (do_munmap(mm, addr, len))
35351 - goto munmap_back;
35352 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35353 + BUG_ON(vma && vma->vm_start < addr + len);
35356 /* Check against address space limits *after* clearing old maps... */
35357 - if (!may_expand_vm(mm, len >> PAGE_SHIFT))
35358 + if (!may_expand_vm(mm, charged))
35361 if (mm->map_count > sysctl_max_map_count)
35364 - if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
35365 - !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
35366 + if (security_vm_enough_memory(charged) ||
35367 + !vx_vmpages_avail(mm, charged))
35370 /* Can we just expand an old private anonymous mapping? */
35371 @@ -2001,10 +2437,21 @@ unsigned long do_brk(unsigned long addr,
35373 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35375 - vm_unacct_memory(len >> PAGE_SHIFT);
35376 + vm_unacct_memory(charged);
35380 +#ifdef CONFIG_PAX_SEGMEXEC
35381 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
35382 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35384 + kmem_cache_free(vm_area_cachep, vma);
35385 + vm_unacct_memory(charged);
35392 vma->vm_start = addr;
35393 vma->vm_end = addr + len;
35394 @@ -2012,12 +2459,19 @@ unsigned long do_brk(unsigned long addr,
35395 vma->vm_flags = flags;
35396 vma->vm_page_prot = vm_get_page_prot(flags);
35397 vma_link(mm, vma, prev, rb_link, rb_parent);
35399 +#ifdef CONFIG_PAX_SEGMEXEC
35401 + pax_mirror_vma(vma_m, vma);
35405 - vx_vmpages_add(mm, len >> PAGE_SHIFT);
35406 + vx_vmpages_add(mm, charged);
35407 if (flags & VM_LOCKED) {
35408 - vx_vmlocked_add(mm, len >> PAGE_SHIFT);
35409 + vx_vmlocked_add(mm, charged);
35410 make_pages_present(addr, addr + len);
35412 + track_exec_limit(mm, addr, addr + len, flags);
35416 @@ -2048,8 +2502,10 @@ void exit_mmap(struct mm_struct *mm)
35417 * Walk the list again, actually closing and freeing it,
35418 * with preemption enabled, without holding any MM locks.
35422 + vma->vm_mirror = NULL;
35423 vma = remove_vma(vma);
35426 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
35428 @@ -2063,6 +2519,10 @@ int insert_vm_struct(struct mm_struct *
35429 struct vm_area_struct * __vma, * prev;
35430 struct rb_node ** rb_link, * rb_parent;
35432 +#ifdef CONFIG_PAX_SEGMEXEC
35433 + struct vm_area_struct *vma_m = NULL;
35437 * The vm_pgoff of a purely anonymous vma should be irrelevant
35438 * until its first write fault, when page's anon_vma and index
35439 @@ -2085,7 +2545,22 @@ int insert_vm_struct(struct mm_struct *
35440 if ((vma->vm_flags & VM_ACCOUNT) &&
35441 security_vm_enough_memory_mm(mm, vma_pages(vma)))
35444 +#ifdef CONFIG_PAX_SEGMEXEC
35445 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
35446 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35452 vma_link(mm, vma, prev, rb_link, rb_parent);
35454 +#ifdef CONFIG_PAX_SEGMEXEC
35456 + pax_mirror_vma(vma_m, vma);
35462 @@ -2103,6 +2578,8 @@ struct vm_area_struct *copy_vma(struct v
35463 struct rb_node **rb_link, *rb_parent;
35464 struct mempolicy *pol;
35466 + BUG_ON(vma->vm_mirror);
35469 * If anonymous vma has not yet been faulted, update new pgoff
35470 * to match new location, to increase its chance of merging.
35471 @@ -2143,6 +2620,34 @@ struct vm_area_struct *copy_vma(struct v
35475 +#ifdef CONFIG_PAX_SEGMEXEC
35476 +void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
35478 + struct vm_area_struct *prev_m;
35479 + struct rb_node **rb_link_m, *rb_parent_m;
35480 + struct mempolicy *pol_m;
35482 + BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
35483 + BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
35484 + BUG_ON(!vma_mpol_equal(vma, vma_m));
35485 + pol_m = vma_policy(vma_m);
35487 + vma_set_policy(vma_m, pol_m);
35488 + vma_m->vm_start += SEGMEXEC_TASK_SIZE;
35489 + vma_m->vm_end += SEGMEXEC_TASK_SIZE;
35490 + vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
35491 + vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
35492 + if (vma_m->vm_file)
35493 + get_file(vma_m->vm_file);
35494 + if (vma_m->vm_ops && vma_m->vm_ops->open)
35495 + vma_m->vm_ops->open(vma_m);
35496 + find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
35497 + vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
35498 + vma_m->vm_mirror = vma;
35499 + vma->vm_mirror = vma_m;
35504 * Return true if the calling process may expand its vm space by the passed
35506 @@ -2153,7 +2658,7 @@ int may_expand_vm(struct mm_struct *mm,
35509 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
35511 + gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
35512 if (cur + npages > lim)
35515 @@ -2165,7 +2670,7 @@ static struct page *special_mapping_nopa
35517 struct page **pages;
35519 - BUG_ON(address < vma->vm_start || address >= vma->vm_end);
35520 + BUG_ON(address < vma->vm_start || address >= vma->vm_end || (address & ~PAGE_MASK));
35522 address -= vma->vm_start;
35523 for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
35524 @@ -2215,6 +2720,15 @@ int install_special_mapping(struct mm_st
35525 vma->vm_start = addr;
35526 vma->vm_end = addr + len;
35528 +#ifdef CONFIG_PAX_MPROTECT
35529 + if (mm->pax_flags & MF_PAX_MPROTECT) {
35530 + if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
35531 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
35533 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
35537 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
35538 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
35540 diff -urNp linux-2.6.24.4/mm/mprotect.c linux-2.6.24.4/mm/mprotect.c
35541 --- linux-2.6.24.4/mm/mprotect.c 2008-03-24 14:49:18.000000000 -0400
35542 +++ linux-2.6.24.4/mm/mprotect.c 2008-03-26 20:21:09.000000000 -0400
35543 @@ -21,10 +21,17 @@
35544 #include <linux/syscalls.h>
35545 #include <linux/swap.h>
35546 #include <linux/swapops.h>
35547 +#include <linux/grsecurity.h>
35549 +#ifdef CONFIG_PAX_MPROTECT
35550 +#include <linux/elf.h>
35553 #include <asm/uaccess.h>
35554 #include <asm/pgtable.h>
35555 #include <asm/cacheflush.h>
35556 #include <asm/tlbflush.h>
35557 +#include <asm/mmu_context.h>
35559 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
35560 unsigned long addr, unsigned long end, pgprot_t newprot,
35561 @@ -127,6 +134,48 @@ static void change_protection(struct vm_
35562 flush_tlb_range(vma, start, end);
35565 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35566 +/* called while holding the mmap semaphor for writing except stack expansion */
35567 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
35569 + unsigned long oldlimit, newlimit = 0UL;
35571 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
35574 + spin_lock(&mm->page_table_lock);
35575 + oldlimit = mm->context.user_cs_limit;
35576 + if ((prot & VM_EXEC) && oldlimit < end)
35577 + /* USER_CS limit moved up */
35579 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
35580 + /* USER_CS limit moved down */
35581 + newlimit = start;
35584 + mm->context.user_cs_limit = newlimit;
35588 + cpus_clear(mm->context.cpu_user_cs_mask);
35589 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
35592 + set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
35594 + spin_unlock(&mm->page_table_lock);
35595 + if (newlimit == end) {
35596 + struct vm_area_struct *vma = find_vma(mm, oldlimit);
35598 + for (; vma && vma->vm_start < end; vma = vma->vm_next)
35599 + if (is_vm_hugetlb_page(vma))
35600 + hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
35602 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
35608 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
35609 unsigned long start, unsigned long end, unsigned long newflags)
35610 @@ -139,11 +188,41 @@ mprotect_fixup(struct vm_area_struct *vm
35612 int dirty_accountable = 0;
35614 +#ifdef CONFIG_PAX_SEGMEXEC
35615 + struct vm_area_struct *vma_m = NULL;
35616 + unsigned long start_m, end_m;
35618 + start_m = start + SEGMEXEC_TASK_SIZE;
35619 + end_m = end + SEGMEXEC_TASK_SIZE;
35622 if (newflags == oldflags) {
35627 +#ifdef CONFIG_PAX_SEGMEXEC
35628 + if (pax_find_mirror_vma(vma) && !(newflags & VM_EXEC)) {
35629 + if (start != vma->vm_start) {
35630 + error = split_vma(mm, vma, start, 1);
35633 + BUG_ON(!*pprev || (*pprev)->vm_next == vma);
35634 + *pprev = (*pprev)->vm_next;
35637 + if (end != vma->vm_end) {
35638 + error = split_vma(mm, vma, end, 0);
35643 + error = __do_munmap(mm, start_m, end_m - start_m);
35650 * If we make a private mapping writable we increase our commit;
35651 * but (without finer accounting) cannot reduce our commit if we
35652 @@ -186,6 +265,25 @@ mprotect_fixup(struct vm_area_struct *vm
35656 +#ifdef CONFIG_PAX_SEGMEXEC
35657 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) {
35658 + struct mempolicy *pol;
35660 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35665 + pol = mpol_copy(vma_policy(vma));
35666 + if (IS_ERR(pol)) {
35667 + kmem_cache_free(vm_area_cachep, vma_m);
35671 + vma_set_policy(vma_m, pol);
35677 * vm_flags and vm_page_prot are protected by the mmap_sem
35678 @@ -202,6 +300,12 @@ success:
35679 hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
35681 change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable);
35683 +#ifdef CONFIG_PAX_SEGMEXEC
35685 + pax_mirror_vma(vma_m, vma);
35688 vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
35689 vm_stat_account(mm, newflags, vma->vm_file, nrpages);
35691 @@ -211,6 +315,70 @@ fail:
35695 +#ifdef CONFIG_PAX_MPROTECT
35696 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
35697 + * therefore we'll grant them VM_MAYWRITE once during their life.
35699 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
35700 + * basis because we want to allow the common case and not the special ones.
35702 +static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
35704 + struct elfhdr elf_h;
35705 + struct elf_phdr elf_p;
35706 + elf_addr_t dyn_offset = 0UL;
35708 + unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
35710 +#ifndef CONFIG_PAX_NOELFRELOCS
35711 + if ((vma->vm_start != start) ||
35713 + !(vma->vm_flags & VM_MAYEXEC) ||
35714 + (vma->vm_flags & VM_MAYNOTWRITE))
35719 + if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
35720 + memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
35722 +#ifdef CONFIG_PAX_ETEXECRELOCS
35723 + (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
35725 + elf_h.e_type != ET_DYN ||
35728 + !elf_check_arch(&elf_h) ||
35729 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
35730 + elf_h.e_phnum > j)
35733 + for (i = 0UL; i < elf_h.e_phnum; i++) {
35734 + if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
35736 + if (elf_p.p_type == PT_DYNAMIC) {
35737 + dyn_offset = elf_p.p_offset;
35741 + if (elf_h.e_phnum <= j)
35746 + if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
35748 + if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
35749 + gr_log_textrel(vma);
35750 + vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
35754 + } while (dyn.d_tag != DT_NULL);
35760 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
35762 @@ -230,6 +398,17 @@ sys_mprotect(unsigned long start, size_t
35767 +#ifdef CONFIG_PAX_SEGMEXEC
35768 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
35769 + if (end > SEGMEXEC_TASK_SIZE)
35774 + if (end > TASK_SIZE)
35777 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
35780 @@ -237,7 +416,7 @@ sys_mprotect(unsigned long start, size_t
35782 * Does the application expect PROT_READ to imply PROT_EXEC:
35784 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
35785 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
35788 vm_flags = calc_vm_prot_bits(prot);
35789 @@ -269,6 +448,16 @@ sys_mprotect(unsigned long start, size_t
35790 if (start > vma->vm_start)
35793 + if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
35798 +#ifdef CONFIG_PAX_MPROTECT
35799 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
35800 + pax_handle_maywrite(vma, start);
35803 for (nstart = start ; ; ) {
35804 unsigned long newflags;
35806 @@ -282,6 +471,12 @@ sys_mprotect(unsigned long start, size_t
35810 +#ifdef CONFIG_PAX_MPROTECT
35811 + /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
35812 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
35813 + newflags &= ~VM_MAYWRITE;
35816 error = security_file_mprotect(vma, reqprot, prot);
35819 @@ -292,6 +487,9 @@ sys_mprotect(unsigned long start, size_t
35820 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
35824 + track_exec_limit(current->mm, nstart, tmp, vm_flags);
35828 if (nstart < prev->vm_end)
35829 diff -urNp linux-2.6.24.4/mm/mremap.c linux-2.6.24.4/mm/mremap.c
35830 --- linux-2.6.24.4/mm/mremap.c 2008-03-24 14:49:18.000000000 -0400
35831 +++ linux-2.6.24.4/mm/mremap.c 2008-03-26 20:21:09.000000000 -0400
35832 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
35834 pte = ptep_clear_flush(vma, old_addr, old_pte);
35835 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
35837 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35838 + if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
35839 + pte = pte_exprotect(pte);
35842 set_pte_at(mm, new_addr, new_pte, pte);
35845 @@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
35846 struct vm_area_struct *vma;
35847 unsigned long ret = -EINVAL;
35848 unsigned long charged = 0;
35849 + unsigned long pax_task_size = TASK_SIZE;
35851 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
35853 @@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
35857 +#ifdef CONFIG_PAX_SEGMEXEC
35858 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
35859 + pax_task_size = SEGMEXEC_TASK_SIZE;
35862 + if (new_len > pax_task_size || addr > pax_task_size-new_len ||
35863 + old_len > pax_task_size || addr > pax_task_size-old_len)
35866 /* new_addr is only valid if MREMAP_FIXED is specified */
35867 if (flags & MREMAP_FIXED) {
35868 if (new_addr & ~PAGE_MASK)
35869 @@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
35870 if (!(flags & MREMAP_MAYMOVE))
35873 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
35874 + if (new_addr > pax_task_size - new_len)
35877 /* Check if the location we're moving into overlaps the
35878 * old location at all, and fail if it does.
35880 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
35883 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
35884 + if (addr + old_len > new_addr && new_addr + new_len > addr)
35887 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
35888 @@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
35893 +#ifdef CONFIG_PAX_SEGMEXEC
35894 + if (pax_find_mirror_vma(vma)) {
35900 /* We can't remap across vm area boundaries */
35901 if (old_len > vma->vm_end - addr)
35903 @@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
35904 if (old_len == vma->vm_end - addr &&
35905 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
35906 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
35907 - unsigned long max_addr = TASK_SIZE;
35908 + unsigned long max_addr = pax_task_size;
35910 max_addr = vma->vm_next->vm_start;
35911 /* can we just expand the current mapping? */
35912 @@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
35916 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
35920 @@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
35923 if (flags & MREMAP_MAYMOVE) {
35924 + unsigned long map_flags = 0;
35925 if (!(flags & MREMAP_FIXED)) {
35926 - unsigned long map_flags = 0;
35927 if (vma->vm_flags & VM_MAYSHARE)
35928 map_flags |= MAP_SHARED;
35930 @@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
35934 + map_flags = vma->vm_flags;
35935 ret = move_vma(vma, addr, old_len, new_len, new_addr);
35936 + if (!(ret & ~PAGE_MASK)) {
35937 + track_exec_limit(current->mm, addr, addr + old_len, 0UL);
35938 + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
35942 if (ret & ~PAGE_MASK)
35943 diff -urNp linux-2.6.24.4/mm/nommu.c linux-2.6.24.4/mm/nommu.c
35944 --- linux-2.6.24.4/mm/nommu.c 2008-03-24 14:49:18.000000000 -0400
35945 +++ linux-2.6.24.4/mm/nommu.c 2008-03-26 20:21:09.000000000 -0400
35946 @@ -377,15 +377,6 @@ struct vm_area_struct *find_vma(struct m
35948 EXPORT_SYMBOL(find_vma);
35952 - * - we don't extend stack VMAs under NOMMU conditions
35954 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
35956 - return find_vma(mm, addr);
35959 int expand_stack(struct vm_area_struct *vma, unsigned long address)
35962 diff -urNp linux-2.6.24.4/mm/page_alloc.c linux-2.6.24.4/mm/page_alloc.c
35963 --- linux-2.6.24.4/mm/page_alloc.c 2008-03-24 14:49:18.000000000 -0400
35964 +++ linux-2.6.24.4/mm/page_alloc.c 2008-03-26 20:21:09.000000000 -0400
35965 @@ -505,9 +505,20 @@ static void free_pages_bulk(struct zone
35967 static void free_one_page(struct zone *zone, struct page *page, int order)
35970 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35971 + unsigned long index = 1UL << order;
35974 spin_lock(&zone->lock);
35975 zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
35976 zone->pages_scanned = 0;
35978 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35979 + for (; index; --index)
35980 + sanitize_highpage(page + index - 1);
35983 __free_one_page(page, zone, order);
35984 spin_unlock(&zone->lock);
35986 @@ -631,8 +642,10 @@ static int prep_new_page(struct page *pa
35987 arch_alloc_page(page, order);
35988 kernel_map_pages(page, 1 << order, 1);
35990 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
35991 if (gfp_flags & __GFP_ZERO)
35992 prep_zero_page(page, order, gfp_flags);
35995 if (order && (gfp_flags & __GFP_COMP))
35996 prep_compound_page(page, order);
35997 @@ -1007,6 +1020,11 @@ static void fastcall free_hot_cold_page(
35998 list_add(&page->lru, &pcp->list);
35999 set_page_private(page, get_pageblock_migratetype(page));
36002 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
36003 + sanitize_highpage(page);
36006 if (pcp->count >= pcp->high) {
36007 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
36008 pcp->count -= pcp->batch;
36009 diff -urNp linux-2.6.24.4/mm/rmap.c linux-2.6.24.4/mm/rmap.c
36010 --- linux-2.6.24.4/mm/rmap.c 2008-03-24 14:49:18.000000000 -0400
36011 +++ linux-2.6.24.4/mm/rmap.c 2008-03-26 20:21:09.000000000 -0400
36012 @@ -64,6 +64,10 @@ int anon_vma_prepare(struct vm_area_stru
36013 struct mm_struct *mm = vma->vm_mm;
36014 struct anon_vma *allocated, *locked;
36016 +#ifdef CONFIG_PAX_SEGMEXEC
36017 + struct vm_area_struct *vma_m;
36020 anon_vma = find_mergeable_anon_vma(vma);
36023 @@ -80,6 +84,15 @@ int anon_vma_prepare(struct vm_area_stru
36024 /* page_table_lock to protect against threads */
36025 spin_lock(&mm->page_table_lock);
36026 if (likely(!vma->anon_vma)) {
36028 +#ifdef CONFIG_PAX_SEGMEXEC
36029 + vma_m = pax_find_mirror_vma(vma);
36031 + vma_m->anon_vma = anon_vma;
36032 + __anon_vma_link(vma_m);
36036 vma->anon_vma = anon_vma;
36037 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
36039 diff -urNp linux-2.6.24.4/mm/shmem.c linux-2.6.24.4/mm/shmem.c
36040 --- linux-2.6.24.4/mm/shmem.c 2008-03-24 14:49:18.000000000 -0400
36041 +++ linux-2.6.24.4/mm/shmem.c 2008-03-26 20:21:09.000000000 -0400
36042 @@ -2462,7 +2462,7 @@ static struct file_system_type tmpfs_fs_
36043 .get_sb = shmem_get_sb,
36044 .kill_sb = kill_litter_super,
36046 -static struct vfsmount *shm_mnt;
36047 +struct vfsmount *shm_mnt;
36049 static int __init init_tmpfs(void)
36051 diff -urNp linux-2.6.24.4/mm/slab.c linux-2.6.24.4/mm/slab.c
36052 --- linux-2.6.24.4/mm/slab.c 2008-03-24 14:49:18.000000000 -0400
36053 +++ linux-2.6.24.4/mm/slab.c 2008-03-26 20:21:09.000000000 -0400
36054 @@ -305,7 +305,7 @@ struct kmem_list3 {
36055 * Need this for bootstrapping a per node allocator.
36057 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
36058 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
36059 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
36060 #define CACHE_CACHE 0
36061 #define SIZE_AC MAX_NUMNODES
36062 #define SIZE_L3 (2 * MAX_NUMNODES)
36063 @@ -654,14 +654,14 @@ struct cache_names {
36064 static struct cache_names __initdata cache_names[] = {
36065 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
36066 #include <linux/kmalloc_sizes.h>
36072 static struct arraycache_init initarray_cache __initdata =
36073 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
36074 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
36075 static struct arraycache_init initarray_generic =
36076 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
36077 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
36079 /* internal cache of cache description objs */
36080 static struct kmem_cache cache_cache = {
36081 @@ -3004,7 +3004,7 @@ retry:
36082 * there must be at least one object available for
36085 - BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
36086 + BUG_ON(slabp->inuse >= cachep->num);
36088 while (slabp->inuse < cachep->num && batchcount--) {
36089 STATS_INC_ALLOCED(cachep);
36090 diff -urNp linux-2.6.24.4/mm/slub.c linux-2.6.24.4/mm/slub.c
36091 --- linux-2.6.24.4/mm/slub.c 2008-03-24 14:49:18.000000000 -0400
36092 +++ linux-2.6.24.4/mm/slub.c 2008-03-26 20:21:09.000000000 -0400
36093 @@ -1539,7 +1539,7 @@ debug:
36095 * Otherwise we can simply pick the next object from the lockless free list.
36097 -static void __always_inline *slab_alloc(struct kmem_cache *s,
36098 +static __always_inline void *slab_alloc(struct kmem_cache *s,
36099 gfp_t gfpflags, int node, void *addr)
36102 @@ -1647,7 +1647,7 @@ debug:
36103 * If fastpath is not possible then fall back to __slab_free where we deal
36104 * with all sorts of special processing.
36106 -static void __always_inline slab_free(struct kmem_cache *s,
36107 +static __always_inline void slab_free(struct kmem_cache *s,
36108 struct page *page, void *x, void *addr)
36110 void **object = (void *)x;
36111 diff -urNp linux-2.6.24.4/mm/swap.c linux-2.6.24.4/mm/swap.c
36112 --- linux-2.6.24.4/mm/swap.c 2008-03-24 14:49:18.000000000 -0400
36113 +++ linux-2.6.24.4/mm/swap.c 2008-03-26 20:21:09.000000000 -0400
36115 /* How many pages do we try to swap or page in/out together? */
36118 -static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
36119 -static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
36120 -static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
36121 +static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} };
36122 +static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} };
36123 +static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, 0, {NULL} };
36126 * This path almost never happens for VM activity - pages are normally
36127 diff -urNp linux-2.6.24.4/mm/tiny-shmem.c linux-2.6.24.4/mm/tiny-shmem.c
36128 --- linux-2.6.24.4/mm/tiny-shmem.c 2008-03-24 14:49:18.000000000 -0400
36129 +++ linux-2.6.24.4/mm/tiny-shmem.c 2008-03-26 20:21:09.000000000 -0400
36130 @@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
36131 .kill_sb = kill_litter_super,
36134 -static struct vfsmount *shm_mnt;
36135 +struct vfsmount *shm_mnt;
36137 static int __init init_tmpfs(void)
36139 diff -urNp linux-2.6.24.4/mm/vmalloc.c linux-2.6.24.4/mm/vmalloc.c
36140 --- linux-2.6.24.4/mm/vmalloc.c 2008-03-24 14:49:18.000000000 -0400
36141 +++ linux-2.6.24.4/mm/vmalloc.c 2008-03-26 20:21:09.000000000 -0400
36142 @@ -202,6 +202,8 @@ static struct vm_struct *__get_vm_area_n
36144 write_lock(&vmlist_lock);
36145 for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
36146 + if (addr > end - size)
36148 if ((unsigned long)tmp->addr < addr) {
36149 if((unsigned long)tmp->addr + tmp->size >= addr)
36150 addr = ALIGN(tmp->size +
36151 @@ -213,8 +215,6 @@ static struct vm_struct *__get_vm_area_n
36152 if (size + addr <= (unsigned long)tmp->addr)
36154 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
36155 - if (addr > end - size)
36160 diff -urNp linux-2.6.24.4/net/bridge/br_stp_if.c linux-2.6.24.4/net/bridge/br_stp_if.c
36161 --- linux-2.6.24.4/net/bridge/br_stp_if.c 2008-03-24 14:49:18.000000000 -0400
36162 +++ linux-2.6.24.4/net/bridge/br_stp_if.c 2008-03-26 20:21:09.000000000 -0400
36163 @@ -148,7 +148,7 @@ static void br_stp_stop(struct net_bridg
36164 char *envp[] = { NULL };
36166 if (br->stp_enabled == BR_USER_STP) {
36167 - r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
36168 + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
36169 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
36172 diff -urNp linux-2.6.24.4/net/core/flow.c linux-2.6.24.4/net/core/flow.c
36173 --- linux-2.6.24.4/net/core/flow.c 2008-03-24 14:49:18.000000000 -0400
36174 +++ linux-2.6.24.4/net/core/flow.c 2008-03-26 20:21:09.000000000 -0400
36175 @@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
36177 static u32 flow_hash_shift;
36178 #define flow_hash_size (1 << flow_hash_shift)
36179 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
36180 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
36182 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
36184 @@ -53,7 +53,7 @@ struct flow_percpu_info {
36187 } ____cacheline_aligned;
36188 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
36189 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
36191 #define flow_hash_rnd_recalc(cpu) \
36192 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
36193 @@ -70,7 +70,7 @@ struct flow_flush_info {
36195 struct completion completion;
36197 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
36198 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
36200 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
36202 diff -urNp linux-2.6.24.4/net/dccp/ccids/ccid3.c linux-2.6.24.4/net/dccp/ccids/ccid3.c
36203 --- linux-2.6.24.4/net/dccp/ccids/ccid3.c 2008-03-24 14:49:18.000000000 -0400
36204 +++ linux-2.6.24.4/net/dccp/ccids/ccid3.c 2008-03-26 20:21:09.000000000 -0400
36206 static int ccid3_debug;
36207 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
36209 -#define ccid3_pr_debug(format, a...)
36210 +#define ccid3_pr_debug(format, a...) do {} while (0)
36213 static struct dccp_tx_hist *ccid3_tx_hist;
36214 diff -urNp linux-2.6.24.4/net/dccp/dccp.h linux-2.6.24.4/net/dccp/dccp.h
36215 --- linux-2.6.24.4/net/dccp/dccp.h 2008-03-24 14:49:18.000000000 -0400
36216 +++ linux-2.6.24.4/net/dccp/dccp.h 2008-03-26 20:21:09.000000000 -0400
36217 @@ -43,8 +43,8 @@ extern int dccp_debug;
36218 #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
36219 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
36221 -#define dccp_pr_debug(format, a...)
36222 -#define dccp_pr_debug_cat(format, a...)
36223 +#define dccp_pr_debug(format, a...) do {} while (0)
36224 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
36227 extern struct inet_hashinfo dccp_hashinfo;
36228 diff -urNp linux-2.6.24.4/net/ipv4/inet_connection_sock.c linux-2.6.24.4/net/ipv4/inet_connection_sock.c
36229 --- linux-2.6.24.4/net/ipv4/inet_connection_sock.c 2008-03-24 14:49:18.000000000 -0400
36230 +++ linux-2.6.24.4/net/ipv4/inet_connection_sock.c 2008-03-26 20:21:09.000000000 -0400
36233 #include <linux/module.h>
36234 #include <linux/jhash.h>
36235 +#include <linux/grsecurity.h>
36237 #include <net/inet_connection_sock.h>
36238 #include <net/inet_hashtables.h>
36239 diff -urNp linux-2.6.24.4/net/ipv4/inet_hashtables.c linux-2.6.24.4/net/ipv4/inet_hashtables.c
36240 --- linux-2.6.24.4/net/ipv4/inet_hashtables.c 2008-03-24 14:49:18.000000000 -0400
36241 +++ linux-2.6.24.4/net/ipv4/inet_hashtables.c 2008-03-26 20:21:09.000000000 -0400
36243 #include <linux/sched.h>
36244 #include <linux/slab.h>
36245 #include <linux/wait.h>
36246 +#include <linux/grsecurity.h>
36248 #include <net/inet_connection_sock.h>
36249 #include <net/inet_hashtables.h>
36251 #include <net/route.h>
36252 #include <net/ip.h>
36254 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
36257 * Allocate and initialize a new local port bind bucket.
36258 * The bindhash mutex for snum's hash chain must be held here.
36259 @@ -338,6 +341,8 @@ ok:
36261 spin_unlock(&head->lock);
36263 + gr_update_task_in_ip_table(current, inet_sk(sk));
36266 inet_twsk_deschedule(tw, death_row);
36268 diff -urNp linux-2.6.24.4/net/ipv4/netfilter/ipt_stealth.c linux-2.6.24.4/net/ipv4/netfilter/ipt_stealth.c
36269 --- linux-2.6.24.4/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
36270 +++ linux-2.6.24.4/net/ipv4/netfilter/ipt_stealth.c 2008-03-26 20:21:09.000000000 -0400
36272 +/* Kernel module to add stealth support.
36274 + * Copyright (C) 2002-2006 Brad Spengler <spender@grsecurity.net>
36278 +#include <linux/kernel.h>
36279 +#include <linux/module.h>
36280 +#include <linux/skbuff.h>
36281 +#include <linux/net.h>
36282 +#include <linux/sched.h>
36283 +#include <linux/inet.h>
36284 +#include <linux/stddef.h>
36286 +#include <net/ip.h>
36287 +#include <net/sock.h>
36288 +#include <net/tcp.h>
36289 +#include <net/udp.h>
36290 +#include <net/route.h>
36291 +#include <net/inet_common.h>
36293 +#include <linux/netfilter_ipv4/ip_tables.h>
36295 +MODULE_LICENSE("GPL");
36297 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
36300 +match(const struct sk_buff *skb,
36301 + const struct net_device *in,
36302 + const struct net_device *out,
36303 + const struct xt_match *match,
36304 + const void *matchinfo,
36306 + unsigned int protoff,
36309 + struct iphdr *ip = ip_hdr(skb);
36310 + struct tcphdr th;
36311 + struct udphdr uh;
36312 + struct sock *sk = NULL;
36314 + if (!ip || offset) return 0;
36316 + switch(ip->protocol) {
36317 + case IPPROTO_TCP:
36318 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
36322 + if (!(th.syn && !th.ack)) return 0;
36323 + sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
36325 + case IPPROTO_UDP:
36326 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
36330 + sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
36336 + if(!sk) // port is being listened on, match this
36344 +/* Called when user tries to insert an entry of this type. */
36346 +checkentry(const char *tablename,
36348 + const struct xt_match *match,
36350 + unsigned int hook_mask)
36352 + const struct ipt_ip *ip = (const struct ipt_ip *)nip;
36354 + if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
36355 + ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
36356 + && (hook_mask & (1 << NF_IP_LOCAL_IN)))
36359 + printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
36365 +static struct xt_match stealth_match = {
36366 + .name = "stealth",
36367 + .family = AF_INET,
36369 + .checkentry = checkentry,
36371 + .me = THIS_MODULE
36374 +static int __init init(void)
36376 + return xt_register_match(&stealth_match);
36379 +static void __exit fini(void)
36381 + xt_unregister_match(&stealth_match);
36384 +module_init(init);
36385 +module_exit(fini);
36386 diff -urNp linux-2.6.24.4/net/ipv4/netfilter/Kconfig linux-2.6.24.4/net/ipv4/netfilter/Kconfig
36387 --- linux-2.6.24.4/net/ipv4/netfilter/Kconfig 2008-03-24 14:49:18.000000000 -0400
36388 +++ linux-2.6.24.4/net/ipv4/netfilter/Kconfig 2008-03-26 20:21:09.000000000 -0400
36389 @@ -130,6 +130,21 @@ config IP_NF_MATCH_ADDRTYPE
36390 If you want to compile it as a module, say M here and read
36391 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
36393 +config IP_NF_MATCH_STEALTH
36394 + tristate "stealth match support"
36395 + depends on IP_NF_IPTABLES
36397 + Enabling this option will drop all syn packets coming to unserved tcp
36398 + ports as well as all packets coming to unserved udp ports. If you
36399 + are using your system to route any type of packets (ie. via NAT)
36400 + you should put this module at the end of your ruleset, since it will
36401 + drop packets that aren't going to ports that are listening on your
36402 + machine itself, it doesn't take into account that the packet might be
36403 + destined for someone on your internal network if you're using NAT for
36406 + To compile it as a module, choose M here. If unsure, say N.
36408 # `filter', generic and specific targets
36409 config IP_NF_FILTER
36410 tristate "Packet filtering"
36411 @@ -403,4 +418,3 @@ config IP_NF_ARP_MANGLE
36412 hardware and network addresses.
36416 diff -urNp linux-2.6.24.4/net/ipv4/netfilter/Makefile linux-2.6.24.4/net/ipv4/netfilter/Makefile
36417 --- linux-2.6.24.4/net/ipv4/netfilter/Makefile 2008-02-25 19:20:20.000000000 -0500
36418 +++ linux-2.6.24.4/net/ipv4/netfilter/Makefile 2008-03-21 01:42:50.000000000 -0400
36420 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
36421 diff -urNp linux-2.6.24.4/net/ipv4/tcp.c linux-2.6.24.4/net/ipv4/tcp.c
36422 --- linux-2.6.24.4/net/ipv4/tcp.c 2008-03-24 14:49:18.000000000 -0400
36423 +++ linux-2.6.24.4/net/ipv4/tcp.c 2008-03-26 20:21:09.000000000 -0400
36424 @@ -1054,7 +1054,8 @@ int tcp_read_sock(struct sock *sk, read_
36426 while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
36427 if (offset < skb->len) {
36428 - size_t used, len;
36432 len = skb->len - offset;
36433 /* Stop reading if we hit a patch of urgent data */
36434 diff -urNp linux-2.6.24.4/net/ipv4/tcp_ipv4.c linux-2.6.24.4/net/ipv4/tcp_ipv4.c
36435 --- linux-2.6.24.4/net/ipv4/tcp_ipv4.c 2008-03-24 14:49:18.000000000 -0400
36436 +++ linux-2.6.24.4/net/ipv4/tcp_ipv4.c 2008-03-26 20:21:09.000000000 -0400
36438 #include <linux/jhash.h>
36439 #include <linux/init.h>
36440 #include <linux/times.h>
36441 +#include <linux/grsecurity.h>
36443 #include <net/net_namespace.h>
36444 #include <net/icmp.h>
36445 diff -urNp linux-2.6.24.4/net/ipv4/udp.c linux-2.6.24.4/net/ipv4/udp.c
36446 --- linux-2.6.24.4/net/ipv4/udp.c 2008-03-24 14:49:18.000000000 -0400
36447 +++ linux-2.6.24.4/net/ipv4/udp.c 2008-03-26 20:21:09.000000000 -0400
36449 #include <linux/skbuff.h>
36450 #include <linux/proc_fs.h>
36451 #include <linux/seq_file.h>
36452 +#include <linux/grsecurity.h>
36453 #include <net/net_namespace.h>
36454 #include <net/icmp.h>
36455 #include <net/route.h>
36456 @@ -105,6 +106,11 @@
36457 #include <net/xfrm.h>
36458 #include "udp_impl.h"
36460 +extern int gr_search_udp_recvmsg(const struct sock *sk,
36461 + const struct sk_buff *skb);
36462 +extern int gr_search_udp_sendmsg(const struct sock *sk,
36463 + const struct sockaddr_in *addr);
36466 * Snmp MIB for the UDP layer
36468 @@ -295,6 +301,13 @@ static struct sock *__udp4_lib_lookup(__
36472 +struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
36473 + __be32 daddr, __be16 dport, int dif)
36475 + return __udp4_lib_lookup(saddr, sport, daddr, dport, dif, udp_hash);
36479 static inline struct sock *udp_v4_mcast_next(struct sock *sk,
36480 __be16 loc_port, __be32 loc_addr,
36481 __be16 rmt_port, __be32 rmt_addr,
36482 @@ -580,9 +593,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
36483 dport = usin->sin_port;
36487 + if (!gr_search_udp_sendmsg(sk, usin))
36490 if (sk->sk_state != TCP_ESTABLISHED)
36491 return -EDESTADDRREQ;
36493 + if (!gr_search_udp_sendmsg(sk, NULL))
36496 daddr = inet->daddr;
36497 dport = inet->dport;
36498 /* Open fast path for connected socket.
36499 @@ -842,6 +862,11 @@ try_again:
36503 + if (!gr_search_udp_recvmsg(sk, skb)) {
36508 ulen = skb->len - sizeof(struct udphdr);
36511 diff -urNp linux-2.6.24.4/net/ipv6/exthdrs.c linux-2.6.24.4/net/ipv6/exthdrs.c
36512 --- linux-2.6.24.4/net/ipv6/exthdrs.c 2008-03-24 14:49:18.000000000 -0400
36513 +++ linux-2.6.24.4/net/ipv6/exthdrs.c 2008-03-26 20:21:09.000000000 -0400
36514 @@ -621,7 +621,7 @@ static struct tlvtype_proc tlvprochopopt
36515 .type = IPV6_TLV_JUMBO,
36516 .func = ipv6_hop_jumbo,
36522 int ipv6_parse_hopopts(struct sk_buff *skb)
36523 diff -urNp linux-2.6.24.4/net/ipv6/raw.c linux-2.6.24.4/net/ipv6/raw.c
36524 --- linux-2.6.24.4/net/ipv6/raw.c 2008-03-24 14:49:18.000000000 -0400
36525 +++ linux-2.6.24.4/net/ipv6/raw.c 2008-03-26 20:21:09.000000000 -0400
36526 @@ -578,7 +578,7 @@ out:
36530 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
36531 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
36532 struct flowi *fl, struct rt6_info *rt,
36533 unsigned int flags)
36535 diff -urNp linux-2.6.24.4/net/irda/ircomm/ircomm_tty.c linux-2.6.24.4/net/irda/ircomm/ircomm_tty.c
36536 --- linux-2.6.24.4/net/irda/ircomm/ircomm_tty.c 2008-03-24 14:49:18.000000000 -0400
36537 +++ linux-2.6.24.4/net/irda/ircomm/ircomm_tty.c 2008-03-26 20:21:09.000000000 -0400
36538 @@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
36539 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
36542 - if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
36543 + if (line >= IRCOMM_TTY_PORTS) {
36547 diff -urNp linux-2.6.24.4/net/mac80211/regdomain.c linux-2.6.24.4/net/mac80211/regdomain.c
36548 --- linux-2.6.24.4/net/mac80211/regdomain.c 2008-03-24 14:49:18.000000000 -0400
36549 +++ linux-2.6.24.4/net/mac80211/regdomain.c 2008-03-26 20:21:09.000000000 -0400
36550 @@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra
36551 { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */,
36552 { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */,
36553 { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */,
36558 static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
36559 { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
36560 { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
36561 { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
36567 diff -urNp linux-2.6.24.4/net/sctp/socket.c linux-2.6.24.4/net/sctp/socket.c
36568 --- linux-2.6.24.4/net/sctp/socket.c 2008-03-24 14:49:18.000000000 -0400
36569 +++ linux-2.6.24.4/net/sctp/socket.c 2008-03-26 20:21:09.000000000 -0400
36570 @@ -1390,7 +1390,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
36571 struct sctp_sndrcvinfo *sinfo;
36572 struct sctp_initmsg *sinit;
36573 sctp_assoc_t associd = 0;
36574 - sctp_cmsgs_t cmsgs = { NULL };
36575 + sctp_cmsgs_t cmsgs = { NULL, NULL };
36577 sctp_scope_t scope;
36579 diff -urNp linux-2.6.24.4/net/socket.c linux-2.6.24.4/net/socket.c
36580 --- linux-2.6.24.4/net/socket.c 2008-03-24 14:49:18.000000000 -0400
36581 +++ linux-2.6.24.4/net/socket.c 2008-03-26 20:21:09.000000000 -0400
36583 #include <linux/audit.h>
36584 #include <linux/wireless.h>
36585 #include <linux/nsproxy.h>
36586 +#include <linux/in.h>
36588 #include <asm/uaccess.h>
36589 #include <asm/unistd.h>
36591 #include <net/sock.h>
36592 #include <linux/netfilter.h>
36594 +extern void gr_attach_curr_ip(const struct sock *sk);
36595 +extern int gr_handle_sock_all(const int family, const int type,
36596 + const int protocol);
36597 +extern int gr_handle_sock_server(const struct sockaddr *sck);
36598 +extern int gr_handle_sock_server_other(const struct socket *sck);
36599 +extern int gr_handle_sock_client(const struct sockaddr *sck);
36600 +extern int gr_search_connect(const struct socket * sock,
36601 + const struct sockaddr_in * addr);
36602 +extern int gr_search_bind(const struct socket * sock,
36603 + const struct sockaddr_in * addr);
36604 +extern int gr_search_listen(const struct socket * sock);
36605 +extern int gr_search_accept(const struct socket * sock);
36606 +extern int gr_search_socket(const int domain, const int type,
36607 + const int protocol);
36609 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
36610 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
36611 unsigned long nr_segs, loff_t pos);
36612 @@ -293,7 +309,7 @@ static int sockfs_get_sb(struct file_sys
36616 -static struct vfsmount *sock_mnt __read_mostly;
36617 +struct vfsmount *sock_mnt __read_mostly;
36619 static struct file_system_type sock_fs_type = {
36621 @@ -1204,6 +1220,16 @@ asmlinkage long sys_socket(int family, i
36623 struct socket *sock;
36625 + if(!gr_search_socket(family, type, protocol)) {
36626 + retval = -EACCES;
36630 + if (gr_handle_sock_all(family, type, protocol)) {
36631 + retval = -EACCES;
36635 retval = sock_create(family, type, protocol, &sock);
36638 @@ -1334,6 +1360,12 @@ asmlinkage long sys_bind(int fd, struct
36640 err = move_addr_to_kernel(umyaddr, addrlen, address);
36642 + if (!gr_search_bind(sock, (struct sockaddr_in *)address) ||
36643 + gr_handle_sock_server((struct sockaddr *)address)) {
36648 err = security_socket_bind(sock,
36649 (struct sockaddr *)address,
36651 @@ -1342,6 +1374,7 @@ asmlinkage long sys_bind(int fd, struct
36652 (struct sockaddr *)
36656 fput_light(sock->file, fput_needed);
36659 @@ -1365,10 +1398,17 @@ asmlinkage long sys_listen(int fd, int b
36660 if ((unsigned)backlog > sysctl_somaxconn)
36661 backlog = sysctl_somaxconn;
36663 + if (gr_handle_sock_server_other(sock) ||
36664 + !gr_search_listen(sock)) {
36669 err = security_socket_listen(sock, backlog);
36671 err = sock->ops->listen(sock, backlog);
36674 fput_light(sock->file, fput_needed);
36677 @@ -1405,6 +1445,13 @@ asmlinkage long sys_accept(int fd, struc
36678 newsock->type = sock->type;
36679 newsock->ops = sock->ops;
36681 + if (gr_handle_sock_server_other(sock) ||
36682 + !gr_search_accept(sock)) {
36684 + sock_release(newsock);
36689 * We don't need try_module_get here, as the listening socket (sock)
36690 * has the protocol module (sock->ops->owner) held.
36691 @@ -1448,6 +1495,7 @@ asmlinkage long sys_accept(int fd, struc
36694 security_socket_post_accept(sock, newsock);
36695 + gr_attach_curr_ip(newsock->sk);
36698 fput_light(sock->file, fput_needed);
36699 @@ -1481,6 +1529,7 @@ asmlinkage long sys_connect(int fd, stru
36701 struct socket *sock;
36702 char address[MAX_SOCK_ADDR];
36703 + struct sockaddr *sck;
36704 int err, fput_needed;
36706 sock = sockfd_lookup_light(fd, &err, &fput_needed);
36707 @@ -1490,6 +1539,13 @@ asmlinkage long sys_connect(int fd, stru
36711 + sck = (struct sockaddr *)address;
36712 + if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
36713 + gr_handle_sock_client(sck)) {
36719 security_socket_connect(sock, (struct sockaddr *)address, addrlen);
36721 @@ -1767,6 +1823,7 @@ asmlinkage long sys_shutdown(int fd, int
36722 err = sock->ops->shutdown(sock, how);
36723 fput_light(sock->file, fput_needed);
36729 diff -urNp linux-2.6.24.4/net/unix/af_unix.c linux-2.6.24.4/net/unix/af_unix.c
36730 --- linux-2.6.24.4/net/unix/af_unix.c 2008-03-24 14:49:18.000000000 -0400
36731 +++ linux-2.6.24.4/net/unix/af_unix.c 2008-03-26 20:21:09.000000000 -0400
36732 @@ -116,6 +116,7 @@
36733 #include <linux/security.h>
36734 #include <linux/vs_context.h>
36735 #include <linux/vs_limit.h>
36736 +#include <linux/grsecurity.h>
36738 int sysctl_unix_max_dgram_qlen __read_mostly = 10;
36740 @@ -738,6 +739,11 @@ static struct sock *unix_find_other(stru
36744 + if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
36749 err = -ECONNREFUSED;
36750 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
36752 @@ -761,6 +767,13 @@ static struct sock *unix_find_other(stru
36754 struct dentry *dentry;
36755 dentry = unix_sk(u)->dentry;
36757 + if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
36764 touch_atime(unix_sk(u)->mnt, dentry);
36766 @@ -839,9 +852,18 @@ static int unix_bind(struct socket *sock
36769 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
36771 + if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
36773 + goto out_mknod_dput;
36776 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
36778 goto out_mknod_dput;
36780 + gr_handle_create(dentry, nd.mnt);
36782 mutex_unlock(&nd.dentry->d_inode->i_mutex);
36784 nd.dentry = dentry;
36785 @@ -859,6 +881,10 @@ static int unix_bind(struct socket *sock
36789 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
36790 + sk->sk_peercred.pid = current->pid;
36793 list = &unix_socket_table[addr->hash];
36795 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
36796 diff -urNp linux-2.6.24.4/scripts/pnmtologo.c linux-2.6.24.4/scripts/pnmtologo.c
36797 --- linux-2.6.24.4/scripts/pnmtologo.c 2008-03-24 14:49:18.000000000 -0400
36798 +++ linux-2.6.24.4/scripts/pnmtologo.c 2008-03-26 20:21:09.000000000 -0400
36799 @@ -237,14 +237,14 @@ static void write_header(void)
36800 fprintf(out, " * Linux logo %s\n", logoname);
36801 fputs(" */\n\n", out);
36802 fputs("#include <linux/linux_logo.h>\n\n", out);
36803 - fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
36804 + fprintf(out, "static unsigned char %s_data[] = {\n",
36808 static void write_footer(void)
36810 fputs("\n};\n\n", out);
36811 - fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
36812 + fprintf(out, "struct linux_logo %s = {\n", logoname);
36813 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
36814 fprintf(out, " .width\t= %d,\n", logo_width);
36815 fprintf(out, " .height\t= %d,\n", logo_height);
36816 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
36817 fputs("\n};\n\n", out);
36819 /* write logo clut */
36820 - fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
36821 + fprintf(out, "static unsigned char %s_clut[] = {\n",
36824 for (i = 0; i < logo_clutsize; i++) {
36825 diff -urNp linux-2.6.24.4/security/commoncap.c linux-2.6.24.4/security/commoncap.c
36826 --- linux-2.6.24.4/security/commoncap.c 2008-03-24 14:49:18.000000000 -0400
36827 +++ linux-2.6.24.4/security/commoncap.c 2008-03-26 20:21:09.000000000 -0400
36829 #include <linux/mount.h>
36830 #include <linux/sched.h>
36831 #include <linux/vs_context.h>
36832 +#include <linux/grsecurity.h>
36834 #ifdef CONFIG_SECURITY_FILE_CAPABILITIES
36836 @@ -44,9 +45,11 @@ EXPORT_SYMBOL(cap_bset);
36837 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
36838 EXPORT_SYMBOL(securebits);
36840 +extern __u32 gr_cap_rtnetlink(struct sock *sk);
36842 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
36844 - cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
36845 + cap_t(NETLINK_CB(skb).eff_cap) = gr_cap_rtnetlink(sk);
36849 @@ -68,7 +71,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
36850 int cap_capable (struct task_struct *tsk, int cap)
36852 /* Derived from include/linux/sched.h:capable. */
36853 - if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
36854 + if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
36859 +int cap_capable_nolog (struct task_struct *tsk, int cap)
36861 + /* tsk = current for all callers */
36862 + if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
36866 @@ -343,8 +354,11 @@ void cap_bprm_apply_creds (struct linux_
36870 - current->suid = current->euid = current->fsuid = bprm->e_uid;
36871 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
36872 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
36873 + current->suid = current->euid = current->fsuid = bprm->e_uid;
36875 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
36876 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
36878 /* For init, we want to retain the capabilities set
36879 * in the init_task struct. Thus we skip the usual
36880 @@ -355,6 +369,8 @@ void cap_bprm_apply_creds (struct linux_
36884 + gr_handle_chroot_caps(current);
36886 /* AUD: Audit candidate if current->cap_effective is set */
36888 current->keep_capabilities = 0;
36889 @@ -602,7 +618,7 @@ int cap_vm_enough_memory(struct mm_struc
36891 int cap_sys_admin = 0;
36893 - if (cap_capable(current, CAP_SYS_ADMIN) == 0)
36894 + if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
36896 return __vm_enough_memory(mm, pages, cap_sys_admin);
36898 diff -urNp linux-2.6.24.4/security/dummy.c linux-2.6.24.4/security/dummy.c
36899 --- linux-2.6.24.4/security/dummy.c 2008-03-24 14:49:18.000000000 -0400
36900 +++ linux-2.6.24.4/security/dummy.c 2008-03-26 20:21:09.000000000 -0400
36902 #include <linux/ptrace.h>
36903 #include <linux/file.h>
36904 #include <linux/vs_context.h>
36905 +#include <linux/grsecurity.h>
36907 static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
36909 @@ -135,8 +136,11 @@ static void dummy_bprm_apply_creds (stru
36913 - current->suid = current->euid = current->fsuid = bprm->e_uid;
36914 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
36915 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
36916 + current->suid = current->euid = current->fsuid = bprm->e_uid;
36918 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
36919 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
36921 dummy_capget(current, ¤t->cap_effective, ¤t->cap_inheritable, ¤t->cap_permitted);
36923 diff -urNp linux-2.6.24.4/security/Kconfig linux-2.6.24.4/security/Kconfig
36924 --- linux-2.6.24.4/security/Kconfig 2008-03-24 14:49:18.000000000 -0400
36925 +++ linux-2.6.24.4/security/Kconfig 2008-03-26 20:21:09.000000000 -0400
36928 menu "Security options"
36930 +source grsecurity/Kconfig
36935 + bool "Enable various PaX features"
36936 + depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
36938 + This allows you to enable various PaX features. PaX adds
36939 + intrusion prevention mechanisms to the kernel that reduce
36940 + the risks posed by exploitable memory corruption bugs.
36942 +menu "PaX Control"
36945 +config PAX_SOFTMODE
36946 + bool 'Support soft mode'
36948 + Enabling this option will allow you to run PaX in soft mode, that
36949 + is, PaX features will not be enforced by default, only on executables
36950 + marked explicitly. You must also enable PT_PAX_FLAGS support as it
36951 + is the only way to mark executables for soft mode use.
36953 + Soft mode can be activated by using the "pax_softmode=1" kernel command
36954 + line option on boot. Furthermore you can control various PaX features
36955 + at runtime via the entries in /proc/sys/kernel/pax.
36958 + bool 'Use legacy ELF header marking'
36960 + Enabling this option will allow you to control PaX features on
36961 + a per executable basis via the 'chpax' utility available at
36962 + http://pax.grsecurity.net/. The control flags will be read from
36963 + an otherwise reserved part of the ELF header. This marking has
36964 + numerous drawbacks (no support for soft-mode, toolchain does not
36965 + know about the non-standard use of the ELF header) therefore it
36966 + has been deprecated in favour of PT_PAX_FLAGS support.
36968 + If you have applications not marked by the PT_PAX_FLAGS ELF
36969 + program header then you MUST enable this option otherwise they
36970 + will not get any protection.
36972 + Note that if you enable PT_PAX_FLAGS marking support as well,
36973 + the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
36975 +config PAX_PT_PAX_FLAGS
36976 + bool 'Use ELF program header marking'
36978 + Enabling this option will allow you to control PaX features on
36979 + a per executable basis via the 'paxctl' utility available at
36980 + http://pax.grsecurity.net/. The control flags will be read from
36981 + a PaX specific ELF program header (PT_PAX_FLAGS). This marking
36982 + has the benefits of supporting both soft mode and being fully
36983 + integrated into the toolchain (the binutils patch is available
36984 + from http://pax.grsecurity.net).
36986 + If you have applications not marked by the PT_PAX_FLAGS ELF
36987 + program header then you MUST enable the EI_PAX marking support
36988 + otherwise they will not get any protection.
36990 + Note that if you enable the legacy EI_PAX marking support as well,
36991 + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
36994 + prompt 'MAC system integration'
36995 + default PAX_HAVE_ACL_FLAGS
36997 + Mandatory Access Control systems have the option of controlling
36998 + PaX flags on a per executable basis, choose the method supported
36999 + by your particular system.
37001 + - "none": if your MAC system does not interact with PaX,
37002 + - "direct": if your MAC system defines pax_set_initial_flags() itself,
37003 + - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
37005 + NOTE: this option is for developers/integrators only.
37007 + config PAX_NO_ACL_FLAGS
37010 + config PAX_HAVE_ACL_FLAGS
37013 + config PAX_HOOK_ACL_FLAGS
37019 +menu "Non-executable pages"
37023 + bool "Enforce non-executable pages"
37024 + 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 || X86_64)
37026 + By design some architectures do not allow for protecting memory
37027 + pages against execution or even if they do, Linux does not make
37028 + use of this feature. In practice this means that if a page is
37029 + readable (such as the stack or heap) it is also executable.
37031 + There is a well known exploit technique that makes use of this
37032 + fact and a common programming mistake where an attacker can
37033 + introduce code of his choice somewhere in the attacked program's
37034 + memory (typically the stack or the heap) and then execute it.
37036 + If the attacked program was running with different (typically
37037 + higher) privileges than that of the attacker, then he can elevate
37038 + his own privilege level (e.g. get a root shell, write to files for
37039 + which he does not have write access to, etc).
37041 + Enabling this option will let you choose from various features
37042 + that prevent the injection and execution of 'foreign' code in
37045 + This will also break programs that rely on the old behaviour and
37046 + expect that dynamically allocated memory via the malloc() family
37047 + of functions is executable (which it is not). Notable examples
37048 + are the XFree86 4.x server, the java runtime and wine.
37050 +config PAX_PAGEEXEC
37051 + bool "Paging based non-executable pages"
37052 + depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
37054 + This implementation is based on the paging feature of the CPU.
37055 + On i386 without hardware non-executable bit support there is a
37056 + variable but usually low performance impact, however on Intel's
37057 + P4 core based CPUs it is very high so you should not enable this
37058 + for kernels meant to be used on such CPUs.
37060 + On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
37061 + with hardware non-executable bit support there is no performance
37062 + impact, on ppc the impact is negligible.
37064 + Note that several architectures require various emulations due to
37065 + badly designed userland ABIs, this will cause a performance impact
37066 + but will disappear as soon as userland is fixed (e.g., ppc users
37067 + can make use of the secure-plt feature found in binutils).
37069 +config PAX_SEGMEXEC
37070 + bool "Segmentation based non-executable pages"
37071 + depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
37073 + This implementation is based on the segmentation feature of the
37074 + CPU and has a very small performance impact, however applications
37075 + will be limited to a 1.5 GB address space instead of the normal
37078 +config PAX_EMUTRAMP
37079 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
37080 + default y if PARISC || PPC32
37082 + There are some programs and libraries that for one reason or
37083 + another attempt to execute special small code snippets from
37084 + non-executable memory pages. Most notable examples are the
37085 + signal handler return code generated by the kernel itself and
37086 + the GCC trampolines.
37088 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
37089 + such programs will no longer work under your kernel.
37091 + As a remedy you can say Y here and use the 'chpax' or 'paxctl'
37092 + utilities to enable trampoline emulation for the affected programs
37093 + yet still have the protection provided by the non-executable pages.
37095 + On parisc and ppc you MUST enable this option and EMUSIGRT as
37096 + well, otherwise your system will not even boot.
37098 + Alternatively you can say N here and use the 'chpax' or 'paxctl'
37099 + utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
37100 + for the affected files.
37102 + NOTE: enabling this feature *may* open up a loophole in the
37103 + protection provided by non-executable pages that an attacker
37104 + could abuse. Therefore the best solution is to not have any
37105 + files on your system that would require this option. This can
37106 + be achieved by not using libc5 (which relies on the kernel
37107 + signal handler return code) and not using or rewriting programs
37108 + that make use of the nested function implementation of GCC.
37109 + Skilled users can just fix GCC itself so that it implements
37110 + nested function calls in a way that does not interfere with PaX.
37112 +config PAX_EMUSIGRT
37113 + bool "Automatically emulate sigreturn trampolines"
37114 + depends on PAX_EMUTRAMP && (PARISC || PPC32)
37117 + Enabling this option will have the kernel automatically detect
37118 + and emulate signal return trampolines executing on the stack
37119 + that would otherwise lead to task termination.
37121 + This solution is intended as a temporary one for users with
37122 + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
37123 + Modula-3 runtime, etc) or executables linked to such, basically
37124 + everything that does not specify its own SA_RESTORER function in
37125 + normal executable memory like glibc 2.1+ does.
37127 + On parisc and ppc you MUST enable this option, otherwise your
37128 + system will not even boot.
37130 + NOTE: this feature cannot be disabled on a per executable basis
37131 + and since it *does* open up a loophole in the protection provided
37132 + by non-executable pages, the best solution is to not have any
37133 + files on your system that would require this option.
37135 +config PAX_MPROTECT
37136 + bool "Restrict mprotect()"
37137 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
37139 + Enabling this option will prevent programs from
37140 + - changing the executable status of memory pages that were
37141 + not originally created as executable,
37142 + - making read-only executable pages writable again,
37143 + - creating executable pages from anonymous memory.
37145 + You should say Y here to complete the protection provided by
37146 + the enforcement of non-executable pages.
37148 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
37149 + this feature on a per file basis.
37151 +config PAX_NOELFRELOCS
37152 + bool "Disallow ELF text relocations"
37153 + depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
37155 + Non-executable pages and mprotect() restrictions are effective
37156 + in preventing the introduction of new executable code into an
37157 + attacked task's address space. There remain only two venues
37158 + for this kind of attack: if the attacker can execute already
37159 + existing code in the attacked task then he can either have it
37160 + create and mmap() a file containing his code or have it mmap()
37161 + an already existing ELF library that does not have position
37162 + independent code in it and use mprotect() on it to make it
37163 + writable and copy his code there. While protecting against
37164 + the former approach is beyond PaX, the latter can be prevented
37165 + by having only PIC ELF libraries on one's system (which do not
37166 + need to relocate their code). If you are sure this is your case,
37167 + then enable this option otherwise be careful as you may not even
37168 + be able to boot or log on your system (for example, some PAM
37169 + modules are erroneously compiled as non-PIC by default).
37171 + NOTE: if you are using dynamic ELF executables (as suggested
37172 + when using ASLR) then you must have made sure that you linked
37173 + your files using the PIC version of crt1 (the et_dyn.tar.gz package
37174 + referenced there has already been updated to support this).
37176 +config PAX_ETEXECRELOCS
37177 + bool "Allow ELF ET_EXEC text relocations"
37178 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
37181 + On some architectures there are incorrectly created applications
37182 + that require text relocations and would not work without enabling
37183 + this option. If you are an alpha, ia64 or parisc user, you should
37184 + enable this option and disable it once you have made sure that
37185 + none of your applications need it.
37188 + bool "Automatically emulate ELF PLT"
37189 + depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
37192 + Enabling this option will have the kernel automatically detect
37193 + and emulate the Procedure Linkage Table entries in ELF files.
37194 + On some architectures such entries are in writable memory, and
37195 + become non-executable leading to task termination. Therefore
37196 + it is mandatory that you enable this option on alpha, parisc,
37197 + ppc (if secure-plt is not used throughout in userland), sparc
37198 + and sparc64, otherwise your system would not even boot.
37200 + NOTE: this feature *does* open up a loophole in the protection
37201 + provided by the non-executable pages, therefore the proper
37202 + solution is to modify the toolchain to produce a PLT that does
37203 + not need to be writable.
37205 +config PAX_DLRESOLVE
37207 + depends on PAX_EMUPLT && (SPARC32 || SPARC64)
37210 +config PAX_SYSCALL
37212 + depends on PAX_PAGEEXEC && PPC32
37215 +config PAX_KERNEXEC
37216 + bool "Enforce non-executable kernel pages"
37217 + depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
37219 + This is the kernel land equivalent of PAGEEXEC and MPROTECT,
37220 + that is, enabling this option will make it harder to inject
37221 + and execute 'foreign' code in kernel memory itself.
37225 +menu "Address Space Layout Randomization"
37229 + bool "Address Space Layout Randomization"
37230 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
37232 + Many if not most exploit techniques rely on the knowledge of
37233 + certain addresses in the attacked program. The following options
37234 + will allow the kernel to apply a certain amount of randomization
37235 + to specific parts of the program thereby forcing an attacker to
37236 + guess them in most cases. Any failed guess will most likely crash
37237 + the attacked program which allows the kernel to detect such attempts
37238 + and react on them. PaX itself provides no reaction mechanisms,
37239 + instead it is strongly encouraged that you make use of Nergal's
37240 + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
37241 + (http://www.grsecurity.net/) built-in crash detection features or
37242 + develop one yourself.
37244 + By saying Y here you can choose to randomize the following areas:
37245 + - top of the task's kernel stack
37246 + - top of the task's userland stack
37247 + - base address for mmap() requests that do not specify one
37248 + (this includes all libraries)
37249 + - base address of the main executable
37251 + It is strongly recommended to say Y here as address space layout
37252 + randomization has negligible impact on performance yet it provides
37253 + a very effective protection.
37255 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
37256 + this feature on a per file basis.
37258 +config PAX_RANDKSTACK
37259 + bool "Randomize kernel stack base"
37260 + depends on PAX_ASLR && X86_TSC && X86_32
37262 + By saying Y here the kernel will randomize every task's kernel
37263 + stack on every system call. This will not only force an attacker
37264 + to guess it but also prevent him from making use of possible
37265 + leaked information about it.
37267 + Since the kernel stack is a rather scarce resource, randomization
37268 + may cause unexpected stack overflows, therefore you should very
37269 + carefully test your system. Note that once enabled in the kernel
37270 + configuration, this feature cannot be disabled on a per file basis.
37272 +config PAX_RANDUSTACK
37273 + bool "Randomize user stack base"
37274 + depends on PAX_ASLR
37276 + By saying Y here the kernel will randomize every task's userland
37277 + stack. The randomization is done in two steps where the second
37278 + one may apply a big amount of shift to the top of the stack and
37279 + cause problems for programs that want to use lots of memory (more
37280 + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
37281 + For this reason the second step can be controlled by 'chpax' or
37282 + 'paxctl' on a per file basis.
37284 +config PAX_RANDMMAP
37285 + bool "Randomize mmap() base"
37286 + depends on PAX_ASLR
37288 + By saying Y here the kernel will use a randomized base address for
37289 + mmap() requests that do not specify one themselves. As a result
37290 + all dynamically loaded libraries will appear at random addresses
37291 + and therefore be harder to exploit by a technique where an attacker
37292 + attempts to execute library code for his purposes (e.g. spawn a
37293 + shell from an exploited program that is running at an elevated
37294 + privilege level).
37296 + Furthermore, if a program is relinked as a dynamic ELF file, its
37297 + base address will be randomized as well, completing the full
37298 + randomization of the address space layout. Attacking such programs
37299 + becomes a guess game. You can find an example of doing this at
37300 + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
37301 + http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
37303 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
37304 + feature on a per file basis.
37308 +menu "Miscellaneous hardening features"
37310 +config PAX_MEMORY_SANITIZE
37311 + bool "Sanitize all freed memory"
37313 + By saying Y here the kernel will erase memory pages as soon as they
37314 + are freed. This in turn reduces the lifetime of data stored in the
37315 + pages, making it less likely that sensitive information such as
37316 + passwords, cryptographic secrets, etc stay in memory for too long.
37318 + This is especially useful for programs whose runtime is short, long
37319 + lived processes and the kernel itself benefit from this as long as
37320 + they operate on whole memory pages and ensure timely freeing of pages
37321 + that may hold sensitive information.
37323 + The tradeoff is performance impact, on a single CPU system kernel
37324 + compilation sees a 3% slowdown, other systems and workloads may vary
37325 + and you are advised to test this feature on your expected workload
37326 + before deploying it.
37328 + Note that this feature does not protect data stored in live pages,
37329 + e.g., process memory swapped to disk may stay there for a long time.
37331 +config PAX_MEMORY_UDEREF
37332 + bool "Prevent invalid userland pointer dereference"
37333 + depends on X86_32 && !COMPAT_VDSO
37335 + By saying Y here the kernel will be prevented from dereferencing
37336 + userland pointers in contexts where the kernel expects only kernel
37337 + pointers. This is both a useful runtime debugging feature and a
37338 + security measure that prevents exploiting a class of kernel bugs.
37340 + The tradeoff is that some virtualization solutions may experience
37341 + a huge slowdown and therefore you should not enable this feature
37342 + for kernels meant to run in such environments. Whether a given VM
37343 + solution is affected or not is best determined by simply trying it
37344 + out, the performance impact will be obvious right on boot as this
37345 + mechanism engages from very early on. A good rule of thumb is that
37346 + VMs running on CPUs without hardware virtualization support (i.e.,
37347 + the majority of IA-32 CPUs) will likely experience the slowdown.
37354 bool "Enable access key retention support"
37356 diff -urNp linux-2.6.24.4/sound/core/oss/pcm_oss.c linux-2.6.24.4/sound/core/oss/pcm_oss.c
37357 --- linux-2.6.24.4/sound/core/oss/pcm_oss.c 2008-03-24 14:49:18.000000000 -0400
37358 +++ linux-2.6.24.4/sound/core/oss/pcm_oss.c 2008-03-26 20:21:09.000000000 -0400
37359 @@ -2913,8 +2913,8 @@ static void snd_pcm_oss_proc_done(struct
37362 #else /* !CONFIG_SND_VERBOSE_PROCFS */
37363 -#define snd_pcm_oss_proc_init(pcm)
37364 -#define snd_pcm_oss_proc_done(pcm)
37365 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
37366 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
37367 #endif /* CONFIG_SND_VERBOSE_PROCFS */
37370 diff -urNp linux-2.6.24.4/sound/core/seq/seq_lock.h linux-2.6.24.4/sound/core/seq/seq_lock.h
37371 --- linux-2.6.24.4/sound/core/seq/seq_lock.h 2008-03-24 14:49:18.000000000 -0400
37372 +++ linux-2.6.24.4/sound/core/seq/seq_lock.h 2008-03-26 20:21:09.000000000 -0400
37373 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
37374 #else /* SMP || CONFIG_SND_DEBUG */
37376 typedef spinlock_t snd_use_lock_t; /* dummy */
37377 -#define snd_use_lock_init(lockp) /**/
37378 -#define snd_use_lock_use(lockp) /**/
37379 -#define snd_use_lock_free(lockp) /**/
37380 -#define snd_use_lock_sync(lockp) /**/
37381 +#define snd_use_lock_init(lockp) do {} while (0)
37382 +#define snd_use_lock_use(lockp) do {} while (0)
37383 +#define snd_use_lock_free(lockp) do {} while (0)
37384 +#define snd_use_lock_sync(lockp) do {} while (0)
37386 #endif /* SMP || CONFIG_SND_DEBUG */
37388 diff -urNp linux-2.6.24.4/sound/pci/ac97/ac97_patch.c linux-2.6.24.4/sound/pci/ac97/ac97_patch.c
37389 --- linux-2.6.24.4/sound/pci/ac97/ac97_patch.c 2008-03-24 14:49:18.000000000 -0400
37390 +++ linux-2.6.24.4/sound/pci/ac97/ac97_patch.c 2008-03-26 20:21:09.000000000 -0400
37391 @@ -1478,7 +1478,7 @@ static const struct snd_ac97_res_table a
37392 { AC97_VIDEO, 0x9f1f },
37393 { AC97_AUX, 0x9f1f },
37394 { AC97_PCM, 0x9f1f },
37395 - { } /* terminator */
37396 + { 0, 0 } /* terminator */
37399 static int patch_ad1819(struct snd_ac97 * ac97)
37400 @@ -3537,7 +3537,7 @@ static struct snd_ac97_res_table lm4550_
37401 { AC97_AUX, 0x1f1f },
37402 { AC97_PCM, 0x1f1f },
37403 { AC97_REC_GAIN, 0x0f0f },
37404 - { } /* terminator */
37405 + { 0, 0 } /* terminator */
37408 static int patch_lm4550(struct snd_ac97 *ac97)
37409 diff -urNp linux-2.6.24.4/sound/pci/ens1370.c linux-2.6.24.4/sound/pci/ens1370.c
37410 --- linux-2.6.24.4/sound/pci/ens1370.c 2008-03-24 14:49:18.000000000 -0400
37411 +++ linux-2.6.24.4/sound/pci/ens1370.c 2008-03-26 20:21:09.000000000 -0400
37412 @@ -453,7 +453,7 @@ static struct pci_device_id snd_audiopci
37413 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
37414 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
37417 + { 0, 0, 0, 0, 0, 0, 0 }
37420 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
37421 diff -urNp linux-2.6.24.4/sound/pci/intel8x0.c linux-2.6.24.4/sound/pci/intel8x0.c
37422 --- linux-2.6.24.4/sound/pci/intel8x0.c 2008-03-24 14:49:18.000000000 -0400
37423 +++ linux-2.6.24.4/sound/pci/intel8x0.c 2008-03-26 20:21:09.000000000 -0400
37424 @@ -436,7 +436,7 @@ static struct pci_device_id snd_intel8x0
37425 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37426 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
37427 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37429 + { 0, 0, 0, 0, 0, 0, 0 }
37432 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
37433 @@ -2044,7 +2044,7 @@ static struct ac97_quirk ac97_quirks[] _
37434 .type = AC97_TUNE_HP_ONLY
37437 - { } /* terminator */
37438 + { 0, 0, 0, 0, NULL, 0 } /* terminator */
37441 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
37442 diff -urNp linux-2.6.24.4/sound/pci/intel8x0m.c linux-2.6.24.4/sound/pci/intel8x0m.c
37443 --- linux-2.6.24.4/sound/pci/intel8x0m.c 2008-03-24 14:49:18.000000000 -0400
37444 +++ linux-2.6.24.4/sound/pci/intel8x0m.c 2008-03-26 20:21:09.000000000 -0400
37445 @@ -240,7 +240,7 @@ static struct pci_device_id snd_intel8x0
37446 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37447 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37450 + { 0, 0, 0, 0, 0, 0, 0 }
37453 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
37454 @@ -1261,7 +1261,7 @@ static struct shortname_table {
37455 { 0x5455, "ALi M5455" },
37456 { 0x746d, "AMD AMD8111" },
37462 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,