1 diff -urNp linux-2.6.27.4/arch/alpha/kernel/module.c linux-2.6.27.4/arch/alpha/kernel/module.c
2 --- linux-2.6.27.4/arch/alpha/kernel/module.c 2008-10-22 17:38:01.000000000 -0400
3 +++ linux-2.6.27.4/arch/alpha/kernel/module.c 2008-10-27 22:36:16.000000000 -0400
4 @@ -182,7 +182,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.27.4/arch/alpha/kernel/osf_sys.c linux-2.6.27.4/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.27.4/arch/alpha/kernel/osf_sys.c 2008-10-22 17:38:01.000000000 -0400
15 +++ linux-2.6.27.4/arch/alpha/kernel/osf_sys.c 2008-10-27 22:36:16.000000000 -0400
16 @@ -1232,6 +1232,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 @@ -1239,8 +1243,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.27.4/arch/alpha/kernel/ptrace.c linux-2.6.27.4/arch/alpha/kernel/ptrace.c
39 --- linux-2.6.27.4/arch/alpha/kernel/ptrace.c 2008-10-22 17:38:01.000000000 -0400
40 +++ linux-2.6.27.4/arch/alpha/kernel/ptrace.c 2008-10-25 12:03:06.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.27.4/arch/alpha/mm/fault.c linux-2.6.27.4/arch/alpha/mm/fault.c
60 --- linux-2.6.27.4/arch/alpha/mm/fault.c 2008-10-22 17:38:01.000000000 -0400
61 +++ linux-2.6.27.4/arch/alpha/mm/fault.c 2008-10-27 22:36:16.000000000 -0400
62 @@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
66 +#ifdef CONFIG_PAX_PAGEEXEC
68 + * PaX: decide what to do with offenders (regs->pc = fault address)
70 + * returns 1 when task should be killed
71 + * 2 when patched PLT trampoline was detected
72 + * 3 when unpatched PLT trampoline was detected
74 +static int pax_handle_fetch_fault(struct pt_regs *regs)
77 +#ifdef CONFIG_PAX_EMUPLT
80 + do { /* PaX: patched PLT emulation #1 */
81 + unsigned int ldah, ldq, jmp;
83 + err = get_user(ldah, (unsigned int *)regs->pc);
84 + err |= get_user(ldq, (unsigned int *)(regs->pc+4));
85 + err |= get_user(jmp, (unsigned int *)(regs->pc+8));
90 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
91 + (ldq & 0xFFFF0000U) == 0xA77B0000U &&
94 + unsigned long r27, addr;
95 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
96 + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
98 + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
99 + err = get_user(r27, (unsigned long *)addr);
109 + do { /* PaX: patched PLT emulation #2 */
110 + unsigned int ldah, lda, br;
112 + err = get_user(ldah, (unsigned int *)regs->pc);
113 + err |= get_user(lda, (unsigned int *)(regs->pc+4));
114 + err |= get_user(br, (unsigned int *)(regs->pc+8));
119 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
120 + (lda & 0xFFFF0000U) == 0xA77B0000U &&
121 + (br & 0xFFE00000U) == 0xC3E00000U)
123 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
124 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
125 + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
127 + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
128 + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
133 + do { /* PaX: unpatched PLT emulation */
136 + err = get_user(br, (unsigned int *)regs->pc);
138 + if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
139 + unsigned int br2, ldq, nop, jmp;
140 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
142 + addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
143 + err = get_user(br2, (unsigned int *)addr);
144 + err |= get_user(ldq, (unsigned int *)(addr+4));
145 + err |= get_user(nop, (unsigned int *)(addr+8));
146 + err |= get_user(jmp, (unsigned int *)(addr+12));
147 + err |= get_user(resolver, (unsigned long *)(addr+16));
152 + if (br2 == 0xC3600000U &&
153 + ldq == 0xA77B000CU &&
154 + nop == 0x47FF041FU &&
155 + jmp == 0x6B7B0000U)
157 + regs->r28 = regs->pc+4;
158 + regs->r27 = addr+16;
159 + regs->pc = resolver;
169 +void pax_report_insns(void *pc, void *sp)
173 + printk(KERN_ERR "PAX: bytes at PC: ");
174 + for (i = 0; i < 5; i++) {
176 + if (get_user(c, (unsigned int *)pc+i))
177 + printk(KERN_CONT "???????? ");
179 + printk(KERN_CONT "%08x ", c);
186 * This routine handles page faults. It determines the address,
187 @@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
189 si_code = SEGV_ACCERR;
191 - if (!(vma->vm_flags & VM_EXEC))
192 + if (!(vma->vm_flags & VM_EXEC)) {
194 +#ifdef CONFIG_PAX_PAGEEXEC
195 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
198 + up_read(&mm->mmap_sem);
199 + switch (pax_handle_fetch_fault(regs)) {
201 +#ifdef CONFIG_PAX_EMUPLT
208 + pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
209 + do_group_exit(SIGKILL);
216 /* Allow reads even for write-only mappings */
217 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
218 diff -urNp linux-2.6.27.4/arch/arm/mm/mmap.c linux-2.6.27.4/arch/arm/mm/mmap.c
219 --- linux-2.6.27.4/arch/arm/mm/mmap.c 2008-10-22 17:38:01.000000000 -0400
220 +++ linux-2.6.27.4/arch/arm/mm/mmap.c 2008-10-27 22:36:16.000000000 -0400
221 @@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
225 +#ifdef CONFIG_PAX_RANDMMAP
226 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
231 addr = COLOUR_ALIGN(addr, pgoff);
232 @@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
235 if (len > mm->cached_hole_size) {
236 - start_addr = addr = mm->free_area_cache;
237 + start_addr = addr = mm->free_area_cache;
239 - start_addr = addr = TASK_UNMAPPED_BASE;
240 - mm->cached_hole_size = 0;
241 + start_addr = addr = mm->mmap_base;
242 + mm->cached_hole_size = 0;
246 @@ -91,8 +95,8 @@ full_search:
247 * Start a new search - just in case we missed
250 - if (start_addr != TASK_UNMAPPED_BASE) {
251 - start_addr = addr = TASK_UNMAPPED_BASE;
252 + if (start_addr != mm->mmap_base) {
253 + start_addr = addr = mm->mmap_base;
254 mm->cached_hole_size = 0;
257 diff -urNp linux-2.6.27.4/arch/avr32/mm/fault.c linux-2.6.27.4/arch/avr32/mm/fault.c
258 --- linux-2.6.27.4/arch/avr32/mm/fault.c 2008-10-22 17:38:01.000000000 -0400
259 +++ linux-2.6.27.4/arch/avr32/mm/fault.c 2008-10-27 22:36:16.000000000 -0400
260 @@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
262 int exception_trace = 1;
264 +#ifdef CONFIG_PAX_PAGEEXEC
265 +void pax_report_insns(void *pc, void *sp)
269 + printk(KERN_ERR "PAX: bytes at PC: ");
270 + for (i = 0; i < 20; i++) {
272 + if (get_user(c, (unsigned char *)pc+i))
273 + printk(KERN_CONT "???????? ");
275 + printk(KERN_CONT "%02x ", c);
282 * This routine handles page faults. It determines the address and the
283 * problem, and then passes it off to one of the appropriate routines.
284 @@ -157,6 +174,16 @@ bad_area:
285 up_read(&mm->mmap_sem);
287 if (user_mode(regs)) {
289 +#ifdef CONFIG_PAX_PAGEEXEC
290 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
291 + if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
292 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
293 + do_group_exit(SIGKILL);
298 if (exception_trace && printk_ratelimit())
299 printk("%s%s[%d]: segfault at %08lx pc %08lx "
300 "sp %08lx ecr %lu\n",
301 diff -urNp linux-2.6.27.4/arch/ia64/ia32/binfmt_elf32.c linux-2.6.27.4/arch/ia64/ia32/binfmt_elf32.c
302 --- linux-2.6.27.4/arch/ia64/ia32/binfmt_elf32.c 2008-10-22 17:38:01.000000000 -0400
303 +++ linux-2.6.27.4/arch/ia64/ia32/binfmt_elf32.c 2008-10-27 22:36:16.000000000 -0400
304 @@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
306 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
308 +#ifdef CONFIG_PAX_ASLR
309 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
311 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
312 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
315 /* Ugly but avoids duplication */
316 #include "../../../fs/binfmt_elf.c"
318 diff -urNp linux-2.6.27.4/arch/ia64/ia32/ia32priv.h linux-2.6.27.4/arch/ia64/ia32/ia32priv.h
319 --- linux-2.6.27.4/arch/ia64/ia32/ia32priv.h 2008-10-22 17:38:01.000000000 -0400
320 +++ linux-2.6.27.4/arch/ia64/ia32/ia32priv.h 2008-10-27 22:36:16.000000000 -0400
321 @@ -296,7 +296,14 @@ typedef struct compat_siginfo {
322 #define ELF_DATA ELFDATA2LSB
323 #define ELF_ARCH EM_386
325 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
326 +#ifdef CONFIG_PAX_RANDUSTACK
327 +#define __IA32_DELTA_STACK (current->mm->delta_stack)
329 +#define __IA32_DELTA_STACK 0UL
332 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
334 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
335 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
337 diff -urNp linux-2.6.27.4/arch/ia64/kernel/module.c linux-2.6.27.4/arch/ia64/kernel/module.c
338 --- linux-2.6.27.4/arch/ia64/kernel/module.c 2008-10-22 17:38:01.000000000 -0400
339 +++ linux-2.6.27.4/arch/ia64/kernel/module.c 2008-10-27 22:36:16.000000000 -0400
340 @@ -312,8 +312,7 @@ module_alloc (unsigned long size)
342 module_free (struct module *mod, void *module_region)
344 - if (mod && mod->arch.init_unw_table &&
345 - module_region == mod->module_init) {
346 + if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
347 unw_remove_unwind_table(mod->arch.init_unw_table);
348 mod->arch.init_unw_table = NULL;
350 @@ -491,15 +490,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
354 +in_init_rx (const struct module *mod, uint64_t addr)
356 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
360 +in_init_rw (const struct module *mod, uint64_t addr)
362 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
366 in_init (const struct module *mod, uint64_t addr)
368 - return addr - (uint64_t) mod->module_init < mod->init_size;
369 + return in_init_rx(mod, addr) || in_init_rw(mod, addr);
373 +in_core_rx (const struct module *mod, uint64_t addr)
375 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
379 +in_core_rw (const struct module *mod, uint64_t addr)
381 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
385 in_core (const struct module *mod, uint64_t addr)
387 - return addr - (uint64_t) mod->module_core < mod->core_size;
388 + return in_core_rx(mod, addr) || in_core_rw(mod, addr);
392 @@ -683,7 +706,14 @@ do_reloc (struct module *mod, uint8_t r_
396 - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
397 + if (in_init_rx(mod, val))
398 + val -= (uint64_t) mod->module_init_rx;
399 + else if (in_init_rw(mod, val))
400 + val -= (uint64_t) mod->module_init_rw;
401 + else if (in_core_rx(mod, val))
402 + val -= (uint64_t) mod->module_core_rx;
403 + else if (in_core_rw(mod, val))
404 + val -= (uint64_t) mod->module_core_rw;
408 @@ -817,15 +847,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
409 * addresses have been selected...
412 - if (mod->core_size > MAX_LTOFF)
413 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
415 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
416 * at the end of the module.
418 - gp = mod->core_size - MAX_LTOFF / 2;
419 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
421 - gp = mod->core_size / 2;
422 - gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
423 + gp = (mod->core_size_rx + mod->core_size_rw) / 2;
424 + gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
426 DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
428 diff -urNp linux-2.6.27.4/arch/ia64/kernel/sys_ia64.c linux-2.6.27.4/arch/ia64/kernel/sys_ia64.c
429 --- linux-2.6.27.4/arch/ia64/kernel/sys_ia64.c 2008-10-22 17:38:01.000000000 -0400
430 +++ linux-2.6.27.4/arch/ia64/kernel/sys_ia64.c 2008-10-27 22:36:16.000000000 -0400
431 @@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
432 if (REGION_NUMBER(addr) == RGN_HPAGE)
436 +#ifdef CONFIG_PAX_RANDMMAP
437 + if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
438 + addr = mm->free_area_cache;
443 addr = mm->free_area_cache;
445 @@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
446 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
447 /* At this point: (!vma || addr < vma->vm_end). */
448 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
449 - if (start_addr != TASK_UNMAPPED_BASE) {
450 + if (start_addr != mm->mmap_base) {
451 /* Start a new search --- just in case we missed some holes. */
452 - addr = TASK_UNMAPPED_BASE;
453 + addr = mm->mmap_base;
457 diff -urNp linux-2.6.27.4/arch/ia64/mm/fault.c linux-2.6.27.4/arch/ia64/mm/fault.c
458 --- linux-2.6.27.4/arch/ia64/mm/fault.c 2008-10-22 17:38:01.000000000 -0400
459 +++ linux-2.6.27.4/arch/ia64/mm/fault.c 2008-10-27 22:36:16.000000000 -0400
460 @@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
461 return pte_present(pte);
464 +#ifdef CONFIG_PAX_PAGEEXEC
465 +void pax_report_insns(void *pc, void *sp)
469 + printk(KERN_ERR "PAX: bytes at PC: ");
470 + for (i = 0; i < 8; i++) {
472 + if (get_user(c, (unsigned int *)pc+i))
473 + printk(KERN_CONT "???????? ");
475 + printk(KERN_CONT "%08x ", c);
482 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
484 @@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
485 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
486 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
488 - if ((vma->vm_flags & mask) != mask)
489 + if ((vma->vm_flags & mask) != mask) {
491 +#ifdef CONFIG_PAX_PAGEEXEC
492 + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
493 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
496 + up_read(&mm->mmap_sem);
497 + pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
498 + do_group_exit(SIGKILL);
508 * If for any reason at all we couldn't handle the fault, make
509 diff -urNp linux-2.6.27.4/arch/ia64/mm/init.c linux-2.6.27.4/arch/ia64/mm/init.c
510 --- linux-2.6.27.4/arch/ia64/mm/init.c 2008-10-22 17:38:01.000000000 -0400
511 +++ linux-2.6.27.4/arch/ia64/mm/init.c 2008-10-27 22:36:16.000000000 -0400
512 @@ -122,6 +122,19 @@ ia64_init_addr_space (void)
513 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
514 vma->vm_end = vma->vm_start + PAGE_SIZE;
515 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
517 +#ifdef CONFIG_PAX_PAGEEXEC
518 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
519 + vma->vm_flags &= ~VM_EXEC;
521 +#ifdef CONFIG_PAX_MPROTECT
522 + if (current->mm->pax_flags & MF_PAX_MPROTECT)
523 + vma->vm_flags &= ~VM_MAYEXEC;
529 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
530 down_write(¤t->mm->mmap_sem);
531 if (insert_vm_struct(current->mm, vma)) {
532 diff -urNp linux-2.6.27.4/arch/mips/kernel/binfmt_elfn32.c linux-2.6.27.4/arch/mips/kernel/binfmt_elfn32.c
533 --- linux-2.6.27.4/arch/mips/kernel/binfmt_elfn32.c 2008-10-22 17:38:01.000000000 -0400
534 +++ linux-2.6.27.4/arch/mips/kernel/binfmt_elfn32.c 2008-10-27 22:36:16.000000000 -0400
535 @@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
536 #undef ELF_ET_DYN_BASE
537 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
539 +#ifdef CONFIG_PAX_ASLR
540 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
542 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
543 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
546 #include <asm/processor.h>
547 #include <linux/module.h>
548 #include <linux/elfcore.h>
549 diff -urNp linux-2.6.27.4/arch/mips/kernel/binfmt_elfo32.c linux-2.6.27.4/arch/mips/kernel/binfmt_elfo32.c
550 --- linux-2.6.27.4/arch/mips/kernel/binfmt_elfo32.c 2008-10-22 17:38:01.000000000 -0400
551 +++ linux-2.6.27.4/arch/mips/kernel/binfmt_elfo32.c 2008-10-27 22:36:16.000000000 -0400
552 @@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
553 #undef ELF_ET_DYN_BASE
554 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
556 +#ifdef CONFIG_PAX_ASLR
557 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
559 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
560 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
563 #include <asm/processor.h>
564 #include <linux/module.h>
565 #include <linux/elfcore.h>
566 diff -urNp linux-2.6.27.4/arch/mips/kernel/process.c linux-2.6.27.4/arch/mips/kernel/process.c
567 --- linux-2.6.27.4/arch/mips/kernel/process.c 2008-10-22 17:38:01.000000000 -0400
568 +++ linux-2.6.27.4/arch/mips/kernel/process.c 2008-10-27 22:36:16.000000000 -0400
569 @@ -458,15 +458,3 @@ unsigned long get_wchan(struct task_stru
575 - * Don't forget that the stack pointer must be aligned on a 8 bytes
576 - * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
578 -unsigned long arch_align_stack(unsigned long sp)
580 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
581 - sp -= get_random_int() & ~PAGE_MASK;
583 - return sp & ALMASK;
585 diff -urNp linux-2.6.27.4/arch/mips/kernel/syscall.c linux-2.6.27.4/arch/mips/kernel/syscall.c
586 --- linux-2.6.27.4/arch/mips/kernel/syscall.c 2008-10-22 17:38:01.000000000 -0400
587 +++ linux-2.6.27.4/arch/mips/kernel/syscall.c 2008-10-27 22:36:16.000000000 -0400
588 @@ -100,6 +100,11 @@ unsigned long arch_get_unmapped_area(str
590 if (filp || (flags & MAP_SHARED))
593 +#ifdef CONFIG_PAX_RANDMMAP
594 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
599 addr = COLOUR_ALIGN(addr, pgoff);
600 @@ -110,7 +115,7 @@ unsigned long arch_get_unmapped_area(str
601 (!vmm || addr + len <= vmm->vm_start))
604 - addr = TASK_UNMAPPED_BASE;
605 + addr = current->mm->mmap_base;
607 addr = COLOUR_ALIGN(addr, pgoff);
609 diff -urNp linux-2.6.27.4/arch/mips/mm/fault.c linux-2.6.27.4/arch/mips/mm/fault.c
610 --- linux-2.6.27.4/arch/mips/mm/fault.c 2008-10-22 17:38:01.000000000 -0400
611 +++ linux-2.6.27.4/arch/mips/mm/fault.c 2008-10-27 22:36:16.000000000 -0400
613 #include <asm/ptrace.h>
614 #include <asm/highmem.h> /* For VMALLOC_END */
616 +#ifdef CONFIG_PAX_PAGEEXEC
617 +void pax_report_insns(void *pc)
621 + printk(KERN_ERR "PAX: bytes at PC: ");
622 + for (i = 0; i < 5; i++) {
624 + if (get_user(c, (unsigned int *)pc+i))
625 + printk(KERN_CONT "???????? ");
627 + printk(KERN_CONT "%08x ", c);
634 * This routine handles page faults. It determines the address,
635 * and the problem, and then passes it off to one of the appropriate
636 diff -urNp linux-2.6.27.4/arch/parisc/kernel/module.c linux-2.6.27.4/arch/parisc/kernel/module.c
637 --- linux-2.6.27.4/arch/parisc/kernel/module.c 2008-10-22 17:38:01.000000000 -0400
638 +++ linux-2.6.27.4/arch/parisc/kernel/module.c 2008-10-27 22:36:16.000000000 -0400
641 /* three functions to determine where in the module core
642 * or init pieces the location is */
643 +static inline int in_init_rx(struct module *me, void *loc)
645 + return (loc >= me->module_init_rx &&
646 + loc < (me->module_init_rx + me->init_size_rx));
649 +static inline int in_init_rw(struct module *me, void *loc)
651 + return (loc >= me->module_init_rw &&
652 + loc < (me->module_init_rw + me->init_size_rw));
655 static inline int in_init(struct module *me, void *loc)
657 - return (loc >= me->module_init &&
658 - loc <= (me->module_init + me->init_size));
659 + return in_init_rx(me, loc) || in_init_rw(me, loc);
662 +static inline int in_core_rx(struct module *me, void *loc)
664 + return (loc >= me->module_core_rx &&
665 + loc < (me->module_core_rx + me->core_size_rx));
668 +static inline int in_core_rw(struct module *me, void *loc)
670 + return (loc >= me->module_core_rw &&
671 + loc < (me->module_core_rw + me->core_size_rw));
674 static inline int in_core(struct module *me, void *loc)
676 - return (loc >= me->module_core &&
677 - loc <= (me->module_core + me->core_size));
678 + return in_core_rx(me, loc) || in_core_rw(me, loc);
681 static inline int in_local(struct module *me, void *loc)
682 @@ -298,21 +320,21 @@ int module_frob_arch_sections(CONST Elf_
685 /* align things a bit */
686 - me->core_size = ALIGN(me->core_size, 16);
687 - me->arch.got_offset = me->core_size;
688 - me->core_size += gots * sizeof(struct got_entry);
690 - me->core_size = ALIGN(me->core_size, 16);
691 - me->arch.fdesc_offset = me->core_size;
692 - me->core_size += fdescs * sizeof(Elf_Fdesc);
694 - me->core_size = ALIGN(me->core_size, 16);
695 - me->arch.stub_offset = me->core_size;
696 - me->core_size += stubs * sizeof(struct stub_entry);
698 - me->init_size = ALIGN(me->init_size, 16);
699 - me->arch.init_stub_offset = me->init_size;
700 - me->init_size += init_stubs * sizeof(struct stub_entry);
701 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
702 + me->arch.got_offset = me->core_size_rw;
703 + me->core_size_rw += gots * sizeof(struct got_entry);
705 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
706 + me->arch.fdesc_offset = me->core_size_rw;
707 + me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
709 + me->core_size_rx = ALIGN(me->core_size_rx, 16);
710 + me->arch.stub_offset = me->core_size_rx;
711 + me->core_size_rx += stubs * sizeof(struct stub_entry);
713 + me->init_size_rx = ALIGN(me->init_size_rx, 16);
714 + me->arch.init_stub_offset = me->init_size_rx;
715 + me->init_size_rx += init_stubs * sizeof(struct stub_entry);
717 me->arch.got_max = gots;
718 me->arch.fdesc_max = fdescs;
719 @@ -332,7 +354,7 @@ static Elf64_Word get_got(struct module
723 - got = me->module_core + me->arch.got_offset;
724 + got = me->module_core_rw + me->arch.got_offset;
725 for (i = 0; got[i].addr; i++)
726 if (got[i].addr == value)
728 @@ -350,7 +372,7 @@ static Elf64_Word get_got(struct module
730 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
732 - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
733 + Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
736 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
737 @@ -368,7 +390,7 @@ static Elf_Addr get_fdesc(struct module
741 - fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
742 + fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
743 return (Elf_Addr)fdesc;
745 #endif /* CONFIG_64BIT */
746 @@ -388,12 +410,12 @@ static Elf_Addr get_stub(struct module *
748 i = me->arch.init_stub_count++;
749 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
750 - stub = me->module_init + me->arch.init_stub_offset +
751 + stub = me->module_init_rx + me->arch.init_stub_offset +
752 i * sizeof(struct stub_entry);
754 i = me->arch.stub_count++;
755 BUG_ON(me->arch.stub_count > me->arch.stub_max);
756 - stub = me->module_core + me->arch.stub_offset +
757 + stub = me->module_core_rx + me->arch.stub_offset +
758 i * sizeof(struct stub_entry);
761 @@ -761,7 +783,7 @@ register_unwind_table(struct module *me,
763 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
764 end = table + sechdrs[me->arch.unwind_section].sh_size;
765 - gp = (Elf_Addr)me->module_core + me->arch.got_offset;
766 + gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
768 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
769 me->arch.unwind_section, table, end, gp);
770 diff -urNp linux-2.6.27.4/arch/parisc/kernel/sys_parisc.c linux-2.6.27.4/arch/parisc/kernel/sys_parisc.c
771 --- linux-2.6.27.4/arch/parisc/kernel/sys_parisc.c 2008-10-22 17:38:01.000000000 -0400
772 +++ linux-2.6.27.4/arch/parisc/kernel/sys_parisc.c 2008-10-27 22:36:16.000000000 -0400
773 @@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
774 if (flags & MAP_FIXED)
777 - addr = TASK_UNMAPPED_BASE;
778 + addr = current->mm->mmap_base;
781 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
782 diff -urNp linux-2.6.27.4/arch/parisc/kernel/traps.c linux-2.6.27.4/arch/parisc/kernel/traps.c
783 --- linux-2.6.27.4/arch/parisc/kernel/traps.c 2008-10-22 17:38:01.000000000 -0400
784 +++ linux-2.6.27.4/arch/parisc/kernel/traps.c 2008-10-27 22:36:16.000000000 -0400
785 @@ -732,9 +732,7 @@ void handle_interruption(int code, struc
787 down_read(¤t->mm->mmap_sem);
788 vma = find_vma(current->mm,regs->iaoq[0]);
789 - if (vma && (regs->iaoq[0] >= vma->vm_start)
790 - && (vma->vm_flags & VM_EXEC)) {
792 + if (vma && (regs->iaoq[0] >= vma->vm_start)) {
793 fault_address = regs->iaoq[0];
794 fault_space = regs->iasq[0];
796 diff -urNp linux-2.6.27.4/arch/parisc/mm/fault.c linux-2.6.27.4/arch/parisc/mm/fault.c
797 --- linux-2.6.27.4/arch/parisc/mm/fault.c 2008-10-22 17:38:01.000000000 -0400
798 +++ linux-2.6.27.4/arch/parisc/mm/fault.c 2008-10-27 22:36:16.000000000 -0400
800 #include <linux/sched.h>
801 #include <linux/interrupt.h>
802 #include <linux/module.h>
803 +#include <linux/unistd.h>
805 #include <asm/uaccess.h>
806 #include <asm/traps.h>
807 @@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
809 parisc_acctyp(unsigned long code, unsigned int inst)
811 - if (code == 6 || code == 16)
812 + if (code == 6 || code == 7 || code == 16)
815 switch (inst & 0xf0000000) {
816 @@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
820 +#ifdef CONFIG_PAX_PAGEEXEC
822 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
824 + * returns 1 when task should be killed
825 + * 2 when rt_sigreturn trampoline was detected
826 + * 3 when unpatched PLT trampoline was detected
828 +static int pax_handle_fetch_fault(struct pt_regs *regs)
831 +#ifdef CONFIG_PAX_EMUPLT
834 + do { /* PaX: unpatched PLT emulation */
835 + unsigned int bl, depwi;
837 + err = get_user(bl, (unsigned int *)instruction_pointer(regs));
838 + err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
843 + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
844 + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
846 + err = get_user(ldw, (unsigned int *)addr);
847 + err |= get_user(bv, (unsigned int *)(addr+4));
848 + err |= get_user(ldw2, (unsigned int *)(addr+8));
853 + if (ldw == 0x0E801096U &&
854 + bv == 0xEAC0C000U &&
855 + ldw2 == 0x0E881095U)
857 + unsigned int resolver, map;
859 + err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
860 + err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
864 + regs->gr[20] = instruction_pointer(regs)+8;
865 + regs->gr[21] = map;
866 + regs->gr[22] = resolver;
867 + regs->iaoq[0] = resolver | 3UL;
868 + regs->iaoq[1] = regs->iaoq[0] + 4;
875 +#ifdef CONFIG_PAX_EMUTRAMP
877 +#ifndef CONFIG_PAX_EMUSIGRT
878 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
882 + do { /* PaX: rt_sigreturn emulation */
883 + unsigned int ldi1, ldi2, bel, nop;
885 + err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
886 + err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
887 + err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
888 + err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
893 + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
894 + ldi2 == 0x3414015AU &&
895 + bel == 0xE4008200U &&
896 + nop == 0x08000240U)
898 + regs->gr[25] = (ldi1 & 2) >> 1;
899 + regs->gr[20] = __NR_rt_sigreturn;
900 + regs->gr[31] = regs->iaoq[1] + 16;
901 + regs->sr[0] = regs->iasq[1];
902 + regs->iaoq[0] = 0x100UL;
903 + regs->iaoq[1] = regs->iaoq[0] + 4;
904 + regs->iasq[0] = regs->sr[2];
905 + regs->iasq[1] = regs->sr[2];
914 +void pax_report_insns(void *pc, void *sp)
918 + printk(KERN_ERR "PAX: bytes at PC: ");
919 + for (i = 0; i < 5; i++) {
921 + if (get_user(c, (unsigned int *)pc+i))
922 + printk(KERN_CONT "???????? ");
924 + printk(KERN_CONT "%08x ", c);
930 void do_page_fault(struct pt_regs *regs, unsigned long code,
931 unsigned long address)
933 @@ -165,8 +276,33 @@ good_area:
935 acc_type = parisc_acctyp(code,regs->iir);
937 - if ((vma->vm_flags & acc_type) != acc_type)
938 + if ((vma->vm_flags & acc_type) != acc_type) {
940 +#ifdef CONFIG_PAX_PAGEEXEC
941 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
942 + (address & ~3UL) == instruction_pointer(regs))
944 + up_read(&mm->mmap_sem);
945 + switch (pax_handle_fetch_fault(regs)) {
947 +#ifdef CONFIG_PAX_EMUPLT
952 +#ifdef CONFIG_PAX_EMUTRAMP
958 + pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
959 + do_group_exit(SIGKILL);
967 * If for any reason at all we couldn't handle the fault, make
968 diff -urNp linux-2.6.27.4/arch/powerpc/kernel/module_32.c linux-2.6.27.4/arch/powerpc/kernel/module_32.c
969 --- linux-2.6.27.4/arch/powerpc/kernel/module_32.c 2008-10-22 17:38:01.000000000 -0400
970 +++ linux-2.6.27.4/arch/powerpc/kernel/module_32.c 2008-10-27 22:36:16.000000000 -0400
971 @@ -158,7 +158,7 @@ int module_frob_arch_sections(Elf32_Ehdr
972 me->arch.core_plt_section = i;
974 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
975 - printk("Module doesn't contain .plt or .init.plt sections.\n");
976 + printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
980 @@ -199,11 +199,16 @@ static uint32_t do_plt_call(void *locati
982 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
983 /* Init, or core PLT? */
984 - if (location >= mod->module_core
985 - && location < mod->module_core + mod->core_size)
986 + if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
987 + (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
988 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
990 + else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
991 + (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
992 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
994 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
998 /* Find this entry, or if that fails, the next avail. entry */
999 while (entry->jump[0]) {
1000 diff -urNp linux-2.6.27.4/arch/powerpc/kernel/signal_32.c linux-2.6.27.4/arch/powerpc/kernel/signal_32.c
1001 --- linux-2.6.27.4/arch/powerpc/kernel/signal_32.c 2008-10-22 17:38:01.000000000 -0400
1002 +++ linux-2.6.27.4/arch/powerpc/kernel/signal_32.c 2008-10-27 22:36:16.000000000 -0400
1003 @@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig
1004 /* Save user registers on the stack */
1005 frame = &rt_sf->uc.uc_mcontext;
1007 - if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1008 + if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1009 if (save_user_regs(regs, frame, 0))
1011 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1012 diff -urNp linux-2.6.27.4/arch/powerpc/kernel/signal_64.c linux-2.6.27.4/arch/powerpc/kernel/signal_64.c
1013 --- linux-2.6.27.4/arch/powerpc/kernel/signal_64.c 2008-10-22 17:38:01.000000000 -0400
1014 +++ linux-2.6.27.4/arch/powerpc/kernel/signal_64.c 2008-10-27 22:36:16.000000000 -0400
1015 @@ -434,7 +434,7 @@ int handle_rt_signal64(int signr, struct
1016 current->thread.fpscr.val = 0;
1018 /* Set up to return from userspace. */
1019 - if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1020 + if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1021 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1023 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1024 diff -urNp linux-2.6.27.4/arch/powerpc/kernel/vdso.c linux-2.6.27.4/arch/powerpc/kernel/vdso.c
1025 --- linux-2.6.27.4/arch/powerpc/kernel/vdso.c 2008-10-22 17:38:01.000000000 -0400
1026 +++ linux-2.6.27.4/arch/powerpc/kernel/vdso.c 2008-10-27 22:36:16.000000000 -0400
1027 @@ -212,7 +212,7 @@ int arch_setup_additional_pages(struct l
1028 vdso_base = VDSO32_MBASE;
1031 - current->mm->context.vdso_base = 0;
1032 + current->mm->context.vdso_base = ~0UL;
1034 /* vDSO has a problem and was disabled, just don't "enable" it for the
1036 @@ -229,7 +229,7 @@ int arch_setup_additional_pages(struct l
1038 down_write(&mm->mmap_sem);
1039 vdso_base = get_unmapped_area(NULL, vdso_base,
1040 - vdso_pages << PAGE_SHIFT, 0, 0);
1041 + vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1042 if (IS_ERR_VALUE(vdso_base)) {
1045 diff -urNp linux-2.6.27.4/arch/powerpc/mm/fault.c linux-2.6.27.4/arch/powerpc/mm/fault.c
1046 --- linux-2.6.27.4/arch/powerpc/mm/fault.c 2008-10-22 17:38:01.000000000 -0400
1047 +++ linux-2.6.27.4/arch/powerpc/mm/fault.c 2008-10-27 22:36:16.000000000 -0400
1049 #include <linux/module.h>
1050 #include <linux/kprobes.h>
1051 #include <linux/kdebug.h>
1052 +#include <linux/slab.h>
1053 +#include <linux/pagemap.h>
1054 +#include <linux/compiler.h>
1055 +#include <linux/unistd.h>
1057 #include <asm/page.h>
1058 #include <asm/pgtable.h>
1059 @@ -62,6 +66,363 @@ static inline int notify_page_fault(stru
1063 +#ifdef CONFIG_PAX_EMUSIGRT
1064 +void pax_syscall_close(struct vm_area_struct *vma)
1066 + vma->vm_mm->call_syscall = 0UL;
1069 +static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1071 + unsigned int *kaddr;
1073 + vmf->page = alloc_page(GFP_HIGHUSER);
1075 + return VM_FAULT_OOM;
1077 + kaddr = kmap(vmf->page);
1078 + memset(kaddr, 0, PAGE_SIZE);
1079 + kaddr[0] = 0x44000002U; /* sc */
1080 + __flush_dcache_icache(kaddr);
1081 + kunmap(vmf->page);
1082 + return VM_FAULT_MAJOR;
1085 +static struct vm_operations_struct pax_vm_ops = {
1086 + .close = pax_syscall_close,
1087 + .fault = pax_syscall_fault
1090 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1094 + vma->vm_mm = current->mm;
1095 + vma->vm_start = addr;
1096 + vma->vm_end = addr + PAGE_SIZE;
1097 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1098 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1099 + vma->vm_ops = &pax_vm_ops;
1101 + ret = insert_vm_struct(current->mm, vma);
1105 + ++current->mm->total_vm;
1110 +#ifdef CONFIG_PAX_PAGEEXEC
1112 + * PaX: decide what to do with offenders (regs->nip = fault address)
1114 + * returns 1 when task should be killed
1115 + * 2 when patched GOT trampoline was detected
1116 + * 3 when patched PLT trampoline was detected
1117 + * 4 when unpatched PLT trampoline was detected
1118 + * 5 when sigreturn trampoline was detected
1119 + * 6 when rt_sigreturn trampoline was detected
1121 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1124 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1128 +#ifdef CONFIG_PAX_EMUPLT
1129 + do { /* PaX: patched GOT emulation */
1130 + unsigned int blrl;
1132 + err = get_user(blrl, (unsigned int *)regs->nip);
1134 + if (!err && blrl == 0x4E800021U) {
1135 + unsigned long temp = regs->nip;
1137 + regs->nip = regs->link & 0xFFFFFFFCUL;
1138 + regs->link = temp + 4UL;
1143 + do { /* PaX: patched PLT emulation #1 */
1146 + err = get_user(b, (unsigned int *)regs->nip);
1148 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
1149 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1154 + do { /* PaX: unpatched PLT emulation #1 */
1155 + unsigned int li, b;
1157 + err = get_user(li, (unsigned int *)regs->nip);
1158 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1160 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1161 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1162 + unsigned long addr = b | 0xFC000000UL;
1164 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1165 + err = get_user(rlwinm, (unsigned int *)addr);
1166 + err |= get_user(add, (unsigned int *)(addr+4));
1167 + err |= get_user(li2, (unsigned int *)(addr+8));
1168 + err |= get_user(addis2, (unsigned int *)(addr+12));
1169 + err |= get_user(mtctr, (unsigned int *)(addr+16));
1170 + err |= get_user(li3, (unsigned int *)(addr+20));
1171 + err |= get_user(addis3, (unsigned int *)(addr+24));
1172 + err |= get_user(bctr, (unsigned int *)(addr+28));
1177 + if (rlwinm == 0x556C083CU &&
1178 + add == 0x7D6C5A14U &&
1179 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1180 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1181 + mtctr == 0x7D8903A6U &&
1182 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1183 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1184 + bctr == 0x4E800420U)
1186 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1187 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1188 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1189 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1190 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1191 + regs->nip = regs->ctr;
1198 + do { /* PaX: unpatched PLT emulation #2 */
1199 + unsigned int lis, lwzu, b, bctr;
1201 + err = get_user(lis, (unsigned int *)regs->nip);
1202 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1203 + err |= get_user(b, (unsigned int *)(regs->nip+8));
1204 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1209 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
1210 + (lwzu & 0xU) == 0xU &&
1211 + (b & 0xFC000003U) == 0x48000000U &&
1212 + bctr == 0x4E800420U)
1214 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1215 + unsigned long addr = b | 0xFC000000UL;
1217 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1218 + err = get_user(addis, (unsigned int *)addr);
1219 + err |= get_user(addi, (unsigned int *)(addr+4));
1220 + err |= get_user(rlwinm, (unsigned int *)(addr+8));
1221 + err |= get_user(add, (unsigned int *)(addr+12));
1222 + err |= get_user(li2, (unsigned int *)(addr+16));
1223 + err |= get_user(addis2, (unsigned int *)(addr+20));
1224 + err |= get_user(mtctr, (unsigned int *)(addr+24));
1225 + err |= get_user(li3, (unsigned int *)(addr+28));
1226 + err |= get_user(addis3, (unsigned int *)(addr+32));
1227 + err |= get_user(bctr, (unsigned int *)(addr+36));
1232 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1233 + (addi & 0xFFFF0000U) == 0x396B0000U &&
1234 + rlwinm == 0x556C083CU &&
1235 + add == 0x7D6C5A14U &&
1236 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1237 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1238 + mtctr == 0x7D8903A6U &&
1239 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1240 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1241 + bctr == 0x4E800420U)
1243 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1244 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1245 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1246 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1247 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1248 + regs->nip = regs->ctr;
1255 + do { /* PaX: unpatched PLT emulation #3 */
1256 + unsigned int li, b;
1258 + err = get_user(li, (unsigned int *)regs->nip);
1259 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1261 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1262 + unsigned int addis, lwz, mtctr, bctr;
1263 + unsigned long addr = b | 0xFC000000UL;
1265 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1266 + err = get_user(addis, (unsigned int *)addr);
1267 + err |= get_user(lwz, (unsigned int *)(addr+4));
1268 + err |= get_user(mtctr, (unsigned int *)(addr+8));
1269 + err |= get_user(bctr, (unsigned int *)(addr+12));
1274 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1275 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
1276 + mtctr == 0x7D6903A6U &&
1277 + bctr == 0x4E800420U)
1281 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1282 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1284 + err = get_user(r11, (unsigned int *)addr);
1288 + regs->gpr[PT_R11] = r11;
1297 +#ifdef CONFIG_PAX_EMUSIGRT
1298 + do { /* PaX: sigreturn emulation */
1299 + unsigned int li, sc;
1301 + err = get_user(li, (unsigned int *)regs->nip);
1302 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1304 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1305 + struct vm_area_struct *vma;
1306 + unsigned long call_syscall;
1308 + down_read(¤t->mm->mmap_sem);
1309 + call_syscall = current->mm->call_syscall;
1310 + up_read(¤t->mm->mmap_sem);
1311 + if (likely(call_syscall))
1314 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1316 + down_write(¤t->mm->mmap_sem);
1317 + if (current->mm->call_syscall) {
1318 + call_syscall = current->mm->call_syscall;
1319 + up_write(¤t->mm->mmap_sem);
1321 + kmem_cache_free(vm_area_cachep, vma);
1325 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1326 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1327 + up_write(¤t->mm->mmap_sem);
1329 + kmem_cache_free(vm_area_cachep, vma);
1333 + if (pax_insert_vma(vma, call_syscall)) {
1334 + up_write(¤t->mm->mmap_sem);
1335 + kmem_cache_free(vm_area_cachep, vma);
1339 + current->mm->call_syscall = call_syscall;
1340 + up_write(¤t->mm->mmap_sem);
1343 + regs->gpr[PT_R0] = __NR_sigreturn;
1344 + regs->nip = call_syscall;
1349 + do { /* PaX: rt_sigreturn emulation */
1350 + unsigned int li, sc;
1352 + err = get_user(li, (unsigned int *)regs->nip);
1353 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1355 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1356 + struct vm_area_struct *vma;
1357 + unsigned int call_syscall;
1359 + down_read(¤t->mm->mmap_sem);
1360 + call_syscall = current->mm->call_syscall;
1361 + up_read(¤t->mm->mmap_sem);
1362 + if (likely(call_syscall))
1365 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1367 + down_write(¤t->mm->mmap_sem);
1368 + if (current->mm->call_syscall) {
1369 + call_syscall = current->mm->call_syscall;
1370 + up_write(¤t->mm->mmap_sem);
1372 + kmem_cache_free(vm_area_cachep, vma);
1376 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1377 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1378 + up_write(¤t->mm->mmap_sem);
1380 + kmem_cache_free(vm_area_cachep, vma);
1384 + if (pax_insert_vma(vma, call_syscall)) {
1385 + up_write(¤t->mm->mmap_sem);
1386 + kmem_cache_free(vm_area_cachep, vma);
1390 + current->mm->call_syscall = call_syscall;
1391 + up_write(¤t->mm->mmap_sem);
1394 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
1395 + regs->nip = call_syscall;
1404 +void pax_report_insns(void *pc, void *sp)
1408 + printk(KERN_ERR "PAX: bytes at PC: ");
1409 + for (i = 0; i < 5; i++) {
1411 + if (get_user(c, (unsigned int *)pc+i))
1412 + printk(KERN_CONT "???????? ");
1414 + printk(KERN_CONT "%08x ", c);
1421 * Check whether the instruction at regs->nip is a store using
1422 * an update addressing form which will update r1.
1423 @@ -132,7 +493,7 @@ int __kprobes do_page_fault(struct pt_re
1424 * indicate errors in DSISR but can validly be set in SRR1.
1427 - error_code &= 0x48200000;
1428 + error_code &= 0x58200000;
1430 is_write = error_code & DSISR_ISSTORE;
1432 @@ -331,6 +692,37 @@ bad_area:
1433 bad_area_nosemaphore:
1434 /* User mode accesses cause a SIGSEGV */
1435 if (user_mode(regs)) {
1437 +#ifdef CONFIG_PAX_PAGEEXEC
1438 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1439 +#ifdef CONFIG_PPC64
1440 + if (is_exec && (error_code & DSISR_PROTFAULT)) {
1442 + if (is_exec && regs->nip == address) {
1444 + switch (pax_handle_fetch_fault(regs)) {
1446 +#ifdef CONFIG_PAX_EMUPLT
1453 +#ifdef CONFIG_PAX_EMUSIGRT
1461 + pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
1462 + do_group_exit(SIGKILL);
1467 _exception(SIGSEGV, regs, code, address);
1470 diff -urNp linux-2.6.27.4/arch/powerpc/mm/mmap.c linux-2.6.27.4/arch/powerpc/mm/mmap.c
1471 --- linux-2.6.27.4/arch/powerpc/mm/mmap.c 2008-10-22 17:38:01.000000000 -0400
1472 +++ linux-2.6.27.4/arch/powerpc/mm/mmap.c 2008-10-27 22:36:16.000000000 -0400
1473 @@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1475 if (mmap_is_legacy()) {
1476 mm->mmap_base = TASK_UNMAPPED_BASE;
1478 +#ifdef CONFIG_PAX_RANDMMAP
1479 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1480 + mm->mmap_base += mm->delta_mmap;
1483 mm->get_unmapped_area = arch_get_unmapped_area;
1484 mm->unmap_area = arch_unmap_area;
1486 mm->mmap_base = mmap_base();
1488 +#ifdef CONFIG_PAX_RANDMMAP
1489 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1490 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1493 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1494 mm->unmap_area = arch_unmap_area_topdown;
1496 diff -urNp linux-2.6.27.4/arch/s390/kernel/module.c linux-2.6.27.4/arch/s390/kernel/module.c
1497 --- linux-2.6.27.4/arch/s390/kernel/module.c 2008-10-22 17:38:01.000000000 -0400
1498 +++ linux-2.6.27.4/arch/s390/kernel/module.c 2008-10-27 22:36:16.000000000 -0400
1499 @@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
1501 /* Increase core size by size of got & plt and set start
1502 offsets for got and plt. */
1503 - me->core_size = ALIGN(me->core_size, 4);
1504 - me->arch.got_offset = me->core_size;
1505 - me->core_size += me->arch.got_size;
1506 - me->arch.plt_offset = me->core_size;
1507 - me->core_size += me->arch.plt_size;
1508 + me->core_size_rw = ALIGN(me->core_size_rw, 4);
1509 + me->arch.got_offset = me->core_size_rw;
1510 + me->core_size_rw += me->arch.got_size;
1511 + me->arch.plt_offset = me->core_size_rx;
1512 + me->core_size_rx += me->arch.plt_size;
1516 @@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1517 if (info->got_initialized == 0) {
1520 - gotent = me->module_core + me->arch.got_offset +
1521 + gotent = me->module_core_rw + me->arch.got_offset +
1524 info->got_initialized = 1;
1525 @@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1526 else if (r_type == R_390_GOTENT ||
1527 r_type == R_390_GOTPLTENT)
1528 *(unsigned int *) loc =
1529 - (val + (Elf_Addr) me->module_core - loc) >> 1;
1530 + (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
1531 else if (r_type == R_390_GOT64 ||
1532 r_type == R_390_GOTPLT64)
1533 *(unsigned long *) loc = val;
1534 @@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1535 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
1536 if (info->plt_initialized == 0) {
1538 - ip = me->module_core + me->arch.plt_offset +
1539 + ip = me->module_core_rx + me->arch.plt_offset +
1541 #ifndef CONFIG_64BIT
1542 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
1543 @@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1544 val = me->arch.plt_offset - me->arch.got_offset +
1545 info->plt_offset + rela->r_addend;
1547 - val = (Elf_Addr) me->module_core +
1548 + val = (Elf_Addr) me->module_core_rx +
1549 me->arch.plt_offset + info->plt_offset +
1550 rela->r_addend - loc;
1551 if (r_type == R_390_PLT16DBL)
1552 @@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1553 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
1554 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
1555 val = val + rela->r_addend -
1556 - ((Elf_Addr) me->module_core + me->arch.got_offset);
1557 + ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
1558 if (r_type == R_390_GOTOFF16)
1559 *(unsigned short *) loc = val;
1560 else if (r_type == R_390_GOTOFF32)
1561 @@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1563 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
1564 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
1565 - val = (Elf_Addr) me->module_core + me->arch.got_offset +
1566 + val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
1567 rela->r_addend - loc;
1568 if (r_type == R_390_GOTPC)
1569 *(unsigned int *) loc = val;
1570 diff -urNp linux-2.6.27.4/arch/sparc/kernel/sys_sparc.c linux-2.6.27.4/arch/sparc/kernel/sys_sparc.c
1571 --- linux-2.6.27.4/arch/sparc/kernel/sys_sparc.c 2008-10-22 17:38:01.000000000 -0400
1572 +++ linux-2.6.27.4/arch/sparc/kernel/sys_sparc.c 2008-10-27 22:36:16.000000000 -0400
1573 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
1574 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
1577 - addr = TASK_UNMAPPED_BASE;
1578 + addr = current->mm->mmap_base;
1580 if (flags & MAP_SHARED)
1581 addr = COLOUR_ALIGN(addr);
1582 diff -urNp linux-2.6.27.4/arch/sparc/Makefile linux-2.6.27.4/arch/sparc/Makefile
1583 --- linux-2.6.27.4/arch/sparc/Makefile 2008-10-22 17:38:01.000000000 -0400
1584 +++ linux-2.6.27.4/arch/sparc/Makefile 2008-10-25 12:03:06.000000000 -0400
1585 @@ -37,7 +37,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
1586 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
1587 INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
1589 -CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
1590 +CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
1591 CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
1592 DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
1593 NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
1594 diff -urNp linux-2.6.27.4/arch/sparc/mm/fault.c linux-2.6.27.4/arch/sparc/mm/fault.c
1595 --- linux-2.6.27.4/arch/sparc/mm/fault.c 2008-10-22 17:38:01.000000000 -0400
1596 +++ linux-2.6.27.4/arch/sparc/mm/fault.c 2008-10-27 22:36:16.000000000 -0400
1598 #include <linux/interrupt.h>
1599 #include <linux/module.h>
1600 #include <linux/kdebug.h>
1601 +#include <linux/slab.h>
1602 +#include <linux/pagemap.h>
1603 +#include <linux/compiler.h>
1605 #include <asm/system.h>
1606 #include <asm/page.h>
1607 @@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
1608 return safe_compute_effective_address(regs, insn);
1611 +#ifdef CONFIG_PAX_PAGEEXEC
1612 +void pax_emuplt_close(struct vm_area_struct *vma)
1614 + vma->vm_mm->call_dl_resolve = 0UL;
1617 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1619 + unsigned int *kaddr;
1621 + vmf->page = alloc_page(GFP_HIGHUSER);
1623 + return VM_FAULT_OOM;
1625 + kaddr = kmap(vmf->page);
1626 + memset(kaddr, 0, PAGE_SIZE);
1627 + kaddr[0] = 0x9DE3BFA8U; /* save */
1628 + flush_dcache_page(vmf->page);
1629 + kunmap(vmf->page);
1630 + return VM_FAULT_MAJOR;
1633 +static struct vm_operations_struct pax_vm_ops = {
1634 + .close = pax_emuplt_close,
1635 + .fault = pax_emuplt_fault
1638 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1642 + vma->vm_mm = current->mm;
1643 + vma->vm_start = addr;
1644 + vma->vm_end = addr + PAGE_SIZE;
1645 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1646 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1647 + vma->vm_ops = &pax_vm_ops;
1649 + ret = insert_vm_struct(current->mm, vma);
1653 + ++current->mm->total_vm;
1658 + * PaX: decide what to do with offenders (regs->pc = fault address)
1660 + * returns 1 when task should be killed
1661 + * 2 when patched PLT trampoline was detected
1662 + * 3 when unpatched PLT trampoline was detected
1664 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1667 +#ifdef CONFIG_PAX_EMUPLT
1670 + do { /* PaX: patched PLT emulation #1 */
1671 + unsigned int sethi1, sethi2, jmpl;
1673 + err = get_user(sethi1, (unsigned int *)regs->pc);
1674 + err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
1675 + err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
1680 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
1681 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
1682 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
1684 + unsigned int addr;
1686 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
1687 + addr = regs->u_regs[UREG_G1];
1688 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
1690 + regs->npc = addr+4;
1695 + { /* PaX: patched PLT emulation #2 */
1698 + err = get_user(ba, (unsigned int *)regs->pc);
1700 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
1701 + unsigned int addr;
1703 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
1705 + regs->npc = addr+4;
1710 + do { /* PaX: patched PLT emulation #3 */
1711 + unsigned int sethi, jmpl, nop;
1713 + err = get_user(sethi, (unsigned int *)regs->pc);
1714 + err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
1715 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
1720 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
1721 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
1722 + nop == 0x01000000U)
1724 + unsigned int addr;
1726 + addr = (sethi & 0x003FFFFFU) << 10;
1727 + regs->u_regs[UREG_G1] = addr;
1728 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
1730 + regs->npc = addr+4;
1735 + do { /* PaX: unpatched PLT emulation step 1 */
1736 + unsigned int sethi, ba, nop;
1738 + err = get_user(sethi, (unsigned int *)regs->pc);
1739 + err |= get_user(ba, (unsigned int *)(regs->pc+4));
1740 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
1745 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
1746 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
1747 + nop == 0x01000000U)
1749 + unsigned int addr, save, call;
1751 + if ((ba & 0xFFC00000U) == 0x30800000U)
1752 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
1754 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
1756 + err = get_user(save, (unsigned int *)addr);
1757 + err |= get_user(call, (unsigned int *)(addr+4));
1758 + err |= get_user(nop, (unsigned int *)(addr+8));
1762 + if (save == 0x9DE3BFA8U &&
1763 + (call & 0xC0000000U) == 0x40000000U &&
1764 + nop == 0x01000000U)
1766 + struct vm_area_struct *vma;
1767 + unsigned long call_dl_resolve;
1769 + down_read(¤t->mm->mmap_sem);
1770 + call_dl_resolve = current->mm->call_dl_resolve;
1771 + up_read(¤t->mm->mmap_sem);
1772 + if (likely(call_dl_resolve))
1775 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1777 + down_write(¤t->mm->mmap_sem);
1778 + if (current->mm->call_dl_resolve) {
1779 + call_dl_resolve = current->mm->call_dl_resolve;
1780 + up_write(¤t->mm->mmap_sem);
1782 + kmem_cache_free(vm_area_cachep, vma);
1786 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1787 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
1788 + up_write(¤t->mm->mmap_sem);
1790 + kmem_cache_free(vm_area_cachep, vma);
1794 + if (pax_insert_vma(vma, call_dl_resolve)) {
1795 + up_write(¤t->mm->mmap_sem);
1796 + kmem_cache_free(vm_area_cachep, vma);
1800 + current->mm->call_dl_resolve = call_dl_resolve;
1801 + up_write(¤t->mm->mmap_sem);
1804 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
1805 + regs->pc = call_dl_resolve;
1806 + regs->npc = addr+4;
1812 + do { /* PaX: unpatched PLT emulation step 2 */
1813 + unsigned int save, call, nop;
1815 + err = get_user(save, (unsigned int *)(regs->pc-4));
1816 + err |= get_user(call, (unsigned int *)regs->pc);
1817 + err |= get_user(nop, (unsigned int *)(regs->pc+4));
1821 + if (save == 0x9DE3BFA8U &&
1822 + (call & 0xC0000000U) == 0x40000000U &&
1823 + nop == 0x01000000U)
1825 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
1827 + regs->u_regs[UREG_RETPC] = regs->pc;
1828 + regs->pc = dl_resolve;
1829 + regs->npc = dl_resolve+4;
1838 +void pax_report_insns(void *pc, void *sp)
1842 + printk(KERN_ERR "PAX: bytes at PC: ");
1843 + for (i = 0; i < 5; i++) {
1845 + if (get_user(c, (unsigned int *)pc+i))
1846 + printk(KERN_CONT "???????? ");
1848 + printk(KERN_CONT "%08x ", c);
1854 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
1855 unsigned long address)
1857 @@ -231,6 +477,24 @@ good_area:
1858 if(!(vma->vm_flags & VM_WRITE))
1862 +#ifdef CONFIG_PAX_PAGEEXEC
1863 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
1864 + up_read(&mm->mmap_sem);
1865 + switch (pax_handle_fetch_fault(regs)) {
1867 +#ifdef CONFIG_PAX_EMUPLT
1874 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
1875 + do_group_exit(SIGKILL);
1879 /* Allow reads even for write-only mappings */
1880 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
1882 diff -urNp linux-2.6.27.4/arch/sparc/mm/init.c linux-2.6.27.4/arch/sparc/mm/init.c
1883 --- linux-2.6.27.4/arch/sparc/mm/init.c 2008-10-22 17:38:01.000000000 -0400
1884 +++ linux-2.6.27.4/arch/sparc/mm/init.c 2008-10-27 22:36:16.000000000 -0400
1885 @@ -312,6 +312,9 @@ extern void device_scan(void);
1886 pgprot_t PAGE_SHARED __read_mostly;
1887 EXPORT_SYMBOL(PAGE_SHARED);
1889 +pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
1890 +EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
1892 void __init paging_init(void)
1894 switch(sparc_cpu_model) {
1895 @@ -337,17 +340,17 @@ void __init paging_init(void)
1897 /* Initialize the protection map with non-constant, MMU dependent values. */
1898 protection_map[0] = PAGE_NONE;
1899 - protection_map[1] = PAGE_READONLY;
1900 - protection_map[2] = PAGE_COPY;
1901 - protection_map[3] = PAGE_COPY;
1902 + protection_map[1] = PAGE_READONLY_NOEXEC;
1903 + protection_map[2] = PAGE_COPY_NOEXEC;
1904 + protection_map[3] = PAGE_COPY_NOEXEC;
1905 protection_map[4] = PAGE_READONLY;
1906 protection_map[5] = PAGE_READONLY;
1907 protection_map[6] = PAGE_COPY;
1908 protection_map[7] = PAGE_COPY;
1909 protection_map[8] = PAGE_NONE;
1910 - protection_map[9] = PAGE_READONLY;
1911 - protection_map[10] = PAGE_SHARED;
1912 - protection_map[11] = PAGE_SHARED;
1913 + protection_map[9] = PAGE_READONLY_NOEXEC;
1914 + protection_map[10] = PAGE_SHARED_NOEXEC;
1915 + protection_map[11] = PAGE_SHARED_NOEXEC;
1916 protection_map[12] = PAGE_READONLY;
1917 protection_map[13] = PAGE_READONLY;
1918 protection_map[14] = PAGE_SHARED;
1919 diff -urNp linux-2.6.27.4/arch/sparc/mm/srmmu.c linux-2.6.27.4/arch/sparc/mm/srmmu.c
1920 --- linux-2.6.27.4/arch/sparc/mm/srmmu.c 2008-10-22 17:38:01.000000000 -0400
1921 +++ linux-2.6.27.4/arch/sparc/mm/srmmu.c 2008-10-27 22:36:16.000000000 -0400
1922 @@ -2163,6 +2163,13 @@ void __init ld_mmu_srmmu(void)
1923 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
1924 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
1925 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
1927 +#ifdef CONFIG_PAX_PAGEEXEC
1928 + PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
1929 + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
1930 + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
1933 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
1934 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
1936 diff -urNp linux-2.6.27.4/arch/sparc64/kernel/Makefile linux-2.6.27.4/arch/sparc64/kernel/Makefile
1937 --- linux-2.6.27.4/arch/sparc64/kernel/Makefile 2008-10-22 17:38:01.000000000 -0400
1938 +++ linux-2.6.27.4/arch/sparc64/kernel/Makefile 2008-10-27 22:36:16.000000000 -0400
1942 EXTRA_AFLAGS := -ansi
1943 -EXTRA_CFLAGS := -Werror
1944 +#EXTRA_CFLAGS := -Werror
1946 extra-y := head.o init_task.o vmlinux.lds
1948 diff -urNp linux-2.6.27.4/arch/sparc64/kernel/sys_sparc.c linux-2.6.27.4/arch/sparc64/kernel/sys_sparc.c
1949 --- linux-2.6.27.4/arch/sparc64/kernel/sys_sparc.c 2008-10-22 17:38:01.000000000 -0400
1950 +++ linux-2.6.27.4/arch/sparc64/kernel/sys_sparc.c 2008-10-27 22:36:16.000000000 -0400
1951 @@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
1952 /* We do not accept a shared mapping if it would violate
1953 * cache aliasing constraints.
1955 - if ((flags & MAP_SHARED) &&
1956 + if ((filp || (flags & MAP_SHARED)) &&
1957 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
1960 @@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
1961 if (filp || (flags & MAP_SHARED))
1964 +#ifdef CONFIG_PAX_RANDMMAP
1965 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
1970 addr = COLOUR_ALIGN(addr, pgoff);
1971 @@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
1974 if (len > mm->cached_hole_size) {
1975 - start_addr = addr = mm->free_area_cache;
1976 + start_addr = addr = mm->free_area_cache;
1978 - start_addr = addr = TASK_UNMAPPED_BASE;
1979 + start_addr = addr = mm->mmap_base;
1980 mm->cached_hole_size = 0;
1983 @@ -174,8 +178,8 @@ full_search:
1984 vma = find_vma(mm, VA_EXCLUDE_END);
1986 if (unlikely(task_size < addr)) {
1987 - if (start_addr != TASK_UNMAPPED_BASE) {
1988 - start_addr = addr = TASK_UNMAPPED_BASE;
1989 + if (start_addr != mm->mmap_base) {
1990 + start_addr = addr = mm->mmap_base;
1991 mm->cached_hole_size = 0;
1994 @@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
1995 /* We do not accept a shared mapping if it would violate
1996 * cache aliasing constraints.
1998 - if ((flags & MAP_SHARED) &&
1999 + if ((filp || (flags & MAP_SHARED)) &&
2000 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2003 @@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
2004 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2005 sysctl_legacy_va_layout) {
2006 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2008 +#ifdef CONFIG_PAX_RANDMMAP
2009 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2010 + mm->mmap_base += mm->delta_mmap;
2013 mm->get_unmapped_area = arch_get_unmapped_area;
2014 mm->unmap_area = arch_unmap_area;
2016 @@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
2017 gap = (task_size / 6 * 5);
2019 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2021 +#ifdef CONFIG_PAX_RANDMMAP
2022 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2023 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2026 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2027 mm->unmap_area = arch_unmap_area_topdown;
2029 diff -urNp linux-2.6.27.4/arch/sparc64/mm/fault.c linux-2.6.27.4/arch/sparc64/mm/fault.c
2030 --- linux-2.6.27.4/arch/sparc64/mm/fault.c 2008-10-22 17:38:01.000000000 -0400
2031 +++ linux-2.6.27.4/arch/sparc64/mm/fault.c 2008-10-27 22:36:16.000000000 -0400
2033 #include <linux/interrupt.h>
2034 #include <linux/kprobes.h>
2035 #include <linux/kdebug.h>
2036 +#include <linux/slab.h>
2037 +#include <linux/pagemap.h>
2038 +#include <linux/compiler.h>
2040 #include <asm/page.h>
2041 #include <asm/pgtable.h>
2042 @@ -261,6 +264,367 @@ cannot_handle:
2043 unhandled_fault (address, current, regs);
2046 +#ifdef CONFIG_PAX_PAGEEXEC
2047 +#ifdef CONFIG_PAX_EMUPLT
2048 +static void pax_emuplt_close(struct vm_area_struct *vma)
2050 + vma->vm_mm->call_dl_resolve = 0UL;
2053 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2055 + unsigned int *kaddr;
2057 + vmf->page = alloc_page(GFP_HIGHUSER);
2059 + return VM_FAULT_OOM;
2061 + kaddr = kmap(vmf->page);
2062 + memset(kaddr, 0, PAGE_SIZE);
2063 + kaddr[0] = 0x9DE3BFA8U; /* save */
2064 + flush_dcache_page(vmf->page);
2065 + kunmap(vmf->page);
2066 + return VM_FAULT_MAJOR;
2069 +static struct vm_operations_struct pax_vm_ops = {
2070 + .close = pax_emuplt_close,
2071 + .fault = pax_emuplt_fault
2074 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2078 + vma->vm_mm = current->mm;
2079 + vma->vm_start = addr;
2080 + vma->vm_end = addr + PAGE_SIZE;
2081 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2082 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2083 + vma->vm_ops = &pax_vm_ops;
2085 + ret = insert_vm_struct(current->mm, vma);
2089 + ++current->mm->total_vm;
2095 + * PaX: decide what to do with offenders (regs->tpc = fault address)
2097 + * returns 1 when task should be killed
2098 + * 2 when patched PLT trampoline was detected
2099 + * 3 when unpatched PLT trampoline was detected
2101 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2104 +#ifdef CONFIG_PAX_EMUPLT
2107 + do { /* PaX: patched PLT emulation #1 */
2108 + unsigned int sethi1, sethi2, jmpl;
2110 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2111 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2112 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
2117 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2118 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2119 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2121 + unsigned long addr;
2123 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2124 + addr = regs->u_regs[UREG_G1];
2125 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2127 + regs->tnpc = addr+4;
2132 + { /* PaX: patched PLT emulation #2 */
2135 + err = get_user(ba, (unsigned int *)regs->tpc);
2137 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2138 + unsigned long addr;
2140 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2142 + regs->tnpc = addr+4;
2147 + do { /* PaX: patched PLT emulation #3 */
2148 + unsigned int sethi, jmpl, nop;
2150 + err = get_user(sethi, (unsigned int *)regs->tpc);
2151 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
2152 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2157 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2158 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2159 + nop == 0x01000000U)
2161 + unsigned long addr;
2163 + addr = (sethi & 0x003FFFFFU) << 10;
2164 + regs->u_regs[UREG_G1] = addr;
2165 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2167 + regs->tnpc = addr+4;
2172 + do { /* PaX: patched PLT emulation #4 */
2173 + unsigned int mov1, call, mov2;
2175 + err = get_user(mov1, (unsigned int *)regs->tpc);
2176 + err |= get_user(call, (unsigned int *)(regs->tpc+4));
2177 + err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
2182 + if (mov1 == 0x8210000FU &&
2183 + (call & 0xC0000000U) == 0x40000000U &&
2184 + mov2 == 0x9E100001U)
2186 + unsigned long addr;
2188 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2189 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2191 + regs->tnpc = addr+4;
2196 + do { /* PaX: patched PLT emulation #5 */
2197 + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
2199 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2200 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2201 + err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2202 + err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2203 + err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2204 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2205 + err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2210 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2211 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2212 + (or1 & 0xFFFFE000U) == 0x82106000U &&
2213 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
2214 + sllx == 0x83287020 &&
2215 + jmpl == 0x81C04005U &&
2216 + nop == 0x01000000U)
2218 + unsigned long addr;
2220 + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2221 + regs->u_regs[UREG_G1] <<= 32;
2222 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2223 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2225 + regs->tnpc = addr+4;
2230 + do { /* PaX: patched PLT emulation #6 */
2231 + unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
2233 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2234 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2235 + err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2236 + err |= get_user(or, (unsigned int *)(regs->tpc+12));
2237 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2238 + err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2243 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2244 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2245 + sllx == 0x83287020 &&
2246 + (or & 0xFFFFE000U) == 0x8A116000U &&
2247 + jmpl == 0x81C04005U &&
2248 + nop == 0x01000000U)
2250 + unsigned long addr;
2252 + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2253 + regs->u_regs[UREG_G1] <<= 32;
2254 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2255 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2257 + regs->tnpc = addr+4;
2262 + do { /* PaX: patched PLT emulation #7 */
2263 + unsigned int sethi, ba, nop;
2265 + err = get_user(sethi, (unsigned int *)regs->tpc);
2266 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2267 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2272 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2273 + (ba & 0xFFF00000U) == 0x30600000U &&
2274 + nop == 0x01000000U)
2276 + unsigned long addr;
2278 + addr = (sethi & 0x003FFFFFU) << 10;
2279 + regs->u_regs[UREG_G1] = addr;
2280 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2282 + regs->tnpc = addr+4;
2287 + do { /* PaX: unpatched PLT emulation step 1 */
2288 + unsigned int sethi, ba, nop;
2290 + err = get_user(sethi, (unsigned int *)regs->tpc);
2291 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2292 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2297 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2298 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2299 + nop == 0x01000000U)
2301 + unsigned long addr;
2302 + unsigned int save, call;
2304 + if ((ba & 0xFFC00000U) == 0x30800000U)
2305 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2307 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2309 + err = get_user(save, (unsigned int *)addr);
2310 + err |= get_user(call, (unsigned int *)(addr+4));
2311 + err |= get_user(nop, (unsigned int *)(addr+8));
2315 + if (save == 0x9DE3BFA8U &&
2316 + (call & 0xC0000000U) == 0x40000000U &&
2317 + nop == 0x01000000U)
2319 + struct vm_area_struct *vma;
2320 + unsigned long call_dl_resolve;
2322 + down_read(¤t->mm->mmap_sem);
2323 + call_dl_resolve = current->mm->call_dl_resolve;
2324 + up_read(¤t->mm->mmap_sem);
2325 + if (likely(call_dl_resolve))
2328 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2330 + down_write(¤t->mm->mmap_sem);
2331 + if (current->mm->call_dl_resolve) {
2332 + call_dl_resolve = current->mm->call_dl_resolve;
2333 + up_write(¤t->mm->mmap_sem);
2335 + kmem_cache_free(vm_area_cachep, vma);
2339 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2340 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2341 + up_write(¤t->mm->mmap_sem);
2343 + kmem_cache_free(vm_area_cachep, vma);
2347 + if (pax_insert_vma(vma, call_dl_resolve)) {
2348 + up_write(¤t->mm->mmap_sem);
2349 + kmem_cache_free(vm_area_cachep, vma);
2353 + current->mm->call_dl_resolve = call_dl_resolve;
2354 + up_write(¤t->mm->mmap_sem);
2357 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2358 + regs->tpc = call_dl_resolve;
2359 + regs->tnpc = addr+4;
2365 + do { /* PaX: unpatched PLT emulation step 2 */
2366 + unsigned int save, call, nop;
2368 + err = get_user(save, (unsigned int *)(regs->tpc-4));
2369 + err |= get_user(call, (unsigned int *)regs->tpc);
2370 + err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2374 + if (save == 0x9DE3BFA8U &&
2375 + (call & 0xC0000000U) == 0x40000000U &&
2376 + nop == 0x01000000U)
2378 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2380 + regs->u_regs[UREG_RETPC] = regs->tpc;
2381 + regs->tpc = dl_resolve;
2382 + regs->tnpc = dl_resolve+4;
2391 +void pax_report_insns(void *pc, void *sp)
2395 + printk(KERN_ERR "PAX: bytes at PC: ");
2396 + for (i = 0; i < 5; i++) {
2398 + if (get_user(c, (unsigned int *)pc+i))
2399 + printk(KERN_CONT "???????? ");
2401 + printk(KERN_CONT "%08x ", c);
2407 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2409 struct mm_struct *mm = current->mm;
2410 @@ -302,8 +666,10 @@ asmlinkage void __kprobes do_sparc64_fau
2413 if (test_thread_flag(TIF_32BIT)) {
2414 - if (!(regs->tstate & TSTATE_PRIV))
2415 + if (!(regs->tstate & TSTATE_PRIV)) {
2416 regs->tpc &= 0xffffffff;
2417 + regs->tnpc &= 0xffffffff;
2419 address &= 0xffffffff;
2422 @@ -320,6 +686,29 @@ asmlinkage void __kprobes do_sparc64_fau
2426 +#ifdef CONFIG_PAX_PAGEEXEC
2427 + /* PaX: detect ITLB misses on non-exec pages */
2428 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2429 + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2431 + if (address != regs->tpc)
2434 + up_read(&mm->mmap_sem);
2435 + switch (pax_handle_fetch_fault(regs)) {
2437 +#ifdef CONFIG_PAX_EMUPLT
2444 + pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
2445 + do_group_exit(SIGKILL);
2449 /* Pure DTLB misses do not tell us whether the fault causing
2450 * load/store/atomic was a write or not, it only says that there
2451 * was no match. So in such a case we (carefully) read the
2452 diff -urNp linux-2.6.27.4/arch/sparc64/mm/Makefile linux-2.6.27.4/arch/sparc64/mm/Makefile
2453 --- linux-2.6.27.4/arch/sparc64/mm/Makefile 2008-10-22 17:38:01.000000000 -0400
2454 +++ linux-2.6.27.4/arch/sparc64/mm/Makefile 2008-10-27 22:36:16.000000000 -0400
2458 EXTRA_AFLAGS := -ansi
2459 -EXTRA_CFLAGS := -Werror
2460 +#EXTRA_CFLAGS := -Werror
2462 obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
2464 diff -urNp linux-2.6.27.4/arch/um/sys-i386/syscalls.c linux-2.6.27.4/arch/um/sys-i386/syscalls.c
2465 --- linux-2.6.27.4/arch/um/sys-i386/syscalls.c 2008-10-22 17:38:01.000000000 -0400
2466 +++ linux-2.6.27.4/arch/um/sys-i386/syscalls.c 2008-10-27 22:36:16.000000000 -0400
2468 #include "asm/uaccess.h"
2469 #include "asm/unistd.h"
2471 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
2473 + unsigned long pax_task_size = TASK_SIZE;
2475 +#ifdef CONFIG_PAX_SEGMEXEC
2476 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2477 + pax_task_size = SEGMEXEC_TASK_SIZE;
2480 + if (len > pax_task_size || addr > pax_task_size - len)
2487 * Perform the select(nd, in, out, ex, tv) and mmap() system
2488 * calls. Linux/i386 didn't use to be able to handle more than
2489 diff -urNp linux-2.6.27.4/arch/x86/boot/bitops.h linux-2.6.27.4/arch/x86/boot/bitops.h
2490 --- linux-2.6.27.4/arch/x86/boot/bitops.h 2008-10-22 17:38:01.000000000 -0400
2491 +++ linux-2.6.27.4/arch/x86/boot/bitops.h 2008-10-27 22:36:16.000000000 -0400
2492 @@ -26,7 +26,7 @@ static inline int variable_test_bit(int
2494 const u32 *p = (const u32 *)addr;
2496 - asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2497 + asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2501 @@ -37,7 +37,7 @@ static inline int variable_test_bit(int
2503 static inline void set_bit(int nr, void *addr)
2505 - asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2506 + asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2509 #endif /* BOOT_BITOPS_H */
2510 diff -urNp linux-2.6.27.4/arch/x86/boot/boot.h linux-2.6.27.4/arch/x86/boot/boot.h
2511 --- linux-2.6.27.4/arch/x86/boot/boot.h 2008-10-22 17:38:01.000000000 -0400
2512 +++ linux-2.6.27.4/arch/x86/boot/boot.h 2008-10-27 22:36:16.000000000 -0400
2513 @@ -80,7 +80,7 @@ static inline void io_delay(void)
2514 static inline u16 ds(void)
2517 - asm("movw %%ds,%0" : "=rm" (seg));
2518 + asm volatile("movw %%ds,%0" : "=rm" (seg));
2522 @@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t
2523 static inline int memcmp(const void *s1, const void *s2, size_t len)
2526 - asm("repe; cmpsb; setnz %0"
2527 + asm volatile("repe; cmpsb; setnz %0"
2528 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
2531 diff -urNp linux-2.6.27.4/arch/x86/boot/compressed/head_32.S linux-2.6.27.4/arch/x86/boot/compressed/head_32.S
2532 --- linux-2.6.27.4/arch/x86/boot/compressed/head_32.S 2008-10-22 17:38:01.000000000 -0400
2533 +++ linux-2.6.27.4/arch/x86/boot/compressed/head_32.S 2008-10-27 22:36:16.000000000 -0400
2534 @@ -70,7 +70,7 @@ startup_32:
2535 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
2536 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
2538 - movl $LOAD_PHYSICAL_ADDR, %ebx
2539 + movl $____LOAD_PHYSICAL_ADDR, %ebx
2542 /* Replace the compressed data size with the uncompressed size */
2543 @@ -105,7 +105,7 @@ startup_32:
2544 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
2545 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
2547 - movl $LOAD_PHYSICAL_ADDR, %ebp
2548 + movl $____LOAD_PHYSICAL_ADDR, %ebp
2552 @@ -159,16 +159,15 @@ relocated:
2553 * and where it was actually loaded.
2556 - subl $LOAD_PHYSICAL_ADDR, %ebx
2557 + subl $____LOAD_PHYSICAL_ADDR, %ebx
2558 jz 2f /* Nothing to be done if loaded at compiled addr. */
2560 * Process relocations.
2564 - movl 0(%edi), %ecx
2569 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
2572 diff -urNp linux-2.6.27.4/arch/x86/boot/compressed/misc.c linux-2.6.27.4/arch/x86/boot/compressed/misc.c
2573 --- linux-2.6.27.4/arch/x86/boot/compressed/misc.c 2008-10-22 17:38:01.000000000 -0400
2574 +++ linux-2.6.27.4/arch/x86/boot/compressed/misc.c 2008-10-27 22:36:16.000000000 -0400
2575 @@ -371,7 +371,7 @@ static void parse_elf(void *output)
2577 #ifdef CONFIG_RELOCATABLE
2579 - dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
2580 + dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
2582 dest = (void *)(phdr->p_paddr);
2584 @@ -423,7 +423,7 @@ asmlinkage void decompress_kernel(void *
2585 if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
2586 error("Destination address too large");
2587 #ifndef CONFIG_RELOCATABLE
2588 - if ((u32)output != LOAD_PHYSICAL_ADDR)
2589 + if ((u32)output != ____LOAD_PHYSICAL_ADDR)
2590 error("Wrong destination address");
2593 diff -urNp linux-2.6.27.4/arch/x86/boot/compressed/relocs.c linux-2.6.27.4/arch/x86/boot/compressed/relocs.c
2594 --- linux-2.6.27.4/arch/x86/boot/compressed/relocs.c 2008-10-22 17:38:01.000000000 -0400
2595 +++ linux-2.6.27.4/arch/x86/boot/compressed/relocs.c 2008-10-27 22:36:16.000000000 -0400
2600 +#include "../../../../include/linux/autoconf.h"
2602 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
2603 static Elf32_Ehdr ehdr;
2604 +static Elf32_Phdr *phdr;
2605 static unsigned long reloc_count, reloc_idx;
2606 static unsigned long *relocs;
2608 @@ -245,6 +248,36 @@ static void read_ehdr(FILE *fp)
2612 +static void read_phdrs(FILE *fp)
2616 + phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
2618 + die("Unable to allocate %d program headers\n",
2621 + if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
2622 + die("Seek to %d failed: %s\n",
2623 + ehdr.e_phoff, strerror(errno));
2625 + if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
2626 + die("Cannot read ELF program headers: %s\n",
2629 + for(i = 0; i < ehdr.e_phnum; i++) {
2630 + phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
2631 + phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
2632 + phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
2633 + phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
2634 + phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
2635 + phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
2636 + phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
2637 + phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
2642 static void read_shdrs(FILE *fp)
2645 @@ -341,6 +374,8 @@ static void read_symtabs(FILE *fp)
2646 static void read_relocs(FILE *fp)
2651 for (i = 0; i < ehdr.e_shnum; i++) {
2652 struct section *sec = &secs[i];
2653 if (sec->shdr.sh_type != SHT_REL) {
2654 @@ -360,9 +395,18 @@ static void read_relocs(FILE *fp)
2655 die("Cannot read symbol table: %s\n",
2659 + for (j = 0; j < ehdr.e_phnum; j++) {
2660 + if (phdr[j].p_type != PT_LOAD )
2662 + if (secs[secs[i].shdr.sh_info].shdr.sh_offset < phdr[j].p_offset || secs[secs[i].shdr.sh_info].shdr.sh_offset > phdr[j].p_offset + phdr[j].p_filesz)
2664 + base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
2667 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
2668 Elf32_Rel *rel = &sec->reltab[j];
2669 - rel->r_offset = elf32_to_cpu(rel->r_offset);
2670 + rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
2671 rel->r_info = elf32_to_cpu(rel->r_info);
2674 @@ -504,6 +548,23 @@ static void walk_relocs(void (*visit)(El
2675 if (sym->st_shndx == SHN_ABS) {
2678 + /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
2679 + if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
2681 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
2682 + /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
2683 + if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
2685 + if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
2687 + if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
2688 + if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
2689 + strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
2692 + if (!strcmp(sec_name(sym->st_shndx), ".text"))
2695 if (r_type == R_386_PC32) {
2696 /* PC relative relocations don't need to be adjusted */
2698 @@ -631,6 +692,7 @@ int main(int argc, char **argv)
2699 fname, strerror(errno));
2706 diff -urNp linux-2.6.27.4/arch/x86/boot/cpucheck.c linux-2.6.27.4/arch/x86/boot/cpucheck.c
2707 --- linux-2.6.27.4/arch/x86/boot/cpucheck.c 2008-10-22 17:38:01.000000000 -0400
2708 +++ linux-2.6.27.4/arch/x86/boot/cpucheck.c 2008-10-27 22:36:16.000000000 -0400
2709 @@ -74,7 +74,7 @@ static int has_fpu(void)
2710 u16 fcw = -1, fsw = -1;
2713 - asm("movl %%cr0,%0" : "=r" (cr0));
2714 + asm volatile("movl %%cr0,%0" : "=r" (cr0));
2715 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
2716 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
2717 asm volatile("movl %0,%%cr0" : : "r" (cr0));
2718 @@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
2723 + asm volatile("pushfl ; "
2727 @@ -115,7 +115,7 @@ static void get_flags(void)
2728 set_bit(X86_FEATURE_FPU, cpu.flags);
2730 if (has_eflag(X86_EFLAGS_ID)) {
2732 + asm volatile("cpuid"
2733 : "=a" (max_intel_level),
2734 "=b" (cpu_vendor[0]),
2735 "=d" (cpu_vendor[1]),
2736 @@ -124,7 +124,7 @@ static void get_flags(void)
2738 if (max_intel_level >= 0x00000001 &&
2739 max_intel_level <= 0x0000ffff) {
2741 + asm volatile("cpuid"
2743 "=c" (cpu.flags[4]),
2745 @@ -136,7 +136,7 @@ static void get_flags(void)
2746 cpu.model += ((tfms >> 16) & 0xf) << 4;
2750 + asm volatile("cpuid"
2751 : "=a" (max_amd_level)
2753 : "ebx", "ecx", "edx");
2754 @@ -144,7 +144,7 @@ static void get_flags(void)
2755 if (max_amd_level >= 0x80000001 &&
2756 max_amd_level <= 0x8000ffff) {
2757 u32 eax = 0x80000001;
2759 + asm volatile("cpuid"
2761 "=c" (cpu.flags[6]),
2763 @@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
2764 u32 ecx = MSR_K7_HWCR;
2767 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
2768 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
2770 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
2771 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
2773 get_flags(); /* Make sure it really did something */
2774 err = check_flags();
2775 @@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
2776 u32 ecx = MSR_VIA_FCR;
2779 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
2780 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
2781 eax |= (1<<1)|(1<<7);
2782 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
2783 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
2785 set_bit(X86_FEATURE_CX8, cpu.flags);
2786 err = check_flags();
2787 @@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
2791 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
2792 - asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
2794 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
2795 + asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
2796 + asm volatile("cpuid"
2797 : "+a" (level), "=d" (cpu.flags[0])
2799 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
2800 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
2802 err = check_flags();
2804 diff -urNp linux-2.6.27.4/arch/x86/boot/edd.c linux-2.6.27.4/arch/x86/boot/edd.c
2805 --- linux-2.6.27.4/arch/x86/boot/edd.c 2008-10-22 17:38:01.000000000 -0400
2806 +++ linux-2.6.27.4/arch/x86/boot/edd.c 2008-10-27 22:36:16.000000000 -0400
2807 @@ -76,7 +76,7 @@ static int get_edd_info(u8 devno, struct
2811 - asm("pushfl; stc; int $0x13; setc %%al; popfl"
2812 + asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
2813 : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
2816 @@ -95,7 +95,7 @@ static int get_edd_info(u8 devno, struct
2817 ei->params.length = sizeof(ei->params);
2820 - asm("pushfl; int $0x13; popfl"
2821 + asm volatile("pushfl; int $0x13; popfl"
2822 : "+a" (ax), "+d" (dx), "=m" (ei->params)
2824 : "ebx", "ecx", "edi");
2825 @@ -106,7 +106,7 @@ static int get_edd_info(u8 devno, struct
2829 - asm("pushw %%es; "
2830 + asm volatile("pushw %%es; "
2832 "pushfl; stc; int $0x13; setc %%al; popfl; "
2834 diff -urNp linux-2.6.27.4/arch/x86/boot/main.c linux-2.6.27.4/arch/x86/boot/main.c
2835 --- linux-2.6.27.4/arch/x86/boot/main.c 2008-10-22 17:38:01.000000000 -0400
2836 +++ linux-2.6.27.4/arch/x86/boot/main.c 2008-10-27 22:36:16.000000000 -0400
2837 @@ -78,7 +78,7 @@ static void query_ist(void)
2842 + asm volatile("int $0x15"
2843 : "=a" (boot_params.ist_info.signature),
2844 "=b" (boot_params.ist_info.command),
2845 "=c" (boot_params.ist_info.event),
2846 diff -urNp linux-2.6.27.4/arch/x86/boot/mca.c linux-2.6.27.4/arch/x86/boot/mca.c
2847 --- linux-2.6.27.4/arch/x86/boot/mca.c 2008-10-22 17:38:01.000000000 -0400
2848 +++ linux-2.6.27.4/arch/x86/boot/mca.c 2008-10-27 22:36:16.000000000 -0400
2849 @@ -19,7 +19,7 @@ int query_mca(void)
2853 - asm("pushw %%es ; "
2854 + asm volatile("pushw %%es ; "
2858 diff -urNp linux-2.6.27.4/arch/x86/boot/memory.c linux-2.6.27.4/arch/x86/boot/memory.c
2859 --- linux-2.6.27.4/arch/x86/boot/memory.c 2008-10-22 17:38:01.000000000 -0400
2860 +++ linux-2.6.27.4/arch/x86/boot/memory.c 2008-10-27 22:36:16.000000000 -0400
2861 @@ -30,7 +30,7 @@ static int detect_memory_e820(void)
2862 /* Important: %edx is clobbered by some BIOSes,
2863 so it must be either used for the error output
2864 or explicitly marked clobbered. */
2865 - asm("int $0x15; setc %0"
2866 + asm volatile("int $0x15; setc %0"
2867 : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
2869 : "D" (desc), "d" (SMAP), "a" (0xe820));
2870 @@ -65,7 +65,7 @@ static int detect_memory_e801(void)
2874 - asm("stc; int $0x15; setc %0"
2875 + asm volatile("stc; int $0x15; setc %0"
2876 : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
2879 @@ -95,7 +95,7 @@ static int detect_memory_88(void)
2883 - asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
2884 + asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
2886 boot_params.screen_info.ext_mem_k = ax;
2888 diff -urNp linux-2.6.27.4/arch/x86/boot/video.c linux-2.6.27.4/arch/x86/boot/video.c
2889 --- linux-2.6.27.4/arch/x86/boot/video.c 2008-10-22 17:38:01.000000000 -0400
2890 +++ linux-2.6.27.4/arch/x86/boot/video.c 2008-10-27 22:36:16.000000000 -0400
2891 @@ -23,7 +23,7 @@ static void store_cursor_position(void)
2896 + asm volatile(INT10
2897 : "=d" (curpos), "+a" (ax), "+b" (bx)
2898 : : "ecx", "esi", "edi");
2900 @@ -38,7 +38,7 @@ static void store_video_mode(void)
2901 /* N.B.: the saving of the video page here is a bit silly,
2902 since we pretty much assume page 0 everywhere. */
2905 + asm volatile(INT10
2906 : "+a" (ax), "=b" (page)
2907 : : "ecx", "edx", "esi", "edi");
2909 diff -urNp linux-2.6.27.4/arch/x86/boot/video-vesa.c linux-2.6.27.4/arch/x86/boot/video-vesa.c
2910 --- linux-2.6.27.4/arch/x86/boot/video-vesa.c 2008-10-22 17:38:01.000000000 -0400
2911 +++ linux-2.6.27.4/arch/x86/boot/video-vesa.c 2008-10-27 22:36:16.000000000 -0400
2912 @@ -41,7 +41,7 @@ static int vesa_probe(void)
2915 di = (size_t)&vginfo;
2917 + asm volatile(INT10
2918 : "+a" (ax), "+D" (di), "=m" (vginfo)
2919 : : "ebx", "ecx", "edx", "esi");
2921 @@ -68,7 +68,7 @@ static int vesa_probe(void)
2924 di = (size_t)&vminfo;
2926 + asm volatile(INT10
2927 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
2928 : : "ebx", "edx", "esi");
2930 @@ -123,7 +123,7 @@ static int vesa_set_mode(struct mode_inf
2933 di = (size_t)&vminfo;
2935 + asm volatile(INT10
2936 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
2937 : : "ebx", "edx", "esi");
2939 @@ -203,19 +203,20 @@ static void vesa_dac_set_8bits(void)
2940 /* Save the VESA protected mode info */
2941 static void vesa_store_pm_info(void)
2943 - u16 ax, bx, di, es;
2944 + u16 ax, bx, cx, di, es;
2948 - asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
2949 - : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
2950 - : : "ecx", "esi");
2952 + asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
2953 + : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
2959 boot_params.screen_info.vesapm_seg = es;
2960 boot_params.screen_info.vesapm_off = di;
2961 + boot_params.screen_info.vesapm_size = cx;
2965 @@ -269,7 +270,7 @@ void vesa_store_edid(void)
2966 /* Note: The VBE DDC spec is different from the main VESA spec;
2967 we genuinely have to assume all registers are destroyed here. */
2969 - asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
2970 + asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
2971 : "+a" (ax), "+b" (bx)
2972 : "c" (cx), "D" (di)
2974 @@ -285,7 +286,7 @@ void vesa_store_edid(void)
2975 cx = 0; /* Controller 0 */
2976 dx = 0; /* EDID block number */
2977 di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
2979 + asm volatile(INT10
2980 : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
2981 : "c" (cx), "D" (di)
2983 diff -urNp linux-2.6.27.4/arch/x86/boot/video-vga.c linux-2.6.27.4/arch/x86/boot/video-vga.c
2984 --- linux-2.6.27.4/arch/x86/boot/video-vga.c 2008-10-22 17:38:01.000000000 -0400
2985 +++ linux-2.6.27.4/arch/x86/boot/video-vga.c 2008-10-27 22:36:16.000000000 -0400
2986 @@ -225,7 +225,7 @@ static int vga_probe(void)
2991 + asm volatile(INT10
2993 : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
2994 : "ecx", "edx", "esi", "edi");
2995 @@ -237,7 +237,7 @@ static int vga_probe(void)
2996 /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
2997 if ((u8)ega_bx != 0x10) {
3000 + asm volatile(INT10
3003 : "ebx", "ecx", "edx", "esi", "edi");
3004 diff -urNp linux-2.6.27.4/arch/x86/boot/voyager.c linux-2.6.27.4/arch/x86/boot/voyager.c
3005 --- linux-2.6.27.4/arch/x86/boot/voyager.c 2008-10-22 17:38:01.000000000 -0400
3006 +++ linux-2.6.27.4/arch/x86/boot/voyager.c 2008-10-27 22:36:16.000000000 -0400
3007 @@ -23,7 +23,7 @@ int query_voyager(void)
3009 data_ptr[0] = 0xff; /* Flag on config not found(?) */
3011 - asm("pushw %%es ; "
3012 + asm volatile("pushw %%es ; "
3016 diff -urNp linux-2.6.27.4/arch/x86/ia32/ia32_signal.c linux-2.6.27.4/arch/x86/ia32/ia32_signal.c
3017 --- linux-2.6.27.4/arch/x86/ia32/ia32_signal.c 2008-10-22 17:38:01.000000000 -0400
3018 +++ linux-2.6.27.4/arch/x86/ia32/ia32_signal.c 2008-10-27 22:36:16.000000000 -0400
3019 @@ -535,6 +535,7 @@ int ia32_setup_rt_frame(int sig, struct
3020 __NR_ia32_rt_sigreturn,
3026 frame = get_sigframe(ka, regs, sizeof(*frame));
3027 diff -urNp linux-2.6.27.4/arch/x86/Kconfig linux-2.6.27.4/arch/x86/Kconfig
3028 --- linux-2.6.27.4/arch/x86/Kconfig 2008-10-22 17:38:01.000000000 -0400
3029 +++ linux-2.6.27.4/arch/x86/Kconfig 2008-10-27 22:36:16.000000000 -0400
3030 @@ -912,7 +912,7 @@ config PAGE_OFFSET
3032 default 0xB0000000 if VMSPLIT_3G_OPT
3033 default 0x80000000 if VMSPLIT_2G
3034 - default 0x78000000 if VMSPLIT_2G_OPT
3035 + default 0x70000000 if VMSPLIT_2G_OPT
3036 default 0x40000000 if VMSPLIT_1G
3039 @@ -1273,8 +1273,7 @@ config KEXEC_JUMP
3040 config PHYSICAL_START
3041 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
3042 default "0x1000000" if X86_NUMAQ
3043 - default "0x200000" if X86_64
3044 - default "0x100000"
3045 + default "0x200000"
3047 This gives the physical address where the kernel is loaded.
3049 @@ -1366,9 +1365,9 @@ config HOTPLUG_CPU
3055 prompt "Compat VDSO support"
3056 - depends on X86_32 || IA32_EMULATION
3057 + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
3059 Map the 32-bit VDSO to the predictable old-style address too.
3061 diff -urNp linux-2.6.27.4/arch/x86/Kconfig.cpu linux-2.6.27.4/arch/x86/Kconfig.cpu
3062 --- linux-2.6.27.4/arch/x86/Kconfig.cpu 2008-10-22 17:38:01.000000000 -0400
3063 +++ linux-2.6.27.4/arch/x86/Kconfig.cpu 2008-10-27 22:36:16.000000000 -0400
3064 @@ -340,7 +340,7 @@ config X86_PPRO_FENCE
3068 - depends on M586MMX || M586TSC || M586 || M486 || M386
3069 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
3071 config X86_WP_WORKS_OK
3073 @@ -360,7 +360,7 @@ config X86_POPAD_OK
3075 config X86_ALIGNMENT_16
3077 - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3078 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3080 config X86_INTEL_USERCOPY
3082 @@ -406,7 +406,7 @@ config X86_CMPXCHG64
3086 - depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
3087 + depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
3089 config X86_MINIMUM_CPU_FAMILY
3091 diff -urNp linux-2.6.27.4/arch/x86/Kconfig.debug linux-2.6.27.4/arch/x86/Kconfig.debug
3092 --- linux-2.6.27.4/arch/x86/Kconfig.debug 2008-10-22 17:38:01.000000000 -0400
3093 +++ linux-2.6.27.4/arch/x86/Kconfig.debug 2008-10-27 22:36:16.000000000 -0400
3094 @@ -94,7 +94,7 @@ config X86_PTDUMP
3096 bool "Write protect kernel read-only data structures"
3098 - depends on DEBUG_KERNEL
3099 + depends on DEBUG_KERNEL && BROKEN
3101 Mark the kernel read-only data as write-protected in the pagetables,
3102 in order to catch accidental (and incorrect) writes to such const
3103 diff -urNp linux-2.6.27.4/arch/x86/kernel/acpi/boot.c linux-2.6.27.4/arch/x86/kernel/acpi/boot.c
3104 --- linux-2.6.27.4/arch/x86/kernel/acpi/boot.c 2008-10-22 17:38:01.000000000 -0400
3105 +++ linux-2.6.27.4/arch/x86/kernel/acpi/boot.c 2008-10-27 22:36:16.000000000 -0400
3106 @@ -1635,7 +1635,7 @@ static struct dmi_system_id __initdata a
3107 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
3111 + { NULL, NULL, {{0, NULL}}, NULL}
3115 diff -urNp linux-2.6.27.4/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.27.4/arch/x86/kernel/acpi/realmode/wakeup.S
3116 --- linux-2.6.27.4/arch/x86/kernel/acpi/realmode/wakeup.S 2008-10-22 17:38:01.000000000 -0400
3117 +++ linux-2.6.27.4/arch/x86/kernel/acpi/realmode/wakeup.S 2008-10-27 22:36:16.000000000 -0400
3118 @@ -104,7 +104,7 @@ _start:
3122 - movl $0xc0000080, %ecx
3123 + mov $MSR_EFER, %ecx
3127 diff -urNp linux-2.6.27.4/arch/x86/kernel/acpi/sleep.c linux-2.6.27.4/arch/x86/kernel/acpi/sleep.c
3128 --- linux-2.6.27.4/arch/x86/kernel/acpi/sleep.c 2008-10-27 22:25:00.000000000 -0400
3129 +++ linux-2.6.27.4/arch/x86/kernel/acpi/sleep.c 2008-10-27 22:36:16.000000000 -0400
3130 @@ -37,6 +37,10 @@ int acpi_save_state_mem(void)
3132 struct wakeup_header *header;
3134 +#ifdef CONFIG_PAX_KERNEXEC
3135 + unsigned long cr0;
3138 if (!acpi_realmode) {
3139 printk(KERN_ERR "Could not allocate memory during boot, "
3141 @@ -99,8 +103,18 @@ int acpi_save_state_mem(void)
3142 header->trampoline_segment = setup_trampoline() >> 4;
3144 stack_start.sp = temp_stack + 4096;
3146 +#ifdef CONFIG_PAX_KERNEXEC
3147 + pax_open_kernel(cr0);
3150 early_gdt_descr.address =
3151 (unsigned long)get_cpu_gdt_table(smp_processor_id());
3153 +#ifdef CONFIG_PAX_KERNEXEC
3154 + pax_close_kernel(cr0);
3158 initial_code = (unsigned long)wakeup_long64;
3159 saved_magic = 0x123456789abcdef0;
3160 diff -urNp linux-2.6.27.4/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.27.4/arch/x86/kernel/acpi/wakeup_32.S
3161 --- linux-2.6.27.4/arch/x86/kernel/acpi/wakeup_32.S 2008-10-22 17:38:01.000000000 -0400
3162 +++ linux-2.6.27.4/arch/x86/kernel/acpi/wakeup_32.S 2008-10-27 22:36:16.000000000 -0400
3163 @@ -30,13 +30,11 @@ wakeup_pmode_return:
3164 # and restore the stack ... but you need gdt for this to work
3165 movl saved_context_esp, %esp
3167 - movl %cs:saved_magic, %eax
3168 - cmpl $0x12345678, %eax
3169 + cmpl $0x12345678, saved_magic
3172 # jump to place where we left off
3173 - movl saved_eip, %eax
3179 diff -urNp linux-2.6.27.4/arch/x86/kernel/alternative.c linux-2.6.27.4/arch/x86/kernel/alternative.c
3180 --- linux-2.6.27.4/arch/x86/kernel/alternative.c 2008-10-22 17:38:01.000000000 -0400
3181 +++ linux-2.6.27.4/arch/x86/kernel/alternative.c 2008-10-27 22:36:16.000000000 -0400
3182 @@ -393,7 +393,7 @@ void apply_paravirt(struct paravirt_patc
3184 BUG_ON(p->len > MAX_PATCH_LEN);
3185 /* prep the buffer with the original instructions */
3186 - memcpy(insnbuf, p->instr, p->len);
3187 + memcpy(insnbuf, ktla_ktva(p->instr), p->len);
3188 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
3189 (unsigned long)p->instr, p->len);
3191 @@ -473,11 +473,26 @@ void __init alternative_instructions(voi
3192 * instructions. And on the local CPU you need to be protected again NMI or MCE
3193 * handlers seeing an inconsistent instruction while you patch.
3195 -void *text_poke_early(void *addr, const void *opcode, size_t len)
3196 +void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
3198 unsigned long flags;
3200 +#ifdef CONFIG_PAX_KERNEXEC
3201 + unsigned long cr0;
3204 local_irq_save(flags);
3205 - memcpy(addr, opcode, len);
3207 +#ifdef CONFIG_PAX_KERNEXEC
3208 + pax_open_kernel(cr0);
3211 + memcpy(ktla_ktva(addr), opcode, len);
3213 +#ifdef CONFIG_PAX_KERNEXEC
3214 + pax_close_kernel(cr0);
3217 local_irq_restore(flags);
3219 /* Could also do a CLFLUSH here to speed up CPU recovery; but
3220 @@ -498,33 +513,27 @@ void *text_poke_early(void *addr, const
3222 void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
3224 - unsigned long flags;
3227 + unsigned char *vaddr = ktla_ktva(addr);
3228 struct page *pages[2];
3232 + if (!core_kernel_text((unsigned long)addr)
3234 - if (!core_kernel_text((unsigned long)addr)) {
3235 - pages[0] = vmalloc_to_page(addr);
3236 - pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
3237 +#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
3238 + && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
3242 + pages[0] = vmalloc_to_page(vaddr);
3243 + pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
3245 - pages[0] = virt_to_page(addr);
3246 + pages[0] = virt_to_page(vaddr);
3247 WARN_ON(!PageReserved(pages[0]));
3248 - pages[1] = virt_to_page(addr + PAGE_SIZE);
3249 + pages[1] = virt_to_page(vaddr + PAGE_SIZE);
3254 - vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
3256 - local_irq_save(flags);
3257 - memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
3258 - local_irq_restore(flags);
3261 - /* Could also do a CLFLUSH here to speed up CPU recovery; but
3262 - that causes hangs on some VIA CPUs. */
3263 + text_poke_early(addr, opcode, len);
3264 for (i = 0; i < len; i++)
3265 - BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
3266 + BUG_ON((vaddr)[i] != ((unsigned char *)opcode)[i]);
3269 diff -urNp linux-2.6.27.4/arch/x86/kernel/apm_32.c linux-2.6.27.4/arch/x86/kernel/apm_32.c
3270 --- linux-2.6.27.4/arch/x86/kernel/apm_32.c 2008-10-22 17:38:01.000000000 -0400
3271 +++ linux-2.6.27.4/arch/x86/kernel/apm_32.c 2008-10-27 22:36:16.000000000 -0400
3272 @@ -408,7 +408,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
3273 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
3274 static struct apm_user *user_list;
3275 static DEFINE_SPINLOCK(user_list_lock);
3276 -static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
3277 +static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
3279 static const char driver_version[] = "1.16ac"; /* no spaces */
3281 @@ -603,19 +603,42 @@ static u8 apm_bios_call(u32 func, u32 eb
3282 struct desc_struct save_desc_40;
3283 struct desc_struct *gdt;
3285 +#ifdef CONFIG_PAX_KERNEXEC
3286 + unsigned long cr0;
3289 cpus = apm_save_cpus();
3292 gdt = get_cpu_gdt_table(cpu);
3293 save_desc_40 = gdt[0x40 / 8];
3295 +#ifdef CONFIG_PAX_KERNEXEC
3296 + pax_open_kernel(cr0);
3299 gdt[0x40 / 8] = bad_bios_desc;
3301 +#ifdef CONFIG_PAX_KERNEXEC
3302 + pax_close_kernel(cr0);
3305 apm_irq_save(flags);
3307 apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
3308 APM_DO_RESTORE_SEGS;
3309 apm_irq_restore(flags);
3311 +#ifdef CONFIG_PAX_KERNEXEC
3312 + pax_open_kernel(cr0);
3315 gdt[0x40 / 8] = save_desc_40;
3317 +#ifdef CONFIG_PAX_KERNEXEC
3318 + pax_close_kernel(cr0);
3322 apm_restore_cpus(cpus);
3324 @@ -646,19 +669,42 @@ static u8 apm_bios_call_simple(u32 func,
3325 struct desc_struct save_desc_40;
3326 struct desc_struct *gdt;
3328 +#ifdef CONFIG_PAX_KERNEXEC
3329 + unsigned long cr0;
3332 cpus = apm_save_cpus();
3335 gdt = get_cpu_gdt_table(cpu);
3336 save_desc_40 = gdt[0x40 / 8];
3338 +#ifdef CONFIG_PAX_KERNEXEC
3339 + pax_open_kernel(cr0);
3342 gdt[0x40 / 8] = bad_bios_desc;
3344 +#ifdef CONFIG_PAX_KERNEXEC
3345 + pax_close_kernel(cr0);
3348 apm_irq_save(flags);
3350 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
3351 APM_DO_RESTORE_SEGS;
3352 apm_irq_restore(flags);
3354 +#ifdef CONFIG_PAX_KERNEXEC
3355 + pax_open_kernel(cr0);
3358 gdt[0x40 / 8] = save_desc_40;
3360 +#ifdef CONFIG_PAX_KERNEXEC
3361 + pax_close_kernel(cr0);
3365 apm_restore_cpus(cpus);
3367 @@ -930,7 +976,7 @@ recalc:
3369 static void apm_power_off(void)
3371 - unsigned char po_bios_call[] = {
3372 + const unsigned char po_bios_call[] = {
3373 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
3374 0x8e, 0xd0, /* movw ax,ss */
3375 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
3376 @@ -1877,7 +1923,10 @@ static const struct file_operations apm_
3377 static struct miscdevice apm_device = {
3388 @@ -2198,7 +2247,7 @@ static struct dmi_system_id __initdata a
3389 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
3393 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
3397 @@ -2216,6 +2265,10 @@ static int __init apm_init(void)
3398 struct desc_struct *gdt;
3401 +#ifdef CONFIG_PAX_KERNEXEC
3402 + unsigned long cr0;
3405 dmi_check_system(apm_dmi_table);
3407 if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
3408 @@ -2289,9 +2342,18 @@ static int __init apm_init(void)
3409 * This is for buggy BIOS's that refer to (real mode) segment 0x40
3410 * even though they are called in protected mode.
3413 +#ifdef CONFIG_PAX_KERNEXEC
3414 + pax_open_kernel(cr0);
3417 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
3418 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
3420 +#ifdef CONFIG_PAX_KERNEXEC
3421 + pax_close_kernel(cr0);
3425 * Set up the long jump entry point to the APM BIOS, which is called
3426 * from inline assembly.
3427 @@ -2310,6 +2372,11 @@ static int __init apm_init(void)
3430 gdt = get_cpu_gdt_table(0);
3432 +#ifdef CONFIG_PAX_KERNEXEC
3433 + pax_open_kernel(cr0);
3436 set_base(gdt[APM_CS >> 3],
3437 __va((unsigned long)apm_info.bios.cseg << 4));
3438 set_base(gdt[APM_CS_16 >> 3],
3439 @@ -2317,6 +2384,10 @@ static int __init apm_init(void)
3440 set_base(gdt[APM_DS >> 3],
3441 __va((unsigned long)apm_info.bios.dseg << 4));
3443 +#ifdef CONFIG_PAX_KERNEXEC
3444 + pax_close_kernel(cr0);
3447 proc_create("apm", 0, NULL, &apm_file_ops);
3449 kapmd_task = kthread_create(apm, NULL, "kapmd");
3450 diff -urNp linux-2.6.27.4/arch/x86/kernel/asm-offsets_32.c linux-2.6.27.4/arch/x86/kernel/asm-offsets_32.c
3451 --- linux-2.6.27.4/arch/x86/kernel/asm-offsets_32.c 2008-10-22 17:38:01.000000000 -0400
3452 +++ linux-2.6.27.4/arch/x86/kernel/asm-offsets_32.c 2008-10-27 22:36:16.000000000 -0400
3453 @@ -100,6 +100,7 @@ void foo(void)
3454 DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
3455 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
3456 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
3457 + DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
3459 OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
3461 @@ -113,6 +114,7 @@ void foo(void)
3462 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
3463 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
3464 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
3465 + OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
3469 diff -urNp linux-2.6.27.4/arch/x86/kernel/asm-offsets_64.c linux-2.6.27.4/arch/x86/kernel/asm-offsets_64.c
3470 --- linux-2.6.27.4/arch/x86/kernel/asm-offsets_64.c 2008-10-22 17:38:01.000000000 -0400
3471 +++ linux-2.6.27.4/arch/x86/kernel/asm-offsets_64.c 2008-10-27 22:36:16.000000000 -0400
3472 @@ -122,6 +122,7 @@ int main(void)
3476 + DEFINE(TSS_size, sizeof(struct tss_struct));
3477 DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
3479 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
3480 diff -urNp linux-2.6.27.4/arch/x86/kernel/cpu/common_64.c linux-2.6.27.4/arch/x86/kernel/cpu/common_64.c
3481 --- linux-2.6.27.4/arch/x86/kernel/cpu/common_64.c 2008-10-22 17:38:01.000000000 -0400
3482 +++ linux-2.6.27.4/arch/x86/kernel/cpu/common_64.c 2008-10-27 22:36:16.000000000 -0400
3487 -/* We need valid kernel segments for data and code in long mode too
3488 - * IRET will check the segment types kkeil 2000/10/28
3489 - * Also sysret mandates a special GDT layout
3491 -/* The TLS descriptors are currently at a different place compared to i386.
3492 - Hopefully nobody expects them at a fixed place (Wine?) */
3493 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
3494 - [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
3495 - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
3496 - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
3497 - [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
3498 - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
3499 - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
3501 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
3503 __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
3505 /* Current gdt points %fs at the "master" per-cpu area: after this,
3506 @@ -457,15 +441,13 @@ cpumask_t cpu_initialized __cpuinitdata
3507 struct x8664_pda **_cpu_pda __read_mostly;
3508 EXPORT_SYMBOL(_cpu_pda);
3510 -struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
3511 +struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
3513 char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
3515 unsigned long __supported_pte_mask __read_mostly = ~0UL;
3516 EXPORT_SYMBOL_GPL(__supported_pte_mask);
3518 -static int do_not_nx __cpuinitdata;
3521 Control non executable mappings for 64bit processes.
3523 @@ -478,9 +460,7 @@ static int __init nonx_setup(char *str)
3525 if (!strncmp(str, "on", 2)) {
3526 __supported_pte_mask |= _PAGE_NX;
3528 } else if (!strncmp(str, "off", 3)) {
3530 __supported_pte_mask &= ~_PAGE_NX;
3533 @@ -576,7 +556,7 @@ void __cpuinit check_efer(void)
3536 rdmsrl(MSR_EFER, efer);
3537 - if (!(efer & EFER_NX) || do_not_nx)
3538 + if (!(efer & EFER_NX))
3539 __supported_pte_mask &= ~_PAGE_NX;
3542 @@ -598,7 +578,7 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
3543 void __cpuinit cpu_init(void)
3545 int cpu = stack_smp_processor_id();
3546 - struct tss_struct *t = &per_cpu(init_tss, cpu);
3547 + struct tss_struct *t = init_tss + cpu;
3548 struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
3550 char *estacks = NULL;
3551 diff -urNp linux-2.6.27.4/arch/x86/kernel/cpu/common.c linux-2.6.27.4/arch/x86/kernel/cpu/common.c
3552 --- linux-2.6.27.4/arch/x86/kernel/cpu/common.c 2008-10-22 17:38:01.000000000 -0400
3553 +++ linux-2.6.27.4/arch/x86/kernel/cpu/common.c 2008-10-27 22:36:16.000000000 -0400
3555 #include <linux/smp.h>
3556 #include <linux/module.h>
3557 #include <linux/percpu.h>
3558 -#include <linux/bootmem.h>
3559 #include <asm/processor.h>
3560 #include <asm/i387.h>
3561 #include <asm/msr.h>
3566 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
3567 - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
3568 - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
3569 - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
3570 - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
3572 - * Segments used for calling PnP BIOS have byte granularity.
3573 - * They code segments and data segments have fixed 64k limits,
3574 - * the transfer segment sizes are set at run time.
3577 - [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
3579 - [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
3581 - [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
3583 - [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
3585 - [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
3587 - * The APM segments have byte granularity and their bases
3588 - * are set at run time. All have 64k limits.
3591 - [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
3593 - [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
3595 - [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
3597 - [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
3598 - [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
3600 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
3602 __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
3604 static int cachesize_override __cpuinitdata = -1;
3605 @@ -493,6 +456,10 @@ static void __cpuinit identify_cpu(struc
3606 * we do "generic changes."
3609 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
3610 + setup_clear_cpu_cap(X86_FEATURE_SEP);
3613 /* If the model name is still unset, do table lookup. */
3614 if (!c->x86_model_id[0]) {
3616 @@ -629,7 +596,7 @@ static __init int setup_disablecpuid(cha
3618 __setup("clearcpuid=", setup_disablecpuid);
3620 -cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
3621 +cpumask_t cpu_initialized = CPU_MASK_NONE;
3623 void __init early_cpu_init(void)
3625 @@ -658,7 +625,7 @@ void switch_to_new_gdt(void)
3627 struct desc_ptr gdt_descr;
3629 - gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
3630 + gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
3631 gdt_descr.size = GDT_SIZE - 1;
3632 load_gdt(&gdt_descr);
3633 asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
3634 @@ -674,7 +641,7 @@ void __cpuinit cpu_init(void)
3636 int cpu = smp_processor_id();
3637 struct task_struct *curr = current;
3638 - struct tss_struct *t = &per_cpu(init_tss, cpu);
3639 + struct tss_struct *t = init_tss + cpu;
3640 struct thread_struct *thread = &curr->thread;
3642 if (cpu_test_and_set(cpu, cpu_initialized)) {
3643 @@ -729,7 +696,7 @@ void __cpuinit cpu_init(void)
3646 #ifdef CONFIG_HOTPLUG_CPU
3647 -void __cpuinit cpu_uninit(void)
3648 +void cpu_uninit(void)
3650 int cpu = raw_smp_processor_id();
3651 cpu_clear(cpu, cpu_initialized);
3652 diff -urNp linux-2.6.27.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.27.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
3653 --- linux-2.6.27.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-10-22 17:38:01.000000000 -0400
3654 +++ linux-2.6.27.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-10-27 22:36:16.000000000 -0400
3655 @@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
3656 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
3660 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
3664 diff -urNp linux-2.6.27.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.27.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
3665 --- linux-2.6.27.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-10-22 17:38:01.000000000 -0400
3666 +++ linux-2.6.27.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-10-27 22:36:16.000000000 -0400
3667 @@ -225,7 +225,7 @@ static struct cpu_model models[] =
3668 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
3669 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
3672 + { NULL, NULL, 0, NULL}
3676 diff -urNp linux-2.6.27.4/arch/x86/kernel/cpu/intel.c linux-2.6.27.4/arch/x86/kernel/cpu/intel.c
3677 --- linux-2.6.27.4/arch/x86/kernel/cpu/intel.c 2008-10-22 17:38:01.000000000 -0400
3678 +++ linux-2.6.27.4/arch/x86/kernel/cpu/intel.c 2008-10-27 22:36:16.000000000 -0400
3679 @@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
3680 * Update the IDT descriptor and reload the IDT so that
3681 * it uses the read-only mapped virtual address.
3683 - idt_descr.address = fix_to_virt(FIX_F00F_IDT);
3684 + idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
3685 load_idt(&idt_descr);
3688 diff -urNp linux-2.6.27.4/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.27.4/arch/x86/kernel/cpu/mcheck/mce_64.c
3689 --- linux-2.6.27.4/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-10-22 17:38:01.000000000 -0400
3690 +++ linux-2.6.27.4/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-10-27 22:36:16.000000000 -0400
3691 @@ -681,6 +681,7 @@ static struct miscdevice mce_log_device
3695 + {NULL, NULL}, NULL, NULL
3698 static unsigned long old_cr4 __initdata;
3699 diff -urNp linux-2.6.27.4/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.27.4/arch/x86/kernel/cpu/mtrr/generic.c
3700 --- linux-2.6.27.4/arch/x86/kernel/cpu/mtrr/generic.c 2008-10-22 17:38:01.000000000 -0400
3701 +++ linux-2.6.27.4/arch/x86/kernel/cpu/mtrr/generic.c 2008-10-27 22:36:16.000000000 -0400
3702 @@ -31,11 +31,11 @@ static struct fixed_range_block fixed_ra
3703 { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
3704 { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
3705 { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
3710 static unsigned long smp_changes_mask;
3711 -static struct mtrr_state mtrr_state = {};
3712 +static struct mtrr_state mtrr_state;
3713 static int mtrr_state_set;
3716 diff -urNp linux-2.6.27.4/arch/x86/kernel/crash.c linux-2.6.27.4/arch/x86/kernel/crash.c
3717 --- linux-2.6.27.4/arch/x86/kernel/crash.c 2008-10-22 17:38:01.000000000 -0400
3718 +++ linux-2.6.27.4/arch/x86/kernel/crash.c 2008-10-27 22:36:16.000000000 -0400
3719 @@ -59,7 +59,7 @@ static int crash_nmi_callback(struct not
3720 local_irq_disable();
3722 #ifdef CONFIG_X86_32
3723 - if (!user_mode_vm(regs)) {
3724 + if (!user_mode(regs)) {
3725 crash_fixup_ss_esp(&fixed_regs, regs);
3728 diff -urNp linux-2.6.27.4/arch/x86/kernel/doublefault_32.c linux-2.6.27.4/arch/x86/kernel/doublefault_32.c
3729 --- linux-2.6.27.4/arch/x86/kernel/doublefault_32.c 2008-10-22 17:38:01.000000000 -0400
3730 +++ linux-2.6.27.4/arch/x86/kernel/doublefault_32.c 2008-10-27 22:36:16.000000000 -0400
3733 #define DOUBLEFAULT_STACKSIZE (1024)
3734 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
3735 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
3736 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
3738 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
3740 @@ -21,7 +21,7 @@ static void doublefault_fn(void)
3741 unsigned long gdt, tss;
3743 store_gdt(&gdt_desc);
3744 - gdt = gdt_desc.address;
3745 + gdt = (unsigned long)gdt_desc.address;
3747 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
3749 @@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
3750 /* 0x2 bit is always set */
3751 .flags = X86_EFLAGS_SF | 0x2,
3754 + .es = __KERNEL_DS,
3758 + .ds = __KERNEL_DS,
3759 .fs = __KERNEL_PERCPU,
3761 .__cr3 = __pa(swapper_pg_dir)
3762 diff -urNp linux-2.6.27.4/arch/x86/kernel/efi_32.c linux-2.6.27.4/arch/x86/kernel/efi_32.c
3763 --- linux-2.6.27.4/arch/x86/kernel/efi_32.c 2008-10-22 17:38:01.000000000 -0400
3764 +++ linux-2.6.27.4/arch/x86/kernel/efi_32.c 2008-10-27 22:36:16.000000000 -0400
3768 static unsigned long efi_rt_eflags;
3769 -static pgd_t efi_bak_pg_dir_pointer[2];
3770 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
3772 -void efi_call_phys_prelog(void)
3773 +void __init efi_call_phys_prelog(void)
3775 - unsigned long cr4;
3776 - unsigned long temp;
3777 struct desc_ptr gdt_descr;
3779 local_irq_save(efi_rt_eflags);
3782 - * If I don't have PAE, I should just duplicate two entries in page
3783 - * directory. If I have PAE, I just need to duplicate one entry in
3786 - cr4 = read_cr4_safe();
3788 - if (cr4 & X86_CR4_PAE) {
3789 - efi_bak_pg_dir_pointer[0].pgd =
3790 - swapper_pg_dir[pgd_index(0)].pgd;
3791 - swapper_pg_dir[0].pgd =
3792 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
3794 - efi_bak_pg_dir_pointer[0].pgd =
3795 - swapper_pg_dir[pgd_index(0)].pgd;
3796 - efi_bak_pg_dir_pointer[1].pgd =
3797 - swapper_pg_dir[pgd_index(0x400000)].pgd;
3798 - swapper_pg_dir[pgd_index(0)].pgd =
3799 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
3800 - temp = PAGE_OFFSET + 0x400000;
3801 - swapper_pg_dir[pgd_index(0x400000)].pgd =
3802 - swapper_pg_dir[pgd_index(temp)].pgd;
3804 + clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
3805 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
3806 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
3809 * After the lock is released, the original page table is restored.
3813 - gdt_descr.address = __pa(get_cpu_gdt_table(0));
3814 + gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
3815 gdt_descr.size = GDT_SIZE - 1;
3816 load_gdt(&gdt_descr);
3819 -void efi_call_phys_epilog(void)
3820 +void __init efi_call_phys_epilog(void)
3822 - unsigned long cr4;
3823 struct desc_ptr gdt_descr;
3825 - gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
3826 + gdt_descr.address = get_cpu_gdt_table(0);
3827 gdt_descr.size = GDT_SIZE - 1;
3828 load_gdt(&gdt_descr);
3830 - cr4 = read_cr4_safe();
3832 - if (cr4 & X86_CR4_PAE) {
3833 - swapper_pg_dir[pgd_index(0)].pgd =
3834 - efi_bak_pg_dir_pointer[0].pgd;
3836 - swapper_pg_dir[pgd_index(0)].pgd =
3837 - efi_bak_pg_dir_pointer[0].pgd;
3838 - swapper_pg_dir[pgd_index(0x400000)].pgd =
3839 - efi_bak_pg_dir_pointer[1].pgd;
3841 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
3844 * After the lock is released, the original page table is restored.
3845 diff -urNp linux-2.6.27.4/arch/x86/kernel/efi_stub_32.S linux-2.6.27.4/arch/x86/kernel/efi_stub_32.S
3846 --- linux-2.6.27.4/arch/x86/kernel/efi_stub_32.S 2008-10-22 17:38:01.000000000 -0400
3847 +++ linux-2.6.27.4/arch/x86/kernel/efi_stub_32.S 2008-10-27 22:36:16.000000000 -0400
3851 #include <linux/linkage.h>
3852 +#include <linux/init.h>
3853 #include <asm/page.h>
3857 * service functions will comply with gcc calling convention, too.
3862 ENTRY(efi_call_phys)
3864 * 0. The function can only be called in Linux kernel. So CS has been
3865 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
3866 * The mapping of lower virtual memory has been created in prelog and
3870 - subl $__PAGE_OFFSET, %edx
3872 + jmp 1f-__PAGE_OFFSET
3876 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
3877 * parameter 2, ..., param n. To make things easy, we save the return
3878 * address of efi_call_phys in a global variable.
3881 - movl %edx, saved_return_addr
3882 - /* get the function pointer into ECX*/
3884 - movl %ecx, efi_rt_function_ptr
3886 - subl $__PAGE_OFFSET, %edx
3888 + popl (saved_return_addr)
3889 + popl (efi_rt_function_ptr)
3892 * 3. Clear PG bit in %CR0.
3893 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
3895 * 5. Call the physical function.
3898 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
3902 * 6. After EFI runtime service returns, control will return to
3903 * following instruction. We'd better readjust stack pointer first.
3904 @@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
3906 orl $0x80000000, %edx
3912 * 8. Now restore the virtual mode from flat mode by
3913 * adding EIP with PAGE_OFFSET.
3917 + jmp 1f+__PAGE_OFFSET
3921 * 9. Balance the stack. And because EAX contain the return value,
3922 * we'd better not clobber it.
3924 - leal efi_rt_function_ptr, %edx
3927 + pushl (efi_rt_function_ptr)
3930 - * 10. Push the saved return address onto the stack and return.
3931 + * 10. Return to the saved return address.
3933 - leal saved_return_addr, %edx
3937 + jmpl *(saved_return_addr)
3944 efi_rt_function_ptr:
3945 diff -urNp linux-2.6.27.4/arch/x86/kernel/entry_32.S linux-2.6.27.4/arch/x86/kernel/entry_32.S
3946 --- linux-2.6.27.4/arch/x86/kernel/entry_32.S 2008-10-22 17:38:01.000000000 -0400
3947 +++ linux-2.6.27.4/arch/x86/kernel/entry_32.S 2008-10-27 22:36:16.000000000 -0400
3949 #define resume_userspace_sig resume_userspace
3953 +#define __SAVE_ALL(_DS) \
3956 CFI_ADJUST_CFA_OFFSET 4;\
3957 @@ -133,12 +133,26 @@
3959 CFI_ADJUST_CFA_OFFSET 4;\
3960 CFI_REL_OFFSET ebx, 0;\
3961 - movl $(__USER_DS), %edx; \
3962 + movl $(_DS), %edx; \
3965 movl $(__KERNEL_PERCPU), %edx; \
3968 +#ifdef CONFIG_PAX_KERNEXEC
3970 + __SAVE_ALL(__KERNEL_DS); \
3971 + GET_CR0_INTO_EDX; \
3972 + movl %edx, %esi; \
3973 + orl $X86_CR0_WP, %edx; \
3974 + xorl %edx, %esi; \
3976 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
3977 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
3979 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
3982 #define RESTORE_INT_REGS \
3984 CFI_ADJUST_CFA_OFFSET -4;\
3985 @@ -229,6 +243,11 @@ ENTRY(ret_from_fork)
3986 CFI_ADJUST_CFA_OFFSET 4
3988 CFI_ADJUST_CFA_OFFSET -4
3990 +#ifdef CONFIG_PAX_KERNEXEC
3997 @@ -252,7 +271,17 @@ check_userspace:
3998 movb PT_CS(%esp), %al
3999 andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
4000 cmpl $USER_RPL, %eax
4002 +#ifdef CONFIG_PAX_KERNEXEC
4003 + jae resume_userspace
4010 jb resume_kernel # not returning to v8086 or userspace
4013 ENTRY(resume_userspace)
4015 @@ -314,10 +343,9 @@ sysenter_past_esp:
4016 /*CFI_REL_OFFSET cs, 0*/
4018 * Push current_thread_info()->sysenter_return to the stack.
4019 - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
4020 - * pushed above; +8 corresponds to copy_thread's esp0 setting.
4022 - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
4023 + GET_THREAD_INFO(%ebp)
4024 + pushl TI_sysenter_return(%ebp)
4025 CFI_ADJUST_CFA_OFFSET 4
4026 CFI_REL_OFFSET eip, 0
4028 @@ -330,9 +358,17 @@ sysenter_past_esp:
4029 * Load the potential sixth argument from user stack.
4030 * Careful about security.
4032 + movl PT_OLDESP(%esp),%ebp
4034 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4035 + mov PT_OLDSS(%esp),%ds
4036 +1: movl %ds:(%ebp),%ebp
4038 cmpl $__PAGE_OFFSET-3,%ebp
4043 movl %ebp,PT_EBP(%esp)
4044 .section __ex_table,"a"
4046 @@ -356,12 +392,23 @@ sysenter_do_call:
4047 testw $_TIF_ALLWORK_MASK, %cx
4051 +#ifdef CONFIG_PAX_RANDKSTACK
4053 + CFI_ADJUST_CFA_OFFSET 4
4054 + call pax_randomize_kstack
4056 + CFI_ADJUST_CFA_OFFSET -4
4059 /* if something modifies registers it must also disable sysexit */
4060 movl PT_EIP(%esp), %edx
4061 movl PT_OLDESP(%esp), %ecx
4064 1: mov PT_FS(%esp), %fs
4065 +2: mov PT_DS(%esp), %ds
4066 +3: mov PT_ES(%esp), %es
4067 ENABLE_INTERRUPTS_SYSEXIT
4069 #ifdef CONFIG_AUDITSYSCALL
4070 @@ -404,11 +451,17 @@ sysexit_audit:
4073 .pushsection .fixup,"ax"
4074 -2: movl $0,PT_FS(%esp)
4075 +4: movl $0,PT_FS(%esp)
4077 +5: movl $0,PT_DS(%esp)
4079 +6: movl $0,PT_ES(%esp)
4081 .section __ex_table,"a"
4088 ENDPROC(ia32_sysenter_target)
4090 @@ -438,6 +491,10 @@ syscall_exit:
4091 testw $_TIF_ALLWORK_MASK, %cx # current->work
4092 jne syscall_exit_work
4094 +#ifdef CONFIG_PAX_RANDKSTACK
4095 + call pax_randomize_kstack
4099 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
4100 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
4101 @@ -531,25 +588,19 @@ work_resched:
4103 work_notifysig: # deal with pending signals and
4104 # notify-resume requests
4107 testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
4109 - jne work_notifysig_v86 # returning to kernel-space or
4110 + jz 1f # returning to kernel-space or
4113 - call do_notify_resume
4114 - jmp resume_userspace_sig
4117 -work_notifysig_v86:
4118 pushl %ecx # save ti_flags for do_notify_resume
4119 CFI_ADJUST_CFA_OFFSET 4
4120 call save_v86_state # %eax contains pt_regs pointer
4122 CFI_ADJUST_CFA_OFFSET -4
4129 call do_notify_resume
4130 @@ -595,17 +646,24 @@ syscall_badsys:
4134 -#define FIXUP_ESPFIX_STACK \
4135 - /* since we are on a wrong stack, we cant make it a C code :( */ \
4136 - PER_CPU(gdt_page, %ebx); \
4137 - GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
4138 - addl %esp, %eax; \
4139 - pushl $__KERNEL_DS; \
4140 - CFI_ADJUST_CFA_OFFSET 4; \
4142 - CFI_ADJUST_CFA_OFFSET 4; \
4143 - lss (%esp), %esp; \
4144 +.macro FIXUP_ESPFIX_STACK
4145 + /* since we are on a wrong stack, we cant make it a C code :( */
4147 + movl PER_CPU_VAR(cpu_number), %ebx;
4148 + shll $PAGE_SHIFT_asm, %ebx;
4149 + addl $cpu_gdt_table, %ebx;
4151 + movl $cpu_gdt_table, %ebx;
4153 + GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
4155 + pushl $__KERNEL_DS;
4156 + CFI_ADJUST_CFA_OFFSET 4;
4158 + CFI_ADJUST_CFA_OFFSET 4;
4160 CFI_ADJUST_CFA_OFFSET -8;
4162 #define UNWIND_ESPFIX_STACK \
4164 /* see if on espfix stack */ \
4165 @@ -622,7 +680,7 @@ END(syscall_badsys)
4166 * Build the entry stubs and pointer table with
4167 * some assembler magic.
4169 -.section .rodata,"a"
4170 +.section .rodata,"a",@progbits
4174 @@ -722,12 +780,21 @@ error_code:
4176 CFI_ADJUST_CFA_OFFSET -4
4177 /*CFI_REGISTER es, ecx*/
4179 +#ifdef CONFIG_PAX_KERNEXEC
4182 + orl $X86_CR0_WP, %edx
4187 movl PT_FS(%esp), %edi # get the function address
4188 movl PT_ORIG_EAX(%esp), %edx # get the error code
4189 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
4190 mov %ecx, PT_FS(%esp)
4191 /*CFI_REL_OFFSET fs, ES*/
4192 - movl $(__USER_DS), %ecx
4193 + movl $(__KERNEL_DS), %ecx
4196 movl %esp,%eax # pt_regs pointer
4197 @@ -861,6 +928,13 @@ nmi_stack_correct:
4198 xorl %edx,%edx # zero error code
4199 movl %esp,%eax # pt_regs pointer
4202 +#ifdef CONFIG_PAX_KERNEXEC
4208 jmp restore_nocheck_notrace
4211 @@ -901,6 +975,13 @@ nmi_espfix_stack:
4212 FIXUP_ESPFIX_STACK # %eax == %esp
4213 xorl %edx,%edx # zero error code
4216 +#ifdef CONFIG_PAX_KERNEXEC
4223 lss 12+4(%esp), %esp # back to espfix stack
4224 CFI_ADJUST_CFA_OFFSET -24
4225 @@ -1226,7 +1307,6 @@ END(mcount)
4226 #endif /* CONFIG_DYNAMIC_FTRACE */
4227 #endif /* CONFIG_FTRACE */
4229 -.section .rodata,"a"
4230 #include "syscall_table_32.S"
4232 syscall_table_size=(.-sys_call_table)
4233 diff -urNp linux-2.6.27.4/arch/x86/kernel/entry_64.S linux-2.6.27.4/arch/x86/kernel/entry_64.S
4234 --- linux-2.6.27.4/arch/x86/kernel/entry_64.S 2008-10-22 17:38:01.000000000 -0400
4235 +++ linux-2.6.27.4/arch/x86/kernel/entry_64.S 2008-10-27 22:36:16.000000000 -0400
4236 @@ -930,17 +930,18 @@ END(spurious_interrupt)
4240 - movq %gs:pda_data_offset, %rbp
4241 + imul $TSS_size, %gs:pda_cpunumber, %ebp
4242 + lea init_tss(%rbp), %rbp
4245 movq ORIG_RAX(%rsp),%rsi
4246 movq $-1,ORIG_RAX(%rsp)
4248 - subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4249 + subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4253 - addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4254 + addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4256 DISABLE_INTERRUPTS(CLBR_NONE)
4258 diff -urNp linux-2.6.27.4/arch/x86/kernel/ftrace.c linux-2.6.27.4/arch/x86/kernel/ftrace.c
4259 --- linux-2.6.27.4/arch/x86/kernel/ftrace.c 2008-10-22 17:38:01.000000000 -0400
4260 +++ linux-2.6.27.4/arch/x86/kernel/ftrace.c 2008-10-27 22:36:16.000000000 -0400
4261 @@ -103,7 +103,7 @@ notrace int ftrace_update_ftrace_func(ft
4262 unsigned char old[MCOUNT_INSN_SIZE], *new;
4265 - memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
4266 + memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
4267 new = ftrace_call_replace(ip, (unsigned long)func);
4268 ret = ftrace_modify_code(ip, old, new);
4270 @@ -120,7 +120,7 @@ notrace int ftrace_mcount_set(unsigned l
4271 * Replace the mcount stub with a pointer to the
4272 * ip recorder function.
4274 - memcpy(old, &mcount_call, MCOUNT_INSN_SIZE);
4275 + memcpy(old, ktla_ktva(mcount_call), MCOUNT_INSN_SIZE);
4276 new = ftrace_call_replace(ip, *addr);
4277 *addr = ftrace_modify_code(ip, old, new);
4279 diff -urNp linux-2.6.27.4/arch/x86/kernel/head32.c linux-2.6.27.4/arch/x86/kernel/head32.c
4280 --- linux-2.6.27.4/arch/x86/kernel/head32.c 2008-10-22 17:38:01.000000000 -0400
4281 +++ linux-2.6.27.4/arch/x86/kernel/head32.c 2008-10-27 22:36:16.000000000 -0400
4283 #include <asm/sections.h>
4284 #include <asm/e820.h>
4285 #include <asm/bios_ebda.h>
4286 +#include <asm/boot.h>
4288 void __init i386_start_kernel(void)
4290 - reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
4291 + reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&_end), "TEXT DATA BSS");
4293 #ifdef CONFIG_BLK_DEV_INITRD
4294 /* Reserve INITRD */
4295 diff -urNp linux-2.6.27.4/arch/x86/kernel/head_32.S linux-2.6.27.4/arch/x86/kernel/head_32.S
4296 --- linux-2.6.27.4/arch/x86/kernel/head_32.S 2008-10-22 17:38:01.000000000 -0400
4297 +++ linux-2.6.27.4/arch/x86/kernel/head_32.S 2008-10-27 22:36:16.000000000 -0400
4299 #include <asm/asm-offsets.h>
4300 #include <asm/setup.h>
4301 #include <asm/processor-flags.h>
4302 +#include <asm/msr-index.h>
4304 /* Physical address */
4305 #define pa(X) ((X) - __PAGE_OFFSET)
4306 @@ -64,17 +65,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
4307 LOW_PAGES = LOW_PAGES + 0x1000000
4310 -#if PTRS_PER_PMD > 1
4311 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
4313 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
4315 +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
4316 BOOTBITMAP_SIZE = LOW_PAGES / 8
4319 INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
4322 + * Real beginning of normal "text" segment
4327 +.section .text.startup,"ax",@progbits
4328 + ljmp $(__BOOT_CS),$phys_startup_32
4331 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
4332 * %esi points to the real-mode code as a 32-bit pointer.
4333 * CS and DS must be 4 GB flat segments, but we don't depend on
4334 @@ -82,6 +88,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
4337 .section .text.head,"ax",@progbits
4339 +#ifdef CONFIG_PAX_KERNEXEC
4340 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
4345 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
4346 us to not reload segments */
4347 @@ -99,6 +111,56 @@ ENTRY(startup_32)
4351 + movl $pa(cpu_gdt_table),%edi
4352 + movl $__per_cpu_start,%eax
4353 + movw %ax,__KERNEL_PERCPU + 2(%edi)
4355 + movb %al,__KERNEL_PERCPU + 4(%edi)
4356 + movb %ah,__KERNEL_PERCPU + 7(%edi)
4357 + movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
4358 + subl $__per_cpu_start,%eax
4359 + movw %ax,__KERNEL_PERCPU + 0(%edi)
4361 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4362 + /* check for VMware */
4363 + movl $0x564d5868,%eax
4368 + cmpl $0x564d5868,%ebx
4371 + movl $NR_CPUS,%ecx
4372 + movl $pa(cpu_gdt_table),%edi
4374 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
4375 + addl $PAGE_SIZE_asm,%edi
4380 +#ifdef CONFIG_PAX_KERNEXEC
4381 + movl $pa(boot_gdt),%edi
4382 + movl $KERNEL_TEXT_OFFSET,%eax
4383 + movw %ax,__BOOT_CS + 2(%edi)
4385 + movb %al,__BOOT_CS + 4(%edi)
4386 + movb %ah,__BOOT_CS + 7(%edi)
4389 + movl $NR_CPUS,%ecx
4390 + movl $pa(cpu_gdt_table),%edi
4392 + movw %ax,__KERNEL_CS + 2(%edi)
4394 + movb %al,__KERNEL_CS + 4(%edi)
4395 + movb %ah,__KERNEL_CS + 7(%edi)
4397 + addl $PAGE_SIZE_asm,%edi
4402 * Clear BSS first so that there are no surprises...
4404 @@ -142,9 +204,7 @@ ENTRY(startup_32)
4405 cmpl $num_subarch_entries, %eax
4408 - movl pa(subarch_entries)(,%eax,4), %eax
4409 - subl $__PAGE_OFFSET, %eax
4411 + jmp *pa(subarch_entries)(,%eax,4)
4415 @@ -156,9 +216,9 @@ WEAK(xen_entry)
4419 - .long default_entry /* normal x86/PC */
4420 - .long lguest_entry /* lguest hypervisor */
4421 - .long xen_entry /* Xen hypervisor */
4422 + .long pa(default_entry) /* normal x86/PC */
4423 + .long pa(lguest_entry) /* lguest hypervisor */
4424 + .long pa(xen_entry) /* Xen hypervisor */
4425 num_subarch_entries = (. - subarch_entries) / 4
4427 #endif /* CONFIG_PARAVIRT */
4428 @@ -172,7 +232,7 @@ num_subarch_entries = (. - subarch_entri
4430 * Note that the stack is not yet set up!
4432 -#define PTE_ATTR 0x007 /* PRESENT+RW+USER */
4433 +#define PTE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
4434 #define PDE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
4435 #define PGD_ATTR 0x001 /* PRESENT (no other attributes) */
4437 @@ -224,8 +284,7 @@ default_entry:
4438 movl %eax, pa(max_pfn_mapped)
4440 /* Do early initialization of the fixmap area */
4441 - movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4442 - movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4443 + movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4446 page_pde_offset = (__PAGE_OFFSET >> 20);
4447 @@ -257,8 +316,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
4448 movl %eax, pa(max_pfn_mapped)
4450 /* Do early initialization of the fixmap area */
4451 - movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4452 - movl %eax,pa(swapper_pg_dir+0xffc)
4453 + movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
4457 @@ -322,13 +380,16 @@ ENTRY(startup_32_smp)
4460 /* Setup EFER (Extended Feature Enable Register) */
4461 - movl $0xc0000080, %ecx
4462 + movl $MSR_EFER, %ecx
4466 /* Make changes effective */
4469 + btsl $63-32,pa(__supported_pte_mask+4)
4470 + movl $1,pa(nx_enabled)
4475 @@ -354,9 +415,7 @@ ENTRY(startup_32_smp)
4479 - jz 1f /* Initial CPU cleans BSS */
4482 + jnz checkCPUtype /* Initial CPU cleans BSS */
4483 #endif /* CONFIG_SMP */
4486 @@ -433,12 +492,12 @@ is386: movl $2,%ecx # set MP
4487 ljmp $(__KERNEL_CS),$1f
4488 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
4489 movl %eax,%ss # after changing gdt.
4490 - movl %eax,%fs # gets reset once there's real percpu
4492 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
4496 + movl $(__KERNEL_PERCPU), %eax
4497 + movl %eax,%fs # set this cpu's percpu
4499 xorl %eax,%eax # Clear GS and LDT
4502 @@ -448,12 +507,6 @@ is386: movl $2,%ecx # set MP
4506 - cmpb $0,%cl # the first CPU calls start_kernel
4508 - movl $(__KERNEL_PERCPU), %eax
4509 - movl %eax,%fs # set this cpu's percpu
4510 - movl (stack_start), %esp
4512 #endif /* CONFIG_SMP */
4515 @@ -539,15 +592,15 @@ early_page_fault:
4520 #ifdef CONFIG_PRINTK
4521 + cmpl $2,%ss:early_recursion_flag
4523 + incl %ss:early_recursion_flag
4526 movl $(__KERNEL_DS),%eax
4529 - cmpl $2,early_recursion_flag
4531 - incl early_recursion_flag
4534 pushl %edx /* trapno */
4535 @@ -557,8 +610,8 @@ early_fault:
4545 @@ -566,8 +619,11 @@ hlt_loop:
4546 /* This is the default interrupt "handler" :-) */
4550 #ifdef CONFIG_PRINTK
4551 + cmpl $2,%ss:early_recursion_flag
4553 + incl %ss:early_recursion_flag
4558 @@ -576,9 +632,6 @@ ignore_int:
4559 movl $(__KERNEL_DS),%eax
4562 - cmpl $2,early_recursion_flag
4564 - incl early_recursion_flag
4568 @@ -603,36 +656,41 @@ ignore_int:
4570 .long i386_start_kernel
4574 - * Real beginning of normal "text" segment
4582 -.section ".bss.page_aligned","wa"
4583 - .align PAGE_SIZE_asm
4584 #ifdef CONFIG_X86_PAE
4585 +.section .swapper_pg_pmd,"a",@progbits
4587 .fill 1024*KPMDS,4,0
4589 +.section .swapper_pg_dir,"a",@progbits
4590 ENTRY(swapper_pg_dir)
4596 +.section .empty_zero_page,"a",@progbits
4597 ENTRY(empty_zero_page)
4601 + * The IDT has to be page-aligned to simplify the Pentium
4602 + * F0 0F bug workaround.. We have a special link segment
4605 +.section .idt,"a",@progbits
4610 * This starts the data section.
4614 #ifdef CONFIG_X86_PAE
4615 -.section ".data.page_aligned","wa"
4616 - /* Page-aligned for the benefit of paravirt? */
4617 - .align PAGE_SIZE_asm
4618 +.section .swapper_pg_dir,"a",@progbits
4619 ENTRY(swapper_pg_dir)
4620 .long pa(swapper_pg_pmd+PGD_ATTR),0 /* low identity map */
4622 @@ -655,11 +713,12 @@ ENTRY(swapper_pg_dir)
4626 - .long init_thread_union+THREAD_SIZE
4627 + .long init_thread_union+THREAD_SIZE-8
4632 +.section .rodata,"a",@progbits
4633 early_recursion_flag:
4636 @@ -695,7 +754,7 @@ fault_msg:
4637 .word 0 # 32 bit align gdt_desc.address
4640 - .long boot_gdt - __PAGE_OFFSET
4641 + .long pa(boot_gdt)
4643 .word 0 # 32-bit align idt_desc.address
4645 @@ -706,7 +765,7 @@ idt_descr:
4646 .word 0 # 32 bit align gdt_desc.address
4647 ENTRY(early_gdt_descr)
4648 .word GDT_ENTRIES*8-1
4649 - .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
4650 + .long cpu_gdt_table /* Overwritten for secondary CPUs */
4653 * The boot_gdt must mirror the equivalent in setup.S and is
4654 @@ -715,5 +774,59 @@ ENTRY(early_gdt_descr)
4655 .align L1_CACHE_BYTES
4657 .fill GDT_ENTRY_BOOT_CS,8,0
4658 - .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
4659 - .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
4660 + .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
4661 + .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
4663 + .align PAGE_SIZE_asm
4664 +ENTRY(cpu_gdt_table)
4666 + .quad 0x0000000000000000 /* NULL descriptor */
4667 + .quad 0x0000000000000000 /* 0x0b reserved */
4668 + .quad 0x0000000000000000 /* 0x13 reserved */
4669 + .quad 0x0000000000000000 /* 0x1b reserved */
4670 + .quad 0x0000000000000000 /* 0x20 unused */
4671 + .quad 0x0000000000000000 /* 0x28 unused */
4672 + .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
4673 + .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
4674 + .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
4675 + .quad 0x0000000000000000 /* 0x4b reserved */
4676 + .quad 0x0000000000000000 /* 0x53 reserved */
4677 + .quad 0x0000000000000000 /* 0x5b reserved */
4679 + .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
4680 + .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
4681 + .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
4682 + .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
4684 + .quad 0x0000000000000000 /* 0x80 TSS descriptor */
4685 + .quad 0x0000000000000000 /* 0x88 LDT descriptor */
4688 + * Segments used for calling PnP BIOS have byte granularity.
4689 + * The code segments and data segments have fixed 64k limits,
4690 + * the transfer segment sizes are set at run time.
4692 + .quad 0x00409b000000ffff /* 0x90 32-bit code */
4693 + .quad 0x00009b000000ffff /* 0x98 16-bit code */
4694 + .quad 0x000093000000ffff /* 0xa0 16-bit data */
4695 + .quad 0x0000930000000000 /* 0xa8 16-bit data */
4696 + .quad 0x0000930000000000 /* 0xb0 16-bit data */
4699 + * The APM segments have byte granularity and their bases
4700 + * are set at run time. All have 64k limits.
4702 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
4703 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
4704 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
4706 + .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
4707 + .quad 0x0040930000000000 /* 0xd8 - PERCPU */
4708 + .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
4709 + .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
4710 + .quad 0x0000000000000000 /* 0xf0 - unused */
4711 + .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
4713 + /* Be sure this is zeroed to avoid false validations in Xen */
4714 + .fill PAGE_SIZE_asm - GDT_SIZE,1,0
4716 diff -urNp linux-2.6.27.4/arch/x86/kernel/head_64.S linux-2.6.27.4/arch/x86/kernel/head_64.S
4717 --- linux-2.6.27.4/arch/x86/kernel/head_64.S 2008-10-22 17:38:01.000000000 -0400
4718 +++ linux-2.6.27.4/arch/x86/kernel/head_64.S 2008-10-27 22:36:16.000000000 -0400
4719 @@ -38,6 +38,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
4720 L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
4721 L4_START_KERNEL = pgd_index(__START_KERNEL_map)
4722 L3_START_KERNEL = pud_index(__START_KERNEL_map)
4723 +L4_VMALLOC_START = pgd_index(VMALLOC_START)
4724 +L3_VMALLOC_START = pud_index(VMALLOC_START)
4725 +L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
4726 +L3_VMEMMAP_START = pud_index(VMEMMAP_START)
4730 @@ -85,14 +89,17 @@ startup_64:
4732 addq %rbp, init_level4_pgt + 0(%rip)
4733 addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
4734 + addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
4735 + addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
4736 addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
4738 addq %rbp, level3_ident_pgt + 0(%rip)
4740 - addq %rbp, level3_kernel_pgt + (510*8)(%rip)
4741 - addq %rbp, level3_kernel_pgt + (511*8)(%rip)
4742 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
4743 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
4745 addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
4746 + addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
4748 /* Add an Identity mapping if I am above 1G */
4749 leaq _text(%rip), %rdi
4750 @@ -187,6 +194,10 @@ ENTRY(secondary_startup_64)
4751 btl $20,%edi /* No Execute supported? */
4753 btsl $_EFER_NX, %eax
4754 + leaq init_level4_pgt(%rip), %rdi
4755 + btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
4756 + btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
4757 + btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
4758 1: wrmsr /* Make changes effective */
4761 @@ -257,16 +268,16 @@ ENTRY(secondary_startup_64)
4764 .quad x86_64_start_kernel
4768 .quad init_thread_union+THREAD_SIZE-8
4775 - .section ".init.text","ax"
4777 #ifdef CONFIG_EARLY_PRINTK
4778 .globl early_idt_handlers
4780 @@ -311,18 +322,23 @@ ENTRY(early_idt_handler)
4781 #endif /* EARLY_PRINTK */
4786 #ifdef CONFIG_EARLY_PRINTK
4788 early_recursion_flag:
4792 + .section .rodata,"a",@progbits
4794 .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
4797 -#endif /* CONFIG_EARLY_PRINTK */
4799 +#endif /* CONFIG_EARLY_PRINTK */
4801 + .section .rodata,"a",@progbits
4804 #define NEXT_PAGE(name) \
4805 @@ -347,6 +363,10 @@ NEXT_PAGE(init_level4_pgt)
4806 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
4807 .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
4808 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
4809 + .org init_level4_pgt + L4_VMALLOC_START*8, 0
4810 + .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
4811 + .org init_level4_pgt + L4_VMEMMAP_START*8, 0
4812 + .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
4813 .org init_level4_pgt + L4_START_KERNEL*8, 0
4814 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
4815 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
4816 @@ -355,6 +375,12 @@ NEXT_PAGE(level3_ident_pgt)
4817 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
4820 +NEXT_PAGE(level3_vmalloc_pgt)
4823 +NEXT_PAGE(level3_vmemmap_pgt)
4826 NEXT_PAGE(level3_kernel_pgt)
4827 .fill L3_START_KERNEL,8,0
4828 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
4829 @@ -364,12 +390,16 @@ NEXT_PAGE(level3_kernel_pgt)
4830 NEXT_PAGE(level2_fixmap_pgt)
4832 .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
4833 - /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
4835 + .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
4836 + /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
4839 NEXT_PAGE(level1_fixmap_pgt)
4842 +NEXT_PAGE(level1_vsyscall_pgt)
4845 NEXT_PAGE(level2_ident_pgt)
4846 /* Since I easily can, map the first 1G.
4847 * Don't set NX because code runs from these pages.
4848 @@ -396,19 +426,39 @@ NEXT_PAGE(level2_spare_pgt)
4854 +ENTRY(cpu_gdt_table)
4856 + .quad 0x0000000000000000 /* NULL descriptor */
4857 + .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
4858 + .quad 0x00af9b000000ffff /* __KERNEL_CS */
4859 + .quad 0x00cf93000000ffff /* __KERNEL_DS */
4860 + .quad 0x00cffb000000ffff /* __USER32_CS */
4861 + .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
4862 + .quad 0x00affb000000ffff /* __USER_CS */
4863 + .quad 0x0 /* unused */
4864 + .quad 0,0 /* TSS */
4865 + .quad 0,0 /* LDT */
4866 + .quad 0,0,0 /* three TLS descriptors */
4867 + .quad 0x0000f40000000000 /* node/CPU stored in limit */
4868 + /* asm/segment.h:GDT_ENTRIES must match this */
4870 + /* zero the remaining page */
4871 + .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
4875 .globl early_gdt_descr
4877 .word GDT_ENTRIES*8-1
4878 - .quad per_cpu__gdt_page
4879 + .quad cpu_gdt_table
4882 /* This must match the first entry in level2_kernel_pgt */
4883 .quad 0x0000000000000000
4885 #include "../../x86/xen/xen-head.S"
4888 .section .bss, "aw", @nobits
4889 .align L1_CACHE_BYTES
4891 diff -urNp linux-2.6.27.4/arch/x86/kernel/i386_ksyms_32.c linux-2.6.27.4/arch/x86/kernel/i386_ksyms_32.c
4892 --- linux-2.6.27.4/arch/x86/kernel/i386_ksyms_32.c 2008-10-22 17:38:01.000000000 -0400
4893 +++ linux-2.6.27.4/arch/x86/kernel/i386_ksyms_32.c 2008-10-27 22:36:16.000000000 -0400
4895 EXPORT_SYMBOL(mcount);
4898 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
4900 /* Networking helper routines. */
4901 EXPORT_SYMBOL(csum_partial_copy_generic);
4902 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
4903 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
4905 EXPORT_SYMBOL(__get_user_1);
4906 EXPORT_SYMBOL(__get_user_2);
4907 @@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr);
4909 EXPORT_SYMBOL(csum_partial);
4910 EXPORT_SYMBOL(empty_zero_page);
4912 +#ifdef CONFIG_PAX_KERNEXEC
4913 +EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
4915 diff -urNp linux-2.6.27.4/arch/x86/kernel/init_task.c linux-2.6.27.4/arch/x86/kernel/init_task.c
4916 --- linux-2.6.27.4/arch/x86/kernel/init_task.c 2008-10-22 17:38:01.000000000 -0400
4917 +++ linux-2.6.27.4/arch/x86/kernel/init_task.c 2008-10-27 22:36:16.000000000 -0400
4918 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
4919 * section. Since TSS's are completely CPU-local, we want them
4920 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
4922 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
4924 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
4925 +EXPORT_SYMBOL(init_tss);
4926 diff -urNp linux-2.6.27.4/arch/x86/kernel/ioport.c linux-2.6.27.4/arch/x86/kernel/ioport.c
4927 --- linux-2.6.27.4/arch/x86/kernel/ioport.c 2008-10-22 17:38:01.000000000 -0400
4928 +++ linux-2.6.27.4/arch/x86/kernel/ioport.c 2008-10-27 22:36:16.000000000 -0400
4930 #include <linux/slab.h>
4931 #include <linux/thread_info.h>
4932 #include <linux/syscalls.h>
4933 +#include <linux/grsecurity.h>
4935 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
4936 static void set_bitmap(unsigned long *bitmap, unsigned int base,
4937 @@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
4939 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
4941 +#ifdef CONFIG_GRKERNSEC_IO
4943 + gr_handle_ioperm();
4947 if (turn_on && !capable(CAP_SYS_RAWIO))
4950 @@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
4951 * because the ->io_bitmap_max value must match the bitmap
4954 - tss = &per_cpu(init_tss, get_cpu());
4955 + tss = init_tss + get_cpu();
4957 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
4959 @@ -121,8 +128,13 @@ static int do_iopl(unsigned int level, s
4961 /* Trying to gain more privileges? */
4963 +#ifdef CONFIG_GRKERNSEC_IO
4967 if (!capable(CAP_SYS_RAWIO))
4971 regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
4973 diff -urNp linux-2.6.27.4/arch/x86/kernel/irq_32.c linux-2.6.27.4/arch/x86/kernel/irq_32.c
4974 --- linux-2.6.27.4/arch/x86/kernel/irq_32.c 2008-10-22 17:38:01.000000000 -0400
4975 +++ linux-2.6.27.4/arch/x86/kernel/irq_32.c 2008-10-27 22:36:16.000000000 -0400
4976 @@ -116,7 +116,7 @@ execute_on_irq_stack(int overflow, struc
4979 /* build the stack frame on the IRQ stack */
4980 - isp = (u32 *) ((char*)irqctx + sizeof(*irqctx));
4981 + isp = (u32 *) ((char*)irqctx + sizeof(*irqctx) - 8);
4982 irqctx->tinfo.task = curctx->tinfo.task;
4983 irqctx->tinfo.previous_esp = current_stack_pointer;
4985 @@ -197,7 +197,7 @@ asmlinkage void do_softirq(void)
4986 irqctx->tinfo.previous_esp = current_stack_pointer;
4988 /* build the stack frame on the softirq stack */
4989 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
4990 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
4992 call_on_stack(__do_softirq, isp);
4994 diff -urNp linux-2.6.27.4/arch/x86/kernel/kprobes.c linux-2.6.27.4/arch/x86/kernel/kprobes.c
4995 --- linux-2.6.27.4/arch/x86/kernel/kprobes.c 2008-10-22 17:38:01.000000000 -0400
4996 +++ linux-2.6.27.4/arch/x86/kernel/kprobes.c 2008-10-27 22:36:17.000000000 -0400
4997 @@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
5000 } __attribute__((packed)) * jop;
5001 - jop = (struct __arch_jmp_op *)from;
5003 +#ifdef CONFIG_PAX_KERNEXEC
5004 + unsigned long cr0;
5007 + jop = (struct __arch_jmp_op *)(ktla_ktva(from));
5009 +#ifdef CONFIG_PAX_KERNEXEC
5010 + pax_open_kernel(cr0);
5013 jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
5014 jop->op = RELATIVEJUMP_INSTRUCTION;
5016 +#ifdef CONFIG_PAX_KERNEXEC
5017 + pax_close_kernel(cr0);
5023 @@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
5025 static void __kprobes arch_copy_kprobe(struct kprobe *p)
5027 - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5029 +#ifdef CONFIG_PAX_KERNEXEC
5030 + unsigned long cr0;
5033 +#ifdef CONFIG_PAX_KERNEXEC
5034 + pax_open_kernel(cr0);
5037 + memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5039 +#ifdef CONFIG_PAX_KERNEXEC
5040 + pax_close_kernel(cr0);
5045 - if (can_boost(p->addr))
5046 + if (can_boost(ktla_ktva(p->addr)))
5047 p->ainsn.boostable = 0;
5049 p->ainsn.boostable = -1;
5051 - p->opcode = *p->addr;
5052 + p->opcode = *(ktla_ktva(p->addr));
5055 int __kprobes arch_prepare_kprobe(struct kprobe *p)
5056 @@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
5057 if (p->opcode == BREAKPOINT_INSTRUCTION)
5058 regs->ip = (unsigned long)p->addr;
5060 - regs->ip = (unsigned long)p->ainsn.insn;
5061 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5064 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
5065 @@ -449,7 +477,7 @@ static void __kprobes setup_singlestep(s
5066 if (p->ainsn.boostable == 1 && !p->post_handler) {
5067 /* Boost up -- we can execute copied instructions directly */
5068 reset_current_kprobe();
5069 - regs->ip = (unsigned long)p->ainsn.insn;
5070 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5071 preempt_enable_no_resched();
5074 @@ -770,7 +798,7 @@ static void __kprobes resume_execution(s
5075 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
5077 unsigned long *tos = stack_addr(regs);
5078 - unsigned long copy_ip = (unsigned long)p->ainsn.insn;
5079 + unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
5080 unsigned long orig_ip = (unsigned long)p->addr;
5081 kprobe_opcode_t *insn = p->ainsn.insn;
5083 @@ -953,7 +981,7 @@ int __kprobes kprobe_exceptions_notify(s
5084 struct die_args *args = data;
5085 int ret = NOTIFY_DONE;
5087 - if (args->regs && user_mode_vm(args->regs))
5088 + if (args->regs && user_mode(args->regs))
5092 diff -urNp linux-2.6.27.4/arch/x86/kernel/ldt.c linux-2.6.27.4/arch/x86/kernel/ldt.c
5093 --- linux-2.6.27.4/arch/x86/kernel/ldt.c 2008-10-22 17:38:01.000000000 -0400
5094 +++ linux-2.6.27.4/arch/x86/kernel/ldt.c 2008-10-27 22:36:17.000000000 -0400
5095 @@ -63,13 +63,13 @@ static int alloc_ldt(mm_context_t *pc, i
5100 + load_LDT_nolock(pc);
5101 if (!cpus_equal(current->mm->cpu_vm_mask,
5102 cpumask_of_cpu(smp_processor_id())))
5103 smp_call_function(flush_ldt, current->mm, 1);
5107 + load_LDT_nolock(pc);
5111 @@ -108,6 +108,24 @@ int init_new_context(struct task_struct
5112 retval = copy_ldt(&mm->context, &old_mm->context);
5113 mutex_unlock(&old_mm->context.lock);
5116 + if (tsk == current) {
5117 + mm->context.vdso = ~0UL;
5119 +#ifdef CONFIG_X86_32
5120 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5121 + mm->context.user_cs_base = 0UL;
5122 + mm->context.user_cs_limit = ~0UL;
5124 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5125 + cpus_clear(mm->context.cpu_user_cs_mask);
5136 @@ -221,6 +239,13 @@ static int write_ldt(void __user *ptr, u
5140 +#ifdef CONFIG_PAX_SEGMEXEC
5141 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
5147 fill_ldt(&ldt, &ldt_info);
5150 diff -urNp linux-2.6.27.4/arch/x86/kernel/machine_kexec_32.c linux-2.6.27.4/arch/x86/kernel/machine_kexec_32.c
5151 --- linux-2.6.27.4/arch/x86/kernel/machine_kexec_32.c 2008-10-22 17:38:01.000000000 -0400
5152 +++ linux-2.6.27.4/arch/x86/kernel/machine_kexec_32.c 2008-10-27 22:36:17.000000000 -0400
5153 @@ -34,7 +34,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
5154 static u32 kexec_pte0[1024] PAGE_ALIGNED;
5155 static u32 kexec_pte1[1024] PAGE_ALIGNED;
5157 -static void set_idt(void *newidt, __u16 limit)
5158 +static void set_idt(struct desc_struct *newidt, __u16 limit)
5160 struct desc_ptr curidt;
5162 @@ -46,7 +46,7 @@ static void set_idt(void *newidt, __u16
5166 -static void set_gdt(void *newgdt, __u16 limit)
5167 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
5169 struct desc_ptr curgdt;
5171 @@ -145,7 +145,7 @@ void machine_kexec(struct kimage *image)
5174 control_page = page_address(image->control_code_page);
5175 - memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
5176 + memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
5178 relocate_kernel_ptr = control_page;
5179 page_list[PA_CONTROL_PAGE] = __pa(control_page);
5180 diff -urNp linux-2.6.27.4/arch/x86/kernel/module_32.c linux-2.6.27.4/arch/x86/kernel/module_32.c
5181 --- linux-2.6.27.4/arch/x86/kernel/module_32.c 2008-10-22 17:38:01.000000000 -0400
5182 +++ linux-2.6.27.4/arch/x86/kernel/module_32.c 2008-10-27 22:36:17.000000000 -0400
5184 #include <linux/kernel.h>
5185 #include <linux/bug.h>
5187 +#include <asm/desc.h>
5188 +#include <asm/pgtable.h>
5191 #define DEBUGP printk
5193 @@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
5198 +#ifdef CONFIG_PAX_KERNEXEC
5199 + return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
5201 return vmalloc_exec(size);
5206 +#ifdef CONFIG_PAX_KERNEXEC
5207 +void *module_alloc_exec(unsigned long size)
5209 + struct vm_struct *area;
5214 + area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
5216 + return area->addr;
5220 +EXPORT_SYMBOL(module_alloc_exec);
5223 /* Free memory returned from module_alloc */
5224 void module_free(struct module *mod, void *module_region)
5225 @@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
5229 +#ifdef CONFIG_PAX_KERNEXEC
5230 +void module_free_exec(struct module *mod, void *module_region)
5232 + struct vm_struct **p, *tmp;
5234 + if (!module_region)
5237 + if ((PAGE_SIZE-1) & (unsigned long)module_region) {
5238 + printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
5243 + write_lock(&vmlist_lock);
5244 + for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
5245 + if (tmp->addr == module_region)
5249 + unsigned long cr0;
5251 + pax_open_kernel(cr0);
5252 + memset(tmp->addr, 0xCC, tmp->size);
5253 + pax_close_kernel(cr0);
5258 + write_unlock(&vmlist_lock);
5261 + printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
5268 /* We don't need anything special. */
5269 int module_frob_arch_sections(Elf_Ehdr *hdr,
5271 @@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5273 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
5275 - uint32_t *location;
5276 + uint32_t *plocation, location;
5278 +#ifdef CONFIG_PAX_KERNEXEC
5279 + unsigned long cr0;
5282 DEBUGP("Applying relocate section %u to %u\n", relsec,
5283 sechdrs[relsec].sh_info);
5284 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
5285 /* This is where to make the change */
5286 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
5287 - + rel[i].r_offset;
5288 + plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
5289 + location = (uint32_t)plocation;
5290 + if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
5291 + plocation = ktla_ktva((void *)plocation);
5292 /* This is the symbol it is referring to. Note that all
5293 undefined symbols have been resolved. */
5294 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
5295 @@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5297 switch (ELF32_R_TYPE(rel[i].r_info)) {
5300 +#ifdef CONFIG_PAX_KERNEXEC
5301 + pax_open_kernel(cr0);
5304 /* We add the value into the location given */
5305 - *location += sym->st_value;
5306 + *plocation += sym->st_value;
5308 +#ifdef CONFIG_PAX_KERNEXEC
5309 + pax_close_kernel(cr0);
5315 +#ifdef CONFIG_PAX_KERNEXEC
5316 + pax_open_kernel(cr0);
5319 /* Add the value, subtract its postition */
5320 - *location += sym->st_value - (uint32_t)location;
5321 + *plocation += sym->st_value - location;
5323 +#ifdef CONFIG_PAX_KERNEXEC
5324 + pax_close_kernel(cr0);
5329 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
5330 diff -urNp linux-2.6.27.4/arch/x86/kernel/module_64.c linux-2.6.27.4/arch/x86/kernel/module_64.c
5331 --- linux-2.6.27.4/arch/x86/kernel/module_64.c 2008-10-22 17:38:01.000000000 -0400
5332 +++ linux-2.6.27.4/arch/x86/kernel/module_64.c 2008-10-27 22:36:17.000000000 -0400
5333 @@ -40,7 +40,7 @@ void module_free(struct module *mod, voi
5337 -void *module_alloc(unsigned long size)
5338 +static void *__module_alloc(unsigned long size, pgprot_t prot)
5340 struct vm_struct *area;
5342 @@ -54,8 +54,31 @@ void *module_alloc(unsigned long size)
5346 - return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
5347 + return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
5350 +#ifdef CONFIG_PAX_KERNEXEC
5351 +void *module_alloc(unsigned long size)
5353 + return __module_alloc(size, PAGE_KERNEL);
5356 +void module_free_exec(struct module *mod, void *module_region)
5358 + module_free(mod, module_region);
5361 +void *module_alloc_exec(unsigned long size)
5363 + return __module_alloc(size, PAGE_KERNEL_RX);
5366 +void *module_alloc(unsigned long size)
5368 + return __module_alloc(size, PAGE_KERNEL_EXEC);
5374 /* We don't need anything special. */
5375 @@ -77,7 +100,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
5376 Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
5382 +#ifdef CONFIG_PAX_KERNEXEC
5383 + unsigned long cr0;
5386 DEBUGP("Applying relocate section %u to %u\n", relsec,
5387 sechdrs[relsec].sh_info);
5388 @@ -101,21 +128,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
5393 +#ifdef CONFIG_PAX_KERNEXEC
5394 + pax_open_kernel(cr0);
5399 +#ifdef CONFIG_PAX_KERNEXEC
5400 + pax_close_kernel(cr0);
5406 +#ifdef CONFIG_PAX_KERNEXEC
5407 + pax_open_kernel(cr0);
5412 +#ifdef CONFIG_PAX_KERNEXEC
5413 + pax_close_kernel(cr0);
5416 if (val != *(u32 *)loc)
5421 +#ifdef CONFIG_PAX_KERNEXEC
5422 + pax_open_kernel(cr0);
5427 +#ifdef CONFIG_PAX_KERNEXEC
5428 + pax_close_kernel(cr0);
5431 if ((s64)val != *(s32 *)loc)
5437 +#ifdef CONFIG_PAX_KERNEXEC
5438 + pax_open_kernel(cr0);
5443 +#ifdef CONFIG_PAX_KERNEXEC
5444 + pax_close_kernel(cr0);
5448 if ((s64)val != *(s32 *)loc)
5450 diff -urNp linux-2.6.27.4/arch/x86/kernel/paravirt.c linux-2.6.27.4/arch/x86/kernel/paravirt.c
5451 --- linux-2.6.27.4/arch/x86/kernel/paravirt.c 2008-10-22 17:38:01.000000000 -0400
5452 +++ linux-2.6.27.4/arch/x86/kernel/paravirt.c 2008-10-27 22:36:17.000000000 -0400
5453 @@ -44,7 +44,7 @@ void _paravirt_nop(void)
5457 -static void __init default_banner(void)
5458 +static void default_banner(void)
5460 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
5462 @@ -164,7 +164,7 @@ unsigned paravirt_patch_insns(void *insn
5463 if (insn_len > len || start == NULL)
5466 - memcpy(insnbuf, start, insn_len);
5467 + memcpy(insnbuf, ktla_ktva(start), insn_len);
5471 @@ -279,21 +279,21 @@ void __init paravirt_use_bytelocks(void)
5475 -struct pv_info pv_info = {
5476 +struct pv_info pv_info __read_only = {
5477 .name = "bare hardware",
5478 .paravirt_enabled = 0,
5480 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
5483 -struct pv_init_ops pv_init_ops = {
5484 +struct pv_init_ops pv_init_ops __read_only = {
5485 .patch = native_patch,
5486 .banner = default_banner,
5487 .arch_setup = paravirt_nop,
5488 .memory_setup = machine_specific_memory_setup,
5491 -struct pv_time_ops pv_time_ops = {
5492 +struct pv_time_ops pv_time_ops __read_only = {
5493 .time_init = hpet_time_init,
5494 .get_wallclock = native_get_wallclock,
5495 .set_wallclock = native_set_wallclock,
5496 @@ -301,7 +301,7 @@ struct pv_time_ops pv_time_ops = {
5497 .get_tsc_khz = native_calibrate_tsc,
5500 -struct pv_irq_ops pv_irq_ops = {
5501 +struct pv_irq_ops pv_irq_ops __read_only = {
5502 .init_IRQ = native_init_IRQ,
5503 .save_fl = native_save_fl,
5504 .restore_fl = native_restore_fl,
5505 @@ -314,7 +314,7 @@ struct pv_irq_ops pv_irq_ops = {
5509 -struct pv_cpu_ops pv_cpu_ops = {
5510 +struct pv_cpu_ops pv_cpu_ops __read_only = {
5511 .cpuid = native_cpuid,
5512 .get_debugreg = native_get_debugreg,
5513 .set_debugreg = native_set_debugreg,
5514 @@ -371,7 +371,7 @@ struct pv_cpu_ops pv_cpu_ops = {
5518 -struct pv_apic_ops pv_apic_ops = {
5519 +struct pv_apic_ops pv_apic_ops __read_only = {
5520 #ifdef CONFIG_X86_LOCAL_APIC
5521 .apic_write = native_apic_write,
5522 .apic_read = native_apic_read,
5523 @@ -381,7 +381,7 @@ struct pv_apic_ops pv_apic_ops = {
5527 -struct pv_mmu_ops pv_mmu_ops = {
5528 +struct pv_mmu_ops pv_mmu_ops __read_only = {
5529 #ifndef CONFIG_X86_64
5530 .pagetable_setup_start = native_pagetable_setup_start,
5531 .pagetable_setup_done = native_pagetable_setup_done,
5532 @@ -461,7 +461,7 @@ struct pv_mmu_ops pv_mmu_ops = {
5533 .set_fixmap = native_set_fixmap,
5536 -struct pv_lock_ops pv_lock_ops = {
5537 +struct pv_lock_ops pv_lock_ops __read_only = {
5539 .spin_is_locked = __ticket_spin_is_locked,
5540 .spin_is_contended = __ticket_spin_is_contended,
5541 diff -urNp linux-2.6.27.4/arch/x86/kernel/process_32.c linux-2.6.27.4/arch/x86/kernel/process_32.c
5542 --- linux-2.6.27.4/arch/x86/kernel/process_32.c 2008-10-22 17:38:01.000000000 -0400
5543 +++ linux-2.6.27.4/arch/x86/kernel/process_32.c 2008-10-27 22:36:17.000000000 -0400
5544 @@ -62,8 +62,10 @@ asmlinkage void ret_from_fork(void) __as
5545 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
5546 EXPORT_PER_CPU_SYMBOL(current_task);
5549 DEFINE_PER_CPU(int, cpu_number);
5550 EXPORT_PER_CPU_SYMBOL(cpu_number);
5554 * Return saved PC of a blocked thread.
5555 @@ -71,6 +73,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
5556 unsigned long thread_saved_pc(struct task_struct *tsk)
5558 return ((unsigned long *)tsk->thread.sp)[3];
5559 +//XXX return tsk->thread.eip;
5562 #ifdef CONFIG_HOTPLUG_CPU
5563 @@ -162,7 +165,7 @@ void __show_registers(struct pt_regs *re
5565 unsigned short ss, gs;
5567 - if (user_mode_vm(regs)) {
5568 + if (user_mode(regs)) {
5570 ss = regs->ss & 0xffff;
5571 savesegment(gs, gs);
5572 @@ -239,8 +242,8 @@ int kernel_thread(int (*fn)(void *), voi
5573 regs.bx = (unsigned long) fn;
5574 regs.dx = (unsigned long) arg;
5576 - regs.ds = __USER_DS;
5577 - regs.es = __USER_DS;
5578 + regs.ds = __KERNEL_DS;
5579 + regs.es = __KERNEL_DS;
5580 regs.fs = __KERNEL_PERCPU;
5582 regs.ip = (unsigned long) kernel_thread_helper;
5583 @@ -262,7 +265,7 @@ void exit_thread(void)
5584 struct task_struct *tsk = current;
5585 struct thread_struct *t = &tsk->thread;
5586 int cpu = get_cpu();
5587 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
5588 + struct tss_struct *tss = init_tss + cpu;
5590 kfree(t->io_bitmap_ptr);
5591 t->io_bitmap_ptr = NULL;
5592 @@ -283,6 +286,7 @@ void flush_thread(void)
5594 struct task_struct *tsk = current;
5596 + loadsegment(gs, 0);
5597 tsk->thread.debugreg0 = 0;
5598 tsk->thread.debugreg1 = 0;
5599 tsk->thread.debugreg2 = 0;
5600 @@ -322,7 +326,7 @@ int copy_thread(int nr, unsigned long cl
5601 struct task_struct *tsk;
5604 - childregs = task_pt_regs(p);
5605 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
5609 @@ -351,6 +355,7 @@ int copy_thread(int nr, unsigned long cl
5610 * Set a new TLS for the child thread?
5612 if (clone_flags & CLONE_SETTLS)
5613 +//XXX needs set_fs()?
5614 err = do_set_thread_area(p, -1,
5615 (struct user_desc __user *)childregs->si, 0);
5617 @@ -550,7 +555,7 @@ struct task_struct * __switch_to(struct
5618 struct thread_struct *prev = &prev_p->thread,
5619 *next = &next_p->thread;
5620 int cpu = smp_processor_id();
5621 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
5622 + struct tss_struct *tss = init_tss + cpu;
5624 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
5626 @@ -578,6 +583,11 @@ struct task_struct * __switch_to(struct
5628 savesegment(gs, prev->gs);
5630 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5631 + if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
5632 + __set_fs(task_thread_info(next_p)->addr_limit, cpu);
5636 * Load the per-thread Thread-Local Storage descriptor.
5638 @@ -716,15 +726,27 @@ unsigned long get_wchan(struct task_stru
5642 -unsigned long arch_align_stack(unsigned long sp)
5643 +#ifdef CONFIG_PAX_RANDKSTACK
5644 +asmlinkage void pax_randomize_kstack(void)
5646 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
5647 - sp -= get_random_int() % 8192;
5650 + struct thread_struct *thread = ¤t->thread;
5651 + unsigned long time;
5653 -unsigned long arch_randomize_brk(struct mm_struct *mm)
5655 - unsigned long range_end = mm->brk + 0x02000000;
5656 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
5657 + if (!randomize_va_space)
5662 + /* P4 seems to return a 0 LSB, ignore it */
5663 +#ifdef CONFIG_MPENTIUM4
5671 + thread->sp0 ^= time;
5672 + load_sp0(init_tss + smp_processor_id(), thread);
5675 diff -urNp linux-2.6.27.4/arch/x86/kernel/process_64.c linux-2.6.27.4/arch/x86/kernel/process_64.c
5676 --- linux-2.6.27.4/arch/x86/kernel/process_64.c 2008-10-22 17:38:01.000000000 -0400
5677 +++ linux-2.6.27.4/arch/x86/kernel/process_64.c 2008-10-27 22:36:17.000000000 -0400
5678 @@ -119,6 +119,8 @@ static inline void play_dead(void)
5681 current_thread_info()->status |= TS_POLLING;
5682 + current->stack_canary = pax_get_random_long();
5683 + write_pda(stack_canary, current->stack_canary);
5684 /* endless idle loop with no priority at all */
5686 tick_nohz_stop_sched_tick(1);
5687 @@ -228,7 +230,7 @@ void exit_thread(void)
5688 struct thread_struct *t = &me->thread;
5690 if (me->thread.io_bitmap_ptr) {
5691 - struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
5692 + struct tss_struct *tss = init_tss + get_cpu();
5694 kfree(t->io_bitmap_ptr);
5695 t->io_bitmap_ptr = NULL;
5696 @@ -541,7 +543,7 @@ __switch_to(struct task_struct *prev_p,
5697 struct thread_struct *prev = &prev_p->thread;
5698 struct thread_struct *next = &next_p->thread;
5699 int cpu = smp_processor_id();
5700 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
5701 + struct tss_struct *tss = init_tss + cpu;
5702 unsigned fsindex, gsindex;
5704 /* we're going to use this soon, after a few expensive things */
5705 @@ -630,7 +632,6 @@ __switch_to(struct task_struct *prev_p,
5706 (unsigned long)task_stack_page(next_p) +
5707 THREAD_SIZE - PDA_STACKOFFSET);
5708 #ifdef CONFIG_CC_STACKPROTECTOR
5709 - write_pda(stack_canary, next_p->stack_canary);
5711 * Build time only check to make sure the stack_canary is at
5712 * offset 40 in the pda; this is a gcc ABI requirement
5713 @@ -844,16 +845,3 @@ long sys_arch_prctl(int code, unsigned l
5715 return do_arch_prctl(current, code, addr);
5718 -unsigned long arch_align_stack(unsigned long sp)
5720 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
5721 - sp -= get_random_int() % 8192;
5725 -unsigned long arch_randomize_brk(struct mm_struct *mm)
5727 - unsigned long range_end = mm->brk + 0x02000000;
5728 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
5730 diff -urNp linux-2.6.27.4/arch/x86/kernel/ptrace.c linux-2.6.27.4/arch/x86/kernel/ptrace.c
5731 --- linux-2.6.27.4/arch/x86/kernel/ptrace.c 2008-10-22 17:38:01.000000000 -0400
5732 +++ linux-2.6.27.4/arch/x86/kernel/ptrace.c 2008-10-27 22:36:17.000000000 -0400
5733 @@ -1369,7 +1369,7 @@ void send_sigtrap(struct task_struct *ts
5734 info.si_code = TRAP_BRKPT;
5737 - info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
5738 + info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
5740 /* Send us the fake SIGTRAP */
5741 force_sig_info(SIGTRAP, &info, tsk);
5742 diff -urNp linux-2.6.27.4/arch/x86/kernel/reboot.c linux-2.6.27.4/arch/x86/kernel/reboot.c
5743 --- linux-2.6.27.4/arch/x86/kernel/reboot.c 2008-10-22 17:38:01.000000000 -0400
5744 +++ linux-2.6.27.4/arch/x86/kernel/reboot.c 2008-10-27 22:36:17.000000000 -0400
5745 @@ -28,7 +28,7 @@ void (*pm_power_off)(void);
5746 EXPORT_SYMBOL(pm_power_off);
5748 static const struct desc_ptr no_idt = {};
5749 -static int reboot_mode;
5750 +static unsigned short reboot_mode;
5751 enum reboot_type reboot_type = BOOT_KBD;
5754 @@ -193,7 +193,7 @@ static struct dmi_system_id __initdata r
5755 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
5759 + { NULL, NULL, {{0, NULL}}, NULL}
5762 static int __init reboot_init(void)
5763 @@ -209,12 +209,12 @@ core_initcall(reboot_init);
5764 controller to pulse the CPU reset line, which is more thorough, but
5765 doesn't work with at least one type of 486 motherboard. It is easy
5766 to stop this code working; hence the copious comments. */
5767 -static const unsigned long long
5768 -real_mode_gdt_entries [3] =
5769 +static struct desc_struct
5770 +real_mode_gdt_entries [3] __read_only =
5772 - 0x0000000000000000ULL, /* Null descriptor */
5773 - 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
5774 - 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
5775 + {{{0x00000000, 0x00000000}}}, /* Null descriptor */
5776 + {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
5777 + {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
5780 static const struct desc_ptr
5781 @@ -263,7 +263,7 @@ static const unsigned char jump_to_bios
5782 * specified by the code and length parameters.
5783 * We assume that length will aways be less that 100!
5785 -void machine_real_restart(const unsigned char *code, int length)
5786 +void machine_real_restart(const unsigned char *code, unsigned int length)
5788 local_irq_disable();
5790 @@ -283,8 +283,8 @@ void machine_real_restart(const unsigned
5791 /* Remap the kernel at virtual address zero, as well as offset zero
5792 from the kernel segment. This assumes the kernel segment starts at
5793 virtual address PAGE_OFFSET. */
5794 - memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
5795 - sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
5796 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
5797 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
5800 * Use `swapper_pg_dir' as our page directory.
5801 @@ -296,16 +296,15 @@ void machine_real_restart(const unsigned
5802 boot)". This seems like a fairly standard thing that gets set by
5803 REBOOT.COM programs, and the previous reset routine did this
5805 - *((unsigned short *)0x472) = reboot_mode;
5806 + *(unsigned short *)(__va(0x472)) = reboot_mode;
5808 /* For the switch to real mode, copy some code to low memory. It has
5809 to be in the first 64k because it is running in 16-bit mode, and it
5810 has to have the same physical and virtual address, because it turns
5811 off paging. Copy it near the end of the first page, out of the way
5812 of BIOS variables. */
5813 - memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
5814 - real_mode_switch, sizeof (real_mode_switch));
5815 - memcpy((void *)(0x1000 - 100), code, length);
5816 + memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
5817 + memcpy(__va(0x1000 - 100), code, length);
5819 /* Set up the IDT for real mode. */
5820 load_idt(&real_mode_idt);
5821 diff -urNp linux-2.6.27.4/arch/x86/kernel/setup.c linux-2.6.27.4/arch/x86/kernel/setup.c
5822 --- linux-2.6.27.4/arch/x86/kernel/setup.c 2008-10-22 17:38:01.000000000 -0400
5823 +++ linux-2.6.27.4/arch/x86/kernel/setup.c 2008-10-27 22:36:17.000000000 -0400
5824 @@ -649,8 +649,8 @@ void __init setup_arch(char **cmdline_p)
5826 if (!boot_params.hdr.root_flags)
5827 root_mountflags &= ~MS_RDONLY;
5828 - init_mm.start_code = (unsigned long) _text;
5829 - init_mm.end_code = (unsigned long) _etext;
5830 + init_mm.start_code = ktla_ktva((unsigned long) _text);
5831 + init_mm.end_code = ktla_ktva((unsigned long) _etext);
5832 init_mm.end_data = (unsigned long) _edata;
5833 #ifdef CONFIG_X86_32
5834 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
5835 @@ -658,9 +658,9 @@ void __init setup_arch(char **cmdline_p)
5836 init_mm.brk = (unsigned long) &_end;
5839 - code_resource.start = virt_to_phys(_text);
5840 - code_resource.end = virt_to_phys(_etext)-1;
5841 - data_resource.start = virt_to_phys(_etext);
5842 + code_resource.start = virt_to_phys(ktla_ktva(_text));
5843 + code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
5844 + data_resource.start = virt_to_phys(_data);
5845 data_resource.end = virt_to_phys(_edata)-1;
5846 bss_resource.start = virt_to_phys(&__bss_start);
5847 bss_resource.end = virt_to_phys(&__bss_stop)-1;
5848 diff -urNp linux-2.6.27.4/arch/x86/kernel/setup_percpu.c linux-2.6.27.4/arch/x86/kernel/setup_percpu.c
5849 --- linux-2.6.27.4/arch/x86/kernel/setup_percpu.c 2008-10-22 17:38:01.000000000 -0400
5850 +++ linux-2.6.27.4/arch/x86/kernel/setup_percpu.c 2008-10-27 22:36:17.000000000 -0400
5851 @@ -166,7 +166,11 @@ void __init setup_per_cpu_areas(void)
5853 ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
5855 +#ifdef CONFIG_X86_32
5856 + __per_cpu_offset[cpu] = ptr - __per_cpu_start;
5858 per_cpu_offset(cpu) = ptr - __per_cpu_start;
5860 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
5863 diff -urNp linux-2.6.27.4/arch/x86/kernel/signal_32.c linux-2.6.27.4/arch/x86/kernel/signal_32.c
5864 --- linux-2.6.27.4/arch/x86/kernel/signal_32.c 2008-10-22 17:38:01.000000000 -0400
5865 +++ linux-2.6.27.4/arch/x86/kernel/signal_32.c 2008-10-27 22:36:17.000000000 -0400
5866 @@ -378,9 +378,9 @@ setup_frame(int sig, struct k_sigaction
5869 if (current->mm->context.vdso)
5870 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
5871 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
5873 - restorer = &frame->retcode;
5874 + restorer = (void __user *)&frame->retcode;
5875 if (ka->sa.sa_flags & SA_RESTORER)
5876 restorer = ka->sa.sa_restorer;
5878 @@ -460,7 +460,7 @@ static int setup_rt_frame(int sig, struc
5881 /* Set up to return from userspace. */
5882 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
5883 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
5884 if (ka->sa.sa_flags & SA_RESTORER)
5885 restorer = ka->sa.sa_restorer;
5886 err |= __put_user(restorer, &frame->pretcode);
5887 @@ -590,7 +590,7 @@ static void do_signal(struct pt_regs *re
5888 * X86_32: vm86 regs switched out by assembly code before reaching
5889 * here, so testing against kernel CS suffices.
5891 - if (!user_mode(regs))
5892 + if (!user_mode_novm(regs))
5895 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
5896 diff -urNp linux-2.6.27.4/arch/x86/kernel/signal_64.c linux-2.6.27.4/arch/x86/kernel/signal_64.c
5897 --- linux-2.6.27.4/arch/x86/kernel/signal_64.c 2008-10-22 17:38:01.000000000 -0400
5898 +++ linux-2.6.27.4/arch/x86/kernel/signal_64.c 2008-10-27 22:36:17.000000000 -0400
5899 @@ -312,8 +312,8 @@ static int setup_rt_frame(int sig, struc
5900 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
5901 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
5902 if (sizeof(*set) == 16) {
5903 - __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
5904 - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
5905 + err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
5906 + err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
5908 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
5910 diff -urNp linux-2.6.27.4/arch/x86/kernel/smpboot.c linux-2.6.27.4/arch/x86/kernel/smpboot.c
5911 --- linux-2.6.27.4/arch/x86/kernel/smpboot.c 2008-10-22 17:38:01.000000000 -0400
5912 +++ linux-2.6.27.4/arch/x86/kernel/smpboot.c 2008-10-27 22:36:17.000000000 -0400
5913 @@ -816,6 +816,11 @@ static int __cpuinit do_boot_cpu(int api
5915 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
5918 +#ifdef CONFIG_PAX_KERNEXEC
5919 + unsigned long cr0;
5922 INIT_WORK(&c_idle.work, do_fork_idle);
5924 #ifdef CONFIG_X86_64
5925 @@ -866,7 +871,17 @@ do_rest:
5926 cpu_pda(cpu)->pcurrent = c_idle.idle;
5927 clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
5930 +#ifdef CONFIG_PAX_KERNEXEC
5931 + pax_open_kernel(cr0);
5934 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
5936 +#ifdef CONFIG_PAX_KERNEXEC
5937 + pax_close_kernel(cr0);
5940 initial_code = (unsigned long)start_secondary;
5941 stack_start.sp = (void *) c_idle.idle->thread.sp;
5943 diff -urNp linux-2.6.27.4/arch/x86/kernel/smpcommon.c linux-2.6.27.4/arch/x86/kernel/smpcommon.c
5944 --- linux-2.6.27.4/arch/x86/kernel/smpcommon.c 2008-10-22 17:38:01.000000000 -0400
5945 +++ linux-2.6.27.4/arch/x86/kernel/smpcommon.c 2008-10-27 22:36:17.000000000 -0400
5948 #include <linux/module.h>
5949 #include <asm/smp.h>
5950 +#include <asm/sections.h>
5952 #ifdef CONFIG_X86_32
5953 -DEFINE_PER_CPU(unsigned long, this_cpu_off);
5954 +DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
5955 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
5958 @@ -15,16 +16,19 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
5960 __cpuinit void init_gdt(int cpu)
5962 - struct desc_struct gdt;
5963 + struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
5964 + unsigned long base, limit;
5966 - pack_descriptor(&gdt, __per_cpu_offset[cpu], 0xFFFFF,
5967 - 0x2 | DESCTYPE_S, 0x8);
5969 + base = per_cpu_offset(cpu);
5970 + limit = PERCPU_ENOUGH_ROOM - 1;
5971 + if (limit < 64*1024)
5972 + pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
5974 + pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
5976 - write_gdt_entry(get_cpu_gdt_table(cpu),
5977 - GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
5978 + write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
5980 - per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
5981 + per_cpu(this_cpu_off, cpu) = base;
5982 per_cpu(cpu_number, cpu) = cpu;
5985 diff -urNp linux-2.6.27.4/arch/x86/kernel/step.c linux-2.6.27.4/arch/x86/kernel/step.c
5986 --- linux-2.6.27.4/arch/x86/kernel/step.c 2008-10-22 17:38:01.000000000 -0400
5987 +++ linux-2.6.27.4/arch/x86/kernel/step.c 2008-10-27 22:36:17.000000000 -0400
5988 @@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
5989 * and APM bios ones we just ignore here.
5991 if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
5993 + struct desc_struct *desc;
5999 mutex_lock(&child->mm->context.lock);
6000 - if (unlikely((seg >> 3) >= child->mm->context.size))
6001 - addr = -1L; /* bogus selector, access would fault */
6002 + if (unlikely(seg >= child->mm->context.size))
6005 - desc = child->mm->context.ldt + seg;
6006 - base = ((desc[0] >> 16) |
6007 - ((desc[1] & 0xff) << 16) |
6008 - (desc[1] & 0xff000000));
6009 + desc = &child->mm->context.ldt[seg];
6010 + base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
6012 /* 16-bit code segment? */
6013 - if (!((desc[1] >> 22) & 1))
6014 + if (!((desc->b >> 22) & 1))
6018 @@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
6019 unsigned char opcode[15];
6020 unsigned long addr = convert_ip_to_linear(child, regs);
6022 + if (addr == -EINVAL)
6025 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6026 for (i = 0; i < copied; i++) {
6027 switch (opcode[i]) {
6028 @@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
6030 #ifdef CONFIG_X86_64
6032 - if (regs->cs != __USER_CS)
6033 + if ((regs->cs & 0xffff) != __USER_CS)
6034 /* 32-bit mode: register increment */
6036 /* 64-bit mode: REX prefix */
6037 diff -urNp linux-2.6.27.4/arch/x86/kernel/syscall_table_32.S linux-2.6.27.4/arch/x86/kernel/syscall_table_32.S
6038 --- linux-2.6.27.4/arch/x86/kernel/syscall_table_32.S 2008-10-22 17:38:01.000000000 -0400
6039 +++ linux-2.6.27.4/arch/x86/kernel/syscall_table_32.S 2008-10-27 22:36:17.000000000 -0400
6041 +.section .rodata,"a",@progbits
6042 ENTRY(sys_call_table)
6043 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
6045 diff -urNp linux-2.6.27.4/arch/x86/kernel/sys_i386_32.c linux-2.6.27.4/arch/x86/kernel/sys_i386_32.c
6046 --- linux-2.6.27.4/arch/x86/kernel/sys_i386_32.c 2008-10-22 17:38:01.000000000 -0400
6047 +++ linux-2.6.27.4/arch/x86/kernel/sys_i386_32.c 2008-10-27 22:36:17.000000000 -0400
6049 #include <linux/uaccess.h>
6050 #include <linux/unistd.h>
6052 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
6054 + unsigned long pax_task_size = TASK_SIZE;
6056 +#ifdef CONFIG_PAX_SEGMEXEC
6057 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
6058 + pax_task_size = SEGMEXEC_TASK_SIZE;
6061 + if (len > pax_task_size || addr > pax_task_size - len)
6067 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
6068 unsigned long prot, unsigned long flags,
6069 unsigned long fd, unsigned long pgoff)
6070 @@ -81,6 +96,205 @@ out:
6075 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
6076 + unsigned long len, unsigned long pgoff, unsigned long flags)
6078 + struct mm_struct *mm = current->mm;
6079 + struct vm_area_struct *vma;
6080 + unsigned long start_addr, pax_task_size = TASK_SIZE;
6082 +#ifdef CONFIG_PAX_SEGMEXEC
6083 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6084 + pax_task_size = SEGMEXEC_TASK_SIZE;
6087 + if (len > pax_task_size)
6090 + if (flags & MAP_FIXED)
6093 +#ifdef CONFIG_PAX_RANDMMAP
6094 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6098 + addr = PAGE_ALIGN(addr);
6099 + vma = find_vma(mm, addr);
6100 + if (pax_task_size - len >= addr &&
6101 + (!vma || addr + len <= vma->vm_start))
6104 + if (len > mm->cached_hole_size) {
6105 + start_addr = addr = mm->free_area_cache;
6107 + start_addr = addr = mm->mmap_base;
6108 + mm->cached_hole_size = 0;
6111 +#ifdef CONFIG_PAX_PAGEEXEC
6112 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
6113 + start_addr = 0x00110000UL;
6115 +#ifdef CONFIG_PAX_RANDMMAP
6116 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6117 + start_addr += mm->delta_mmap & 0x03FFF000UL;
6120 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
6121 + start_addr = addr = mm->mmap_base;
6123 + addr = start_addr;
6128 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6129 + /* At this point: (!vma || addr < vma->vm_end). */
6130 + if (pax_task_size - len < addr) {
6132 + * Start a new search - just in case we missed
6135 + if (start_addr != mm->mmap_base) {
6136 + start_addr = addr = mm->mmap_base;
6137 + mm->cached_hole_size = 0;
6142 + if (!vma || addr + len <= vma->vm_start) {
6144 + * Remember the place where we stopped the search:
6146 + mm->free_area_cache = addr + len;
6149 + if (addr + mm->cached_hole_size < vma->vm_start)
6150 + mm->cached_hole_size = vma->vm_start - addr;
6151 + addr = vma->vm_end;
6152 + if (mm->start_brk <= addr && addr < mm->mmap_base) {
6153 + start_addr = addr = mm->mmap_base;
6154 + mm->cached_hole_size = 0;
6161 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
6162 + const unsigned long len, const unsigned long pgoff,
6163 + const unsigned long flags)
6165 + struct vm_area_struct *vma;
6166 + struct mm_struct *mm = current->mm;
6167 + unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
6169 +#ifdef CONFIG_PAX_SEGMEXEC
6170 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6171 + pax_task_size = SEGMEXEC_TASK_SIZE;
6174 + /* requested length too big for entire address space */
6175 + if (len > pax_task_size)
6178 + if (flags & MAP_FIXED)
6181 +#ifdef CONFIG_PAX_PAGEEXEC
6182 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
6186 +#ifdef CONFIG_PAX_RANDMMAP
6187 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6190 + /* requesting a specific address */
6192 + addr = PAGE_ALIGN(addr);
6193 + vma = find_vma(mm, addr);
6194 + if (pax_task_size - len >= addr &&
6195 + (!vma || addr + len <= vma->vm_start))
6199 + /* check if free_area_cache is useful for us */
6200 + if (len <= mm->cached_hole_size) {
6201 + mm->cached_hole_size = 0;
6202 + mm->free_area_cache = mm->mmap_base;
6205 + /* either no address requested or can't fit in requested address hole */
6206 + addr = mm->free_area_cache;
6208 + /* make sure it can fit in the remaining address space */
6210 + vma = find_vma(mm, addr-len);
6211 + if (!vma || addr <= vma->vm_start)
6212 + /* remember the address as a hint for next time */
6213 + return (mm->free_area_cache = addr-len);
6216 + if (mm->mmap_base < len)
6219 + addr = mm->mmap_base-len;
6223 + * Lookup failure means no vma is above this address,
6224 + * else if new region fits below vma->vm_start,
6225 + * return with success:
6227 + vma = find_vma(mm, addr);
6228 + if (!vma || addr+len <= vma->vm_start)
6229 + /* remember the address as a hint for next time */
6230 + return (mm->free_area_cache = addr);
6232 + /* remember the largest hole we saw so far */
6233 + if (addr + mm->cached_hole_size < vma->vm_start)
6234 + mm->cached_hole_size = vma->vm_start - addr;
6236 + /* try just below the current vma->vm_start */
6237 + addr = vma->vm_start-len;
6238 + } while (len < vma->vm_start);
6242 + * A failed mmap() very likely causes application failure,
6243 + * so fall back to the bottom-up function here. This scenario
6244 + * can happen with large stack limits and large mmap()
6248 +#ifdef CONFIG_PAX_SEGMEXEC
6249 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6250 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
6254 + mm->mmap_base = TASK_UNMAPPED_BASE;
6256 +#ifdef CONFIG_PAX_RANDMMAP
6257 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6258 + mm->mmap_base += mm->delta_mmap;
6261 + mm->free_area_cache = mm->mmap_base;
6262 + mm->cached_hole_size = ~0UL;
6263 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6265 + * Restore the topdown base:
6267 + mm->mmap_base = base;
6268 + mm->free_area_cache = base;
6269 + mm->cached_hole_size = ~0UL;
6274 struct sel_arg_struct {
6276 diff -urNp linux-2.6.27.4/arch/x86/kernel/sys_x86_64.c linux-2.6.27.4/arch/x86/kernel/sys_x86_64.c
6277 --- linux-2.6.27.4/arch/x86/kernel/sys_x86_64.c 2008-10-22 17:38:01.000000000 -0400
6278 +++ linux-2.6.27.4/arch/x86/kernel/sys_x86_64.c 2008-10-27 22:36:17.000000000 -0400
6279 @@ -45,8 +45,8 @@ out:
6283 -static void find_start_end(unsigned long flags, unsigned long *begin,
6284 - unsigned long *end)
6285 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
6286 + unsigned long *begin, unsigned long *end)
6288 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
6289 unsigned long new_begin;
6290 @@ -65,7 +65,7 @@ static void find_start_end(unsigned long
6294 - *begin = TASK_UNMAPPED_BASE;
6295 + *begin = mm->mmap_base;
6299 @@ -82,11 +82,15 @@ arch_get_unmapped_area(struct file *filp
6300 if (flags & MAP_FIXED)
6303 - find_start_end(flags, &begin, &end);
6304 + find_start_end(mm, flags, &begin, &end);
6309 +#ifdef CONFIG_PAX_RANDMMAP
6310 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6314 addr = PAGE_ALIGN(addr);
6315 vma = find_vma(mm, addr);
6316 @@ -141,7 +145,7 @@ arch_get_unmapped_area_topdown(struct fi
6318 struct vm_area_struct *vma;
6319 struct mm_struct *mm = current->mm;
6320 - unsigned long addr = addr0;
6321 + unsigned long base = mm->mmap_base, addr = addr0;
6323 /* requested length too big for entire address space */
6324 if (len > TASK_SIZE)
6325 @@ -154,6 +158,10 @@ arch_get_unmapped_area_topdown(struct fi
6326 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
6329 +#ifdef CONFIG_PAX_RANDMMAP
6330 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
6333 /* requesting a specific address */
6335 addr = PAGE_ALIGN(addr);
6336 @@ -211,13 +219,21 @@ bottomup:
6337 * can happen with large stack limits and large mmap()
6340 + mm->mmap_base = TASK_UNMAPPED_BASE;
6342 +#ifdef CONFIG_PAX_RANDMMAP
6343 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6344 + mm->mmap_base += mm->delta_mmap;
6347 + mm->free_area_cache = mm->mmap_base;
6348 mm->cached_hole_size = ~0UL;
6349 - mm->free_area_cache = TASK_UNMAPPED_BASE;
6350 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6352 * Restore the topdown base:
6354 - mm->free_area_cache = mm->mmap_base;
6355 + mm->mmap_base = base;
6356 + mm->free_area_cache = base;
6357 mm->cached_hole_size = ~0UL;
6360 diff -urNp linux-2.6.27.4/arch/x86/kernel/time_32.c linux-2.6.27.4/arch/x86/kernel/time_32.c
6361 --- linux-2.6.27.4/arch/x86/kernel/time_32.c 2008-10-22 17:38:01.000000000 -0400
6362 +++ linux-2.6.27.4/arch/x86/kernel/time_32.c 2008-10-27 22:36:17.000000000 -0400
6363 @@ -49,20 +49,30 @@ unsigned long profile_pc(struct pt_regs
6364 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
6365 in_lock_functions(pc)) {
6366 #ifdef CONFIG_FRAME_POINTER
6367 - return *(unsigned long *)(regs->bp + 4);
6368 + return ktla_ktva(*(unsigned long *)(regs->bp + 4));
6370 unsigned long *sp = (unsigned long *)®s->sp;
6372 /* Return address is either directly at stack pointer
6373 or above a saved flags. Eflags has bits 22-31 zero,
6374 kernel addresses don't. */
6376 +#ifdef CONFIG_PAX_KERNEXEC
6377 + return ktla_ktva(sp[0]);
6389 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
6390 + pc = ktla_ktva(pc);
6394 EXPORT_SYMBOL(profile_pc);
6395 diff -urNp linux-2.6.27.4/arch/x86/kernel/tlb_32.c linux-2.6.27.4/arch/x86/kernel/tlb_32.c
6396 --- linux-2.6.27.4/arch/x86/kernel/tlb_32.c 2008-10-22 17:38:01.000000000 -0400
6397 +++ linux-2.6.27.4/arch/x86/kernel/tlb_32.c 2008-10-27 22:36:17.000000000 -0400
6399 #include <asm/tlbflush.h>
6401 DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
6402 - ____cacheline_aligned = { &init_mm, 0, };
6403 + ____cacheline_aligned = { &init_mm, 0, {0} };
6405 /* must come after the send_IPI functions above for inlining */
6406 #include <mach_ipi.h>
6407 diff -urNp linux-2.6.27.4/arch/x86/kernel/tls.c linux-2.6.27.4/arch/x86/kernel/tls.c
6408 --- linux-2.6.27.4/arch/x86/kernel/tls.c 2008-10-22 17:38:01.000000000 -0400
6409 +++ linux-2.6.27.4/arch/x86/kernel/tls.c 2008-10-27 22:36:17.000000000 -0400
6410 @@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
6411 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6414 +#ifdef CONFIG_PAX_SEGMEXEC
6415 + if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6419 set_tls_desc(p, idx, &info, 1);
6422 diff -urNp linux-2.6.27.4/arch/x86/kernel/traps_32.c linux-2.6.27.4/arch/x86/kernel/traps_32.c
6423 --- linux-2.6.27.4/arch/x86/kernel/traps_32.c 2008-10-22 17:38:01.000000000 -0400
6424 +++ linux-2.6.27.4/arch/x86/kernel/traps_32.c 2008-10-27 22:36:17.000000000 -0400
6425 @@ -70,14 +70,6 @@ asmlinkage int system_call(void);
6426 /* Do we ignore FPU interrupts ? */
6427 char ignore_fpu_irq;
6430 - * The IDT has to be page-aligned to simplify the Pentium
6431 - * F0 0F bug workaround.. We have a special link segment
6434 -gate_desc idt_table[256]
6435 - __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
6437 int panic_on_unrecovered_nmi;
6438 int kstack_depth_to_print = 24;
6439 static unsigned int code_bytes = 64;
6440 @@ -320,21 +312,22 @@ void show_registers(struct pt_regs *regs
6441 * When in-kernel, we also print out the stack and code at the
6442 * time of the fault..
6444 - if (!user_mode_vm(regs)) {
6445 + if (!user_mode(regs)) {
6446 unsigned int code_prologue = code_bytes * 43 / 64;
6447 unsigned int code_len = code_bytes;
6450 + unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
6452 printk("\n" KERN_EMERG "Stack: ");
6453 show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG);
6455 printk(KERN_EMERG "Code: ");
6457 - ip = (u8 *)regs->ip - code_prologue;
6458 + ip = (u8 *)regs->ip - code_prologue + cs_base;
6459 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
6460 /* try starting at EIP */
6461 - ip = (u8 *)regs->ip;
6462 + ip = (u8 *)regs->ip + cs_base;
6463 code_len = code_len - code_prologue + 1;
6465 for (i = 0; i < code_len; i++, ip++) {
6466 @@ -343,7 +336,7 @@ void show_registers(struct pt_regs *regs
6467 printk(" Bad EIP value.");
6470 - if (ip == (u8 *)regs->ip)
6471 + if (ip == (u8 *)regs->ip + cs_base)
6472 printk("<%02x> ", c);
6475 @@ -356,6 +349,7 @@ int is_valid_bugaddr(unsigned long ip)
6479 + ip = ktla_ktva(ip);
6480 if (ip < PAGE_OFFSET)
6482 if (probe_kernel_address((unsigned short *)ip, ud2))
6483 @@ -469,7 +463,7 @@ void die(const char *str, struct pt_regs
6485 die_if_kernel(const char *str, struct pt_regs *regs, long err)
6487 - if (!user_mode_vm(regs))
6488 + if (!user_mode(regs))
6489 die(str, regs, err);
6492 @@ -479,7 +473,7 @@ do_trap(int trapnr, int signr, char *str
6494 struct task_struct *tsk = current;
6496 - if (regs->flags & X86_VM_MASK) {
6497 + if (v8086_mode(regs)) {
6501 @@ -513,6 +507,12 @@ kernel_trap:
6502 tsk->thread.trap_no = trapnr;
6503 die(str, regs, error_code);
6506 +#ifdef CONFIG_PAX_REFCOUNT
6508 + pax_report_refcount_overflow(regs);
6514 @@ -595,7 +595,7 @@ do_general_protection(struct pt_regs *re
6518 - tss = &per_cpu(init_tss, cpu);
6519 + tss = init_tss + cpu;
6520 thread = ¤t->thread;
6523 @@ -627,13 +627,29 @@ do_general_protection(struct pt_regs *re
6527 - if (regs->flags & X86_VM_MASK)
6528 + if (v8086_mode(regs))
6532 - if (!user_mode(regs))
6533 + if (!user_mode_novm(regs))
6536 +#ifdef CONFIG_PAX_PAGEEXEC
6537 + if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
6538 + struct mm_struct *mm = tsk->mm;
6539 + unsigned long limit;
6541 + down_write(&mm->mmap_sem);
6542 + limit = mm->context.user_cs_limit;
6543 + if (limit < TASK_SIZE) {
6544 + track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
6545 + up_write(&mm->mmap_sem);
6548 + up_write(&mm->mmap_sem);
6552 tsk->thread.error_code = error_code;
6553 tsk->thread.trap_no = 13;
6555 @@ -664,6 +680,13 @@ gp_in_kernel:
6556 if (notify_die(DIE_GPF, "general protection fault", regs,
6557 error_code, 13, SIGSEGV) == NOTIFY_STOP)
6560 +#ifdef CONFIG_PAX_KERNEXEC
6561 + if ((regs->cs & 0xFFFF) == __KERNEL_CS)
6562 + die("PAX: suspicious general protection fault", regs, error_code);
6566 die("general protection fault", regs, error_code);
6569 @@ -766,7 +789,7 @@ void notrace __kprobes die_nmi(char *str
6570 * If we are in kernel we are probably nested up pretty bad
6571 * and might aswell get out now while we still can:
6573 - if (!user_mode_vm(regs)) {
6574 + if (!user_mode(regs)) {
6575 current->thread.trap_no = 2;
6578 @@ -915,7 +938,7 @@ void __kprobes do_debug(struct pt_regs *
6582 - if (regs->flags & X86_VM_MASK)
6583 + if (v8086_mode(regs))
6586 /* Save debug status register where ptrace can see it */
6587 @@ -931,7 +954,7 @@ void __kprobes do_debug(struct pt_regs *
6588 * check for kernel mode by just checking the CPL
6591 - if (!user_mode(regs))
6592 + if (!user_mode_novm(regs))
6593 goto clear_TF_reenable;
6596 @@ -1086,7 +1109,7 @@ void do_simd_coprocessor_error(struct pt
6597 * Handle strange cache flush from user space exception
6598 * in all other cases. This is undocumented behaviour.
6600 - if (regs->flags & X86_VM_MASK) {
6601 + if (v8086_mode(regs)) {
6602 handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
6605 @@ -1106,19 +1129,14 @@ void do_spurious_interrupt_bug(struct pt
6607 unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
6609 - struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
6610 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
6611 unsigned long new_kesp = kesp - base;
6612 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
6613 - __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
6614 + struct desc_struct ss;
6616 /* Set up base for espfix segment */
6617 - desc &= 0x00f0ff0000000000ULL;
6618 - desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
6619 - ((((__u64)base) << 32) & 0xff00000000000000ULL) |
6620 - ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
6621 - (lim_pages & 0xffff);
6622 - *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
6623 + pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
6624 + write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
6628 diff -urNp linux-2.6.27.4/arch/x86/kernel/traps_64.c linux-2.6.27.4/arch/x86/kernel/traps_64.c
6629 --- linux-2.6.27.4/arch/x86/kernel/traps_64.c 2008-10-22 17:38:01.000000000 -0400
6630 +++ linux-2.6.27.4/arch/x86/kernel/traps_64.c 2008-10-27 22:36:17.000000000 -0400
6631 @@ -634,6 +634,12 @@ kernel_trap:
6632 tsk->thread.trap_no = trapnr;
6633 die(str, regs, error_code);
6636 +#ifdef CONFIG_PAX_REFCOUNT
6638 + pax_report_refcount_overflow(regs);
6644 diff -urNp linux-2.6.27.4/arch/x86/kernel/tsc.c linux-2.6.27.4/arch/x86/kernel/tsc.c
6645 --- linux-2.6.27.4/arch/x86/kernel/tsc.c 2008-10-22 17:38:01.000000000 -0400
6646 +++ linux-2.6.27.4/arch/x86/kernel/tsc.c 2008-10-27 22:36:17.000000000 -0400
6647 @@ -554,7 +554,7 @@ static struct dmi_system_id __initdata b
6648 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
6652 + { NULL, NULL, {{0, NULL}}, NULL}
6656 diff -urNp linux-2.6.27.4/arch/x86/kernel/vm86_32.c linux-2.6.27.4/arch/x86/kernel/vm86_32.c
6657 --- linux-2.6.27.4/arch/x86/kernel/vm86_32.c 2008-10-22 17:38:01.000000000 -0400
6658 +++ linux-2.6.27.4/arch/x86/kernel/vm86_32.c 2008-10-27 22:36:17.000000000 -0400
6659 @@ -147,7 +147,7 @@ struct pt_regs *save_v86_state(struct ke
6663 - tss = &per_cpu(init_tss, get_cpu());
6664 + tss = init_tss + get_cpu();
6665 current->thread.sp0 = current->thread.saved_sp0;
6666 current->thread.sysenter_cs = __KERNEL_CS;
6667 load_sp0(tss, ¤t->thread);
6668 @@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
6669 tsk->thread.saved_fs = info->regs32->fs;
6670 savesegment(gs, tsk->thread.saved_gs);
6672 - tss = &per_cpu(init_tss, get_cpu());
6673 + tss = init_tss + get_cpu();
6674 tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
6676 tsk->thread.sysenter_cs = 0;
6677 diff -urNp linux-2.6.27.4/arch/x86/kernel/vmi_32.c linux-2.6.27.4/arch/x86/kernel/vmi_32.c
6678 --- linux-2.6.27.4/arch/x86/kernel/vmi_32.c 2008-10-22 17:38:01.000000000 -0400
6679 +++ linux-2.6.27.4/arch/x86/kernel/vmi_32.c 2008-10-27 22:36:17.000000000 -0400
6680 @@ -102,18 +102,43 @@ static unsigned patch_internal(int call,
6683 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
6685 +#ifdef CONFIG_PAX_KERNEXEC
6686 + unsigned long cr0;
6689 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
6691 case VMI_RELOCATION_CALL_REL:
6694 +#ifdef CONFIG_PAX_KERNEXEC
6695 + pax_open_kernel(cr0);
6698 *(char *)insnbuf = MNEM_CALL;
6699 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
6701 +#ifdef CONFIG_PAX_KERNEXEC
6702 + pax_close_kernel(cr0);
6707 case VMI_RELOCATION_JUMP_REL:
6710 +#ifdef CONFIG_PAX_KERNEXEC
6711 + pax_open_kernel(cr0);
6714 *(char *)insnbuf = MNEM_JMP;
6715 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
6717 +#ifdef CONFIG_PAX_KERNEXEC
6718 + pax_close_kernel(cr0);
6723 case VMI_RELOCATION_NOP:
6724 @@ -516,14 +541,14 @@ static void vmi_set_pud(pud_t *pudp, pud
6726 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
6728 - const pte_t pte = { .pte = 0 };
6729 + const pte_t pte = __pte(0ULL);
6730 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
6731 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
6734 static void vmi_pmd_clear(pmd_t *pmd)
6736 - const pte_t pte = { .pte = 0 };
6737 + const pte_t pte = __pte(0ULL);
6738 vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
6739 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
6741 @@ -552,8 +577,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
6742 ap.ss = __KERNEL_DS;
6743 ap.esp = (unsigned long) start_esp;
6745 - ap.ds = __USER_DS;
6746 - ap.es = __USER_DS;
6747 + ap.ds = __KERNEL_DS;
6748 + ap.es = __KERNEL_DS;
6749 ap.fs = __KERNEL_PERCPU;
6752 @@ -748,12 +773,20 @@ static inline int __init activate_vmi(vo
6754 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
6756 +#ifdef CONFIG_PAX_KERNEXEC
6757 + unsigned long cr0;
6760 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
6761 printk(KERN_ERR "VMI ROM failed to initialize!");
6764 savesegment(cs, kernel_cs);
6766 +#ifdef CONFIG_PAX_KERNEXEC
6767 + pax_open_kernel(cr0);
6770 pv_info.paravirt_enabled = 1;
6771 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
6772 pv_info.name = "vmi";
6773 @@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
6775 para_fill(pv_irq_ops.safe_halt, Halt);
6777 +#ifdef CONFIG_PAX_KERNEXEC
6778 + pax_close_kernel(cr0);
6782 * Alternative instruction rewriting doesn't happen soon enough
6783 * to convert VMI_IRET to a call instead of a jump; so we have
6784 diff -urNp linux-2.6.27.4/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.27.4/arch/x86/kernel/vmlinux_32.lds.S
6785 --- linux-2.6.27.4/arch/x86/kernel/vmlinux_32.lds.S 2008-10-22 17:38:01.000000000 -0400
6786 +++ linux-2.6.27.4/arch/x86/kernel/vmlinux_32.lds.S 2008-10-27 22:36:17.000000000 -0400
6788 #include <asm/page.h>
6789 #include <asm/cache.h>
6790 #include <asm/boot.h>
6791 +#include <asm/segment.h>
6793 +#ifdef CONFIG_X86_PAE
6794 +#define PMD_SHIFT 21
6796 +#define PMD_SHIFT 22
6798 +#define PMD_SIZE (1 << PMD_SHIFT)
6800 +#ifdef CONFIG_PAX_KERNEXEC
6801 +#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
6803 +#define __KERNEL_TEXT_OFFSET 0
6806 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
6808 @@ -22,81 +36,23 @@ ENTRY(phys_startup_32)
6809 jiffies = jiffies_64;
6812 - text PT_LOAD FLAGS(5); /* R_E */
6813 - data PT_LOAD FLAGS(7); /* RWE */
6814 - note PT_NOTE FLAGS(0); /* ___ */
6815 + initdata PT_LOAD FLAGS(6); /* RW_ */
6816 + percpu PT_LOAD FLAGS(6); /* RW_ */
6817 + inittext PT_LOAD FLAGS(5); /* R_E */
6818 + text PT_LOAD FLAGS(5); /* R_E */
6819 + rodata PT_LOAD FLAGS(4); /* R__ */
6820 + data PT_LOAD FLAGS(6); /* RW_ */
6821 + note PT_NOTE FLAGS(0); /* ___ */
6825 - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
6826 - phys_startup_32 = startup_32 - LOAD_OFFSET;
6828 - .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
6829 - _text = .; /* Text and read-only data */
6834 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
6835 - . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
6836 - *(.text.page_aligned)
6843 - _etext = .; /* End of text section */
6847 + . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
6849 - . = ALIGN(16); /* Exception table */
6850 - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
6851 - __start___ex_table = .;
6853 - __stop___ex_table = .;
6859 - . = ALIGN(PAGE_SIZE);
6860 - .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
6865 - . = ALIGN(PAGE_SIZE);
6866 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
6867 - __nosave_begin = .;
6869 - . = ALIGN(PAGE_SIZE);
6873 - . = ALIGN(PAGE_SIZE);
6874 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
6875 - *(.data.page_aligned)
6880 - .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
6881 - *(.data.cacheline_aligned)
6884 - /* rarely changed data like cpu maps */
6886 - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
6887 - *(.data.read_mostly)
6888 - _edata = .; /* End of data section */
6891 - . = ALIGN(THREAD_SIZE); /* init_task */
6892 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
6893 - *(.data.init_task)
6895 + .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
6896 + __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
6897 + phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
6901 /* might get freed after init */
6902 . = ALIGN(PAGE_SIZE);
6903 @@ -114,14 +70,8 @@ SECTIONS
6904 . = ALIGN(PAGE_SIZE);
6906 /* will be freed after init */
6907 - . = ALIGN(PAGE_SIZE); /* Init code and data */
6908 - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
6914 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
6919 @@ -161,11 +111,6 @@ SECTIONS
6920 *(.parainstructions)
6921 __parainstructions_end = .;
6923 - /* .exit.text is discard at runtime, not link time, to deal with references
6924 - from .altinstructions and .eh_frame */
6925 - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
6928 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
6931 @@ -178,17 +123,136 @@ SECTIONS
6934 . = ALIGN(PAGE_SIZE);
6935 - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
6936 - __per_cpu_start = .;
6937 + per_cpu_start = .;
6938 + .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
6939 + __per_cpu_start = . + per_cpu_start;
6942 *(.data.percpu.shared_aligned)
6943 - __per_cpu_end = .;
6945 + __per_cpu_end = . + per_cpu_start;
6947 + . += per_cpu_start;
6948 . = ALIGN(PAGE_SIZE);
6949 /* freed after init ends here */
6951 + . = ALIGN(PAGE_SIZE); /* Init code and data */
6952 + .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
6958 + /* .exit.text is discard at runtime, not link time, to deal with references
6959 + from .altinstructions and .eh_frame */
6960 + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
6964 + .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
6966 + . = ALIGN(2*PMD_SIZE) - 1;
6969 + /* freed after init ends here */
6971 + .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
6972 + __init_end = . + __KERNEL_TEXT_OFFSET;
6973 + KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
6974 + _text = .; /* Text and read-only data */
6979 + .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
6980 + . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
6981 + *(.text.page_aligned)
6988 + _etext = .; /* End of text section */
6991 + . += __KERNEL_TEXT_OFFSET;
6993 + . = ALIGN(4096); /* Exception table */
6994 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
6995 + __start___ex_table = .;
6997 + __stop___ex_table = .;
7000 + NOTES :rodata :note
7002 + RO_DATA(PAGE_SIZE)
7004 + . = ALIGN(PAGE_SIZE);
7005 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
7007 + . = ALIGN(PAGE_SIZE);
7008 + *(.empty_zero_page)
7009 + *(.swapper_pg_pmd)
7010 + *(.swapper_pg_dir)
7013 +#ifdef CONFIG_PAX_KERNEXEC
7015 +#ifdef CONFIG_MODULES
7016 + . = ALIGN(PAGE_SIZE);
7017 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
7018 + MODULES_VADDR = .;
7020 + . += (6 * 1024 * 1024);
7021 + . = ALIGN( PMD_SIZE) - 1;
7025 + . = ALIGN(PMD_SIZE) - 1;
7031 + . = ALIGN(PAGE_SIZE);
7032 + .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7038 + . = ALIGN(PAGE_SIZE);
7039 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
7040 + __nosave_begin = .;
7042 + . = ALIGN(PAGE_SIZE);
7046 + . = ALIGN(PAGE_SIZE);
7047 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7048 + *(.data.page_aligned)
7052 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7053 + *(.data.cacheline_aligned)
7056 + /* rarely changed data like cpu maps */
7058 + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
7059 + *(.data.read_mostly)
7060 + _edata = .; /* End of data section */
7063 + . = ALIGN(THREAD_SIZE); /* init_task */
7064 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7065 + *(.data.init_task)
7068 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7070 __bss_start = .; /* BSS */
7071 *(.bss.page_aligned)
7073 diff -urNp linux-2.6.27.4/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.27.4/arch/x86/kernel/vmlinux_64.lds.S
7074 --- linux-2.6.27.4/arch/x86/kernel/vmlinux_64.lds.S 2008-10-22 17:38:01.000000000 -0400
7075 +++ linux-2.6.27.4/arch/x86/kernel/vmlinux_64.lds.S 2008-10-27 22:36:17.000000000 -0400
7076 @@ -16,7 +16,7 @@ jiffies_64 = jiffies;
7079 text PT_LOAD FLAGS(5); /* R_E */
7080 - data PT_LOAD FLAGS(7); /* RWE */
7081 + data PT_LOAD FLAGS(6); /* RW_ */
7082 user PT_LOAD FLAGS(7); /* RWE */
7083 data.init PT_LOAD FLAGS(7); /* RWE */
7084 note PT_NOTE FLAGS(0); /* ___ */
7085 @@ -49,17 +49,20 @@ SECTIONS
7086 __stop___ex_table = .;
7090 + RO_DATA(PAGE_SIZE)
7092 +#ifdef CONFIG_PAX_KERNEXEC
7093 + . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
7095 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
7099 .data : AT(ADDR(.data) - LOAD_OFFSET) {
7104 - _edata = .; /* End of data section */
7106 . = ALIGN(PAGE_SIZE);
7107 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
7108 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7109 @@ -70,9 +73,27 @@ SECTIONS
7110 *(.data.read_mostly)
7113 + . = ALIGN(THREAD_SIZE); /* init_task */
7114 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7115 + *(.data.init_task)
7118 + . = ALIGN(PAGE_SIZE);
7119 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7120 + *(.data.page_aligned)
7123 + . = ALIGN(PAGE_SIZE);
7124 + __nosave_begin = .;
7125 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7126 + . = ALIGN(PAGE_SIZE);
7129 + _edata = .; /* End of data section */
7131 #define VSYSCALL_ADDR (-10*1024*1024)
7132 -#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7133 -#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7134 +#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7135 +#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7137 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
7138 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
7139 @@ -120,23 +141,13 @@ SECTIONS
7143 - . = ALIGN(THREAD_SIZE); /* init_task */
7144 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7145 - *(.data.init_task)
7148 - . = ALIGN(PAGE_SIZE);
7149 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7150 - *(.data.page_aligned)
7153 /* might get freed after init */
7154 . = ALIGN(PAGE_SIZE);
7155 __smp_alt_begin = .;
7157 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7161 __smp_locks_end = .;
7162 . = ALIGN(PAGE_SIZE);
7164 @@ -213,12 +224,6 @@ SECTIONS
7165 . = ALIGN(PAGE_SIZE);
7168 - . = ALIGN(PAGE_SIZE);
7169 - __nosave_begin = .;
7170 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7171 - . = ALIGN(PAGE_SIZE);
7174 __bss_start = .; /* BSS */
7175 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7176 *(.bss.page_aligned)
7177 @@ -226,6 +231,7 @@ SECTIONS
7181 + . = ALIGN(2*1024*1024);
7184 /* Sections to be discarded */
7185 diff -urNp linux-2.6.27.4/arch/x86/kernel/vsyscall_64.c linux-2.6.27.4/arch/x86/kernel/vsyscall_64.c
7186 --- linux-2.6.27.4/arch/x86/kernel/vsyscall_64.c 2008-10-22 17:38:01.000000000 -0400
7187 +++ linux-2.6.27.4/arch/x86/kernel/vsyscall_64.c 2008-10-27 22:36:17.000000000 -0400
7188 @@ -236,13 +236,13 @@ static ctl_table kernel_table2[] = {
7189 .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
7191 .proc_handler = vsyscall_sysctl_change },
7193 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7196 static ctl_table kernel_root_table2[] = {
7197 { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
7198 .child = kernel_table2 },
7200 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7204 diff -urNp linux-2.6.27.4/arch/x86/kvm/svm.c linux-2.6.27.4/arch/x86/kvm/svm.c
7205 --- linux-2.6.27.4/arch/x86/kvm/svm.c 2008-10-22 17:38:01.000000000 -0400
7206 +++ linux-2.6.27.4/arch/x86/kvm/svm.c 2008-10-27 22:36:17.000000000 -0400
7207 @@ -1515,7 +1515,19 @@ static void reload_tss(struct kvm_vcpu *
7208 int cpu = raw_smp_processor_id();
7210 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
7212 +#ifdef CONFIG_PAX_KERNEXEC
7213 + unsigned long cr0;
7215 + pax_open_kernel(cr0);
7218 svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
7220 +#ifdef CONFIG_PAX_KERNEXEC
7221 + pax_close_kernel(cr0);
7227 diff -urNp linux-2.6.27.4/arch/x86/kvm/vmx.c linux-2.6.27.4/arch/x86/kvm/vmx.c
7228 --- linux-2.6.27.4/arch/x86/kvm/vmx.c 2008-10-22 17:38:01.000000000 -0400
7229 +++ linux-2.6.27.4/arch/x86/kvm/vmx.c 2008-10-27 22:36:17.000000000 -0400
7230 @@ -115,7 +115,7 @@ static struct vmcs_config {
7234 -struct vmx_capability {
7235 +static struct vmx_capability {
7239 @@ -484,9 +484,23 @@ static void reload_tss(void)
7240 struct descriptor_table gdt;
7241 struct desc_struct *descs;
7243 +#ifdef CONFIG_PAX_KERNEXEC
7244 + unsigned long cr0;
7248 descs = (void *)gdt.base;
7250 +#ifdef CONFIG_PAX_KERNEXEC
7251 + pax_open_kernel(cr0);
7254 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
7256 +#ifdef CONFIG_PAX_KERNEXEC
7257 + pax_close_kernel(cr0);
7263 @@ -3069,7 +3083,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
7264 (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
7265 (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)) == 0;
7267 - asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
7268 + asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
7271 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
7272 diff -urNp linux-2.6.27.4/arch/x86/kvm/x86.c linux-2.6.27.4/arch/x86/kvm/x86.c
7273 --- linux-2.6.27.4/arch/x86/kvm/x86.c 2008-10-22 17:38:01.000000000 -0400
7274 +++ linux-2.6.27.4/arch/x86/kvm/x86.c 2008-10-27 22:36:17.000000000 -0400
7275 @@ -63,35 +63,35 @@ static int kvm_dev_ioctl_get_supported_c
7276 struct kvm_x86_ops *kvm_x86_ops;
7278 struct kvm_stats_debugfs_item debugfs_entries[] = {
7279 - { "pf_fixed", VCPU_STAT(pf_fixed) },
7280 - { "pf_guest", VCPU_STAT(pf_guest) },
7281 - { "tlb_flush", VCPU_STAT(tlb_flush) },
7282 - { "invlpg", VCPU_STAT(invlpg) },
7283 - { "exits", VCPU_STAT(exits) },
7284 - { "io_exits", VCPU_STAT(io_exits) },
7285 - { "mmio_exits", VCPU_STAT(mmio_exits) },
7286 - { "signal_exits", VCPU_STAT(signal_exits) },
7287 - { "irq_window", VCPU_STAT(irq_window_exits) },
7288 - { "nmi_window", VCPU_STAT(nmi_window_exits) },
7289 - { "halt_exits", VCPU_STAT(halt_exits) },
7290 - { "halt_wakeup", VCPU_STAT(halt_wakeup) },
7291 - { "hypercalls", VCPU_STAT(hypercalls) },
7292 - { "request_irq", VCPU_STAT(request_irq_exits) },
7293 - { "irq_exits", VCPU_STAT(irq_exits) },
7294 - { "host_state_reload", VCPU_STAT(host_state_reload) },
7295 - { "efer_reload", VCPU_STAT(efer_reload) },
7296 - { "fpu_reload", VCPU_STAT(fpu_reload) },
7297 - { "insn_emulation", VCPU_STAT(insn_emulation) },
7298 - { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
7299 - { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
7300 - { "mmu_pte_write", VM_STAT(mmu_pte_write) },
7301 - { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
7302 - { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
7303 - { "mmu_flooded", VM_STAT(mmu_flooded) },
7304 - { "mmu_recycled", VM_STAT(mmu_recycled) },
7305 - { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
7306 - { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
7307 - { "largepages", VM_STAT(lpages) },
7308 + { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
7309 + { "pf_guest", VCPU_STAT(pf_guest), NULL },
7310 + { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
7311 + { "invlpg", VCPU_STAT(invlpg), NULL },
7312 + { "exits", VCPU_STAT(exits), NULL },
7313 + { "io_exits", VCPU_STAT(io_exits), NULL },
7314 + { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
7315 + { "signal_exits", VCPU_STAT(signal_exits), NULL },
7316 + { "irq_window", VCPU_STAT(irq_window_exits), NULL },
7317 + { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
7318 + { "halt_exits", VCPU_STAT(halt_exits), NULL },
7319 + { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
7320 + { "hypercalls", VCPU_STAT(hypercalls), NULL },
7321 + { "request_irq", VCPU_STAT(request_irq_exits), NULL },
7322 + { "irq_exits", VCPU_STAT(irq_exits), NULL },
7323 + { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
7324 + { "efer_reload", VCPU_STAT(efer_reload), NULL },
7325 + { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
7326 + { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
7327 + { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
7328 + { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
7329 + { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
7330 + { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
7331 + { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
7332 + { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
7333 + { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
7334 + { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
7335 + { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
7336 + { "largepages", VM_STAT(lpages), NULL },
7340 @@ -1274,7 +1274,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
7341 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
7342 struct kvm_interrupt *irq)
7344 - if (irq->irq < 0 || irq->irq >= 256)
7345 + if (irq->irq >= 256)
7347 if (irqchip_in_kernel(vcpu->kvm))
7349 diff -urNp linux-2.6.27.4/arch/x86/lib/checksum_32.S linux-2.6.27.4/arch/x86/lib/checksum_32.S
7350 --- linux-2.6.27.4/arch/x86/lib/checksum_32.S 2008-10-22 17:38:01.000000000 -0400
7351 +++ linux-2.6.27.4/arch/x86/lib/checksum_32.S 2008-10-27 22:36:17.000000000 -0400
7353 #include <linux/linkage.h>
7354 #include <asm/dwarf2.h>
7355 #include <asm/errno.h>
7357 +#include <asm/segment.h>
7360 * computes a partial checksum, e.g. for TCP/UDP fragments
7362 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
7367 -ENTRY(csum_partial_copy_generic)
7369 +ENTRY(csum_partial_copy_generic_to_user)
7371 + pushl $(__USER_DS)
7372 + CFI_ADJUST_CFA_OFFSET 4
7374 + CFI_ADJUST_CFA_OFFSET -4
7375 + jmp csum_partial_copy_generic
7377 +ENTRY(csum_partial_copy_generic_from_user)
7378 + pushl $(__USER_DS)
7379 + CFI_ADJUST_CFA_OFFSET 4
7381 + CFI_ADJUST_CFA_OFFSET -4
7383 +ENTRY(csum_partial_copy_generic)
7385 CFI_ADJUST_CFA_OFFSET 4
7387 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
7389 SRC(1: movw (%esi), %bx )
7391 -DST( movw %bx, (%edi) )
7392 +DST( movw %bx, %es:(%edi) )
7396 @@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
7397 SRC(1: movl (%esi), %ebx )
7398 SRC( movl 4(%esi), %edx )
7400 -DST( movl %ebx, (%edi) )
7401 +DST( movl %ebx, %es:(%edi) )
7403 -DST( movl %edx, 4(%edi) )
7404 +DST( movl %edx, %es:4(%edi) )
7406 SRC( movl 8(%esi), %ebx )
7407 SRC( movl 12(%esi), %edx )
7409 -DST( movl %ebx, 8(%edi) )
7410 +DST( movl %ebx, %es:8(%edi) )
7412 -DST( movl %edx, 12(%edi) )
7413 +DST( movl %edx, %es:12(%edi) )
7415 SRC( movl 16(%esi), %ebx )
7416 SRC( movl 20(%esi), %edx )
7418 -DST( movl %ebx, 16(%edi) )
7419 +DST( movl %ebx, %es:16(%edi) )
7421 -DST( movl %edx, 20(%edi) )
7422 +DST( movl %edx, %es:20(%edi) )
7424 SRC( movl 24(%esi), %ebx )
7425 SRC( movl 28(%esi), %edx )
7427 -DST( movl %ebx, 24(%edi) )
7428 +DST( movl %ebx, %es:24(%edi) )
7430 -DST( movl %edx, 28(%edi) )
7431 +DST( movl %edx, %es:28(%edi) )
7435 @@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
7436 shrl $2, %edx # This clears CF
7437 SRC(3: movl (%esi), %ebx )
7439 -DST( movl %ebx, (%edi) )
7440 +DST( movl %ebx, %es:(%edi) )
7444 @@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
7446 SRC( movw (%esi), %cx )
7448 -DST( movw %cx, (%edi) )
7449 +DST( movw %cx, %es:(%edi) )
7453 SRC(5: movb (%esi), %cl )
7454 -DST( movb %cl, (%edi) )
7455 +DST( movb %cl, %es:(%edi) )
7459 @@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
7462 movl ARGBASE+20(%esp), %ebx # src_err_ptr
7463 - movl $-EFAULT, (%ebx)
7464 + movl $-EFAULT, %ss:(%ebx)
7466 # zero the complete destination - computing the rest
7468 @@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
7471 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
7472 - movl $-EFAULT,(%ebx)
7473 + movl $-EFAULT,%ss:(%ebx)
7479 + CFI_ADJUST_CFA_OFFSET 4
7481 + CFI_ADJUST_CFA_OFFSET -4
7483 + CFI_ADJUST_CFA_OFFSET 4
7485 + CFI_ADJUST_CFA_OFFSET -4
7487 CFI_ADJUST_CFA_OFFSET -4
7489 @@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
7490 CFI_ADJUST_CFA_OFFSET -4
7493 -ENDPROC(csum_partial_copy_generic)
7494 +ENDPROC(csum_partial_copy_generic_to_user)
7498 /* Version for PentiumII/PPro */
7502 SRC(movl x(%esi), %ebx ) ; \
7504 - DST(movl %ebx, x(%edi) ) ;
7505 + DST(movl %ebx, %es:x(%edi)) ;
7509 SRC(movl x(%esi), %ebx ) ; \
7511 - DST(movl %ebx, x(%edi) ) ;
7512 + DST(movl %ebx, %es:x(%edi)) ;
7516 -ENTRY(csum_partial_copy_generic)
7518 +ENTRY(csum_partial_copy_generic_to_user)
7520 + pushl $(__USER_DS)
7521 + CFI_ADJUST_CFA_OFFSET 4
7523 + CFI_ADJUST_CFA_OFFSET -4
7524 + jmp csum_partial_copy_generic
7526 +ENTRY(csum_partial_copy_generic_from_user)
7527 + pushl $(__USER_DS)
7528 + CFI_ADJUST_CFA_OFFSET 4
7530 + CFI_ADJUST_CFA_OFFSET -4
7532 +ENTRY(csum_partial_copy_generic)
7534 CFI_ADJUST_CFA_OFFSET 4
7535 CFI_REL_OFFSET ebx, 0
7536 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
7540 - lea 3f(%ebx,%ebx), %ebx
7541 + lea 3f(%ebx,%ebx,2), %ebx
7545 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
7547 SRC( movw (%esi), %dx )
7549 -DST( movw %dx, (%edi) )
7550 +DST( movw %dx, %es:(%edi) )
7555 SRC( movb (%esi), %dl )
7556 -DST( movb %dl, (%edi) )
7557 +DST( movb %dl, %es:(%edi) )
7561 .section .fixup, "ax"
7562 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
7563 - movl $-EFAULT, (%ebx)
7564 + movl $-EFAULT, %ss:(%ebx)
7565 # zero the complete destination (computing the rest is too much work)
7566 movl ARGBASE+8(%esp),%edi # dst
7567 movl ARGBASE+12(%esp),%ecx # len
7568 @@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
7571 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
7572 - movl $-EFAULT, (%ebx)
7573 + movl $-EFAULT, %ss:(%ebx)
7578 + CFI_ADJUST_CFA_OFFSET 4
7580 + CFI_ADJUST_CFA_OFFSET -4
7582 + CFI_ADJUST_CFA_OFFSET 4
7584 + CFI_ADJUST_CFA_OFFSET -4
7586 CFI_ADJUST_CFA_OFFSET -4
7588 @@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
7592 -ENDPROC(csum_partial_copy_generic)
7593 +ENDPROC(csum_partial_copy_generic_to_user)
7597 diff -urNp linux-2.6.27.4/arch/x86/lib/clear_page_64.S linux-2.6.27.4/arch/x86/lib/clear_page_64.S
7598 --- linux-2.6.27.4/arch/x86/lib/clear_page_64.S 2008-10-22 17:38:01.000000000 -0400
7599 +++ linux-2.6.27.4/arch/x86/lib/clear_page_64.S 2008-10-27 22:36:17.000000000 -0400
7600 @@ -44,7 +44,7 @@ ENDPROC(clear_page)
7602 #include <asm/cpufeature.h>
7604 - .section .altinstr_replacement,"ax"
7605 + .section .altinstr_replacement,"a"
7606 1: .byte 0xeb /* jmp <disp8> */
7607 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
7609 diff -urNp linux-2.6.27.4/arch/x86/lib/copy_page_64.S linux-2.6.27.4/arch/x86/lib/copy_page_64.S
7610 --- linux-2.6.27.4/arch/x86/lib/copy_page_64.S 2008-10-22 17:38:01.000000000 -0400
7611 +++ linux-2.6.27.4/arch/x86/lib/copy_page_64.S 2008-10-27 22:36:17.000000000 -0400
7612 @@ -104,7 +104,7 @@ ENDPROC(copy_page)
7614 #include <asm/cpufeature.h>
7616 - .section .altinstr_replacement,"ax"
7617 + .section .altinstr_replacement,"a"
7618 1: .byte 0xeb /* jmp <disp8> */
7619 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
7621 diff -urNp linux-2.6.27.4/arch/x86/lib/copy_user_64.S linux-2.6.27.4/arch/x86/lib/copy_user_64.S
7622 --- linux-2.6.27.4/arch/x86/lib/copy_user_64.S 2008-10-22 17:38:01.000000000 -0400
7623 +++ linux-2.6.27.4/arch/x86/lib/copy_user_64.S 2008-10-27 22:36:17.000000000 -0400
7625 .byte 0xe9 /* 32bit jump */
7626 .long \orig-1f /* by default jump to orig */
7628 - .section .altinstr_replacement,"ax"
7629 + .section .altinstr_replacement,"a"
7630 2: .byte 0xe9 /* near jump with 32bit immediate */
7631 .long \alt-1b /* offset */ /* or alternatively to alt */
7633 @@ -106,6 +106,8 @@ ENDPROC(__copy_from_user_inatomic)
7634 ENTRY(bad_from_user)
7642 diff -urNp linux-2.6.27.4/arch/x86/lib/getuser.S linux-2.6.27.4/arch/x86/lib/getuser.S
7643 --- linux-2.6.27.4/arch/x86/lib/getuser.S 2008-10-22 17:38:01.000000000 -0400
7644 +++ linux-2.6.27.4/arch/x86/lib/getuser.S 2008-10-27 22:36:17.000000000 -0400
7646 #include <asm/asm-offsets.h>
7647 #include <asm/thread_info.h>
7648 #include <asm/asm.h>
7649 +#include <asm/segment.h>
7653 @@ -40,7 +41,19 @@ ENTRY(__get_user_1)
7654 GET_THREAD_INFO(%_ASM_DX)
7655 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
7658 +#ifdef CONFIG_X86_32
7659 + pushl $(__USER_DS)
7663 1: movzb (%_ASM_AX),%edx
7665 +#ifdef CONFIG_X86_32
7673 @@ -53,7 +66,19 @@ ENTRY(__get_user_2)
7674 GET_THREAD_INFO(%_ASM_DX)
7675 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
7678 +#ifdef CONFIG_X86_32
7679 + pushl $(__USER_DS)
7683 2: movzwl -1(%_ASM_AX),%edx
7685 +#ifdef CONFIG_X86_32
7693 @@ -66,7 +91,19 @@ ENTRY(__get_user_4)
7694 GET_THREAD_INFO(%_ASM_DX)
7695 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
7698 +#ifdef CONFIG_X86_32
7699 + pushl $(__USER_DS)
7703 3: mov -3(%_ASM_AX),%edx
7705 +#ifdef CONFIG_X86_32
7713 @@ -89,6 +126,12 @@ ENDPROC(__get_user_8)
7718 +#ifdef CONFIG_X86_32
7724 mov $(-EFAULT),%_ASM_AX
7726 diff -urNp linux-2.6.27.4/arch/x86/lib/memcpy_64.S linux-2.6.27.4/arch/x86/lib/memcpy_64.S
7727 --- linux-2.6.27.4/arch/x86/lib/memcpy_64.S 2008-10-22 17:38:01.000000000 -0400
7728 +++ linux-2.6.27.4/arch/x86/lib/memcpy_64.S 2008-10-27 22:36:17.000000000 -0400
7729 @@ -114,7 +114,7 @@ ENDPROC(__memcpy)
7730 /* Some CPUs run faster using the string copy instructions.
7731 It is also a lot simpler. Use this when possible */
7733 - .section .altinstr_replacement,"ax"
7734 + .section .altinstr_replacement,"a"
7735 1: .byte 0xeb /* jmp <disp8> */
7736 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
7738 diff -urNp linux-2.6.27.4/arch/x86/lib/memset_64.S linux-2.6.27.4/arch/x86/lib/memset_64.S
7739 --- linux-2.6.27.4/arch/x86/lib/memset_64.S 2008-10-22 17:38:01.000000000 -0400
7740 +++ linux-2.6.27.4/arch/x86/lib/memset_64.S 2008-10-27 22:36:17.000000000 -0400
7741 @@ -118,7 +118,7 @@ ENDPROC(__memset)
7743 #include <asm/cpufeature.h>
7745 - .section .altinstr_replacement,"ax"
7746 + .section .altinstr_replacement,"a"
7747 1: .byte 0xeb /* jmp <disp8> */
7748 .byte (memset_c - memset) - (2f - 1b) /* offset */
7750 diff -urNp linux-2.6.27.4/arch/x86/lib/mmx_32.c linux-2.6.27.4/arch/x86/lib/mmx_32.c
7751 --- linux-2.6.27.4/arch/x86/lib/mmx_32.c 2008-10-22 17:38:01.000000000 -0400
7752 +++ linux-2.6.27.4/arch/x86/lib/mmx_32.c 2008-10-27 22:36:17.000000000 -0400
7753 @@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
7757 + unsigned long cr0;
7759 if (unlikely(in_interrupt()))
7760 return __memcpy(to, from, len);
7761 @@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
7764 __asm__ __volatile__ (
7765 - "1: prefetch (%0)\n" /* This set is 28 bytes */
7766 - " prefetch 64(%0)\n"
7767 - " prefetch 128(%0)\n"
7768 - " prefetch 192(%0)\n"
7769 - " prefetch 256(%0)\n"
7770 + "1: prefetch (%1)\n" /* This set is 28 bytes */
7771 + " prefetch 64(%1)\n"
7772 + " prefetch 128(%1)\n"
7773 + " prefetch 192(%1)\n"
7774 + " prefetch 256(%1)\n"
7776 ".section .fixup, \"ax\"\n"
7777 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
7780 +#ifdef CONFIG_PAX_KERNEXEC
7781 + " movl %%cr0, %0\n"
7782 + " movl %0, %%eax\n"
7783 + " andl $0xFFFEFFFF, %%eax\n"
7784 + " movl %%eax, %%cr0\n"
7787 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
7789 +#ifdef CONFIG_PAX_KERNEXEC
7790 + " movl %0, %%cr0\n"
7795 _ASM_EXTABLE(1b, 3b)
7797 + : "=&r" (cr0) : "r" (from) : "ax");
7799 for ( ; i > 5; i--) {
7800 __asm__ __volatile__ (
7801 - "1: prefetch 320(%0)\n"
7802 - "2: movq (%0), %%mm0\n"
7803 - " movq 8(%0), %%mm1\n"
7804 - " movq 16(%0), %%mm2\n"
7805 - " movq 24(%0), %%mm3\n"
7806 - " movq %%mm0, (%1)\n"
7807 - " movq %%mm1, 8(%1)\n"
7808 - " movq %%mm2, 16(%1)\n"
7809 - " movq %%mm3, 24(%1)\n"
7810 - " movq 32(%0), %%mm0\n"
7811 - " movq 40(%0), %%mm1\n"
7812 - " movq 48(%0), %%mm2\n"
7813 - " movq 56(%0), %%mm3\n"
7814 - " movq %%mm0, 32(%1)\n"
7815 - " movq %%mm1, 40(%1)\n"
7816 - " movq %%mm2, 48(%1)\n"
7817 - " movq %%mm3, 56(%1)\n"
7818 + "1: prefetch 320(%1)\n"
7819 + "2: movq (%1), %%mm0\n"
7820 + " movq 8(%1), %%mm1\n"
7821 + " movq 16(%1), %%mm2\n"
7822 + " movq 24(%1), %%mm3\n"
7823 + " movq %%mm0, (%2)\n"
7824 + " movq %%mm1, 8(%2)\n"
7825 + " movq %%mm2, 16(%2)\n"
7826 + " movq %%mm3, 24(%2)\n"
7827 + " movq 32(%1), %%mm0\n"
7828 + " movq 40(%1), %%mm1\n"
7829 + " movq 48(%1), %%mm2\n"
7830 + " movq 56(%1), %%mm3\n"
7831 + " movq %%mm0, 32(%2)\n"
7832 + " movq %%mm1, 40(%2)\n"
7833 + " movq %%mm2, 48(%2)\n"
7834 + " movq %%mm3, 56(%2)\n"
7835 ".section .fixup, \"ax\"\n"
7836 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
7839 +#ifdef CONFIG_PAX_KERNEXEC
7840 + " movl %%cr0, %0\n"
7841 + " movl %0, %%eax\n"
7842 + " andl $0xFFFEFFFF, %%eax\n"
7843 + " movl %%eax, %%cr0\n"
7846 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
7848 +#ifdef CONFIG_PAX_KERNEXEC
7849 + " movl %0, %%cr0\n"
7854 _ASM_EXTABLE(1b, 3b)
7855 - : : "r" (from), "r" (to) : "memory");
7856 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
7860 @@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
7861 static void fast_copy_page(void *to, void *from)
7864 + unsigned long cr0;
7868 @@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
7869 * but that is for later. -AV
7871 __asm__ __volatile__(
7872 - "1: prefetch (%0)\n"
7873 - " prefetch 64(%0)\n"
7874 - " prefetch 128(%0)\n"
7875 - " prefetch 192(%0)\n"
7876 - " prefetch 256(%0)\n"
7877 + "1: prefetch (%1)\n"
7878 + " prefetch 64(%1)\n"
7879 + " prefetch 128(%1)\n"
7880 + " prefetch 192(%1)\n"
7881 + " prefetch 256(%1)\n"
7883 ".section .fixup, \"ax\"\n"
7884 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
7887 +#ifdef CONFIG_PAX_KERNEXEC
7888 + " movl %%cr0, %0\n"
7889 + " movl %0, %%eax\n"
7890 + " andl $0xFFFEFFFF, %%eax\n"
7891 + " movl %%eax, %%cr0\n"
7894 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
7896 +#ifdef CONFIG_PAX_KERNEXEC
7897 + " movl %0, %%cr0\n"
7902 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
7903 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
7905 for (i = 0; i < (4096-320)/64; i++) {
7906 __asm__ __volatile__ (
7907 - "1: prefetch 320(%0)\n"
7908 - "2: movq (%0), %%mm0\n"
7909 - " movntq %%mm0, (%1)\n"
7910 - " movq 8(%0), %%mm1\n"
7911 - " movntq %%mm1, 8(%1)\n"
7912 - " movq 16(%0), %%mm2\n"
7913 - " movntq %%mm2, 16(%1)\n"
7914 - " movq 24(%0), %%mm3\n"
7915 - " movntq %%mm3, 24(%1)\n"
7916 - " movq 32(%0), %%mm4\n"
7917 - " movntq %%mm4, 32(%1)\n"
7918 - " movq 40(%0), %%mm5\n"
7919 - " movntq %%mm5, 40(%1)\n"
7920 - " movq 48(%0), %%mm6\n"
7921 - " movntq %%mm6, 48(%1)\n"
7922 - " movq 56(%0), %%mm7\n"
7923 - " movntq %%mm7, 56(%1)\n"
7924 + "1: prefetch 320(%1)\n"
7925 + "2: movq (%1), %%mm0\n"
7926 + " movntq %%mm0, (%2)\n"
7927 + " movq 8(%1), %%mm1\n"
7928 + " movntq %%mm1, 8(%2)\n"
7929 + " movq 16(%1), %%mm2\n"
7930 + " movntq %%mm2, 16(%2)\n"
7931 + " movq 24(%1), %%mm3\n"
7932 + " movntq %%mm3, 24(%2)\n"
7933 + " movq 32(%1), %%mm4\n"
7934 + " movntq %%mm4, 32(%2)\n"
7935 + " movq 40(%1), %%mm5\n"
7936 + " movntq %%mm5, 40(%2)\n"
7937 + " movq 48(%1), %%mm6\n"
7938 + " movntq %%mm6, 48(%2)\n"
7939 + " movq 56(%1), %%mm7\n"
7940 + " movntq %%mm7, 56(%2)\n"
7941 ".section .fixup, \"ax\"\n"
7942 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
7945 +#ifdef CONFIG_PAX_KERNEXEC
7946 + " movl %%cr0, %0\n"
7947 + " movl %0, %%eax\n"
7948 + " andl $0xFFFEFFFF, %%eax\n"
7949 + " movl %%eax, %%cr0\n"
7952 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
7954 +#ifdef CONFIG_PAX_KERNEXEC
7955 + " movl %0, %%cr0\n"
7960 - _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
7961 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
7965 @@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
7966 static void fast_copy_page(void *to, void *from)
7969 + unsigned long cr0;
7973 __asm__ __volatile__ (
7974 - "1: prefetch (%0)\n"
7975 - " prefetch 64(%0)\n"
7976 - " prefetch 128(%0)\n"
7977 - " prefetch 192(%0)\n"
7978 - " prefetch 256(%0)\n"
7979 + "1: prefetch (%1)\n"
7980 + " prefetch 64(%1)\n"
7981 + " prefetch 128(%1)\n"
7982 + " prefetch 192(%1)\n"
7983 + " prefetch 256(%1)\n"
7985 ".section .fixup, \"ax\"\n"
7986 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
7989 +#ifdef CONFIG_PAX_KERNEXEC
7990 + " movl %%cr0, %0\n"
7991 + " movl %0, %%eax\n"
7992 + " andl $0xFFFEFFFF, %%eax\n"
7993 + " movl %%eax, %%cr0\n"
7996 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
7998 +#ifdef CONFIG_PAX_KERNEXEC
7999 + " movl %0, %%cr0\n"
8004 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
8005 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
8007 for (i = 0; i < 4096/64; i++) {
8008 __asm__ __volatile__ (
8009 - "1: prefetch 320(%0)\n"
8010 - "2: movq (%0), %%mm0\n"
8011 - " movq 8(%0), %%mm1\n"
8012 - " movq 16(%0), %%mm2\n"
8013 - " movq 24(%0), %%mm3\n"
8014 - " movq %%mm0, (%1)\n"
8015 - " movq %%mm1, 8(%1)\n"
8016 - " movq %%mm2, 16(%1)\n"
8017 - " movq %%mm3, 24(%1)\n"
8018 - " movq 32(%0), %%mm0\n"
8019 - " movq 40(%0), %%mm1\n"
8020 - " movq 48(%0), %%mm2\n"
8021 - " movq 56(%0), %%mm3\n"
8022 - " movq %%mm0, 32(%1)\n"
8023 - " movq %%mm1, 40(%1)\n"
8024 - " movq %%mm2, 48(%1)\n"
8025 - " movq %%mm3, 56(%1)\n"
8026 + "1: prefetch 320(%1)\n"
8027 + "2: movq (%1), %%mm0\n"
8028 + " movq 8(%1), %%mm1\n"
8029 + " movq 16(%1), %%mm2\n"
8030 + " movq 24(%1), %%mm3\n"
8031 + " movq %%mm0, (%2)\n"
8032 + " movq %%mm1, 8(%2)\n"
8033 + " movq %%mm2, 16(%2)\n"
8034 + " movq %%mm3, 24(%2)\n"
8035 + " movq 32(%1), %%mm0\n"
8036 + " movq 40(%1), %%mm1\n"
8037 + " movq 48(%1), %%mm2\n"
8038 + " movq 56(%1), %%mm3\n"
8039 + " movq %%mm0, 32(%2)\n"
8040 + " movq %%mm1, 40(%2)\n"
8041 + " movq %%mm2, 48(%2)\n"
8042 + " movq %%mm3, 56(%2)\n"
8043 ".section .fixup, \"ax\"\n"
8044 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8047 +#ifdef CONFIG_PAX_KERNEXEC
8048 + " movl %%cr0, %0\n"
8049 + " movl %0, %%eax\n"
8050 + " andl $0xFFFEFFFF, %%eax\n"
8051 + " movl %%eax, %%cr0\n"
8054 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8056 +#ifdef CONFIG_PAX_KERNEXEC
8057 + " movl %0, %%cr0\n"
8062 _ASM_EXTABLE(1b, 3b)
8063 - : : "r" (from), "r" (to) : "memory");
8064 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8068 diff -urNp linux-2.6.27.4/arch/x86/lib/putuser.S linux-2.6.27.4/arch/x86/lib/putuser.S
8069 --- linux-2.6.27.4/arch/x86/lib/putuser.S 2008-10-22 17:38:01.000000000 -0400
8070 +++ linux-2.6.27.4/arch/x86/lib/putuser.S 2008-10-27 22:36:17.000000000 -0400
8072 #include <asm/thread_info.h>
8073 #include <asm/errno.h>
8074 #include <asm/asm.h>
8075 +#include <asm/segment.h>
8079 @@ -39,7 +40,19 @@ ENTRY(__put_user_1)
8081 cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
8084 +#ifdef CONFIG_X86_32
8085 + pushl $(__USER_DS)
8089 1: movb %al,(%_ASM_CX)
8091 +#ifdef CONFIG_X86_32
8098 ENDPROC(__put_user_1)
8099 @@ -50,7 +63,19 @@ ENTRY(__put_user_2)
8101 cmp %_ASM_BX,%_ASM_CX
8104 +#ifdef CONFIG_X86_32
8105 + pushl $(__USER_DS)
8109 2: movw %ax,(%_ASM_CX)
8111 +#ifdef CONFIG_X86_32
8118 ENDPROC(__put_user_2)
8119 @@ -61,7 +86,19 @@ ENTRY(__put_user_4)
8121 cmp %_ASM_BX,%_ASM_CX
8124 +#ifdef CONFIG_X86_32
8125 + pushl $(__USER_DS)
8129 3: movl %eax,(%_ASM_CX)
8131 +#ifdef CONFIG_X86_32
8138 ENDPROC(__put_user_4)
8139 @@ -72,16 +109,34 @@ ENTRY(__put_user_8)
8141 cmp %_ASM_BX,%_ASM_CX
8144 +#ifdef CONFIG_X86_32
8145 + pushl $(__USER_DS)
8149 4: mov %_ASM_AX,(%_ASM_CX)
8150 #ifdef CONFIG_X86_32
8151 5: movl %edx,4(%_ASM_CX)
8154 +#ifdef CONFIG_X86_32
8161 ENDPROC(__put_user_8)
8166 +#ifdef CONFIG_X86_32
8174 diff -urNp linux-2.6.27.4/arch/x86/lib/usercopy_32.c linux-2.6.27.4/arch/x86/lib/usercopy_32.c
8175 --- linux-2.6.27.4/arch/x86/lib/usercopy_32.c 2008-10-22 17:38:01.000000000 -0400
8176 +++ linux-2.6.27.4/arch/x86/lib/usercopy_32.c 2008-10-27 22:36:17.000000000 -0400
8177 @@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
8178 * Copy a null terminated string from userspace.
8181 -#define __do_strncpy_from_user(dst, src, count, res) \
8183 - int __d0, __d1, __d2; \
8185 - __asm__ __volatile__( \
8186 - " testl %1,%1\n" \
8190 - " testb %%al,%%al\n" \
8194 - "1: subl %1,%0\n" \
8196 - ".section .fixup,\"ax\"\n" \
8197 - "3: movl %5,%0\n" \
8200 - _ASM_EXTABLE(0b,3b) \
8201 - : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
8203 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
8206 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
8208 + int __d0, __d1, __d2;
8209 + long res = -EFAULT;
8212 + __asm__ __volatile__(
8213 + " movw %w10,%%ds\n"
8218 + " testb %%al,%%al\n"
8226 + ".section .fixup,\"ax\"\n"
8230 + _ASM_EXTABLE(0b,3b)
8231 + : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
8233 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
8240 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
8241 @@ -78,9 +85,7 @@ do { \
8243 __strncpy_from_user(char *dst, const char __user *src, long count)
8246 - __do_strncpy_from_user(dst, src, count, res);
8248 + return __do_strncpy_from_user(dst, src, count);
8250 EXPORT_SYMBOL(__strncpy_from_user);
8252 @@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char
8255 if (access_ok(VERIFY_READ, src, 1))
8256 - __do_strncpy_from_user(dst, src, count, res);
8257 + res = __do_strncpy_from_user(dst, src, count);
8260 EXPORT_SYMBOL(strncpy_from_user);
8261 @@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
8265 -#define __do_clear_user(addr,size) \
8269 - __asm__ __volatile__( \
8270 - "0: rep; stosl\n" \
8272 - "1: rep; stosb\n" \
8274 - ".section .fixup,\"ax\"\n" \
8275 - "3: lea 0(%2,%0,4),%0\n" \
8278 - _ASM_EXTABLE(0b,3b) \
8279 - _ASM_EXTABLE(1b,2b) \
8280 - : "=&c"(size), "=&D" (__d0) \
8281 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
8283 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
8288 + __asm__ __volatile__(
8289 + " movw %w6,%%es\n"
8296 + ".section .fixup,\"ax\"\n"
8297 + "3: lea 0(%2,%0,4),%0\n"
8300 + _ASM_EXTABLE(0b,3b)
8301 + _ASM_EXTABLE(1b,2b)
8302 + : "=&c"(size), "=&D" (__d0)
8303 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
8309 * clear_user: - Zero a block of memory in user space.
8310 @@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
8313 if (access_ok(VERIFY_WRITE, to, n))
8314 - __do_clear_user(to, n);
8315 + n = __do_clear_user(to, n);
8318 EXPORT_SYMBOL(clear_user);
8319 @@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
8321 __clear_user(void __user *to, unsigned long n)
8323 - __do_clear_user(to, n);
8325 + return __do_clear_user(to, n);
8327 EXPORT_SYMBOL(__clear_user);
8329 @@ -193,14 +203,17 @@ long strnlen_user(const char __user *s,
8332 __asm__ __volatile__(
8333 + " movw %w8,%%es\n"
8336 - " andl %0,%%ecx\n"
8337 + " movl %0,%%ecx\n"
8345 ".section .fixup,\"ax\"\n"
8346 "2: xorl %%eax,%%eax\n"
8348 @@ -212,7 +225,7 @@ long strnlen_user(const char __user *s,
8351 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
8352 - :"0" (n), "1" (s), "2" (0), "3" (mask)
8353 + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
8357 @@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
8359 #ifdef CONFIG_X86_INTEL_USERCOPY
8360 static unsigned long
8361 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
8362 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
8365 __asm__ __volatile__(
8366 + " movw %w6, %%es\n"
8368 "1: movl 32(%4), %%eax\n"
8370 @@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
8372 "3: movl 0(%4), %%eax\n"
8373 "4: movl 4(%4), %%edx\n"
8374 - "5: movl %%eax, 0(%3)\n"
8375 - "6: movl %%edx, 4(%3)\n"
8376 + "5: movl %%eax, %%es:0(%3)\n"
8377 + "6: movl %%edx, %%es:4(%3)\n"
8378 "7: movl 8(%4), %%eax\n"
8379 "8: movl 12(%4),%%edx\n"
8380 - "9: movl %%eax, 8(%3)\n"
8381 - "10: movl %%edx, 12(%3)\n"
8382 + "9: movl %%eax, %%es:8(%3)\n"
8383 + "10: movl %%edx, %%es:12(%3)\n"
8384 "11: movl 16(%4), %%eax\n"
8385 "12: movl 20(%4), %%edx\n"
8386 - "13: movl %%eax, 16(%3)\n"
8387 - "14: movl %%edx, 20(%3)\n"
8388 + "13: movl %%eax, %%es:16(%3)\n"
8389 + "14: movl %%edx, %%es:20(%3)\n"
8390 "15: movl 24(%4), %%eax\n"
8391 "16: movl 28(%4), %%edx\n"
8392 - "17: movl %%eax, 24(%3)\n"
8393 - "18: movl %%edx, 28(%3)\n"
8394 + "17: movl %%eax, %%es:24(%3)\n"
8395 + "18: movl %%edx, %%es:28(%3)\n"
8396 "19: movl 32(%4), %%eax\n"
8397 "20: movl 36(%4), %%edx\n"
8398 - "21: movl %%eax, 32(%3)\n"
8399 - "22: movl %%edx, 36(%3)\n"
8400 + "21: movl %%eax, %%es:32(%3)\n"
8401 + "22: movl %%edx, %%es:36(%3)\n"
8402 "23: movl 40(%4), %%eax\n"
8403 "24: movl 44(%4), %%edx\n"
8404 - "25: movl %%eax, 40(%3)\n"
8405 - "26: movl %%edx, 44(%3)\n"
8406 + "25: movl %%eax, %%es:40(%3)\n"
8407 + "26: movl %%edx, %%es:44(%3)\n"
8408 "27: movl 48(%4), %%eax\n"
8409 "28: movl 52(%4), %%edx\n"
8410 - "29: movl %%eax, 48(%3)\n"
8411 - "30: movl %%edx, 52(%3)\n"
8412 + "29: movl %%eax, %%es:48(%3)\n"
8413 + "30: movl %%edx, %%es:52(%3)\n"
8414 "31: movl 56(%4), %%eax\n"
8415 "32: movl 60(%4), %%edx\n"
8416 - "33: movl %%eax, 56(%3)\n"
8417 - "34: movl %%edx, 60(%3)\n"
8418 + "33: movl %%eax, %%es:56(%3)\n"
8419 + "34: movl %%edx, %%es:60(%3)\n"
8423 @@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
8424 "36: movl %%eax, %0\n"
8429 ".section .fixup,\"ax\"\n"
8430 "101: lea 0(%%eax,%0,4),%0\n"
8432 @@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
8435 : "=&c"(size), "=&D" (d0), "=&S" (d1)
8436 - : "1"(to), "2"(from), "0"(size)
8437 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8438 + : "eax", "edx", "memory");
8442 +static unsigned long
8443 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
8446 + __asm__ __volatile__(
8447 + " movw %w6, %%ds\n"
8448 + " .align 2,0x90\n"
8449 + "1: movl 32(%4), %%eax\n"
8452 + "2: movl 64(%4), %%eax\n"
8453 + " .align 2,0x90\n"
8454 + "3: movl 0(%4), %%eax\n"
8455 + "4: movl 4(%4), %%edx\n"
8456 + "5: movl %%eax, %%es:0(%3)\n"
8457 + "6: movl %%edx, %%es:4(%3)\n"
8458 + "7: movl 8(%4), %%eax\n"
8459 + "8: movl 12(%4),%%edx\n"
8460 + "9: movl %%eax, %%es:8(%3)\n"
8461 + "10: movl %%edx, %%es:12(%3)\n"
8462 + "11: movl 16(%4), %%eax\n"
8463 + "12: movl 20(%4), %%edx\n"
8464 + "13: movl %%eax, %%es:16(%3)\n"
8465 + "14: movl %%edx, %%es:20(%3)\n"
8466 + "15: movl 24(%4), %%eax\n"
8467 + "16: movl 28(%4), %%edx\n"
8468 + "17: movl %%eax, %%es:24(%3)\n"
8469 + "18: movl %%edx, %%es:28(%3)\n"
8470 + "19: movl 32(%4), %%eax\n"
8471 + "20: movl 36(%4), %%edx\n"
8472 + "21: movl %%eax, %%es:32(%3)\n"
8473 + "22: movl %%edx, %%es:36(%3)\n"
8474 + "23: movl 40(%4), %%eax\n"
8475 + "24: movl 44(%4), %%edx\n"
8476 + "25: movl %%eax, %%es:40(%3)\n"
8477 + "26: movl %%edx, %%es:44(%3)\n"
8478 + "27: movl 48(%4), %%eax\n"
8479 + "28: movl 52(%4), %%edx\n"
8480 + "29: movl %%eax, %%es:48(%3)\n"
8481 + "30: movl %%edx, %%es:52(%3)\n"
8482 + "31: movl 56(%4), %%eax\n"
8483 + "32: movl 60(%4), %%edx\n"
8484 + "33: movl %%eax, %%es:56(%3)\n"
8485 + "34: movl %%edx, %%es:60(%3)\n"
8486 + " addl $-64, %0\n"
8491 + "35: movl %0, %%eax\n"
8493 + " andl $3, %%eax\n"
8495 + "99: rep; movsl\n"
8496 + "36: movl %%eax, %0\n"
8497 + "37: rep; movsb\n"
8501 + ".section .fixup,\"ax\"\n"
8502 + "101: lea 0(%%eax,%0,4),%0\n"
8505 + ".section __ex_table,\"a\"\n"
8507 + " .long 1b,100b\n"
8508 + " .long 2b,100b\n"
8509 + " .long 3b,100b\n"
8510 + " .long 4b,100b\n"
8511 + " .long 5b,100b\n"
8512 + " .long 6b,100b\n"
8513 + " .long 7b,100b\n"
8514 + " .long 8b,100b\n"
8515 + " .long 9b,100b\n"
8516 + " .long 10b,100b\n"
8517 + " .long 11b,100b\n"
8518 + " .long 12b,100b\n"
8519 + " .long 13b,100b\n"
8520 + " .long 14b,100b\n"
8521 + " .long 15b,100b\n"
8522 + " .long 16b,100b\n"
8523 + " .long 17b,100b\n"
8524 + " .long 18b,100b\n"
8525 + " .long 19b,100b\n"
8526 + " .long 20b,100b\n"
8527 + " .long 21b,100b\n"
8528 + " .long 22b,100b\n"
8529 + " .long 23b,100b\n"
8530 + " .long 24b,100b\n"
8531 + " .long 25b,100b\n"
8532 + " .long 26b,100b\n"
8533 + " .long 27b,100b\n"
8534 + " .long 28b,100b\n"
8535 + " .long 29b,100b\n"
8536 + " .long 30b,100b\n"
8537 + " .long 31b,100b\n"
8538 + " .long 32b,100b\n"
8539 + " .long 33b,100b\n"
8540 + " .long 34b,100b\n"
8541 + " .long 35b,100b\n"
8542 + " .long 36b,100b\n"
8543 + " .long 37b,100b\n"
8544 + " .long 99b,101b\n"
8546 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
8547 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8548 : "eax", "edx", "memory");
8551 @@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
8554 __asm__ __volatile__(
8555 + " movw %w6, %%ds\n"
8557 "0: movl 32(%4), %%eax\n"
8559 @@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
8561 "2: movl 0(%4), %%eax\n"
8562 "21: movl 4(%4), %%edx\n"
8563 - " movl %%eax, 0(%3)\n"
8564 - " movl %%edx, 4(%3)\n"
8565 + " movl %%eax, %%es:0(%3)\n"
8566 + " movl %%edx, %%es:4(%3)\n"
8567 "3: movl 8(%4), %%eax\n"
8568 "31: movl 12(%4),%%edx\n"
8569 - " movl %%eax, 8(%3)\n"
8570 - " movl %%edx, 12(%3)\n"
8571 + " movl %%eax, %%es:8(%3)\n"
8572 + " movl %%edx, %%es:12(%3)\n"
8573 "4: movl 16(%4), %%eax\n"
8574 "41: movl 20(%4), %%edx\n"
8575 - " movl %%eax, 16(%3)\n"
8576 - " movl %%edx, 20(%3)\n"
8577 + " movl %%eax, %%es:16(%3)\n"
8578 + " movl %%edx, %%es:20(%3)\n"
8579 "10: movl 24(%4), %%eax\n"
8580 "51: movl 28(%4), %%edx\n"
8581 - " movl %%eax, 24(%3)\n"
8582 - " movl %%edx, 28(%3)\n"
8583 + " movl %%eax, %%es:24(%3)\n"
8584 + " movl %%edx, %%es:28(%3)\n"
8585 "11: movl 32(%4), %%eax\n"
8586 "61: movl 36(%4), %%edx\n"
8587 - " movl %%eax, 32(%3)\n"
8588 - " movl %%edx, 36(%3)\n"
8589 + " movl %%eax, %%es:32(%3)\n"
8590 + " movl %%edx, %%es:36(%3)\n"
8591 "12: movl 40(%4), %%eax\n"
8592 "71: movl 44(%4), %%edx\n"
8593 - " movl %%eax, 40(%3)\n"
8594 - " movl %%edx, 44(%3)\n"
8595 + " movl %%eax, %%es:40(%3)\n"
8596 + " movl %%edx, %%es:44(%3)\n"
8597 "13: movl 48(%4), %%eax\n"
8598 "81: movl 52(%4), %%edx\n"
8599 - " movl %%eax, 48(%3)\n"
8600 - " movl %%edx, 52(%3)\n"
8601 + " movl %%eax, %%es:48(%3)\n"
8602 + " movl %%edx, %%es:52(%3)\n"
8603 "14: movl 56(%4), %%eax\n"
8604 "91: movl 60(%4), %%edx\n"
8605 - " movl %%eax, 56(%3)\n"
8606 - " movl %%edx, 60(%3)\n"
8607 + " movl %%eax, %%es:56(%3)\n"
8608 + " movl %%edx, %%es:60(%3)\n"
8612 @@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
8618 ".section .fixup,\"ax\"\n"
8619 "9: lea 0(%%eax,%0,4),%0\n"
8621 @@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
8624 : "=&c"(size), "=&D" (d0), "=&S" (d1)
8625 - : "1"(to), "2"(from), "0"(size)
8626 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8627 : "eax", "edx", "memory");
8630 @@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
8633 __asm__ __volatile__(
8634 + " movw %w6, %%ds\n"
8636 "0: movl 32(%4), %%eax\n"
8638 @@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
8640 "2: movl 0(%4), %%eax\n"
8641 "21: movl 4(%4), %%edx\n"
8642 - " movnti %%eax, 0(%3)\n"
8643 - " movnti %%edx, 4(%3)\n"
8644 + " movnti %%eax, %%es:0(%3)\n"
8645 + " movnti %%edx, %%es:4(%3)\n"
8646 "3: movl 8(%4), %%eax\n"
8647 "31: movl 12(%4),%%edx\n"
8648 - " movnti %%eax, 8(%3)\n"
8649 - " movnti %%edx, 12(%3)\n"
8650 + " movnti %%eax, %%es:8(%3)\n"
8651 + " movnti %%edx, %%es:12(%3)\n"
8652 "4: movl 16(%4), %%eax\n"
8653 "41: movl 20(%4), %%edx\n"
8654 - " movnti %%eax, 16(%3)\n"
8655 - " movnti %%edx, 20(%3)\n"
8656 + " movnti %%eax, %%es:16(%3)\n"
8657 + " movnti %%edx, %%es:20(%3)\n"
8658 "10: movl 24(%4), %%eax\n"
8659 "51: movl 28(%4), %%edx\n"
8660 - " movnti %%eax, 24(%3)\n"
8661 - " movnti %%edx, 28(%3)\n"
8662 + " movnti %%eax, %%es:24(%3)\n"
8663 + " movnti %%edx, %%es:28(%3)\n"
8664 "11: movl 32(%4), %%eax\n"
8665 "61: movl 36(%4), %%edx\n"
8666 - " movnti %%eax, 32(%3)\n"
8667 - " movnti %%edx, 36(%3)\n"
8668 + " movnti %%eax, %%es:32(%3)\n"
8669 + " movnti %%edx, %%es:36(%3)\n"
8670 "12: movl 40(%4), %%eax\n"
8671 "71: movl 44(%4), %%edx\n"
8672 - " movnti %%eax, 40(%3)\n"
8673 - " movnti %%edx, 44(%3)\n"
8674 + " movnti %%eax, %%es:40(%3)\n"
8675 + " movnti %%edx, %%es:44(%3)\n"
8676 "13: movl 48(%4), %%eax\n"
8677 "81: movl 52(%4), %%edx\n"
8678 - " movnti %%eax, 48(%3)\n"
8679 - " movnti %%edx, 52(%3)\n"
8680 + " movnti %%eax, %%es:48(%3)\n"
8681 + " movnti %%edx, %%es:52(%3)\n"
8682 "14: movl 56(%4), %%eax\n"
8683 "91: movl 60(%4), %%edx\n"
8684 - " movnti %%eax, 56(%3)\n"
8685 - " movnti %%edx, 60(%3)\n"
8686 + " movnti %%eax, %%es:56(%3)\n"
8687 + " movnti %%edx, %%es:60(%3)\n"
8691 @@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
8697 ".section .fixup,\"ax\"\n"
8698 "9: lea 0(%%eax,%0,4),%0\n"
8700 @@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
8703 : "=&c"(size), "=&D" (d0), "=&S" (d1)
8704 - : "1"(to), "2"(from), "0"(size)
8705 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8706 : "eax", "edx", "memory");
8709 @@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
8712 __asm__ __volatile__(
8713 + " movw %w6, %%ds\n"
8715 "0: movl 32(%4), %%eax\n"
8717 @@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
8719 "2: movl 0(%4), %%eax\n"
8720 "21: movl 4(%4), %%edx\n"
8721 - " movnti %%eax, 0(%3)\n"
8722 - " movnti %%edx, 4(%3)\n"
8723 + " movnti %%eax, %%es:0(%3)\n"
8724 + " movnti %%edx, %%es:4(%3)\n"
8725 "3: movl 8(%4), %%eax\n"
8726 "31: movl 12(%4),%%edx\n"
8727 - " movnti %%eax, 8(%3)\n"
8728 - " movnti %%edx, 12(%3)\n"
8729 + " movnti %%eax, %%es:8(%3)\n"
8730 + " movnti %%edx, %%es:12(%3)\n"
8731 "4: movl 16(%4), %%eax\n"
8732 "41: movl 20(%4), %%edx\n"
8733 - " movnti %%eax, 16(%3)\n"
8734 - " movnti %%edx, 20(%3)\n"
8735 + " movnti %%eax, %%es:16(%3)\n"
8736 + " movnti %%edx, %%es:20(%3)\n"
8737 "10: movl 24(%4), %%eax\n"
8738 "51: movl 28(%4), %%edx\n"
8739 - " movnti %%eax, 24(%3)\n"
8740 - " movnti %%edx, 28(%3)\n"
8741 + " movnti %%eax, %%es:24(%3)\n"
8742 + " movnti %%edx, %%es:28(%3)\n"
8743 "11: movl 32(%4), %%eax\n"
8744 "61: movl 36(%4), %%edx\n"
8745 - " movnti %%eax, 32(%3)\n"
8746 - " movnti %%edx, 36(%3)\n"
8747 + " movnti %%eax, %%es:32(%3)\n"
8748 + " movnti %%edx, %%es:36(%3)\n"
8749 "12: movl 40(%4), %%eax\n"
8750 "71: movl 44(%4), %%edx\n"
8751 - " movnti %%eax, 40(%3)\n"
8752 - " movnti %%edx, 44(%3)\n"
8753 + " movnti %%eax, %%es:40(%3)\n"
8754 + " movnti %%edx, %%es:44(%3)\n"
8755 "13: movl 48(%4), %%eax\n"
8756 "81: movl 52(%4), %%edx\n"
8757 - " movnti %%eax, 48(%3)\n"
8758 - " movnti %%edx, 52(%3)\n"
8759 + " movnti %%eax, %%es:48(%3)\n"
8760 + " movnti %%edx, %%es:52(%3)\n"
8761 "14: movl 56(%4), %%eax\n"
8762 "91: movl 60(%4), %%edx\n"
8763 - " movnti %%eax, 56(%3)\n"
8764 - " movnti %%edx, 60(%3)\n"
8765 + " movnti %%eax, %%es:56(%3)\n"
8766 + " movnti %%edx, %%es:60(%3)\n"
8770 @@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
8776 ".section .fixup,\"ax\"\n"
8777 "9: lea 0(%%eax,%0,4),%0\n"
8779 @@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
8782 : "=&c"(size), "=&D" (d0), "=&S" (d1)
8783 - : "1"(to), "2"(from), "0"(size)
8784 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8785 : "eax", "edx", "memory");
8788 @@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
8790 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
8791 unsigned long size);
8792 -unsigned long __copy_user_intel(void __user *to, const void *from,
8793 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
8794 + unsigned long size);
8795 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
8796 unsigned long size);
8797 unsigned long __copy_user_zeroing_intel_nocache(void *to,
8798 const void __user *from, unsigned long size);
8799 #endif /* CONFIG_X86_INTEL_USERCOPY */
8801 /* Generic arbitrary sized copy. */
8802 -#define __copy_user(to, from, size) \
8804 - int __d0, __d1, __d2; \
8805 - __asm__ __volatile__( \
8812 - "4: rep; movsb\n" \
8816 - " .align 2,0x90\n" \
8817 - "0: rep; movsl\n" \
8819 - "1: rep; movsb\n" \
8821 - ".section .fixup,\"ax\"\n" \
8822 - "5: addl %3,%0\n" \
8824 - "3: lea 0(%3,%0,4),%0\n" \
8827 - ".section __ex_table,\"a\"\n" \
8829 - " .long 4b,5b\n" \
8830 - " .long 0b,3b\n" \
8831 - " .long 1b,2b\n" \
8833 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
8834 - : "3"(size), "0"(size), "1"(to), "2"(from) \
8838 -#define __copy_user_zeroing(to, from, size) \
8840 - int __d0, __d1, __d2; \
8841 - __asm__ __volatile__( \
8848 - "4: rep; movsb\n" \
8852 - " .align 2,0x90\n" \
8853 - "0: rep; movsl\n" \
8855 - "1: rep; movsb\n" \
8857 - ".section .fixup,\"ax\"\n" \
8858 - "5: addl %3,%0\n" \
8860 - "3: lea 0(%3,%0,4),%0\n" \
8862 - " pushl %%eax\n" \
8863 - " xorl %%eax,%%eax\n" \
8869 - ".section __ex_table,\"a\"\n" \
8871 - " .long 4b,5b\n" \
8872 - " .long 0b,3b\n" \
8873 - " .long 1b,6b\n" \
8875 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
8876 - : "3"(size), "0"(size), "1"(to), "2"(from) \
8879 +static unsigned long
8880 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
8882 + int __d0, __d1, __d2;
8884 + __asm__ __volatile__(
8885 + " movw %w8,%%es\n"
8896 + " .align 2,0x90\n"
8903 + ".section .fixup,\"ax\"\n"
8906 + "3: lea 0(%3,%0,4),%0\n"
8909 + ".section __ex_table,\"a\"\n"
8915 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
8916 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
8921 +static unsigned long
8922 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
8924 + int __d0, __d1, __d2;
8926 + __asm__ __volatile__(
8927 + " movw %w8,%%ds\n"
8938 + " .align 2,0x90\n"
8945 + ".section .fixup,\"ax\"\n"
8948 + "3: lea 0(%3,%0,4),%0\n"
8951 + ".section __ex_table,\"a\"\n"
8957 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
8958 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
8963 +static unsigned long
8964 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
8966 + int __d0, __d1, __d2;
8968 + __asm__ __volatile__(
8969 + " movw %w8,%%ds\n"
8980 + " .align 2,0x90\n"
8987 + ".section .fixup,\"ax\"\n"
8990 + "3: lea 0(%3,%0,4),%0\n"
8993 + " xorl %%eax,%%eax\n"
8999 + ".section __ex_table,\"a\"\n"
9005 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9006 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9011 unsigned long __copy_to_user_ll(void __user *to, const void *from,
9013 @@ -768,9 +959,9 @@ survive:
9016 if (movsl_is_ok(to, from, n))
9017 - __copy_user(to, from, n);
9018 + n = __generic_copy_to_user(to, from, n);
9020 - n = __copy_user_intel(to, from, n);
9021 + n = __generic_copy_to_user_intel(to, from, n);
9024 EXPORT_SYMBOL(__copy_to_user_ll);
9025 @@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
9028 if (movsl_is_ok(to, from, n))
9029 - __copy_user_zeroing(to, from, n);
9030 + n = __copy_user_zeroing(to, from, n);
9032 n = __copy_user_zeroing_intel(to, from, n);
9034 @@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
9037 if (movsl_is_ok(to, from, n))
9038 - __copy_user(to, from, n);
9039 + n = __generic_copy_from_user(to, from, n);
9041 - n = __copy_user_intel((void __user *)to,
9042 - (const void *)from, n);
9043 + n = __generic_copy_from_user_intel(to, from, n);
9046 EXPORT_SYMBOL(__copy_from_user_ll_nozero);
9047 @@ -802,12 +992,12 @@ unsigned long __copy_from_user_ll_nocach
9050 #ifdef CONFIG_X86_INTEL_USERCOPY
9051 - if (n > 64 && cpu_has_xmm2)
9052 + if ( n > 64 && cpu_has_xmm2)
9053 n = __copy_user_zeroing_intel_nocache(to, from, n);
9055 - __copy_user_zeroing(to, from, n);
9056 + n = __copy_user_zeroing(to, from, n);
9058 - __copy_user_zeroing(to, from, n);
9059 + n = __copy_user_zeroing(to, from, n);
9063 @@ -817,12 +1007,12 @@ unsigned long __copy_from_user_ll_nocach
9066 #ifdef CONFIG_X86_INTEL_USERCOPY
9067 - if (n > 64 && cpu_has_xmm2)
9068 + if ( n > 64 && cpu_has_xmm2)
9069 n = __copy_user_intel_nocache(to, from, n);
9071 - __copy_user(to, from, n);
9072 + n = __generic_copy_from_user(to, from, n);
9074 - __copy_user(to, from, n);
9075 + n = __generic_copy_from_user(to, from, n);
9079 @@ -871,8 +1061,35 @@ copy_from_user(void *to, const void __us
9081 if (access_ok(VERIFY_READ, from, n))
9082 n = __copy_from_user(to, from, n);
9084 + else if ((long)n > 0)
9088 EXPORT_SYMBOL(copy_from_user);
9090 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9091 +void __set_fs(mm_segment_t x, int cpu)
9093 + unsigned long limit = x.seg;
9094 + struct desc_struct d;
9096 + current_thread_info()->addr_limit = x;
9097 + if (likely(limit))
9098 + limit = (limit - 1UL) >> PAGE_SHIFT;
9099 + pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
9100 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
9103 +void set_fs(mm_segment_t x)
9105 + __set_fs(x, get_cpu());
9106 + put_cpu_no_resched();
9109 +void set_fs(mm_segment_t x)
9111 + current_thread_info()->addr_limit = x;
9115 +EXPORT_SYMBOL(set_fs);
9116 diff -urNp linux-2.6.27.4/arch/x86/mach-voyager/voyager_basic.c linux-2.6.27.4/arch/x86/mach-voyager/voyager_basic.c
9117 --- linux-2.6.27.4/arch/x86/mach-voyager/voyager_basic.c 2008-10-22 17:38:01.000000000 -0400
9118 +++ linux-2.6.27.4/arch/x86/mach-voyager/voyager_basic.c 2008-10-27 22:36:17.000000000 -0400
9119 @@ -123,7 +123,7 @@ int __init voyager_memory_detect(int reg
9122 unsigned long map_addr;
9123 - unsigned long old;
9126 if (region >= CLICK_ENTRIES) {
9127 printk("Voyager: Illegal ClickMap region %d\n", region);
9128 @@ -138,7 +138,7 @@ int __init voyager_memory_detect(int reg
9130 /* steal page 0 for this */
9132 - pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9133 + pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9135 /* now clear everything out but page 0 */
9136 map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
9137 diff -urNp linux-2.6.27.4/arch/x86/mach-voyager/voyager_smp.c linux-2.6.27.4/arch/x86/mach-voyager/voyager_smp.c
9138 --- linux-2.6.27.4/arch/x86/mach-voyager/voyager_smp.c 2008-10-22 17:38:01.000000000 -0400
9139 +++ linux-2.6.27.4/arch/x86/mach-voyager/voyager_smp.c 2008-10-27 22:36:17.000000000 -0400
9140 @@ -510,6 +510,10 @@ static void __init do_boot_cpu(__u8 cpu)
9141 __u32 *hijack_vector;
9142 __u32 start_phys_address = setup_trampoline();
9144 +#ifdef CONFIG_PAX_KERNEXEC
9145 + unsigned long cr0;
9148 /* There's a clever trick to this: The linux trampoline is
9149 * compiled to begin at absolute location zero, so make the
9150 * address zero but have the data segment selector compensate
9151 @@ -529,7 +533,17 @@ static void __init do_boot_cpu(__u8 cpu)
9154 per_cpu(current_task, cpu) = idle;
9155 - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9157 +#ifdef CONFIG_PAX_KERNEXEC
9158 + pax_open_kernel(cr0);
9161 + early_gdt_descr.address = get_cpu_gdt_table(cpu);
9163 +#ifdef CONFIG_PAX_KERNEXEC
9164 + pax_close_kernel(cr0);
9169 /* Note: Don't modify initial ss override */
9170 @@ -1141,7 +1155,7 @@ void smp_local_timer_interrupt(void)
9171 per_cpu(prof_counter, cpu);
9174 - update_process_times(user_mode_vm(get_irq_regs()));
9175 + update_process_times(user_mode(get_irq_regs()));
9178 if (((1 << cpu) & voyager_extended_vic_processors) == 0)
9179 diff -urNp linux-2.6.27.4/arch/x86/Makefile linux-2.6.27.4/arch/x86/Makefile
9180 --- linux-2.6.27.4/arch/x86/Makefile 2008-10-22 17:38:01.000000000 -0400
9181 +++ linux-2.6.27.4/arch/x86/Makefile 2008-10-27 22:36:16.000000000 -0400
9182 @@ -232,3 +232,12 @@ endef
9183 CLEAN_FILES += arch/x86/boot/fdimage \
9184 arch/x86/boot/image.iso \
9185 arch/x86/boot/mtools.conf
9189 +*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
9190 +*** Please upgrade your binutils to 2.18 or newer
9194 + $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
9195 diff -urNp linux-2.6.27.4/arch/x86/mm/discontig_32.c linux-2.6.27.4/arch/x86/mm/discontig_32.c
9196 --- linux-2.6.27.4/arch/x86/mm/discontig_32.c 2008-10-22 17:38:01.000000000 -0400
9197 +++ linux-2.6.27.4/arch/x86/mm/discontig_32.c 2008-10-27 22:36:17.000000000 -0400
9198 @@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
9202 -extern unsigned long find_max_low_pfn(void);
9203 extern unsigned long highend_pfn, highstart_pfn;
9205 #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
9206 diff -urNp linux-2.6.27.4/arch/x86/mm/extable.c linux-2.6.27.4/arch/x86/mm/extable.c
9207 --- linux-2.6.27.4/arch/x86/mm/extable.c 2008-10-22 17:38:01.000000000 -0400
9208 +++ linux-2.6.27.4/arch/x86/mm/extable.c 2008-10-27 22:36:17.000000000 -0400
9210 #include <linux/module.h>
9211 #include <linux/spinlock.h>
9212 +#include <linux/sort.h>
9213 #include <asm/uaccess.h>
9216 + * The exception table needs to be sorted so that the binary
9217 + * search that we use to find entries in it works properly.
9218 + * This is used both for the kernel exception table and for
9219 + * the exception tables of modules that get loaded.
9221 +static int cmp_ex(const void *a, const void *b)
9223 + const struct exception_table_entry *x = a, *y = b;
9225 + /* avoid overflow */
9226 + if (x->insn > y->insn)
9228 + if (x->insn < y->insn)
9233 +static void swap_ex(void *a, void *b, int size)
9235 + struct exception_table_entry t, *x = a, *y = b;
9237 +#ifdef CONFIG_PAX_KERNEXEC
9238 + unsigned long cr0;
9243 +#ifdef CONFIG_PAX_KERNEXEC
9244 + pax_open_kernel(cr0);
9250 +#ifdef CONFIG_PAX_KERNEXEC
9251 + pax_close_kernel(cr0);
9256 +void sort_extable(struct exception_table_entry *start,
9257 + struct exception_table_entry *finish)
9259 + sort(start, finish - start, sizeof(struct exception_table_entry),
9263 int fixup_exception(struct pt_regs *regs)
9265 const struct exception_table_entry *fixup;
9267 #ifdef CONFIG_PNPBIOS
9268 - if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
9269 + if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
9270 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
9271 extern u32 pnp_bios_is_utter_crap;
9272 pnp_bios_is_utter_crap = 1;
9273 diff -urNp linux-2.6.27.4/arch/x86/mm/fault.c linux-2.6.27.4/arch/x86/mm/fault.c
9274 --- linux-2.6.27.4/arch/x86/mm/fault.c 2008-10-22 17:38:01.000000000 -0400
9275 +++ linux-2.6.27.4/arch/x86/mm/fault.c 2008-10-27 22:56:15.000000000 -0400
9277 #include <linux/kprobes.h>
9278 #include <linux/uaccess.h>
9279 #include <linux/kdebug.h>
9280 +#include <linux/unistd.h>
9281 +#include <linux/compiler.h>
9283 #include <asm/system.h>
9284 #include <asm/desc.h>
9286 #include <asm/tlbflush.h>
9287 #include <asm/proto.h>
9288 #include <asm-generic/sections.h>
9289 +#include <asm/tlbflush.h>
9292 * Page fault error code bits
9293 @@ -66,7 +69,7 @@ static inline int notify_page_fault(stru
9296 /* kprobe_running() needs smp_processor_id() */
9297 - if (!user_mode_vm(regs)) {
9298 + if (!user_mode(regs)) {
9300 if (kprobe_running() && kprobe_fault_handler(regs, 14))
9302 @@ -264,6 +267,30 @@ bad:
9306 +#ifdef CONFIG_PAX_EMUTRAMP
9307 +static int pax_handle_fetch_fault(struct pt_regs *regs);
9310 +#ifdef CONFIG_PAX_PAGEEXEC
9311 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
9317 + pgd = pgd_offset(mm, address);
9318 + if (!pgd_present(*pgd))
9320 + pud = pud_offset(pgd, address);
9321 + if (!pud_present(*pud))
9323 + pmd = pmd_offset(pud, address);
9324 + if (!pmd_present(*pmd))
9330 #ifdef CONFIG_X86_32
9331 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
9333 @@ -350,7 +377,7 @@ static int is_errata93(struct pt_regs *r
9334 static int is_errata100(struct pt_regs *regs, unsigned long address)
9336 #ifdef CONFIG_X86_64
9337 - if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
9338 + if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
9342 @@ -387,14 +414,31 @@ static void show_fault_oops(struct pt_re
9345 #ifdef CONFIG_X86_PAE
9346 - if (error_code & PF_INSTR) {
9347 + if (nx_enabled && (error_code & PF_INSTR)) {
9349 pte_t *pte = lookup_address(address, &level);
9351 if (pte && pte_present(*pte) && !pte_exec(*pte))
9352 printk(KERN_CRIT "kernel tried to execute "
9353 "NX-protected page - exploit attempt? "
9354 - "(uid: %d)\n", current->uid);
9355 + "(uid: %d, task: %s, pid: %d)\n",
9356 + current->uid, current->comm, task_pid_nr(current));
9360 +#ifdef CONFIG_PAX_KERNEXEC
9361 +#ifdef CONFIG_MODULES
9362 + if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
9364 + if (init_mm.start_code <= address && address < init_mm.end_code)
9367 + if (current->signal->curr_ip)
9368 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9369 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
9371 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9372 + current->comm, task_pid_nr(current), current->uid, current->euid);
9376 @@ -586,13 +630,22 @@ void __kprobes do_page_fault(struct pt_r
9377 struct task_struct *tsk;
9378 struct mm_struct *mm;
9379 struct vm_area_struct *vma;
9380 - unsigned long address;
9383 #ifdef CONFIG_X86_64
9384 unsigned long flags;
9387 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9391 + unsigned char pte_mask;
9394 + /* get the address */
9395 + const unsigned long address = read_cr2();
9398 * We can fault from pretty much anywhere, with unknown IRQ state.
9400 @@ -602,9 +655,6 @@ void __kprobes do_page_fault(struct pt_r
9402 prefetchw(&mm->mmap_sem);
9404 - /* get the address */
9405 - address = read_cr2();
9407 si_code = SEGV_MAPERR;
9409 if (notify_page_fault(regs))
9410 @@ -657,7 +707,7 @@ void __kprobes do_page_fault(struct pt_r
9411 * atomic region then we must not take the fault.
9413 if (in_atomic() || !mm)
9414 - goto bad_area_nosemaphore;
9415 + goto bad_area_nopax;
9416 #else /* CONFIG_X86_64 */
9417 if (likely(regs->flags & X86_EFLAGS_IF))
9419 @@ -670,13 +720,13 @@ void __kprobes do_page_fault(struct pt_r
9420 * atomic region then we must not take the fault.
9422 if (unlikely(in_atomic() || !mm))
9423 - goto bad_area_nosemaphore;
9424 + goto bad_area_nopax;
9427 * User-mode registers count as a user access even for any
9428 * potential system fault or CPU buglet.
9430 - if (user_mode_vm(regs))
9431 + if (user_mode(regs))
9432 error_code |= PF_USER;
9435 @@ -698,10 +748,104 @@ again:
9436 if (!down_read_trylock(&mm->mmap_sem)) {
9437 if ((error_code & PF_USER) == 0 &&
9438 !search_exception_tables(regs->ip))
9439 - goto bad_area_nosemaphore;
9440 + goto bad_area_nopax;
9441 down_read(&mm->mmap_sem);
9444 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9445 + if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
9446 + !(mm->pax_flags & MF_PAX_PAGEEXEC))
9447 + goto not_pax_fault;
9449 + /* PaX: it's our fault, let's handle it if we can */
9451 + /* PaX: take a look at read faults before acquiring any locks */
9452 + if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
9453 + /* instruction fetch attempt from a protected page in user mode */
9454 + up_read(&mm->mmap_sem);
9456 +#ifdef CONFIG_PAX_EMUTRAMP
9457 + switch (pax_handle_fetch_fault(regs)) {
9463 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
9464 + do_group_exit(SIGKILL);
9467 + pmd = pax_get_pmd(mm, address);
9468 + if (unlikely(!pmd))
9469 + goto not_pax_fault;
9471 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
9472 + if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
9473 + pte_unmap_unlock(pte, ptl);
9474 + goto not_pax_fault;
9477 + if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
9478 + /* write attempt to a protected page in user mode */
9479 + pte_unmap_unlock(pte, ptl);
9480 + goto not_pax_fault;
9484 + if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
9486 + if (likely(address > get_limit(regs->cs)))
9489 + set_pte(pte, pte_mkread(*pte));
9490 + __flush_tlb_one(address);
9491 + pte_unmap_unlock(pte, ptl);
9492 + up_read(&mm->mmap_sem);
9496 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
9499 + * PaX: fill DTLB with user rights and retry
9501 + __asm__ __volatile__ (
9502 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9506 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
9508 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
9509 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
9510 + * page fault when examined during a TLB load attempt. this is true not only
9511 + * for PTEs holding a non-present entry but also present entries that will
9512 + * raise a page fault (such as those set up by PaX, or the copy-on-write
9513 + * mechanism). in effect it means that we do *not* need to flush the TLBs
9514 + * for our target pages since their PTEs are simply not in the TLBs at all.
9516 + * the best thing in omitting it is that we gain around 15-20% speed in the
9517 + * fast path of the page fault handler and can get rid of tracing since we
9518 + * can no longer flush unintended entries.
9522 + "testb $0,%%es:(%0)\n"
9524 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9529 + : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
9530 + : "memory", "cc");
9531 + pte_unmap_unlock(pte, ptl);
9532 + up_read(&mm->mmap_sem);
9538 vma = find_vma(mm, address);
9541 @@ -719,6 +863,12 @@ again:
9542 if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
9546 +#ifdef CONFIG_PAX_SEGMEXEC
9547 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
9551 if (expand_stack(vma, address))
9554 @@ -728,6 +878,8 @@ again:
9556 si_code = SEGV_ACCERR;
9558 + if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
9560 switch (error_code & (PF_PROT|PF_WRITE)) {
9561 default: /* 3: write, present */
9563 @@ -785,6 +937,54 @@ bad_area:
9564 up_read(&mm->mmap_sem);
9566 bad_area_nosemaphore:
9568 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
9569 + if (mm && (error_code & PF_USER)) {
9570 + unsigned long ip = regs->ip;
9572 + if (v8086_mode(regs))
9573 + ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
9576 + * It's possible to have interrupts off here.
9578 + local_irq_enable();
9580 +#ifdef CONFIG_PAX_PAGEEXEC
9581 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
9582 + (nx_enabled && ((error_code & PF_INSTR) || !(error_code & (PF_PROT | PF_WRITE))) && (regs->ip == address))) {
9584 +#ifdef CONFIG_PAX_EMUTRAMP
9585 + switch (pax_handle_fetch_fault(regs)) {
9591 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
9592 + do_group_exit(SIGKILL);
9596 +#ifdef CONFIG_PAX_SEGMEXEC
9597 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
9599 +#ifdef CONFIG_PAX_EMUTRAMP
9600 + switch (pax_handle_fetch_fault(regs)) {
9606 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
9607 + do_group_exit(SIGKILL);
9615 /* User mode accesses just cause a SIGSEGV */
9616 if (error_code & PF_USER) {
9618 @@ -863,7 +1063,7 @@ no_context:
9619 #ifdef CONFIG_X86_32
9620 die("Oops", regs, error_code);
9623 + do_group_exit(SIGKILL);
9625 if (__die("Oops", regs, error_code))
9627 @@ -877,17 +1077,17 @@ no_context:
9628 * us unable to handle the page fault gracefully.
9631 - up_read(&mm->mmap_sem);
9632 if (is_global_init(tsk)) {
9634 #ifdef CONFIG_X86_32
9635 - down_read(&mm->mmap_sem);
9638 + up_read(&mm->mmap_sem);
9643 + up_read(&mm->mmap_sem);
9644 printk("VM: killing process %s\n", tsk->comm);
9645 if (error_code & PF_USER)
9646 do_group_exit(SIGKILL);
9647 @@ -959,3 +1159,174 @@ void vmalloc_sync_all(void)
9652 +#ifdef CONFIG_PAX_EMUTRAMP
9653 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
9657 + do { /* PaX: gcc trampoline emulation #1 */
9658 + unsigned char mov1, mov2;
9659 + unsigned short jmp;
9660 + unsigned int addr1, addr2;
9662 +#ifdef CONFIG_X86_64
9663 + if ((regs->ip + 11) >> 32)
9667 + err = get_user(mov1, (unsigned char __user *)regs->ip);
9668 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
9669 + err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
9670 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
9671 + err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
9676 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
9684 + do { /* PaX: gcc trampoline emulation #2 */
9685 + unsigned char mov, jmp;
9686 + unsigned int addr1, addr2;
9688 +#ifdef CONFIG_X86_64
9689 + if ((regs->ip + 9) >> 32)
9693 + err = get_user(mov, (unsigned char __user *)regs->ip);
9694 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
9695 + err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
9696 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
9701 + if (mov == 0xB9 && jmp == 0xE9) {
9703 + regs->ip = (unsigned int)(regs->ip + addr2 + 10);
9708 + return 1; /* PaX in action */
9711 +#ifdef CONFIG_X86_64
9712 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
9716 + do { /* PaX: gcc trampoline emulation #1 */
9717 + unsigned short mov1, mov2, jmp1;
9718 + unsigned char jmp2;
9719 + unsigned int addr1;
9720 + unsigned long addr2;
9722 + err = get_user(mov1, (unsigned short __user *)regs->ip);
9723 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
9724 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
9725 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
9726 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
9727 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
9732 + if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
9733 + regs->r11 = addr1;
9734 + regs->r10 = addr2;
9740 + do { /* PaX: gcc trampoline emulation #2 */
9741 + unsigned short mov1, mov2, jmp1;
9742 + unsigned char jmp2;
9743 + unsigned long addr1, addr2;
9745 + err = get_user(mov1, (unsigned short __user *)regs->ip);
9746 + err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
9747 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
9748 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
9749 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
9750 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
9755 + if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
9756 + regs->r11 = addr1;
9757 + regs->r10 = addr2;
9763 + return 1; /* PaX in action */
9768 + * PaX: decide what to do with offenders (regs->ip = fault address)
9770 + * returns 1 when task should be killed
9771 + * 2 when gcc trampoline was detected
9773 +static int pax_handle_fetch_fault(struct pt_regs *regs)
9775 + if (v8086_mode(regs))
9778 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
9781 +#ifdef CONFIG_X86_32
9782 + return pax_handle_fetch_fault_32(regs);
9784 + if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
9785 + return pax_handle_fetch_fault_32(regs);
9787 + return pax_handle_fetch_fault_64(regs);
9792 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
9793 +void pax_report_insns(void *pc, void *sp)
9797 + printk(KERN_ERR "PAX: bytes at PC: ");
9798 + for (i = 0; i < 20; i++) {
9800 + if (get_user(c, (unsigned char __user *)pc+i))
9801 + printk(KERN_CONT "?? ");
9803 + printk(KERN_CONT "%02x ", c);
9807 + printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
9808 + for (i = -1; i < 80 / sizeof(long); i++) {
9810 + if (get_user(c, (unsigned long __user *)sp+i))
9811 +#ifdef CONFIG_X86_32
9812 + printk(KERN_CONT "???????? ");
9814 + printk(KERN_CONT "???????????????? ");
9817 + printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
9822 diff -urNp linux-2.6.27.4/arch/x86/mm/highmem_32.c linux-2.6.27.4/arch/x86/mm/highmem_32.c
9823 --- linux-2.6.27.4/arch/x86/mm/highmem_32.c 2008-10-22 17:38:01.000000000 -0400
9824 +++ linux-2.6.27.4/arch/x86/mm/highmem_32.c 2008-10-27 22:36:17.000000000 -0400
9825 @@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
9826 enum fixed_addresses idx;
9827 unsigned long vaddr;
9829 +#ifdef CONFIG_PAX_KERNEXEC
9830 + unsigned long cr0;
9833 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
9834 pagefault_disable();
9836 @@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
9837 idx = type + KM_TYPE_NR*smp_processor_id();
9838 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
9839 BUG_ON(!pte_none(*(kmap_pte-idx)));
9841 +#ifdef CONFIG_PAX_KERNEXEC
9842 + pax_open_kernel(cr0);
9845 set_pte(kmap_pte-idx, mk_pte(page, prot));
9847 +#ifdef CONFIG_PAX_KERNEXEC
9848 + pax_close_kernel(cr0);
9851 arch_flush_lazy_mmu_mode();
9853 return (void *)vaddr;
9854 @@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
9855 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
9856 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
9858 +#ifdef CONFIG_PAX_KERNEXEC
9859 + unsigned long cr0;
9863 * Force other mappings to Oops if they'll try to access this pte
9864 * without first remap it. Keeping stale mappings around is a bad idea
9865 * also, in case the page changes cacheability attributes or becomes
9866 * a protected page in a hypervisor.
9868 - if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
9869 + if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
9871 +#ifdef CONFIG_PAX_KERNEXEC
9872 + pax_open_kernel(cr0);
9875 kpte_clear_flush(kmap_pte-idx, vaddr);
9878 +#ifdef CONFIG_PAX_KERNEXEC
9879 + pax_close_kernel(cr0);
9883 #ifdef CONFIG_DEBUG_HIGHMEM
9884 BUG_ON(vaddr < PAGE_OFFSET);
9885 BUG_ON(vaddr >= (unsigned long)high_memory);
9886 @@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
9887 enum fixed_addresses idx;
9888 unsigned long vaddr;
9890 +#ifdef CONFIG_PAX_KERNEXEC
9891 + unsigned long cr0;
9894 pagefault_disable();
9896 idx = type + KM_TYPE_NR*smp_processor_id();
9897 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
9899 +#ifdef CONFIG_PAX_KERNEXEC
9900 + pax_open_kernel(cr0);
9903 set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
9905 +#ifdef CONFIG_PAX_KERNEXEC
9906 + pax_close_kernel(cr0);
9909 arch_flush_lazy_mmu_mode();
9911 return (void*) vaddr;
9912 diff -urNp linux-2.6.27.4/arch/x86/mm/hugetlbpage.c linux-2.6.27.4/arch/x86/mm/hugetlbpage.c
9913 --- linux-2.6.27.4/arch/x86/mm/hugetlbpage.c 2008-10-22 17:38:01.000000000 -0400
9914 +++ linux-2.6.27.4/arch/x86/mm/hugetlbpage.c 2008-10-27 22:36:17.000000000 -0400
9915 @@ -263,13 +263,18 @@ static unsigned long hugetlb_get_unmappe
9916 struct hstate *h = hstate_file(file);
9917 struct mm_struct *mm = current->mm;
9918 struct vm_area_struct *vma;
9919 - unsigned long start_addr;
9920 + unsigned long start_addr, pax_task_size = TASK_SIZE;
9922 +#ifdef CONFIG_PAX_SEGMEXEC
9923 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
9924 + pax_task_size = SEGMEXEC_TASK_SIZE;
9927 if (len > mm->cached_hole_size) {
9928 - start_addr = mm->free_area_cache;
9929 + start_addr = mm->free_area_cache;
9931 - start_addr = TASK_UNMAPPED_BASE;
9932 - mm->cached_hole_size = 0;
9933 + start_addr = mm->mmap_base;
9934 + mm->cached_hole_size = 0;
9938 @@ -277,13 +282,13 @@ full_search:
9940 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
9941 /* At this point: (!vma || addr < vma->vm_end). */
9942 - if (TASK_SIZE - len < addr) {
9943 + if (pax_task_size - len < addr) {
9945 * Start a new search - just in case we missed
9948 - if (start_addr != TASK_UNMAPPED_BASE) {
9949 - start_addr = TASK_UNMAPPED_BASE;
9950 + if (start_addr != mm->mmap_base) {
9951 + start_addr = mm->mmap_base;
9952 mm->cached_hole_size = 0;
9955 @@ -306,9 +311,8 @@ static unsigned long hugetlb_get_unmappe
9956 struct hstate *h = hstate_file(file);
9957 struct mm_struct *mm = current->mm;
9958 struct vm_area_struct *vma, *prev_vma;
9959 - unsigned long base = mm->mmap_base, addr = addr0;
9960 + unsigned long base = mm->mmap_base, addr;
9961 unsigned long largest_hole = mm->cached_hole_size;
9962 - int first_time = 1;
9964 /* don't allow allocations above current base */
9965 if (mm->free_area_cache > base)
9966 @@ -318,7 +322,7 @@ static unsigned long hugetlb_get_unmappe
9968 mm->free_area_cache = base;
9972 /* make sure it can fit in the remaining address space */
9973 if (mm->free_area_cache < len)
9975 @@ -360,22 +364,26 @@ try_again:
9979 - * if hint left us with no space for the requested
9980 - * mapping then try again:
9983 - mm->free_area_cache = base;
9989 * A failed mmap() very likely causes application failure,
9990 * so fall back to the bottom-up function here. This scenario
9991 * can happen with large stack limits and large mmap()
9994 - mm->free_area_cache = TASK_UNMAPPED_BASE;
9996 +#ifdef CONFIG_PAX_SEGMEXEC
9997 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
9998 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
10002 + mm->mmap_base = TASK_UNMAPPED_BASE;
10004 +#ifdef CONFIG_PAX_RANDMMAP
10005 + if (mm->pax_flags & MF_PAX_RANDMMAP)
10006 + mm->mmap_base += mm->delta_mmap;
10009 + mm->free_area_cache = mm->mmap_base;
10010 mm->cached_hole_size = ~0UL;
10011 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
10012 len, pgoff, flags);
10013 @@ -383,6 +391,7 @@ fail:
10015 * Restore the topdown base:
10017 + mm->mmap_base = base;
10018 mm->free_area_cache = base;
10019 mm->cached_hole_size = ~0UL;
10021 @@ -396,10 +405,17 @@ hugetlb_get_unmapped_area(struct file *f
10022 struct hstate *h = hstate_file(file);
10023 struct mm_struct *mm = current->mm;
10024 struct vm_area_struct *vma;
10025 + unsigned long pax_task_size = TASK_SIZE;
10027 if (len & ~huge_page_mask(h))
10029 - if (len > TASK_SIZE)
10031 +#ifdef CONFIG_PAX_SEGMEXEC
10032 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10033 + pax_task_size = SEGMEXEC_TASK_SIZE;
10036 + if (len > pax_task_size)
10039 if (flags & MAP_FIXED) {
10040 @@ -411,7 +427,7 @@ hugetlb_get_unmapped_area(struct file *f
10042 addr = ALIGN(addr, huge_page_size(h));
10043 vma = find_vma(mm, addr);
10044 - if (TASK_SIZE - len >= addr &&
10045 + if (pax_task_size - len >= addr &&
10046 (!vma || addr + len <= vma->vm_start))
10049 diff -urNp linux-2.6.27.4/arch/x86/mm/init_32.c linux-2.6.27.4/arch/x86/mm/init_32.c
10050 --- linux-2.6.27.4/arch/x86/mm/init_32.c 2008-10-22 17:38:01.000000000 -0400
10051 +++ linux-2.6.27.4/arch/x86/mm/init_32.c 2008-10-27 22:36:17.000000000 -0400
10053 #include <asm/paravirt.h>
10054 #include <asm/setup.h>
10055 #include <asm/cacheflush.h>
10056 +#include <asm/desc.h>
10058 unsigned int __VMALLOC_RESERVE = 128 << 20;
10060 @@ -80,35 +81,6 @@ static __init void *alloc_low_page(unsig
10064 - * Creates a middle page table and puts a pointer to it in the
10065 - * given global directory entry. This only returns the gd entry
10066 - * in non-PAE compilation mode, since the middle layer is folded.
10068 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
10071 - pmd_t *pmd_table;
10073 -#ifdef CONFIG_X86_PAE
10074 - unsigned long phys;
10075 - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
10076 - if (after_init_bootmem)
10077 - pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
10079 - pmd_table = (pmd_t *)alloc_low_page(&phys);
10080 - paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
10081 - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
10082 - pud = pud_offset(pgd, 0);
10083 - BUG_ON(pmd_table != pmd_offset(pud, 0));
10086 - pud = pud_offset(pgd, 0);
10087 - pmd_table = pmd_offset(pud, 0);
10089 - return pmd_table;
10093 * Create a page table and place a pointer to it in a middle page
10096 @@ -130,7 +102,11 @@ static pte_t * __init one_page_table_ini
10099 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
10100 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10101 + set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
10103 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
10105 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
10108 @@ -152,6 +128,7 @@ page_table_range_init(unsigned long star
10109 int pgd_idx, pmd_idx;
10110 unsigned long vaddr;
10116 @@ -160,8 +137,13 @@ page_table_range_init(unsigned long star
10117 pgd = pgd_base + pgd_idx;
10119 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
10120 - pmd = one_md_table_init(pgd);
10121 - pmd = pmd + pmd_index(vaddr);
10122 + pud = pud_offset(pgd, vaddr);
10123 + pmd = pmd_offset(pud, vaddr);
10125 +#ifdef CONFIG_X86_PAE
10126 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10129 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
10130 pmd++, pmd_idx++) {
10131 one_page_table_init(pmd);
10132 @@ -172,11 +154,23 @@ page_table_range_init(unsigned long star
10136 -static inline int is_kernel_text(unsigned long addr)
10137 +static inline int is_kernel_text(unsigned long start, unsigned long end)
10139 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
10142 + unsigned long etext;
10144 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
10145 + etext = ktva_ktla((unsigned long)&MODULES_END);
10147 + etext = (unsigned long)&_etext;
10150 + if ((start > ktla_ktva(etext) ||
10151 + end <= ktla_ktva((unsigned long)_stext)) &&
10152 + (start > ktla_ktva((unsigned long)_einittext) ||
10153 + end <= ktla_ktva((unsigned long)_sinittext)) &&
10154 + (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
10160 @@ -189,9 +183,10 @@ static void __init kernel_physical_mappi
10161 unsigned long end_pfn,
10164 - int pgd_idx, pmd_idx, pte_ofs;
10165 + unsigned int pgd_idx, pmd_idx, pte_ofs;
10171 unsigned pages_2m = 0, pages_4k = 0;
10172 @@ -202,8 +197,13 @@ static void __init kernel_physical_mappi
10174 pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
10175 pgd = pgd_base + pgd_idx;
10176 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
10177 - pmd = one_md_table_init(pgd);
10178 + for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
10179 + pud = pud_offset(pgd, 0);
10180 + pmd = pmd_offset(pud, 0);
10182 +#ifdef CONFIG_X86_PAE
10183 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10186 if (pfn >= end_pfn)
10188 @@ -215,21 +215,16 @@ static void __init kernel_physical_mappi
10190 for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
10191 pmd++, pmd_idx++) {
10192 - unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
10193 + unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
10196 * Map with big pages if possible, otherwise
10197 * create normal page tables:
10200 - unsigned int addr2;
10201 pgprot_t prot = PAGE_KERNEL_LARGE;
10203 - addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
10204 - PAGE_OFFSET + PAGE_SIZE-1;
10206 - if (is_kernel_text(addr) ||
10207 - is_kernel_text(addr2))
10208 + if (is_kernel_text(address, address + PMD_SIZE))
10209 prot = PAGE_KERNEL_LARGE_EXEC;
10212 @@ -243,10 +238,10 @@ static void __init kernel_physical_mappi
10213 pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
10215 for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
10216 - pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
10217 + pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
10218 pgprot_t prot = PAGE_KERNEL;
10220 - if (is_kernel_text(addr))
10221 + if (is_kernel_text(address, address + PAGE_SIZE))
10222 prot = PAGE_KERNEL_EXEC;
10225 @@ -270,7 +265,9 @@ static void __init kernel_physical_mappi
10227 int devmem_is_allowed(unsigned long pagenr)
10229 - if (pagenr <= 256)
10232 + if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10234 if (!page_is_ram(pagenr))
10236 @@ -404,7 +401,7 @@ void __init native_pagetable_setup_start
10238 pud = pud_offset(pgd, va);
10239 pmd = pmd_offset(pud, va);
10240 - if (!pmd_present(*pmd))
10241 + if (!pmd_present(*pmd) || pmd_huge(*pmd))
10244 pte = pte_offset_kernel(pmd, va);
10245 @@ -456,9 +453,7 @@ static void __init early_ioremap_page_ta
10247 static void __init pagetable_init(void)
10249 - pgd_t *pgd_base = swapper_pg_dir;
10251 - permanent_kmaps_init(pgd_base);
10252 + permanent_kmaps_init(swapper_pg_dir);
10255 #ifdef CONFIG_ACPI_SLEEP
10256 @@ -466,12 +461,12 @@ static void __init pagetable_init(void)
10257 * ACPI suspend needs this for resume, because things like the intel-agp
10258 * driver might have split up a kernel 4MB mapping.
10260 -char swsusp_pg_dir[PAGE_SIZE]
10261 +pgd_t swsusp_pg_dir[PTRS_PER_PGD]
10262 __attribute__ ((aligned(PAGE_SIZE)));
10264 static inline void save_pg_dir(void)
10266 - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
10267 + clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
10269 #else /* !CONFIG_ACPI_SLEEP */
10270 static inline void save_pg_dir(void)
10271 @@ -501,13 +496,11 @@ void zap_low_mappings(void)
10275 -pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL);
10276 +pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL);
10277 EXPORT_SYMBOL_GPL(__supported_pte_mask);
10279 #ifdef CONFIG_X86_PAE
10281 -static int disable_nx __initdata;
10286 @@ -516,40 +509,33 @@ static int disable_nx __initdata;
10290 +#if !defined(CONFIG_PAX_PAGEEXEC)
10291 static int __init noexec_setup(char *str)
10293 if (!str || !strcmp(str, "on")) {
10294 - if (cpu_has_nx) {
10295 - __supported_pte_mask |= _PAGE_NX;
10301 - if (!strcmp(str, "off")) {
10303 - __supported_pte_mask &= ~_PAGE_NX;
10305 + if (!strcmp(str, "off"))
10314 early_param("noexec", noexec_setup);
10317 static void __init set_nx(void)
10319 - unsigned int v[4], l, h;
10321 - if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
10322 - cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
10323 + if (!nx_enabled && cpu_has_nx) {
10326 - if ((v[3] & (1 << 20)) && !disable_nx) {
10327 - rdmsr(MSR_EFER, l, h);
10329 - wrmsr(MSR_EFER, l, h);
10331 - __supported_pte_mask |= _PAGE_NX;
10333 + __supported_pte_mask &= ~_PAGE_NX;
10334 + rdmsr(MSR_EFER, l, h);
10336 + wrmsr(MSR_EFER, l, h);
10340 @@ -920,7 +906,7 @@ void __init mem_init(void)
10341 set_highmem_pages_init();
10343 codesize = (unsigned long) &_etext - (unsigned long) &_text;
10344 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
10345 + datasize = (unsigned long) &_edata - (unsigned long) &_data;
10346 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
10348 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
10349 @@ -966,10 +952,10 @@ void __init mem_init(void)
10350 ((unsigned long)&__init_end -
10351 (unsigned long)&__init_begin) >> 10,
10353 - (unsigned long)&_etext, (unsigned long)&_edata,
10354 - ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
10355 + (unsigned long)&_data, (unsigned long)&_edata,
10356 + ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
10358 - (unsigned long)&_text, (unsigned long)&_etext,
10359 + ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
10360 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
10362 #ifdef CONFIG_HIGHMEM
10363 @@ -1099,6 +1085,46 @@ void free_init_pages(char *what, unsigne
10365 void free_initmem(void)
10368 +#ifdef CONFIG_PAX_KERNEXEC
10369 + /* PaX: limit KERNEL_CS to actual size */
10370 + unsigned long addr, limit;
10371 + struct desc_struct d;
10377 +#ifdef CONFIG_MODULES
10378 + limit = ktva_ktla((unsigned long)&MODULES_END);
10380 + limit = (unsigned long)&_etext;
10382 + limit = (limit - 1UL) >> PAGE_SHIFT;
10384 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
10385 + pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
10386 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
10389 + /* PaX: make KERNEL_CS read-only */
10390 + for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
10391 + pgd = pgd_offset_k(addr);
10392 + pud = pud_offset(pgd, addr);
10393 + pmd = pmd_offset(pud, addr);
10394 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10396 +#ifdef CONFIG_X86_PAE
10397 + for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
10398 + pgd = pgd_offset_k(addr);
10399 + pud = pud_offset(pgd, addr);
10400 + pmd = pmd_offset(pud, addr);
10401 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10407 free_init_pages("unused kernel memory",
10408 (unsigned long)(&__init_begin),
10409 (unsigned long)(&__init_end));
10410 diff -urNp linux-2.6.27.4/arch/x86/mm/init_64.c linux-2.6.27.4/arch/x86/mm/init_64.c
10411 --- linux-2.6.27.4/arch/x86/mm/init_64.c 2008-10-22 17:38:01.000000000 -0400
10412 +++ linux-2.6.27.4/arch/x86/mm/init_64.c 2008-10-27 22:36:17.000000000 -0400
10413 @@ -118,6 +118,10 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
10417 +#ifdef CONFIG_PAX_KERNEXEC
10418 + unsigned long cr0;
10421 pud = pud_page + pud_index(vaddr);
10422 if (pud_none(*pud)) {
10423 pmd = (pmd_t *) spp_getpage();
10424 @@ -142,8 +146,17 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
10425 if (!pte_none(*pte) && pte_val(new_pte) &&
10426 pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
10429 +#ifdef CONFIG_PAX_KERNEXEC
10430 + pax_open_kernel(cr0);
10433 set_pte(pte, new_pte);
10435 +#ifdef CONFIG_PAX_KERNEXEC
10436 + pax_close_kernel(cr0);
10440 * It's enough to flush this one mapping.
10441 * (PGE mappings get flushed as well)
10442 @@ -184,14 +197,12 @@ static void __init __init_extra_mapping(
10443 pgd = pgd_offset_k((unsigned long)__va(phys));
10444 if (pgd_none(*pgd)) {
10445 pud = (pud_t *) spp_getpage();
10446 - set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
10448 + set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
10450 pud = pud_offset(pgd, (unsigned long)__va(phys));
10451 if (pud_none(*pud)) {
10452 pmd = (pmd_t *) spp_getpage();
10453 - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
10455 + set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
10457 pmd = pmd_offset(pud, phys);
10458 BUG_ON(!pmd_none(*pmd));
10459 @@ -754,7 +765,9 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
10461 int devmem_is_allowed(unsigned long pagenr)
10463 - if (pagenr <= 256)
10466 + if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10468 if (!page_is_ram(pagenr))
10470 @@ -842,6 +855,39 @@ void free_init_pages(char *what, unsigne
10472 void free_initmem(void)
10475 +#ifdef CONFIG_PAX_KERNEXEC
10476 + unsigned long addr, end;
10481 + /* PaX: make kernel code/rodata read-only, rest non-executable */
10482 + for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
10483 + pgd = pgd_offset_k(addr);
10484 + pud = pud_offset(pgd, addr);
10485 + pmd = pmd_offset(pud, addr);
10486 + if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
10487 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10489 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10492 + addr = (unsigned long)__va(__pa(__START_KERNEL_map));
10493 + end = addr + KERNEL_IMAGE_SIZE;
10494 + for (; addr < end; addr += PMD_SIZE) {
10495 + pgd = pgd_offset_k(addr);
10496 + pud = pud_offset(pgd, addr);
10497 + pmd = pmd_offset(pud, addr);
10498 + if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
10499 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10501 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10507 free_init_pages("unused kernel memory",
10508 (unsigned long)(&__init_begin),
10509 (unsigned long)(&__init_end));
10510 @@ -1014,7 +1060,7 @@ int in_gate_area_no_task(unsigned long a
10512 const char *arch_vma_name(struct vm_area_struct *vma)
10514 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
10515 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
10517 if (vma == &gate_vma)
10518 return "[vsyscall]";
10519 diff -urNp linux-2.6.27.4/arch/x86/mm/ioremap.c linux-2.6.27.4/arch/x86/mm/ioremap.c
10520 --- linux-2.6.27.4/arch/x86/mm/ioremap.c 2008-10-22 17:38:01.000000000 -0400
10521 +++ linux-2.6.27.4/arch/x86/mm/ioremap.c 2008-10-27 22:36:17.000000000 -0400
10522 @@ -63,8 +63,8 @@ int page_is_ram(unsigned long pagenr)
10523 * Second special case: Some BIOSen report the PC BIOS
10524 * area (640->1Mb) as ram even though it is not.
10526 - if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
10527 - pagenr < (BIOS_END >> PAGE_SHIFT))
10528 + if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
10529 + pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10532 for (i = 0; i < e820.nr_map; i++) {
10533 @@ -217,6 +217,8 @@ static void __iomem *__ioremap_caller(re
10537 + prot = canon_pgprot(prot);
10542 diff -urNp linux-2.6.27.4/arch/x86/mm/mmap.c linux-2.6.27.4/arch/x86/mm/mmap.c
10543 --- linux-2.6.27.4/arch/x86/mm/mmap.c 2008-10-22 17:38:01.000000000 -0400
10544 +++ linux-2.6.27.4/arch/x86/mm/mmap.c 2008-10-27 22:36:17.000000000 -0400
10546 * Leave an at least ~128 MB hole.
10548 #define MIN_GAP (128*1024*1024)
10549 -#define MAX_GAP (TASK_SIZE/6*5)
10550 +#define MAX_GAP (pax_task_size/6*5)
10553 * True on X86_32 or when emulating IA32 on X86_64
10554 @@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
10555 return rnd << PAGE_SHIFT;
10558 -static unsigned long mmap_base(void)
10559 +static unsigned long mmap_base(struct mm_struct *mm)
10561 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
10562 + unsigned long pax_task_size = TASK_SIZE;
10564 +#ifdef CONFIG_PAX_SEGMEXEC
10565 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10566 + pax_task_size = SEGMEXEC_TASK_SIZE;
10571 else if (gap > MAX_GAP)
10574 - return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
10575 + return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
10579 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
10580 * does, but not when emulating X86_32
10582 -static unsigned long mmap_legacy_base(void)
10583 +static unsigned long mmap_legacy_base(struct mm_struct *mm)
10585 - if (mmap_is_ia32())
10586 + if (mmap_is_ia32()) {
10588 +#ifdef CONFIG_PAX_SEGMEXEC
10589 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10590 + return SEGMEXEC_TASK_UNMAPPED_BASE;
10594 return TASK_UNMAPPED_BASE;
10597 return TASK_UNMAPPED_BASE + mmap_rnd();
10600 @@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
10601 void arch_pick_mmap_layout(struct mm_struct *mm)
10603 if (mmap_is_legacy()) {
10604 - mm->mmap_base = mmap_legacy_base();
10605 + mm->mmap_base = mmap_legacy_base(mm);
10607 +#ifdef CONFIG_PAX_RANDMMAP
10608 + if (mm->pax_flags & MF_PAX_RANDMMAP)
10609 + mm->mmap_base += mm->delta_mmap;
10612 mm->get_unmapped_area = arch_get_unmapped_area;
10613 mm->unmap_area = arch_unmap_area;
10615 - mm->mmap_base = mmap_base();
10616 + mm->mmap_base = mmap_base(mm);
10618 +#ifdef CONFIG_PAX_RANDMMAP
10619 + if (mm->pax_flags & MF_PAX_RANDMMAP)
10620 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
10623 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
10624 mm->unmap_area = arch_unmap_area_topdown;
10626 diff -urNp linux-2.6.27.4/arch/x86/mm/pageattr.c linux-2.6.27.4/arch/x86/mm/pageattr.c
10627 --- linux-2.6.27.4/arch/x86/mm/pageattr.c 2008-10-22 17:38:01.000000000 -0400
10628 +++ linux-2.6.27.4/arch/x86/mm/pageattr.c 2008-10-27 22:36:17.000000000 -0400
10630 #include <asm/pgalloc.h>
10631 #include <asm/proto.h>
10632 #include <asm/pat.h>
10633 +#include <asm/desc.h>
10636 * The current flushing context - we pass it instead of 5 arguments:
10637 @@ -213,7 +214,7 @@ static inline pgprot_t static_protection
10638 * Does not cover __inittext since that is gone later on. On
10639 * 64bit we do not enforce !NX on the low mapping
10641 - if (within(address, (unsigned long)_text, (unsigned long)_etext))
10642 + if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
10643 pgprot_val(forbidden) |= _PAGE_NX;
10646 @@ -275,8 +276,20 @@ EXPORT_SYMBOL_GPL(lookup_address);
10648 static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
10651 +#ifdef CONFIG_PAX_KERNEXEC
10652 + unsigned long cr0;
10654 + pax_open_kernel(cr0);
10657 /* change init_mm */
10658 set_pte_atomic(kpte, pte);
10660 +#ifdef CONFIG_PAX_KERNEXEC
10661 + pax_close_kernel(cr0);
10664 #ifdef CONFIG_X86_32
10665 if (!SHARED_KERNEL_PMD) {
10667 diff -urNp linux-2.6.27.4/arch/x86/mm/pat.c linux-2.6.27.4/arch/x86/mm/pat.c
10668 --- linux-2.6.27.4/arch/x86/mm/pat.c 2008-10-22 17:38:01.000000000 -0400
10669 +++ linux-2.6.27.4/arch/x86/mm/pat.c 2008-10-27 22:36:17.000000000 -0400
10670 @@ -396,7 +396,7 @@ pgprot_t phys_mem_access_prot(struct fil
10674 -#ifdef CONFIG_STRICT_DEVMEM
10675 +#ifndef CONFIG_STRICT_DEVMEM
10676 /* This check is done in drivers/char/mem.c in case of STRICT_DEVMEM*/
10677 static inline int range_is_allowed(unsigned long pfn, unsigned long size)
10679 diff -urNp linux-2.6.27.4/arch/x86/mm/pgtable_32.c linux-2.6.27.4/arch/x86/mm/pgtable_32.c
10680 --- linux-2.6.27.4/arch/x86/mm/pgtable_32.c 2008-10-22 17:38:01.000000000 -0400
10681 +++ linux-2.6.27.4/arch/x86/mm/pgtable_32.c 2008-10-27 22:36:17.000000000 -0400
10682 @@ -31,6 +31,10 @@ void set_pte_vaddr(unsigned long vaddr,
10686 +#ifdef CONFIG_PAX_KERNEXEC
10687 + unsigned long cr0;
10690 pgd = swapper_pg_dir + pgd_index(vaddr);
10691 if (pgd_none(*pgd)) {
10693 @@ -47,11 +51,20 @@ void set_pte_vaddr(unsigned long vaddr,
10696 pte = pte_offset_kernel(pmd, vaddr);
10698 +#ifdef CONFIG_PAX_KERNEXEC
10699 + pax_open_kernel(cr0);
10702 if (pte_val(pteval))
10703 set_pte_present(&init_mm, vaddr, pte, pteval);
10705 pte_clear(&init_mm, vaddr, pte);
10707 +#ifdef CONFIG_PAX_KERNEXEC
10708 + pax_close_kernel(cr0);
10712 * It's enough to flush this one mapping.
10713 * (PGE mappings get flushed as well)
10714 diff -urNp linux-2.6.27.4/arch/x86/oprofile/backtrace.c linux-2.6.27.4/arch/x86/oprofile/backtrace.c
10715 --- linux-2.6.27.4/arch/x86/oprofile/backtrace.c 2008-10-22 17:38:01.000000000 -0400
10716 +++ linux-2.6.27.4/arch/x86/oprofile/backtrace.c 2008-10-27 22:36:17.000000000 -0400
10717 @@ -37,7 +37,7 @@ static void backtrace_address(void *data
10718 unsigned int *depth = data;
10721 - oprofile_add_trace(addr);
10722 + oprofile_add_trace(ktla_ktva(addr));
10725 static struct stacktrace_ops backtrace_ops = {
10726 @@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
10727 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
10728 unsigned long stack = kernel_trap_sp(regs);
10730 - if (!user_mode_vm(regs)) {
10731 + if (!user_mode(regs)) {
10733 dump_trace(NULL, regs, (unsigned long *)stack, 0,
10734 &backtrace_ops, &depth);
10735 diff -urNp linux-2.6.27.4/arch/x86/oprofile/op_model_p4.c linux-2.6.27.4/arch/x86/oprofile/op_model_p4.c
10736 --- linux-2.6.27.4/arch/x86/oprofile/op_model_p4.c 2008-10-22 17:38:01.000000000 -0400
10737 +++ linux-2.6.27.4/arch/x86/oprofile/op_model_p4.c 2008-10-27 22:36:17.000000000 -0400
10738 @@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
10742 -static int inline addr_increment(void)
10743 +static inline int addr_increment(void)
10746 return smp_num_siblings == 2 ? 2 : 1;
10747 diff -urNp linux-2.6.27.4/arch/x86/pci/common.c linux-2.6.27.4/arch/x86/pci/common.c
10748 --- linux-2.6.27.4/arch/x86/pci/common.c 2008-10-22 17:38:01.000000000 -0400
10749 +++ linux-2.6.27.4/arch/x86/pci/common.c 2008-10-27 22:36:17.000000000 -0400
10750 @@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat
10751 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
10755 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
10758 void __init dmi_check_pciprobe(void)
10759 diff -urNp linux-2.6.27.4/arch/x86/pci/fixup.c linux-2.6.27.4/arch/x86/pci/fixup.c
10760 --- linux-2.6.27.4/arch/x86/pci/fixup.c 2008-10-22 17:38:01.000000000 -0400
10761 +++ linux-2.6.27.4/arch/x86/pci/fixup.c 2008-10-27 22:36:17.000000000 -0400
10762 @@ -365,7 +365,7 @@ static struct dmi_system_id __devinitdat
10763 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
10767 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
10771 @@ -436,7 +436,7 @@ static struct dmi_system_id __devinitdat
10772 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
10776 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
10779 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
10780 diff -urNp linux-2.6.27.4/arch/x86/pci/irq.c linux-2.6.27.4/arch/x86/pci/irq.c
10781 --- linux-2.6.27.4/arch/x86/pci/irq.c 2008-10-22 17:38:01.000000000 -0400
10782 +++ linux-2.6.27.4/arch/x86/pci/irq.c 2008-10-27 22:36:17.000000000 -0400
10783 @@ -544,7 +544,7 @@ static __init int intel_router_probe(str
10784 static struct pci_device_id __initdata pirq_440gx[] = {
10785 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
10786 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
10788 + { PCI_DEVICE(0, 0) }
10791 /* 440GX has a proprietary PIRQ router -- don't use it */
10792 @@ -1131,7 +1131,7 @@ static struct dmi_system_id __initdata p
10793 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
10797 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
10800 int __init pcibios_irq_init(void)
10801 diff -urNp linux-2.6.27.4/arch/x86/pci/pcbios.c linux-2.6.27.4/arch/x86/pci/pcbios.c
10802 --- linux-2.6.27.4/arch/x86/pci/pcbios.c 2008-10-22 17:38:01.000000000 -0400
10803 +++ linux-2.6.27.4/arch/x86/pci/pcbios.c 2008-10-27 22:36:17.000000000 -0400
10804 @@ -57,50 +57,120 @@ union bios32 {
10806 unsigned long address;
10807 unsigned short segment;
10808 -} bios32_indirect = { 0, __KERNEL_CS };
10809 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
10812 * Returns the entry point for the given service, NULL on error
10815 -static unsigned long bios32_service(unsigned long service)
10816 +static unsigned long __devinit bios32_service(unsigned long service)
10818 unsigned char return_code; /* %al */
10819 unsigned long address; /* %ebx */
10820 unsigned long length; /* %ecx */
10821 unsigned long entry; /* %edx */
10822 unsigned long flags;
10823 + struct desc_struct d, *gdt;
10825 +#ifdef CONFIG_PAX_KERNEXEC
10826 + unsigned long cr0;
10829 local_irq_save(flags);
10830 - __asm__("lcall *(%%edi); cld"
10832 + gdt = get_cpu_gdt_table(smp_processor_id());
10834 +#ifdef CONFIG_PAX_KERNEXEC
10835 + pax_open_kernel(cr0);
10838 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
10839 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
10840 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
10841 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
10843 +#ifdef CONFIG_PAX_KERNEXEC
10844 + pax_close_kernel(cr0);
10847 + __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
10848 : "=a" (return_code),
10854 - "D" (&bios32_indirect));
10855 + "D" (&bios32_indirect),
10856 + "r"(__PCIBIOS_DS)
10859 +#ifdef CONFIG_PAX_KERNEXEC
10860 + pax_open_kernel(cr0);
10863 + gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
10864 + gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
10865 + gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
10866 + gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
10868 +#ifdef CONFIG_PAX_KERNEXEC
10869 + pax_close_kernel(cr0);
10872 local_irq_restore(flags);
10874 switch (return_code) {
10876 - return address + entry;
10877 - case 0x80: /* Not present */
10878 - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
10880 - default: /* Shouldn't happen */
10881 - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
10882 - service, return_code);
10885 + unsigned char flags;
10887 + printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
10888 + if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
10889 + printk(KERN_WARNING "bios32_service: not valid\n");
10892 + address = address + PAGE_OFFSET;
10893 + length += 16UL; /* some BIOSs underreport this... */
10895 + if (length >= 64*1024*1024) {
10896 + length >>= PAGE_SHIFT;
10900 +#ifdef CONFIG_PAX_KERNEXEC
10901 + pax_open_kernel(cr0);
10904 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
10905 + gdt = get_cpu_gdt_table(cpu);
10906 + pack_descriptor(&d, address, length, 0x9b, flags);
10907 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
10908 + pack_descriptor(&d, address, length, 0x93, flags);
10909 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
10912 +#ifdef CONFIG_PAX_KERNEXEC
10913 + pax_close_kernel(cr0);
10918 + case 0x80: /* Not present */
10919 + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
10921 + default: /* Shouldn't happen */
10922 + printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
10923 + service, return_code);
10929 unsigned long address;
10930 unsigned short segment;
10931 -} pci_indirect = { 0, __KERNEL_CS };
10932 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
10934 -static int pci_bios_present;
10935 +static int pci_bios_present __read_only;
10937 static int __devinit check_pcibios(void)
10939 @@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
10940 unsigned long flags, pcibios_entry;
10942 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
10943 - pci_indirect.address = pcibios_entry + PAGE_OFFSET;
10944 + pci_indirect.address = pcibios_entry;
10946 local_irq_save(flags);
10948 - "lcall *(%%edi); cld\n\t"
10949 + __asm__("movw %w6, %%ds\n\t"
10950 + "lcall *%%ss:(%%edi); cld\n\t"
10956 @@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
10959 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
10960 - "D" (&pci_indirect)
10961 + "D" (&pci_indirect),
10962 + "r" (__PCIBIOS_DS)
10964 local_irq_restore(flags);
10966 @@ -166,7 +239,10 @@ static int pci_bios_read(unsigned int se
10970 - __asm__("lcall *(%%esi); cld\n\t"
10971 + __asm__("movw %w6, %%ds\n\t"
10972 + "lcall *%%ss:(%%esi); cld\n\t"
10978 @@ -175,7 +251,8 @@ static int pci_bios_read(unsigned int se
10979 : "1" (PCIBIOS_READ_CONFIG_BYTE),
10982 - "S" (&pci_indirect));
10983 + "S" (&pci_indirect),
10984 + "r" (__PCIBIOS_DS));
10986 * Zero-extend the result beyond 8 bits, do not trust the
10987 * BIOS having done it:
10988 @@ -183,7 +260,10 @@ static int pci_bios_read(unsigned int se
10992 - __asm__("lcall *(%%esi); cld\n\t"
10993 + __asm__("movw %w6, %%ds\n\t"
10994 + "lcall *%%ss:(%%esi); cld\n\t"
11000 @@ -192,7 +272,8 @@ static int pci_bios_read(unsigned int se
11001 : "1" (PCIBIOS_READ_CONFIG_WORD),
11004 - "S" (&pci_indirect));
11005 + "S" (&pci_indirect),
11006 + "r" (__PCIBIOS_DS));
11008 * Zero-extend the result beyond 16 bits, do not trust the
11009 * BIOS having done it:
11010 @@ -200,7 +281,10 @@ static int pci_bios_read(unsigned int se
11014 - __asm__("lcall *(%%esi); cld\n\t"
11015 + __asm__("movw %w6, %%ds\n\t"
11016 + "lcall *%%ss:(%%esi); cld\n\t"
11022 @@ -209,7 +293,8 @@ static int pci_bios_read(unsigned int se
11023 : "1" (PCIBIOS_READ_CONFIG_DWORD),
11026 - "S" (&pci_indirect));
11027 + "S" (&pci_indirect),
11028 + "r" (__PCIBIOS_DS));
11032 @@ -232,7 +317,10 @@ static int pci_bios_write(unsigned int s
11036 - __asm__("lcall *(%%esi); cld\n\t"
11037 + __asm__("movw %w6, %%ds\n\t"
11038 + "lcall *%%ss:(%%esi); cld\n\t"
11044 @@ -241,10 +329,14 @@ static int pci_bios_write(unsigned int s
11048 - "S" (&pci_indirect));
11049 + "S" (&pci_indirect),
11050 + "r" (__PCIBIOS_DS));
11053 - __asm__("lcall *(%%esi); cld\n\t"
11054 + __asm__("movw %w6, %%ds\n\t"
11055 + "lcall *%%ss:(%%esi); cld\n\t"
11061 @@ -253,10 +345,14 @@ static int pci_bios_write(unsigned int s
11065 - "S" (&pci_indirect));
11066 + "S" (&pci_indirect),
11067 + "r" (__PCIBIOS_DS));
11070 - __asm__("lcall *(%%esi); cld\n\t"
11071 + __asm__("movw %w6, %%ds\n\t"
11072 + "lcall *%%ss:(%%esi); cld\n\t"
11078 @@ -265,7 +361,8 @@ static int pci_bios_write(unsigned int s
11082 - "S" (&pci_indirect));
11083 + "S" (&pci_indirect),
11084 + "r" (__PCIBIOS_DS));
11088 @@ -369,10 +466,13 @@ struct irq_routing_table * pcibios_get_i
11090 DBG("PCI: Fetching IRQ routing table... ");
11091 __asm__("push %%es\n\t"
11092 + "movw %w8, %%ds\n\t"
11095 - "lcall *(%%esi); cld\n\t"
11096 + "lcall *%%ss:(%%esi); cld\n\t"
11103 @@ -383,7 +483,8 @@ struct irq_routing_table * pcibios_get_i
11106 "S" (&pci_indirect),
11109 + "r" (__PCIBIOS_DS)
11111 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
11113 @@ -407,7 +508,10 @@ int pcibios_set_irq_routing(struct pci_d
11117 - __asm__("lcall *(%%esi); cld\n\t"
11118 + __asm__("movw %w5, %%ds\n\t"
11119 + "lcall *%%ss:(%%esi); cld\n\t"
11125 @@ -415,7 +519,8 @@ int pcibios_set_irq_routing(struct pci_d
11126 : "0" (PCIBIOS_SET_PCI_HW_INT),
11127 "b" ((dev->bus->number << 8) | dev->devfn),
11128 "c" ((irq << 8) | (pin + 10)),
11129 - "S" (&pci_indirect));
11130 + "S" (&pci_indirect),
11131 + "r" (__PCIBIOS_DS));
11132 return !(ret & 0xff00);
11134 EXPORT_SYMBOL(pcibios_set_irq_routing);
11135 diff -urNp linux-2.6.27.4/arch/x86/power/cpu_32.c linux-2.6.27.4/arch/x86/power/cpu_32.c
11136 --- linux-2.6.27.4/arch/x86/power/cpu_32.c 2008-10-22 17:38:01.000000000 -0400
11137 +++ linux-2.6.27.4/arch/x86/power/cpu_32.c 2008-10-27 22:36:17.000000000 -0400
11138 @@ -66,7 +66,7 @@ static void do_fpu_end(void)
11139 static void fix_processor_context(void)
11141 int cpu = smp_processor_id();
11142 - struct tss_struct *t = &per_cpu(init_tss, cpu);
11143 + struct tss_struct *t = init_tss + cpu;
11145 set_tss_desc(cpu, t); /*
11146 * This just modifies memory; should not be
11147 diff -urNp linux-2.6.27.4/arch/x86/power/cpu_64.c linux-2.6.27.4/arch/x86/power/cpu_64.c
11148 --- linux-2.6.27.4/arch/x86/power/cpu_64.c 2008-10-22 17:38:01.000000000 -0400
11149 +++ linux-2.6.27.4/arch/x86/power/cpu_64.c 2008-10-27 22:36:17.000000000 -0400
11150 @@ -136,7 +136,11 @@ void restore_processor_state(void)
11151 static void fix_processor_context(void)
11153 int cpu = smp_processor_id();
11154 - struct tss_struct *t = &per_cpu(init_tss, cpu);
11155 + struct tss_struct *t = init_tss + cpu;
11157 +#ifdef CONFIG_PAX_KERNEXEC
11158 + unsigned long cr0;
11162 * This just modifies memory; should not be necessary. But... This
11163 @@ -145,8 +149,16 @@ static void fix_processor_context(void)
11165 set_tss_desc(cpu, t);
11167 +#ifdef CONFIG_PAX_KERNEXEC
11168 + pax_open_kernel(cr0);
11171 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
11173 +#ifdef CONFIG_PAX_KERNEXEC
11174 + pax_close_kernel(cr0);
11177 syscall_init(); /* This sets MSR_*STAR and related */
11178 load_TR_desc(); /* This does ltr */
11179 load_LDT(¤t->active_mm->context); /* This does lldt */
11180 diff -urNp linux-2.6.27.4/arch/x86/vdso/vdso32-setup.c linux-2.6.27.4/arch/x86/vdso/vdso32-setup.c
11181 --- linux-2.6.27.4/arch/x86/vdso/vdso32-setup.c 2008-10-22 17:38:01.000000000 -0400
11182 +++ linux-2.6.27.4/arch/x86/vdso/vdso32-setup.c 2008-10-27 22:36:17.000000000 -0400
11183 @@ -226,7 +226,7 @@ static inline void map_compat_vdso(int m
11184 void enable_sep_cpu(void)
11186 int cpu = get_cpu();
11187 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
11188 + struct tss_struct *tss = init_tss + cpu;
11190 if (!boot_cpu_has(X86_FEATURE_SEP)) {
11192 @@ -249,7 +249,7 @@ static int __init gate_vma_init(void)
11193 gate_vma.vm_start = FIXADDR_USER_START;
11194 gate_vma.vm_end = FIXADDR_USER_END;
11195 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
11196 - gate_vma.vm_page_prot = __P101;
11197 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
11199 * Make sure the vDSO gets into every core dump.
11200 * Dumping its contents makes post-mortem fully interpretable later
11201 @@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct l
11203 addr = VDSO_HIGH_BASE;
11205 - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
11206 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
11207 if (IS_ERR_VALUE(addr)) {
11210 @@ -358,7 +358,7 @@ int arch_setup_additional_pages(struct l
11214 - current->mm->context.vdso = (void *)addr;
11215 + current->mm->context.vdso = addr;
11216 current_thread_info()->sysenter_return =
11217 VDSO32_SYMBOL(addr, SYSENTER_RETURN);
11219 @@ -384,7 +384,7 @@ static ctl_table abi_table2[] = {
11221 .proc_handler = proc_dointvec
11224 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11227 static ctl_table abi_root_table2[] = {
11228 @@ -394,7 +394,7 @@ static ctl_table abi_root_table2[] = {
11230 .child = abi_table2
11233 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11236 static __init int ia32_binfmt_init(void)
11237 @@ -409,8 +409,14 @@ __initcall(ia32_binfmt_init);
11239 const char *arch_vma_name(struct vm_area_struct *vma)
11241 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
11242 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
11245 +#ifdef CONFIG_PAX_SEGMEXEC
11246 + if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
11253 @@ -419,7 +425,7 @@ struct vm_area_struct *get_gate_vma(stru
11254 struct mm_struct *mm = tsk->mm;
11256 /* Check to see if this task was created in compat vdso mode */
11257 - if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
11258 + if (mm && mm->context.vdso == VDSO_HIGH_BASE)
11262 diff -urNp linux-2.6.27.4/arch/x86/vdso/vma.c linux-2.6.27.4/arch/x86/vdso/vma.c
11263 --- linux-2.6.27.4/arch/x86/vdso/vma.c 2008-10-22 17:38:01.000000000 -0400
11264 +++ linux-2.6.27.4/arch/x86/vdso/vma.c 2008-10-27 22:36:17.000000000 -0400
11265 @@ -123,7 +123,7 @@ int arch_setup_additional_pages(struct l
11269 - current->mm->context.vdso = (void *)addr;
11270 + current->mm->context.vdso = addr;
11272 up_write(&mm->mmap_sem);
11274 diff -urNp linux-2.6.27.4/arch/x86/xen/enlighten.c linux-2.6.27.4/arch/x86/xen/enlighten.c
11275 --- linux-2.6.27.4/arch/x86/xen/enlighten.c 2008-10-22 17:38:01.000000000 -0400
11276 +++ linux-2.6.27.4/arch/x86/xen/enlighten.c 2008-10-27 22:36:17.000000000 -0400
11277 @@ -343,7 +343,7 @@ static void xen_set_ldt(const void *addr
11278 static void xen_load_gdt(const struct desc_ptr *dtr)
11280 unsigned long *frames;
11281 - unsigned long va = dtr->address;
11282 + unsigned long va = (unsigned long)dtr->address;
11283 unsigned int size = dtr->size + 1;
11284 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
11286 @@ -358,7 +358,7 @@ static void xen_load_gdt(const struct de
11287 mcs = xen_mc_entry(sizeof(*frames) * pages);
11290 - for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
11291 + for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
11292 frames[f] = virt_to_mfn(va);
11293 make_lowmem_page_readonly((void *)va);
11295 @@ -467,7 +467,7 @@ static void xen_write_idt_entry(gate_des
11299 - start = __get_cpu_var(idt_desc).address;
11300 + start = (unsigned long)__get_cpu_var(idt_desc).address;
11301 end = start + __get_cpu_var(idt_desc).size + 1;
11304 @@ -1574,6 +1574,8 @@ static __init pgd_t *xen_setup_kernel_pa
11305 convert_pfn_mfn(init_level4_pgt);
11306 convert_pfn_mfn(level3_ident_pgt);
11307 convert_pfn_mfn(level3_kernel_pgt);
11308 + convert_pfn_mfn(level3_vmalloc_pgt);
11309 + convert_pfn_mfn(level3_vmemmap_pgt);
11311 l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
11312 l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
11313 @@ -1592,9 +1594,12 @@ static __init pgd_t *xen_setup_kernel_pa
11314 set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
11315 set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
11316 set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
11317 + set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
11318 + set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
11319 set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
11320 set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
11321 set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
11322 + set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
11324 /* Pin down new L4 */
11325 pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
11326 diff -urNp linux-2.6.27.4/arch/x86/xen/smp.c linux-2.6.27.4/arch/x86/xen/smp.c
11327 --- linux-2.6.27.4/arch/x86/xen/smp.c 2008-10-22 17:38:01.000000000 -0400
11328 +++ linux-2.6.27.4/arch/x86/xen/smp.c 2008-10-27 22:36:17.000000000 -0400
11329 @@ -173,7 +173,7 @@ static void __init xen_smp_prepare_boot_
11331 /* We've switched to the "real" per-cpu gdt, so make sure the
11332 old memory can be recycled */
11333 - make_lowmem_page_readwrite(&per_cpu_var(gdt_page));
11334 + make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
11336 xen_setup_vcpu_info_placement();
11338 @@ -232,8 +232,8 @@ cpu_initialize_context(unsigned int cpu,
11339 gdt = get_cpu_gdt_table(cpu);
11341 ctxt->flags = VGCF_IN_KERNEL;
11342 - ctxt->user_regs.ds = __USER_DS;
11343 - ctxt->user_regs.es = __USER_DS;
11344 + ctxt->user_regs.ds = __KERNEL_DS;
11345 + ctxt->user_regs.es = __KERNEL_DS;
11346 ctxt->user_regs.ss = __KERNEL_DS;
11347 #ifdef CONFIG_X86_32
11348 ctxt->user_regs.fs = __KERNEL_PERCPU;
11349 diff -urNp linux-2.6.27.4/crypto/async_tx/async_tx.c linux-2.6.27.4/crypto/async_tx/async_tx.c
11350 --- linux-2.6.27.4/crypto/async_tx/async_tx.c 2008-10-22 17:38:01.000000000 -0400
11351 +++ linux-2.6.27.4/crypto/async_tx/async_tx.c 2008-10-27 22:36:17.000000000 -0400
11352 @@ -358,8 +358,8 @@ async_tx_init(void)
11354 printk(KERN_ERR "async_tx: initialization failure\n");
11356 - while (--cap >= 0)
11357 - free_percpu(channel_table[cap]);
11359 + free_percpu(channel_table[--cap]);
11363 diff -urNp linux-2.6.27.4/crypto/lrw.c linux-2.6.27.4/crypto/lrw.c
11364 --- linux-2.6.27.4/crypto/lrw.c 2008-10-22 17:38:01.000000000 -0400
11365 +++ linux-2.6.27.4/crypto/lrw.c 2008-10-27 22:36:17.000000000 -0400
11366 @@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
11367 struct priv *ctx = crypto_tfm_ctx(parent);
11368 struct crypto_cipher *child = ctx->child;
11370 - be128 tmp = { 0 };
11371 + be128 tmp = { 0, 0 };
11372 int bsize = crypto_cipher_blocksize(child);
11374 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
11375 diff -urNp linux-2.6.27.4/Documentation/dontdiff linux-2.6.27.4/Documentation/dontdiff
11376 --- linux-2.6.27.4/Documentation/dontdiff 2008-10-22 17:38:01.000000000 -0400
11377 +++ linux-2.6.27.4/Documentation/dontdiff 2008-10-27 22:36:16.000000000 -0400
11386 @@ -53,9 +54,14 @@ COPYING
11401 @@ -74,6 +80,7 @@ bbootsect
11409 @@ -90,6 +97,7 @@ config_data.gz*
11411 consolemap_deftbl.c*
11417 @@ -138,6 +146,7 @@ miboot*
11425 @@ -179,16 +188,21 @@ times.h*
11450 diff -urNp linux-2.6.27.4/drivers/acpi/blacklist.c linux-2.6.27.4/drivers/acpi/blacklist.c
11451 --- linux-2.6.27.4/drivers/acpi/blacklist.c 2008-10-22 17:38:01.000000000 -0400
11452 +++ linux-2.6.27.4/drivers/acpi/blacklist.c 2008-10-27 22:36:17.000000000 -0400
11453 @@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
11454 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
11455 "Incorrect _ADR", 1},
11458 + {"", "", 0, 0, 0, all_versions, 0}
11461 #if CONFIG_ACPI_BLACKLIST_YEAR
11462 diff -urNp linux-2.6.27.4/drivers/acpi/osl.c linux-2.6.27.4/drivers/acpi/osl.c
11463 --- linux-2.6.27.4/drivers/acpi/osl.c 2008-10-22 17:38:01.000000000 -0400
11464 +++ linux-2.6.27.4/drivers/acpi/osl.c 2008-10-27 22:36:17.000000000 -0400
11465 @@ -494,6 +494,8 @@ acpi_os_read_memory(acpi_physical_addres
11466 void __iomem *virt_addr;
11468 virt_addr = ioremap(phys_addr, width);
11470 + return AE_NO_MEMORY;
11474 @@ -522,6 +524,8 @@ acpi_os_write_memory(acpi_physical_addre
11475 void __iomem *virt_addr;
11477 virt_addr = ioremap(phys_addr, width);
11479 + return AE_NO_MEMORY;
11483 diff -urNp linux-2.6.27.4/drivers/acpi/processor_core.c linux-2.6.27.4/drivers/acpi/processor_core.c
11484 --- linux-2.6.27.4/drivers/acpi/processor_core.c 2008-10-22 17:38:01.000000000 -0400
11485 +++ linux-2.6.27.4/drivers/acpi/processor_core.c 2008-10-27 22:36:17.000000000 -0400
11486 @@ -667,7 +667,7 @@ static int __cpuinit acpi_processor_star
11490 - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
11491 + BUG_ON(pr->id >= nr_cpu_ids);
11495 diff -urNp linux-2.6.27.4/drivers/acpi/processor_idle.c linux-2.6.27.4/drivers/acpi/processor_idle.c
11496 --- linux-2.6.27.4/drivers/acpi/processor_idle.c 2008-10-22 17:38:01.000000000 -0400
11497 +++ linux-2.6.27.4/drivers/acpi/processor_idle.c 2008-10-27 22:36:17.000000000 -0400
11498 @@ -182,7 +182,7 @@ static struct dmi_system_id __cpuinitdat
11499 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
11500 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
11503 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
11506 static inline u32 ticks_elapsed(u32 t1, u32 t2)
11507 diff -urNp linux-2.6.27.4/drivers/acpi/tables/tbfadt.c linux-2.6.27.4/drivers/acpi/tables/tbfadt.c
11508 --- linux-2.6.27.4/drivers/acpi/tables/tbfadt.c 2008-10-22 17:38:01.000000000 -0400
11509 +++ linux-2.6.27.4/drivers/acpi/tables/tbfadt.c 2008-10-27 22:36:17.000000000 -0400
11511 ACPI_MODULE_NAME("tbfadt")
11513 /* Local prototypes */
11514 -static void inline
11515 +static inline void
11516 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
11517 u8 bit_width, u64 address);
11519 @@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
11521 ******************************************************************************/
11523 -static void inline
11524 +static inline void
11525 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
11526 u8 bit_width, u64 address)
11528 diff -urNp linux-2.6.27.4/drivers/ata/ahci.c linux-2.6.27.4/drivers/ata/ahci.c
11529 --- linux-2.6.27.4/drivers/ata/ahci.c 2008-10-22 17:38:01.000000000 -0400
11530 +++ linux-2.6.27.4/drivers/ata/ahci.c 2008-10-27 22:36:17.000000000 -0400
11531 @@ -591,7 +591,7 @@ static const struct pci_device_id ahci_p
11532 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
11533 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
11535 - { } /* terminate list */
11536 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
11540 diff -urNp linux-2.6.27.4/drivers/ata/ata_piix.c linux-2.6.27.4/drivers/ata/ata_piix.c
11541 --- linux-2.6.27.4/drivers/ata/ata_piix.c 2008-10-22 17:38:01.000000000 -0400
11542 +++ linux-2.6.27.4/drivers/ata/ata_piix.c 2008-10-27 22:36:17.000000000 -0400
11543 @@ -284,7 +284,7 @@ static const struct pci_device_id piix_p
11544 /* SATA Controller IDE (PCH) */
11545 { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
11547 - { } /* terminate list */
11548 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
11551 static struct pci_driver piix_pci_driver = {
11552 @@ -587,7 +587,7 @@ static const struct ich_laptop ich_lapto
11553 { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
11554 { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
11561 @@ -1143,7 +1143,7 @@ static int piix_broken_suspend(void)
11565 - { } /* terminate list */
11566 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
11568 static const char *oemstrs[] = {
11570 diff -urNp linux-2.6.27.4/drivers/ata/libata-core.c linux-2.6.27.4/drivers/ata/libata-core.c
11571 --- linux-2.6.27.4/drivers/ata/libata-core.c 2008-10-22 17:38:01.000000000 -0400
11572 +++ linux-2.6.27.4/drivers/ata/libata-core.c 2008-10-27 22:36:17.000000000 -0400
11573 @@ -746,7 +746,7 @@ static const struct ata_xfer_ent {
11574 { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
11575 { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
11576 { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
11582 @@ -2910,7 +2910,7 @@ static const struct ata_timing ata_timin
11583 { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
11584 { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
11587 + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
11590 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
11591 @@ -3999,7 +3999,7 @@ static const struct ata_blacklist_entry
11592 { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
11596 + { NULL, NULL, 0 }
11599 static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
11600 diff -urNp linux-2.6.27.4/drivers/char/agp/frontend.c linux-2.6.27.4/drivers/char/agp/frontend.c
11601 --- linux-2.6.27.4/drivers/char/agp/frontend.c 2008-10-22 17:38:01.000000000 -0400
11602 +++ linux-2.6.27.4/drivers/char/agp/frontend.c 2008-10-27 22:36:17.000000000 -0400
11603 @@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag
11604 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
11607 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
11608 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
11611 client = agp_find_client_by_pid(reserve.pid);
11612 diff -urNp linux-2.6.27.4/drivers/char/agp/intel-agp.c linux-2.6.27.4/drivers/char/agp/intel-agp.c
11613 --- linux-2.6.27.4/drivers/char/agp/intel-agp.c 2008-10-22 17:38:01.000000000 -0400
11614 +++ linux-2.6.27.4/drivers/char/agp/intel-agp.c 2008-10-27 22:36:17.000000000 -0400
11615 @@ -2330,7 +2330,7 @@ static struct pci_device_id agp_intel_pc
11616 ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
11617 ID(PCI_DEVICE_ID_INTEL_Q45_HB),
11618 ID(PCI_DEVICE_ID_INTEL_G45_HB),
11620 + { 0, 0, 0, 0, 0, 0, 0 }
11623 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
11624 diff -urNp linux-2.6.27.4/drivers/char/hpet.c linux-2.6.27.4/drivers/char/hpet.c
11625 --- linux-2.6.27.4/drivers/char/hpet.c 2008-10-22 17:38:01.000000000 -0400
11626 +++ linux-2.6.27.4/drivers/char/hpet.c 2008-10-27 22:36:17.000000000 -0400
11627 @@ -959,7 +959,7 @@ static struct acpi_driver hpet_acpi_driv
11631 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
11632 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
11634 static int __init hpet_init(void)
11636 diff -urNp linux-2.6.27.4/drivers/char/keyboard.c linux-2.6.27.4/drivers/char/keyboard.c
11637 --- linux-2.6.27.4/drivers/char/keyboard.c 2008-10-22 17:38:01.000000000 -0400
11638 +++ linux-2.6.27.4/drivers/char/keyboard.c 2008-10-27 22:36:17.000000000 -0400
11639 @@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u
11640 kbd->kbdmode == VC_MEDIUMRAW) &&
11641 value != KVAL(K_SAK))
11642 return; /* SAK is allowed even in raw mode */
11644 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
11646 + void *func = fn_handler[value];
11647 + if (func == fn_show_state || func == fn_show_ptregs ||
11648 + func == fn_show_mem)
11653 fn_handler[value](vc);
11656 @@ -1388,7 +1398,7 @@ static const struct input_device_id kbd_
11657 .evbit = { BIT_MASK(EV_SND) },
11660 - { }, /* Terminating entry */
11661 + { 0 }, /* Terminating entry */
11664 MODULE_DEVICE_TABLE(input, kbd_ids);
11665 diff -urNp linux-2.6.27.4/drivers/char/mem.c linux-2.6.27.4/drivers/char/mem.c
11666 --- linux-2.6.27.4/drivers/char/mem.c 2008-10-22 17:38:01.000000000 -0400
11667 +++ linux-2.6.27.4/drivers/char/mem.c 2008-10-25 12:36:04.000000000 -0400
11669 #include <linux/splice.h>
11670 #include <linux/pfn.h>
11671 #include <linux/smp_lock.h>
11672 +#include <linux/grsecurity.h>
11674 #include <asm/uaccess.h>
11675 #include <asm/io.h>
11677 # include <linux/efi.h>
11680 +#ifdef CONFIG_GRKERNSEC
11681 +extern struct file_operations grsec_fops;
11685 * Architectures vary in how they handle caching for addresses
11686 * outside of main memory.
11687 @@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f
11688 if (!valid_phys_addr_range(p, count))
11691 +#ifdef CONFIG_GRKERNSEC_KMEM
11692 + gr_handle_mem_write();
11698 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
11699 @@ -350,6 +360,11 @@ static int mmap_mem(struct file * file,
11700 &vma->vm_page_prot))
11703 +#ifdef CONFIG_GRKERNSEC_KMEM
11704 + if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
11708 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
11710 vma->vm_page_prot);
11711 @@ -588,6 +603,11 @@ static ssize_t write_kmem(struct file *
11713 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
11715 +#ifdef CONFIG_GRKERNSEC_KMEM
11716 + gr_handle_kmem_write();
11720 if (p < (unsigned long) high_memory) {
11723 @@ -791,6 +811,16 @@ static loff_t memory_lseek(struct file *
11725 static int open_port(struct inode * inode, struct file * filp)
11727 +#ifdef CONFIG_GRKERNSEC_KMEM
11728 + gr_handle_open_port();
11732 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
11735 +static int open_mem(struct inode * inode, struct file * filp)
11737 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
11740 @@ -798,7 +828,6 @@ static int open_port(struct inode * inod
11741 #define full_lseek null_lseek
11742 #define write_zero write_null
11743 #define read_full read_zero
11744 -#define open_mem open_port
11745 #define open_kmem open_mem
11746 #define open_oldmem open_mem
11748 @@ -938,6 +967,11 @@ static int memory_open(struct inode * in
11749 filp->f_op = &oldmem_fops;
11752 +#ifdef CONFIG_GRKERNSEC
11754 + filp->f_op = &grsec_fops;
11760 @@ -974,6 +1008,9 @@ static const struct {
11761 #ifdef CONFIG_CRASH_DUMP
11762 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
11764 +#ifdef CONFIG_GRKERNSEC
11765 + {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
11769 static struct class *mem_class;
11770 diff -urNp linux-2.6.27.4/drivers/char/nvram.c linux-2.6.27.4/drivers/char/nvram.c
11771 --- linux-2.6.27.4/drivers/char/nvram.c 2008-10-22 17:38:01.000000000 -0400
11772 +++ linux-2.6.27.4/drivers/char/nvram.c 2008-10-27 22:36:17.000000000 -0400
11773 @@ -433,7 +433,10 @@ static const struct file_operations nvra
11774 static struct miscdevice nvram_dev = {
11785 diff -urNp linux-2.6.27.4/drivers/char/random.c linux-2.6.27.4/drivers/char/random.c
11786 --- linux-2.6.27.4/drivers/char/random.c 2008-10-22 17:38:01.000000000 -0400
11787 +++ linux-2.6.27.4/drivers/char/random.c 2008-10-27 22:36:17.000000000 -0400
11788 @@ -249,8 +249,13 @@
11790 * Configuration information
11792 +#ifdef CONFIG_GRKERNSEC_RANDNET
11793 +#define INPUT_POOL_WORDS 512
11794 +#define OUTPUT_POOL_WORDS 128
11796 #define INPUT_POOL_WORDS 128
11797 #define OUTPUT_POOL_WORDS 32
11799 #define SEC_XFER_SIZE 512
11802 @@ -287,10 +292,17 @@ static struct poolinfo {
11804 int tap1, tap2, tap3, tap4, tap5;
11805 } poolinfo_table[] = {
11806 +#ifdef CONFIG_GRKERNSEC_RANDNET
11807 + /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
11808 + { 512, 411, 308, 208, 104, 1 },
11809 + /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
11810 + { 128, 103, 76, 51, 25, 1 },
11812 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
11813 { 128, 103, 76, 51, 25, 1 },
11814 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
11815 { 32, 26, 20, 14, 7, 1 },
11818 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
11819 { 2048, 1638, 1231, 819, 411, 1 },
11820 @@ -1166,7 +1178,7 @@ EXPORT_SYMBOL(generate_random_uuid);
11821 #include <linux/sysctl.h>
11823 static int min_read_thresh = 8, min_write_thresh;
11824 -static int max_read_thresh = INPUT_POOL_WORDS * 32;
11825 +static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
11826 static int max_write_thresh = INPUT_POOL_WORDS * 32;
11827 static char sysctl_bootid[16];
11829 diff -urNp linux-2.6.27.4/drivers/char/tpm/tpm.c linux-2.6.27.4/drivers/char/tpm/tpm.c
11830 --- linux-2.6.27.4/drivers/char/tpm/tpm.c 2008-10-22 17:38:01.000000000 -0400
11831 +++ linux-2.6.27.4/drivers/char/tpm/tpm.c 2008-10-25 12:03:06.000000000 -0400
11832 @@ -1037,7 +1037,7 @@ ssize_t tpm_write(struct file *file, con
11834 mutex_lock(&chip->buffer_mutex);
11836 - if (in_size > TPM_BUFSIZE)
11837 + if (in_size > (unsigned int)TPM_BUFSIZE)
11838 in_size = TPM_BUFSIZE;
11841 diff -urNp linux-2.6.27.4/drivers/char/vt_ioctl.c linux-2.6.27.4/drivers/char/vt_ioctl.c
11842 --- linux-2.6.27.4/drivers/char/vt_ioctl.c 2008-10-22 17:38:01.000000000 -0400
11843 +++ linux-2.6.27.4/drivers/char/vt_ioctl.c 2008-10-25 12:03:06.000000000 -0400
11844 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
11849 +#ifdef CONFIG_GRKERNSEC
11850 + if (!capable(CAP_SYS_TTY_CONFIG))
11854 if (!i && v == K_NOSUCHMAP) {
11855 /* deallocate map */
11856 key_map = key_maps[s];
11857 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
11861 +#ifdef CONFIG_GRKERNSEC
11862 + if (!capable(CAP_SYS_TTY_CONFIG)) {
11869 first_free = funcbufptr + (funcbufsize - funcbufleft);
11870 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
11871 diff -urNp linux-2.6.27.4/drivers/edac/edac_core.h linux-2.6.27.4/drivers/edac/edac_core.h
11872 --- linux-2.6.27.4/drivers/edac/edac_core.h 2008-10-22 17:38:01.000000000 -0400
11873 +++ linux-2.6.27.4/drivers/edac/edac_core.h 2008-10-27 22:36:17.000000000 -0400
11874 @@ -85,11 +85,11 @@ extern int edac_debug_level;
11876 #else /* !CONFIG_EDAC_DEBUG */
11878 -#define debugf0( ... )
11879 -#define debugf1( ... )
11880 -#define debugf2( ... )
11881 -#define debugf3( ... )
11882 -#define debugf4( ... )
11883 +#define debugf0( ... ) do {} while (0)
11884 +#define debugf1( ... ) do {} while (0)
11885 +#define debugf2( ... ) do {} while (0)
11886 +#define debugf3( ... ) do {} while (0)
11887 +#define debugf4( ... ) do {} while (0)
11889 #endif /* !CONFIG_EDAC_DEBUG */
11891 diff -urNp linux-2.6.27.4/drivers/firmware/dmi_scan.c linux-2.6.27.4/drivers/firmware/dmi_scan.c
11892 --- linux-2.6.27.4/drivers/firmware/dmi_scan.c 2008-10-22 17:38:01.000000000 -0400
11893 +++ linux-2.6.27.4/drivers/firmware/dmi_scan.c 2008-10-27 22:36:17.000000000 -0400
11894 @@ -384,11 +384,6 @@ void __init dmi_scan_machine(void)
11899 - * no iounmap() for that ioremap(); it would be a no-op, but
11900 - * it's so early in setup that sucker gets confused into doing
11901 - * what it shouldn't if we actually call it.
11903 p = dmi_ioremap(0xF0000, 0x10000);
11906 diff -urNp linux-2.6.27.4/drivers/hwmon/fscpos.c linux-2.6.27.4/drivers/hwmon/fscpos.c
11907 --- linux-2.6.27.4/drivers/hwmon/fscpos.c 2008-10-22 17:38:01.000000000 -0400
11908 +++ linux-2.6.27.4/drivers/hwmon/fscpos.c 2008-10-27 22:36:17.000000000 -0400
11909 @@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client
11910 unsigned long v = simple_strtoul(buf, NULL, 10);
11912 /* Range: 0..255 */
11913 - if (v < 0) v = 0;
11914 if (v > 255) v = 255;
11916 mutex_lock(&data->update_lock);
11917 diff -urNp linux-2.6.27.4/drivers/hwmon/k8temp.c linux-2.6.27.4/drivers/hwmon/k8temp.c
11918 --- linux-2.6.27.4/drivers/hwmon/k8temp.c 2008-10-22 17:38:01.000000000 -0400
11919 +++ linux-2.6.27.4/drivers/hwmon/k8temp.c 2008-10-27 22:36:17.000000000 -0400
11920 @@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
11922 static struct pci_device_id k8temp_ids[] = {
11923 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
11925 + { 0, 0, 0, 0, 0, 0, 0 },
11928 MODULE_DEVICE_TABLE(pci, k8temp_ids);
11929 diff -urNp linux-2.6.27.4/drivers/hwmon/sis5595.c linux-2.6.27.4/drivers/hwmon/sis5595.c
11930 --- linux-2.6.27.4/drivers/hwmon/sis5595.c 2008-10-22 17:38:01.000000000 -0400
11931 +++ linux-2.6.27.4/drivers/hwmon/sis5595.c 2008-10-27 22:36:17.000000000 -0400
11932 @@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
11934 static struct pci_device_id sis5595_pci_ids[] = {
11935 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
11937 + { 0, 0, 0, 0, 0, 0, 0 }
11940 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
11941 diff -urNp linux-2.6.27.4/drivers/hwmon/via686a.c linux-2.6.27.4/drivers/hwmon/via686a.c
11942 --- linux-2.6.27.4/drivers/hwmon/via686a.c 2008-10-22 17:38:01.000000000 -0400
11943 +++ linux-2.6.27.4/drivers/hwmon/via686a.c 2008-10-27 22:36:17.000000000 -0400
11944 @@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
11946 static struct pci_device_id via686a_pci_ids[] = {
11947 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
11949 + { 0, 0, 0, 0, 0, 0, 0 }
11952 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
11953 diff -urNp linux-2.6.27.4/drivers/hwmon/vt8231.c linux-2.6.27.4/drivers/hwmon/vt8231.c
11954 --- linux-2.6.27.4/drivers/hwmon/vt8231.c 2008-10-22 17:38:01.000000000 -0400
11955 +++ linux-2.6.27.4/drivers/hwmon/vt8231.c 2008-10-27 22:36:17.000000000 -0400
11956 @@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
11958 static struct pci_device_id vt8231_pci_ids[] = {
11959 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
11961 + { 0, 0, 0, 0, 0, 0, 0 }
11964 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
11965 diff -urNp linux-2.6.27.4/drivers/hwmon/w83791d.c linux-2.6.27.4/drivers/hwmon/w83791d.c
11966 --- linux-2.6.27.4/drivers/hwmon/w83791d.c 2008-10-22 17:38:01.000000000 -0400
11967 +++ linux-2.6.27.4/drivers/hwmon/w83791d.c 2008-10-27 22:36:17.000000000 -0400
11968 @@ -289,8 +289,8 @@ static int w83791d_detect(struct i2c_cli
11969 struct i2c_board_info *info);
11970 static int w83791d_remove(struct i2c_client *client);
11972 -static int w83791d_read(struct i2c_client *client, u8 register);
11973 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
11974 +static int w83791d_read(struct i2c_client *client, u8 reg);
11975 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
11976 static struct w83791d_data *w83791d_update_device(struct device *dev);
11979 diff -urNp linux-2.6.27.4/drivers/i2c/busses/i2c-i801.c linux-2.6.27.4/drivers/i2c/busses/i2c-i801.c
11980 --- linux-2.6.27.4/drivers/i2c/busses/i2c-i801.c 2008-10-22 17:38:01.000000000 -0400
11981 +++ linux-2.6.27.4/drivers/i2c/busses/i2c-i801.c 2008-10-27 22:36:17.000000000 -0400
11982 @@ -576,7 +576,7 @@ static struct pci_device_id i801_ids[] =
11983 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
11984 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
11985 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
11987 + { 0, 0, 0, 0, 0, 0, 0 }
11990 MODULE_DEVICE_TABLE (pci, i801_ids);
11991 diff -urNp linux-2.6.27.4/drivers/i2c/busses/i2c-piix4.c linux-2.6.27.4/drivers/i2c/busses/i2c-piix4.c
11992 --- linux-2.6.27.4/drivers/i2c/busses/i2c-piix4.c 2008-10-22 17:38:01.000000000 -0400
11993 +++ linux-2.6.27.4/drivers/i2c/busses/i2c-piix4.c 2008-10-27 22:36:17.000000000 -0400
11994 @@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat
11996 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
11999 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
12002 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
12003 @@ -424,7 +424,7 @@ static struct pci_device_id piix4_ids[]
12004 PCI_DEVICE_ID_SERVERWORKS_CSB6) },
12005 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
12006 PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
12008 + { 0, 0, 0, 0, 0, 0, 0 }
12011 MODULE_DEVICE_TABLE (pci, piix4_ids);
12012 diff -urNp linux-2.6.27.4/drivers/i2c/busses/i2c-sis630.c linux-2.6.27.4/drivers/i2c/busses/i2c-sis630.c
12013 --- linux-2.6.27.4/drivers/i2c/busses/i2c-sis630.c 2008-10-22 17:38:01.000000000 -0400
12014 +++ linux-2.6.27.4/drivers/i2c/busses/i2c-sis630.c 2008-10-27 22:36:17.000000000 -0400
12015 @@ -472,7 +472,7 @@ static struct i2c_adapter sis630_adapter
12016 static struct pci_device_id sis630_ids[] __devinitdata = {
12017 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12018 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
12020 + { 0, 0, 0, 0, 0, 0, 0 }
12023 MODULE_DEVICE_TABLE (pci, sis630_ids);
12024 diff -urNp linux-2.6.27.4/drivers/i2c/busses/i2c-sis96x.c linux-2.6.27.4/drivers/i2c/busses/i2c-sis96x.c
12025 --- linux-2.6.27.4/drivers/i2c/busses/i2c-sis96x.c 2008-10-22 17:38:01.000000000 -0400
12026 +++ linux-2.6.27.4/drivers/i2c/busses/i2c-sis96x.c 2008-10-27 22:36:17.000000000 -0400
12027 @@ -248,7 +248,7 @@ static struct i2c_adapter sis96x_adapter
12029 static struct pci_device_id sis96x_ids[] = {
12030 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
12032 + { 0, 0, 0, 0, 0, 0, 0 }
12035 MODULE_DEVICE_TABLE (pci, sis96x_ids);
12036 diff -urNp linux-2.6.27.4/drivers/ieee1394/dv1394.c linux-2.6.27.4/drivers/ieee1394/dv1394.c
12037 --- linux-2.6.27.4/drivers/ieee1394/dv1394.c 2008-10-22 17:38:01.000000000 -0400
12038 +++ linux-2.6.27.4/drivers/ieee1394/dv1394.c 2008-10-27 22:36:17.000000000 -0400
12039 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
12040 based upon DIF section and sequence
12043 -static void inline
12044 +static inline void
12045 frame_put_packet (struct frame *f, struct packet *p)
12047 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
12048 @@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
12049 /* default SYT offset is 3 cycles */
12050 init->syt_offset = 3;
12052 - if ( (init->channel > 63) || (init->channel < 0) )
12053 + if (init->channel > 63)
12054 init->channel = 63;
12056 chan_mask = (u64)1 << init->channel;
12057 @@ -2174,7 +2174,7 @@ static struct ieee1394_device_id dv1394_
12058 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
12059 .version = AVC_SW_VERSION_ENTRY & 0xffffff
12062 + { 0, 0, 0, 0, 0, 0 }
12065 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
12066 diff -urNp linux-2.6.27.4/drivers/ieee1394/eth1394.c linux-2.6.27.4/drivers/ieee1394/eth1394.c
12067 --- linux-2.6.27.4/drivers/ieee1394/eth1394.c 2008-10-22 17:38:01.000000000 -0400
12068 +++ linux-2.6.27.4/drivers/ieee1394/eth1394.c 2008-10-27 22:36:17.000000000 -0400
12069 @@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
12070 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
12071 .version = ETHER1394_GASP_VERSION,
12074 + { 0, 0, 0, 0, 0, 0 }
12077 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
12078 diff -urNp linux-2.6.27.4/drivers/ieee1394/hosts.c linux-2.6.27.4/drivers/ieee1394/hosts.c
12079 --- linux-2.6.27.4/drivers/ieee1394/hosts.c 2008-10-22 17:38:01.000000000 -0400
12080 +++ linux-2.6.27.4/drivers/ieee1394/hosts.c 2008-10-27 22:36:17.000000000 -0400
12081 @@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
12084 static struct hpsb_host_driver dummy_driver = {
12086 .transmit_packet = dummy_transmit_packet,
12087 .devctl = dummy_devctl,
12088 .isoctl = dummy_isoctl
12089 diff -urNp linux-2.6.27.4/drivers/ieee1394/ohci1394.c linux-2.6.27.4/drivers/ieee1394/ohci1394.c
12090 --- linux-2.6.27.4/drivers/ieee1394/ohci1394.c 2008-10-22 17:38:01.000000000 -0400
12091 +++ linux-2.6.27.4/drivers/ieee1394/ohci1394.c 2008-10-27 22:36:17.000000000 -0400
12092 @@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
12093 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
12095 /* Module Parameters */
12096 -static int phys_dma = 1;
12097 +static int phys_dma;
12098 module_param(phys_dma, int, 0444);
12099 -MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
12100 +MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
12102 static void dma_trm_tasklet(unsigned long data);
12103 static void dma_trm_reset(struct dma_trm_ctx *d);
12104 @@ -3437,7 +3437,7 @@ static struct pci_device_id ohci1394_pci
12105 .subvendor = PCI_ANY_ID,
12106 .subdevice = PCI_ANY_ID,
12109 + { 0, 0, 0, 0, 0, 0, 0 },
12112 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
12113 diff -urNp linux-2.6.27.4/drivers/ieee1394/raw1394.c linux-2.6.27.4/drivers/ieee1394/raw1394.c
12114 --- linux-2.6.27.4/drivers/ieee1394/raw1394.c 2008-10-22 17:38:01.000000000 -0400
12115 +++ linux-2.6.27.4/drivers/ieee1394/raw1394.c 2008-10-27 22:36:17.000000000 -0400
12116 @@ -2968,7 +2968,7 @@ static struct ieee1394_device_id raw1394
12117 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12118 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12119 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
12121 + { 0, 0, 0, 0, 0, 0 }
12124 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
12125 diff -urNp linux-2.6.27.4/drivers/ieee1394/sbp2.c linux-2.6.27.4/drivers/ieee1394/sbp2.c
12126 --- linux-2.6.27.4/drivers/ieee1394/sbp2.c 2008-10-22 17:38:01.000000000 -0400
12127 +++ linux-2.6.27.4/drivers/ieee1394/sbp2.c 2008-10-27 22:36:17.000000000 -0400
12128 @@ -290,7 +290,7 @@ static struct ieee1394_device_id sbp2_id
12129 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12130 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
12131 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
12133 + { 0, 0, 0, 0, 0, 0 }
12135 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
12137 @@ -2130,7 +2130,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
12138 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
12139 MODULE_LICENSE("GPL");
12141 -static int sbp2_module_init(void)
12142 +static int __init sbp2_module_init(void)
12146 diff -urNp linux-2.6.27.4/drivers/ieee1394/video1394.c linux-2.6.27.4/drivers/ieee1394/video1394.c
12147 --- linux-2.6.27.4/drivers/ieee1394/video1394.c 2008-10-22 17:38:01.000000000 -0400
12148 +++ linux-2.6.27.4/drivers/ieee1394/video1394.c 2008-10-27 22:36:17.000000000 -0400
12149 @@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
12150 if (unlikely(d == NULL))
12153 - if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
12154 + if (unlikely(v.buffer>=d->num_desc - 1)) {
12155 PRINT(KERN_ERR, ohci->host->id,
12156 "Buffer %d out of range",v.buffer);
12158 @@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
12159 if (unlikely(d == NULL))
12162 - if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
12163 + if (unlikely(v.buffer>d->num_desc - 1)) {
12164 PRINT(KERN_ERR, ohci->host->id,
12165 "Buffer %d out of range",v.buffer);
12167 @@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
12168 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12169 if (d == NULL) return -EFAULT;
12171 - if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
12172 + if (v.buffer>=d->num_desc - 1) {
12173 PRINT(KERN_ERR, ohci->host->id,
12174 "Buffer %d out of range",v.buffer);
12176 @@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
12177 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12178 if (d == NULL) return -EFAULT;
12180 - if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
12181 + if (v.buffer>=d->num_desc-1) {
12182 PRINT(KERN_ERR, ohci->host->id,
12183 "Buffer %d out of range",v.buffer);
12185 @@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
12186 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12187 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
12190 + { 0, 0, 0, 0, 0, 0 }
12193 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
12194 diff -urNp linux-2.6.27.4/drivers/input/keyboard/atkbd.c linux-2.6.27.4/drivers/input/keyboard/atkbd.c
12195 --- linux-2.6.27.4/drivers/input/keyboard/atkbd.c 2008-10-22 17:38:01.000000000 -0400
12196 +++ linux-2.6.27.4/drivers/input/keyboard/atkbd.c 2008-10-27 22:36:17.000000000 -0400
12197 @@ -1132,7 +1132,7 @@ static struct serio_device_id atkbd_seri
12199 .extra = SERIO_ANY,
12205 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
12206 diff -urNp linux-2.6.27.4/drivers/input/mouse/lifebook.c linux-2.6.27.4/drivers/input/mouse/lifebook.c
12207 --- linux-2.6.27.4/drivers/input/mouse/lifebook.c 2008-10-22 17:38:01.000000000 -0400
12208 +++ linux-2.6.27.4/drivers/input/mouse/lifebook.c 2008-10-27 22:36:17.000000000 -0400
12209 @@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
12210 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
12214 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
12217 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
12218 diff -urNp linux-2.6.27.4/drivers/input/mouse/psmouse-base.c linux-2.6.27.4/drivers/input/mouse/psmouse-base.c
12219 --- linux-2.6.27.4/drivers/input/mouse/psmouse-base.c 2008-10-22 17:38:01.000000000 -0400
12220 +++ linux-2.6.27.4/drivers/input/mouse/psmouse-base.c 2008-10-27 22:36:17.000000000 -0400
12221 @@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
12223 .extra = SERIO_ANY,
12229 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
12230 diff -urNp linux-2.6.27.4/drivers/input/mouse/synaptics.c linux-2.6.27.4/drivers/input/mouse/synaptics.c
12231 --- linux-2.6.27.4/drivers/input/mouse/synaptics.c 2008-10-22 17:38:01.000000000 -0400
12232 +++ linux-2.6.27.4/drivers/input/mouse/synaptics.c 2008-10-27 22:36:17.000000000 -0400
12233 @@ -417,7 +417,7 @@ static void synaptics_process_packet(str
12236 if (SYN_MODEL_PEN(priv->model_id))
12237 - ; /* Nothing, treat a pen as a single finger */
12238 + break; /* Nothing, treat a pen as a single finger */
12241 if (SYN_CAP_PALMDETECT(priv->capabilities))
12242 @@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
12243 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
12247 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12251 diff -urNp linux-2.6.27.4/drivers/input/mousedev.c linux-2.6.27.4/drivers/input/mousedev.c
12252 --- linux-2.6.27.4/drivers/input/mousedev.c 2008-10-22 17:38:01.000000000 -0400
12253 +++ linux-2.6.27.4/drivers/input/mousedev.c 2008-10-27 22:36:17.000000000 -0400
12254 @@ -1064,7 +1064,7 @@ static struct input_handler mousedev_han
12256 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
12257 static struct miscdevice psaux_mouse = {
12258 - PSMOUSE_MINOR, "psaux", &mousedev_fops
12259 + PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
12261 static int psaux_registered;
12263 diff -urNp linux-2.6.27.4/drivers/input/serio/i8042-x86ia64io.h linux-2.6.27.4/drivers/input/serio/i8042-x86ia64io.h
12264 --- linux-2.6.27.4/drivers/input/serio/i8042-x86ia64io.h 2008-10-22 17:38:01.000000000 -0400
12265 +++ linux-2.6.27.4/drivers/input/serio/i8042-x86ia64io.h 2008-10-27 22:36:17.000000000 -0400
12266 @@ -135,7 +135,7 @@ static struct dmi_system_id __initdata i
12267 DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
12271 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12275 @@ -322,7 +322,7 @@ static struct dmi_system_id __initdata i
12276 DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
12280 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12284 @@ -334,7 +334,7 @@ static struct dmi_system_id __initdata i
12285 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
12289 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12293 @@ -401,7 +401,7 @@ static struct dmi_system_id __initdata i
12294 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
12298 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12301 #endif /* CONFIG_X86 */
12302 diff -urNp linux-2.6.27.4/drivers/input/serio/serio_raw.c linux-2.6.27.4/drivers/input/serio/serio_raw.c
12303 --- linux-2.6.27.4/drivers/input/serio/serio_raw.c 2008-10-22 17:38:01.000000000 -0400
12304 +++ linux-2.6.27.4/drivers/input/serio/serio_raw.c 2008-10-27 22:36:17.000000000 -0400
12305 @@ -373,7 +373,7 @@ static struct serio_device_id serio_raw_
12307 .extra = SERIO_ANY,
12313 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
12314 diff -urNp linux-2.6.27.4/drivers/md/bitmap.c linux-2.6.27.4/drivers/md/bitmap.c
12315 --- linux-2.6.27.4/drivers/md/bitmap.c 2008-10-22 17:38:01.000000000 -0400
12316 +++ linux-2.6.27.4/drivers/md/bitmap.c 2008-10-27 22:36:17.000000000 -0400
12319 # define PRINTK(x...) printk(KERN_DEBUG x)
12321 -# define PRINTK(x...)
12322 +# define PRINTK(x...) do {} while (0)
12326 diff -urNp linux-2.6.27.4/drivers/mtd/devices/doc2000.c linux-2.6.27.4/drivers/mtd/devices/doc2000.c
12327 --- linux-2.6.27.4/drivers/mtd/devices/doc2000.c 2008-10-22 17:38:01.000000000 -0400
12328 +++ linux-2.6.27.4/drivers/mtd/devices/doc2000.c 2008-10-27 22:36:17.000000000 -0400
12329 @@ -777,7 +777,7 @@ static int doc_write(struct mtd_info *mt
12331 /* The ECC will not be calculated correctly if less than 512 is written */
12333 - if (len != 0x200 && eccbuf)
12334 + if (len != 0x200)
12335 printk(KERN_WARNING
12336 "ECC needs a full sector write (adr: %lx size %lx)\n",
12337 (long) to, (long) len);
12338 diff -urNp linux-2.6.27.4/drivers/mtd/devices/doc2001.c linux-2.6.27.4/drivers/mtd/devices/doc2001.c
12339 --- linux-2.6.27.4/drivers/mtd/devices/doc2001.c 2008-10-22 17:38:01.000000000 -0400
12340 +++ linux-2.6.27.4/drivers/mtd/devices/doc2001.c 2008-10-25 12:03:06.000000000 -0400
12341 @@ -396,6 +396,8 @@ static int doc_read (struct mtd_info *mt
12342 /* Don't allow read past end of device */
12343 if (from >= this->totlen)
12348 /* Don't allow a single read to cross a 512-byte block boundary */
12349 if (from + len > ((from | 0x1ff) + 1))
12350 diff -urNp linux-2.6.27.4/drivers/mtd/devices/slram.c linux-2.6.27.4/drivers/mtd/devices/slram.c
12351 --- linux-2.6.27.4/drivers/mtd/devices/slram.c 2008-10-22 17:38:01.000000000 -0400
12352 +++ linux-2.6.27.4/drivers/mtd/devices/slram.c 2008-10-27 22:36:17.000000000 -0400
12353 @@ -273,7 +273,7 @@ static int parse_cmdline(char *devname,
12355 T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
12356 devname, devstart, devlength);
12357 - if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
12358 + if (devlength % SLRAM_BLK_SZ != 0) {
12359 E("slram: Illegal start / length parameter.\n");
12362 diff -urNp linux-2.6.27.4/drivers/mtd/ubi/build.c linux-2.6.27.4/drivers/mtd/ubi/build.c
12363 --- linux-2.6.27.4/drivers/mtd/ubi/build.c 2008-10-22 17:38:01.000000000 -0400
12364 +++ linux-2.6.27.4/drivers/mtd/ubi/build.c 2008-10-27 22:36:17.000000000 -0400
12365 @@ -1104,7 +1104,7 @@ static int __init bytes_str_to_int(const
12366 unsigned long result;
12368 result = simple_strtoul(str, &endp, 0);
12369 - if (str == endp || result < 0) {
12370 + if (str == endp) {
12371 printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
12374 diff -urNp linux-2.6.27.4/drivers/net/eepro100.c linux-2.6.27.4/drivers/net/eepro100.c
12375 --- linux-2.6.27.4/drivers/net/eepro100.c 2008-10-22 17:38:01.000000000 -0400
12376 +++ linux-2.6.27.4/drivers/net/eepro100.c 2008-10-27 22:36:17.000000000 -0400
12377 @@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
12378 # define rx_align(skb) skb_reserve((skb), 2)
12379 # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
12381 -# define rx_align(skb)
12382 +# define rx_align(skb) do {} while (0)
12383 # define RxFD_ALIGNMENT
12386 @@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
12389 static struct pci_device_id eepro100_pci_tbl[] = {
12390 - { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
12391 - { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
12392 - { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
12393 - { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
12394 - { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
12395 - { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
12396 - { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
12397 - { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
12398 - { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
12399 - { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
12400 - { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
12401 - { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
12402 - { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
12403 - { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
12404 - { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
12405 - { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
12406 - { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
12407 - { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
12408 - { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
12409 - { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
12410 - { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
12411 - { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
12412 - { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
12413 - { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
12414 - { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
12415 - { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
12417 + { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12418 + { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12419 + { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12420 + { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12421 + { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12422 + { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12423 + { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12424 + { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12425 + { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12426 + { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12427 + { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12428 + { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12429 + { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12430 + { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12431 + { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12432 + { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12433 + { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12434 + { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12435 + { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12436 + { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12437 + { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12438 + { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12439 + { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12440 + { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12441 + { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12442 + { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12443 + { 0, 0, 0, 0, 0, 0, 0 }
12445 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
12447 diff -urNp linux-2.6.27.4/drivers/net/irda/vlsi_ir.c linux-2.6.27.4/drivers/net/irda/vlsi_ir.c
12448 --- linux-2.6.27.4/drivers/net/irda/vlsi_ir.c 2008-10-22 17:38:01.000000000 -0400
12449 +++ linux-2.6.27.4/drivers/net/irda/vlsi_ir.c 2008-10-27 22:36:17.000000000 -0400
12450 @@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
12451 /* no race - tx-ring already empty */
12452 vlsi_set_baud(idev, iobase);
12453 netif_wake_queue(ndev);
12458 /* keep the speed change pending like it would
12459 * for any len>0 packet. tx completion interrupt
12460 * will apply it when the tx ring becomes empty.
12463 spin_unlock_irqrestore(&idev->lock, flags);
12464 dev_kfree_skb_any(skb);
12466 diff -urNp linux-2.6.27.4/drivers/net/pcnet32.c linux-2.6.27.4/drivers/net/pcnet32.c
12467 --- linux-2.6.27.4/drivers/net/pcnet32.c 2008-10-22 17:38:01.000000000 -0400
12468 +++ linux-2.6.27.4/drivers/net/pcnet32.c 2008-10-27 22:36:17.000000000 -0400
12469 @@ -78,7 +78,7 @@ static int cards_found;
12471 * VLB I/O addresses
12473 -static unsigned int pcnet32_portlist[] __initdata =
12474 +static unsigned int pcnet32_portlist[] __devinitdata =
12475 { 0x300, 0x320, 0x340, 0x360, 0 };
12477 static int pcnet32_debug = 0;
12478 diff -urNp linux-2.6.27.4/drivers/net/tg3.h linux-2.6.27.4/drivers/net/tg3.h
12479 --- linux-2.6.27.4/drivers/net/tg3.h 2008-10-22 17:38:01.000000000 -0400
12480 +++ linux-2.6.27.4/drivers/net/tg3.h 2008-10-27 22:36:17.000000000 -0400
12481 @@ -102,6 +102,7 @@
12482 #define CHIPREV_ID_5750_A0 0x4000
12483 #define CHIPREV_ID_5750_A1 0x4001
12484 #define CHIPREV_ID_5750_A3 0x4003
12485 +#define CHIPREV_ID_5750_C1 0x4201
12486 #define CHIPREV_ID_5750_C2 0x4202
12487 #define CHIPREV_ID_5752_A0_HW 0x5000
12488 #define CHIPREV_ID_5752_A0 0x6000
12489 diff -urNp linux-2.6.27.4/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.27.4/drivers/pci/hotplug/cpqphp_nvram.c
12490 --- linux-2.6.27.4/drivers/pci/hotplug/cpqphp_nvram.c 2008-10-22 17:38:01.000000000 -0400
12491 +++ linux-2.6.27.4/drivers/pci/hotplug/cpqphp_nvram.c 2008-10-27 22:36:17.000000000 -0400
12492 @@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
12494 void compaq_nvram_init (void __iomem *rom_start)
12497 +#ifndef CONFIG_PAX_KERNEXEC
12499 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
12503 dbg("int15 entry = %p\n", compaq_int15_entry_point);
12505 /* initialize our int15 lock */
12506 diff -urNp linux-2.6.27.4/drivers/pci/pcie/aer/aerdrv.c linux-2.6.27.4/drivers/pci/pcie/aer/aerdrv.c
12507 --- linux-2.6.27.4/drivers/pci/pcie/aer/aerdrv.c 2008-10-22 17:38:01.000000000 -0400
12508 +++ linux-2.6.27.4/drivers/pci/pcie/aer/aerdrv.c 2008-10-27 22:36:17.000000000 -0400
12509 @@ -59,7 +59,7 @@ static struct pcie_port_service_id aer_i
12510 .port_type = PCIE_RC_PORT,
12511 .service_type = PCIE_PORT_SERVICE_AER,
12513 - { /* end: all zeroes */ }
12514 + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
12517 static struct pci_error_handlers aer_error_handlers = {
12518 diff -urNp linux-2.6.27.4/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.27.4/drivers/pci/pcie/aer/aerdrv_core.c
12519 --- linux-2.6.27.4/drivers/pci/pcie/aer/aerdrv_core.c 2008-10-22 17:38:01.000000000 -0400
12520 +++ linux-2.6.27.4/drivers/pci/pcie/aer/aerdrv_core.c 2008-10-27 22:36:17.000000000 -0400
12521 @@ -663,7 +663,7 @@ static void aer_isr_one_error(struct pci
12522 struct aer_err_source *e_src)
12524 struct device *s_device;
12525 - struct aer_err_info e_info = {0, 0, 0,};
12526 + struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
12530 diff -urNp linux-2.6.27.4/drivers/pci/pcie/portdrv_pci.c linux-2.6.27.4/drivers/pci/pcie/portdrv_pci.c
12531 --- linux-2.6.27.4/drivers/pci/pcie/portdrv_pci.c 2008-10-22 17:38:01.000000000 -0400
12532 +++ linux-2.6.27.4/drivers/pci/pcie/portdrv_pci.c 2008-10-27 22:36:17.000000000 -0400
12533 @@ -264,7 +264,7 @@ static void pcie_portdrv_err_resume(stru
12534 static const struct pci_device_id port_pci_ids[] = { {
12535 /* handle any PCI-Express port */
12536 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
12537 - }, { /* end: all zeroes */ }
12538 + }, { 0, 0, 0, 0, 0, 0, 0 }
12540 MODULE_DEVICE_TABLE(pci, port_pci_ids);
12542 diff -urNp linux-2.6.27.4/drivers/pci/proc.c linux-2.6.27.4/drivers/pci/proc.c
12543 --- linux-2.6.27.4/drivers/pci/proc.c 2008-10-22 17:38:01.000000000 -0400
12544 +++ linux-2.6.27.4/drivers/pci/proc.c 2008-10-25 12:03:06.000000000 -0400
12545 @@ -470,7 +470,16 @@ static const struct file_operations proc
12546 static int __init pci_proc_init(void)
12548 struct pci_dev *dev = NULL;
12550 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
12551 +#ifdef CONFIG_GRKERNSEC_PROC_USER
12552 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
12553 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
12554 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
12557 proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
12559 proc_create("devices", 0, proc_bus_pci_dir,
12560 &proc_bus_pci_dev_operations);
12561 proc_initialized = 1;
12562 diff -urNp linux-2.6.27.4/drivers/pcmcia/ti113x.h linux-2.6.27.4/drivers/pcmcia/ti113x.h
12563 --- linux-2.6.27.4/drivers/pcmcia/ti113x.h 2008-10-22 17:38:01.000000000 -0400
12564 +++ linux-2.6.27.4/drivers/pcmcia/ti113x.h 2008-10-27 22:36:17.000000000 -0400
12565 @@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
12566 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
12567 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
12570 + { 0, 0, 0, 0, 0, 0, 0 }
12573 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
12574 diff -urNp linux-2.6.27.4/drivers/pcmcia/yenta_socket.c linux-2.6.27.4/drivers/pcmcia/yenta_socket.c
12575 --- linux-2.6.27.4/drivers/pcmcia/yenta_socket.c 2008-10-22 17:38:01.000000000 -0400
12576 +++ linux-2.6.27.4/drivers/pcmcia/yenta_socket.c 2008-10-27 22:36:17.000000000 -0400
12577 @@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
12579 /* match any cardbus bridge */
12580 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
12581 - { /* all zeroes */ }
12582 + { 0, 0, 0, 0, 0, 0, 0 }
12584 MODULE_DEVICE_TABLE(pci, yenta_table);
12586 diff -urNp linux-2.6.27.4/drivers/pnp/pnpbios/bioscalls.c linux-2.6.27.4/drivers/pnp/pnpbios/bioscalls.c
12587 --- linux-2.6.27.4/drivers/pnp/pnpbios/bioscalls.c 2008-10-22 17:38:01.000000000 -0400
12588 +++ linux-2.6.27.4/drivers/pnp/pnpbios/bioscalls.c 2008-10-27 22:36:17.000000000 -0400
12589 @@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
12590 set_limit(gdt[(selname) >> 3], size); \
12593 -static struct desc_struct bad_bios_desc;
12594 +static struct desc_struct bad_bios_desc __read_only;
12597 * At some point we want to use this stack frame pointer to unwind
12598 @@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
12599 struct desc_struct save_desc_40;
12602 +#ifdef CONFIG_PAX_KERNEXEC
12603 + unsigned long cr0;
12607 * PnP BIOSes are generally not terribly re-entrant.
12608 * Also, don't rely on them to save everything correctly.
12609 @@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
12612 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
12614 +#ifdef CONFIG_PAX_KERNEXEC
12615 + pax_open_kernel(cr0);
12618 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
12620 +#ifdef CONFIG_PAX_KERNEXEC
12621 + pax_close_kernel(cr0);
12624 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
12625 spin_lock_irqsave(&pnp_bios_lock, flags);
12627 @@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
12629 spin_unlock_irqrestore(&pnp_bios_lock, flags);
12631 +#ifdef CONFIG_PAX_KERNEXEC
12632 + pax_open_kernel(cr0);
12635 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
12637 +#ifdef CONFIG_PAX_KERNEXEC
12638 + pax_close_kernel(cr0);
12643 /* If we get here and this is set then the PnP BIOS faulted on us. */
12644 @@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
12648 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
12649 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
12653 +#ifdef CONFIG_PAX_KERNEXEC
12654 + unsigned long cr0;
12657 spin_lock_init(&pnp_bios_lock);
12658 pnp_bios_callpoint.offset = header->fields.pm16offset;
12659 pnp_bios_callpoint.segment = PNP_CS16;
12661 +#ifdef CONFIG_PAX_KERNEXEC
12662 + pax_open_kernel(cr0);
12665 bad_bios_desc.a = 0;
12666 - bad_bios_desc.b = 0x00409200;
12667 + bad_bios_desc.b = 0x00409300;
12669 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
12670 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
12671 @@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
12672 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
12673 __va(header->fields.pm16dseg));
12676 +#ifdef CONFIG_PAX_KERNEXEC
12677 + pax_close_kernel(cr0);
12681 diff -urNp linux-2.6.27.4/drivers/pnp/quirks.c linux-2.6.27.4/drivers/pnp/quirks.c
12682 --- linux-2.6.27.4/drivers/pnp/quirks.c 2008-10-22 17:38:01.000000000 -0400
12683 +++ linux-2.6.27.4/drivers/pnp/quirks.c 2008-10-27 22:36:17.000000000 -0400
12684 @@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = {
12685 /* PnP resources that might overlap PCI BARs */
12686 {"PNP0c01", quirk_system_pci_resources},
12687 {"PNP0c02", quirk_system_pci_resources},
12692 void pnp_fixup_device(struct pnp_dev *dev)
12693 diff -urNp linux-2.6.27.4/drivers/pnp/resource.c linux-2.6.27.4/drivers/pnp/resource.c
12694 --- linux-2.6.27.4/drivers/pnp/resource.c 2008-10-22 17:38:01.000000000 -0400
12695 +++ linux-2.6.27.4/drivers/pnp/resource.c 2008-10-27 22:36:17.000000000 -0400
12696 @@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
12699 /* check if the resource is valid */
12700 - if (*irq < 0 || *irq > 15)
12704 /* check if the resource is reserved */
12705 @@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
12708 /* check if the resource is valid */
12709 - if (*dma < 0 || *dma == 4 || *dma > 7)
12710 + if (*dma == 4 || *dma > 7)
12713 /* check if the resource is reserved */
12714 diff -urNp linux-2.6.27.4/drivers/scsi/scsi_logging.h linux-2.6.27.4/drivers/scsi/scsi_logging.h
12715 --- linux-2.6.27.4/drivers/scsi/scsi_logging.h 2008-10-22 17:38:01.000000000 -0400
12716 +++ linux-2.6.27.4/drivers/scsi/scsi_logging.h 2008-10-27 22:36:17.000000000 -0400
12717 @@ -51,7 +51,7 @@ do { \
12721 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
12722 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
12723 #endif /* CONFIG_SCSI_LOGGING */
12726 diff -urNp linux-2.6.27.4/drivers/serial/8250_pci.c linux-2.6.27.4/drivers/serial/8250_pci.c
12727 --- linux-2.6.27.4/drivers/serial/8250_pci.c 2008-10-22 17:38:01.000000000 -0400
12728 +++ linux-2.6.27.4/drivers/serial/8250_pci.c 2008-10-27 22:36:17.000000000 -0400
12729 @@ -2859,7 +2859,7 @@ static struct pci_device_id serial_pci_t
12730 PCI_ANY_ID, PCI_ANY_ID,
12731 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
12732 0xffff00, pbn_default },
12734 + { 0, 0, 0, 0, 0, 0, 0 }
12737 static struct pci_driver serial_pci_driver = {
12738 diff -urNp linux-2.6.27.4/drivers/usb/class/cdc-acm.c linux-2.6.27.4/drivers/usb/class/cdc-acm.c
12739 --- linux-2.6.27.4/drivers/usb/class/cdc-acm.c 2008-10-27 22:25:01.000000000 -0400
12740 +++ linux-2.6.27.4/drivers/usb/class/cdc-acm.c 2008-10-27 22:36:17.000000000 -0400
12741 @@ -1382,7 +1382,7 @@ static struct usb_device_id acm_ids[] =
12742 USB_CDC_ACM_PROTO_AT_CDMA) },
12744 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
12746 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
12749 MODULE_DEVICE_TABLE (usb, acm_ids);
12750 diff -urNp linux-2.6.27.4/drivers/usb/class/usblp.c linux-2.6.27.4/drivers/usb/class/usblp.c
12751 --- linux-2.6.27.4/drivers/usb/class/usblp.c 2008-10-22 17:38:01.000000000 -0400
12752 +++ linux-2.6.27.4/drivers/usb/class/usblp.c 2008-10-27 22:36:17.000000000 -0400
12753 @@ -227,7 +227,7 @@ static const struct quirk_printer_struct
12754 { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
12755 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
12756 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
12761 static int usblp_wwait(struct usblp *usblp, int nonblock);
12762 @@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
12763 { USB_INTERFACE_INFO(7, 1, 2) },
12764 { USB_INTERFACE_INFO(7, 1, 3) },
12765 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
12766 - { } /* Terminating entry */
12767 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
12770 MODULE_DEVICE_TABLE (usb, usblp_ids);
12771 diff -urNp linux-2.6.27.4/drivers/usb/core/hub.c linux-2.6.27.4/drivers/usb/core/hub.c
12772 --- linux-2.6.27.4/drivers/usb/core/hub.c 2008-10-27 22:25:01.000000000 -0400
12773 +++ linux-2.6.27.4/drivers/usb/core/hub.c 2008-10-27 22:36:17.000000000 -0400
12774 @@ -3110,7 +3110,7 @@ static struct usb_device_id hub_id_table
12775 .bDeviceClass = USB_CLASS_HUB},
12776 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
12777 .bInterfaceClass = USB_CLASS_HUB},
12778 - { } /* Terminating entry */
12779 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
12782 MODULE_DEVICE_TABLE (usb, hub_id_table);
12783 diff -urNp linux-2.6.27.4/drivers/usb/host/ehci-pci.c linux-2.6.27.4/drivers/usb/host/ehci-pci.c
12784 --- linux-2.6.27.4/drivers/usb/host/ehci-pci.c 2008-10-22 17:38:01.000000000 -0400
12785 +++ linux-2.6.27.4/drivers/usb/host/ehci-pci.c 2008-10-27 22:36:17.000000000 -0400
12786 @@ -390,7 +390,7 @@ static const struct pci_device_id pci_id
12787 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
12788 .driver_data = (unsigned long) &ehci_pci_hc_driver,
12790 - { /* end: all zeroes */ }
12791 + { 0, 0, 0, 0, 0, 0, 0 }
12793 MODULE_DEVICE_TABLE(pci, pci_ids);
12795 diff -urNp linux-2.6.27.4/drivers/usb/host/uhci-hcd.c linux-2.6.27.4/drivers/usb/host/uhci-hcd.c
12796 --- linux-2.6.27.4/drivers/usb/host/uhci-hcd.c 2008-10-22 17:38:01.000000000 -0400
12797 +++ linux-2.6.27.4/drivers/usb/host/uhci-hcd.c 2008-10-27 22:36:17.000000000 -0400
12798 @@ -928,7 +928,7 @@ static const struct pci_device_id uhci_p
12799 /* handle any USB UHCI controller */
12800 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
12801 .driver_data = (unsigned long) &uhci_driver,
12802 - }, { /* end: all zeroes */ }
12803 + }, { 0, 0, 0, 0, 0, 0, 0 }
12806 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
12807 diff -urNp linux-2.6.27.4/drivers/usb/storage/debug.h linux-2.6.27.4/drivers/usb/storage/debug.h
12808 --- linux-2.6.27.4/drivers/usb/storage/debug.h 2008-10-22 17:38:01.000000000 -0400
12809 +++ linux-2.6.27.4/drivers/usb/storage/debug.h 2008-10-27 22:36:17.000000000 -0400
12810 @@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
12811 #define US_DEBUGPX(x...) printk( x )
12812 #define US_DEBUG(x) x
12814 -#define US_DEBUGP(x...)
12815 -#define US_DEBUGPX(x...)
12816 -#define US_DEBUG(x)
12817 +#define US_DEBUGP(x...) do {} while (0)
12818 +#define US_DEBUGPX(x...) do {} while (0)
12819 +#define US_DEBUG(x) do {} while (0)
12823 diff -urNp linux-2.6.27.4/drivers/usb/storage/usb.c linux-2.6.27.4/drivers/usb/storage/usb.c
12824 --- linux-2.6.27.4/drivers/usb/storage/usb.c 2008-10-22 17:38:01.000000000 -0400
12825 +++ linux-2.6.27.4/drivers/usb/storage/usb.c 2008-10-27 22:36:17.000000000 -0400
12826 @@ -136,7 +136,7 @@ static struct usb_device_id storage_usb_
12829 /* Terminating entry */
12831 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
12834 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
12835 @@ -176,7 +176,7 @@ static struct us_unusual_dev us_unusual_
12838 /* Terminating entry */
12840 + { NULL, NULL, 0, 0, NULL }
12844 diff -urNp linux-2.6.27.4/drivers/video/fbcmap.c linux-2.6.27.4/drivers/video/fbcmap.c
12845 --- linux-2.6.27.4/drivers/video/fbcmap.c 2008-10-22 17:38:01.000000000 -0400
12846 +++ linux-2.6.27.4/drivers/video/fbcmap.c 2008-10-27 22:36:17.000000000 -0400
12847 @@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
12848 int rc, size = cmap->len * sizeof(u16);
12849 struct fb_cmap umap;
12851 - if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
12852 - !info->fbops->fb_setcmap))
12853 + if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
12856 memset(&umap, 0, sizeof(struct fb_cmap));
12857 diff -urNp linux-2.6.27.4/drivers/video/fbmem.c linux-2.6.27.4/drivers/video/fbmem.c
12858 --- linux-2.6.27.4/drivers/video/fbmem.c 2008-10-22 17:38:01.000000000 -0400
12859 +++ linux-2.6.27.4/drivers/video/fbmem.c 2008-10-27 22:36:17.000000000 -0400
12860 @@ -395,7 +395,7 @@ static void fb_do_show_logo(struct fb_in
12861 image->dx += image->width + 8;
12863 } else if (rotate == FB_ROTATE_UD) {
12864 - for (x = 0; x < num && image->dx >= 0; x++) {
12865 + for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
12866 info->fbops->fb_imageblit(info, image);
12867 image->dx -= image->width + 8;
12869 @@ -407,7 +407,7 @@ static void fb_do_show_logo(struct fb_in
12870 image->dy += image->height + 8;
12872 } else if (rotate == FB_ROTATE_CCW) {
12873 - for (x = 0; x < num && image->dy >= 0; x++) {
12874 + for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
12875 info->fbops->fb_imageblit(info, image);
12876 image->dy -= image->height + 8;
12878 @@ -1083,7 +1083,7 @@ fb_ioctl(struct inode *inode, struct fil
12880 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
12882 - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
12883 + if (con2fb.framebuffer >= FB_MAX)
12886 if (!registered_fb[con2fb.framebuffer])
12887 diff -urNp linux-2.6.27.4/drivers/video/fbmon.c linux-2.6.27.4/drivers/video/fbmon.c
12888 --- linux-2.6.27.4/drivers/video/fbmon.c 2008-10-22 17:38:01.000000000 -0400
12889 +++ linux-2.6.27.4/drivers/video/fbmon.c 2008-10-27 22:36:17.000000000 -0400
12892 #define DPRINTK(fmt, args...) printk(fmt,## args)
12894 -#define DPRINTK(fmt, args...)
12895 +#define DPRINTK(fmt, args...) do {} while (0)
12898 #define FBMON_FIX_HEADER 1
12899 diff -urNp linux-2.6.27.4/drivers/video/i810/i810_accel.c linux-2.6.27.4/drivers/video/i810/i810_accel.c
12900 --- linux-2.6.27.4/drivers/video/i810/i810_accel.c 2008-10-22 17:38:01.000000000 -0400
12901 +++ linux-2.6.27.4/drivers/video/i810/i810_accel.c 2008-10-27 22:36:17.000000000 -0400
12902 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct
12905 printk("ringbuffer lockup!!!\n");
12906 + printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
12907 i810_report_error(mmio);
12908 par->dev_flags |= LOCKUP;
12909 info->pixmap.scan_align = 1;
12910 diff -urNp linux-2.6.27.4/drivers/video/i810/i810_main.c linux-2.6.27.4/drivers/video/i810/i810_main.c
12911 --- linux-2.6.27.4/drivers/video/i810/i810_main.c 2008-10-22 17:38:01.000000000 -0400
12912 +++ linux-2.6.27.4/drivers/video/i810/i810_main.c 2008-10-27 22:36:17.000000000 -0400
12913 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
12914 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
12915 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
12916 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
12918 + { 0, 0, 0, 0, 0, 0, 0 },
12921 static struct pci_driver i810fb_driver = {
12922 @@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
12923 int size = ((cursor->image.width + 7) >> 3) *
12924 cursor->image.height;
12926 - u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
12927 + u8 *data = kmalloc(64 * 8, GFP_KERNEL);
12931 diff -urNp linux-2.6.27.4/drivers/video/modedb.c linux-2.6.27.4/drivers/video/modedb.c
12932 --- linux-2.6.27.4/drivers/video/modedb.c 2008-10-22 17:38:01.000000000 -0400
12933 +++ linux-2.6.27.4/drivers/video/modedb.c 2008-10-27 22:36:18.000000000 -0400
12934 @@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
12936 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
12937 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
12938 - 0, FB_VMODE_NONINTERLACED
12939 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12941 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
12942 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
12943 - 0, FB_VMODE_NONINTERLACED
12944 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12946 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
12947 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
12948 - 0, FB_VMODE_NONINTERLACED
12949 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12951 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
12952 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
12953 - 0, FB_VMODE_INTERLACED
12954 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
12956 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
12957 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
12958 - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12959 + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12961 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
12962 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
12963 - 0, FB_VMODE_NONINTERLACED
12964 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12966 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
12967 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
12968 - 0, FB_VMODE_NONINTERLACED
12969 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12971 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
12972 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
12973 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12974 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12976 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
12977 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
12978 - 0, FB_VMODE_NONINTERLACED
12979 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12981 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
12982 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
12983 - 0, FB_VMODE_INTERLACED
12984 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
12986 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
12987 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
12988 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12989 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12991 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
12992 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
12993 - 0, FB_VMODE_NONINTERLACED
12994 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12996 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
12997 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
12998 - 0, FB_VMODE_NONINTERLACED
12999 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13001 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
13002 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
13003 - 0, FB_VMODE_NONINTERLACED
13004 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13006 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
13007 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
13008 - 0, FB_VMODE_NONINTERLACED
13009 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13011 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
13012 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
13013 - 0, FB_VMODE_NONINTERLACED
13014 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13016 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
13017 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
13018 - 0, FB_VMODE_INTERLACED
13019 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13021 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
13022 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
13023 - 0, FB_VMODE_NONINTERLACED
13024 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13026 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
13027 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
13028 - 0, FB_VMODE_NONINTERLACED
13029 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13031 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
13032 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
13033 - 0, FB_VMODE_NONINTERLACED
13034 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13036 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
13037 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
13038 - 0, FB_VMODE_NONINTERLACED
13039 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13041 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
13042 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
13043 - 0, FB_VMODE_NONINTERLACED
13044 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13046 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
13047 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
13048 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13049 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13051 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
13052 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
13053 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13054 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13056 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
13057 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
13058 - 0, FB_VMODE_NONINTERLACED
13059 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13061 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
13062 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
13063 - 0, FB_VMODE_NONINTERLACED
13064 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13066 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
13067 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
13068 - 0, FB_VMODE_NONINTERLACED
13069 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13071 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
13072 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
13073 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13074 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13076 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
13077 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
13078 - 0, FB_VMODE_NONINTERLACED
13079 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13081 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
13082 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
13083 - 0, FB_VMODE_NONINTERLACED
13084 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13086 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
13087 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
13088 - 0, FB_VMODE_NONINTERLACED
13089 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13091 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
13092 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
13093 - 0, FB_VMODE_NONINTERLACED
13094 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13096 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
13097 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
13098 - 0, FB_VMODE_NONINTERLACED
13099 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13101 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
13102 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
13103 - 0, FB_VMODE_NONINTERLACED
13104 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13106 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
13107 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
13108 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13109 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13111 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
13112 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
13113 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13114 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13116 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
13117 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
13118 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13119 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13121 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
13122 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
13123 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13124 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13126 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
13127 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
13128 - 0, FB_VMODE_NONINTERLACED
13129 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13131 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
13132 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
13133 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13134 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13136 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
13137 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
13138 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13139 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13141 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
13142 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
13143 - 0, FB_VMODE_NONINTERLACED
13144 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13146 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
13147 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
13148 - 0, FB_VMODE_NONINTERLACED
13149 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13151 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
13152 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
13153 - 0, FB_VMODE_DOUBLE
13154 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13156 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
13157 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
13158 - 0, FB_VMODE_DOUBLE
13159 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13161 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
13162 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
13163 - 0, FB_VMODE_DOUBLE
13164 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13166 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
13167 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
13168 - 0, FB_VMODE_DOUBLE
13169 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13171 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
13172 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
13173 - 0, FB_VMODE_DOUBLE
13174 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13176 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
13177 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
13178 - 0, FB_VMODE_DOUBLE
13179 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13181 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
13182 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
13183 - 0, FB_VMODE_DOUBLE
13184 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13186 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
13187 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
13188 - 0, FB_VMODE_DOUBLE
13189 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13191 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
13192 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
13193 - 0, FB_VMODE_DOUBLE
13194 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13196 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
13197 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
13198 - 0, FB_VMODE_DOUBLE
13199 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13201 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
13202 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
13203 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
13204 - FB_VMODE_NONINTERLACED
13205 + FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13207 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
13208 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
13209 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13210 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13212 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
13213 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
13214 - 0, FB_VMODE_NONINTERLACED
13215 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13217 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
13218 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
13219 - 0, FB_VMODE_NONINTERLACED
13220 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13224 diff -urNp linux-2.6.27.4/drivers/video/uvesafb.c linux-2.6.27.4/drivers/video/uvesafb.c
13225 --- linux-2.6.27.4/drivers/video/uvesafb.c 2008-10-22 17:38:01.000000000 -0400
13226 +++ linux-2.6.27.4/drivers/video/uvesafb.c 2008-10-27 22:36:18.000000000 -0400
13228 #include <linux/fb.h>
13229 #include <linux/io.h>
13230 #include <linux/mutex.h>
13231 +#include <linux/moduleloader.h>
13232 #include <video/edid.h>
13233 #include <video/uvesafb.h>
13235 @@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
13239 - return call_usermodehelper(v86d_path, argv, envp, 1);
13240 + return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
13244 @@ -569,10 +570,34 @@ static int __devinit uvesafb_vbe_getpmi(
13245 if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
13246 par->pmi_setpal = par->ypan = 0;
13249 +#ifdef CONFIG_PAX_KERNEXEC
13250 +#ifdef CONFIG_MODULES
13251 + unsigned long cr0;
13253 + par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
13255 + if (!par->pmi_code) {
13256 + par->pmi_setpal = par->ypan = 0;
13261 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
13262 + task->t.regs.edi);
13264 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13265 + pax_open_kernel(cr0);
13266 + memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
13267 + pax_close_kernel(cr0);
13269 + par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
13270 + par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
13272 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
13273 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
13276 printk(KERN_INFO "uvesafb: protected mode interface info at "
13278 (u16)task->t.regs.es, (u16)task->t.regs.edi);
13279 @@ -1827,6 +1852,11 @@ out:
13280 if (par->vbe_modes)
13281 kfree(par->vbe_modes);
13283 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13284 + if (par->pmi_code)
13285 + module_free_exec(NULL, par->pmi_code);
13288 framebuffer_release(info);
13291 @@ -1853,6 +1883,12 @@ static int uvesafb_remove(struct platfor
13292 kfree(par->vbe_state_orig);
13293 if (par->vbe_state_saved)
13294 kfree(par->vbe_state_saved);
13296 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13297 + if (par->pmi_code)
13298 + module_free_exec(NULL, par->pmi_code);
13303 framebuffer_release(info);
13304 diff -urNp linux-2.6.27.4/drivers/video/vesafb.c linux-2.6.27.4/drivers/video/vesafb.c
13305 --- linux-2.6.27.4/drivers/video/vesafb.c 2008-10-22 17:38:01.000000000 -0400
13306 +++ linux-2.6.27.4/drivers/video/vesafb.c 2008-10-27 22:36:18.000000000 -0400
13310 #include <linux/module.h>
13311 +#include <linux/moduleloader.h>
13312 #include <linux/kernel.h>
13313 #include <linux/errno.h>
13314 #include <linux/string.h>
13315 @@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
13316 static int vram_total __initdata; /* Set total amount of memory */
13317 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
13318 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
13319 -static void (*pmi_start)(void) __read_mostly;
13320 -static void (*pmi_pal) (void) __read_mostly;
13321 +static void (*pmi_start)(void) __read_only;
13322 +static void (*pmi_pal) (void) __read_only;
13323 static int depth __read_mostly;
13324 static int vga_compat __read_mostly;
13325 /* --------------------------------------------------------------------- */
13326 @@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
13327 unsigned int size_vmode;
13328 unsigned int size_remap;
13329 unsigned int size_total;
13330 + void *pmi_code = NULL;
13332 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
13334 @@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
13335 size_remap = size_total;
13336 vesafb_fix.smem_len = size_remap;
13339 - screen_info.vesapm_seg = 0;
13342 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
13343 printk(KERN_WARNING
13344 "vesafb: cannot reserve video memory at 0x%lx\n",
13345 @@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
13346 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
13347 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
13351 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13352 + pmi_code = module_alloc_exec(screen_info.vesapm_size);
13354 +#elif !defined(CONFIG_PAX_KERNEXEC)
13359 + screen_info.vesapm_seg = 0;
13361 if (screen_info.vesapm_seg) {
13362 - printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
13363 - screen_info.vesapm_seg,screen_info.vesapm_off);
13364 + printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
13365 + screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
13368 if (screen_info.vesapm_seg < 0xc000)
13369 @@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
13371 if (ypan || pmi_setpal) {
13372 unsigned short *pmi_base;
13373 - pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13374 - pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
13375 - pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
13377 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13378 + unsigned long cr0;
13381 + pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13383 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13384 + pax_open_kernel(cr0);
13385 + memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
13387 + pmi_code = pmi_base;
13390 + pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
13391 + pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
13393 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13394 + pmi_start = ktva_ktla(pmi_start);
13395 + pmi_pal = ktva_ktla(pmi_pal);
13396 + pax_close_kernel(cr0);
13399 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
13401 printk(KERN_INFO "vesafb: pmi: ports = ");
13402 @@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
13403 info->node, info->fix.id);
13407 +#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13408 + module_free_exec(NULL, pmi_code);
13411 if (info->screen_base)
13412 iounmap(info->screen_base);
13413 framebuffer_release(info);
13414 diff -urNp linux-2.6.27.4/fs/9p/vfs_inode.c linux-2.6.27.4/fs/9p/vfs_inode.c
13415 --- linux-2.6.27.4/fs/9p/vfs_inode.c 2008-10-22 17:38:01.000000000 -0400
13416 +++ linux-2.6.27.4/fs/9p/vfs_inode.c 2008-10-27 22:36:18.000000000 -0400
13417 @@ -1021,7 +1021,7 @@ static void *v9fs_vfs_follow_link(struct
13419 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
13421 - char *s = nd_get_link(nd);
13422 + const char *s = nd_get_link(nd);
13424 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
13426 diff -urNp linux-2.6.27.4/fs/aio.c linux-2.6.27.4/fs/aio.c
13427 --- linux-2.6.27.4/fs/aio.c 2008-10-22 17:38:01.000000000 -0400
13428 +++ linux-2.6.27.4/fs/aio.c 2008-10-27 22:36:18.000000000 -0400
13429 @@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
13430 size += sizeof(struct io_event) * nr_events;
13431 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
13433 - if (nr_pages < 0)
13434 + if (nr_pages <= 0)
13437 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
13438 diff -urNp linux-2.6.27.4/fs/autofs4/symlink.c linux-2.6.27.4/fs/autofs4/symlink.c
13439 --- linux-2.6.27.4/fs/autofs4/symlink.c 2008-10-22 17:38:01.000000000 -0400
13440 +++ linux-2.6.27.4/fs/autofs4/symlink.c 2008-10-27 22:36:18.000000000 -0400
13442 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
13444 struct autofs_info *ino = autofs4_dentry_ino(dentry);
13445 - nd_set_link(nd, (char *)ino->u.symlink);
13446 + nd_set_link(nd, ino->u.symlink);
13450 diff -urNp linux-2.6.27.4/fs/befs/linuxvfs.c linux-2.6.27.4/fs/befs/linuxvfs.c
13451 --- linux-2.6.27.4/fs/befs/linuxvfs.c 2008-10-22 17:38:01.000000000 -0400
13452 +++ linux-2.6.27.4/fs/befs/linuxvfs.c 2008-10-27 22:36:18.000000000 -0400
13453 @@ -490,7 +490,7 @@ static void befs_put_link(struct dentry
13455 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
13456 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
13457 - char *link = nd_get_link(nd);
13458 + const char *link = nd_get_link(nd);
13462 diff -urNp linux-2.6.27.4/fs/binfmt_aout.c linux-2.6.27.4/fs/binfmt_aout.c
13463 --- linux-2.6.27.4/fs/binfmt_aout.c 2008-10-22 17:38:01.000000000 -0400
13464 +++ linux-2.6.27.4/fs/binfmt_aout.c 2008-10-27 22:36:18.000000000 -0400
13466 #include <linux/personality.h>
13467 #include <linux/init.h>
13468 #include <linux/vs_memory.h>
13469 +#include <linux/grsecurity.h>
13471 #include <asm/system.h>
13472 #include <asm/uaccess.h>
13473 @@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
13474 /* If the size of the dump file exceeds the rlimit, then see what would happen
13475 if we wrote the stack, but not the data area. */
13477 + gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
13478 if ((dump.u_dsize + dump.u_ssize) > limit)
13481 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
13482 if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
13486 /* Make sure we have enough room to write the stack and data areas. */
13488 + gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
13489 if (dump.u_ssize > limit)
13492 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
13493 if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
13496 @@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
13497 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
13498 if (rlim >= RLIM_INFINITY)
13501 + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
13502 if (ex.a_data + ex.a_bss > rlim)
13505 @@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
13507 compute_creds(bprm);
13508 current->flags &= ~PF_FORKNOEXEC;
13510 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13511 + current->mm->pax_flags = 0UL;
13514 +#ifdef CONFIG_PAX_PAGEEXEC
13515 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
13516 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
13518 +#ifdef CONFIG_PAX_EMUTRAMP
13519 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
13520 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
13523 +#ifdef CONFIG_PAX_MPROTECT
13524 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
13525 + current->mm->pax_flags |= MF_PAX_MPROTECT;
13532 if (N_MAGIC(ex) == NMAGIC) {
13533 loff_t pos = fd_offset;
13534 @@ -413,7 +442,7 @@ static int load_aout_binary(struct linux
13536 down_write(¤t->mm->mmap_sem);
13537 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
13538 - PROT_READ | PROT_WRITE | PROT_EXEC,
13539 + PROT_READ | PROT_WRITE,
13540 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
13541 fd_offset + ex.a_text);
13542 up_write(¤t->mm->mmap_sem);
13543 diff -urNp linux-2.6.27.4/fs/binfmt_elf.c linux-2.6.27.4/fs/binfmt_elf.c
13544 --- linux-2.6.27.4/fs/binfmt_elf.c 2008-10-22 17:38:01.000000000 -0400
13545 +++ linux-2.6.27.4/fs/binfmt_elf.c 2008-10-27 22:36:18.000000000 -0400
13546 @@ -38,10 +38,16 @@
13547 #include <linux/elf.h>
13548 #include <linux/utsname.h>
13549 #include <linux/vs_memory.h>
13550 +#include <linux/grsecurity.h>
13552 #include <asm/uaccess.h>
13553 #include <asm/param.h>
13554 #include <asm/page.h>
13556 +#ifdef CONFIG_PAX_SEGMEXEC
13557 +#include <asm/desc.h>
13560 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
13561 static int load_elf_library(struct file *);
13562 static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
13563 @@ -84,6 +90,8 @@ static struct linux_binfmt elf_format =
13565 static int set_brk(unsigned long start, unsigned long end)
13567 + unsigned long e = end;
13569 start = ELF_PAGEALIGN(start);
13570 end = ELF_PAGEALIGN(end);
13572 @@ -94,7 +102,7 @@ static int set_brk(unsigned long start,
13573 if (BAD_ADDR(addr))
13576 - current->mm->start_brk = current->mm->brk = end;
13577 + current->mm->start_brk = current->mm->brk = e;
13581 @@ -380,10 +388,10 @@ static unsigned long load_elf_interp(str
13583 struct elf_phdr *elf_phdata;
13584 struct elf_phdr *eppnt;
13585 - unsigned long load_addr = 0;
13586 + unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
13587 int load_addr_set = 0;
13588 unsigned long last_bss = 0, elf_bss = 0;
13589 - unsigned long error = ~0UL;
13590 + unsigned long error = -EINVAL;
13591 unsigned long total_size;
13592 int retval, i, size;
13594 @@ -429,6 +437,11 @@ static unsigned long load_elf_interp(str
13598 +#ifdef CONFIG_PAX_SEGMEXEC
13599 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
13600 + pax_task_size = SEGMEXEC_TASK_SIZE;
13603 eppnt = elf_phdata;
13604 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
13605 if (eppnt->p_type == PT_LOAD) {
13606 @@ -472,8 +485,8 @@ static unsigned long load_elf_interp(str
13607 k = load_addr + eppnt->p_vaddr;
13609 eppnt->p_filesz > eppnt->p_memsz ||
13610 - eppnt->p_memsz > TASK_SIZE ||
13611 - TASK_SIZE - eppnt->p_memsz < k) {
13612 + eppnt->p_memsz > pax_task_size ||
13613 + pax_task_size - eppnt->p_memsz < k) {
13617 @@ -527,6 +540,177 @@ out:
13621 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
13622 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
13624 + unsigned long pax_flags = 0UL;
13626 +#ifdef CONFIG_PAX_PAGEEXEC
13627 + if (elf_phdata->p_flags & PF_PAGEEXEC)
13628 + pax_flags |= MF_PAX_PAGEEXEC;
13631 +#ifdef CONFIG_PAX_SEGMEXEC
13632 + if (elf_phdata->p_flags & PF_SEGMEXEC)
13633 + pax_flags |= MF_PAX_SEGMEXEC;
13636 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
13637 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13639 + pax_flags &= ~MF_PAX_SEGMEXEC;
13641 + pax_flags &= ~MF_PAX_PAGEEXEC;
13645 +#ifdef CONFIG_PAX_EMUTRAMP
13646 + if (elf_phdata->p_flags & PF_EMUTRAMP)
13647 + pax_flags |= MF_PAX_EMUTRAMP;
13650 +#ifdef CONFIG_PAX_MPROTECT
13651 + if (elf_phdata->p_flags & PF_MPROTECT)
13652 + pax_flags |= MF_PAX_MPROTECT;
13655 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
13656 + if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
13657 + pax_flags |= MF_PAX_RANDMMAP;
13660 + return pax_flags;
13664 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
13665 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
13667 + unsigned long pax_flags = 0UL;
13669 +#ifdef CONFIG_PAX_PAGEEXEC
13670 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
13671 + pax_flags |= MF_PAX_PAGEEXEC;
13674 +#ifdef CONFIG_PAX_SEGMEXEC
13675 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
13676 + pax_flags |= MF_PAX_SEGMEXEC;
13679 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
13680 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13682 + pax_flags &= ~MF_PAX_SEGMEXEC;
13684 + pax_flags &= ~MF_PAX_PAGEEXEC;
13688 +#ifdef CONFIG_PAX_EMUTRAMP
13689 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
13690 + pax_flags |= MF_PAX_EMUTRAMP;
13693 +#ifdef CONFIG_PAX_MPROTECT
13694 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
13695 + pax_flags |= MF_PAX_MPROTECT;
13698 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
13699 + if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
13700 + pax_flags |= MF_PAX_RANDMMAP;
13703 + return pax_flags;
13707 +#ifdef CONFIG_PAX_EI_PAX
13708 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
13710 + unsigned long pax_flags = 0UL;
13712 +#ifdef CONFIG_PAX_PAGEEXEC
13713 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
13714 + pax_flags |= MF_PAX_PAGEEXEC;
13717 +#ifdef CONFIG_PAX_SEGMEXEC
13718 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
13719 + pax_flags |= MF_PAX_SEGMEXEC;
13722 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
13723 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13725 + pax_flags &= ~MF_PAX_SEGMEXEC;
13727 + pax_flags &= ~MF_PAX_PAGEEXEC;
13731 +#ifdef CONFIG_PAX_EMUTRAMP
13732 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
13733 + pax_flags |= MF_PAX_EMUTRAMP;
13736 +#ifdef CONFIG_PAX_MPROTECT
13737 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
13738 + pax_flags |= MF_PAX_MPROTECT;
13741 +#ifdef CONFIG_PAX_ASLR
13742 + if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
13743 + pax_flags |= MF_PAX_RANDMMAP;
13746 + return pax_flags;
13750 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
13751 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
13753 + unsigned long pax_flags = 0UL;
13755 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
13759 +#ifdef CONFIG_PAX_EI_PAX
13760 + pax_flags = pax_parse_ei_pax(elf_ex);
13763 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
13764 + for (i = 0UL; i < elf_ex->e_phnum; i++)
13765 + if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
13766 + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
13767 + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
13768 + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
13769 + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
13770 + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
13773 +#ifdef CONFIG_PAX_SOFTMODE
13774 + if (pax_softmode)
13775 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
13779 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
13784 + if (0 > pax_check_flags(&pax_flags))
13787 + current->mm->pax_flags = pax_flags;
13793 * These are the functions used to load ELF style executables and shared
13794 * libraries. There is no binary dependent code anywhere else.
13795 @@ -543,6 +727,11 @@ static unsigned long randomize_stack_top
13797 unsigned int random_variable = 0;
13799 +#ifdef CONFIG_PAX_RANDUSTACK
13800 + if (randomize_va_space)
13801 + return stack_top - current->mm->delta_stack;
13804 if ((current->flags & PF_RANDOMIZE) &&
13805 !(current->personality & ADDR_NO_RANDOMIZE)) {
13806 random_variable = get_random_int() & STACK_RND_MASK;
13807 @@ -561,7 +750,7 @@ static int load_elf_binary(struct linux_
13808 unsigned long load_addr = 0, load_bias = 0;
13809 int load_addr_set = 0;
13810 char * elf_interpreter = NULL;
13811 - unsigned long error;
13812 + unsigned long error = 0;
13813 struct elf_phdr *elf_ppnt, *elf_phdata;
13814 unsigned long elf_bss, elf_brk;
13815 int elf_exec_fileno;
13816 @@ -572,11 +761,11 @@ static int load_elf_binary(struct linux_
13817 unsigned long start_code, end_code, start_data, end_data;
13818 unsigned long reloc_func_desc = 0;
13819 int executable_stack = EXSTACK_DEFAULT;
13820 - unsigned long def_flags = 0;
13822 struct elfhdr elf_ex;
13823 struct elfhdr interp_elf_ex;
13825 + unsigned long pax_task_size = TASK_SIZE;
13827 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
13829 @@ -744,11 +933,80 @@ static int load_elf_binary(struct linux_
13831 /* OK, This is the point of no return */
13832 current->flags &= ~PF_FORKNOEXEC;
13833 - current->mm->def_flags = def_flags;
13835 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13836 + current->mm->pax_flags = 0UL;
13839 +#ifdef CONFIG_PAX_DLRESOLVE
13840 + current->mm->call_dl_resolve = 0UL;
13843 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
13844 + current->mm->call_syscall = 0UL;
13847 +#ifdef CONFIG_PAX_ASLR
13848 + current->mm->delta_mmap = 0UL;
13849 + current->mm->delta_stack = 0UL;
13852 + current->mm->def_flags = 0;
13854 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
13855 + if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
13856 + send_sig(SIGKILL, current, 0);
13857 + goto out_free_dentry;
13861 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
13862 + pax_set_initial_flags(bprm);
13863 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
13864 + if (pax_set_initial_flags_func)
13865 + (pax_set_initial_flags_func)(bprm);
13868 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
13869 + if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
13870 + current->mm->context.user_cs_limit = PAGE_SIZE;
13871 + current->mm->def_flags |= VM_PAGEEXEC;
13875 +#ifdef CONFIG_PAX_SEGMEXEC
13876 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
13877 + current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
13878 + current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
13879 + pax_task_size = SEGMEXEC_TASK_SIZE;
13883 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
13884 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13885 + set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
13886 + put_cpu_no_resched();
13890 +#ifdef CONFIG_PAX_ASLR
13891 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
13892 + current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
13893 + current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
13897 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
13898 may depend on the personality. */
13899 SET_PERSONALITY(loc->elf_ex, 0);
13901 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13902 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13903 + executable_stack = EXSTACK_DISABLE_X;
13904 + current->personality &= ~READ_IMPLIES_EXEC;
13908 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
13909 current->personality |= READ_IMPLIES_EXEC;
13911 @@ -829,6 +1087,20 @@ static int load_elf_binary(struct linux_
13913 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
13916 +#ifdef CONFIG_PAX_RANDMMAP
13917 + /* PaX: randomize base address at the default exe base if requested */
13918 + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
13919 +#ifdef CONFIG_SPARC64
13920 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
13922 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
13924 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
13925 + elf_flags |= MAP_FIXED;
13931 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
13932 @@ -861,9 +1133,9 @@ static int load_elf_binary(struct linux_
13933 * allowed task size. Note that p_filesz must always be
13934 * <= p_memsz so it is only necessary to check p_memsz.
13936 - if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
13937 - elf_ppnt->p_memsz > TASK_SIZE ||
13938 - TASK_SIZE - elf_ppnt->p_memsz < k) {
13939 + if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
13940 + elf_ppnt->p_memsz > pax_task_size ||
13941 + pax_task_size - elf_ppnt->p_memsz < k) {
13942 /* set_brk can never work. Avoid overflows. */
13943 send_sig(SIGKILL, current, 0);
13945 @@ -891,6 +1163,11 @@ static int load_elf_binary(struct linux_
13946 start_data += load_bias;
13947 end_data += load_bias;
13949 +#ifdef CONFIG_PAX_RANDMMAP
13950 + if (current->mm->pax_flags & MF_PAX_RANDMMAP)
13951 + elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
13954 /* Calling set_brk effectively mmaps the pages that we need
13955 * for the bss and break sections. We must do this before
13956 * mapping in the interpreter, to make sure it doesn't wind
13957 @@ -902,9 +1179,11 @@ static int load_elf_binary(struct linux_
13958 goto out_free_dentry;
13960 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
13961 - send_sig(SIGSEGV, current, 0);
13962 - retval = -EFAULT; /* Nobody gets to see this, but.. */
13963 - goto out_free_dentry;
13965 + * This bss-zeroing can fail if the ELF
13966 + * file specifies odd protections. So
13967 + * we don't check the return value
13971 if (elf_interpreter) {
13972 @@ -1141,8 +1420,10 @@ static int dump_seek(struct file *file,
13973 unsigned long n = off;
13976 - if (!dump_write(file, buf, n))
13977 + if (!dump_write(file, buf, n)) {
13978 + free_page((unsigned long)buf);
13983 free_page((unsigned long)buf);
13984 @@ -1154,7 +1435,7 @@ static int dump_seek(struct file *file,
13985 * Decide what to dump of a segment, part, all or none.
13987 static unsigned long vma_dump_size(struct vm_area_struct *vma,
13988 - unsigned long mm_flags)
13989 + unsigned long mm_flags, long signr)
13991 /* The vma can be set up to tell us the answer directly. */
13992 if (vma->vm_flags & VM_ALWAYSDUMP)
13993 @@ -1180,7 +1461,7 @@ static unsigned long vma_dump_size(struc
13994 if (vma->vm_file == NULL)
13997 - if (FILTER(MAPPED_PRIVATE))
13998 + if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
14002 @@ -1266,8 +1547,11 @@ static int writenote(struct memelfnote *
14005 #define DUMP_WRITE(addr, nr) \
14007 + gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
14008 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
14009 - goto end_coredump;
14010 + goto end_coredump; \
14012 #define DUMP_SEEK(off) \
14013 if (!dump_seek(file, (off))) \
14015 @@ -1973,7 +2257,7 @@ static int elf_core_dump(long signr, str
14016 phdr.p_offset = offset;
14017 phdr.p_vaddr = vma->vm_start;
14019 - phdr.p_filesz = vma_dump_size(vma, mm_flags);
14020 + phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
14021 phdr.p_memsz = vma->vm_end - vma->vm_start;
14022 offset += phdr.p_filesz;
14023 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
14024 @@ -2005,7 +2289,7 @@ static int elf_core_dump(long signr, str
14025 unsigned long addr;
14028 - end = vma->vm_start + vma_dump_size(vma, mm_flags);
14029 + end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
14031 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
14033 @@ -2025,6 +2309,7 @@ static int elf_core_dump(long signr, str
14034 flush_cache_page(tmp_vma, addr,
14035 page_to_pfn(page));
14036 kaddr = kmap(page);
14037 + gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
14038 if ((size += PAGE_SIZE) > limit ||
14039 !dump_write(file, kaddr,
14041 diff -urNp linux-2.6.27.4/fs/binfmt_flat.c linux-2.6.27.4/fs/binfmt_flat.c
14042 --- linux-2.6.27.4/fs/binfmt_flat.c 2008-10-22 17:38:01.000000000 -0400
14043 +++ linux-2.6.27.4/fs/binfmt_flat.c 2008-10-27 22:36:18.000000000 -0400
14044 @@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
14045 realdatastart = (unsigned long) -ENOMEM;
14046 printk("Unable to allocate RAM for process data, errno %d\n",
14047 (int)-realdatastart);
14048 + down_write(¤t->mm->mmap_sem);
14049 do_munmap(current->mm, textpos, text_len);
14050 + up_write(¤t->mm->mmap_sem);
14051 ret = realdatastart;
14054 @@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
14056 if (result >= (unsigned long)-4096) {
14057 printk("Unable to read data+bss, errno %d\n", (int)-result);
14058 + down_write(¤t->mm->mmap_sem);
14059 do_munmap(current->mm, textpos, text_len);
14060 do_munmap(current->mm, realdatastart, data_len + extra);
14061 + up_write(¤t->mm->mmap_sem);
14065 @@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
14067 if (result >= (unsigned long)-4096) {
14068 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
14069 + down_write(¤t->mm->mmap_sem);
14070 do_munmap(current->mm, textpos, text_len + data_len + extra +
14071 MAX_SHARED_LIBS * sizeof(unsigned long));
14072 + up_write(¤t->mm->mmap_sem);
14076 diff -urNp linux-2.6.27.4/fs/binfmt_misc.c linux-2.6.27.4/fs/binfmt_misc.c
14077 --- linux-2.6.27.4/fs/binfmt_misc.c 2008-10-22 17:38:01.000000000 -0400
14078 +++ linux-2.6.27.4/fs/binfmt_misc.c 2008-10-27 22:36:18.000000000 -0400
14079 @@ -696,7 +696,7 @@ static int bm_fill_super(struct super_bl
14080 static struct tree_descr bm_files[] = {
14081 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
14082 [3] = {"register", &bm_register_operations, S_IWUSR},
14083 - /* last one */ {""}
14084 + /* last one */ {"", NULL, 0}
14086 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
14088 diff -urNp linux-2.6.27.4/fs/bio.c linux-2.6.27.4/fs/bio.c
14089 --- linux-2.6.27.4/fs/bio.c 2008-10-22 17:38:01.000000000 -0400
14090 +++ linux-2.6.27.4/fs/bio.c 2008-10-27 22:36:18.000000000 -0400
14091 @@ -507,7 +507,7 @@ static int __bio_copy_iov(struct bio *bi
14093 while (bv_len && iov_idx < iov_count) {
14094 unsigned int bytes;
14096 + char __user *iov_addr;
14098 bytes = min_t(unsigned int,
14099 iov[iov_idx].iov_len - iov_off, bv_len);
14100 diff -urNp linux-2.6.27.4/fs/buffer.c linux-2.6.27.4/fs/buffer.c
14101 --- linux-2.6.27.4/fs/buffer.c 2008-10-22 17:38:01.000000000 -0400
14102 +++ linux-2.6.27.4/fs/buffer.c 2008-10-25 12:03:06.000000000 -0400
14104 #include <linux/bitops.h>
14105 #include <linux/mpage.h>
14106 #include <linux/bit_spinlock.h>
14107 +#include <linux/grsecurity.h>
14109 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
14111 @@ -2249,6 +2250,7 @@ int generic_cont_expand_simple(struct in
14114 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
14115 + gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
14116 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
14117 send_sig(SIGXFSZ, current, 0);
14119 diff -urNp linux-2.6.27.4/fs/cifs/cifs_uniupr.h linux-2.6.27.4/fs/cifs/cifs_uniupr.h
14120 --- linux-2.6.27.4/fs/cifs/cifs_uniupr.h 2008-10-22 17:38:01.000000000 -0400
14121 +++ linux-2.6.27.4/fs/cifs/cifs_uniupr.h 2008-10-27 22:36:18.000000000 -0400
14122 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
14123 {0x0490, 0x04cc, UniCaseRangeU0490},
14124 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
14125 {0xff40, 0xff5a, UniCaseRangeUff40},
14131 diff -urNp linux-2.6.27.4/fs/cifs/link.c linux-2.6.27.4/fs/cifs/link.c
14132 --- linux-2.6.27.4/fs/cifs/link.c 2008-10-22 17:38:01.000000000 -0400
14133 +++ linux-2.6.27.4/fs/cifs/link.c 2008-10-27 22:36:18.000000000 -0400
14134 @@ -318,7 +318,7 @@ cifs_readlink(struct dentry *direntry, c
14136 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
14138 - char *p = nd_get_link(nd);
14139 + const char *p = nd_get_link(nd);
14143 diff -urNp linux-2.6.27.4/fs/compat.c linux-2.6.27.4/fs/compat.c
14144 --- linux-2.6.27.4/fs/compat.c 2008-10-22 17:38:01.000000000 -0400
14145 +++ linux-2.6.27.4/fs/compat.c 2008-10-27 22:36:18.000000000 -0400
14147 #include <linux/poll.h>
14148 #include <linux/mm.h>
14149 #include <linux/eventpoll.h>
14150 +#include <linux/grsecurity.h>
14152 #include <asm/uaccess.h>
14153 #include <asm/mmu_context.h>
14154 @@ -1298,14 +1299,12 @@ static int compat_copy_strings(int argc,
14155 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
14158 -#ifdef CONFIG_STACK_GROWSUP
14159 ret = expand_stack_downwards(bprm->vma, pos);
14161 /* We've exceed the stack rlimit. */
14166 ret = get_user_pages(current, bprm->mm, pos,
14167 1, 1, 1, &page, NULL);
14169 @@ -1351,6 +1350,11 @@ int compat_do_execve(char * filename,
14170 compat_uptr_t __user *envp,
14171 struct pt_regs * regs)
14173 +#ifdef CONFIG_GRKERNSEC
14174 + struct file *old_exec_file;
14175 + struct acl_subject_label *old_acl;
14176 + struct rlimit old_rlim[RLIM_NLIMITS];
14178 struct linux_binprm *bprm;
14181 @@ -1371,6 +1375,14 @@ int compat_do_execve(char * filename,
14182 bprm->filename = filename;
14183 bprm->interp = filename;
14185 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
14186 + retval = -EAGAIN;
14187 + if (gr_handle_nproc())
14189 + retval = -EACCES;
14190 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
14193 retval = bprm_mm_init(bprm);
14196 @@ -1404,8 +1416,36 @@ int compat_do_execve(char * filename,
14200 + if (!gr_tpe_allow(file)) {
14201 + retval = -EACCES;
14205 + if (gr_check_crash_exec(file)) {
14206 + retval = -EACCES;
14210 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14212 + gr_handle_exec_args(bprm, (char __user * __user *)argv);
14214 +#ifdef CONFIG_GRKERNSEC
14215 + old_acl = current->acl;
14216 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14217 + old_exec_file = current->exec_file;
14219 + current->exec_file = file;
14222 + gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14224 retval = search_binary_handler(bprm, regs);
14226 +#ifdef CONFIG_GRKERNSEC
14227 + if (old_exec_file)
14228 + fput(old_exec_file);
14230 /* execve success */
14231 security_bprm_free(bprm);
14232 acct_update_integrals(current);
14233 @@ -1413,6 +1453,13 @@ int compat_do_execve(char * filename,
14237 +#ifdef CONFIG_GRKERNSEC
14238 + current->acl = old_acl;
14239 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14240 + fput(current->exec_file);
14241 + current->exec_file = old_exec_file;
14245 if (bprm->security)
14246 security_bprm_free(bprm);
14247 diff -urNp linux-2.6.27.4/fs/compat_ioctl.c linux-2.6.27.4/fs/compat_ioctl.c
14248 --- linux-2.6.27.4/fs/compat_ioctl.c 2008-10-22 17:38:01.000000000 -0400
14249 +++ linux-2.6.27.4/fs/compat_ioctl.c 2008-10-27 22:36:18.000000000 -0400
14250 @@ -1831,15 +1831,15 @@ struct ioctl_trans {
14253 #define HANDLE_IOCTL(cmd,handler) \
14254 - { (cmd), (ioctl_trans_handler_t)(handler) },
14255 + { (cmd), (ioctl_trans_handler_t)(handler), NULL },
14257 /* pointer to compatible structure or no argument */
14258 #define COMPATIBLE_IOCTL(cmd) \
14259 - { (cmd), do_ioctl32_pointer },
14260 + { (cmd), do_ioctl32_pointer, NULL },
14262 /* argument is an unsigned long integer, not a pointer */
14263 #define ULONG_IOCTL(cmd) \
14264 - { (cmd), (ioctl_trans_handler_t)sys_ioctl },
14265 + { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
14267 /* ioctl should not be warned about even if it's not implemented.
14268 Valid reasons to use this:
14269 diff -urNp linux-2.6.27.4/fs/debugfs/inode.c linux-2.6.27.4/fs/debugfs/inode.c
14270 --- linux-2.6.27.4/fs/debugfs/inode.c 2008-10-22 17:38:01.000000000 -0400
14271 +++ linux-2.6.27.4/fs/debugfs/inode.c 2008-10-27 22:36:18.000000000 -0400
14272 @@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
14274 static int debug_fill_super(struct super_block *sb, void *data, int silent)
14276 - static struct tree_descr debug_files[] = {{""}};
14277 + static struct tree_descr debug_files[] = {{"", NULL, 0}};
14279 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
14281 diff -urNp linux-2.6.27.4/fs/exec.c linux-2.6.27.4/fs/exec.c
14282 --- linux-2.6.27.4/fs/exec.c 2008-10-22 17:38:01.000000000 -0400
14283 +++ linux-2.6.27.4/fs/exec.c 2008-10-27 23:01:49.000000000 -0400
14285 #include <linux/cn_proc.h>
14286 #include <linux/audit.h>
14287 #include <linux/tracehook.h>
14288 +#include <linux/random.h>
14289 +#include <linux/grsecurity.h>
14291 +#ifdef CONFIG_PAX_REFCOUNT
14292 +#include <linux/kallsyms.h>
14293 +#include <linux/kdebug.h>
14296 #include <asm/uaccess.h>
14297 #include <asm/mmu_context.h>
14299 #include <linux/a.out.h>
14302 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
14303 +void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
14304 +EXPORT_SYMBOL(pax_set_initial_flags_func);
14308 char core_pattern[CORENAME_MAX_SIZE] = "core";
14309 int suid_dumpable = 0;
14310 @@ -172,18 +184,10 @@ static struct page *get_arg_page(struct
14316 -#ifdef CONFIG_STACK_GROWSUP
14318 - ret = expand_stack_downwards(bprm->vma, pos);
14323 - ret = get_user_pages(current, bprm->mm, pos,
14324 - 1, write, 1, &page, NULL);
14326 + if (0 > expand_stack_downwards(bprm->vma, pos))
14328 + if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
14332 @@ -256,6 +260,11 @@ static int __bprm_mm_init(struct linux_b
14333 vma->vm_start = vma->vm_end - PAGE_SIZE;
14335 vma->vm_flags = VM_STACK_FLAGS;
14337 +#ifdef CONFIG_PAX_SEGMEXEC
14338 + vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
14341 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
14342 err = insert_vm_struct(mm, vma);
14344 @@ -268,6 +277,11 @@ static int __bprm_mm_init(struct linux_b
14346 bprm->p = vma->vm_end - sizeof(void *);
14348 +#ifdef CONFIG_PAX_RANDUSTACK
14349 + if (randomize_va_space)
14350 + bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
14356 @@ -391,7 +405,7 @@ static int count(char __user * __user *
14365 @@ -531,6 +545,10 @@ static int shift_arg_pages(struct vm_are
14366 if (vma != find_vma(mm, new_start))
14369 +#ifdef CONFIG_PAX_SEGMEXEC
14370 + BUG_ON(pax_find_mirror_vma(vma));
14374 * cover the whole range: [new_start, old_end)
14376 @@ -619,6 +637,14 @@ int setup_arg_pages(struct linux_binprm
14377 bprm->exec -= stack_shift;
14379 down_write(&mm->mmap_sem);
14381 + /* Move stack pages down in memory. */
14382 + if (stack_shift) {
14383 + ret = shift_arg_pages(vma, stack_shift);
14388 vm_flags = VM_STACK_FLAGS;
14391 @@ -632,21 +658,24 @@ int setup_arg_pages(struct linux_binprm
14392 vm_flags &= ~VM_EXEC;
14393 vm_flags |= mm->def_flags;
14395 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14396 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14397 + vm_flags &= ~VM_EXEC;
14399 +#ifdef CONFIG_PAX_MPROTECT
14400 + if (mm->pax_flags & MF_PAX_MPROTECT)
14401 + vm_flags &= ~VM_MAYEXEC;
14407 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
14411 BUG_ON(prev != vma);
14413 - /* Move stack pages down in memory. */
14414 - if (stack_shift) {
14415 - ret = shift_arg_pages(vma, stack_shift);
14417 - up_write(&mm->mmap_sem);
14422 #ifdef CONFIG_STACK_GROWSUP
14423 stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
14425 @@ -658,7 +687,7 @@ int setup_arg_pages(struct linux_binprm
14428 up_write(&mm->mmap_sem);
14432 EXPORT_SYMBOL(setup_arg_pages);
14434 @@ -1278,6 +1307,11 @@ int do_execve(char * filename,
14435 char __user *__user *envp,
14436 struct pt_regs * regs)
14438 +#ifdef CONFIG_GRKERNSEC
14439 + struct file *old_exec_file;
14440 + struct acl_subject_label *old_acl;
14441 + struct rlimit old_rlim[RLIM_NLIMITS];
14443 struct linux_binprm *bprm;
14445 struct files_struct *displaced;
14446 @@ -1297,6 +1331,20 @@ int do_execve(char * filename,
14450 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
14452 + if (gr_handle_nproc()) {
14453 + allow_write_access(file);
14458 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
14459 + allow_write_access(file);
14467 @@ -1336,9 +1384,39 @@ int do_execve(char * filename,
14471 + if (!gr_tpe_allow(file)) {
14472 + retval = -EACCES;
14476 + if (gr_check_crash_exec(file)) {
14477 + retval = -EACCES;
14481 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14483 + gr_handle_exec_args(bprm, argv);
14485 +#ifdef CONFIG_GRKERNSEC
14486 + old_acl = current->acl;
14487 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14488 + old_exec_file = current->exec_file;
14490 + current->exec_file = file;
14493 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14497 current->flags &= ~PF_KTHREAD;
14498 retval = search_binary_handler(bprm,regs);
14500 +#ifdef CONFIG_GRKERNSEC
14501 + if (old_exec_file)
14502 + fput(old_exec_file);
14504 /* execve success */
14505 security_bprm_free(bprm);
14506 acct_update_integrals(current);
14507 @@ -1348,6 +1426,14 @@ int do_execve(char * filename,
14512 +#ifdef CONFIG_GRKERNSEC
14513 + current->acl = old_acl;
14514 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14515 + fput(current->exec_file);
14516 + current->exec_file = old_exec_file;
14520 if (bprm->security)
14521 security_bprm_free(bprm);
14522 @@ -1511,6 +1597,125 @@ out:
14526 +int pax_check_flags(unsigned long *flags)
14530 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
14531 + if (*flags & MF_PAX_SEGMEXEC)
14533 + *flags &= ~MF_PAX_SEGMEXEC;
14534 + retval = -EINVAL;
14538 + if ((*flags & MF_PAX_PAGEEXEC)
14540 +#ifdef CONFIG_PAX_PAGEEXEC
14541 + && (*flags & MF_PAX_SEGMEXEC)
14546 + *flags &= ~MF_PAX_PAGEEXEC;
14547 + retval = -EINVAL;
14550 + if ((*flags & MF_PAX_MPROTECT)
14552 +#ifdef CONFIG_PAX_MPROTECT
14553 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14558 + *flags &= ~MF_PAX_MPROTECT;
14559 + retval = -EINVAL;
14562 + if ((*flags & MF_PAX_EMUTRAMP)
14564 +#ifdef CONFIG_PAX_EMUTRAMP
14565 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14570 + *flags &= ~MF_PAX_EMUTRAMP;
14571 + retval = -EINVAL;
14577 +EXPORT_SYMBOL(pax_check_flags);
14579 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14580 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
14582 + struct task_struct *tsk = current;
14583 + struct mm_struct *mm = current->mm;
14584 + char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
14585 + char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
14586 + char *path_exec = NULL;
14587 + char *path_fault = NULL;
14588 + unsigned long start = 0UL, end = 0UL, offset = 0UL;
14590 + if (buffer_exec && buffer_fault) {
14591 + struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
14593 + down_read(&mm->mmap_sem);
14595 + while (vma && (!vma_exec || !vma_fault)) {
14596 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
14598 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
14600 + vma = vma->vm_next;
14603 + path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
14604 + if (IS_ERR(path_exec))
14605 + path_exec = "<path too long>";
14608 + start = vma_fault->vm_start;
14609 + end = vma_fault->vm_end;
14610 + offset = vma_fault->vm_pgoff << PAGE_SHIFT;
14611 + if (vma_fault->vm_file) {
14612 + path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
14613 + if (IS_ERR(path_fault))
14614 + path_fault = "<path too long>";
14616 + path_fault = "<anonymous mapping>";
14618 + up_read(&mm->mmap_sem);
14620 + if (tsk->signal->curr_ip)
14621 + 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);
14623 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
14624 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
14625 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
14626 + tsk->uid, tsk->euid, pc, sp);
14627 + free_page((unsigned long)buffer_exec);
14628 + free_page((unsigned long)buffer_fault);
14629 + pax_report_insns(pc, sp);
14630 + do_coredump(SIGKILL, SIGKILL, regs);
14634 +#ifdef CONFIG_PAX_REFCOUNT
14635 +void pax_report_refcount_overflow(struct pt_regs *regs)
14637 + printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
14638 + current->comm, task_pid_nr(current), current->uid, current->euid);
14639 + print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
14640 + show_registers(regs);
14641 + force_sig_specific(SIGKILL, current);
14645 static int zap_process(struct task_struct *start)
14647 struct task_struct *t;
14648 @@ -1757,6 +1962,10 @@ int do_coredump(long signr, int exit_cod
14650 clear_thread_flag(TIF_SIGPENDING);
14652 + if (signr == SIGKILL || signr == SIGILL)
14653 + gr_handle_brute_attach(current);
14654 + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
14657 * lock_kernel() because format_corename() is controlled by sysctl, which
14658 * uses lock_kernel()
14659 @@ -1777,6 +1986,8 @@ int do_coredump(long signr, int exit_cod
14662 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
14663 + if (!helper_argv)
14664 + goto fail_unlock;
14665 /* Terminate the string before the first option */
14666 delimit = strchr(corename, ' ');
14668 diff -urNp linux-2.6.27.4/fs/ext2/balloc.c linux-2.6.27.4/fs/ext2/balloc.c
14669 --- linux-2.6.27.4/fs/ext2/balloc.c 2008-10-22 17:38:01.000000000 -0400
14670 +++ linux-2.6.27.4/fs/ext2/balloc.c 2008-10-25 12:03:07.000000000 -0400
14671 @@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
14673 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
14674 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
14675 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
14676 + if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
14677 sbi->s_resuid != current->fsuid &&
14678 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
14680 diff -urNp linux-2.6.27.4/fs/ext3/balloc.c linux-2.6.27.4/fs/ext3/balloc.c
14681 --- linux-2.6.27.4/fs/ext3/balloc.c 2008-10-22 17:38:01.000000000 -0400
14682 +++ linux-2.6.27.4/fs/ext3/balloc.c 2008-10-25 12:03:07.000000000 -0400
14683 @@ -1435,14 +1435,14 @@ static int ext3_has_free_blocks(struct s
14684 DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
14686 cond = (free_blocks < root_blocks + 1 &&
14687 - !capable(CAP_SYS_RESOURCE) &&
14688 + !capable_nolog(CAP_SYS_RESOURCE) &&
14689 sbi->s_resuid != current->fsuid &&
14690 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
14692 vxdprintk(VXD_CBIT(dlim, 3),
14693 "ext3_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
14694 sb, free_blocks, root_blocks,
14695 - !capable(CAP_SYS_RESOURCE)?'1':'0',
14696 + !capable_nolog(CAP_SYS_RESOURCE)?'1':'0',
14697 sbi->s_resuid, current->fsuid, cond?0:1);
14699 return (cond ? 0 : 1);
14700 diff -urNp linux-2.6.27.4/fs/ext3/namei.c linux-2.6.27.4/fs/ext3/namei.c
14701 --- linux-2.6.27.4/fs/ext3/namei.c 2008-10-22 17:38:01.000000000 -0400
14702 +++ linux-2.6.27.4/fs/ext3/namei.c 2008-10-27 22:36:18.000000000 -0400
14703 @@ -1173,9 +1173,9 @@ static struct ext3_dir_entry_2 *do_split
14705 struct dx_map_entry *map;
14706 char *data1 = (*bh)->b_data, *data2;
14707 - unsigned split, move, size, i;
14708 + unsigned split, move, size;
14709 struct ext3_dir_entry_2 *de = NULL, *de2;
14713 bh2 = ext3_append (handle, dir, &newblock, &err);
14715 diff -urNp linux-2.6.27.4/fs/ext3/xattr.c linux-2.6.27.4/fs/ext3/xattr.c
14716 --- linux-2.6.27.4/fs/ext3/xattr.c 2008-10-22 17:38:01.000000000 -0400
14717 +++ linux-2.6.27.4/fs/ext3/xattr.c 2008-10-27 22:36:18.000000000 -0400
14722 -# define ea_idebug(f...)
14723 -# define ea_bdebug(f...)
14724 +# define ea_idebug(f...) do {} while (0)
14725 +# define ea_bdebug(f...) do {} while (0)
14728 static void ext3_xattr_cache_insert(struct buffer_head *);
14729 diff -urNp linux-2.6.27.4/fs/ext4/balloc.c linux-2.6.27.4/fs/ext4/balloc.c
14730 --- linux-2.6.27.4/fs/ext4/balloc.c 2008-10-22 17:38:01.000000000 -0400
14731 +++ linux-2.6.27.4/fs/ext4/balloc.c 2008-10-25 12:34:31.000000000 -0400
14732 @@ -1617,7 +1617,7 @@ ext4_fsblk_t ext4_has_free_blocks(struct
14734 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
14736 - if (!capable(CAP_SYS_RESOURCE) &&
14737 + if (!capable_nolog(CAP_SYS_RESOURCE) &&
14738 sbi->s_resuid != current->fsuid &&
14739 (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid)))
14740 root_blocks = ext4_r_blocks_count(sbi->s_es);
14741 diff -urNp linux-2.6.27.4/fs/ext4/namei.c linux-2.6.27.4/fs/ext4/namei.c
14742 --- linux-2.6.27.4/fs/ext4/namei.c 2008-10-22 17:38:01.000000000 -0400
14743 +++ linux-2.6.27.4/fs/ext4/namei.c 2008-10-27 22:36:18.000000000 -0400
14744 @@ -1176,9 +1176,9 @@ static struct ext4_dir_entry_2 *do_split
14746 struct dx_map_entry *map;
14747 char *data1 = (*bh)->b_data, *data2;
14748 - unsigned split, move, size, i;
14749 + unsigned split, move, size;
14750 struct ext4_dir_entry_2 *de = NULL, *de2;
14754 bh2 = ext4_append (handle, dir, &newblock, &err);
14756 diff -urNp linux-2.6.27.4/fs/fcntl.c linux-2.6.27.4/fs/fcntl.c
14757 --- linux-2.6.27.4/fs/fcntl.c 2008-10-22 17:38:01.000000000 -0400
14758 +++ linux-2.6.27.4/fs/fcntl.c 2008-10-25 12:15:49.000000000 -0400
14760 #include <linux/rcupdate.h>
14761 #include <linux/pid_namespace.h>
14762 #include <linux/vs_limit.h>
14763 +#include <linux/grsecurity.h>
14765 #include <asm/poll.h>
14766 #include <asm/siginfo.h>
14767 @@ -259,6 +260,7 @@ static long do_fcntl(int fd, unsigned in
14770 case F_DUPFD_CLOEXEC:
14771 + gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
14772 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
14774 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
14775 @@ -403,7 +405,8 @@ static inline int sigio_perm(struct task
14776 return (((fown->euid == 0) ||
14777 (fown->euid == p->suid) || (fown->euid == p->uid) ||
14778 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
14779 - !security_file_send_sigiotask(p, fown, sig));
14780 + !security_file_send_sigiotask(p, fown, sig) &&
14781 + !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
14784 static void send_sigio_to_task(struct task_struct *p,
14785 diff -urNp linux-2.6.27.4/fs/file.c linux-2.6.27.4/fs/file.c
14786 --- linux-2.6.27.4/fs/file.c 2008-10-22 17:38:01.000000000 -0400
14787 +++ linux-2.6.27.4/fs/file.c 2008-10-26 03:47:18.000000000 -0400
14789 #include <linux/rcupdate.h>
14790 #include <linux/workqueue.h>
14791 #include <linux/vs_limit.h>
14792 +#include <linux/grsecurity.h>
14794 struct fdtable_defer {
14796 @@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi
14797 * N.B. For clone tasks sharing a files structure, this test
14798 * will limit the total number of files that can be opened.
14801 + gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
14802 if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
14805 diff -urNp linux-2.6.27.4/fs/fuse/control.c linux-2.6.27.4/fs/fuse/control.c
14806 --- linux-2.6.27.4/fs/fuse/control.c 2008-10-22 17:38:01.000000000 -0400
14807 +++ linux-2.6.27.4/fs/fuse/control.c 2008-10-27 22:36:18.000000000 -0400
14808 @@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
14810 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
14812 - struct tree_descr empty_descr = {""};
14813 + struct tree_descr empty_descr = {"", NULL, 0};
14814 struct fuse_conn *fc;
14817 diff -urNp linux-2.6.27.4/fs/fuse/dir.c linux-2.6.27.4/fs/fuse/dir.c
14818 --- linux-2.6.27.4/fs/fuse/dir.c 2008-10-22 17:38:01.000000000 -0400
14819 +++ linux-2.6.27.4/fs/fuse/dir.c 2008-10-27 22:36:18.000000000 -0400
14820 @@ -1072,7 +1072,7 @@ static char *read_link(struct dentry *de
14824 -static void free_link(char *link)
14825 +static void free_link(const char *link)
14828 free_page((unsigned long) link);
14829 diff -urNp linux-2.6.27.4/fs/hfs/inode.c linux-2.6.27.4/fs/hfs/inode.c
14830 --- linux-2.6.27.4/fs/hfs/inode.c 2008-10-22 17:38:01.000000000 -0400
14831 +++ linux-2.6.27.4/fs/hfs/inode.c 2008-10-27 22:36:18.000000000 -0400
14832 @@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
14834 if (S_ISDIR(main_inode->i_mode)) {
14835 if (fd.entrylength < sizeof(struct hfs_cat_dir))
14838 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
14839 sizeof(struct hfs_cat_dir));
14840 if (rec.type != HFS_CDR_DIR ||
14841 @@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
14842 sizeof(struct hfs_cat_file));
14844 if (fd.entrylength < sizeof(struct hfs_cat_file))
14847 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
14848 sizeof(struct hfs_cat_file));
14849 if (rec.type != HFS_CDR_FIL ||
14850 diff -urNp linux-2.6.27.4/fs/hfsplus/inode.c linux-2.6.27.4/fs/hfsplus/inode.c
14851 --- linux-2.6.27.4/fs/hfsplus/inode.c 2008-10-22 17:38:01.000000000 -0400
14852 +++ linux-2.6.27.4/fs/hfsplus/inode.c 2008-10-27 22:36:18.000000000 -0400
14853 @@ -417,7 +417,7 @@ int hfsplus_cat_read_inode(struct inode
14854 struct hfsplus_cat_folder *folder = &entry.folder;
14856 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
14859 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
14860 sizeof(struct hfsplus_cat_folder));
14861 hfsplus_get_perms(inode, &folder->permissions, 1);
14862 @@ -434,7 +434,7 @@ int hfsplus_cat_read_inode(struct inode
14863 struct hfsplus_cat_file *file = &entry.file;
14865 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
14868 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
14869 sizeof(struct hfsplus_cat_file));
14871 @@ -490,7 +490,7 @@ int hfsplus_cat_write_inode(struct inode
14872 struct hfsplus_cat_folder *folder = &entry.folder;
14874 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
14877 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
14878 sizeof(struct hfsplus_cat_folder));
14879 /* simple node checks? */
14880 @@ -512,7 +512,7 @@ int hfsplus_cat_write_inode(struct inode
14881 struct hfsplus_cat_file *file = &entry.file;
14883 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
14886 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
14887 sizeof(struct hfsplus_cat_file));
14888 hfsplus_inode_write_fork(inode, &file->data_fork);
14889 diff -urNp linux-2.6.27.4/fs/jffs2/debug.h linux-2.6.27.4/fs/jffs2/debug.h
14890 --- linux-2.6.27.4/fs/jffs2/debug.h 2008-10-22 17:38:01.000000000 -0400
14891 +++ linux-2.6.27.4/fs/jffs2/debug.h 2008-10-27 22:36:18.000000000 -0400
14892 @@ -52,13 +52,13 @@
14893 #if CONFIG_JFFS2_FS_DEBUG > 0
14897 +#define D1(x) do {} while (0);
14900 #if CONFIG_JFFS2_FS_DEBUG > 1
14904 +#define D2(x) do {} while (0);
14907 /* The prefixes of JFFS2 messages */
14908 @@ -114,73 +114,73 @@
14909 #ifdef JFFS2_DBG_READINODE_MESSAGES
14910 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14912 -#define dbg_readinode(fmt, ...)
14913 +#define dbg_readinode(fmt, ...) do {} while (0)
14915 #ifdef JFFS2_DBG_READINODE2_MESSAGES
14916 #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14918 -#define dbg_readinode2(fmt, ...)
14919 +#define dbg_readinode2(fmt, ...) do {} while (0)
14922 /* Fragtree build debugging messages */
14923 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
14924 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14926 -#define dbg_fragtree(fmt, ...)
14927 +#define dbg_fragtree(fmt, ...) do {} while (0)
14929 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
14930 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14932 -#define dbg_fragtree2(fmt, ...)
14933 +#define dbg_fragtree2(fmt, ...) do {} while (0)
14936 /* Directory entry list manilulation debugging messages */
14937 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
14938 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14940 -#define dbg_dentlist(fmt, ...)
14941 +#define dbg_dentlist(fmt, ...) do {} while (0)
14944 /* Print the messages about manipulating node_refs */
14945 #ifdef JFFS2_DBG_NODEREF_MESSAGES
14946 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14948 -#define dbg_noderef(fmt, ...)
14949 +#define dbg_noderef(fmt, ...) do {} while (0)
14952 /* Manipulations with the list of inodes (JFFS2 inocache) */
14953 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
14954 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14956 -#define dbg_inocache(fmt, ...)
14957 +#define dbg_inocache(fmt, ...) do {} while (0)
14960 /* Summary debugging messages */
14961 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
14962 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14964 -#define dbg_summary(fmt, ...)
14965 +#define dbg_summary(fmt, ...) do {} while (0)
14968 /* File system build messages */
14969 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
14970 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14972 -#define dbg_fsbuild(fmt, ...)
14973 +#define dbg_fsbuild(fmt, ...) do {} while (0)
14976 /* Watch the object allocations */
14977 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
14978 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14980 -#define dbg_memalloc(fmt, ...)
14981 +#define dbg_memalloc(fmt, ...) do {} while (0)
14984 /* Watch the XATTR subsystem */
14985 #ifdef JFFS2_DBG_XATTR_MESSAGES
14986 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
14988 -#define dbg_xattr(fmt, ...)
14989 +#define dbg_xattr(fmt, ...) do {} while (0)
14992 /* "Sanity" checks */
14993 diff -urNp linux-2.6.27.4/fs/jffs2/erase.c linux-2.6.27.4/fs/jffs2/erase.c
14994 --- linux-2.6.27.4/fs/jffs2/erase.c 2008-10-22 17:38:01.000000000 -0400
14995 +++ linux-2.6.27.4/fs/jffs2/erase.c 2008-10-27 22:36:18.000000000 -0400
14996 @@ -431,7 +431,8 @@ static void jffs2_mark_erased_block(stru
14997 struct jffs2_unknown_node marker = {
14998 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
14999 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15000 - .totlen = cpu_to_je32(c->cleanmarker_size)
15001 + .totlen = cpu_to_je32(c->cleanmarker_size),
15002 + .hdr_crc = cpu_to_je32(0)
15005 jffs2_prealloc_raw_node_refs(c, jeb, 1);
15006 diff -urNp linux-2.6.27.4/fs/jffs2/summary.h linux-2.6.27.4/fs/jffs2/summary.h
15007 --- linux-2.6.27.4/fs/jffs2/summary.h 2008-10-22 17:38:01.000000000 -0400
15008 +++ linux-2.6.27.4/fs/jffs2/summary.h 2008-10-27 22:36:18.000000000 -0400
15009 @@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
15011 #define jffs2_sum_active() (0)
15012 #define jffs2_sum_init(a) (0)
15013 -#define jffs2_sum_exit(a)
15014 -#define jffs2_sum_disable_collecting(a)
15015 +#define jffs2_sum_exit(a) do {} while (0)
15016 +#define jffs2_sum_disable_collecting(a) do {} while (0)
15017 #define jffs2_sum_is_disabled(a) (0)
15018 -#define jffs2_sum_reset_collected(a)
15019 +#define jffs2_sum_reset_collected(a) do {} while (0)
15020 #define jffs2_sum_add_kvec(a,b,c,d) (0)
15021 -#define jffs2_sum_move_collected(a,b)
15022 +#define jffs2_sum_move_collected(a,b) do {} while (0)
15023 #define jffs2_sum_write_sumnode(a) (0)
15024 -#define jffs2_sum_add_padding_mem(a,b)
15025 -#define jffs2_sum_add_inode_mem(a,b,c)
15026 -#define jffs2_sum_add_dirent_mem(a,b,c)
15027 -#define jffs2_sum_add_xattr_mem(a,b,c)
15028 -#define jffs2_sum_add_xref_mem(a,b,c)
15029 +#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
15030 +#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
15031 +#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
15032 +#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
15033 +#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
15034 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
15036 #endif /* CONFIG_JFFS2_SUMMARY */
15037 diff -urNp linux-2.6.27.4/fs/jffs2/wbuf.c linux-2.6.27.4/fs/jffs2/wbuf.c
15038 --- linux-2.6.27.4/fs/jffs2/wbuf.c 2008-10-22 17:38:01.000000000 -0400
15039 +++ linux-2.6.27.4/fs/jffs2/wbuf.c 2008-10-27 22:36:18.000000000 -0400
15040 @@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
15042 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
15043 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15044 - .totlen = constant_cpu_to_je32(8)
15045 + .totlen = constant_cpu_to_je32(8),
15046 + .hdr_crc = constant_cpu_to_je32(0)
15050 diff -urNp linux-2.6.27.4/fs/locks.c linux-2.6.27.4/fs/locks.c
15051 --- linux-2.6.27.4/fs/locks.c 2008-10-22 17:38:01.000000000 -0400
15052 +++ linux-2.6.27.4/fs/locks.c 2008-10-27 22:36:18.000000000 -0400
15053 @@ -2005,16 +2005,16 @@ void locks_remove_flock(struct file *fil
15056 if (filp->f_op && filp->f_op->flock) {
15057 - struct file_lock fl = {
15058 + struct file_lock flock = {
15059 .fl_pid = current->tgid,
15061 .fl_flags = FL_FLOCK,
15062 .fl_type = F_UNLCK,
15063 .fl_end = OFFSET_MAX,
15065 - filp->f_op->flock(filp, F_SETLKW, &fl);
15066 - if (fl.fl_ops && fl.fl_ops->fl_release_private)
15067 - fl.fl_ops->fl_release_private(&fl);
15068 + filp->f_op->flock(filp, F_SETLKW, &flock);
15069 + if (flock.fl_ops && flock.fl_ops->fl_release_private)
15070 + flock.fl_ops->fl_release_private(&flock);
15074 diff -urNp linux-2.6.27.4/fs/namei.c linux-2.6.27.4/fs/namei.c
15075 --- linux-2.6.27.4/fs/namei.c 2008-10-22 17:38:01.000000000 -0400
15076 +++ linux-2.6.27.4/fs/namei.c 2008-10-27 22:36:18.000000000 -0400
15078 #include <linux/vs_device.h>
15079 #include <linux/vs_context.h>
15080 #include <linux/pid_namespace.h>
15081 +#include <linux/grsecurity.h>
15083 #include <asm/uaccess.h>
15085 #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
15086 @@ -646,7 +648,7 @@ static __always_inline int __do_follow_l
15087 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
15088 error = PTR_ERR(cookie);
15089 if (!IS_ERR(cookie)) {
15090 - char *s = nd_get_link(nd);
15091 + const char *s = nd_get_link(nd);
15094 error = __vfs_follow_link(nd, s);
15095 @@ -677,6 +679,13 @@ static inline int do_follow_link(struct
15096 err = security_inode_follow_link(path->dentry, nd);
15100 + if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
15101 + path->dentry->d_inode, path->dentry, nd->path.mnt)) {
15106 current->link_count++;
15107 current->total_link_count++;
15109 @@ -1025,11 +1034,18 @@ return_reval:
15113 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
15114 + path_put(&nd->path);
15119 path_put_conditional(&next, nd);
15122 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
15125 path_put(&nd->path);
15128 @@ -1613,9 +1629,17 @@ static int __open_namei_create(struct na
15130 struct dentry *dir = nd->path.dentry;
15132 + if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
15134 + goto out_unlock_dput;
15137 if (!IS_POSIXACL(dir->d_inode))
15138 mode &= ~current->fs->umask;
15139 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
15141 + gr_handle_create(path->dentry, nd->path.mnt);
15143 mutex_unlock(&dir->d_inode->i_mutex);
15144 dput(nd->path.dentry);
15145 nd->path.dentry = path->dentry;
15146 @@ -1696,6 +1720,17 @@ struct file *do_filp_open(int dfd, const
15149 return ERR_PTR(error);
15151 + if (gr_handle_rawio(nd.path.dentry->d_inode)) {
15156 + if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
15164 @@ -1759,6 +1794,20 @@ do_last:
15166 * It already exists.
15169 + if (gr_handle_rawio(path.dentry->d_inode)) {
15171 + goto exit_mutex_unlock;
15173 + if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
15175 + goto exit_mutex_unlock;
15177 + if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
15179 + goto exit_mutex_unlock;
15182 mutex_unlock(&dir->d_inode->i_mutex);
15183 audit_inode(pathname, path.dentry);
15185 @@ -1843,6 +1892,13 @@ do_link:
15186 error = security_inode_follow_link(path.dentry, &nd);
15190 + if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
15191 + path.dentry, nd.path.mnt)) {
15196 error = __do_follow_link(&path, &nd);
15198 /* Does someone understand code flow here? Or it is only
15199 @@ -2015,9 +2071,21 @@ asmlinkage long sys_mknodat(int dfd, con
15200 error = may_mknod(mode);
15204 + if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
15209 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
15214 error = mnt_want_write(nd.path.mnt);
15218 switch (mode & S_IFMT) {
15219 case 0: case S_IFREG:
15220 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
15221 @@ -2031,6 +2099,9 @@ asmlinkage long sys_mknodat(int dfd, con
15224 mnt_drop_write(nd.path.mnt);
15227 + gr_handle_create(dentry, nd.path.mnt);
15231 @@ -2084,6 +2155,11 @@ asmlinkage long sys_mkdirat(int dfd, con
15232 if (IS_ERR(dentry))
15235 + if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
15240 if (!IS_POSIXACL(nd.path.dentry->d_inode))
15241 mode &= ~current->fs->umask;
15242 error = mnt_want_write(nd.path.mnt);
15243 @@ -2091,6 +2167,10 @@ asmlinkage long sys_mkdirat(int dfd, con
15245 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
15246 mnt_drop_write(nd.path.mnt);
15249 + gr_handle_create(dentry, nd.path.mnt);
15254 @@ -2172,6 +2252,8 @@ static long do_rmdir(int dfd, const char
15256 struct dentry *dentry;
15257 struct nameidata nd;
15258 + ino_t saved_ino = 0;
15259 + dev_t saved_dev = 0;
15261 error = user_path_parent(dfd, pathname, &nd, &name);
15263 @@ -2193,11 +2275,26 @@ static long do_rmdir(int dfd, const char
15264 error = PTR_ERR(dentry);
15265 if (IS_ERR(dentry))
15268 + if (dentry->d_inode != NULL) {
15269 + if (dentry->d_inode->i_nlink <= 1) {
15270 + saved_ino = dentry->d_inode->i_ino;
15271 + saved_dev = dentry->d_inode->i_sb->s_dev;
15274 + if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
15280 error = mnt_want_write(nd.path.mnt);
15283 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
15284 mnt_drop_write(nd.path.mnt);
15285 + if (!error && (saved_dev || saved_ino))
15286 + gr_handle_delete(saved_ino, saved_dev);
15290 @@ -2257,6 +2354,8 @@ static long do_unlinkat(int dfd, const c
15291 struct dentry *dentry;
15292 struct nameidata nd;
15293 struct inode *inode = NULL;
15294 + ino_t saved_ino = 0;
15295 + dev_t saved_dev = 0;
15297 error = user_path_parent(dfd, pathname, &nd, &name);
15299 @@ -2273,12 +2372,25 @@ static long do_unlinkat(int dfd, const c
15300 if (nd.last.name[nd.last.len])
15302 inode = dentry->d_inode;
15305 + if (inode->i_nlink <= 1) {
15306 + saved_ino = inode->i_ino;
15307 + saved_dev = inode->i_sb->s_dev;
15310 atomic_inc(&inode->i_count);
15312 + if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
15317 error = mnt_want_write(nd.path.mnt);
15320 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
15321 + if (!error && (saved_ino || saved_dev))
15322 + gr_handle_delete(saved_ino, saved_dev);
15323 mnt_drop_write(nd.path.mnt);
15326 @@ -2356,10 +2468,17 @@ asmlinkage long sys_symlinkat(const char
15327 if (IS_ERR(dentry))
15330 + if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
15335 error = mnt_want_write(nd.path.mnt);
15338 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
15340 + gr_handle_create(dentry, nd.path.mnt);
15341 mnt_drop_write(nd.path.mnt);
15344 @@ -2453,10 +2572,26 @@ asmlinkage long sys_linkat(int olddfd, c
15345 error = PTR_ERR(new_dentry);
15346 if (IS_ERR(new_dentry))
15349 + if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
15350 + old_path.dentry->d_inode,
15351 + old_path.dentry->d_inode->i_mode, to)) {
15356 + if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
15357 + old_path.dentry, old_path.mnt, to)) {
15362 error = mnt_want_write(nd.path.mnt);
15365 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
15367 + gr_handle_create(new_dentry, nd.path.mnt);
15368 mnt_drop_write(nd.path.mnt);
15371 @@ -2612,8 +2747,10 @@ int vfs_rename(struct inode *old_dir, st
15372 error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
15374 error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
15377 const char *new_name = old_dentry->d_name.name;
15379 fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
15380 new_dentry->d_inode, old_dentry);
15382 @@ -2685,11 +2822,21 @@ asmlinkage long sys_renameat(int olddfd,
15383 if (new_dentry == trap)
15386 + error = gr_acl_handle_rename(new_dentry, newnd.path.dentry, newnd.path.mnt,
15387 + old_dentry, old_dir->d_inode, oldnd.path.mnt,
15392 error = mnt_want_write(oldnd.path.mnt);
15395 error = vfs_rename(old_dir->d_inode, old_dentry,
15396 new_dir->d_inode, new_dentry);
15398 + gr_handle_rename(old_dir->d_inode, newnd.path.dentry->d_inode, old_dentry,
15399 + new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
15401 mnt_drop_write(oldnd.path.mnt);
15404 diff -urNp linux-2.6.27.4/fs/namespace.c linux-2.6.27.4/fs/namespace.c
15405 --- linux-2.6.27.4/fs/namespace.c 2008-10-22 17:38:01.000000000 -0400
15406 +++ linux-2.6.27.4/fs/namespace.c 2008-10-25 12:03:07.000000000 -0400
15408 #include <linux/vs_tag.h>
15409 #include <linux/vserver/space.h>
15410 #include <linux/vserver/global.h>
15411 +#include <linux/grsecurity.h>
15412 #include <asm/uaccess.h>
15413 #include <asm/unistd.h>
15415 @@ -1094,6 +1095,8 @@ static int do_umount(struct vfsmount *mn
15417 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
15420 + gr_log_remount(mnt->mnt_devname, retval);
15422 up_write(&sb->s_umount);
15424 @@ -1117,6 +1120,9 @@ static int do_umount(struct vfsmount *mn
15425 security_sb_umount_busy(mnt);
15426 up_write(&namespace_sem);
15427 release_mounts(&umount_list);
15429 + gr_log_unmount(mnt->mnt_devname, retval);
15434 @@ -1949,6 +1955,11 @@ long do_mount(char *dev_name, char *dir_
15438 + if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
15443 if (flags & MS_REMOUNT)
15444 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
15446 @@ -1963,6 +1974,9 @@ long do_mount(char *dev_name, char *dir_
15447 dev_name, data_page);
15449 path_put(&nd.path);
15451 + gr_log_mount(dev_name, dir_name, retval);
15456 @@ -2075,6 +2089,9 @@ asmlinkage long sys_mount(char __user *
15460 + if (gr_handle_chroot_pivot())
15464 retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
15465 flags, (void *)data_page);
15466 diff -urNp linux-2.6.27.4/fs/nfs/nfs4proc.c linux-2.6.27.4/fs/nfs/nfs4proc.c
15467 --- linux-2.6.27.4/fs/nfs/nfs4proc.c 2008-10-22 17:38:01.000000000 -0400
15468 +++ linux-2.6.27.4/fs/nfs/nfs4proc.c 2008-10-27 22:36:18.000000000 -0400
15469 @@ -653,7 +653,7 @@ static int _nfs4_do_open_reclaim(struct
15470 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
15472 struct nfs_server *server = NFS_SERVER(state->inode);
15473 - struct nfs4_exception exception = { };
15474 + struct nfs4_exception exception = {0, 0};
15477 err = _nfs4_do_open_reclaim(ctx, state);
15478 @@ -695,7 +695,7 @@ static int _nfs4_open_delegation_recall(
15480 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
15482 - struct nfs4_exception exception = { };
15483 + struct nfs4_exception exception = {0, 0};
15484 struct nfs_server *server = NFS_SERVER(state->inode);
15487 @@ -988,7 +988,7 @@ static int _nfs4_open_expired(struct nfs
15488 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
15490 struct nfs_server *server = NFS_SERVER(state->inode);
15491 - struct nfs4_exception exception = { };
15492 + struct nfs4_exception exception = {0, 0};
15496 @@ -1090,7 +1090,7 @@ out_err:
15498 static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
15500 - struct nfs4_exception exception = { };
15501 + struct nfs4_exception exception = {0, 0};
15502 struct nfs4_state *res;
15505 @@ -1181,7 +1181,7 @@ static int nfs4_do_setattr(struct inode
15506 struct nfs4_state *state)
15508 struct nfs_server *server = NFS_SERVER(inode);
15509 - struct nfs4_exception exception = { };
15510 + struct nfs4_exception exception = {0, 0};
15513 err = nfs4_handle_exception(server,
15514 @@ -1494,7 +1494,7 @@ static int _nfs4_server_capabilities(str
15516 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
15518 - struct nfs4_exception exception = { };
15519 + struct nfs4_exception exception = {0, 0};
15522 err = nfs4_handle_exception(server,
15523 @@ -1527,7 +1527,7 @@ static int _nfs4_lookup_root(struct nfs_
15524 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
15525 struct nfs_fsinfo *info)
15527 - struct nfs4_exception exception = { };
15528 + struct nfs4_exception exception = {0, 0};
15531 err = nfs4_handle_exception(server,
15532 @@ -1616,7 +1616,7 @@ static int _nfs4_proc_getattr(struct nfs
15534 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15536 - struct nfs4_exception exception = { };
15537 + struct nfs4_exception exception = {0, 0};
15540 err = nfs4_handle_exception(server,
15541 @@ -1702,7 +1702,7 @@ static int nfs4_proc_lookupfh(struct nfs
15542 struct qstr *name, struct nfs_fh *fhandle,
15543 struct nfs_fattr *fattr)
15545 - struct nfs4_exception exception = { };
15546 + struct nfs4_exception exception = {0, 0};
15549 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
15550 @@ -1731,7 +1731,7 @@ static int _nfs4_proc_lookup(struct inod
15552 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15554 - struct nfs4_exception exception = { };
15555 + struct nfs4_exception exception = {0, 0};
15558 err = nfs4_handle_exception(NFS_SERVER(dir),
15559 @@ -1795,7 +1795,7 @@ static int _nfs4_proc_access(struct inod
15561 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
15563 - struct nfs4_exception exception = { };
15564 + struct nfs4_exception exception = {0, 0};
15567 err = nfs4_handle_exception(NFS_SERVER(inode),
15568 @@ -1850,7 +1850,7 @@ static int _nfs4_proc_readlink(struct in
15569 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
15570 unsigned int pgbase, unsigned int pglen)
15572 - struct nfs4_exception exception = { };
15573 + struct nfs4_exception exception = {0, 0};
15576 err = nfs4_handle_exception(NFS_SERVER(inode),
15577 @@ -1947,7 +1947,7 @@ static int _nfs4_proc_remove(struct inod
15579 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
15581 - struct nfs4_exception exception = { };
15582 + struct nfs4_exception exception = {0, 0};
15585 err = nfs4_handle_exception(NFS_SERVER(dir),
15586 @@ -2019,7 +2019,7 @@ static int _nfs4_proc_rename(struct inod
15587 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
15588 struct inode *new_dir, struct qstr *new_name)
15590 - struct nfs4_exception exception = { };
15591 + struct nfs4_exception exception = {0, 0};
15594 err = nfs4_handle_exception(NFS_SERVER(old_dir),
15595 @@ -2066,7 +2066,7 @@ static int _nfs4_proc_link(struct inode
15597 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
15599 - struct nfs4_exception exception = { };
15600 + struct nfs4_exception exception = {0, 0};
15603 err = nfs4_handle_exception(NFS_SERVER(inode),
15604 @@ -2157,7 +2157,7 @@ out:
15605 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
15606 struct page *page, unsigned int len, struct iattr *sattr)
15608 - struct nfs4_exception exception = { };
15609 + struct nfs4_exception exception = {0, 0};
15612 err = nfs4_handle_exception(NFS_SERVER(dir),
15613 @@ -2188,7 +2188,7 @@ out:
15614 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
15615 struct iattr *sattr)
15617 - struct nfs4_exception exception = { };
15618 + struct nfs4_exception exception = {0, 0};
15621 err = nfs4_handle_exception(NFS_SERVER(dir),
15622 @@ -2237,7 +2237,7 @@ static int _nfs4_proc_readdir(struct den
15623 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
15624 u64 cookie, struct page *page, unsigned int count, int plus)
15626 - struct nfs4_exception exception = { };
15627 + struct nfs4_exception exception = {0, 0};
15630 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
15631 @@ -2285,7 +2285,7 @@ out:
15632 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
15633 struct iattr *sattr, dev_t rdev)
15635 - struct nfs4_exception exception = { };
15636 + struct nfs4_exception exception = {0, 0};
15639 err = nfs4_handle_exception(NFS_SERVER(dir),
15640 @@ -2314,7 +2314,7 @@ static int _nfs4_proc_statfs(struct nfs_
15642 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
15644 - struct nfs4_exception exception = { };
15645 + struct nfs4_exception exception = {0, 0};
15648 err = nfs4_handle_exception(server,
15649 @@ -2342,7 +2342,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
15651 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
15653 - struct nfs4_exception exception = { };
15654 + struct nfs4_exception exception = {0, 0};
15658 @@ -2385,7 +2385,7 @@ static int _nfs4_proc_pathconf(struct nf
15659 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
15660 struct nfs_pathconf *pathconf)
15662 - struct nfs4_exception exception = { };
15663 + struct nfs4_exception exception = {0, 0};
15667 @@ -2672,7 +2672,7 @@ out_free:
15669 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
15671 - struct nfs4_exception exception = { };
15672 + struct nfs4_exception exception = {0, 0};
15675 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
15676 @@ -2729,7 +2729,7 @@ static int __nfs4_proc_set_acl(struct in
15678 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
15680 - struct nfs4_exception exception = { };
15681 + struct nfs4_exception exception = {0, 0};
15684 err = nfs4_handle_exception(NFS_SERVER(inode),
15685 @@ -3020,7 +3020,7 @@ out:
15686 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
15688 struct nfs_server *server = NFS_SERVER(inode);
15689 - struct nfs4_exception exception = { };
15690 + struct nfs4_exception exception = {0, 0};
15693 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
15694 @@ -3095,7 +3095,7 @@ out:
15696 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
15698 - struct nfs4_exception exception = { };
15699 + struct nfs4_exception exception = {0, 0};
15703 @@ -3445,7 +3445,7 @@ static int _nfs4_do_setlk(struct nfs4_st
15704 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
15706 struct nfs_server *server = NFS_SERVER(state->inode);
15707 - struct nfs4_exception exception = { };
15708 + struct nfs4_exception exception = {0, 0};
15712 @@ -3463,7 +3463,7 @@ static int nfs4_lock_reclaim(struct nfs4
15713 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
15715 struct nfs_server *server = NFS_SERVER(state->inode);
15716 - struct nfs4_exception exception = { };
15717 + struct nfs4_exception exception = {0, 0};
15720 err = nfs4_set_lock_state(state, request);
15721 @@ -3524,7 +3524,7 @@ out:
15723 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
15725 - struct nfs4_exception exception = { };
15726 + struct nfs4_exception exception = {0, 0};
15730 @@ -3574,7 +3574,7 @@ nfs4_proc_lock(struct file *filp, int cm
15731 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
15733 struct nfs_server *server = NFS_SERVER(state->inode);
15734 - struct nfs4_exception exception = { };
15735 + struct nfs4_exception exception = {0, 0};
15738 err = nfs4_set_lock_state(state, fl);
15739 diff -urNp linux-2.6.27.4/fs/nfsd/export.c linux-2.6.27.4/fs/nfsd/export.c
15740 --- linux-2.6.27.4/fs/nfsd/export.c 2008-10-22 17:38:01.000000000 -0400
15741 +++ linux-2.6.27.4/fs/nfsd/export.c 2008-10-27 22:36:18.000000000 -0400
15742 @@ -473,7 +473,7 @@ static int secinfo_parse(char **mesg, ch
15743 * probably discover the problem when someone fails to
15746 - if (f->pseudoflavor < 0)
15747 + if ((s32)f->pseudoflavor < 0)
15749 err = get_int(mesg, &f->flags);
15751 diff -urNp linux-2.6.27.4/fs/nls/nls_base.c linux-2.6.27.4/fs/nls/nls_base.c
15752 --- linux-2.6.27.4/fs/nls/nls_base.c 2008-10-22 17:38:01.000000000 -0400
15753 +++ linux-2.6.27.4/fs/nls/nls_base.c 2008-10-27 22:36:18.000000000 -0400
15754 @@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
15755 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
15756 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
15757 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
15758 - {0, /* end of table */}
15759 + {0, 0, 0, 0, 0, /* end of table */}
15763 diff -urNp linux-2.6.27.4/fs/ntfs/file.c linux-2.6.27.4/fs/ntfs/file.c
15764 --- linux-2.6.27.4/fs/ntfs/file.c 2008-10-22 17:38:01.000000000 -0400
15765 +++ linux-2.6.27.4/fs/ntfs/file.c 2008-10-27 22:36:18.000000000 -0400
15766 @@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
15767 #endif /* NTFS_RW */
15770 -const struct file_operations ntfs_empty_file_ops = {};
15771 +const struct file_operations ntfs_empty_file_ops;
15773 -const struct inode_operations ntfs_empty_inode_ops = {};
15774 +const struct inode_operations ntfs_empty_inode_ops;
15775 diff -urNp linux-2.6.27.4/fs/open.c linux-2.6.27.4/fs/open.c
15776 --- linux-2.6.27.4/fs/open.c 2008-10-22 17:38:01.000000000 -0400
15777 +++ linux-2.6.27.4/fs/open.c 2008-10-26 03:40:32.000000000 -0400
15779 #include <linux/vs_dlimit.h>
15780 #include <linux/vs_tag.h>
15781 #include <linux/vs_cowbl.h>
15782 +#include <linux/grsecurity.h>
15784 int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
15786 @@ -207,6 +208,9 @@ int do_truncate(struct dentry *dentry, l
15790 + if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
15793 newattrs.ia_size = length;
15794 newattrs.ia_valid = ATTR_SIZE | time_attrs;
15796 @@ -491,6 +495,9 @@ asmlinkage long sys_faccessat(int dfd, c
15797 if (__mnt_is_readonly(path.mnt))
15800 + if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
15806 @@ -521,6 +528,8 @@ asmlinkage long sys_chdir(const char __u
15810 + gr_log_chdir(path.dentry, path.mnt);
15812 set_fs_pwd(current->fs, &path);
15815 @@ -547,6 +556,13 @@ asmlinkage long sys_fchdir(unsigned int
15818 error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
15820 + if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
15824 + gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
15827 set_fs_pwd(current->fs, &file->f_path);
15829 @@ -572,7 +588,14 @@ asmlinkage long sys_chroot(const char __
15830 if (!capable(CAP_SYS_CHROOT))
15833 + if (gr_handle_chroot_chroot(path.dentry, path.mnt))
15834 + goto dput_and_out;
15836 set_fs_root(current->fs, &path);
15838 + gr_handle_chroot_caps(current);
15839 + gr_handle_chroot_chdir(&path);
15844 @@ -600,13 +623,28 @@ asmlinkage long sys_fchmod(unsigned int
15845 err = mnt_want_write(file->f_path.mnt);
15849 + if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
15851 + goto out_drop_write;
15854 mutex_lock(&inode->i_mutex);
15855 if (mode == (mode_t) -1)
15856 mode = inode->i_mode;
15858 + if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
15860 + mutex_unlock(&inode->i_mutex);
15861 + goto out_drop_write;
15864 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
15865 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
15866 err = notify_change(dentry, &newattrs);
15867 mutex_unlock(&inode->i_mutex);
15870 mnt_drop_write(file->f_path.mnt);
15873 @@ -630,13 +668,28 @@ asmlinkage long sys_fchmodat(int dfd, co
15874 error = mnt_want_write(path.mnt);
15878 + if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
15880 + goto out_drop_write;
15883 mutex_lock(&inode->i_mutex);
15884 if (mode == (mode_t) -1)
15885 mode = inode->i_mode;
15887 + if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
15889 + mutex_unlock(&inode->i_mutex);
15890 + goto out_drop_write;
15893 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
15894 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
15895 error = notify_change(path.dentry, &newattrs);
15896 mutex_unlock(&inode->i_mutex);
15899 mnt_drop_write(path.mnt);
15902 @@ -649,12 +702,15 @@ asmlinkage long sys_chmod(const char __u
15903 return sys_fchmodat(AT_FDCWD, filename, mode);
15906 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
15907 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
15909 struct inode *inode = dentry->d_inode;
15911 struct iattr newattrs;
15913 + if (!gr_acl_handle_chown(dentry, mnt))
15916 newattrs.ia_valid = ATTR_CTIME;
15917 if (user != (uid_t) -1) {
15918 newattrs.ia_valid |= ATTR_UID;
15919 @@ -685,7 +741,7 @@ asmlinkage long sys_chown(const char __u
15920 error = cow_check_and_break(&path);
15923 - error = chown_common(path.dentry, user, group);
15924 + error = chown_common(path.dentry, user, group, path.mnt);
15925 mnt_drop_write(path.mnt);
15928 @@ -710,7 +766,7 @@ asmlinkage long sys_fchownat(int dfd, co
15929 error = cow_check_and_break(&path);
15932 - error = chown_common(path.dentry, user, group);
15933 + error = chown_common(path.dentry, user, group, path.mnt);
15934 mnt_drop_write(path.mnt);
15937 @@ -729,7 +785,7 @@ asmlinkage long sys_lchown(const char __
15938 error = cow_check_and_break(&path);
15941 - error = chown_common(path.dentry, user, group);
15942 + error = chown_common(path.dentry, user, group, path.mnt);
15943 mnt_drop_write(path.mnt);
15946 @@ -753,7 +809,7 @@ asmlinkage long sys_fchown(unsigned int
15948 dentry = file->f_path.dentry;
15949 audit_inode(NULL, dentry);
15950 - error = chown_common(dentry, user, group);
15951 + error = chown_common(dentry, user, group, file->f_path.mnt);
15952 mnt_drop_write(file->f_path.mnt);
15955 diff -urNp linux-2.6.27.4/fs/pipe.c linux-2.6.27.4/fs/pipe.c
15956 --- linux-2.6.27.4/fs/pipe.c 2008-10-22 17:38:01.000000000 -0400
15957 +++ linux-2.6.27.4/fs/pipe.c 2008-10-25 12:03:07.000000000 -0400
15958 @@ -851,7 +851,7 @@ void free_pipe_info(struct inode *inode)
15959 inode->i_pipe = NULL;
15962 -static struct vfsmount *pipe_mnt __read_mostly;
15963 +struct vfsmount *pipe_mnt __read_mostly;
15964 static int pipefs_delete_dentry(struct dentry *dentry)
15967 diff -urNp linux-2.6.27.4/fs/proc/array.c linux-2.6.27.4/fs/proc/array.c
15968 --- linux-2.6.27.4/fs/proc/array.c 2008-10-22 17:38:01.000000000 -0400
15969 +++ linux-2.6.27.4/fs/proc/array.c 2008-10-27 22:36:18.000000000 -0400
15970 @@ -315,6 +315,21 @@ static inline void task_context_switch_c
15974 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
15975 +static inline void task_pax(struct seq_file *m, struct task_struct *p)
15978 + seq_printf(m, "PaX:\t%c%c%c%c%c\n",
15979 + p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
15980 + p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
15981 + p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
15982 + p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
15983 + p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
15985 + seq_printf(m, "PaX:\t-----\n");
15989 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
15990 struct pid *pid, struct task_struct *task)
15992 @@ -334,9 +349,20 @@ int proc_pid_status(struct seq_file *m,
15993 task_show_regs(m, task);
15995 task_context_switch_counts(m, task);
15997 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
15998 + task_pax(m, task);
16004 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16005 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
16006 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
16007 + _mm->pax_flags & MF_PAX_SEGMEXEC))
16010 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
16011 struct pid *pid, struct task_struct *task, int whole)
16013 @@ -429,6 +455,19 @@ static int do_task_stat(struct seq_file
16014 gtime = task_gtime(task);
16017 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16018 + if (PAX_RAND_FLAGS(mm)) {
16024 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16030 /* scale priority and nice values from timeslices to -20..20 */
16031 /* to make it look like a "normal" Unix priority/nice value */
16032 priority = task_prio(task);
16033 @@ -469,9 +508,15 @@ static int do_task_stat(struct seq_file
16035 mm ? get_mm_rss(mm) : 0,
16037 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16038 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
16039 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
16040 + PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
16042 mm ? mm->start_code : 0,
16043 mm ? mm->end_code : 0,
16044 mm ? mm->start_stack : 0,
16048 /* The signal information here is obsolete.
16049 @@ -524,3 +569,10 @@ int proc_pid_statm(struct seq_file *m, s
16054 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16055 +int proc_pid_ipaddr(struct task_struct *task, char *buffer)
16057 + return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
16060 diff -urNp linux-2.6.27.4/fs/proc/base.c linux-2.6.27.4/fs/proc/base.c
16061 --- linux-2.6.27.4/fs/proc/base.c 2008-10-22 17:38:01.000000000 -0400
16062 +++ linux-2.6.27.4/fs/proc/base.c 2008-10-27 22:36:18.000000000 -0400
16064 #include <linux/pid_namespace.h>
16065 #include <linux/vs_context.h>
16066 #include <linux/vs_network.h>
16067 +#include <linux/grsecurity.h>
16069 #include "internal.h"
16072 @@ -148,7 +150,7 @@ static unsigned int pid_entry_count_dirs
16077 +int maps_protect = 1;
16078 EXPORT_SYMBOL(maps_protect);
16080 static struct fs_struct *get_fs_struct(struct task_struct *task)
16081 @@ -229,6 +231,9 @@ static int check_mem_permission(struct t
16082 if (task == current)
16085 + if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
16089 * If current is actively ptrace'ing, and would also be
16090 * permitted to freshly attach with ptrace now, permit it.
16091 @@ -312,9 +317,9 @@ static int proc_pid_auxv(struct task_str
16092 struct mm_struct *mm = get_task_mm(task);
16094 unsigned int nwords = 0;
16098 - while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16099 + } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16100 res = nwords * sizeof(mm->saved_auxv[0]);
16101 if (res > PAGE_SIZE)
16103 @@ -1437,7 +1442,11 @@ static struct inode *proc_pid_make_inode
16105 if (task_dumpable(task)) {
16106 inode->i_uid = task->euid;
16107 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16108 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16110 inode->i_gid = task->egid;
16113 security_task_to_inode(task, inode);
16115 @@ -1453,17 +1462,45 @@ static int pid_getattr(struct vfsmount *
16117 struct inode *inode = dentry->d_inode;
16118 struct task_struct *task;
16119 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16120 + struct task_struct *tmp = current;
16123 generic_fillattr(inode, stat);
16128 task = pid_task(proc_pid(inode), PIDTYPE_PID);
16131 + if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
16132 + rcu_read_unlock();
16138 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16139 + && (!tmp->uid || (tmp->uid == task->uid)
16140 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16141 + || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16146 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16147 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16148 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16149 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16150 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16152 task_dumpable(task)) {
16153 stat->uid = task->euid;
16154 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16155 + stat->gid = CONFIG_GRKERNSEC_PROC_GID;
16157 stat->gid = task->egid;
16162 @@ -1491,11 +1528,21 @@ static int pid_revalidate(struct dentry
16164 struct inode *inode = dentry->d_inode;
16165 struct task_struct *task = get_proc_task(inode);
16168 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16169 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16170 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16171 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16172 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16174 task_dumpable(task)) {
16175 inode->i_uid = task->euid;
16176 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16177 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16179 inode->i_gid = task->egid;
16184 @@ -1863,12 +1910,22 @@ static const struct file_operations proc
16185 static int proc_fd_permission(struct inode *inode, int mask)
16188 + struct task_struct *task;
16190 rv = generic_permission(inode, mask, NULL);
16194 if (task_pid(current) == proc_pid(inode))
16197 + task = get_proc_task(inode);
16198 + if (task == NULL)
16201 + if (gr_acl_handle_procpidmem(task))
16204 + put_task_struct(task);
16209 @@ -1979,6 +2036,9 @@ static struct dentry *proc_pident_lookup
16213 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16217 * Yes, it does not scale. And it should not. Don't add
16218 * new entries into /proc/<tgid>/ without very good reasons.
16219 @@ -2023,6 +2083,9 @@ static int proc_pident_readdir(struct fi
16223 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16229 @@ -2385,6 +2448,9 @@ static struct dentry *proc_base_lookup(s
16233 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16236 error = proc_base_instantiate(dir, dentry, task, p);
16239 @@ -2518,6 +2584,9 @@ static const struct pid_entry tgid_base_
16240 #ifdef CONFIG_TASK_IO_ACCOUNTING
16241 INF("io", S_IRUGO, tgid_io_accounting),
16243 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16244 + INF("ipaddr", S_IRUSR, pid_ipaddr),
16246 ONE("nsproxy", S_IRUGO, pid_nsproxy),
16249 @@ -2647,7 +2716,14 @@ static struct dentry *proc_pid_instantia
16253 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16254 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
16255 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16256 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16257 + inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
16259 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
16261 inode->i_op = &proc_tgid_base_inode_operations;
16262 inode->i_fop = &proc_tgid_base_operations;
16263 inode->i_flags|=S_IMMUTABLE;
16264 @@ -2689,7 +2765,11 @@ struct dentry *proc_pid_lookup(struct in
16268 + if (gr_check_hidden_task(task))
16269 + goto out_put_task;
16271 result = proc_pid_instantiate(dir, dentry, task, NULL);
16273 put_task_struct(task);
16276 @@ -2754,6 +2834,9 @@ int proc_pid_readdir(struct file * filp,
16278 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
16279 struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
16280 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16281 + struct task_struct *tmp = current;
16283 struct tgid_iter iter;
16284 struct pid_namespace *ns;
16286 @@ -2772,6 +2855,17 @@ int proc_pid_readdir(struct file * filp,
16287 for (iter = next_tgid(ns, iter);
16289 iter.tgid += 1, iter = next_tgid(ns, iter)) {
16290 + if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
16291 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16292 + || (tmp->uid && (iter.task->uid != tmp->uid)
16293 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16294 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16301 filp->f_pos = iter.tgid + TGID_OFFSET;
16302 if (!vx_proc_task_visible(iter.task))
16304 diff -urNp linux-2.6.27.4/fs/proc/inode.c linux-2.6.27.4/fs/proc/inode.c
16305 --- linux-2.6.27.4/fs/proc/inode.c 2008-10-22 17:38:01.000000000 -0400
16306 +++ linux-2.6.27.4/fs/proc/inode.c 2008-10-25 12:03:07.000000000 -0400
16307 @@ -467,7 +467,11 @@ struct inode *proc_get_inode(struct supe
16309 inode->i_mode = de->mode;
16310 inode->i_uid = de->uid;
16311 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16312 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16314 inode->i_gid = de->gid;
16318 inode->i_size = de->size;
16319 diff -urNp linux-2.6.27.4/fs/proc/internal.h linux-2.6.27.4/fs/proc/internal.h
16320 --- linux-2.6.27.4/fs/proc/internal.h 2008-10-22 17:38:01.000000000 -0400
16321 +++ linux-2.6.27.4/fs/proc/internal.h 2008-10-25 12:03:07.000000000 -0400
16322 @@ -55,6 +55,9 @@ extern int proc_pid_status(struct seq_fi
16323 extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
16324 struct pid *pid, struct task_struct *task);
16326 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16327 +extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
16329 extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
16331 extern const struct file_operations proc_maps_operations;
16332 diff -urNp linux-2.6.27.4/fs/proc/Kconfig linux-2.6.27.4/fs/proc/Kconfig
16333 --- linux-2.6.27.4/fs/proc/Kconfig 2008-10-22 17:38:01.000000000 -0400
16334 +++ linux-2.6.27.4/fs/proc/Kconfig 2008-10-25 12:20:56.000000000 -0400
16335 @@ -30,12 +30,12 @@ config PROC_FS
16338 bool "/proc/kcore support" if !ARM
16339 - depends on PROC_FS && MMU
16340 + depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
16343 bool "/proc/vmcore support (EXPERIMENTAL)"
16344 - depends on PROC_FS && CRASH_DUMP
16346 + depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
16349 Exports the dump image of crashed kernel in ELF format.
16351 diff -urNp linux-2.6.27.4/fs/proc/proc_misc.c linux-2.6.27.4/fs/proc/proc_misc.c
16352 --- linux-2.6.27.4/fs/proc/proc_misc.c 2008-10-22 17:38:01.000000000 -0400
16353 +++ linux-2.6.27.4/fs/proc/proc_misc.c 2008-10-25 12:03:07.000000000 -0400
16354 @@ -860,6 +860,8 @@ struct proc_dir_entry *proc_root_kcore;
16356 void __init proc_misc_init(void)
16362 int (*read_proc)(char*,char**,off_t,int,int*,void*);
16363 @@ -875,13 +877,24 @@ void __init proc_misc_init(void)
16364 {"stram", stram_read_proc},
16366 {"filesystems", filesystems_read_proc},
16367 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
16368 {"cmdline", cmdline_read_proc},
16370 {"execdomains", execdomains_read_proc},
16373 for (p = simple_ones; p->name; p++)
16374 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
16376 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16377 + gr_mode = S_IRUSR;
16378 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16379 + gr_mode = S_IRUSR | S_IRGRP;
16381 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
16382 + create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
16385 proc_symlink("mounts", NULL, "self/mounts");
16387 /* And now for trickier ones */
16388 @@ -889,14 +902,18 @@ void __init proc_misc_init(void)
16389 proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
16391 proc_create("locks", 0, NULL, &proc_locks_operations);
16392 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
16393 + proc_create("devices", gr_mode, NULL, &proc_devinfo_operations);
16395 proc_create("devices", 0, NULL, &proc_devinfo_operations);
16397 proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
16398 #ifdef CONFIG_BLOCK
16399 proc_create("partitions", 0, NULL, &proc_partitions_operations);
16401 proc_create("stat", 0, NULL, &proc_stat_operations);
16402 proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
16403 -#ifdef CONFIG_SLABINFO
16404 +#if defined(CONFIG_SLABINFO) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
16405 proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
16406 #ifdef CONFIG_DEBUG_SLAB_LEAK
16407 proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
16408 @@ -918,7 +935,7 @@ void __init proc_misc_init(void)
16409 #ifdef CONFIG_SCHEDSTATS
16410 proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
16412 -#ifdef CONFIG_PROC_KCORE
16413 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
16414 proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
16415 if (proc_root_kcore)
16416 proc_root_kcore->size =
16417 diff -urNp linux-2.6.27.4/fs/proc/proc_net.c linux-2.6.27.4/fs/proc/proc_net.c
16418 --- linux-2.6.27.4/fs/proc/proc_net.c 2008-10-22 17:38:01.000000000 -0400
16419 +++ linux-2.6.27.4/fs/proc/proc_net.c 2008-10-25 12:03:07.000000000 -0400
16420 @@ -106,6 +106,14 @@ static struct net *get_proc_task_net(str
16421 struct nsproxy *ns;
16422 struct net *net = NULL;
16424 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16425 + if (current->fsuid)
16427 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16428 + if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
16433 task = pid_task(proc_pid(dir), PIDTYPE_PID);
16434 if (task != NULL) {
16435 diff -urNp linux-2.6.27.4/fs/proc/proc_sysctl.c linux-2.6.27.4/fs/proc/proc_sysctl.c
16436 --- linux-2.6.27.4/fs/proc/proc_sysctl.c 2008-10-22 17:38:01.000000000 -0400
16437 +++ linux-2.6.27.4/fs/proc/proc_sysctl.c 2008-10-26 03:51:55.000000000 -0400
16439 #include <linux/security.h>
16440 #include "internal.h"
16442 +extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
16444 static struct dentry_operations proc_sys_dentry_operations;
16445 static const struct file_operations proc_sys_file_operations;
16446 static const struct inode_operations proc_sys_inode_operations;
16447 @@ -109,6 +111,9 @@ static struct dentry *proc_sys_lookup(st
16451 + if (gr_handle_sysctl(table, 001))
16454 err = ERR_PTR(-ENOMEM);
16455 inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
16457 @@ -228,6 +233,9 @@ static int scan(struct ctl_table_header
16458 if (*pos < file->f_pos)
16461 + if (gr_handle_sysctl(table, 0))
16464 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
16467 @@ -338,6 +346,9 @@ static int proc_sys_getattr(struct vfsmo
16469 return PTR_ERR(head);
16471 + if (table && gr_handle_sysctl(table, MAY_EXEC))
16474 generic_fillattr(inode, stat);
16476 stat->mode = (stat->mode & S_IFMT) | table->mode;
16477 diff -urNp linux-2.6.27.4/fs/proc/root.c linux-2.6.27.4/fs/proc/root.c
16478 --- linux-2.6.27.4/fs/proc/root.c 2008-10-22 17:38:01.000000000 -0400
16479 +++ linux-2.6.27.4/fs/proc/root.c 2008-10-25 12:03:07.000000000 -0400
16480 @@ -135,7 +135,15 @@ void __init proc_root_init(void)
16481 #ifdef CONFIG_PROC_DEVICETREE
16482 proc_device_tree_init();
16484 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
16485 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16486 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
16487 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16488 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
16491 proc_mkdir("bus", NULL);
16496 diff -urNp linux-2.6.27.4/fs/proc/task_mmu.c linux-2.6.27.4/fs/proc/task_mmu.c
16497 --- linux-2.6.27.4/fs/proc/task_mmu.c 2008-10-27 22:25:01.000000000 -0400
16498 +++ linux-2.6.27.4/fs/proc/task_mmu.c 2008-10-27 22:36:18.000000000 -0400
16499 @@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
16500 "VmStk:\t%8lu kB\n"
16501 "VmExe:\t%8lu kB\n"
16502 "VmLib:\t%8lu kB\n"
16503 - "VmPTE:\t%8lu kB\n",
16504 - hiwater_vm << (PAGE_SHIFT-10),
16505 + "VmPTE:\t%8lu kB\n"
16507 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16508 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
16511 + ,hiwater_vm << (PAGE_SHIFT-10),
16512 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
16513 mm->locked_vm << (PAGE_SHIFT-10),
16514 hiwater_rss << (PAGE_SHIFT-10),
16515 total_rss << (PAGE_SHIFT-10),
16516 data << (PAGE_SHIFT-10),
16517 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
16518 - (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
16519 + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
16521 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16522 + , mm->context.user_cs_base, mm->context.user_cs_limit
16528 unsigned long task_vsize(struct mm_struct *mm)
16529 @@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
16533 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16534 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
16535 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
16536 + _mm->pax_flags & MF_PAX_SEGMEXEC))
16539 static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
16541 struct mm_struct *mm = vma->vm_mm;
16542 @@ -214,13 +231,22 @@ static void show_map_vma(struct seq_file
16545 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
16546 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16547 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
16548 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
16553 flags & VM_READ ? 'r' : '-',
16554 flags & VM_WRITE ? 'w' : '-',
16555 flags & VM_EXEC ? 'x' : '-',
16556 flags & VM_MAYSHARE ? 's' : 'p',
16557 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16558 + PAX_RAND_FLAGS(mm) ? 0UL : ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
16560 ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
16562 MAJOR(dev), MINOR(dev), ino, &len);
16565 @@ -234,11 +260,11 @@ static void show_map_vma(struct seq_file
16566 const char *name = arch_vma_name(vma);
16569 - if (vma->vm_start <= mm->start_brk &&
16570 - vma->vm_end >= mm->brk) {
16571 + if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
16573 - } else if (vma->vm_start <= mm->start_stack &&
16574 - vma->vm_end >= mm->start_stack) {
16575 + } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
16576 + (vma->vm_start <= mm->start_stack &&
16577 + vma->vm_end >= mm->start_stack)) {
16581 @@ -387,9 +413,16 @@ static int show_smap(struct seq_file *m,
16584 memset(&mss, 0, sizeof mss);
16586 - if (vma->vm_mm && !is_vm_hugetlb_page(vma))
16587 - walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
16589 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16590 + if (!PAX_RAND_FLAGS(vma->vm_mm)) {
16593 + if (vma->vm_mm && !is_vm_hugetlb_page(vma))
16594 + walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
16595 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16599 show_map_vma(m, vma);
16601 @@ -403,7 +436,11 @@ static int show_smap(struct seq_file *m,
16602 "Private_Dirty: %8lu kB\n"
16603 "Referenced: %8lu kB\n"
16605 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16606 + PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
16608 (vma->vm_end - vma->vm_start) >> 10,
16610 mss.resident >> 10,
16611 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
16612 mss.shared_clean >> 10,
16613 @@ -757,6 +794,11 @@ static int show_numa_map_checked(struct
16614 struct proc_maps_private *priv = m->private;
16615 struct task_struct *task = priv->task;
16617 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16618 + if (!ptrace_may_access(task, PTRACE_MODE_READ))
16622 if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
16625 diff -urNp linux-2.6.27.4/fs/readdir.c linux-2.6.27.4/fs/readdir.c
16626 --- linux-2.6.27.4/fs/readdir.c 2008-10-22 17:38:01.000000000 -0400
16627 +++ linux-2.6.27.4/fs/readdir.c 2008-10-25 12:33:44.000000000 -0400
16629 #include <linux/security.h>
16630 #include <linux/syscalls.h>
16631 #include <linux/unistd.h>
16632 +#include <linux/namei.h>
16633 +#include <linux/grsecurity.h>
16635 #include <asm/uaccess.h>
16637 @@ -67,6 +69,7 @@ struct old_linux_dirent {
16639 struct readdir_callback {
16640 struct old_linux_dirent __user * dirent;
16641 + struct file * file;
16645 @@ -84,6 +87,10 @@ static int fillonedir(void * __buf, cons
16646 buf->result = -EOVERFLOW;
16650 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
16654 dirent = buf->dirent;
16655 if (!access_ok(VERIFY_WRITE, dirent,
16656 @@ -115,6 +122,7 @@ asmlinkage long old_readdir(unsigned int
16659 buf.dirent = dirent;
16662 error = vfs_readdir(file, fillonedir, &buf);
16664 @@ -141,6 +149,7 @@ struct linux_dirent {
16665 struct getdents_callback {
16666 struct linux_dirent __user * current_dir;
16667 struct linux_dirent __user * previous;
16668 + struct file * file;
16672 @@ -161,6 +170,10 @@ static int filldir(void * __buf, const c
16673 buf->error = -EOVERFLOW;
16677 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
16680 dirent = buf->previous;
16682 if (__put_user(offset, &dirent->d_off))
16683 @@ -207,6 +220,7 @@ asmlinkage long sys_getdents(unsigned in
16684 buf.previous = NULL;
16689 error = vfs_readdir(file, filldir, &buf);
16691 @@ -229,6 +243,7 @@ out:
16692 struct getdents_callback64 {
16693 struct linux_dirent64 __user * current_dir;
16694 struct linux_dirent64 __user * previous;
16695 + struct file *file;
16699 @@ -243,6 +258,10 @@ static int filldir64(void * __buf, const
16700 buf->error = -EINVAL; /* only used if we fail.. */
16701 if (reclen > buf->count)
16704 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
16707 dirent = buf->previous;
16709 if (__put_user(offset, &dirent->d_off))
16710 @@ -289,6 +308,7 @@ asmlinkage long sys_getdents64(unsigned
16712 buf.current_dir = dirent;
16713 buf.previous = NULL;
16718 diff -urNp linux-2.6.27.4/fs/select.c linux-2.6.27.4/fs/select.c
16719 --- linux-2.6.27.4/fs/select.c 2008-10-22 17:38:01.000000000 -0400
16720 +++ linux-2.6.27.4/fs/select.c 2008-10-26 03:46:05.000000000 -0400
16722 #include <linux/fdtable.h>
16723 #include <linux/fs.h>
16724 #include <linux/rcupdate.h>
16725 +#include <linux/grsecurity.h>
16727 #include <asm/uaccess.h>
16729 @@ -658,6 +659,7 @@ int do_sys_poll(struct pollfd __user *uf
16730 struct poll_list *walk = head;
16731 unsigned long todo = nfds;
16733 + gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
16734 if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
16737 diff -urNp linux-2.6.27.4/fs/smbfs/symlink.c linux-2.6.27.4/fs/smbfs/symlink.c
16738 --- linux-2.6.27.4/fs/smbfs/symlink.c 2008-10-22 17:38:01.000000000 -0400
16739 +++ linux-2.6.27.4/fs/smbfs/symlink.c 2008-10-27 22:36:18.000000000 -0400
16740 @@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
16742 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
16744 - char *s = nd_get_link(nd);
16745 + const char *s = nd_get_link(nd);
16749 diff -urNp linux-2.6.27.4/fs/sysfs/symlink.c linux-2.6.27.4/fs/sysfs/symlink.c
16750 --- linux-2.6.27.4/fs/sysfs/symlink.c 2008-10-22 17:38:01.000000000 -0400
16751 +++ linux-2.6.27.4/fs/sysfs/symlink.c 2008-10-27 22:36:18.000000000 -0400
16752 @@ -200,7 +200,7 @@ static void *sysfs_follow_link(struct de
16754 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
16756 - char *page = nd_get_link(nd);
16757 + const char *page = nd_get_link(nd);
16759 free_page((unsigned long)page);
16761 diff -urNp linux-2.6.27.4/fs/udf/balloc.c linux-2.6.27.4/fs/udf/balloc.c
16762 --- linux-2.6.27.4/fs/udf/balloc.c 2008-10-22 17:38:01.000000000 -0400
16763 +++ linux-2.6.27.4/fs/udf/balloc.c 2008-10-27 22:36:18.000000000 -0400
16764 @@ -169,9 +169,7 @@ static void udf_bitmap_free_blocks(struc
16765 unsigned long overflow;
16767 mutex_lock(&sbi->s_alloc_mutex);
16768 - if (bloc.logicalBlockNum < 0 ||
16769 - (bloc.logicalBlockNum + count) >
16770 - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
16771 + if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
16772 udf_debug("%d < %d || %d + %d > %d\n",
16773 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
16774 sbi->s_partmaps[bloc.partitionReferenceNum].
16775 @@ -239,7 +237,7 @@ static int udf_bitmap_prealloc_blocks(st
16777 mutex_lock(&sbi->s_alloc_mutex);
16778 part_len = sbi->s_partmaps[partition].s_partition_len;
16779 - if (first_block < 0 || first_block >= part_len)
16780 + if (first_block >= part_len)
16783 if (first_block + block_count > part_len)
16784 @@ -300,7 +298,7 @@ static int udf_bitmap_new_block(struct s
16785 mutex_lock(&sbi->s_alloc_mutex);
16788 - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
16789 + if (goal >= sbi->s_partmaps[partition].s_partition_len)
16792 nr_groups = bitmap->s_nr_groups;
16793 @@ -438,9 +436,7 @@ static void udf_table_free_blocks(struct
16794 struct udf_inode_info *iinfo;
16796 mutex_lock(&sbi->s_alloc_mutex);
16797 - if (bloc.logicalBlockNum < 0 ||
16798 - (bloc.logicalBlockNum + count) >
16799 - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
16800 + if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
16801 udf_debug("%d < %d || %d + %d > %d\n",
16802 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
16803 sbi->s_partmaps[bloc.partitionReferenceNum].
16804 @@ -671,8 +667,7 @@ static int udf_table_prealloc_blocks(str
16806 struct udf_inode_info *iinfo;
16808 - if (first_block < 0 ||
16809 - first_block >= sbi->s_partmaps[partition].s_partition_len)
16810 + if (first_block >= sbi->s_partmaps[partition].s_partition_len)
16813 iinfo = UDF_I(table);
16814 @@ -750,7 +745,7 @@ static int udf_table_new_block(struct su
16817 mutex_lock(&sbi->s_alloc_mutex);
16818 - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
16819 + if (goal >= sbi->s_partmaps[partition].s_partition_len)
16822 /* We search for the closest matching block to goal. If we find
16823 diff -urNp linux-2.6.27.4/fs/ufs/inode.c linux-2.6.27.4/fs/ufs/inode.c
16824 --- linux-2.6.27.4/fs/ufs/inode.c 2008-10-22 17:38:01.000000000 -0400
16825 +++ linux-2.6.27.4/fs/ufs/inode.c 2008-10-27 22:36:18.000000000 -0400
16826 @@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
16829 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
16830 - if (i_block < 0) {
16831 - ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
16832 - } else if (i_block < direct_blocks) {
16833 + if (i_block < direct_blocks) {
16834 offsets[n++] = i_block;
16835 } else if ((i_block -= direct_blocks) < indirect_blocks) {
16836 offsets[n++] = UFS_IND_BLOCK;
16837 @@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
16840 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
16841 - if (fragment < 0)
16842 - goto abort_negative;
16844 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
16845 << uspi->s_fpbshift))
16846 @@ -504,10 +500,6 @@ abort:
16851 - ufs_warning(sb, "ufs_get_block", "block < 0");
16855 ufs_warning(sb, "ufs_get_block", "block > big");
16857 diff -urNp linux-2.6.27.4/fs/utimes.c linux-2.6.27.4/fs/utimes.c
16858 --- linux-2.6.27.4/fs/utimes.c 2008-10-22 17:38:01.000000000 -0400
16859 +++ linux-2.6.27.4/fs/utimes.c 2008-10-25 12:13:12.000000000 -0400
16861 #include <linux/syscalls.h>
16862 #include <linux/mount.h>
16863 #include <linux/vs_cowbl.h>
16864 +#include <linux/grsecurity.h>
16865 #include <asm/uaccess.h>
16866 #include <asm/unistd.h>
16868 @@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
16869 goto mnt_drop_write_and_out;
16873 + if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
16875 + goto mnt_drop_write_and_out;
16878 mutex_lock(&inode->i_mutex);
16879 error = notify_change(path->dentry, &newattrs);
16880 mutex_unlock(&inode->i_mutex);
16881 diff -urNp linux-2.6.27.4/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.27.4/fs/xfs/linux-2.6/xfs_iops.c
16882 --- linux-2.6.27.4/fs/xfs/linux-2.6/xfs_iops.c 2008-10-22 17:38:01.000000000 -0400
16883 +++ linux-2.6.27.4/fs/xfs/linux-2.6/xfs_iops.c 2008-10-27 22:36:18.000000000 -0400
16884 @@ -500,7 +500,7 @@ xfs_vn_put_link(
16885 struct nameidata *nd,
16888 - char *s = nd_get_link(nd);
16889 + const char *s = nd_get_link(nd);
16893 diff -urNp linux-2.6.27.4/fs/xfs/xfs_bmap.c linux-2.6.27.4/fs/xfs/xfs_bmap.c
16894 --- linux-2.6.27.4/fs/xfs/xfs_bmap.c 2008-10-22 17:38:01.000000000 -0400
16895 +++ linux-2.6.27.4/fs/xfs/xfs_bmap.c 2008-10-27 22:36:18.000000000 -0400
16896 @@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
16900 -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
16901 +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
16904 #if defined(XFS_RW_TRACE)
16905 diff -urNp linux-2.6.27.4/grsecurity/gracl_alloc.c linux-2.6.27.4/grsecurity/gracl_alloc.c
16906 --- linux-2.6.27.4/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
16907 +++ linux-2.6.27.4/grsecurity/gracl_alloc.c 2008-10-25 12:03:07.000000000 -0400
16909 +#include <linux/kernel.h>
16910 +#include <linux/mm.h>
16911 +#include <linux/slab.h>
16912 +#include <linux/vmalloc.h>
16913 +#include <linux/gracl.h>
16914 +#include <linux/grsecurity.h>
16916 +static unsigned long alloc_stack_next = 1;
16917 +static unsigned long alloc_stack_size = 1;
16918 +static void **alloc_stack;
16920 +static __inline__ int
16923 + if (alloc_stack_next == 1)
16926 + kfree(alloc_stack[alloc_stack_next - 2]);
16928 + alloc_stack_next--;
16933 +static __inline__ void
16934 +alloc_push(void *buf)
16936 + if (alloc_stack_next >= alloc_stack_size)
16939 + alloc_stack[alloc_stack_next - 1] = buf;
16941 + alloc_stack_next++;
16947 +acl_alloc(unsigned long len)
16951 + if (len > PAGE_SIZE)
16954 + ret = kmalloc(len, GFP_KERNEL);
16963 +acl_free_all(void)
16965 + if (gr_acl_is_enabled() || !alloc_stack)
16968 + while (alloc_pop()) ;
16970 + if (alloc_stack) {
16971 + if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
16972 + kfree(alloc_stack);
16974 + vfree(alloc_stack);
16977 + alloc_stack = NULL;
16978 + alloc_stack_size = 1;
16979 + alloc_stack_next = 1;
16985 +acl_alloc_stack_init(unsigned long size)
16987 + if ((size * sizeof (void *)) <= PAGE_SIZE)
16989 + (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
16991 + alloc_stack = (void **) vmalloc(size * sizeof (void *));
16993 + alloc_stack_size = size;
16995 + if (!alloc_stack)
17000 diff -urNp linux-2.6.27.4/grsecurity/gracl.c linux-2.6.27.4/grsecurity/gracl.c
17001 --- linux-2.6.27.4/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
17002 +++ linux-2.6.27.4/grsecurity/gracl.c 2008-10-25 13:45:16.000000000 -0400
17004 +#include <linux/kernel.h>
17005 +#include <linux/module.h>
17006 +#include <linux/sched.h>
17007 +#include <linux/mm.h>
17008 +#include <linux/file.h>
17009 +#include <linux/fs.h>
17010 +#include <linux/namei.h>
17011 +#include <linux/mount.h>
17012 +#include <linux/tty.h>
17013 +#include <linux/proc_fs.h>
17014 +#include <linux/smp_lock.h>
17015 +#include <linux/slab.h>
17016 +#include <linux/vmalloc.h>
17017 +#include <linux/types.h>
17018 +#include <linux/sysctl.h>
17019 +#include <linux/netdevice.h>
17020 +#include <linux/ptrace.h>
17021 +#include <linux/gracl.h>
17022 +#include <linux/gralloc.h>
17023 +#include <linux/grsecurity.h>
17024 +#include <linux/grinternal.h>
17025 +#include <linux/pid_namespace.h>
17026 +#include <linux/fdtable.h>
17027 +#include <linux/percpu.h>
17029 +#include <asm/uaccess.h>
17030 +#include <asm/errno.h>
17031 +#include <asm/mman.h>
17033 +static struct acl_role_db acl_role_set;
17034 +static struct name_db name_set;
17035 +static struct inodev_db inodev_set;
17037 +/* for keeping track of userspace pointers used for subjects, so we
17038 + can share references in the kernel as well
17041 +static struct dentry *real_root;
17042 +static struct vfsmount *real_root_mnt;
17044 +static struct acl_subj_map_db subj_map_set;
17046 +static struct acl_role_label *default_role;
17048 +static u16 acl_sp_role_value;
17050 +extern char *gr_shared_page[4];
17051 +static DECLARE_MUTEX(gr_dev_sem);
17052 +DEFINE_RWLOCK(gr_inode_lock);
17054 +struct gr_arg *gr_usermode;
17056 +static unsigned int gr_status = GR_STATUS_INIT;
17058 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
17059 +extern void gr_clear_learn_entries(void);
17061 +#ifdef CONFIG_GRKERNSEC_RESLOG
17062 +extern void gr_log_resource(const struct task_struct *task,
17063 + const int res, const unsigned long wanted, const int gt);
17066 +unsigned char *gr_system_salt;
17067 +unsigned char *gr_system_sum;
17069 +static struct sprole_pw **acl_special_roles = NULL;
17070 +static __u16 num_sprole_pws = 0;
17072 +static struct acl_role_label *kernel_role = NULL;
17074 +static unsigned int gr_auth_attempts = 0;
17075 +static unsigned long gr_auth_expires = 0UL;
17077 +extern struct vfsmount *sock_mnt;
17078 +extern struct vfsmount *pipe_mnt;
17079 +extern struct vfsmount *shm_mnt;
17080 +static struct acl_object_label *fakefs_obj;
17082 +extern int gr_init_uidset(void);
17083 +extern void gr_free_uidset(void);
17084 +extern void gr_remove_uid(uid_t uid);
17085 +extern int gr_find_uid(uid_t uid);
17088 +gr_acl_is_enabled(void)
17090 + return (gr_status & GR_READY);
17093 +char gr_roletype_to_char(void)
17095 + switch (current->role->roletype &
17096 + (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
17097 + GR_ROLE_SPECIAL)) {
17098 + case GR_ROLE_DEFAULT:
17100 + case GR_ROLE_USER:
17102 + case GR_ROLE_GROUP:
17104 + case GR_ROLE_SPECIAL:
17112 +gr_acl_tpe_check(void)
17114 + if (unlikely(!(gr_status & GR_READY)))
17116 + if (current->role->roletype & GR_ROLE_TPE)
17123 +gr_handle_rawio(const struct inode *inode)
17125 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17126 + if (inode && S_ISBLK(inode->i_mode) &&
17127 + grsec_enable_chroot_caps && proc_is_chrooted(current) &&
17128 + !capable(CAP_SYS_RAWIO))
17135 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
17138 + unsigned long *l1;
17139 + unsigned long *l2;
17140 + unsigned char *c1;
17141 + unsigned char *c2;
17144 + if (likely(lena != lenb))
17147 + l1 = (unsigned long *)a;
17148 + l2 = (unsigned long *)b;
17150 + num_longs = lena / sizeof(unsigned long);
17152 + for (i = num_longs; i--; l1++, l2++) {
17153 + if (unlikely(*l1 != *l2))
17157 + c1 = (unsigned char *) l1;
17158 + c2 = (unsigned char *) l2;
17160 + i = lena - (num_longs * sizeof(unsigned long));
17162 + for (; i--; c1++, c2++) {
17163 + if (unlikely(*c1 != *c2))
17170 +static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17171 + struct dentry *root, struct vfsmount *rootmnt,
17172 + char *buffer, int buflen)
17174 + char * end = buffer+buflen;
17183 + /* Get '/' right */
17188 + struct dentry * parent;
17190 + if (dentry == root && vfsmnt == rootmnt)
17192 + if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
17193 + /* Global root? */
17194 + spin_lock(&vfsmount_lock);
17195 + if (vfsmnt->mnt_parent == vfsmnt) {
17196 + spin_unlock(&vfsmount_lock);
17197 + goto global_root;
17199 + dentry = vfsmnt->mnt_mountpoint;
17200 + vfsmnt = vfsmnt->mnt_parent;
17201 + spin_unlock(&vfsmount_lock);
17204 + parent = dentry->d_parent;
17205 + prefetch(parent);
17206 + namelen = dentry->d_name.len;
17207 + buflen -= namelen + 1;
17211 + memcpy(end, dentry->d_name.name, namelen);
17220 + namelen = dentry->d_name.len;
17221 + buflen -= namelen;
17224 + retval -= namelen-1; /* hit the slash */
17225 + memcpy(retval, dentry->d_name.name, namelen);
17228 + return ERR_PTR(-ENAMETOOLONG);
17232 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17233 + struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
17237 + retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
17238 + if (unlikely(IS_ERR(retval)))
17239 + retval = strcpy(buf, "<path too long>");
17240 + else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
17241 + retval[1] = '\0';
17247 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17248 + char *buf, int buflen)
17252 + /* we can use real_root, real_root_mnt, because this is only called
17253 + by the RBAC system */
17254 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
17260 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17261 + char *buf, int buflen)
17264 + struct dentry *root;
17265 + struct vfsmount *rootmnt;
17266 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
17268 + /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
17269 + read_lock(&reaper->fs->lock);
17270 + root = dget(reaper->fs->root.dentry);
17271 + rootmnt = mntget(reaper->fs->root.mnt);
17272 + read_unlock(&reaper->fs->lock);
17274 + spin_lock(&dcache_lock);
17275 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
17276 + spin_unlock(&dcache_lock);
17284 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
17287 + spin_lock(&dcache_lock);
17288 + ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17290 + spin_unlock(&dcache_lock);
17295 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
17297 + return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17302 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
17304 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
17309 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
17311 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
17316 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
17318 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
17323 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
17325 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
17330 +to_gr_audit(const __u32 reqmode)
17332 + /* masks off auditable permission flags, then shifts them to create
17333 + auditing flags, and adds the special case of append auditing if
17334 + we're requesting write */
17335 + return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
17338 +struct acl_subject_label *
17339 +lookup_subject_map(const struct acl_subject_label *userp)
17341 + unsigned int index = shash(userp, subj_map_set.s_size);
17342 + struct subject_map *match;
17344 + match = subj_map_set.s_hash[index];
17346 + while (match && match->user != userp)
17347 + match = match->next;
17349 + if (match != NULL)
17350 + return match->kernel;
17356 +insert_subj_map_entry(struct subject_map *subjmap)
17358 + unsigned int index = shash(subjmap->user, subj_map_set.s_size);
17359 + struct subject_map **curr;
17361 + subjmap->prev = NULL;
17363 + curr = &subj_map_set.s_hash[index];
17364 + if (*curr != NULL)
17365 + (*curr)->prev = subjmap;
17367 + subjmap->next = *curr;
17373 +static struct acl_role_label *
17374 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
17377 + unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
17378 + struct acl_role_label *match;
17379 + struct role_allowed_ip *ipp;
17382 + match = acl_role_set.r_hash[index];
17385 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
17386 + for (x = 0; x < match->domain_child_num; x++) {
17387 + if (match->domain_children[x] == uid)
17390 + } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
17392 + match = match->next;
17395 + if (match == NULL) {
17397 + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
17398 + match = acl_role_set.r_hash[index];
17401 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
17402 + for (x = 0; x < match->domain_child_num; x++) {
17403 + if (match->domain_children[x] == gid)
17406 + } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
17408 + match = match->next;
17411 + if (match == NULL)
17412 + match = default_role;
17413 + if (match->allowed_ips == NULL)
17416 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
17418 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
17419 + (ntohl(ipp->addr) & ipp->netmask)))
17422 + match = default_role;
17424 + } else if (match->allowed_ips == NULL) {
17427 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
17429 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
17430 + (ntohl(ipp->addr) & ipp->netmask)))
17439 +struct acl_subject_label *
17440 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
17441 + const struct acl_role_label *role)
17443 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
17444 + struct acl_subject_label *match;
17446 + match = role->subj_hash[index];
17448 + while (match && (match->inode != ino || match->device != dev ||
17449 + (match->mode & GR_DELETED))) {
17450 + match = match->next;
17453 + if (match && !(match->mode & GR_DELETED))
17459 +static struct acl_object_label *
17460 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
17461 + const struct acl_subject_label *subj)
17463 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
17464 + struct acl_object_label *match;
17466 + match = subj->obj_hash[index];
17468 + while (match && (match->inode != ino || match->device != dev ||
17469 + (match->mode & GR_DELETED))) {
17470 + match = match->next;
17473 + if (match && !(match->mode & GR_DELETED))
17479 +static struct acl_object_label *
17480 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
17481 + const struct acl_subject_label *subj)
17483 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
17484 + struct acl_object_label *match;
17486 + match = subj->obj_hash[index];
17488 + while (match && (match->inode != ino || match->device != dev ||
17489 + !(match->mode & GR_DELETED))) {
17490 + match = match->next;
17493 + if (match && (match->mode & GR_DELETED))
17496 + match = subj->obj_hash[index];
17498 + while (match && (match->inode != ino || match->device != dev ||
17499 + (match->mode & GR_DELETED))) {
17500 + match = match->next;
17503 + if (match && !(match->mode & GR_DELETED))
17509 +static struct name_entry *
17510 +lookup_name_entry(const char *name)
17512 + unsigned int len = strlen(name);
17513 + unsigned int key = full_name_hash(name, len);
17514 + unsigned int index = key % name_set.n_size;
17515 + struct name_entry *match;
17517 + match = name_set.n_hash[index];
17519 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
17520 + match = match->next;
17525 +static struct name_entry *
17526 +lookup_name_entry_create(const char *name)
17528 + unsigned int len = strlen(name);
17529 + unsigned int key = full_name_hash(name, len);
17530 + unsigned int index = key % name_set.n_size;
17531 + struct name_entry *match;
17533 + match = name_set.n_hash[index];
17535 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
17536 + !match->deleted))
17537 + match = match->next;
17539 + if (match && match->deleted)
17542 + match = name_set.n_hash[index];
17544 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
17546 + match = match->next;
17548 + if (match && !match->deleted)
17554 +static struct inodev_entry *
17555 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
17557 + unsigned int index = fhash(ino, dev, inodev_set.i_size);
17558 + struct inodev_entry *match;
17560 + match = inodev_set.i_hash[index];
17562 + while (match && (match->nentry->inode != ino || match->nentry->device != dev))
17563 + match = match->next;
17569 +insert_inodev_entry(struct inodev_entry *entry)
17571 + unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
17572 + inodev_set.i_size);
17573 + struct inodev_entry **curr;
17575 + entry->prev = NULL;
17577 + curr = &inodev_set.i_hash[index];
17578 + if (*curr != NULL)
17579 + (*curr)->prev = entry;
17581 + entry->next = *curr;
17588 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
17590 + unsigned int index =
17591 + rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
17592 + struct acl_role_label **curr;
17594 + role->prev = NULL;
17596 + curr = &acl_role_set.r_hash[index];
17597 + if (*curr != NULL)
17598 + (*curr)->prev = role;
17600 + role->next = *curr;
17607 +insert_acl_role_label(struct acl_role_label *role)
17611 + if (role->roletype & GR_ROLE_DOMAIN) {
17612 + for (i = 0; i < role->domain_child_num; i++)
17613 + __insert_acl_role_label(role, role->domain_children[i]);
17615 + __insert_acl_role_label(role, role->uidgid);
17619 +insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
17621 + struct name_entry **curr, *nentry;
17622 + struct inodev_entry *ientry;
17623 + unsigned int len = strlen(name);
17624 + unsigned int key = full_name_hash(name, len);
17625 + unsigned int index = key % name_set.n_size;
17627 + curr = &name_set.n_hash[index];
17629 + while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
17630 + curr = &((*curr)->next);
17632 + if (*curr != NULL)
17635 + nentry = acl_alloc(sizeof (struct name_entry));
17636 + if (nentry == NULL)
17638 + ientry = acl_alloc(sizeof (struct inodev_entry));
17639 + if (ientry == NULL)
17641 + ientry->nentry = nentry;
17643 + nentry->key = key;
17644 + nentry->name = name;
17645 + nentry->inode = inode;
17646 + nentry->device = device;
17647 + nentry->len = len;
17648 + nentry->deleted = deleted;
17650 + nentry->prev = NULL;
17651 + curr = &name_set.n_hash[index];
17652 + if (*curr != NULL)
17653 + (*curr)->prev = nentry;
17654 + nentry->next = *curr;
17657 + /* insert us into the table searchable by inode/dev */
17658 + insert_inodev_entry(ientry);
17664 +insert_acl_obj_label(struct acl_object_label *obj,
17665 + struct acl_subject_label *subj)
17667 + unsigned int index =
17668 + fhash(obj->inode, obj->device, subj->obj_hash_size);
17669 + struct acl_object_label **curr;
17672 + obj->prev = NULL;
17674 + curr = &subj->obj_hash[index];
17675 + if (*curr != NULL)
17676 + (*curr)->prev = obj;
17678 + obj->next = *curr;
17685 +insert_acl_subj_label(struct acl_subject_label *obj,
17686 + struct acl_role_label *role)
17688 + unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
17689 + struct acl_subject_label **curr;
17691 + obj->prev = NULL;
17693 + curr = &role->subj_hash[index];
17694 + if (*curr != NULL)
17695 + (*curr)->prev = obj;
17697 + obj->next = *curr;
17703 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
17706 +create_table(__u32 * len, int elementsize)
17708 + unsigned int table_sizes[] = {
17709 + 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
17710 + 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
17711 + 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
17712 + 268435399, 536870909, 1073741789, 2147483647
17714 + void *newtable = NULL;
17715 + unsigned int pwr = 0;
17717 + while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
17718 + table_sizes[pwr] <= *len)
17721 + if (table_sizes[pwr] <= *len)
17724 + if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
17726 + kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
17728 + newtable = vmalloc(table_sizes[pwr] * elementsize);
17730 + *len = table_sizes[pwr];
17736 +init_variables(const struct gr_arg *arg)
17738 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
17739 + unsigned int stacksize;
17741 + subj_map_set.s_size = arg->role_db.num_subjects;
17742 + acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
17743 + name_set.n_size = arg->role_db.num_objects;
17744 + inodev_set.i_size = arg->role_db.num_objects;
17746 + if (!subj_map_set.s_size || !acl_role_set.r_size ||
17747 + !name_set.n_size || !inodev_set.i_size)
17750 + if (!gr_init_uidset())
17753 + /* set up the stack that holds allocation info */
17755 + stacksize = arg->role_db.num_pointers + 5;
17757 + if (!acl_alloc_stack_init(stacksize))
17760 + /* grab reference for the real root dentry and vfsmount */
17761 + read_lock(&reaper->fs->lock);
17762 + real_root_mnt = mntget(reaper->fs->root.mnt);
17763 + real_root = dget(reaper->fs->root.dentry);
17764 + read_unlock(&reaper->fs->lock);
17766 + fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
17767 + if (fakefs_obj == NULL)
17769 + fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
17771 + subj_map_set.s_hash =
17772 + (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
17773 + acl_role_set.r_hash =
17774 + (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
17775 + name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
17776 + inodev_set.i_hash =
17777 + (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
17779 + if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
17780 + !name_set.n_hash || !inodev_set.i_hash)
17783 + memset(subj_map_set.s_hash, 0,
17784 + sizeof(struct subject_map *) * subj_map_set.s_size);
17785 + memset(acl_role_set.r_hash, 0,
17786 + sizeof (struct acl_role_label *) * acl_role_set.r_size);
17787 + memset(name_set.n_hash, 0,
17788 + sizeof (struct name_entry *) * name_set.n_size);
17789 + memset(inodev_set.i_hash, 0,
17790 + sizeof (struct inodev_entry *) * inodev_set.i_size);
17795 +/* free information not needed after startup
17796 + currently contains user->kernel pointer mappings for subjects
17800 +free_init_variables(void)
17804 + if (subj_map_set.s_hash) {
17805 + for (i = 0; i < subj_map_set.s_size; i++) {
17806 + if (subj_map_set.s_hash[i]) {
17807 + kfree(subj_map_set.s_hash[i]);
17808 + subj_map_set.s_hash[i] = NULL;
17812 + if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
17814 + kfree(subj_map_set.s_hash);
17816 + vfree(subj_map_set.s_hash);
17823 +free_variables(void)
17825 + struct acl_subject_label *s;
17826 + struct acl_role_label *r;
17827 + struct task_struct *task, *task2;
17828 + unsigned int i, x;
17830 + gr_clear_learn_entries();
17832 + read_lock(&tasklist_lock);
17833 + do_each_thread(task2, task) {
17834 + task->acl_sp_role = 0;
17835 + task->acl_role_id = 0;
17836 + task->acl = NULL;
17837 + task->role = NULL;
17838 + } while_each_thread(task2, task);
17839 + read_unlock(&tasklist_lock);
17841 + /* release the reference to the real root dentry and vfsmount */
17844 + real_root = NULL;
17845 + if (real_root_mnt)
17846 + mntput(real_root_mnt);
17847 + real_root_mnt = NULL;
17849 + /* free all object hash tables */
17851 + FOR_EACH_ROLE_START(r, i)
17852 + if (r->subj_hash == NULL)
17854 + FOR_EACH_SUBJECT_START(r, s, x)
17855 + if (s->obj_hash == NULL)
17857 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
17858 + kfree(s->obj_hash);
17860 + vfree(s->obj_hash);
17861 + FOR_EACH_SUBJECT_END(s, x)
17862 + FOR_EACH_NESTED_SUBJECT_START(r, s)
17863 + if (s->obj_hash == NULL)
17865 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
17866 + kfree(s->obj_hash);
17868 + vfree(s->obj_hash);
17869 + FOR_EACH_NESTED_SUBJECT_END(s)
17870 + if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
17871 + kfree(r->subj_hash);
17873 + vfree(r->subj_hash);
17874 + r->subj_hash = NULL;
17875 + FOR_EACH_ROLE_END(r,i)
17879 + if (acl_role_set.r_hash) {
17880 + if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
17882 + kfree(acl_role_set.r_hash);
17884 + vfree(acl_role_set.r_hash);
17886 + if (name_set.n_hash) {
17887 + if ((name_set.n_size * sizeof (struct name_entry *)) <=
17889 + kfree(name_set.n_hash);
17891 + vfree(name_set.n_hash);
17894 + if (inodev_set.i_hash) {
17895 + if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
17897 + kfree(inodev_set.i_hash);
17899 + vfree(inodev_set.i_hash);
17902 + gr_free_uidset();
17904 + memset(&name_set, 0, sizeof (struct name_db));
17905 + memset(&inodev_set, 0, sizeof (struct inodev_db));
17906 + memset(&acl_role_set, 0, sizeof (struct acl_role_db));
17907 + memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
17909 + default_role = NULL;
17915 +count_user_objs(struct acl_object_label *userp)
17917 + struct acl_object_label o_tmp;
17921 + if (copy_from_user(&o_tmp, userp,
17922 + sizeof (struct acl_object_label)))
17925 + userp = o_tmp.prev;
17932 +static struct acl_subject_label *
17933 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
17936 +copy_user_glob(struct acl_object_label *obj)
17938 + struct acl_object_label *g_tmp, **guser;
17939 + unsigned int len;
17942 + if (obj->globbed == NULL)
17945 + guser = &obj->globbed;
17947 + g_tmp = (struct acl_object_label *)
17948 + acl_alloc(sizeof (struct acl_object_label));
17949 + if (g_tmp == NULL)
17952 + if (copy_from_user(g_tmp, *guser,
17953 + sizeof (struct acl_object_label)))
17956 + len = strnlen_user(g_tmp->filename, PATH_MAX);
17958 + if (!len || len >= PATH_MAX)
17961 + if ((tmp = (char *) acl_alloc(len)) == NULL)
17964 + if (copy_from_user(tmp, g_tmp->filename, len))
17967 + g_tmp->filename = tmp;
17970 + guser = &(g_tmp->next);
17977 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
17978 + struct acl_role_label *role)
17980 + struct acl_object_label *o_tmp;
17981 + unsigned int len;
17986 + if ((o_tmp = (struct acl_object_label *)
17987 + acl_alloc(sizeof (struct acl_object_label))) == NULL)
17990 + if (copy_from_user(o_tmp, userp,
17991 + sizeof (struct acl_object_label)))
17994 + userp = o_tmp->prev;
17996 + len = strnlen_user(o_tmp->filename, PATH_MAX);
17998 + if (!len || len >= PATH_MAX)
18001 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18004 + if (copy_from_user(tmp, o_tmp->filename, len))
18007 + o_tmp->filename = tmp;
18009 + insert_acl_obj_label(o_tmp, subj);
18010 + if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
18011 + o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
18014 + ret = copy_user_glob(o_tmp);
18018 + if (o_tmp->nested) {
18019 + o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
18020 + if (IS_ERR(o_tmp->nested))
18021 + return PTR_ERR(o_tmp->nested);
18023 + /* insert into nested subject list */
18024 + o_tmp->nested->next = role->hash->first;
18025 + role->hash->first = o_tmp->nested;
18033 +count_user_subjs(struct acl_subject_label *userp)
18035 + struct acl_subject_label s_tmp;
18039 + if (copy_from_user(&s_tmp, userp,
18040 + sizeof (struct acl_subject_label)))
18043 + userp = s_tmp.prev;
18044 + /* do not count nested subjects against this count, since
18045 + they are not included in the hash table, but are
18046 + attached to objects. We have already counted
18047 + the subjects in userspace for the allocation
18050 + if (!(s_tmp.mode & GR_NESTED))
18058 +copy_user_allowedips(struct acl_role_label *rolep)
18060 + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
18062 + ruserip = rolep->allowed_ips;
18064 + while (ruserip) {
18067 + if ((rtmp = (struct role_allowed_ip *)
18068 + acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
18071 + if (copy_from_user(rtmp, ruserip,
18072 + sizeof (struct role_allowed_ip)))
18075 + ruserip = rtmp->prev;
18078 + rtmp->prev = NULL;
18079 + rolep->allowed_ips = rtmp;
18081 + rlast->next = rtmp;
18082 + rtmp->prev = rlast;
18086 + rtmp->next = NULL;
18093 +copy_user_transitions(struct acl_role_label *rolep)
18095 + struct role_transition *rusertp, *rtmp = NULL, *rlast;
18097 + unsigned int len;
18100 + rusertp = rolep->transitions;
18102 + while (rusertp) {
18105 + if ((rtmp = (struct role_transition *)
18106 + acl_alloc(sizeof (struct role_transition))) == NULL)
18109 + if (copy_from_user(rtmp, rusertp,
18110 + sizeof (struct role_transition)))
18113 + rusertp = rtmp->prev;
18115 + len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
18117 + if (!len || len >= GR_SPROLE_LEN)
18120 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18123 + if (copy_from_user(tmp, rtmp->rolename, len))
18126 + rtmp->rolename = tmp;
18129 + rtmp->prev = NULL;
18130 + rolep->transitions = rtmp;
18132 + rlast->next = rtmp;
18133 + rtmp->prev = rlast;
18137 + rtmp->next = NULL;
18143 +static struct acl_subject_label *
18144 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
18146 + struct acl_subject_label *s_tmp = NULL, *s_tmp2;
18147 + unsigned int len;
18150 + struct acl_ip_label **i_tmp, *i_utmp2;
18151 + struct gr_hash_struct ghash;
18152 + struct subject_map *subjmap;
18153 + unsigned int i_num;
18156 + s_tmp = lookup_subject_map(userp);
18158 + /* we've already copied this subject into the kernel, just return
18159 + the reference to it, and don't copy it over again
18164 + if ((s_tmp = (struct acl_subject_label *)
18165 + acl_alloc(sizeof (struct acl_subject_label))) == NULL)
18166 + return ERR_PTR(-ENOMEM);
18168 + subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
18169 + if (subjmap == NULL)
18170 + return ERR_PTR(-ENOMEM);
18172 + subjmap->user = userp;
18173 + subjmap->kernel = s_tmp;
18174 + insert_subj_map_entry(subjmap);
18176 + if (copy_from_user(s_tmp, userp,
18177 + sizeof (struct acl_subject_label)))
18178 + return ERR_PTR(-EFAULT);
18180 + len = strnlen_user(s_tmp->filename, PATH_MAX);
18182 + if (!len || len >= PATH_MAX)
18183 + return ERR_PTR(-EINVAL);
18185 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18186 + return ERR_PTR(-ENOMEM);
18188 + if (copy_from_user(tmp, s_tmp->filename, len))
18189 + return ERR_PTR(-EFAULT);
18191 + s_tmp->filename = tmp;
18193 + if (!strcmp(s_tmp->filename, "/"))
18194 + role->root_label = s_tmp;
18196 + if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
18197 + return ERR_PTR(-EFAULT);
18199 + /* copy user and group transition tables */
18201 + if (s_tmp->user_trans_num) {
18204 + uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
18205 + if (uidlist == NULL)
18206 + return ERR_PTR(-ENOMEM);
18207 + if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
18208 + return ERR_PTR(-EFAULT);
18210 + s_tmp->user_transitions = uidlist;
18213 + if (s_tmp->group_trans_num) {
18216 + gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
18217 + if (gidlist == NULL)
18218 + return ERR_PTR(-ENOMEM);
18219 + if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
18220 + return ERR_PTR(-EFAULT);
18222 + s_tmp->group_transitions = gidlist;
18225 + /* set up object hash table */
18226 + num_objs = count_user_objs(ghash.first);
18228 + s_tmp->obj_hash_size = num_objs;
18229 + s_tmp->obj_hash =
18230 + (struct acl_object_label **)
18231 + create_table(&(s_tmp->obj_hash_size), sizeof(void *));
18233 + if (!s_tmp->obj_hash)
18234 + return ERR_PTR(-ENOMEM);
18236 + memset(s_tmp->obj_hash, 0,
18237 + s_tmp->obj_hash_size *
18238 + sizeof (struct acl_object_label *));
18240 + /* add in objects */
18241 + err = copy_user_objs(ghash.first, s_tmp, role);
18244 + return ERR_PTR(err);
18246 + /* set pointer for parent subject */
18247 + if (s_tmp->parent_subject) {
18248 + s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
18250 + if (IS_ERR(s_tmp2))
18253 + s_tmp->parent_subject = s_tmp2;
18256 + /* add in ip acls */
18258 + if (!s_tmp->ip_num) {
18259 + s_tmp->ips = NULL;
18264 + (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
18266 + acl_ip_label *));
18269 + return ERR_PTR(-ENOMEM);
18271 + for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
18272 + *(i_tmp + i_num) =
18273 + (struct acl_ip_label *)
18274 + acl_alloc(sizeof (struct acl_ip_label));
18275 + if (!*(i_tmp + i_num))
18276 + return ERR_PTR(-ENOMEM);
18278 + if (copy_from_user
18279 + (&i_utmp2, s_tmp->ips + i_num,
18280 + sizeof (struct acl_ip_label *)))
18281 + return ERR_PTR(-EFAULT);
18283 + if (copy_from_user
18284 + (*(i_tmp + i_num), i_utmp2,
18285 + sizeof (struct acl_ip_label)))
18286 + return ERR_PTR(-EFAULT);
18288 + if ((*(i_tmp + i_num))->iface == NULL)
18291 + len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
18292 + if (!len || len >= IFNAMSIZ)
18293 + return ERR_PTR(-EINVAL);
18294 + tmp = acl_alloc(len);
18296 + return ERR_PTR(-ENOMEM);
18297 + if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
18298 + return ERR_PTR(-EFAULT);
18299 + (*(i_tmp + i_num))->iface = tmp;
18302 + s_tmp->ips = i_tmp;
18305 + if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
18306 + s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
18307 + return ERR_PTR(-ENOMEM);
18313 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
18315 + struct acl_subject_label s_pre;
18316 + struct acl_subject_label * ret;
18320 + if (copy_from_user(&s_pre, userp,
18321 + sizeof (struct acl_subject_label)))
18324 + /* do not add nested subjects here, add
18325 + while parsing objects
18328 + if (s_pre.mode & GR_NESTED) {
18329 + userp = s_pre.prev;
18333 + ret = do_copy_user_subj(userp, role);
18335 + err = PTR_ERR(ret);
18339 + insert_acl_subj_label(ret, role);
18341 + userp = s_pre.prev;
18348 +copy_user_acl(struct gr_arg *arg)
18350 + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
18351 + struct sprole_pw *sptmp;
18352 + struct gr_hash_struct *ghash;
18353 + uid_t *domainlist;
18354 + unsigned int r_num;
18355 + unsigned int len;
18361 + /* we need a default and kernel role */
18362 + if (arg->role_db.num_roles < 2)
18365 + /* copy special role authentication info from userspace */
18367 + num_sprole_pws = arg->num_sprole_pws;
18368 + acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
18370 + if (!acl_special_roles) {
18375 + for (i = 0; i < num_sprole_pws; i++) {
18376 + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
18381 + if (copy_from_user(sptmp, arg->sprole_pws + i,
18382 + sizeof (struct sprole_pw))) {
18388 + strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
18390 + if (!len || len >= GR_SPROLE_LEN) {
18395 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
18400 + if (copy_from_user(tmp, sptmp->rolename, len)) {
18405 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
18406 + printk(KERN_ALERT "Copying special role %s\n", tmp);
18408 + sptmp->rolename = tmp;
18409 + acl_special_roles[i] = sptmp;
18412 + r_utmp = (struct acl_role_label **) arg->role_db.r_table;
18414 + for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
18415 + r_tmp = acl_alloc(sizeof (struct acl_role_label));
18422 + if (copy_from_user(&r_utmp2, r_utmp + r_num,
18423 + sizeof (struct acl_role_label *))) {
18428 + if (copy_from_user(r_tmp, r_utmp2,
18429 + sizeof (struct acl_role_label))) {
18434 + len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
18436 + if (!len || len >= PATH_MAX) {
18441 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
18445 + if (copy_from_user(tmp, r_tmp->rolename, len)) {
18449 + r_tmp->rolename = tmp;
18451 + if (!strcmp(r_tmp->rolename, "default")
18452 + && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
18453 + default_role = r_tmp;
18454 + } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
18455 + kernel_role = r_tmp;
18458 + if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
18462 + if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
18467 + r_tmp->hash = ghash;
18469 + num_subjs = count_user_subjs(r_tmp->hash->first);
18471 + r_tmp->subj_hash_size = num_subjs;
18472 + r_tmp->subj_hash =
18473 + (struct acl_subject_label **)
18474 + create_table(&(r_tmp->subj_hash_size), sizeof(void *));
18476 + if (!r_tmp->subj_hash) {
18481 + err = copy_user_allowedips(r_tmp);
18485 + /* copy domain info */
18486 + if (r_tmp->domain_children != NULL) {
18487 + domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
18488 + if (domainlist == NULL) {
18492 + if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
18496 + r_tmp->domain_children = domainlist;
18499 + err = copy_user_transitions(r_tmp);
18503 + memset(r_tmp->subj_hash, 0,
18504 + r_tmp->subj_hash_size *
18505 + sizeof (struct acl_subject_label *));
18507 + err = copy_user_subjs(r_tmp->hash->first, r_tmp);
18512 + /* set nested subject list to null */
18513 + r_tmp->hash->first = NULL;
18515 + insert_acl_role_label(r_tmp);
18520 + free_variables();
18527 +gracl_init(struct gr_arg *args)
18531 + memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
18532 + memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
18534 + if (init_variables(args)) {
18535 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
18537 + free_variables();
18541 + error = copy_user_acl(args);
18542 + free_init_variables();
18544 + free_variables();
18548 + if ((error = gr_set_acls(0))) {
18549 + free_variables();
18553 + gr_status |= GR_READY;
18558 +/* derived from glibc fnmatch() 0: match, 1: no match*/
18561 +glob_match(const char *p, const char *n)
18565 + while ((c = *p++) != '\0') {
18570 + else if (*n == '/')
18578 + for (c = *p++; c == '?' || c == '*'; c = *p++) {
18581 + else if (c == '?') {
18591 + const char *endp;
18593 + if ((endp = strchr(n, '/')) == NULL)
18594 + endp = n + strlen(n);
18597 + for (--p; n < endp; ++n)
18598 + if (!glob_match(p, n))
18600 + } else if (c == '/') {
18601 + while (*n != '\0' && *n != '/')
18603 + if (*n == '/' && !glob_match(p, n + 1))
18606 + for (--p; n < endp; ++n)
18607 + if (*n == c && !glob_match(p, n))
18618 + if (*n == '\0' || *n == '/')
18621 + not = (*p == '!' || *p == '^');
18627 + unsigned char fn = (unsigned char)*n;
18637 + if (c == '-' && *p != ']') {
18638 + unsigned char cend = *p++;
18640 + if (cend == '\0')
18643 + if (cold <= fn && fn <= cend)
18657 + while (c != ']') {
18684 +static struct acl_object_label *
18685 +chk_glob_label(struct acl_object_label *globbed,
18686 + struct dentry *dentry, struct vfsmount *mnt, char **path)
18688 + struct acl_object_label *tmp;
18690 + if (*path == NULL)
18691 + *path = gr_to_filename_nolock(dentry, mnt);
18696 + if (!glob_match(tmp->filename, *path))
18704 +static struct acl_object_label *
18705 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
18706 + const ino_t curr_ino, const dev_t curr_dev,
18707 + const struct acl_subject_label *subj, char **path)
18709 + struct acl_subject_label *tmpsubj;
18710 + struct acl_object_label *retval;
18711 + struct acl_object_label *retval2;
18713 + tmpsubj = (struct acl_subject_label *) subj;
18714 + read_lock(&gr_inode_lock);
18716 + retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
18718 + if (retval->globbed) {
18719 + retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
18720 + (struct vfsmount *)orig_mnt, path);
18722 + retval = retval2;
18726 + } while ((tmpsubj = tmpsubj->parent_subject));
18727 + read_unlock(&gr_inode_lock);
18732 +static __inline__ struct acl_object_label *
18733 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
18734 + const struct dentry *curr_dentry,
18735 + const struct acl_subject_label *subj, char **path)
18737 + return __full_lookup(orig_dentry, orig_mnt,
18738 + curr_dentry->d_inode->i_ino,
18739 + curr_dentry->d_inode->i_sb->s_dev, subj, path);
18742 +static struct acl_object_label *
18743 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
18744 + const struct acl_subject_label *subj, char *path)
18746 + struct dentry *dentry = (struct dentry *) l_dentry;
18747 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
18748 + struct acl_object_label *retval;
18750 + spin_lock(&dcache_lock);
18752 + if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
18753 + /* ignore Eric Biederman */
18754 + IS_PRIVATE(l_dentry->d_inode))) {
18755 + retval = fakefs_obj;
18760 + if (dentry == real_root && mnt == real_root_mnt)
18763 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
18764 + if (mnt->mnt_parent == mnt)
18767 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
18768 + if (retval != NULL)
18771 + dentry = mnt->mnt_mountpoint;
18772 + mnt = mnt->mnt_parent;
18776 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
18777 + if (retval != NULL)
18780 + dentry = dentry->d_parent;
18783 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
18785 + if (retval == NULL)
18786 + retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
18788 + spin_unlock(&dcache_lock);
18792 +static __inline__ struct acl_object_label *
18793 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
18794 + const struct acl_subject_label *subj)
18796 + char *path = NULL;
18797 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
18800 +static __inline__ struct acl_object_label *
18801 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
18802 + const struct acl_subject_label *subj, char *path)
18804 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
18807 +static struct acl_subject_label *
18808 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
18809 + const struct acl_role_label *role)
18811 + struct dentry *dentry = (struct dentry *) l_dentry;
18812 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
18813 + struct acl_subject_label *retval;
18815 + spin_lock(&dcache_lock);
18818 + if (dentry == real_root && mnt == real_root_mnt)
18820 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
18821 + if (mnt->mnt_parent == mnt)
18824 + read_lock(&gr_inode_lock);
18826 + lookup_acl_subj_label(dentry->d_inode->i_ino,
18827 + dentry->d_inode->i_sb->s_dev, role);
18828 + read_unlock(&gr_inode_lock);
18829 + if (retval != NULL)
18832 + dentry = mnt->mnt_mountpoint;
18833 + mnt = mnt->mnt_parent;
18837 + read_lock(&gr_inode_lock);
18838 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
18839 + dentry->d_inode->i_sb->s_dev, role);
18840 + read_unlock(&gr_inode_lock);
18841 + if (retval != NULL)
18844 + dentry = dentry->d_parent;
18847 + read_lock(&gr_inode_lock);
18848 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
18849 + dentry->d_inode->i_sb->s_dev, role);
18850 + read_unlock(&gr_inode_lock);
18852 + if (unlikely(retval == NULL)) {
18853 + read_lock(&gr_inode_lock);
18854 + retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
18855 + real_root->d_inode->i_sb->s_dev, role);
18856 + read_unlock(&gr_inode_lock);
18859 + spin_unlock(&dcache_lock);
18865 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
18867 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
18868 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
18869 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
18870 + 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
18876 +gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
18878 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
18879 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
18880 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
18881 + 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
18887 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
18888 + const unsigned int effective, const unsigned int fs)
18890 + security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
18891 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
18892 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
18893 + type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
18899 +gr_check_link(const struct dentry * new_dentry,
18900 + const struct dentry * parent_dentry,
18901 + const struct vfsmount * parent_mnt,
18902 + const struct dentry * old_dentry, const struct vfsmount * old_mnt)
18904 + struct acl_object_label *obj;
18905 + __u32 oldmode, newmode;
18908 + if (unlikely(!(gr_status & GR_READY)))
18909 + return (GR_CREATE | GR_LINK);
18911 + obj = chk_obj_label(old_dentry, old_mnt, current->acl);
18912 + oldmode = obj->mode;
18914 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
18915 + oldmode |= (GR_CREATE | GR_LINK);
18917 + needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
18918 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
18919 + needmode |= GR_SETID | GR_AUDIT_SETID;
18922 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
18923 + oldmode | needmode);
18925 + needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
18926 + GR_SETID | GR_READ | GR_FIND | GR_DELETE |
18927 + GR_INHERIT | GR_AUDIT_INHERIT);
18929 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
18932 + if ((oldmode & needmode) != needmode)
18935 + needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
18936 + if ((newmode & needmode) != needmode)
18939 + if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
18942 + needmode = oldmode;
18943 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
18944 + needmode |= GR_SETID;
18946 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
18947 + gr_log_learn(current, old_dentry, old_mnt, needmode);
18948 + return (GR_CREATE | GR_LINK);
18949 + } else if (newmode & GR_SUPPRESS)
18950 + return GR_SUPPRESS;
18956 +gr_search_file(const struct dentry * dentry, const __u32 mode,
18957 + const struct vfsmount * mnt)
18959 + __u32 retval = mode;
18960 + struct acl_subject_label *curracl;
18961 + struct acl_object_label *currobj;
18963 + if (unlikely(!(gr_status & GR_READY)))
18964 + return (mode & ~GR_AUDITS);
18966 + curracl = current->acl;
18968 + currobj = chk_obj_label(dentry, mnt, curracl);
18969 + retval = currobj->mode & mode;
18972 + ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
18973 + && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
18974 + __u32 new_mode = mode;
18976 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
18978 + retval = new_mode;
18980 + if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
18981 + new_mode |= GR_INHERIT;
18983 + if (!(mode & GR_NOLEARN))
18984 + gr_log_learn(current, dentry, mnt, new_mode);
18991 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
18992 + const struct vfsmount * mnt, const __u32 mode)
18994 + struct name_entry *match;
18995 + struct acl_object_label *matchpo;
18996 + struct acl_subject_label *curracl;
19000 + if (unlikely(!(gr_status & GR_READY)))
19001 + return (mode & ~GR_AUDITS);
19003 + preempt_disable();
19004 + path = gr_to_filename_rbac(new_dentry, mnt);
19005 + match = lookup_name_entry_create(path);
19008 + goto check_parent;
19010 + curracl = current->acl;
19012 + read_lock(&gr_inode_lock);
19013 + matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
19014 + read_unlock(&gr_inode_lock);
19017 + if ((matchpo->mode & mode) !=
19018 + (mode & ~(GR_AUDITS | GR_SUPPRESS))
19019 + && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
19020 + __u32 new_mode = mode;
19022 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19024 + gr_log_learn(current, new_dentry, mnt, new_mode);
19026 + preempt_enable();
19029 + preempt_enable();
19030 + return (matchpo->mode & mode);
19034 + curracl = current->acl;
19036 + matchpo = chk_obj_create_label(parent, mnt, curracl, path);
19037 + retval = matchpo->mode & mode;
19039 + if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
19040 + && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
19041 + __u32 new_mode = mode;
19043 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19045 + gr_log_learn(current, new_dentry, mnt, new_mode);
19046 + preempt_enable();
19050 + preempt_enable();
19055 +gr_check_hidden_task(const struct task_struct *task)
19057 + if (unlikely(!(gr_status & GR_READY)))
19060 + if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
19067 +gr_check_protected_task(const struct task_struct *task)
19069 + if (unlikely(!(gr_status & GR_READY) || !task))
19072 + if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
19073 + task->acl != current->acl)
19080 +gr_copy_label(struct task_struct *tsk)
19082 + tsk->signal->used_accept = 0;
19083 + tsk->acl_sp_role = 0;
19084 + tsk->acl_role_id = current->acl_role_id;
19085 + tsk->acl = current->acl;
19086 + tsk->role = current->role;
19087 + tsk->signal->curr_ip = current->signal->curr_ip;
19088 + if (current->exec_file)
19089 + get_file(current->exec_file);
19090 + tsk->exec_file = current->exec_file;
19091 + tsk->is_writable = current->is_writable;
19092 + if (unlikely(current->signal->used_accept))
19093 + current->signal->curr_ip = 0;
19099 +gr_set_proc_res(struct task_struct *task)
19101 + struct acl_subject_label *proc;
19102 + unsigned short i;
19104 + proc = task->acl;
19106 + if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
19109 + for (i = 0; i < (GR_NLIMITS - 1); i++) {
19110 + if (!(proc->resmask & (1 << i)))
19113 + task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
19114 + task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
19121 +gr_check_user_change(int real, int effective, int fs)
19128 + int effectiveok = 0;
19131 + if (unlikely(!(gr_status & GR_READY)))
19134 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19135 + gr_log_learn_id_change(current, 'u', real, effective, fs);
19137 + num = current->acl->user_trans_num;
19138 + uidlist = current->acl->user_transitions;
19140 + if (uidlist == NULL)
19145 + if (effective == -1)
19150 + if (current->acl->user_trans_type & GR_ID_ALLOW) {
19151 + for (i = 0; i < num; i++) {
19152 + curuid = (int)uidlist[i];
19153 + if (real == curuid)
19155 + if (effective == curuid)
19157 + if (fs == curuid)
19160 + } else if (current->acl->user_trans_type & GR_ID_DENY) {
19161 + for (i = 0; i < num; i++) {
19162 + curuid = (int)uidlist[i];
19163 + if (real == curuid)
19165 + if (effective == curuid)
19167 + if (fs == curuid)
19170 + /* not in deny list */
19178 + if (realok && effectiveok && fsok)
19181 + gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19187 +gr_check_group_change(int real, int effective, int fs)
19194 + int effectiveok = 0;
19197 + if (unlikely(!(gr_status & GR_READY)))
19200 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19201 + gr_log_learn_id_change(current, 'g', real, effective, fs);
19203 + num = current->acl->group_trans_num;
19204 + gidlist = current->acl->group_transitions;
19206 + if (gidlist == NULL)
19211 + if (effective == -1)
19216 + if (current->acl->group_trans_type & GR_ID_ALLOW) {
19217 + for (i = 0; i < num; i++) {
19218 + curgid = (int)gidlist[i];
19219 + if (real == curgid)
19221 + if (effective == curgid)
19223 + if (fs == curgid)
19226 + } else if (current->acl->group_trans_type & GR_ID_DENY) {
19227 + for (i = 0; i < num; i++) {
19228 + curgid = (int)gidlist[i];
19229 + if (real == curgid)
19231 + if (effective == curgid)
19233 + if (fs == curgid)
19236 + /* not in deny list */
19244 + if (realok && effectiveok && fsok)
19247 + gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19253 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
19255 + struct acl_role_label *role = task->role;
19256 + struct acl_subject_label *subj = NULL;
19257 + struct acl_object_label *obj;
19258 + struct file *filp;
19260 + if (unlikely(!(gr_status & GR_READY)))
19263 + filp = task->exec_file;
19265 + /* kernel process, we'll give them the kernel role */
19266 + if (unlikely(!filp)) {
19267 + task->role = kernel_role;
19268 + task->acl = kernel_role->root_label;
19270 + } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
19271 + role = lookup_acl_role_label(task, uid, gid);
19273 + /* perform subject lookup in possibly new role
19274 + we can use this result below in the case where role == task->role
19276 + subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
19278 + /* if we changed uid/gid, but result in the same role
19279 + and are using inheritance, don't lose the inherited subject
19280 + if current subject is other than what normal lookup
19281 + would result in, we arrived via inheritance, don't
19284 + if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
19285 + (subj == task->acl)))
19286 + task->acl = subj;
19288 + task->role = role;
19290 + task->is_writable = 0;
19292 + /* ignore additional mmap checks for processes that are writable
19293 + by the default ACL */
19294 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
19295 + if (unlikely(obj->mode & GR_WRITE))
19296 + task->is_writable = 1;
19297 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
19298 + if (unlikely(obj->mode & GR_WRITE))
19299 + task->is_writable = 1;
19301 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19302 + printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19305 + gr_set_proc_res(task);
19311 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
19313 + struct task_struct *task = current;
19314 + struct acl_subject_label *newacl;
19315 + struct acl_object_label *obj;
19318 + if (unlikely(!(gr_status & GR_READY)))
19321 + newacl = chk_subj_label(dentry, mnt, task->role);
19324 + if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
19325 + GR_POVERRIDE) && (task->acl != newacl) &&
19326 + !(task->role->roletype & GR_ROLE_GOD) &&
19327 + !gr_search_file(dentry, GR_PTRACERD, mnt) &&
19328 + !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
19329 + (atomic_read(&task->fs->count) > 1 ||
19330 + atomic_read(&task->files->count) > 1 ||
19331 + atomic_read(&task->sighand->count) > 1)) {
19332 + task_unlock(task);
19333 + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
19336 + task_unlock(task);
19338 + obj = chk_obj_label(dentry, mnt, task->acl);
19339 + retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
19341 + if (!(task->acl->mode & GR_INHERITLEARN) &&
19342 + ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
19344 + task->acl = obj->nested;
19346 + task->acl = newacl;
19347 + } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
19348 + gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
19350 + task->is_writable = 0;
19352 + /* ignore additional mmap checks for processes that are writable
19353 + by the default ACL */
19354 + obj = chk_obj_label(dentry, mnt, default_role->root_label);
19355 + if (unlikely(obj->mode & GR_WRITE))
19356 + task->is_writable = 1;
19357 + obj = chk_obj_label(dentry, mnt, task->role->root_label);
19358 + if (unlikely(obj->mode & GR_WRITE))
19359 + task->is_writable = 1;
19361 + gr_set_proc_res(task);
19363 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19364 + printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19369 +/* always called with valid inodev ptr */
19371 +do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
19373 + struct acl_object_label *matchpo;
19374 + struct acl_subject_label *matchps;
19375 + struct acl_subject_label *subj;
19376 + struct acl_role_label *role;
19377 + unsigned int i, x;
19379 + FOR_EACH_ROLE_START(role, i)
19380 + FOR_EACH_SUBJECT_START(role, subj, x)
19381 + if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
19382 + matchpo->mode |= GR_DELETED;
19383 + FOR_EACH_SUBJECT_END(subj,x)
19384 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
19385 + if (subj->inode == ino && subj->device == dev)
19386 + subj->mode |= GR_DELETED;
19387 + FOR_EACH_NESTED_SUBJECT_END(subj)
19388 + if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
19389 + matchps->mode |= GR_DELETED;
19390 + FOR_EACH_ROLE_END(role,i)
19392 + inodev->nentry->deleted = 1;
19398 +gr_handle_delete(const ino_t ino, const dev_t dev)
19400 + struct inodev_entry *inodev;
19402 + if (unlikely(!(gr_status & GR_READY)))
19405 + write_lock(&gr_inode_lock);
19406 + inodev = lookup_inodev_entry(ino, dev);
19407 + if (inodev != NULL)
19408 + do_handle_delete(inodev, ino, dev);
19409 + write_unlock(&gr_inode_lock);
19415 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
19416 + const ino_t newinode, const dev_t newdevice,
19417 + struct acl_subject_label *subj)
19419 + unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
19420 + struct acl_object_label *match;
19422 + match = subj->obj_hash[index];
19424 + while (match && (match->inode != oldinode ||
19425 + match->device != olddevice ||
19426 + !(match->mode & GR_DELETED)))
19427 + match = match->next;
19429 + if (match && (match->inode == oldinode)
19430 + && (match->device == olddevice)
19431 + && (match->mode & GR_DELETED)) {
19432 + if (match->prev == NULL) {
19433 + subj->obj_hash[index] = match->next;
19434 + if (match->next != NULL)
19435 + match->next->prev = NULL;
19437 + match->prev->next = match->next;
19438 + if (match->next != NULL)
19439 + match->next->prev = match->prev;
19441 + match->prev = NULL;
19442 + match->next = NULL;
19443 + match->inode = newinode;
19444 + match->device = newdevice;
19445 + match->mode &= ~GR_DELETED;
19447 + insert_acl_obj_label(match, subj);
19454 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
19455 + const ino_t newinode, const dev_t newdevice,
19456 + struct acl_role_label *role)
19458 + unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
19459 + struct acl_subject_label *match;
19461 + match = role->subj_hash[index];
19463 + while (match && (match->inode != oldinode ||
19464 + match->device != olddevice ||
19465 + !(match->mode & GR_DELETED)))
19466 + match = match->next;
19468 + if (match && (match->inode == oldinode)
19469 + && (match->device == olddevice)
19470 + && (match->mode & GR_DELETED)) {
19471 + if (match->prev == NULL) {
19472 + role->subj_hash[index] = match->next;
19473 + if (match->next != NULL)
19474 + match->next->prev = NULL;
19476 + match->prev->next = match->next;
19477 + if (match->next != NULL)
19478 + match->next->prev = match->prev;
19480 + match->prev = NULL;
19481 + match->next = NULL;
19482 + match->inode = newinode;
19483 + match->device = newdevice;
19484 + match->mode &= ~GR_DELETED;
19486 + insert_acl_subj_label(match, role);
19493 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
19494 + const ino_t newinode, const dev_t newdevice)
19496 + unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
19497 + struct inodev_entry *match;
19499 + match = inodev_set.i_hash[index];
19501 + while (match && (match->nentry->inode != oldinode ||
19502 + match->nentry->device != olddevice || !match->nentry->deleted))
19503 + match = match->next;
19505 + if (match && (match->nentry->inode == oldinode)
19506 + && (match->nentry->device == olddevice) &&
19507 + match->nentry->deleted) {
19508 + if (match->prev == NULL) {
19509 + inodev_set.i_hash[index] = match->next;
19510 + if (match->next != NULL)
19511 + match->next->prev = NULL;
19513 + match->prev->next = match->next;
19514 + if (match->next != NULL)
19515 + match->next->prev = match->prev;
19517 + match->prev = NULL;
19518 + match->next = NULL;
19519 + match->nentry->inode = newinode;
19520 + match->nentry->device = newdevice;
19521 + match->nentry->deleted = 0;
19523 + insert_inodev_entry(match);
19530 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
19531 + const struct vfsmount *mnt)
19533 + struct acl_subject_label *subj;
19534 + struct acl_role_label *role;
19535 + unsigned int i, x;
19537 + FOR_EACH_ROLE_START(role, i)
19538 + update_acl_subj_label(matchn->inode, matchn->device,
19539 + dentry->d_inode->i_ino,
19540 + dentry->d_inode->i_sb->s_dev, role);
19542 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
19543 + if ((subj->inode == dentry->d_inode->i_ino) &&
19544 + (subj->device == dentry->d_inode->i_sb->s_dev)) {
19545 + subj->inode = dentry->d_inode->i_ino;
19546 + subj->device = dentry->d_inode->i_sb->s_dev;
19548 + FOR_EACH_NESTED_SUBJECT_END(subj)
19549 + FOR_EACH_SUBJECT_START(role, subj, x)
19550 + update_acl_obj_label(matchn->inode, matchn->device,
19551 + dentry->d_inode->i_ino,
19552 + dentry->d_inode->i_sb->s_dev, subj);
19553 + FOR_EACH_SUBJECT_END(subj,x)
19554 + FOR_EACH_ROLE_END(role,i)
19556 + update_inodev_entry(matchn->inode, matchn->device,
19557 + dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
19563 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
19565 + struct name_entry *matchn;
19567 + if (unlikely(!(gr_status & GR_READY)))
19570 + preempt_disable();
19571 + matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
19573 + if (unlikely((unsigned long)matchn)) {
19574 + write_lock(&gr_inode_lock);
19575 + do_handle_create(matchn, dentry, mnt);
19576 + write_unlock(&gr_inode_lock);
19578 + preempt_enable();
19584 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
19585 + struct dentry *old_dentry,
19586 + struct dentry *new_dentry,
19587 + struct vfsmount *mnt, const __u8 replace)
19589 + struct name_entry *matchn;
19590 + struct inodev_entry *inodev;
19592 + /* vfs_rename swaps the name and parent link for old_dentry and
19594 + at this point, old_dentry has the new name, parent link, and inode
19595 + for the renamed file
19596 + if a file is being replaced by a rename, new_dentry has the inode
19597 + and name for the replaced file
19600 + if (unlikely(!(gr_status & GR_READY)))
19603 + preempt_disable();
19604 + matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
19606 + /* we wouldn't have to check d_inode if it weren't for
19607 + NFS silly-renaming
19610 + write_lock(&gr_inode_lock);
19611 + if (unlikely(replace && new_dentry->d_inode)) {
19612 + inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
19613 + new_dentry->d_inode->i_sb->s_dev);
19614 + if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
19615 + do_handle_delete(inodev, new_dentry->d_inode->i_ino,
19616 + new_dentry->d_inode->i_sb->s_dev);
19619 + inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
19620 + old_dentry->d_inode->i_sb->s_dev);
19621 + if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
19622 + do_handle_delete(inodev, old_dentry->d_inode->i_ino,
19623 + old_dentry->d_inode->i_sb->s_dev);
19625 + if (unlikely((unsigned long)matchn))
19626 + do_handle_create(matchn, old_dentry, mnt);
19628 + write_unlock(&gr_inode_lock);
19629 + preempt_enable();
19635 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
19636 + unsigned char **sum)
19638 + struct acl_role_label *r;
19639 + struct role_allowed_ip *ipp;
19640 + struct role_transition *trans;
19644 + /* check transition table */
19646 + for (trans = current->role->transitions; trans; trans = trans->next) {
19647 + if (!strcmp(rolename, trans->rolename)) {
19656 + /* handle special roles that do not require authentication
19659 + FOR_EACH_ROLE_START(r, i)
19660 + if (!strcmp(rolename, r->rolename) &&
19661 + (r->roletype & GR_ROLE_SPECIAL)) {
19663 + if (r->allowed_ips != NULL) {
19664 + for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
19665 + if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
19666 + (ntohl(ipp->addr) & ipp->netmask))
19674 + if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
19675 + ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
19681 + FOR_EACH_ROLE_END(r,i)
19683 + for (i = 0; i < num_sprole_pws; i++) {
19684 + if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
19685 + *salt = acl_special_roles[i]->salt;
19686 + *sum = acl_special_roles[i]->sum;
19695 +assign_special_role(char *rolename)
19697 + struct acl_object_label *obj;
19698 + struct acl_role_label *r;
19699 + struct acl_role_label *assigned = NULL;
19700 + struct task_struct *tsk;
19701 + struct file *filp;
19704 + FOR_EACH_ROLE_START(r, i)
19705 + if (!strcmp(rolename, r->rolename) &&
19706 + (r->roletype & GR_ROLE_SPECIAL))
19708 + FOR_EACH_ROLE_END(r,i)
19713 + read_lock(&tasklist_lock);
19714 + read_lock(&grsec_exec_file_lock);
19716 + tsk = current->parent;
19720 + filp = tsk->exec_file;
19721 + if (filp == NULL)
19724 + tsk->is_writable = 0;
19726 + tsk->acl_sp_role = 1;
19727 + tsk->acl_role_id = ++acl_sp_role_value;
19728 + tsk->role = assigned;
19729 + tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
19731 + /* ignore additional mmap checks for processes that are writable
19732 + by the default ACL */
19733 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
19734 + if (unlikely(obj->mode & GR_WRITE))
19735 + tsk->is_writable = 1;
19736 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
19737 + if (unlikely(obj->mode & GR_WRITE))
19738 + tsk->is_writable = 1;
19740 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19741 + printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
19745 + read_unlock(&grsec_exec_file_lock);
19746 + read_unlock(&tasklist_lock);
19750 +int gr_check_secure_terminal(struct task_struct *task)
19752 + struct task_struct *p, *p2, *p3;
19753 + struct files_struct *files;
19754 + struct fdtable *fdt;
19755 + struct file *our_file = NULL, *file;
19758 + if (task->signal->tty == NULL)
19761 + files = get_files_struct(task);
19762 + if (files != NULL) {
19764 + fdt = files_fdtable(files);
19765 + for (i=0; i < fdt->max_fds; i++) {
19766 + file = fcheck_files(files, i);
19767 + if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
19772 + rcu_read_unlock();
19773 + put_files_struct(files);
19776 + if (our_file == NULL)
19779 + read_lock(&tasklist_lock);
19780 + do_each_thread(p2, p) {
19781 + files = get_files_struct(p);
19782 + if (files == NULL ||
19783 + (p->signal && p->signal->tty == task->signal->tty)) {
19784 + if (files != NULL)
19785 + put_files_struct(files);
19789 + fdt = files_fdtable(files);
19790 + for (i=0; i < fdt->max_fds; i++) {
19791 + file = fcheck_files(files, i);
19792 + if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
19793 + file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
19795 + while (p3->pid > 0) {
19802 + gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
19803 + gr_handle_alertkill(p);
19804 + rcu_read_unlock();
19805 + put_files_struct(files);
19806 + read_unlock(&tasklist_lock);
19811 + rcu_read_unlock();
19812 + put_files_struct(files);
19813 + } while_each_thread(p2, p);
19814 + read_unlock(&tasklist_lock);
19821 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
19823 + struct gr_arg_wrapper uwrap;
19824 + unsigned char *sprole_salt;
19825 + unsigned char *sprole_sum;
19826 + int error = sizeof (struct gr_arg_wrapper);
19829 + down(&gr_dev_sem);
19831 + if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
19836 + if (count != sizeof (struct gr_arg_wrapper)) {
19837 + gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
19843 + if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
19844 + gr_auth_expires = 0;
19845 + gr_auth_attempts = 0;
19848 + if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
19853 + if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
19858 + if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
19863 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
19864 + gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
19865 + time_after(gr_auth_expires, get_seconds())) {
19870 + /* if non-root trying to do anything other than use a special role,
19871 + do not attempt authentication, do not count towards authentication
19875 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
19876 + gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
19882 + /* ensure pw and special role name are null terminated */
19884 + gr_usermode->pw[GR_PW_LEN - 1] = '\0';
19885 + gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
19888 + * We have our enough of the argument structure..(we have yet
19889 + * to copy_from_user the tables themselves) . Copy the tables
19890 + * only if we need them, i.e. for loading operations. */
19892 + switch (gr_usermode->mode) {
19894 + if (gr_status & GR_READY) {
19896 + if (!gr_check_secure_terminal(current))
19902 + if ((gr_status & GR_READY)
19903 + && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
19904 + gr_status &= ~GR_READY;
19905 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
19906 + free_variables();
19907 + memset(gr_usermode, 0, sizeof (struct gr_arg));
19908 + memset(gr_system_salt, 0, GR_SALT_LEN);
19909 + memset(gr_system_sum, 0, GR_SHA_LEN);
19910 + } else if (gr_status & GR_READY) {
19911 + gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
19914 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
19919 + if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
19920 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
19922 + if (gr_status & GR_READY)
19926 + gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
19930 + if (!(gr_status & GR_READY)) {
19931 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
19933 + } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
19935 + gr_status &= ~GR_READY;
19936 + free_variables();
19937 + if (!(error2 = gracl_init(gr_usermode))) {
19939 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
19943 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
19946 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
19951 + if (unlikely(!(gr_status & GR_READY))) {
19952 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
19957 + if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
19958 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
19959 + if (gr_usermode->segv_device && gr_usermode->segv_inode) {
19960 + struct acl_subject_label *segvacl;
19962 + lookup_acl_subj_label(gr_usermode->segv_inode,
19963 + gr_usermode->segv_device,
19966 + segvacl->crashes = 0;
19967 + segvacl->expires = 0;
19969 + } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
19970 + gr_remove_uid(gr_usermode->segv_uid);
19973 + gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
19979 + if (unlikely(!(gr_status & GR_READY))) {
19980 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
19985 + if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
19986 + current->role->expires = 0;
19987 + current->role->auth_attempts = 0;
19990 + if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
19991 + time_after(current->role->expires, get_seconds())) {
19996 + if (lookup_special_role_auth
19997 + (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
19998 + && ((!sprole_salt && !sprole_sum)
19999 + || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
20001 + assign_special_role(gr_usermode->sp_role);
20002 + read_lock(&tasklist_lock);
20003 + if (current->parent)
20004 + p = current->parent->role->rolename;
20005 + read_unlock(&tasklist_lock);
20006 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
20007 + p, acl_sp_role_value);
20009 + gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
20011 + if(!(current->role->auth_attempts++))
20012 + current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20018 + if (unlikely(!(gr_status & GR_READY))) {
20019 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
20024 + if (current->role->roletype & GR_ROLE_SPECIAL) {
20028 + read_lock(&tasklist_lock);
20029 + if (current->parent) {
20030 + p = current->parent->role->rolename;
20031 + i = current->parent->acl_role_id;
20033 + read_unlock(&tasklist_lock);
20035 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
20038 + gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
20044 + gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
20049 + if (error != -EPERM)
20052 + if(!(gr_auth_attempts++))
20053 + gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20061 +gr_set_acls(const int type)
20063 + struct acl_object_label *obj;
20064 + struct task_struct *task, *task2;
20065 + struct file *filp;
20066 + struct acl_role_label *role = current->role;
20067 + __u16 acl_role_id = current->acl_role_id;
20069 + read_lock(&tasklist_lock);
20070 + read_lock(&grsec_exec_file_lock);
20071 + do_each_thread(task2, task) {
20072 + /* check to see if we're called from the exit handler,
20073 + if so, only replace ACLs that have inherited the admin
20076 + if (type && (task->role != role ||
20077 + task->acl_role_id != acl_role_id))
20080 + task->acl_role_id = 0;
20081 + task->acl_sp_role = 0;
20083 + if ((filp = task->exec_file)) {
20084 + task->role = lookup_acl_role_label(task, task->uid, task->gid);
20087 + chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
20090 + struct acl_subject_label *curr;
20091 + curr = task->acl;
20093 + task->is_writable = 0;
20094 + /* ignore additional mmap checks for processes that are writable
20095 + by the default ACL */
20096 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20097 + if (unlikely(obj->mode & GR_WRITE))
20098 + task->is_writable = 1;
20099 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
20100 + if (unlikely(obj->mode & GR_WRITE))
20101 + task->is_writable = 1;
20103 + gr_set_proc_res(task);
20105 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20106 + printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
20109 + read_unlock(&grsec_exec_file_lock);
20110 + read_unlock(&tasklist_lock);
20111 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
20115 + // it's a kernel process
20116 + task->role = kernel_role;
20117 + task->acl = kernel_role->root_label;
20118 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
20119 + task->acl->mode &= ~GR_PROCFIND;
20122 + } while_each_thread(task2, task);
20123 + read_unlock(&grsec_exec_file_lock);
20124 + read_unlock(&tasklist_lock);
20129 +gr_learn_resource(const struct task_struct *task,
20130 + const int res, const unsigned long wanted, const int gt)
20132 + struct acl_subject_label *acl;
20134 + if (unlikely((gr_status & GR_READY) &&
20135 + task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
20136 + goto skip_reslog;
20138 +#ifdef CONFIG_GRKERNSEC_RESLOG
20139 + gr_log_resource(task, res, wanted, gt);
20143 + if (unlikely(!(gr_status & GR_READY) || !wanted))
20148 + if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
20149 + !(acl->resmask & (1 << (unsigned short) res))))
20152 + if (wanted >= acl->res[res].rlim_cur) {
20153 + unsigned long res_add;
20155 + res_add = wanted;
20158 + res_add += GR_RLIM_CPU_BUMP;
20160 + case RLIMIT_FSIZE:
20161 + res_add += GR_RLIM_FSIZE_BUMP;
20163 + case RLIMIT_DATA:
20164 + res_add += GR_RLIM_DATA_BUMP;
20166 + case RLIMIT_STACK:
20167 + res_add += GR_RLIM_STACK_BUMP;
20169 + case RLIMIT_CORE:
20170 + res_add += GR_RLIM_CORE_BUMP;
20173 + res_add += GR_RLIM_RSS_BUMP;
20175 + case RLIMIT_NPROC:
20176 + res_add += GR_RLIM_NPROC_BUMP;
20178 + case RLIMIT_NOFILE:
20179 + res_add += GR_RLIM_NOFILE_BUMP;
20181 + case RLIMIT_MEMLOCK:
20182 + res_add += GR_RLIM_MEMLOCK_BUMP;
20185 + res_add += GR_RLIM_AS_BUMP;
20187 + case RLIMIT_LOCKS:
20188 + res_add += GR_RLIM_LOCKS_BUMP;
20192 + acl->res[res].rlim_cur = res_add;
20194 + if (wanted > acl->res[res].rlim_max)
20195 + acl->res[res].rlim_max = res_add;
20197 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
20198 + task->role->roletype, acl->filename,
20199 + acl->res[res].rlim_cur, acl->res[res].rlim_max,
20200 + "", (unsigned long) res);
20206 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
20208 +pax_set_initial_flags(struct linux_binprm *bprm)
20210 + struct task_struct *task = current;
20211 + struct acl_subject_label *proc;
20212 + unsigned long flags;
20214 + if (unlikely(!(gr_status & GR_READY)))
20217 + flags = pax_get_flags(task);
20219 + proc = task->acl;
20221 + if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
20222 + flags &= ~MF_PAX_PAGEEXEC;
20223 + if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
20224 + flags &= ~MF_PAX_SEGMEXEC;
20225 + if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
20226 + flags &= ~MF_PAX_RANDMMAP;
20227 + if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
20228 + flags &= ~MF_PAX_EMUTRAMP;
20229 + if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
20230 + flags &= ~MF_PAX_MPROTECT;
20232 + if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
20233 + flags |= MF_PAX_PAGEEXEC;
20234 + if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
20235 + flags |= MF_PAX_SEGMEXEC;
20236 + if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
20237 + flags |= MF_PAX_RANDMMAP;
20238 + if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
20239 + flags |= MF_PAX_EMUTRAMP;
20240 + if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
20241 + flags |= MF_PAX_MPROTECT;
20243 + pax_set_flags(task, flags);
20249 +#ifdef CONFIG_SYSCTL
20250 +/* Eric Biederman likes breaking userland ABI and every inode-based security
20251 + system to save 35kb of memory */
20253 +/* we modify the passed in filename, but adjust it back before returning */
20254 +static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
20256 + struct name_entry *nmatch;
20257 + char *p, *lastp = NULL;
20258 + struct acl_object_label *obj = NULL, *tmp;
20259 + struct acl_subject_label *tmpsubj;
20262 + read_lock(&gr_inode_lock);
20264 + p = name + len - 1;
20266 + nmatch = lookup_name_entry(name);
20267 + if (lastp != NULL)
20270 + if (nmatch == NULL)
20271 + goto next_component;
20272 + tmpsubj = current->acl;
20274 + obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
20275 + if (obj != NULL) {
20276 + tmp = obj->globbed;
20278 + if (!glob_match(tmp->filename, name)) {
20286 + } while ((tmpsubj = tmpsubj->parent_subject));
20292 + while (*p != '/')
20304 + read_unlock(&gr_inode_lock);
20305 + /* obj returned will always be non-null */
20309 +/* returns 0 when allowing, non-zero on error
20310 + op of 0 is used for readdir, so we don't log the names of hidden files
20313 +gr_handle_sysctl(const struct ctl_table *table, const int op)
20316 + const char *proc_sys = "/proc/sys";
20318 + struct acl_object_label *obj;
20319 + unsigned short len = 0, pos = 0, depth = 0, i;
20323 + if (unlikely(!(gr_status & GR_READY)))
20326 + /* for now, ignore operations on non-sysctl entries if it's not a
20328 + if (table->child != NULL && op != 0)
20332 + /* it's only a read if it's an entry, read on dirs is for readdir */
20333 + if (op & MAY_READ)
20335 + if (op & MAY_WRITE)
20336 + mode |= GR_WRITE;
20338 + preempt_disable();
20340 + path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
20342 + /* it's only a read/write if it's an actual entry, not a dir
20343 + (which are opened for readdir)
20346 + /* convert the requested sysctl entry into a pathname */
20348 + for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20349 + len += strlen(tmp->procname);
20354 + if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
20359 + memset(path, 0, PAGE_SIZE);
20361 + memcpy(path, proc_sys, strlen(proc_sys));
20363 + pos += strlen(proc_sys);
20365 + for (; depth > 0; depth--) {
20368 + for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20369 + if (depth == i) {
20370 + memcpy(path + pos, tmp->procname,
20371 + strlen(tmp->procname));
20372 + pos += strlen(tmp->procname);
20378 + obj = gr_lookup_by_name(path, pos);
20379 + err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
20381 + if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
20382 + ((err & mode) != mode))) {
20383 + __u32 new_mode = mode;
20385 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
20388 + gr_log_learn_sysctl(current, path, new_mode);
20389 + } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
20390 + gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
20392 + } else if (!(err & GR_FIND)) {
20394 + } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
20395 + gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
20396 + path, (mode & GR_READ) ? " reading" : "",
20397 + (mode & GR_WRITE) ? " writing" : "");
20399 + } else if ((err & mode) != mode) {
20401 + } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
20402 + gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
20403 + path, (mode & GR_READ) ? " reading" : "",
20404 + (mode & GR_WRITE) ? " writing" : "");
20410 + preempt_enable();
20417 +gr_handle_proc_ptrace(struct task_struct *task)
20419 + struct file *filp;
20420 + struct task_struct *tmp = task;
20421 + struct task_struct *curtemp = current;
20424 + if (unlikely(!(gr_status & GR_READY)))
20427 + read_lock(&tasklist_lock);
20428 + read_lock(&grsec_exec_file_lock);
20429 + filp = task->exec_file;
20431 + while (tmp->pid > 0) {
20432 + if (tmp == curtemp)
20434 + tmp = tmp->parent;
20437 + if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
20438 + read_unlock(&grsec_exec_file_lock);
20439 + read_unlock(&tasklist_lock);
20443 + retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
20444 + read_unlock(&grsec_exec_file_lock);
20445 + read_unlock(&tasklist_lock);
20447 + if (retmode & GR_NOPTRACE)
20450 + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
20451 + && (current->acl != task->acl || (current->acl != current->role->root_label
20452 + && current->pid != task->pid)))
20459 +gr_handle_ptrace(struct task_struct *task, const long request)
20461 + struct task_struct *tmp = task;
20462 + struct task_struct *curtemp = current;
20465 + if (unlikely(!(gr_status & GR_READY)))
20468 + read_lock(&tasklist_lock);
20469 + while (tmp->pid > 0) {
20470 + if (tmp == curtemp)
20472 + tmp = tmp->parent;
20475 + if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
20476 + read_unlock(&tasklist_lock);
20477 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
20480 + read_unlock(&tasklist_lock);
20482 + read_lock(&grsec_exec_file_lock);
20483 + if (unlikely(!task->exec_file)) {
20484 + read_unlock(&grsec_exec_file_lock);
20488 + retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
20489 + read_unlock(&grsec_exec_file_lock);
20491 + if (retmode & GR_NOPTRACE) {
20492 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
20496 + if (retmode & GR_PTRACERD) {
20497 + switch (request) {
20498 + case PTRACE_POKETEXT:
20499 + case PTRACE_POKEDATA:
20500 + case PTRACE_POKEUSR:
20501 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
20502 + case PTRACE_SETREGS:
20503 + case PTRACE_SETFPREGS:
20506 + case PTRACE_SETFPXREGS:
20508 +#ifdef CONFIG_ALTIVEC
20509 + case PTRACE_SETVRREGS:
20515 + } else if (!(current->acl->mode & GR_POVERRIDE) &&
20516 + !(current->role->roletype & GR_ROLE_GOD) &&
20517 + (current->acl != task->acl)) {
20518 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
20525 +static int is_writable_mmap(const struct file *filp)
20527 + struct task_struct *task = current;
20528 + struct acl_object_label *obj, *obj2;
20530 + if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
20531 + !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
20532 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20533 + obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
20534 + task->role->root_label);
20535 + if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
20536 + gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
20544 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
20548 + if (unlikely(!file || !(prot & PROT_EXEC)))
20551 + if (is_writable_mmap(file))
20555 + gr_search_file(file->f_path.dentry,
20556 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
20557 + file->f_path.mnt);
20559 + if (!gr_tpe_allow(file))
20562 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
20563 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
20565 + } else if (unlikely(!(mode & GR_EXEC))) {
20567 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
20568 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
20576 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
20580 + if (unlikely(!file || !(prot & PROT_EXEC)))
20583 + if (is_writable_mmap(file))
20587 + gr_search_file(file->f_path.dentry,
20588 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
20589 + file->f_path.mnt);
20591 + if (!gr_tpe_allow(file))
20594 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
20595 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
20597 + } else if (unlikely(!(mode & GR_EXEC))) {
20599 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
20600 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
20608 +gr_acl_handle_psacct(struct task_struct *task, const long code)
20610 + unsigned long runtime;
20611 + unsigned long cputime;
20612 + unsigned int wday, cday;
20616 + struct timespec timeval;
20618 + if (unlikely(!(gr_status & GR_READY) || !task->acl ||
20619 + !(task->acl->mode & GR_PROCACCT)))
20622 + do_posix_clock_monotonic_gettime(&timeval);
20623 + runtime = timeval.tv_sec - task->start_time.tv_sec;
20624 + wday = runtime / (3600 * 24);
20625 + runtime -= wday * (3600 * 24);
20626 + whr = runtime / 3600;
20627 + runtime -= whr * 3600;
20628 + wmin = runtime / 60;
20629 + runtime -= wmin * 60;
20632 + cputime = (task->utime + task->stime) / HZ;
20633 + cday = cputime / (3600 * 24);
20634 + cputime -= cday * (3600 * 24);
20635 + chr = cputime / 3600;
20636 + cputime -= chr * 3600;
20637 + cmin = cputime / 60;
20638 + cputime -= cmin * 60;
20641 + gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
20646 +void gr_set_kernel_label(struct task_struct *task)
20648 + if (gr_status & GR_READY) {
20649 + task->role = kernel_role;
20650 + task->acl = kernel_role->root_label;
20655 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
20657 + struct task_struct *task = current;
20658 + struct dentry *dentry = file->f_path.dentry;
20659 + struct vfsmount *mnt = file->f_path.mnt;
20660 + struct acl_object_label *obj, *tmp;
20661 + struct acl_subject_label *subj;
20662 + unsigned int bufsize;
20666 + if (unlikely(!(gr_status & GR_READY)))
20669 + if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
20672 + /* ignore Eric Biederman */
20673 + if (IS_PRIVATE(dentry->d_inode))
20676 + subj = task->acl;
20678 + obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
20680 + return (obj->mode & GR_FIND) ? 1 : 0;
20681 + } while ((subj = subj->parent_subject));
20683 + obj = chk_obj_label(dentry, mnt, task->acl);
20684 + if (obj->globbed == NULL)
20685 + return (obj->mode & GR_FIND) ? 1 : 0;
20687 + is_not_root = ((obj->filename[0] == '/') &&
20688 + (obj->filename[1] == '\0')) ? 0 : 1;
20689 + bufsize = PAGE_SIZE - namelen - is_not_root;
20691 + /* check bufsize > PAGE_SIZE || bufsize == 0 */
20692 + if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
20695 + preempt_disable();
20696 + path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
20699 + bufsize = strlen(path);
20701 + /* if base is "/", don't append an additional slash */
20703 + *(path + bufsize) = '/';
20704 + memcpy(path + bufsize + is_not_root, name, namelen);
20705 + *(path + bufsize + namelen + is_not_root) = '\0';
20707 + tmp = obj->globbed;
20709 + if (!glob_match(tmp->filename, path)) {
20710 + preempt_enable();
20711 + return (tmp->mode & GR_FIND) ? 1 : 0;
20715 + preempt_enable();
20716 + return (obj->mode & GR_FIND) ? 1 : 0;
20719 +EXPORT_SYMBOL(gr_learn_resource);
20720 +EXPORT_SYMBOL(gr_set_kernel_label);
20721 +#ifdef CONFIG_SECURITY
20722 +EXPORT_SYMBOL(gr_check_user_change);
20723 +EXPORT_SYMBOL(gr_check_group_change);
20726 diff -urNp linux-2.6.27.4/grsecurity/gracl_cap.c linux-2.6.27.4/grsecurity/gracl_cap.c
20727 --- linux-2.6.27.4/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
20728 +++ linux-2.6.27.4/grsecurity/gracl_cap.c 2008-10-25 12:03:07.000000000 -0400
20730 +#include <linux/kernel.h>
20731 +#include <linux/module.h>
20732 +#include <linux/sched.h>
20733 +#include <linux/gracl.h>
20734 +#include <linux/grsecurity.h>
20735 +#include <linux/grinternal.h>
20737 +static const char *captab_log[] = {
20739 + "CAP_DAC_OVERRIDE",
20740 + "CAP_DAC_READ_SEARCH",
20747 + "CAP_LINUX_IMMUTABLE",
20748 + "CAP_NET_BIND_SERVICE",
20749 + "CAP_NET_BROADCAST",
20754 + "CAP_SYS_MODULE",
20756 + "CAP_SYS_CHROOT",
20757 + "CAP_SYS_PTRACE",
20762 + "CAP_SYS_RESOURCE",
20764 + "CAP_SYS_TTY_CONFIG",
20767 + "CAP_AUDIT_WRITE",
20768 + "CAP_AUDIT_CONTROL",
20770 + "CAP_MAC_OVERRIDE",
20774 +EXPORT_SYMBOL(gr_task_is_capable);
20775 +EXPORT_SYMBOL(gr_is_capable_nolog);
20778 +gr_task_is_capable(struct task_struct *task, const int cap)
20780 + struct acl_subject_label *curracl;
20781 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
20783 + if (!gr_acl_is_enabled())
20786 + curracl = task->acl;
20788 + cap_drop = curracl->cap_lower;
20789 + cap_mask = curracl->cap_mask;
20791 + while ((curracl = curracl->parent_subject)) {
20792 + /* if the cap isn't specified in the current computed mask but is specified in the
20793 + current level subject, and is lowered in the current level subject, then add
20794 + it to the set of dropped capabilities
20795 + otherwise, add the current level subject's mask to the current computed mask
20797 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
20798 + cap_raise(cap_mask, cap);
20799 + if (cap_raised(curracl->cap_lower, cap))
20800 + cap_raise(cap_drop, cap);
20804 + if (!cap_raised(cap_drop, cap))
20807 + curracl = task->acl;
20809 + if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
20810 + && cap_raised(task->cap_effective, cap)) {
20811 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
20812 + task->role->roletype, task->uid,
20813 + task->gid, task->exec_file ?
20814 + gr_to_filename(task->exec_file->f_path.dentry,
20815 + task->exec_file->f_path.mnt) : curracl->filename,
20816 + curracl->filename, 0UL,
20817 + 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
20821 + if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
20822 + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
20827 +gr_is_capable_nolog(const int cap)
20829 + struct acl_subject_label *curracl;
20830 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
20832 + if (!gr_acl_is_enabled())
20835 + curracl = current->acl;
20837 + cap_drop = curracl->cap_lower;
20838 + cap_mask = curracl->cap_mask;
20840 + while ((curracl = curracl->parent_subject)) {
20841 + /* if the cap isn't specified in the current computed mask but is specified in the
20842 + current level subject, and is lowered in the current level subject, then add
20843 + it to the set of dropped capabilities
20844 + otherwise, add the current level subject's mask to the current computed mask
20846 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
20847 + cap_raise(cap_mask, cap);
20848 + if (cap_raised(curracl->cap_lower, cap))
20849 + cap_raise(cap_drop, cap);
20853 + if (!cap_raised(cap_drop, cap))
20859 diff -urNp linux-2.6.27.4/grsecurity/gracl_fs.c linux-2.6.27.4/grsecurity/gracl_fs.c
20860 --- linux-2.6.27.4/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
20861 +++ linux-2.6.27.4/grsecurity/gracl_fs.c 2008-10-25 12:03:07.000000000 -0400
20863 +#include <linux/kernel.h>
20864 +#include <linux/sched.h>
20865 +#include <linux/types.h>
20866 +#include <linux/fs.h>
20867 +#include <linux/file.h>
20868 +#include <linux/stat.h>
20869 +#include <linux/grsecurity.h>
20870 +#include <linux/grinternal.h>
20871 +#include <linux/gracl.h>
20874 +gr_acl_handle_hidden_file(const struct dentry * dentry,
20875 + const struct vfsmount * mnt)
20879 + if (unlikely(!dentry->d_inode))
20883 + gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
20885 + if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
20886 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
20888 + } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
20889 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
20891 + } else if (unlikely(!(mode & GR_FIND)))
20898 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
20901 + __u32 reqmode = GR_FIND;
20904 + if (unlikely(!dentry->d_inode))
20907 + if (unlikely(fmode & O_APPEND))
20908 + reqmode |= GR_APPEND;
20909 + else if (unlikely(fmode & FMODE_WRITE))
20910 + reqmode |= GR_WRITE;
20911 + if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
20912 + reqmode |= GR_READ;
20915 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
20918 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
20919 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
20920 + reqmode & GR_READ ? " reading" : "",
20921 + reqmode & GR_WRITE ? " writing" : reqmode &
20922 + GR_APPEND ? " appending" : "");
20925 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
20927 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
20928 + reqmode & GR_READ ? " reading" : "",
20929 + reqmode & GR_WRITE ? " writing" : reqmode &
20930 + GR_APPEND ? " appending" : "");
20932 + } else if (unlikely((mode & reqmode) != reqmode))
20939 +gr_acl_handle_creat(const struct dentry * dentry,
20940 + const struct dentry * p_dentry,
20941 + const struct vfsmount * p_mnt, const int fmode,
20944 + __u32 reqmode = GR_WRITE | GR_CREATE;
20947 + if (unlikely(fmode & O_APPEND))
20948 + reqmode |= GR_APPEND;
20949 + if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
20950 + reqmode |= GR_READ;
20951 + if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
20952 + reqmode |= GR_SETID;
20955 + gr_check_create(dentry, p_dentry, p_mnt,
20956 + reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
20958 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
20959 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
20960 + reqmode & GR_READ ? " reading" : "",
20961 + reqmode & GR_WRITE ? " writing" : reqmode &
20962 + GR_APPEND ? " appending" : "");
20965 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
20967 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
20968 + reqmode & GR_READ ? " reading" : "",
20969 + reqmode & GR_WRITE ? " writing" : reqmode &
20970 + GR_APPEND ? " appending" : "");
20972 + } else if (unlikely((mode & reqmode) != reqmode))
20979 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
20982 + __u32 mode, reqmode = GR_FIND;
20984 + if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
20985 + reqmode |= GR_EXEC;
20986 + if (fmode & S_IWOTH)
20987 + reqmode |= GR_WRITE;
20988 + if (fmode & S_IROTH)
20989 + reqmode |= GR_READ;
20992 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
20995 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
20996 + gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
20997 + reqmode & GR_READ ? " reading" : "",
20998 + reqmode & GR_WRITE ? " writing" : "",
20999 + reqmode & GR_EXEC ? " executing" : "");
21002 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21004 + gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
21005 + reqmode & GR_READ ? " reading" : "",
21006 + reqmode & GR_WRITE ? " writing" : "",
21007 + reqmode & GR_EXEC ? " executing" : "");
21009 + } else if (unlikely((mode & reqmode) != reqmode))
21015 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
21019 + mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
21021 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21022 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
21024 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21025 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
21027 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
21030 + return (reqmode);
21034 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
21036 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
21040 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
21042 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
21046 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
21048 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
21052 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
21054 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
21058 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
21061 + if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
21064 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21065 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21066 + GR_FCHMOD_ACL_MSG);
21068 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
21073 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
21076 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21077 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21078 + GR_CHMOD_ACL_MSG);
21080 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
21085 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
21087 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
21091 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
21093 + return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
21097 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
21099 + return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
21100 + GR_UNIXCONNECT_ACL_MSG);
21103 +/* hardlinks require at minimum create permission,
21104 + any additional privilege required is based on the
21105 + privilege of the file being linked to
21108 +gr_acl_handle_link(const struct dentry * new_dentry,
21109 + const struct dentry * parent_dentry,
21110 + const struct vfsmount * parent_mnt,
21111 + const struct dentry * old_dentry,
21112 + const struct vfsmount * old_mnt, const char *to)
21115 + __u32 needmode = GR_CREATE | GR_LINK;
21116 + __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
21119 + gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
21122 + if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
21123 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21125 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21126 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21128 + } else if (unlikely((mode & needmode) != needmode))
21135 +gr_acl_handle_symlink(const struct dentry * new_dentry,
21136 + const struct dentry * parent_dentry,
21137 + const struct vfsmount * parent_mnt, const char *from)
21139 + __u32 needmode = GR_WRITE | GR_CREATE;
21143 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
21144 + GR_CREATE | GR_AUDIT_CREATE |
21145 + GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
21147 + if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
21148 + gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21150 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21151 + gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21153 + } else if (unlikely((mode & needmode) != needmode))
21156 + return (GR_WRITE | GR_CREATE);
21159 +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)
21163 + mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
21165 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21166 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
21168 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21169 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
21171 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
21174 + return (reqmode);
21178 +gr_acl_handle_mknod(const struct dentry * new_dentry,
21179 + const struct dentry * parent_dentry,
21180 + const struct vfsmount * parent_mnt,
21183 + __u32 reqmode = GR_WRITE | GR_CREATE;
21184 + if (unlikely(mode & (S_ISUID | S_ISGID)))
21185 + reqmode |= GR_SETID;
21187 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21188 + reqmode, GR_MKNOD_ACL_MSG);
21192 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
21193 + const struct dentry *parent_dentry,
21194 + const struct vfsmount *parent_mnt)
21196 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21197 + GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
21200 +#define RENAME_CHECK_SUCCESS(old, new) \
21201 + (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
21202 + ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
21205 +gr_acl_handle_rename(struct dentry *new_dentry,
21206 + struct dentry *parent_dentry,
21207 + const struct vfsmount *parent_mnt,
21208 + struct dentry *old_dentry,
21209 + struct inode *old_parent_inode,
21210 + struct vfsmount *old_mnt, const char *newname)
21212 + __u32 comp1, comp2;
21215 + if (unlikely(!gr_acl_is_enabled()))
21218 + if (!new_dentry->d_inode) {
21219 + comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
21220 + GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
21221 + GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
21222 + comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
21223 + GR_DELETE | GR_AUDIT_DELETE |
21224 + GR_AUDIT_READ | GR_AUDIT_WRITE |
21225 + GR_SUPPRESS, old_mnt);
21227 + comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
21228 + GR_CREATE | GR_DELETE |
21229 + GR_AUDIT_CREATE | GR_AUDIT_DELETE |
21230 + GR_AUDIT_READ | GR_AUDIT_WRITE |
21231 + GR_SUPPRESS, parent_mnt);
21233 + gr_search_file(old_dentry,
21234 + GR_READ | GR_WRITE | GR_AUDIT_READ |
21235 + GR_DELETE | GR_AUDIT_DELETE |
21236 + GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
21239 + if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
21240 + ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
21241 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21242 + else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
21243 + && !(comp2 & GR_SUPPRESS)) {
21244 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21246 + } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
21253 +gr_acl_handle_exit(void)
21257 + struct file *exec_file;
21259 + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
21260 + id = current->acl_role_id;
21261 + rolename = current->role->rolename;
21263 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
21266 + write_lock(&grsec_exec_file_lock);
21267 + exec_file = current->exec_file;
21268 + current->exec_file = NULL;
21269 + write_unlock(&grsec_exec_file_lock);
21276 +gr_acl_handle_procpidmem(const struct task_struct *task)
21278 + if (unlikely(!gr_acl_is_enabled()))
21281 + if (task != current && task->acl->mode & GR_PROTPROCFD)
21286 diff -urNp linux-2.6.27.4/grsecurity/gracl_ip.c linux-2.6.27.4/grsecurity/gracl_ip.c
21287 --- linux-2.6.27.4/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
21288 +++ linux-2.6.27.4/grsecurity/gracl_ip.c 2008-10-25 12:03:07.000000000 -0400
21290 +#include <linux/kernel.h>
21291 +#include <asm/uaccess.h>
21292 +#include <asm/errno.h>
21293 +#include <net/sock.h>
21294 +#include <linux/file.h>
21295 +#include <linux/fs.h>
21296 +#include <linux/net.h>
21297 +#include <linux/in.h>
21298 +#include <linux/skbuff.h>
21299 +#include <linux/ip.h>
21300 +#include <linux/udp.h>
21301 +#include <linux/smp_lock.h>
21302 +#include <linux/types.h>
21303 +#include <linux/sched.h>
21304 +#include <linux/netdevice.h>
21305 +#include <linux/inetdevice.h>
21306 +#include <linux/gracl.h>
21307 +#include <linux/grsecurity.h>
21308 +#include <linux/grinternal.h>
21310 +#define GR_BIND 0x01
21311 +#define GR_CONNECT 0x02
21312 +#define GR_INVERT 0x04
21314 +static const char * gr_protocols[256] = {
21315 + "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
21316 + "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
21317 + "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
21318 + "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
21319 + "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
21320 + "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
21321 + "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
21322 + "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
21323 + "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
21324 + "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
21325 + "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
21326 + "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
21327 + "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
21328 + "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
21329 + "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
21330 + "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
21331 + "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
21332 + "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
21333 + "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
21334 + "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
21335 + "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
21336 + "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
21337 + "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
21338 + "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
21339 + "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
21340 + "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
21341 + "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
21342 + "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
21343 + "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
21344 + "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
21345 + "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
21346 + "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
21349 +static const char * gr_socktypes[11] = {
21350 + "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
21351 + "unknown:7", "unknown:8", "unknown:9", "packet"
21355 +gr_proto_to_name(unsigned char proto)
21357 + return gr_protocols[proto];
21361 +gr_socktype_to_name(unsigned char type)
21363 + return gr_socktypes[type];
21367 +gr_search_socket(const int domain, const int type, const int protocol)
21369 + struct acl_subject_label *curr;
21371 + if (unlikely(!gr_acl_is_enabled()))
21374 + if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
21375 + || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
21376 + goto exit; // let the kernel handle it
21378 + curr = current->acl;
21383 + if ((curr->ip_type & (1 << type)) &&
21384 + (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
21387 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
21388 + /* we don't place acls on raw sockets , and sometimes
21389 + dgram/ip sockets are opened for ioctl and not
21390 + bind/connect, so we'll fake a bind learn log */
21391 + if (type == SOCK_RAW || type == SOCK_PACKET) {
21392 + __u32 fakeip = 0;
21393 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
21394 + current->role->roletype, current->uid,
21395 + current->gid, current->exec_file ?
21396 + gr_to_filename(current->exec_file->f_path.dentry,
21397 + current->exec_file->f_path.mnt) :
21398 + curr->filename, curr->filename,
21399 + NIPQUAD(fakeip), 0, type,
21400 + protocol, GR_CONNECT,
21401 +NIPQUAD(current->signal->curr_ip));
21402 + } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
21403 + __u32 fakeip = 0;
21404 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
21405 + current->role->roletype, current->uid,
21406 + current->gid, current->exec_file ?
21407 + gr_to_filename(current->exec_file->f_path.dentry,
21408 + current->exec_file->f_path.mnt) :
21409 + curr->filename, curr->filename,
21410 + NIPQUAD(fakeip), 0, type,
21411 + protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
21413 + /* we'll log when they use connect or bind */
21417 + gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
21418 + gr_socktype_to_name(type), gr_proto_to_name(protocol));
21425 +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)
21427 + if ((ip->mode & mode) &&
21428 + (ip_port >= ip->low) &&
21429 + (ip_port <= ip->high) &&
21430 + ((ntohl(ip_addr) & our_netmask) ==
21431 + (ntohl(our_addr) & our_netmask))
21432 + && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
21433 + && (ip->type & (1 << type))) {
21434 + if (ip->mode & GR_INVERT)
21435 + return 2; // specifically denied
21437 + return 1; // allowed
21440 + return 0; // not specifically allowed, may continue parsing
21444 +gr_search_connectbind(const int mode, const struct sock *sk,
21445 + const struct sockaddr_in *addr, const int type)
21447 + char iface[IFNAMSIZ] = {0};
21448 + struct acl_subject_label *curr;
21449 + struct acl_ip_label *ip;
21450 + struct net_device *dev;
21451 + struct in_device *idev;
21454 + __u32 ip_addr = 0;
21456 + __u32 our_netmask;
21458 + __u16 ip_port = 0;
21460 + if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
21463 + curr = current->acl;
21468 + ip_addr = addr->sin_addr.s_addr;
21469 + ip_port = ntohs(addr->sin_port);
21471 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
21472 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
21473 + current->role->roletype, current->uid,
21474 + current->gid, current->exec_file ?
21475 + gr_to_filename(current->exec_file->f_path.dentry,
21476 + current->exec_file->f_path.mnt) :
21477 + curr->filename, curr->filename,
21478 + NIPQUAD(ip_addr), ip_port, type,
21479 + sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
21483 + for (i = 0; i < curr->ip_num; i++) {
21484 + ip = *(curr->ips + i);
21485 + if (ip->iface != NULL) {
21486 + strncpy(iface, ip->iface, IFNAMSIZ - 1);
21487 + p = strchr(iface, ':');
21490 + dev = dev_get_by_name(sock_net(sk), iface);
21493 + idev = in_dev_get(dev);
21494 + if (idev == NULL) {
21500 + if (!strcmp(ip->iface, ifa->ifa_label)) {
21501 + our_addr = ifa->ifa_address;
21502 + our_netmask = 0xffffffff;
21503 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
21505 + rcu_read_unlock();
21506 + in_dev_put(idev);
21509 + } else if (ret == 2) {
21510 + rcu_read_unlock();
21511 + in_dev_put(idev);
21516 + } endfor_ifa(idev);
21517 + rcu_read_unlock();
21518 + in_dev_put(idev);
21521 + our_addr = ip->addr;
21522 + our_netmask = ip->netmask;
21523 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
21526 + else if (ret == 2)
21532 + if (mode == GR_BIND)
21533 + 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));
21534 + else if (mode == GR_CONNECT)
21535 + 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));
21541 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
21543 + return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
21547 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
21549 + return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
21552 +int gr_search_listen(const struct socket *sock)
21554 + struct sock *sk = sock->sk;
21555 + struct sockaddr_in addr;
21557 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
21558 + addr.sin_port = inet_sk(sk)->sport;
21560 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
21563 +int gr_search_accept(const struct socket *sock)
21565 + struct sock *sk = sock->sk;
21566 + struct sockaddr_in addr;
21568 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
21569 + addr.sin_port = inet_sk(sk)->sport;
21571 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
21575 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
21578 + return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
21580 + struct sockaddr_in sin;
21581 + const struct inet_sock *inet = inet_sk(sk);
21583 + sin.sin_addr.s_addr = inet->daddr;
21584 + sin.sin_port = inet->dport;
21586 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
21591 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
21593 + struct sockaddr_in sin;
21595 + if (unlikely(skb->len < sizeof (struct udphdr)))
21596 + return 1; // skip this packet
21598 + sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
21599 + sin.sin_port = udp_hdr(skb)->source;
21601 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
21603 diff -urNp linux-2.6.27.4/grsecurity/gracl_learn.c linux-2.6.27.4/grsecurity/gracl_learn.c
21604 --- linux-2.6.27.4/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
21605 +++ linux-2.6.27.4/grsecurity/gracl_learn.c 2008-10-25 12:03:07.000000000 -0400
21607 +#include <linux/kernel.h>
21608 +#include <linux/mm.h>
21609 +#include <linux/sched.h>
21610 +#include <linux/poll.h>
21611 +#include <linux/smp_lock.h>
21612 +#include <linux/string.h>
21613 +#include <linux/file.h>
21614 +#include <linux/types.h>
21615 +#include <linux/vmalloc.h>
21616 +#include <linux/grinternal.h>
21618 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
21619 + size_t count, loff_t *ppos);
21620 +extern int gr_acl_is_enabled(void);
21622 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
21623 +static int gr_learn_attached;
21625 +/* use a 512k buffer */
21626 +#define LEARN_BUFFER_SIZE (512 * 1024)
21628 +static DEFINE_SPINLOCK(gr_learn_lock);
21629 +static DECLARE_MUTEX(gr_learn_user_sem);
21631 +/* we need to maintain two buffers, so that the kernel context of grlearn
21632 + uses a semaphore around the userspace copying, and the other kernel contexts
21633 + use a spinlock when copying into the buffer, since they cannot sleep
21635 +static char *learn_buffer;
21636 +static char *learn_buffer_user;
21637 +static int learn_buffer_len;
21638 +static int learn_buffer_user_len;
21641 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
21643 + DECLARE_WAITQUEUE(wait, current);
21644 + ssize_t retval = 0;
21646 + add_wait_queue(&learn_wait, &wait);
21647 + set_current_state(TASK_INTERRUPTIBLE);
21649 + down(&gr_learn_user_sem);
21650 + spin_lock(&gr_learn_lock);
21651 + if (learn_buffer_len)
21653 + spin_unlock(&gr_learn_lock);
21654 + up(&gr_learn_user_sem);
21655 + if (file->f_flags & O_NONBLOCK) {
21656 + retval = -EAGAIN;
21659 + if (signal_pending(current)) {
21660 + retval = -ERESTARTSYS;
21667 + memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
21668 + learn_buffer_user_len = learn_buffer_len;
21669 + retval = learn_buffer_len;
21670 + learn_buffer_len = 0;
21672 + spin_unlock(&gr_learn_lock);
21674 + if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
21675 + retval = -EFAULT;
21677 + up(&gr_learn_user_sem);
21679 + set_current_state(TASK_RUNNING);
21680 + remove_wait_queue(&learn_wait, &wait);
21684 +static unsigned int
21685 +poll_learn(struct file * file, poll_table * wait)
21687 + poll_wait(file, &learn_wait, wait);
21689 + if (learn_buffer_len)
21690 + return (POLLIN | POLLRDNORM);
21696 +gr_clear_learn_entries(void)
21700 + down(&gr_learn_user_sem);
21701 + if (learn_buffer != NULL) {
21702 + spin_lock(&gr_learn_lock);
21703 + tmp = learn_buffer;
21704 + learn_buffer = NULL;
21705 + spin_unlock(&gr_learn_lock);
21706 + vfree(learn_buffer);
21708 + if (learn_buffer_user != NULL) {
21709 + vfree(learn_buffer_user);
21710 + learn_buffer_user = NULL;
21712 + learn_buffer_len = 0;
21713 + up(&gr_learn_user_sem);
21719 +gr_add_learn_entry(const char *fmt, ...)
21722 + unsigned int len;
21724 + if (!gr_learn_attached)
21727 + spin_lock(&gr_learn_lock);
21729 + /* leave a gap at the end so we know when it's "full" but don't have to
21730 + compute the exact length of the string we're trying to append
21732 + if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
21733 + spin_unlock(&gr_learn_lock);
21734 + wake_up_interruptible(&learn_wait);
21737 + if (learn_buffer == NULL) {
21738 + spin_unlock(&gr_learn_lock);
21742 + va_start(args, fmt);
21743 + len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
21746 + learn_buffer_len += len + 1;
21748 + spin_unlock(&gr_learn_lock);
21749 + wake_up_interruptible(&learn_wait);
21755 +open_learn(struct inode *inode, struct file *file)
21757 + if (file->f_mode & FMODE_READ && gr_learn_attached)
21759 + if (file->f_mode & FMODE_READ) {
21761 + down(&gr_learn_user_sem);
21762 + if (learn_buffer == NULL)
21763 + learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
21764 + if (learn_buffer_user == NULL)
21765 + learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
21766 + if (learn_buffer == NULL) {
21767 + retval = -ENOMEM;
21770 + if (learn_buffer_user == NULL) {
21771 + retval = -ENOMEM;
21774 + learn_buffer_len = 0;
21775 + learn_buffer_user_len = 0;
21776 + gr_learn_attached = 1;
21778 + up(&gr_learn_user_sem);
21785 +close_learn(struct inode *inode, struct file *file)
21789 + if (file->f_mode & FMODE_READ) {
21790 + down(&gr_learn_user_sem);
21791 + if (learn_buffer != NULL) {
21792 + spin_lock(&gr_learn_lock);
21793 + tmp = learn_buffer;
21794 + learn_buffer = NULL;
21795 + spin_unlock(&gr_learn_lock);
21798 + if (learn_buffer_user != NULL) {
21799 + vfree(learn_buffer_user);
21800 + learn_buffer_user = NULL;
21802 + learn_buffer_len = 0;
21803 + learn_buffer_user_len = 0;
21804 + gr_learn_attached = 0;
21805 + up(&gr_learn_user_sem);
21811 +struct file_operations grsec_fops = {
21812 + .read = read_learn,
21813 + .write = write_grsec_handler,
21814 + .open = open_learn,
21815 + .release = close_learn,
21816 + .poll = poll_learn,
21818 diff -urNp linux-2.6.27.4/grsecurity/gracl_res.c linux-2.6.27.4/grsecurity/gracl_res.c
21819 --- linux-2.6.27.4/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
21820 +++ linux-2.6.27.4/grsecurity/gracl_res.c 2008-10-25 12:03:07.000000000 -0400
21822 +#include <linux/kernel.h>
21823 +#include <linux/sched.h>
21824 +#include <linux/gracl.h>
21825 +#include <linux/grinternal.h>
21827 +static const char *restab_log[] = {
21828 + [RLIMIT_CPU] = "RLIMIT_CPU",
21829 + [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
21830 + [RLIMIT_DATA] = "RLIMIT_DATA",
21831 + [RLIMIT_STACK] = "RLIMIT_STACK",
21832 + [RLIMIT_CORE] = "RLIMIT_CORE",
21833 + [RLIMIT_RSS] = "RLIMIT_RSS",
21834 + [RLIMIT_NPROC] = "RLIMIT_NPROC",
21835 + [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
21836 + [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
21837 + [RLIMIT_AS] = "RLIMIT_AS",
21838 + [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
21839 + [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
21843 +gr_log_resource(const struct task_struct *task,
21844 + const int res, const unsigned long wanted, const int gt)
21846 + if (res == RLIMIT_NPROC &&
21847 + (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
21848 + cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
21850 + else if (res == RLIMIT_MEMLOCK &&
21851 + cap_raised(task->cap_effective, CAP_IPC_LOCK))
21854 + if (!gr_acl_is_enabled() && !grsec_resource_logging)
21857 + preempt_disable();
21859 + if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
21860 + (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
21861 + task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
21862 + gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
21863 + preempt_enable_no_resched();
21867 diff -urNp linux-2.6.27.4/grsecurity/gracl_segv.c linux-2.6.27.4/grsecurity/gracl_segv.c
21868 --- linux-2.6.27.4/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
21869 +++ linux-2.6.27.4/grsecurity/gracl_segv.c 2008-10-25 12:03:07.000000000 -0400
21871 +#include <linux/kernel.h>
21872 +#include <linux/mm.h>
21873 +#include <asm/uaccess.h>
21874 +#include <asm/errno.h>
21875 +#include <asm/mman.h>
21876 +#include <net/sock.h>
21877 +#include <linux/file.h>
21878 +#include <linux/fs.h>
21879 +#include <linux/net.h>
21880 +#include <linux/in.h>
21881 +#include <linux/smp_lock.h>
21882 +#include <linux/slab.h>
21883 +#include <linux/types.h>
21884 +#include <linux/sched.h>
21885 +#include <linux/timer.h>
21886 +#include <linux/gracl.h>
21887 +#include <linux/grsecurity.h>
21888 +#include <linux/grinternal.h>
21890 +static struct crash_uid *uid_set;
21891 +static unsigned short uid_used;
21892 +static DEFINE_SPINLOCK(gr_uid_lock);
21893 +extern rwlock_t gr_inode_lock;
21894 +extern struct acl_subject_label *
21895 + lookup_acl_subj_label(const ino_t inode, const dev_t dev,
21896 + struct acl_role_label *role);
21897 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
21900 +gr_init_uidset(void)
21903 + kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
21906 + return uid_set ? 1 : 0;
21910 +gr_free_uidset(void)
21919 +gr_find_uid(const uid_t uid)
21921 + struct crash_uid *tmp = uid_set;
21923 + int low = 0, high = uid_used - 1, mid;
21925 + while (high >= low) {
21926 + mid = (low + high) >> 1;
21927 + buid = tmp[mid].uid;
21939 +static __inline__ void
21940 +gr_insertsort(void)
21942 + unsigned short i, j;
21943 + struct crash_uid index;
21945 + for (i = 1; i < uid_used; i++) {
21946 + index = uid_set[i];
21948 + while ((j > 0) && uid_set[j - 1].uid > index.uid) {
21949 + uid_set[j] = uid_set[j - 1];
21952 + uid_set[j] = index;
21958 +static __inline__ void
21959 +gr_insert_uid(const uid_t uid, const unsigned long expires)
21963 + if (uid_used == GR_UIDTABLE_MAX)
21966 + loc = gr_find_uid(uid);
21969 + uid_set[loc].expires = expires;
21973 + uid_set[uid_used].uid = uid;
21974 + uid_set[uid_used].expires = expires;
21983 +gr_remove_uid(const unsigned short loc)
21985 + unsigned short i;
21987 + for (i = loc + 1; i < uid_used; i++)
21988 + uid_set[i - 1] = uid_set[i];
21996 +gr_check_crash_uid(const uid_t uid)
22001 + if (unlikely(!gr_acl_is_enabled()))
22004 + spin_lock(&gr_uid_lock);
22005 + loc = gr_find_uid(uid);
22010 + if (time_before_eq(uid_set[loc].expires, get_seconds()))
22011 + gr_remove_uid(loc);
22016 + spin_unlock(&gr_uid_lock);
22020 +static __inline__ int
22021 +proc_is_setxid(const struct task_struct *task)
22023 + if (task->uid != task->euid || task->uid != task->suid ||
22024 + task->uid != task->fsuid)
22026 + if (task->gid != task->egid || task->gid != task->sgid ||
22027 + task->gid != task->fsgid)
22032 +static __inline__ int
22033 +gr_fake_force_sig(int sig, struct task_struct *t)
22035 + unsigned long int flags;
22036 + int ret, blocked, ignored;
22037 + struct k_sigaction *action;
22039 + spin_lock_irqsave(&t->sighand->siglock, flags);
22040 + action = &t->sighand->action[sig-1];
22041 + ignored = action->sa.sa_handler == SIG_IGN;
22042 + blocked = sigismember(&t->blocked, sig);
22043 + if (blocked || ignored) {
22044 + action->sa.sa_handler = SIG_DFL;
22046 + sigdelset(&t->blocked, sig);
22047 + recalc_sigpending_and_wake(t);
22050 + if (action->sa.sa_handler == SIG_DFL)
22051 + t->signal->flags &= ~SIGNAL_UNKILLABLE;
22052 + ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
22054 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
22060 +gr_handle_crash(struct task_struct *task, const int sig)
22062 + struct acl_subject_label *curr;
22063 + struct acl_subject_label *curr2;
22064 + struct task_struct *tsk, *tsk2;
22066 + if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
22069 + if (unlikely(!gr_acl_is_enabled()))
22072 + curr = task->acl;
22074 + if (!(curr->resmask & (1 << GR_CRASH_RES)))
22077 + if (time_before_eq(curr->expires, get_seconds())) {
22078 + curr->expires = 0;
22079 + curr->crashes = 0;
22084 + if (!curr->expires)
22085 + curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
22087 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22088 + time_after(curr->expires, get_seconds())) {
22089 + if (task->uid && proc_is_setxid(task)) {
22090 + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22091 + spin_lock(&gr_uid_lock);
22092 + gr_insert_uid(task->uid, curr->expires);
22093 + spin_unlock(&gr_uid_lock);
22094 + curr->expires = 0;
22095 + curr->crashes = 0;
22096 + read_lock(&tasklist_lock);
22097 + do_each_thread(tsk2, tsk) {
22098 + if (tsk != task && tsk->uid == task->uid)
22099 + gr_fake_force_sig(SIGKILL, tsk);
22100 + } while_each_thread(tsk2, tsk);
22101 + read_unlock(&tasklist_lock);
22103 + gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22104 + read_lock(&tasklist_lock);
22105 + do_each_thread(tsk2, tsk) {
22106 + if (likely(tsk != task)) {
22107 + curr2 = tsk->acl;
22109 + if (curr2->device == curr->device &&
22110 + curr2->inode == curr->inode)
22111 + gr_fake_force_sig(SIGKILL, tsk);
22113 + } while_each_thread(tsk2, tsk);
22114 + read_unlock(&tasklist_lock);
22122 +gr_check_crash_exec(const struct file *filp)
22124 + struct acl_subject_label *curr;
22126 + if (unlikely(!gr_acl_is_enabled()))
22129 + read_lock(&gr_inode_lock);
22130 + curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
22131 + filp->f_path.dentry->d_inode->i_sb->s_dev,
22133 + read_unlock(&gr_inode_lock);
22135 + if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
22136 + (!curr->crashes && !curr->expires))
22139 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22140 + time_after(curr->expires, get_seconds()))
22142 + else if (time_before_eq(curr->expires, get_seconds())) {
22143 + curr->crashes = 0;
22144 + curr->expires = 0;
22151 +gr_handle_alertkill(struct task_struct *task)
22153 + struct acl_subject_label *curracl;
22155 + struct task_struct *p, *p2;
22157 + if (unlikely(!gr_acl_is_enabled()))
22160 + curracl = task->acl;
22161 + curr_ip = task->signal->curr_ip;
22163 + if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
22164 + read_lock(&tasklist_lock);
22165 + do_each_thread(p2, p) {
22166 + if (p->signal->curr_ip == curr_ip)
22167 + gr_fake_force_sig(SIGKILL, p);
22168 + } while_each_thread(p2, p);
22169 + read_unlock(&tasklist_lock);
22170 + } else if (curracl->mode & GR_KILLPROC)
22171 + gr_fake_force_sig(SIGKILL, task);
22175 diff -urNp linux-2.6.27.4/grsecurity/gracl_shm.c linux-2.6.27.4/grsecurity/gracl_shm.c
22176 --- linux-2.6.27.4/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
22177 +++ linux-2.6.27.4/grsecurity/gracl_shm.c 2008-10-26 04:01:55.000000000 -0400
22179 +#include <linux/kernel.h>
22180 +#include <linux/mm.h>
22181 +#include <linux/sched.h>
22182 +#include <linux/file.h>
22183 +#include <linux/ipc.h>
22184 +#include <linux/gracl.h>
22185 +#include <linux/grsecurity.h>
22186 +#include <linux/grinternal.h>
22189 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22190 + const time_t shm_createtime, const uid_t cuid, const int shmid)
22192 + struct task_struct *task;
22194 + if (!gr_acl_is_enabled())
22197 + task = find_task_by_vpid(shm_cprid);
22199 + if (unlikely(!task))
22200 + task = find_task_by_vpid(shm_lapid);
22202 + if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
22203 + (task->pid == shm_lapid)) &&
22204 + (task->acl->mode & GR_PROTSHM) &&
22205 + (task->acl != current->acl))) {
22206 + gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
22212 diff -urNp linux-2.6.27.4/grsecurity/grsec_chdir.c linux-2.6.27.4/grsecurity/grsec_chdir.c
22213 --- linux-2.6.27.4/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
22214 +++ linux-2.6.27.4/grsecurity/grsec_chdir.c 2008-10-25 12:03:07.000000000 -0400
22216 +#include <linux/kernel.h>
22217 +#include <linux/sched.h>
22218 +#include <linux/fs.h>
22219 +#include <linux/file.h>
22220 +#include <linux/grsecurity.h>
22221 +#include <linux/grinternal.h>
22224 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
22226 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
22227 + if ((grsec_enable_chdir && grsec_enable_group &&
22228 + in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
22229 + !grsec_enable_group)) {
22230 + gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
22235 diff -urNp linux-2.6.27.4/grsecurity/grsec_chroot.c linux-2.6.27.4/grsecurity/grsec_chroot.c
22236 --- linux-2.6.27.4/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
22237 +++ linux-2.6.27.4/grsecurity/grsec_chroot.c 2008-10-26 03:54:30.000000000 -0400
22239 +#include <linux/kernel.h>
22240 +#include <linux/module.h>
22241 +#include <linux/sched.h>
22242 +#include <linux/file.h>
22243 +#include <linux/fs.h>
22244 +#include <linux/mount.h>
22245 +#include <linux/types.h>
22246 +#include <linux/pid_namespace.h>
22247 +#include <linux/grsecurity.h>
22248 +#include <linux/grinternal.h>
22251 +gr_handle_chroot_unix(const pid_t pid)
22253 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
22254 + struct pid *spid = NULL;
22256 + if (unlikely(!grsec_enable_chroot_unix))
22259 + if (likely(!proc_is_chrooted(current)))
22262 + read_lock(&tasklist_lock);
22264 + spid = find_vpid(pid);
22266 + struct task_struct *p;
22267 + p = pid_task(spid, PIDTYPE_PID);
22269 + if (unlikely(!have_same_root(current, p))) {
22271 + read_unlock(&tasklist_lock);
22272 + gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
22277 + read_unlock(&tasklist_lock);
22283 +gr_handle_chroot_nice(void)
22285 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22286 + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
22287 + gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
22295 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
22297 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22298 + if (grsec_enable_chroot_nice && (niceval < task_nice(p))
22299 + && proc_is_chrooted(current)) {
22300 + gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
22308 +gr_handle_chroot_rawio(const struct inode *inode)
22310 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
22311 + if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
22312 + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
22319 +gr_pid_is_chrooted(struct task_struct *p)
22321 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
22322 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
22326 + if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
22327 + !have_same_root(current, p)) {
22336 +EXPORT_SYMBOL(gr_pid_is_chrooted);
22338 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
22339 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
22341 + struct dentry *dentry = (struct dentry *)u_dentry;
22342 + struct vfsmount *mnt = (struct vfsmount *)u_mnt;
22343 + struct dentry *realroot;
22344 + struct vfsmount *realrootmnt;
22345 + struct dentry *currentroot;
22346 + struct vfsmount *currentmnt;
22347 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
22350 + read_lock(&reaper->fs->lock);
22351 + realrootmnt = mntget(reaper->fs->root.mnt);
22352 + realroot = dget(reaper->fs->root.dentry);
22353 + read_unlock(&reaper->fs->lock);
22355 + read_lock(¤t->fs->lock);
22356 + currentmnt = mntget(current->fs->root.mnt);
22357 + currentroot = dget(current->fs->root.dentry);
22358 + read_unlock(¤t->fs->lock);
22360 + spin_lock(&dcache_lock);
22362 + if (unlikely((dentry == realroot && mnt == realrootmnt)
22363 + || (dentry == currentroot && mnt == currentmnt)))
22365 + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
22366 + if (mnt->mnt_parent == mnt)
22368 + dentry = mnt->mnt_mountpoint;
22369 + mnt = mnt->mnt_parent;
22372 + dentry = dentry->d_parent;
22374 + spin_unlock(&dcache_lock);
22376 + dput(currentroot);
22377 + mntput(currentmnt);
22379 + /* access is outside of chroot */
22380 + if (dentry == realroot && mnt == realrootmnt)
22384 + mntput(realrootmnt);
22390 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
22392 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
22393 + if (!grsec_enable_chroot_fchdir)
22396 + if (!proc_is_chrooted(current))
22398 + else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
22399 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
22407 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22408 + const time_t shm_createtime)
22410 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
22411 + struct pid *pid = NULL;
22412 + time_t starttime;
22414 + if (unlikely(!grsec_enable_chroot_shmat))
22417 + if (likely(!proc_is_chrooted(current)))
22420 + read_lock(&tasklist_lock);
22422 + pid = find_vpid(shm_cprid);
22424 + struct task_struct *p;
22425 + p = pid_task(pid, PIDTYPE_PID);
22427 + starttime = p->start_time.tv_sec;
22428 + if (unlikely(!have_same_root(current, p) &&
22429 + time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
22431 + read_unlock(&tasklist_lock);
22432 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
22437 + pid = find_vpid(shm_lapid);
22439 + struct task_struct *p;
22440 + p = pid_task(pid, PIDTYPE_PID);
22442 + if (unlikely(!have_same_root(current, p))) {
22444 + read_unlock(&tasklist_lock);
22445 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
22452 + read_unlock(&tasklist_lock);
22458 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
22460 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
22461 + if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
22462 + gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
22468 +gr_handle_chroot_mknod(const struct dentry *dentry,
22469 + const struct vfsmount *mnt, const int mode)
22471 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
22472 + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
22473 + proc_is_chrooted(current)) {
22474 + gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
22482 +gr_handle_chroot_mount(const struct dentry *dentry,
22483 + const struct vfsmount *mnt, const char *dev_name)
22485 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
22486 + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
22487 + gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
22495 +gr_handle_chroot_pivot(void)
22497 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
22498 + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
22499 + gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
22507 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
22509 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
22510 + if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
22511 + !gr_is_outside_chroot(dentry, mnt)) {
22512 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
22520 +gr_handle_chroot_caps(struct task_struct *task)
22522 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
22523 + if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
22524 + kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
22525 + task->cap_permitted =
22526 + cap_drop(task->cap_permitted, chroot_caps);
22527 + task->cap_inheritable =
22528 + cap_drop(task->cap_inheritable, chroot_caps);
22529 + task->cap_effective =
22530 + cap_drop(task->cap_effective, chroot_caps);
22537 +gr_handle_chroot_sysctl(const int op)
22539 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
22540 + if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
22541 + && (op & MAY_WRITE))
22548 +gr_handle_chroot_chdir(struct path *path)
22550 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
22551 + if (grsec_enable_chroot_chdir)
22552 + set_fs_pwd(current->fs, path);
22558 +gr_handle_chroot_chmod(const struct dentry *dentry,
22559 + const struct vfsmount *mnt, const int mode)
22561 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
22562 + if (grsec_enable_chroot_chmod &&
22563 + ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
22564 + proc_is_chrooted(current)) {
22565 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
22572 +#ifdef CONFIG_SECURITY
22573 +EXPORT_SYMBOL(gr_handle_chroot_caps);
22575 diff -urNp linux-2.6.27.4/grsecurity/grsec_disabled.c linux-2.6.27.4/grsecurity/grsec_disabled.c
22576 --- linux-2.6.27.4/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
22577 +++ linux-2.6.27.4/grsecurity/grsec_disabled.c 2008-10-25 12:03:07.000000000 -0400
22579 +#include <linux/kernel.h>
22580 +#include <linux/module.h>
22581 +#include <linux/sched.h>
22582 +#include <linux/file.h>
22583 +#include <linux/fs.h>
22584 +#include <linux/kdev_t.h>
22585 +#include <linux/net.h>
22586 +#include <linux/in.h>
22587 +#include <linux/ip.h>
22588 +#include <linux/skbuff.h>
22589 +#include <linux/sysctl.h>
22591 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
22593 +pax_set_initial_flags(struct linux_binprm *bprm)
22599 +#ifdef CONFIG_SYSCTL
22601 +gr_handle_sysctl(const struct ctl_table * table, const int op)
22608 +gr_acl_is_enabled(void)
22614 +gr_handle_rawio(const struct inode *inode)
22620 +gr_acl_handle_psacct(struct task_struct *task, const long code)
22626 +gr_handle_ptrace(struct task_struct *task, const long request)
22632 +gr_handle_proc_ptrace(struct task_struct *task)
22638 +gr_learn_resource(const struct task_struct *task,
22639 + const int res, const unsigned long wanted, const int gt)
22645 +gr_set_acls(const int type)
22651 +gr_check_hidden_task(const struct task_struct *tsk)
22657 +gr_check_protected_task(const struct task_struct *task)
22663 +gr_copy_label(struct task_struct *tsk)
22669 +gr_set_pax_flags(struct task_struct *task)
22675 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
22681 +gr_handle_delete(const ino_t ino, const dev_t dev)
22687 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
22693 +gr_handle_crash(struct task_struct *task, const int sig)
22699 +gr_check_crash_exec(const struct file *filp)
22705 +gr_check_crash_uid(const uid_t uid)
22711 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
22712 + struct dentry *old_dentry,
22713 + struct dentry *new_dentry,
22714 + struct vfsmount *mnt, const __u8 replace)
22720 +gr_search_socket(const int family, const int type, const int protocol)
22726 +gr_search_connectbind(const int mode, const struct socket *sock,
22727 + const struct sockaddr_in *addr)
22733 +gr_task_is_capable(struct task_struct *task, const int cap)
22739 +gr_is_capable_nolog(const int cap)
22745 +gr_handle_alertkill(struct task_struct *task)
22751 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
22757 +gr_acl_handle_hidden_file(const struct dentry * dentry,
22758 + const struct vfsmount * mnt)
22764 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
22771 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
22777 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
22783 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
22784 + unsigned int *vm_flags)
22790 +gr_acl_handle_truncate(const struct dentry * dentry,
22791 + const struct vfsmount * mnt)
22797 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
22803 +gr_acl_handle_access(const struct dentry * dentry,
22804 + const struct vfsmount * mnt, const int fmode)
22810 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
22817 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
22824 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
22830 +grsecurity_init(void)
22836 +gr_acl_handle_mknod(const struct dentry * new_dentry,
22837 + const struct dentry * parent_dentry,
22838 + const struct vfsmount * parent_mnt,
22845 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
22846 + const struct dentry * parent_dentry,
22847 + const struct vfsmount * parent_mnt)
22853 +gr_acl_handle_symlink(const struct dentry * new_dentry,
22854 + const struct dentry * parent_dentry,
22855 + const struct vfsmount * parent_mnt, const char *from)
22861 +gr_acl_handle_link(const struct dentry * new_dentry,
22862 + const struct dentry * parent_dentry,
22863 + const struct vfsmount * parent_mnt,
22864 + const struct dentry * old_dentry,
22865 + const struct vfsmount * old_mnt, const char *to)
22871 +gr_acl_handle_rename(const struct dentry *new_dentry,
22872 + const struct dentry *parent_dentry,
22873 + const struct vfsmount *parent_mnt,
22874 + const struct dentry *old_dentry,
22875 + const struct inode *old_parent_inode,
22876 + const struct vfsmount *old_mnt, const char *newname)
22882 +gr_acl_handle_filldir(const struct file *file, const char *name,
22883 + const int namelen, const ino_t ino)
22889 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22890 + const time_t shm_createtime, const uid_t cuid, const int shmid)
22896 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
22902 +gr_search_accept(const struct socket *sock)
22908 +gr_search_listen(const struct socket *sock)
22914 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
22920 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
22926 +gr_acl_handle_creat(const struct dentry * dentry,
22927 + const struct dentry * p_dentry,
22928 + const struct vfsmount * p_mnt, const int fmode,
22935 +gr_acl_handle_exit(void)
22941 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
22947 +gr_set_role_label(const uid_t uid, const gid_t gid)
22953 +gr_acl_handle_procpidmem(const struct task_struct *task)
22959 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
22965 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
22971 +gr_set_kernel_label(struct task_struct *task)
22977 +gr_check_user_change(int real, int effective, int fs)
22983 +gr_check_group_change(int real, int effective, int fs)
22989 +EXPORT_SYMBOL(gr_task_is_capable);
22990 +EXPORT_SYMBOL(gr_is_capable_nolog);
22991 +EXPORT_SYMBOL(gr_learn_resource);
22992 +EXPORT_SYMBOL(gr_set_kernel_label);
22993 +#ifdef CONFIG_SECURITY
22994 +EXPORT_SYMBOL(gr_check_user_change);
22995 +EXPORT_SYMBOL(gr_check_group_change);
22997 diff -urNp linux-2.6.27.4/grsecurity/grsec_exec.c linux-2.6.27.4/grsecurity/grsec_exec.c
22998 --- linux-2.6.27.4/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
22999 +++ linux-2.6.27.4/grsecurity/grsec_exec.c 2008-10-25 12:03:07.000000000 -0400
23001 +#include <linux/kernel.h>
23002 +#include <linux/sched.h>
23003 +#include <linux/file.h>
23004 +#include <linux/binfmts.h>
23005 +#include <linux/smp_lock.h>
23006 +#include <linux/fs.h>
23007 +#include <linux/types.h>
23008 +#include <linux/grdefs.h>
23009 +#include <linux/grinternal.h>
23010 +#include <linux/capability.h>
23012 +#include <asm/uaccess.h>
23014 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23015 +static char gr_exec_arg_buf[132];
23016 +static DECLARE_MUTEX(gr_exec_arg_sem);
23020 +gr_handle_nproc(void)
23022 +#ifdef CONFIG_GRKERNSEC_EXECVE
23023 + if (grsec_enable_execve && current->user &&
23024 + (atomic_read(¤t->user->processes) >
23025 + current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
23026 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
23027 + gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
23035 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
23037 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23038 + char *grarg = gr_exec_arg_buf;
23039 + unsigned int i, x, execlen = 0;
23042 + if (!((grsec_enable_execlog && grsec_enable_group &&
23043 + in_group_p(grsec_audit_gid))
23044 + || (grsec_enable_execlog && !grsec_enable_group)))
23047 + down(&gr_exec_arg_sem);
23048 + memset(grarg, 0, sizeof(gr_exec_arg_buf));
23050 + if (unlikely(argv == NULL))
23053 + for (i = 0; i < bprm->argc && execlen < 128; i++) {
23054 + const char __user *p;
23055 + unsigned int len;
23057 + if (copy_from_user(&p, argv + i, sizeof(p)))
23061 + len = strnlen_user(p, 128 - execlen);
23062 + if (len > 128 - execlen)
23063 + len = 128 - execlen;
23064 + else if (len > 0)
23066 + if (copy_from_user(grarg + execlen, p, len))
23069 + /* rewrite unprintable characters */
23070 + for (x = 0; x < len; x++) {
23071 + c = *(grarg + execlen + x);
23072 + if (c < 32 || c > 126)
23073 + *(grarg + execlen + x) = ' ';
23077 + *(grarg + execlen) = ' ';
23078 + *(grarg + execlen + 1) = '\0';
23083 + gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
23084 + bprm->file->f_path.mnt, grarg);
23085 + up(&gr_exec_arg_sem);
23089 diff -urNp linux-2.6.27.4/grsecurity/grsec_fifo.c linux-2.6.27.4/grsecurity/grsec_fifo.c
23090 --- linux-2.6.27.4/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
23091 +++ linux-2.6.27.4/grsecurity/grsec_fifo.c 2008-10-25 12:03:07.000000000 -0400
23093 +#include <linux/kernel.h>
23094 +#include <linux/sched.h>
23095 +#include <linux/fs.h>
23096 +#include <linux/file.h>
23097 +#include <linux/grinternal.h>
23100 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
23101 + const struct dentry *dir, const int flag, const int acc_mode)
23103 +#ifdef CONFIG_GRKERNSEC_FIFO
23104 + if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
23105 + !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
23106 + (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
23107 + (current->fsuid != dentry->d_inode->i_uid)) {
23108 + if (!generic_permission(dentry->d_inode, acc_mode, NULL))
23109 + gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
23115 diff -urNp linux-2.6.27.4/grsecurity/grsec_fork.c linux-2.6.27.4/grsecurity/grsec_fork.c
23116 --- linux-2.6.27.4/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
23117 +++ linux-2.6.27.4/grsecurity/grsec_fork.c 2008-10-25 12:03:07.000000000 -0400
23119 +#include <linux/kernel.h>
23120 +#include <linux/sched.h>
23121 +#include <linux/grsecurity.h>
23122 +#include <linux/grinternal.h>
23123 +#include <linux/errno.h>
23126 +gr_log_forkfail(const int retval)
23128 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
23129 + if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
23130 + gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
23134 diff -urNp linux-2.6.27.4/grsecurity/grsec_init.c linux-2.6.27.4/grsecurity/grsec_init.c
23135 --- linux-2.6.27.4/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
23136 +++ linux-2.6.27.4/grsecurity/grsec_init.c 2008-10-25 12:03:07.000000000 -0400
23138 +#include <linux/kernel.h>
23139 +#include <linux/sched.h>
23140 +#include <linux/mm.h>
23141 +#include <linux/smp_lock.h>
23142 +#include <linux/gracl.h>
23143 +#include <linux/slab.h>
23144 +#include <linux/vmalloc.h>
23145 +#include <linux/percpu.h>
23147 +int grsec_enable_link;
23148 +int grsec_enable_dmesg;
23149 +int grsec_enable_fifo;
23150 +int grsec_enable_execve;
23151 +int grsec_enable_execlog;
23152 +int grsec_enable_signal;
23153 +int grsec_enable_forkfail;
23154 +int grsec_enable_time;
23155 +int grsec_enable_audit_textrel;
23156 +int grsec_enable_group;
23157 +int grsec_audit_gid;
23158 +int grsec_enable_chdir;
23159 +int grsec_enable_audit_ipc;
23160 +int grsec_enable_mount;
23161 +int grsec_enable_chroot_findtask;
23162 +int grsec_enable_chroot_mount;
23163 +int grsec_enable_chroot_shmat;
23164 +int grsec_enable_chroot_fchdir;
23165 +int grsec_enable_chroot_double;
23166 +int grsec_enable_chroot_pivot;
23167 +int grsec_enable_chroot_chdir;
23168 +int grsec_enable_chroot_chmod;
23169 +int grsec_enable_chroot_mknod;
23170 +int grsec_enable_chroot_nice;
23171 +int grsec_enable_chroot_execlog;
23172 +int grsec_enable_chroot_caps;
23173 +int grsec_enable_chroot_sysctl;
23174 +int grsec_enable_chroot_unix;
23175 +int grsec_enable_tpe;
23176 +int grsec_tpe_gid;
23177 +int grsec_enable_tpe_all;
23178 +int grsec_enable_socket_all;
23179 +int grsec_socket_all_gid;
23180 +int grsec_enable_socket_client;
23181 +int grsec_socket_client_gid;
23182 +int grsec_enable_socket_server;
23183 +int grsec_socket_server_gid;
23184 +int grsec_resource_logging;
23187 +DEFINE_SPINLOCK(grsec_alert_lock);
23188 +unsigned long grsec_alert_wtime = 0;
23189 +unsigned long grsec_alert_fyet = 0;
23191 +DEFINE_SPINLOCK(grsec_audit_lock);
23193 +DEFINE_RWLOCK(grsec_exec_file_lock);
23195 +char *gr_shared_page[4];
23197 +char *gr_alert_log_fmt;
23198 +char *gr_audit_log_fmt;
23199 +char *gr_alert_log_buf;
23200 +char *gr_audit_log_buf;
23202 +extern struct gr_arg *gr_usermode;
23203 +extern unsigned char *gr_system_salt;
23204 +extern unsigned char *gr_system_sum;
23207 +grsecurity_init(void)
23210 + /* create the per-cpu shared pages */
23213 + memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
23216 + for (j = 0; j < 4; j++) {
23217 + gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
23218 + if (gr_shared_page[j] == NULL) {
23219 + panic("Unable to allocate grsecurity shared page");
23224 + /* allocate log buffers */
23225 + gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
23226 + if (!gr_alert_log_fmt) {
23227 + panic("Unable to allocate grsecurity alert log format buffer");
23230 + gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
23231 + if (!gr_audit_log_fmt) {
23232 + panic("Unable to allocate grsecurity audit log format buffer");
23235 + gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23236 + if (!gr_alert_log_buf) {
23237 + panic("Unable to allocate grsecurity alert log buffer");
23240 + gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23241 + if (!gr_audit_log_buf) {
23242 + panic("Unable to allocate grsecurity audit log buffer");
23246 + /* allocate memory for authentication structure */
23247 + gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
23248 + gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
23249 + gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
23251 + if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
23252 + panic("Unable to allocate grsecurity authentication structure");
23256 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
23257 +#ifndef CONFIG_GRKERNSEC_SYSCTL
23260 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
23261 + grsec_enable_audit_textrel = 1;
23263 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
23264 + grsec_enable_group = 1;
23265 + grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
23267 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
23268 + grsec_enable_chdir = 1;
23270 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23271 + grsec_enable_audit_ipc = 1;
23273 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
23274 + grsec_enable_mount = 1;
23276 +#ifdef CONFIG_GRKERNSEC_LINK
23277 + grsec_enable_link = 1;
23279 +#ifdef CONFIG_GRKERNSEC_DMESG
23280 + grsec_enable_dmesg = 1;
23282 +#ifdef CONFIG_GRKERNSEC_FIFO
23283 + grsec_enable_fifo = 1;
23285 +#ifdef CONFIG_GRKERNSEC_EXECVE
23286 + grsec_enable_execve = 1;
23288 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23289 + grsec_enable_execlog = 1;
23291 +#ifdef CONFIG_GRKERNSEC_SIGNAL
23292 + grsec_enable_signal = 1;
23294 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
23295 + grsec_enable_forkfail = 1;
23297 +#ifdef CONFIG_GRKERNSEC_TIME
23298 + grsec_enable_time = 1;
23300 +#ifdef CONFIG_GRKERNSEC_RESLOG
23301 + grsec_resource_logging = 1;
23303 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
23304 + grsec_enable_chroot_findtask = 1;
23306 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23307 + grsec_enable_chroot_unix = 1;
23309 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23310 + grsec_enable_chroot_mount = 1;
23312 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23313 + grsec_enable_chroot_fchdir = 1;
23315 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23316 + grsec_enable_chroot_shmat = 1;
23318 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23319 + grsec_enable_chroot_double = 1;
23321 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23322 + grsec_enable_chroot_pivot = 1;
23324 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23325 + grsec_enable_chroot_chdir = 1;
23327 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23328 + grsec_enable_chroot_chmod = 1;
23330 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23331 + grsec_enable_chroot_mknod = 1;
23333 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23334 + grsec_enable_chroot_nice = 1;
23336 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23337 + grsec_enable_chroot_execlog = 1;
23339 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23340 + grsec_enable_chroot_caps = 1;
23342 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23343 + grsec_enable_chroot_sysctl = 1;
23345 +#ifdef CONFIG_GRKERNSEC_TPE
23346 + grsec_enable_tpe = 1;
23347 + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
23348 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
23349 + grsec_enable_tpe_all = 1;
23352 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
23353 + grsec_enable_socket_all = 1;
23354 + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
23356 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
23357 + grsec_enable_socket_client = 1;
23358 + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
23360 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
23361 + grsec_enable_socket_server = 1;
23362 + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
23368 diff -urNp linux-2.6.27.4/grsecurity/grsec_ipc.c linux-2.6.27.4/grsecurity/grsec_ipc.c
23369 --- linux-2.6.27.4/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
23370 +++ linux-2.6.27.4/grsecurity/grsec_ipc.c 2008-10-25 12:03:07.000000000 -0400
23372 +#include <linux/kernel.h>
23373 +#include <linux/sched.h>
23374 +#include <linux/types.h>
23375 +#include <linux/ipc.h>
23376 +#include <linux/grsecurity.h>
23377 +#include <linux/grinternal.h>
23380 +gr_log_msgget(const int ret, const int msgflg)
23382 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23383 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23384 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
23385 + !grsec_enable_group)) && (ret >= 0)
23386 + && (msgflg & IPC_CREAT))
23387 + gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
23393 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
23395 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23396 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23397 + grsec_enable_audit_ipc) ||
23398 + (grsec_enable_audit_ipc && !grsec_enable_group))
23399 + gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
23405 +gr_log_semget(const int err, const int semflg)
23407 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23408 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23409 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
23410 + !grsec_enable_group)) && (err >= 0)
23411 + && (semflg & IPC_CREAT))
23412 + gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
23418 +gr_log_semrm(const uid_t uid, const uid_t cuid)
23420 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23421 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23422 + grsec_enable_audit_ipc) ||
23423 + (grsec_enable_audit_ipc && !grsec_enable_group))
23424 + gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
23430 +gr_log_shmget(const int err, const int shmflg, const size_t size)
23432 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23433 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23434 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
23435 + !grsec_enable_group)) && (err >= 0)
23436 + && (shmflg & IPC_CREAT))
23437 + gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
23443 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
23445 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23446 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23447 + grsec_enable_audit_ipc) ||
23448 + (grsec_enable_audit_ipc && !grsec_enable_group))
23449 + gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
23453 diff -urNp linux-2.6.27.4/grsecurity/grsec_link.c linux-2.6.27.4/grsecurity/grsec_link.c
23454 --- linux-2.6.27.4/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
23455 +++ linux-2.6.27.4/grsecurity/grsec_link.c 2008-10-25 12:03:07.000000000 -0400
23457 +#include <linux/kernel.h>
23458 +#include <linux/sched.h>
23459 +#include <linux/fs.h>
23460 +#include <linux/file.h>
23461 +#include <linux/grinternal.h>
23464 +gr_handle_follow_link(const struct inode *parent,
23465 + const struct inode *inode,
23466 + const struct dentry *dentry, const struct vfsmount *mnt)
23468 +#ifdef CONFIG_GRKERNSEC_LINK
23469 + if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
23470 + (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
23471 + (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
23472 + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
23480 +gr_handle_hardlink(const struct dentry *dentry,
23481 + const struct vfsmount *mnt,
23482 + struct inode *inode, const int mode, const char *to)
23484 +#ifdef CONFIG_GRKERNSEC_LINK
23485 + if (grsec_enable_link && current->fsuid != inode->i_uid &&
23486 + (!S_ISREG(mode) || (mode & S_ISUID) ||
23487 + ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
23488 + (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
23489 + !capable(CAP_FOWNER) && current->uid) {
23490 + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
23496 diff -urNp linux-2.6.27.4/grsecurity/grsec_log.c linux-2.6.27.4/grsecurity/grsec_log.c
23497 --- linux-2.6.27.4/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
23498 +++ linux-2.6.27.4/grsecurity/grsec_log.c 2008-10-25 12:03:07.000000000 -0400
23500 +#include <linux/kernel.h>
23501 +#include <linux/sched.h>
23502 +#include <linux/file.h>
23503 +#include <linux/tty.h>
23504 +#include <linux/fs.h>
23505 +#include <linux/grinternal.h>
23507 +#define BEGIN_LOCKS(x) \
23508 + read_lock(&tasklist_lock); \
23509 + read_lock(&grsec_exec_file_lock); \
23510 + if (x != GR_DO_AUDIT) \
23511 + spin_lock(&grsec_alert_lock); \
23513 + spin_lock(&grsec_audit_lock)
23515 +#define END_LOCKS(x) \
23516 + if (x != GR_DO_AUDIT) \
23517 + spin_unlock(&grsec_alert_lock); \
23519 + spin_unlock(&grsec_audit_lock); \
23520 + read_unlock(&grsec_exec_file_lock); \
23521 + read_unlock(&tasklist_lock); \
23522 + if (x == GR_DONT_AUDIT) \
23523 + gr_handle_alertkill(current)
23530 +extern char *gr_alert_log_fmt;
23531 +extern char *gr_audit_log_fmt;
23532 +extern char *gr_alert_log_buf;
23533 +extern char *gr_audit_log_buf;
23535 +static int gr_log_start(int audit)
23537 + char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
23538 + char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
23539 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
23541 + if (audit == GR_DO_AUDIT)
23544 + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
23545 + grsec_alert_wtime = jiffies;
23546 + grsec_alert_fyet = 0;
23547 + } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
23548 + grsec_alert_fyet++;
23549 + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
23550 + grsec_alert_wtime = jiffies;
23551 + grsec_alert_fyet++;
23552 + printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
23554 + } else return FLOODING;
23557 + memset(buf, 0, PAGE_SIZE);
23558 + if (current->signal->curr_ip && gr_acl_is_enabled()) {
23559 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
23560 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
23561 + } else if (current->signal->curr_ip) {
23562 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
23563 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
23564 + } else if (gr_acl_is_enabled()) {
23565 + sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
23566 + snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
23568 + sprintf(fmt, "%s%s", loglevel, "grsec: ");
23569 + strcpy(buf, fmt);
23572 + return NO_FLOODING;
23575 +static void gr_log_middle(int audit, const char *msg, va_list ap)
23577 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
23578 + unsigned int len = strlen(buf);
23580 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
23585 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
23587 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
23588 + unsigned int len = strlen(buf);
23591 + va_start(ap, msg);
23592 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
23598 +static void gr_log_end(int audit)
23600 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
23601 + unsigned int len = strlen(buf);
23603 + snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
23604 + printk("%s\n", buf);
23609 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
23612 + char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
23613 + char *str1, *str2, *str3;
23615 + unsigned long ulong1, ulong2;
23616 + struct dentry *dentry;
23617 + struct vfsmount *mnt;
23618 + struct file *file;
23619 + struct task_struct *task;
23622 + BEGIN_LOCKS(audit);
23623 + logtype = gr_log_start(audit);
23624 + if (logtype == FLOODING) {
23625 + END_LOCKS(audit);
23628 + va_start(ap, argtypes);
23629 + switch (argtypes) {
23630 + case GR_TTYSNIFF:
23631 + task = va_arg(ap, struct task_struct *);
23632 + 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);
23634 + case GR_SYSCTL_HIDDEN:
23635 + str1 = va_arg(ap, char *);
23636 + gr_log_middle_varargs(audit, msg, result, str1);
23639 + dentry = va_arg(ap, struct dentry *);
23640 + mnt = va_arg(ap, struct vfsmount *);
23641 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
23643 + case GR_RBAC_STR:
23644 + dentry = va_arg(ap, struct dentry *);
23645 + mnt = va_arg(ap, struct vfsmount *);
23646 + str1 = va_arg(ap, char *);
23647 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
23649 + case GR_STR_RBAC:
23650 + str1 = va_arg(ap, char *);
23651 + dentry = va_arg(ap, struct dentry *);
23652 + mnt = va_arg(ap, struct vfsmount *);
23653 + gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
23655 + case GR_RBAC_MODE2:
23656 + dentry = va_arg(ap, struct dentry *);
23657 + mnt = va_arg(ap, struct vfsmount *);
23658 + str1 = va_arg(ap, char *);
23659 + str2 = va_arg(ap, char *);
23660 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
23662 + case GR_RBAC_MODE3:
23663 + dentry = va_arg(ap, struct dentry *);
23664 + mnt = va_arg(ap, struct vfsmount *);
23665 + str1 = va_arg(ap, char *);
23666 + str2 = va_arg(ap, char *);
23667 + str3 = va_arg(ap, char *);
23668 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
23670 + case GR_FILENAME:
23671 + dentry = va_arg(ap, struct dentry *);
23672 + mnt = va_arg(ap, struct vfsmount *);
23673 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
23675 + case GR_STR_FILENAME:
23676 + str1 = va_arg(ap, char *);
23677 + dentry = va_arg(ap, struct dentry *);
23678 + mnt = va_arg(ap, struct vfsmount *);
23679 + gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
23681 + case GR_FILENAME_STR:
23682 + dentry = va_arg(ap, struct dentry *);
23683 + mnt = va_arg(ap, struct vfsmount *);
23684 + str1 = va_arg(ap, char *);
23685 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
23687 + case GR_FILENAME_TWO_INT:
23688 + dentry = va_arg(ap, struct dentry *);
23689 + mnt = va_arg(ap, struct vfsmount *);
23690 + num1 = va_arg(ap, int);
23691 + num2 = va_arg(ap, int);
23692 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
23694 + case GR_FILENAME_TWO_INT_STR:
23695 + dentry = va_arg(ap, struct dentry *);
23696 + mnt = va_arg(ap, struct vfsmount *);
23697 + num1 = va_arg(ap, int);
23698 + num2 = va_arg(ap, int);
23699 + str1 = va_arg(ap, char *);
23700 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
23703 + file = va_arg(ap, struct file *);
23704 + ulong1 = va_arg(ap, unsigned long);
23705 + ulong2 = va_arg(ap, unsigned long);
23706 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
23709 + task = va_arg(ap, struct task_struct *);
23710 + gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_path.dentry, task->exec_file->f_path.mnt) : "(none)", task->comm, task->pid);
23712 + case GR_RESOURCE:
23713 + task = va_arg(ap, struct task_struct *);
23714 + ulong1 = va_arg(ap, unsigned long);
23715 + str1 = va_arg(ap, char *);
23716 + ulong2 = va_arg(ap, unsigned long);
23717 + 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);
23720 + task = va_arg(ap, struct task_struct *);
23721 + str1 = va_arg(ap, char *);
23722 + 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);
23725 + task = va_arg(ap, struct task_struct *);
23726 + num1 = va_arg(ap, int);
23727 + 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);
23730 + task = va_arg(ap, struct task_struct *);
23731 + ulong1 = va_arg(ap, unsigned long);
23732 + 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);
23735 + task = va_arg(ap, struct task_struct *);
23736 + ulong1 = va_arg(ap, unsigned long);
23737 + 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);
23741 + unsigned int wday, cday;
23745 + char cur_tty[64] = { 0 };
23746 + char parent_tty[64] = { 0 };
23748 + task = va_arg(ap, struct task_struct *);
23749 + wday = va_arg(ap, unsigned int);
23750 + cday = va_arg(ap, unsigned int);
23751 + whr = va_arg(ap, int);
23752 + chr = va_arg(ap, int);
23753 + wmin = va_arg(ap, int);
23754 + cmin = va_arg(ap, int);
23755 + wsec = va_arg(ap, int);
23756 + csec = va_arg(ap, int);
23757 + ulong1 = va_arg(ap, unsigned long);
23759 + 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);
23763 + gr_log_middle(audit, msg, ap);
23766 + gr_log_end(audit);
23767 + END_LOCKS(audit);
23769 diff -urNp linux-2.6.27.4/grsecurity/grsec_mem.c linux-2.6.27.4/grsecurity/grsec_mem.c
23770 --- linux-2.6.27.4/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
23771 +++ linux-2.6.27.4/grsecurity/grsec_mem.c 2008-10-25 12:03:07.000000000 -0400
23773 +#include <linux/kernel.h>
23774 +#include <linux/sched.h>
23775 +#include <linux/mm.h>
23776 +#include <linux/mman.h>
23777 +#include <linux/grinternal.h>
23780 +gr_handle_ioperm(void)
23782 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
23787 +gr_handle_iopl(void)
23789 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
23794 +gr_handle_mem_write(void)
23796 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
23801 +gr_handle_kmem_write(void)
23803 + gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
23808 +gr_handle_open_port(void)
23810 + gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
23815 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
23817 + unsigned long start, end;
23820 + end = start + vma->vm_end - vma->vm_start;
23822 + if (start > end) {
23823 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
23827 + /* allowed ranges : ISA I/O BIOS */
23828 + if ((start >= __pa(high_memory))
23830 + || (start >= 0x000a0000 && end <= 0x00100000)
23831 + || (start >= 0x00000000 && end <= 0x00001000)
23836 + if (vma->vm_flags & VM_WRITE) {
23837 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
23840 + vma->vm_flags &= ~VM_MAYWRITE;
23844 diff -urNp linux-2.6.27.4/grsecurity/grsec_mount.c linux-2.6.27.4/grsecurity/grsec_mount.c
23845 --- linux-2.6.27.4/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
23846 +++ linux-2.6.27.4/grsecurity/grsec_mount.c 2008-10-25 12:03:07.000000000 -0400
23848 +#include <linux/kernel.h>
23849 +#include <linux/sched.h>
23850 +#include <linux/grsecurity.h>
23851 +#include <linux/grinternal.h>
23854 +gr_log_remount(const char *devname, const int retval)
23856 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
23857 + if (grsec_enable_mount && (retval >= 0))
23858 + gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
23864 +gr_log_unmount(const char *devname, const int retval)
23866 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
23867 + if (grsec_enable_mount && (retval >= 0))
23868 + gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
23874 +gr_log_mount(const char *from, const char *to, const int retval)
23876 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
23877 + if (grsec_enable_mount && (retval >= 0))
23878 + gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
23882 diff -urNp linux-2.6.27.4/grsecurity/grsec_sig.c linux-2.6.27.4/grsecurity/grsec_sig.c
23883 --- linux-2.6.27.4/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
23884 +++ linux-2.6.27.4/grsecurity/grsec_sig.c 2008-10-25 12:03:07.000000000 -0400
23886 +#include <linux/kernel.h>
23887 +#include <linux/sched.h>
23888 +#include <linux/delay.h>
23889 +#include <linux/grsecurity.h>
23890 +#include <linux/grinternal.h>
23893 +gr_log_signal(const int sig, const struct task_struct *t)
23895 +#ifdef CONFIG_GRKERNSEC_SIGNAL
23896 + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
23897 + (sig == SIGABRT) || (sig == SIGBUS))) {
23898 + if (t->pid == current->pid) {
23899 + gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
23901 + gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
23909 +gr_handle_signal(const struct task_struct *p, const int sig)
23911 +#ifdef CONFIG_GRKERNSEC
23912 + if (current->pid > 1 && gr_check_protected_task(p)) {
23913 + gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
23915 + } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
23922 +void gr_handle_brute_attach(struct task_struct *p)
23924 +#ifdef CONFIG_GRKERNSEC_BRUTE
23925 + read_lock(&tasklist_lock);
23926 + read_lock(&grsec_exec_file_lock);
23927 + if (p->parent && p->parent->exec_file == p->exec_file)
23928 + p->parent->brute = 1;
23929 + read_unlock(&grsec_exec_file_lock);
23930 + read_unlock(&tasklist_lock);
23935 +void gr_handle_brute_check(void)
23937 +#ifdef CONFIG_GRKERNSEC_BRUTE
23938 + if (current->brute)
23939 + msleep(30 * 1000);
23944 diff -urNp linux-2.6.27.4/grsecurity/grsec_sock.c linux-2.6.27.4/grsecurity/grsec_sock.c
23945 --- linux-2.6.27.4/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
23946 +++ linux-2.6.27.4/grsecurity/grsec_sock.c 2008-10-25 12:03:07.000000000 -0400
23948 +#include <linux/kernel.h>
23949 +#include <linux/module.h>
23950 +#include <linux/sched.h>
23951 +#include <linux/file.h>
23952 +#include <linux/net.h>
23953 +#include <linux/in.h>
23954 +#include <linux/ip.h>
23955 +#include <net/sock.h>
23956 +#include <net/inet_sock.h>
23957 +#include <linux/grsecurity.h>
23958 +#include <linux/grinternal.h>
23959 +#include <linux/gracl.h>
23961 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
23962 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
23963 +EXPORT_SYMBOL(udp_v4_lookup);
23966 +kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
23967 +EXPORT_SYMBOL(gr_cap_rtnetlink);
23969 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
23970 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
23972 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
23973 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
23975 +#ifdef CONFIG_UNIX_MODULE
23976 +EXPORT_SYMBOL(gr_acl_handle_unix);
23977 +EXPORT_SYMBOL(gr_acl_handle_mknod);
23978 +EXPORT_SYMBOL(gr_handle_chroot_unix);
23979 +EXPORT_SYMBOL(gr_handle_create);
23982 +#ifdef CONFIG_GRKERNSEC
23983 +#define gr_conn_table_size 32749
23984 +struct conn_table_entry {
23985 + struct conn_table_entry *next;
23986 + struct signal_struct *sig;
23989 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
23990 +DEFINE_SPINLOCK(gr_conn_table_lock);
23992 +extern const char * gr_socktype_to_name(unsigned char type);
23993 +extern const char * gr_proto_to_name(unsigned char proto);
23995 +static __inline__ int
23996 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
23998 + return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
24001 +static __inline__ int
24002 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
24003 + __u16 sport, __u16 dport)
24005 + if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
24006 + sig->gr_sport == sport && sig->gr_dport == dport))
24012 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
24014 + struct conn_table_entry **match;
24015 + unsigned int index;
24017 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
24018 + sig->gr_sport, sig->gr_dport,
24019 + gr_conn_table_size);
24021 + newent->sig = sig;
24023 + match = &gr_conn_table[index];
24024 + newent->next = *match;
24030 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
24032 + struct conn_table_entry *match, *last = NULL;
24033 + unsigned int index;
24035 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
24036 + sig->gr_sport, sig->gr_dport,
24037 + gr_conn_table_size);
24039 + match = gr_conn_table[index];
24040 + while (match && !conn_match(match->sig,
24041 + sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
24042 + sig->gr_dport)) {
24044 + match = match->next;
24049 + last->next = match->next;
24051 + gr_conn_table[index] = NULL;
24058 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
24059 + __u16 sport, __u16 dport)
24061 + struct conn_table_entry *match;
24062 + unsigned int index;
24064 + index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
24066 + match = gr_conn_table[index];
24067 + while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
24068 + match = match->next;
24071 + return match->sig;
24078 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
24080 +#ifdef CONFIG_GRKERNSEC
24081 + struct signal_struct *sig = task->signal;
24082 + struct conn_table_entry *newent;
24084 + newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
24085 + if (newent == NULL)
24087 + /* no bh lock needed since we are called with bh disabled */
24088 + spin_lock(&gr_conn_table_lock);
24089 + gr_del_task_from_ip_table_nolock(sig);
24090 + sig->gr_saddr = inet->rcv_saddr;
24091 + sig->gr_daddr = inet->daddr;
24092 + sig->gr_sport = inet->sport;
24093 + sig->gr_dport = inet->dport;
24094 + gr_add_to_task_ip_table_nolock(sig, newent);
24095 + spin_unlock(&gr_conn_table_lock);
24100 +void gr_del_task_from_ip_table(struct task_struct *task)
24102 +#ifdef CONFIG_GRKERNSEC
24103 + spin_lock(&gr_conn_table_lock);
24104 + gr_del_task_from_ip_table_nolock(task->signal);
24105 + spin_unlock(&gr_conn_table_lock);
24111 +gr_attach_curr_ip(const struct sock *sk)
24113 +#ifdef CONFIG_GRKERNSEC
24114 + struct signal_struct *p, *set;
24115 + const struct inet_sock *inet = inet_sk(sk);
24117 + if (unlikely(sk->sk_protocol != IPPROTO_TCP))
24120 + set = current->signal;
24122 + spin_lock_bh(&gr_conn_table_lock);
24123 + p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
24124 + inet->dport, inet->sport);
24125 + if (unlikely(p != NULL)) {
24126 + set->curr_ip = p->curr_ip;
24127 + set->used_accept = 1;
24128 + gr_del_task_from_ip_table_nolock(p);
24129 + spin_unlock_bh(&gr_conn_table_lock);
24132 + spin_unlock_bh(&gr_conn_table_lock);
24134 + set->curr_ip = inet->daddr;
24135 + set->used_accept = 1;
24141 +gr_handle_sock_all(const int family, const int type, const int protocol)
24143 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24144 + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
24145 + (family != AF_UNIX) && (family != AF_LOCAL)) {
24146 + gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
24154 +gr_handle_sock_server(const struct sockaddr *sck)
24156 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24157 + if (grsec_enable_socket_server &&
24158 + in_group_p(grsec_socket_server_gid) &&
24159 + sck && (sck->sa_family != AF_UNIX) &&
24160 + (sck->sa_family != AF_LOCAL)) {
24161 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24169 +gr_handle_sock_server_other(const struct sock *sck)
24171 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24172 + if (grsec_enable_socket_server &&
24173 + in_group_p(grsec_socket_server_gid) &&
24174 + sck && (sck->sk_family != AF_UNIX) &&
24175 + (sck->sk_family != AF_LOCAL)) {
24176 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24184 +gr_handle_sock_client(const struct sockaddr *sck)
24186 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24187 + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
24188 + sck && (sck->sa_family != AF_UNIX) &&
24189 + (sck->sa_family != AF_LOCAL)) {
24190 + gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
24198 +gr_cap_rtnetlink(struct sock *sock)
24200 +#ifdef CONFIG_GRKERNSEC
24201 + if (!gr_acl_is_enabled())
24202 + return current->cap_effective;
24203 + else if (sock->sk_protocol == NETLINK_ISCSI &&
24204 + cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
24205 + gr_task_is_capable(current, CAP_SYS_ADMIN))
24206 + return current->cap_effective;
24207 + else if (sock->sk_protocol == NETLINK_AUDIT &&
24208 + cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
24209 + gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
24210 + cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
24211 + gr_task_is_capable(current, CAP_AUDIT_CONTROL))
24212 + return current->cap_effective;
24213 + else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
24214 + gr_task_is_capable(current, CAP_NET_ADMIN))
24215 + return current->cap_effective;
24217 + return __cap_empty_set;
24219 + return current->cap_effective;
24222 diff -urNp linux-2.6.27.4/grsecurity/grsec_sysctl.c linux-2.6.27.4/grsecurity/grsec_sysctl.c
24223 --- linux-2.6.27.4/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
24224 +++ linux-2.6.27.4/grsecurity/grsec_sysctl.c 2008-10-25 13:42:27.000000000 -0400
24226 +#include <linux/kernel.h>
24227 +#include <linux/sched.h>
24228 +#include <linux/sysctl.h>
24229 +#include <linux/grsecurity.h>
24230 +#include <linux/grinternal.h>
24232 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24233 +int grsec_modstop;
24237 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
24239 +#ifdef CONFIG_GRKERNSEC_SYSCTL
24240 + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
24241 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24245 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24246 + if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
24247 + grsec_modstop && (op & MAY_WRITE)) {
24248 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24255 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
24256 +ctl_table grsecurity_table[] = {
24257 +#ifdef CONFIG_GRKERNSEC_SYSCTL
24258 +#ifdef CONFIG_GRKERNSEC_LINK
24260 + .ctl_name = CTL_UNNUMBERED,
24261 + .procname = "linking_restrictions",
24262 + .data = &grsec_enable_link,
24263 + .maxlen = sizeof(int),
24265 + .proc_handler = &proc_dointvec,
24268 +#ifdef CONFIG_GRKERNSEC_FIFO
24270 + .ctl_name = CTL_UNNUMBERED,
24271 + .procname = "fifo_restrictions",
24272 + .data = &grsec_enable_fifo,
24273 + .maxlen = sizeof(int),
24275 + .proc_handler = &proc_dointvec,
24278 +#ifdef CONFIG_GRKERNSEC_EXECVE
24280 + .ctl_name = CTL_UNNUMBERED,
24281 + .procname = "execve_limiting",
24282 + .data = &grsec_enable_execve,
24283 + .maxlen = sizeof(int),
24285 + .proc_handler = &proc_dointvec,
24288 +#ifdef CONFIG_GRKERNSEC_EXECLOG
24290 + .ctl_name = CTL_UNNUMBERED,
24291 + .procname = "exec_logging",
24292 + .data = &grsec_enable_execlog,
24293 + .maxlen = sizeof(int),
24295 + .proc_handler = &proc_dointvec,
24298 +#ifdef CONFIG_GRKERNSEC_SIGNAL
24300 + .ctl_name = CTL_UNNUMBERED,
24301 + .procname = "signal_logging",
24302 + .data = &grsec_enable_signal,
24303 + .maxlen = sizeof(int),
24305 + .proc_handler = &proc_dointvec,
24308 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
24310 + .ctl_name = CTL_UNNUMBERED,
24311 + .procname = "forkfail_logging",
24312 + .data = &grsec_enable_forkfail,
24313 + .maxlen = sizeof(int),
24315 + .proc_handler = &proc_dointvec,
24318 +#ifdef CONFIG_GRKERNSEC_TIME
24320 + .ctl_name = CTL_UNNUMBERED,
24321 + .procname = "timechange_logging",
24322 + .data = &grsec_enable_time,
24323 + .maxlen = sizeof(int),
24325 + .proc_handler = &proc_dointvec,
24328 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
24330 + .ctl_name = CTL_UNNUMBERED,
24331 + .procname = "chroot_deny_shmat",
24332 + .data = &grsec_enable_chroot_shmat,
24333 + .maxlen = sizeof(int),
24335 + .proc_handler = &proc_dointvec,
24338 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
24340 + .ctl_name = CTL_UNNUMBERED,
24341 + .procname = "chroot_deny_unix",
24342 + .data = &grsec_enable_chroot_unix,
24343 + .maxlen = sizeof(int),
24345 + .proc_handler = &proc_dointvec,
24348 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
24350 + .ctl_name = CTL_UNNUMBERED,
24351 + .procname = "chroot_deny_mount",
24352 + .data = &grsec_enable_chroot_mount,
24353 + .maxlen = sizeof(int),
24355 + .proc_handler = &proc_dointvec,
24358 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
24360 + .ctl_name = CTL_UNNUMBERED,
24361 + .procname = "chroot_deny_fchdir",
24362 + .data = &grsec_enable_chroot_fchdir,
24363 + .maxlen = sizeof(int),
24365 + .proc_handler = &proc_dointvec,
24368 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
24370 + .ctl_name = CTL_UNNUMBERED,
24371 + .procname = "chroot_deny_chroot",
24372 + .data = &grsec_enable_chroot_double,
24373 + .maxlen = sizeof(int),
24375 + .proc_handler = &proc_dointvec,
24378 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
24380 + .ctl_name = CTL_UNNUMBERED,
24381 + .procname = "chroot_deny_pivot",
24382 + .data = &grsec_enable_chroot_pivot,
24383 + .maxlen = sizeof(int),
24385 + .proc_handler = &proc_dointvec,
24388 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
24390 + .ctl_name = CTL_UNNUMBERED,
24391 + .procname = "chroot_enforce_chdir",
24392 + .data = &grsec_enable_chroot_chdir,
24393 + .maxlen = sizeof(int),
24395 + .proc_handler = &proc_dointvec,
24398 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
24400 + .ctl_name = CTL_UNNUMBERED,
24401 + .procname = "chroot_deny_chmod",
24402 + .data = &grsec_enable_chroot_chmod,
24403 + .maxlen = sizeof(int),
24405 + .proc_handler = &proc_dointvec,
24408 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
24410 + .ctl_name = CTL_UNNUMBERED,
24411 + .procname = "chroot_deny_mknod",
24412 + .data = &grsec_enable_chroot_mknod,
24413 + .maxlen = sizeof(int),
24415 + .proc_handler = &proc_dointvec,
24418 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
24420 + .ctl_name = CTL_UNNUMBERED,
24421 + .procname = "chroot_restrict_nice",
24422 + .data = &grsec_enable_chroot_nice,
24423 + .maxlen = sizeof(int),
24425 + .proc_handler = &proc_dointvec,
24428 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
24430 + .ctl_name = CTL_UNNUMBERED,
24431 + .procname = "chroot_execlog",
24432 + .data = &grsec_enable_chroot_execlog,
24433 + .maxlen = sizeof(int),
24435 + .proc_handler = &proc_dointvec,
24438 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
24440 + .ctl_name = CTL_UNNUMBERED,
24441 + .procname = "chroot_caps",
24442 + .data = &grsec_enable_chroot_caps,
24443 + .maxlen = sizeof(int),
24445 + .proc_handler = &proc_dointvec,
24448 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
24450 + .ctl_name = CTL_UNNUMBERED,
24451 + .procname = "chroot_deny_sysctl",
24452 + .data = &grsec_enable_chroot_sysctl,
24453 + .maxlen = sizeof(int),
24455 + .proc_handler = &proc_dointvec,
24458 +#ifdef CONFIG_GRKERNSEC_TPE
24460 + .ctl_name = CTL_UNNUMBERED,
24461 + .procname = "tpe",
24462 + .data = &grsec_enable_tpe,
24463 + .maxlen = sizeof(int),
24465 + .proc_handler = &proc_dointvec,
24468 + .ctl_name = CTL_UNNUMBERED,
24469 + .procname = "tpe_gid",
24470 + .data = &grsec_tpe_gid,
24471 + .maxlen = sizeof(int),
24473 + .proc_handler = &proc_dointvec,
24476 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
24478 + .ctl_name = CTL_UNNUMBERED,
24479 + .procname = "tpe_restrict_all",
24480 + .data = &grsec_enable_tpe_all,
24481 + .maxlen = sizeof(int),
24483 + .proc_handler = &proc_dointvec,
24486 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24488 + .ctl_name = CTL_UNNUMBERED,
24489 + .procname = "socket_all",
24490 + .data = &grsec_enable_socket_all,
24491 + .maxlen = sizeof(int),
24493 + .proc_handler = &proc_dointvec,
24496 + .ctl_name = CTL_UNNUMBERED,
24497 + .procname = "socket_all_gid",
24498 + .data = &grsec_socket_all_gid,
24499 + .maxlen = sizeof(int),
24501 + .proc_handler = &proc_dointvec,
24504 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24506 + .ctl_name = CTL_UNNUMBERED,
24507 + .procname = "socket_client",
24508 + .data = &grsec_enable_socket_client,
24509 + .maxlen = sizeof(int),
24511 + .proc_handler = &proc_dointvec,
24514 + .ctl_name = CTL_UNNUMBERED,
24515 + .procname = "socket_client_gid",
24516 + .data = &grsec_socket_client_gid,
24517 + .maxlen = sizeof(int),
24519 + .proc_handler = &proc_dointvec,
24522 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24524 + .ctl_name = CTL_UNNUMBERED,
24525 + .procname = "socket_server",
24526 + .data = &grsec_enable_socket_server,
24527 + .maxlen = sizeof(int),
24529 + .proc_handler = &proc_dointvec,
24532 + .ctl_name = CTL_UNNUMBERED,
24533 + .procname = "socket_server_gid",
24534 + .data = &grsec_socket_server_gid,
24535 + .maxlen = sizeof(int),
24537 + .proc_handler = &proc_dointvec,
24540 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
24542 + .ctl_name = CTL_UNNUMBERED,
24543 + .procname = "audit_group",
24544 + .data = &grsec_enable_group,
24545 + .maxlen = sizeof(int),
24547 + .proc_handler = &proc_dointvec,
24550 + .ctl_name = CTL_UNNUMBERED,
24551 + .procname = "audit_gid",
24552 + .data = &grsec_audit_gid,
24553 + .maxlen = sizeof(int),
24555 + .proc_handler = &proc_dointvec,
24558 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
24560 + .ctl_name = CTL_UNNUMBERED,
24561 + .procname = "audit_chdir",
24562 + .data = &grsec_enable_chdir,
24563 + .maxlen = sizeof(int),
24565 + .proc_handler = &proc_dointvec,
24568 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24570 + .ctl_name = CTL_UNNUMBERED,
24571 + .procname = "audit_mount",
24572 + .data = &grsec_enable_mount,
24573 + .maxlen = sizeof(int),
24575 + .proc_handler = &proc_dointvec,
24578 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24580 + .ctl_name = CTL_UNNUMBERED,
24581 + .procname = "audit_ipc",
24582 + .data = &grsec_enable_audit_ipc,
24583 + .maxlen = sizeof(int),
24585 + .proc_handler = &proc_dointvec,
24588 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
24590 + .ctl_name = CTL_UNNUMBERED,
24591 + .procname = "audit_textrel",
24592 + .data = &grsec_enable_audit_textrel,
24593 + .maxlen = sizeof(int),
24595 + .proc_handler = &proc_dointvec,
24598 +#ifdef CONFIG_GRKERNSEC_DMESG
24600 + .ctl_name = CTL_UNNUMBERED,
24601 + .procname = "dmesg",
24602 + .data = &grsec_enable_dmesg,
24603 + .maxlen = sizeof(int),
24605 + .proc_handler = &proc_dointvec,
24608 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
24610 + .ctl_name = CTL_UNNUMBERED,
24611 + .procname = "chroot_findtask",
24612 + .data = &grsec_enable_chroot_findtask,
24613 + .maxlen = sizeof(int),
24615 + .proc_handler = &proc_dointvec,
24618 +#ifdef CONFIG_GRKERNSEC_RESLOG
24620 + .ctl_name = CTL_UNNUMBERED,
24621 + .procname = "resource_logging",
24622 + .data = &grsec_resource_logging,
24623 + .maxlen = sizeof(int),
24625 + .proc_handler = &proc_dointvec,
24629 + .ctl_name = CTL_UNNUMBERED,
24630 + .procname = "grsec_lock",
24631 + .data = &grsec_lock,
24632 + .maxlen = sizeof(int),
24634 + .proc_handler = &proc_dointvec,
24637 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24639 + .ctl_name = CTL_UNNUMBERED,
24640 + .procname = "disable_modules",
24641 + .data = &grsec_modstop,
24642 + .maxlen = sizeof(int),
24644 + .proc_handler = &proc_dointvec,
24647 + { .ctl_name = 0 }
24651 +int gr_check_modstop(void)
24653 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24654 + if (grsec_modstop == 1) {
24655 + gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
24661 diff -urNp linux-2.6.27.4/grsecurity/grsec_textrel.c linux-2.6.27.4/grsecurity/grsec_textrel.c
24662 --- linux-2.6.27.4/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
24663 +++ linux-2.6.27.4/grsecurity/grsec_textrel.c 2008-10-25 12:03:07.000000000 -0400
24665 +#include <linux/kernel.h>
24666 +#include <linux/sched.h>
24667 +#include <linux/mm.h>
24668 +#include <linux/file.h>
24669 +#include <linux/grinternal.h>
24670 +#include <linux/grsecurity.h>
24673 +gr_log_textrel(struct vm_area_struct * vma)
24675 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
24676 + if (grsec_enable_audit_textrel)
24677 + gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
24681 diff -urNp linux-2.6.27.4/grsecurity/grsec_time.c linux-2.6.27.4/grsecurity/grsec_time.c
24682 --- linux-2.6.27.4/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
24683 +++ linux-2.6.27.4/grsecurity/grsec_time.c 2008-10-25 12:03:07.000000000 -0400
24685 +#include <linux/kernel.h>
24686 +#include <linux/sched.h>
24687 +#include <linux/grinternal.h>
24690 +gr_log_timechange(void)
24692 +#ifdef CONFIG_GRKERNSEC_TIME
24693 + if (grsec_enable_time)
24694 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
24698 diff -urNp linux-2.6.27.4/grsecurity/grsec_tpe.c linux-2.6.27.4/grsecurity/grsec_tpe.c
24699 --- linux-2.6.27.4/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
24700 +++ linux-2.6.27.4/grsecurity/grsec_tpe.c 2008-10-25 12:03:07.000000000 -0400
24702 +#include <linux/kernel.h>
24703 +#include <linux/sched.h>
24704 +#include <linux/file.h>
24705 +#include <linux/fs.h>
24706 +#include <linux/grinternal.h>
24708 +extern int gr_acl_tpe_check(void);
24711 +gr_tpe_allow(const struct file *file)
24713 +#ifdef CONFIG_GRKERNSEC
24714 + struct inode *inode = file->f_path.dentry->d_parent->d_inode;
24716 + if (current->uid && ((grsec_enable_tpe &&
24717 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
24718 + !in_group_p(grsec_tpe_gid)
24720 + in_group_p(grsec_tpe_gid)
24722 + ) || gr_acl_tpe_check()) &&
24723 + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
24724 + (inode->i_mode & S_IWOTH))))) {
24725 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
24728 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
24729 + if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
24730 + ((inode->i_uid && (inode->i_uid != current->uid)) ||
24731 + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
24732 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
24739 diff -urNp linux-2.6.27.4/grsecurity/grsum.c linux-2.6.27.4/grsecurity/grsum.c
24740 --- linux-2.6.27.4/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
24741 +++ linux-2.6.27.4/grsecurity/grsum.c 2008-10-25 12:03:07.000000000 -0400
24743 +#include <linux/err.h>
24744 +#include <linux/kernel.h>
24745 +#include <linux/sched.h>
24746 +#include <linux/mm.h>
24747 +#include <linux/scatterlist.h>
24748 +#include <linux/crypto.h>
24749 +#include <linux/gracl.h>
24752 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
24753 +#error "crypto and sha256 must be built into the kernel"
24757 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
24760 + struct crypto_hash *tfm;
24761 + struct hash_desc desc;
24762 + struct scatterlist sg;
24763 + unsigned char temp_sum[GR_SHA_LEN];
24764 + volatile int retval = 0;
24765 + volatile int dummy = 0;
24768 + tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
24769 + if (IS_ERR(tfm)) {
24770 + /* should never happen, since sha256 should be built in */
24777 + crypto_hash_init(&desc);
24780 + sg_set_buf(&sg, p, GR_SALT_LEN);
24781 + crypto_hash_update(&desc, &sg, sg.length);
24784 + sg_set_buf(&sg, p, strlen(p));
24786 + crypto_hash_update(&desc, &sg, sg.length);
24788 + crypto_hash_final(&desc, temp_sum);
24790 + memset(entry->pw, 0, GR_PW_LEN);
24792 + for (i = 0; i < GR_SHA_LEN; i++)
24793 + if (sum[i] != temp_sum[i])
24796 + dummy = 1; // waste a cycle
24798 + crypto_free_hash(tfm);
24802 diff -urNp linux-2.6.27.4/grsecurity/Kconfig linux-2.6.27.4/grsecurity/Kconfig
24803 --- linux-2.6.27.4/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
24804 +++ linux-2.6.27.4/grsecurity/Kconfig 2008-10-25 12:03:07.000000000 -0400
24807 +# grecurity configuration
24813 + bool "Grsecurity"
24815 + select CRYPTO_SHA256
24817 + select SECURITY_CAPABILITIES
24819 + If you say Y here, you will be able to configure many features
24820 + that will enhance the security of your system. It is highly
24821 + recommended that you say Y here and read through the help
24822 + for each option so that you fully understand the features and
24823 + can evaluate their usefulness for your machine.
24826 + prompt "Security Level"
24827 + depends on GRKERNSEC
24828 + default GRKERNSEC_CUSTOM
24830 +config GRKERNSEC_LOW
24832 + select GRKERNSEC_LINK
24833 + select GRKERNSEC_FIFO
24834 + select GRKERNSEC_EXECVE
24835 + select GRKERNSEC_RANDNET
24836 + select GRKERNSEC_DMESG
24837 + select GRKERNSEC_CHROOT_CHDIR
24838 + select GRKERNSEC_MODSTOP if (MODULES)
24841 + If you choose this option, several of the grsecurity options will
24842 + be enabled that will give you greater protection against a number
24843 + of attacks, while assuring that none of your software will have any
24844 + conflicts with the additional security measures. If you run a lot
24845 + of unusual software, or you are having problems with the higher
24846 + security levels, you should say Y here. With this option, the
24847 + following features are enabled:
24849 + - Linking restrictions
24850 + - FIFO restrictions
24851 + - Enforcing RLIMIT_NPROC on execve
24852 + - Restricted dmesg
24853 + - Enforced chdir("/") on chroot
24854 + - Runtime module disabling
24856 +config GRKERNSEC_MEDIUM
24859 + select PAX_EI_PAX
24860 + select PAX_PT_PAX_FLAGS
24861 + select PAX_HAVE_ACL_FLAGS
24862 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
24863 + select GRKERNSEC_CHROOT_SYSCTL
24864 + select GRKERNSEC_LINK
24865 + select GRKERNSEC_FIFO
24866 + select GRKERNSEC_EXECVE
24867 + select GRKERNSEC_DMESG
24868 + select GRKERNSEC_RANDNET
24869 + select GRKERNSEC_FORKFAIL
24870 + select GRKERNSEC_TIME
24871 + select GRKERNSEC_SIGNAL
24872 + select GRKERNSEC_CHROOT
24873 + select GRKERNSEC_CHROOT_UNIX
24874 + select GRKERNSEC_CHROOT_MOUNT
24875 + select GRKERNSEC_CHROOT_PIVOT
24876 + select GRKERNSEC_CHROOT_DOUBLE
24877 + select GRKERNSEC_CHROOT_CHDIR
24878 + select GRKERNSEC_CHROOT_MKNOD
24879 + select GRKERNSEC_PROC
24880 + select GRKERNSEC_PROC_USERGROUP
24881 + select GRKERNSEC_MODSTOP if (MODULES)
24882 + select PAX_RANDUSTACK
24884 + select PAX_RANDMMAP
24885 + select PAX_REFCOUNT
24888 + If you say Y here, several features in addition to those included
24889 + in the low additional security level will be enabled. These
24890 + features provide even more security to your system, though in rare
24891 + cases they may be incompatible with very old or poorly written
24892 + software. If you enable this option, make sure that your auth
24893 + service (identd) is running as gid 1001. With this option,
24894 + the following features (in addition to those provided in the
24895 + low additional security level) will be enabled:
24897 + - Failed fork logging
24898 + - Time change logging
24900 + - Deny mounts in chroot
24901 + - Deny double chrooting
24902 + - Deny sysctl writes in chroot
24903 + - Deny mknod in chroot
24904 + - Deny access to abstract AF_UNIX sockets out of chroot
24905 + - Deny pivot_root in chroot
24906 + - Denied writes of /dev/kmem, /dev/mem, and /dev/port
24907 + - /proc restrictions with special GID set to 10 (usually wheel)
24908 + - Address Space Layout Randomization (ASLR)
24910 +config GRKERNSEC_HIGH
24912 + select GRKERNSEC_LINK
24913 + select GRKERNSEC_FIFO
24914 + select GRKERNSEC_EXECVE
24915 + select GRKERNSEC_DMESG
24916 + select GRKERNSEC_FORKFAIL
24917 + select GRKERNSEC_TIME
24918 + select GRKERNSEC_SIGNAL
24919 + select GRKERNSEC_CHROOT_SHMAT
24920 + select GRKERNSEC_CHROOT_UNIX
24921 + select GRKERNSEC_CHROOT_MOUNT
24922 + select GRKERNSEC_CHROOT_FCHDIR
24923 + select GRKERNSEC_CHROOT_PIVOT
24924 + select GRKERNSEC_CHROOT_DOUBLE
24925 + select GRKERNSEC_CHROOT_CHDIR
24926 + select GRKERNSEC_CHROOT_MKNOD
24927 + select GRKERNSEC_CHROOT_CAPS
24928 + select GRKERNSEC_CHROOT_SYSCTL
24929 + select GRKERNSEC_CHROOT_FINDTASK
24930 + select GRKERNSEC_PROC
24931 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
24932 + select GRKERNSEC_HIDESYM
24933 + select GRKERNSEC_BRUTE
24934 + select GRKERNSEC_PROC_USERGROUP
24935 + select GRKERNSEC_KMEM
24936 + select GRKERNSEC_RESLOG
24937 + select GRKERNSEC_RANDNET
24938 + select GRKERNSEC_PROC_ADD
24939 + select GRKERNSEC_CHROOT_CHMOD
24940 + select GRKERNSEC_CHROOT_NICE
24941 + select GRKERNSEC_AUDIT_MOUNT
24942 + select GRKERNSEC_MODSTOP if (MODULES)
24944 + select PAX_RANDUSTACK
24946 + select PAX_RANDMMAP
24947 + select PAX_NOEXEC
24948 + select PAX_MPROTECT
24949 + select PAX_EI_PAX
24950 + select PAX_PT_PAX_FLAGS
24951 + select PAX_HAVE_ACL_FLAGS
24952 + select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
24953 + select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
24954 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
24955 + select PAX_SEGMEXEC if (X86 && !X86_64)
24956 + select PAX_PAGEEXEC if (!X86)
24957 + select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
24958 + select PAX_DLRESOLVE if (SPARC32 || SPARC64)
24959 + select PAX_SYSCALL if (PPC32)
24960 + select PAX_EMUTRAMP if (PARISC)
24961 + select PAX_EMUSIGRT if (PARISC)
24962 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
24963 + select PAX_REFCOUNT
24965 + If you say Y here, many of the features of grsecurity will be
24966 + enabled, which will protect you against many kinds of attacks
24967 + against your system. The heightened security comes at a cost
24968 + of an increased chance of incompatibilities with rare software
24969 + on your machine. Since this security level enables PaX, you should
24970 + view <http://pax.grsecurity.net> and read about the PaX
24971 + project. While you are there, download chpax and run it on
24972 + binaries that cause problems with PaX. Also remember that
24973 + since the /proc restrictions are enabled, you must run your
24974 + identd as gid 1001. This security level enables the following
24975 + features in addition to those listed in the low and medium
24978 + - Additional /proc restrictions
24979 + - Chmod restrictions in chroot
24980 + - No signals, ptrace, or viewing of processes outside of chroot
24981 + - Capability restrictions in chroot
24982 + - Deny fchdir out of chroot
24983 + - Priority restrictions in chroot
24984 + - Segmentation-based implementation of PaX
24985 + - Mprotect restrictions
24986 + - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
24987 + - Kernel stack randomization
24988 + - Mount/unmount/remount logging
24989 + - Kernel symbol hiding
24990 + - Prevention of memory exhaustion-based exploits
24991 +config GRKERNSEC_CUSTOM
24994 + If you say Y here, you will be able to configure every grsecurity
24995 + option, which allows you to enable many more features that aren't
24996 + covered in the basic security levels. These additional features
24997 + include TPE, socket restrictions, and the sysctl system for
24998 + grsecurity. It is advised that you read through the help for
24999 + each option to determine its usefulness in your situation.
25003 +menu "Address Space Protection"
25004 +depends on GRKERNSEC
25006 +config GRKERNSEC_KMEM
25007 + bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
25009 + If you say Y here, /dev/kmem and /dev/mem won't be allowed to
25010 + be written to via mmap or otherwise to modify the running kernel.
25011 + /dev/port will also not be allowed to be opened. If you have module
25012 + support disabled, enabling this will close up four ways that are
25013 + currently used to insert malicious code into the running kernel.
25014 + Even with all these features enabled, we still highly recommend that
25015 + you use the RBAC system, as it is still possible for an attacker to
25016 + modify the running kernel through privileged I/O granted by ioperm/iopl.
25017 + If you are not using XFree86, you may be able to stop this additional
25018 + case by enabling the 'Disable privileged I/O' option. Though nothing
25019 + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
25020 + but only to video memory, which is the only writing we allow in this
25021 + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
25022 + not be allowed to mprotect it with PROT_WRITE later.
25023 + It is highly recommended that you say Y here if you meet all the
25024 + conditions above.
25026 +config GRKERNSEC_IO
25027 + bool "Disable privileged I/O"
25031 + If you say Y here, all ioperm and iopl calls will return an error.
25032 + Ioperm and iopl can be used to modify the running kernel.
25033 + Unfortunately, some programs need this access to operate properly,
25034 + the most notable of which are XFree86 and hwclock. hwclock can be
25035 + remedied by having RTC support in the kernel, so CONFIG_RTC is
25036 + enabled if this option is enabled, to ensure that hwclock operates
25037 + correctly. XFree86 still will not operate correctly with this option
25038 + enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
25039 + and you still want to protect your kernel against modification,
25040 + use the RBAC system.
25042 +config GRKERNSEC_PROC_MEMMAP
25043 + bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
25044 + depends on PAX_NOEXEC || PAX_ASLR
25046 + If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
25047 + give no information about the addresses of its mappings if
25048 + PaX features that rely on random addresses are enabled on the task.
25049 + If you use PaX it is greatly recommended that you say Y here as it
25050 + closes up a hole that makes the full ASLR useless for suid
25053 +config GRKERNSEC_BRUTE
25054 + bool "Deter exploit bruteforcing"
25056 + If you say Y here, attempts to bruteforce exploits against forking
25057 + daemons such as apache or sshd will be deterred. When a child of a
25058 + forking daemon is killed by PaX or crashes due to an illegal
25059 + instruction, the parent process will be delayed 30 seconds upon every
25060 + subsequent fork until the administrator is able to assess the
25061 + situation and restart the daemon. It is recommended that you also
25062 + enable signal logging in the auditing section so that logs are
25063 + generated when a process performs an illegal instruction.
25065 +config GRKERNSEC_MODSTOP
25066 + bool "Runtime module disabling"
25067 + depends on MODULES
25069 + If you say Y here, you will be able to disable the ability to (un)load
25070 + modules at runtime. This feature is useful if you need the ability
25071 + to load kernel modules at boot time, but do not want to allow an
25072 + attacker to load a rootkit kernel module into the system, or to remove
25073 + a loaded kernel module important to system functioning. You should
25074 + enable the /dev/mem protection feature as well, since rootkits can be
25075 + inserted into the kernel via other methods than kernel modules. Since
25076 + an untrusted module could still be loaded by modifying init scripts and
25077 + rebooting the system, it is also recommended that you enable the RBAC
25078 + system. If you enable this option, a sysctl option with name
25079 + "disable_modules" will be created. Setting this option to "1" disables
25080 + module loading. After this option is set, no further writes to it are
25081 + allowed until the system is rebooted.
25083 +config GRKERNSEC_HIDESYM
25084 + bool "Hide kernel symbols"
25086 + If you say Y here, getting information on loaded modules, and
25087 + displaying all kernel symbols through a syscall will be restricted
25088 + to users with CAP_SYS_MODULE. This option is only effective
25089 + provided the following conditions are met:
25090 + 1) The kernel using grsecurity is not precompiled by some distribution
25091 + 2) You are using the RBAC system and hiding other files such as your
25092 + kernel image and System.map
25093 + 3) You have the additional /proc restrictions enabled, which removes
25095 + If the above conditions are met, this option will aid to provide a
25096 + useful protection against local and remote kernel exploitation of
25097 + overflows and arbitrary read/write vulnerabilities.
25100 +menu "Role Based Access Control Options"
25101 +depends on GRKERNSEC
25103 +config GRKERNSEC_ACL_HIDEKERN
25104 + bool "Hide kernel processes"
25106 + If you say Y here, all kernel threads will be hidden to all
25107 + processes but those whose subject has the "view hidden processes"
25110 +config GRKERNSEC_ACL_MAXTRIES
25111 + int "Maximum tries before password lockout"
25114 + This option enforces the maximum number of times a user can attempt
25115 + to authorize themselves with the grsecurity RBAC system before being
25116 + denied the ability to attempt authorization again for a specified time.
25117 + The lower the number, the harder it will be to brute-force a password.
25119 +config GRKERNSEC_ACL_TIMEOUT
25120 + int "Time to wait after max password tries, in seconds"
25123 + This option specifies the time the user must wait after attempting to
25124 + authorize to the RBAC system with the maximum number of invalid
25125 + passwords. The higher the number, the harder it will be to brute-force
25129 +menu "Filesystem Protections"
25130 +depends on GRKERNSEC
25132 +config GRKERNSEC_PROC
25133 + bool "Proc restrictions"
25135 + If you say Y here, the permissions of the /proc filesystem
25136 + will be altered to enhance system security and privacy. You MUST
25137 + choose either a user only restriction or a user and group restriction.
25138 + Depending upon the option you choose, you can either restrict users to
25139 + see only the processes they themselves run, or choose a group that can
25140 + view all processes and files normally restricted to root if you choose
25141 + the "restrict to user only" option. NOTE: If you're running identd as
25142 + a non-root user, you will have to run it as the group you specify here.
25144 +config GRKERNSEC_PROC_USER
25145 + bool "Restrict /proc to user only"
25146 + depends on GRKERNSEC_PROC
25148 + If you say Y here, non-root users will only be able to view their own
25149 + processes, and restricts them from viewing network-related information,
25150 + and viewing kernel symbol and module information.
25152 +config GRKERNSEC_PROC_USERGROUP
25153 + bool "Allow special group"
25154 + depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
25156 + If you say Y here, you will be able to select a group that will be
25157 + able to view all processes, network-related information, and
25158 + kernel and symbol information. This option is useful if you want
25159 + to run identd as a non-root user.
25161 +config GRKERNSEC_PROC_GID
25162 + int "GID for special group"
25163 + depends on GRKERNSEC_PROC_USERGROUP
25166 +config GRKERNSEC_PROC_ADD
25167 + bool "Additional restrictions"
25168 + depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
25170 + If you say Y here, additional restrictions will be placed on
25171 + /proc that keep normal users from viewing device information and
25172 + slabinfo information that could be useful for exploits.
25174 +config GRKERNSEC_LINK
25175 + bool "Linking restrictions"
25177 + If you say Y here, /tmp race exploits will be prevented, since users
25178 + will no longer be able to follow symlinks owned by other users in
25179 + world-writable +t directories (i.e. /tmp), unless the owner of the
25180 + symlink is the owner of the directory. users will also not be
25181 + able to hardlink to files they do not own. If the sysctl option is
25182 + enabled, a sysctl option with name "linking_restrictions" is created.
25184 +config GRKERNSEC_FIFO
25185 + bool "FIFO restrictions"
25187 + If you say Y here, users will not be able to write to FIFOs they don't
25188 + own in world-writable +t directories (i.e. /tmp), unless the owner of
25189 + the FIFO is the same owner of the directory it's held in. If the sysctl
25190 + option is enabled, a sysctl option with name "fifo_restrictions" is
25193 +config GRKERNSEC_CHROOT
25194 + bool "Chroot jail restrictions"
25196 + If you say Y here, you will be able to choose several options that will
25197 + make breaking out of a chrooted jail much more difficult. If you
25198 + encounter no software incompatibilities with the following options, it
25199 + is recommended that you enable each one.
25201 +config GRKERNSEC_CHROOT_MOUNT
25202 + bool "Deny mounts"
25203 + depends on GRKERNSEC_CHROOT
25205 + If you say Y here, processes inside a chroot will not be able to
25206 + mount or remount filesystems. If the sysctl option is enabled, a
25207 + sysctl option with name "chroot_deny_mount" is created.
25209 +config GRKERNSEC_CHROOT_DOUBLE
25210 + bool "Deny double-chroots"
25211 + depends on GRKERNSEC_CHROOT
25213 + If you say Y here, processes inside a chroot will not be able to chroot
25214 + again outside the chroot. This is a widely used method of breaking
25215 + out of a chroot jail and should not be allowed. If the sysctl
25216 + option is enabled, a sysctl option with name
25217 + "chroot_deny_chroot" is created.
25219 +config GRKERNSEC_CHROOT_PIVOT
25220 + bool "Deny pivot_root in chroot"
25221 + depends on GRKERNSEC_CHROOT
25223 + If you say Y here, processes inside a chroot will not be able to use
25224 + a function called pivot_root() that was introduced in Linux 2.3.41. It
25225 + works similar to chroot in that it changes the root filesystem. This
25226 + function could be misused in a chrooted process to attempt to break out
25227 + of the chroot, and therefore should not be allowed. If the sysctl
25228 + option is enabled, a sysctl option with name "chroot_deny_pivot" is
25231 +config GRKERNSEC_CHROOT_CHDIR
25232 + bool "Enforce chdir(\"/\") on all chroots"
25233 + depends on GRKERNSEC_CHROOT
25235 + If you say Y here, the current working directory of all newly-chrooted
25236 + applications will be set to the the root directory of the chroot.
25237 + The man page on chroot(2) states:
25238 + Note that this call does not change the current working
25239 + directory, so that `.' can be outside the tree rooted at
25240 + `/'. In particular, the super-user can escape from a
25241 + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
25243 + It is recommended that you say Y here, since it's not known to break
25244 + any software. If the sysctl option is enabled, a sysctl option with
25245 + name "chroot_enforce_chdir" is created.
25247 +config GRKERNSEC_CHROOT_CHMOD
25248 + bool "Deny (f)chmod +s"
25249 + depends on GRKERNSEC_CHROOT
25251 + If you say Y here, processes inside a chroot will not be able to chmod
25252 + or fchmod files to make them have suid or sgid bits. This protects
25253 + against another published method of breaking a chroot. If the sysctl
25254 + option is enabled, a sysctl option with name "chroot_deny_chmod" is
25257 +config GRKERNSEC_CHROOT_FCHDIR
25258 + bool "Deny fchdir out of chroot"
25259 + depends on GRKERNSEC_CHROOT
25261 + If you say Y here, a well-known method of breaking chroots by fchdir'ing
25262 + to a file descriptor of the chrooting process that points to a directory
25263 + outside the filesystem will be stopped. If the sysctl option
25264 + is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
25266 +config GRKERNSEC_CHROOT_MKNOD
25267 + bool "Deny mknod"
25268 + depends on GRKERNSEC_CHROOT
25270 + If you say Y here, processes inside a chroot will not be allowed to
25271 + mknod. The problem with using mknod inside a chroot is that it
25272 + would allow an attacker to create a device entry that is the same
25273 + as one on the physical root of your system, which could range from
25274 + anything from the console device to a device for your harddrive (which
25275 + they could then use to wipe the drive or steal data). It is recommended
25276 + that you say Y here, unless you run into software incompatibilities.
25277 + If the sysctl option is enabled, a sysctl option with name
25278 + "chroot_deny_mknod" is created.
25280 +config GRKERNSEC_CHROOT_SHMAT
25281 + bool "Deny shmat() out of chroot"
25282 + depends on GRKERNSEC_CHROOT
25284 + If you say Y here, processes inside a chroot will not be able to attach
25285 + to shared memory segments that were created outside of the chroot jail.
25286 + It is recommended that you say Y here. If the sysctl option is enabled,
25287 + a sysctl option with name "chroot_deny_shmat" is created.
25289 +config GRKERNSEC_CHROOT_UNIX
25290 + bool "Deny access to abstract AF_UNIX sockets out of chroot"
25291 + depends on GRKERNSEC_CHROOT
25293 + If you say Y here, processes inside a chroot will not be able to
25294 + connect to abstract (meaning not belonging to a filesystem) Unix
25295 + domain sockets that were bound outside of a chroot. It is recommended
25296 + that you say Y here. If the sysctl option is enabled, a sysctl option
25297 + with name "chroot_deny_unix" is created.
25299 +config GRKERNSEC_CHROOT_FINDTASK
25300 + bool "Protect outside processes"
25301 + depends on GRKERNSEC_CHROOT
25303 + If you say Y here, processes inside a chroot will not be able to
25304 + kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
25305 + or view any process outside of the chroot. If the sysctl
25306 + option is enabled, a sysctl option with name "chroot_findtask" is
25309 +config GRKERNSEC_CHROOT_NICE
25310 + bool "Restrict priority changes"
25311 + depends on GRKERNSEC_CHROOT
25313 + If you say Y here, processes inside a chroot will not be able to raise
25314 + the priority of processes in the chroot, or alter the priority of
25315 + processes outside the chroot. This provides more security than simply
25316 + removing CAP_SYS_NICE from the process' capability set. If the
25317 + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
25320 +config GRKERNSEC_CHROOT_SYSCTL
25321 + bool "Deny sysctl writes"
25322 + depends on GRKERNSEC_CHROOT
25324 + If you say Y here, an attacker in a chroot will not be able to
25325 + write to sysctl entries, either by sysctl(2) or through a /proc
25326 + interface. It is strongly recommended that you say Y here. If the
25327 + sysctl option is enabled, a sysctl option with name
25328 + "chroot_deny_sysctl" is created.
25330 +config GRKERNSEC_CHROOT_CAPS
25331 + bool "Capability restrictions"
25332 + depends on GRKERNSEC_CHROOT
25334 + If you say Y here, the capabilities on all root processes within a
25335 + chroot jail will be lowered to stop module insertion, raw i/o,
25336 + system and net admin tasks, rebooting the system, modifying immutable
25337 + files, modifying IPC owned by another, and changing the system time.
25338 + This is left an option because it can break some apps. Disable this
25339 + if your chrooted apps are having problems performing those kinds of
25340 + tasks. If the sysctl option is enabled, a sysctl option with
25341 + name "chroot_caps" is created.
25344 +menu "Kernel Auditing"
25345 +depends on GRKERNSEC
25347 +config GRKERNSEC_AUDIT_GROUP
25348 + bool "Single group for auditing"
25350 + If you say Y here, the exec, chdir, (un)mount, and ipc logging features
25351 + will only operate on a group you specify. This option is recommended
25352 + if you only want to watch certain users instead of having a large
25353 + amount of logs from the entire system. If the sysctl option is enabled,
25354 + a sysctl option with name "audit_group" is created.
25356 +config GRKERNSEC_AUDIT_GID
25357 + int "GID for auditing"
25358 + depends on GRKERNSEC_AUDIT_GROUP
25361 +config GRKERNSEC_EXECLOG
25362 + bool "Exec logging"
25364 + If you say Y here, all execve() calls will be logged (since the
25365 + other exec*() calls are frontends to execve(), all execution
25366 + will be logged). Useful for shell-servers that like to keep track
25367 + of their users. If the sysctl option is enabled, a sysctl option with
25368 + name "exec_logging" is created.
25369 + WARNING: This option when enabled will produce a LOT of logs, especially
25370 + on an active system.
25372 +config GRKERNSEC_RESLOG
25373 + bool "Resource logging"
25375 + If you say Y here, all attempts to overstep resource limits will
25376 + be logged with the resource name, the requested size, and the current
25377 + limit. It is highly recommended that you say Y here. If the sysctl
25378 + option is enabled, a sysctl option with name "resource_logging" is
25379 + created. If the RBAC system is enabled, the sysctl value is ignored.
25381 +config GRKERNSEC_CHROOT_EXECLOG
25382 + bool "Log execs within chroot"
25384 + If you say Y here, all executions inside a chroot jail will be logged
25385 + to syslog. This can cause a large amount of logs if certain
25386 + applications (eg. djb's daemontools) are installed on the system, and
25387 + is therefore left as an option. If the sysctl option is enabled, a
25388 + sysctl option with name "chroot_execlog" is created.
25390 +config GRKERNSEC_AUDIT_CHDIR
25391 + bool "Chdir logging"
25393 + If you say Y here, all chdir() calls will be logged. If the sysctl
25394 + option is enabled, a sysctl option with name "audit_chdir" is created.
25396 +config GRKERNSEC_AUDIT_MOUNT
25397 + bool "(Un)Mount logging"
25399 + If you say Y here, all mounts and unmounts will be logged. If the
25400 + sysctl option is enabled, a sysctl option with name "audit_mount" is
25403 +config GRKERNSEC_AUDIT_IPC
25404 + bool "IPC logging"
25406 + If you say Y here, creation and removal of message queues, semaphores,
25407 + and shared memory will be logged. If the sysctl option is enabled, a
25408 + sysctl option with name "audit_ipc" is created.
25410 +config GRKERNSEC_SIGNAL
25411 + bool "Signal logging"
25413 + If you say Y here, certain important signals will be logged, such as
25414 + SIGSEGV, which will as a result inform you of when a error in a program
25415 + occurred, which in some cases could mean a possible exploit attempt.
25416 + If the sysctl option is enabled, a sysctl option with name
25417 + "signal_logging" is created.
25419 +config GRKERNSEC_FORKFAIL
25420 + bool "Fork failure logging"
25422 + If you say Y here, all failed fork() attempts will be logged.
25423 + This could suggest a fork bomb, or someone attempting to overstep
25424 + their process limit. If the sysctl option is enabled, a sysctl option
25425 + with name "forkfail_logging" is created.
25427 +config GRKERNSEC_TIME
25428 + bool "Time change logging"
25430 + If you say Y here, any changes of the system clock will be logged.
25431 + If the sysctl option is enabled, a sysctl option with name
25432 + "timechange_logging" is created.
25434 +config GRKERNSEC_PROC_IPADDR
25435 + bool "/proc/<pid>/ipaddr support"
25437 + If you say Y here, a new entry will be added to each /proc/<pid>
25438 + directory that contains the IP address of the person using the task.
25439 + The IP is carried across local TCP and AF_UNIX stream sockets.
25440 + This information can be useful for IDS/IPSes to perform remote response
25441 + to a local attack. The entry is readable by only the owner of the
25442 + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
25443 + the RBAC system), and thus does not create privacy concerns.
25445 +config GRKERNSEC_AUDIT_TEXTREL
25446 + bool 'ELF text relocations logging (READ HELP)'
25447 + depends on PAX_MPROTECT
25449 + If you say Y here, text relocations will be logged with the filename
25450 + of the offending library or binary. The purpose of the feature is
25451 + to help Linux distribution developers get rid of libraries and
25452 + binaries that need text relocations which hinder the future progress
25453 + of PaX. Only Linux distribution developers should say Y here, and
25454 + never on a production machine, as this option creates an information
25455 + leak that could aid an attacker in defeating the randomization of
25456 + a single memory region. If the sysctl option is enabled, a sysctl
25457 + option with name "audit_textrel" is created.
25461 +menu "Executable Protections"
25462 +depends on GRKERNSEC
25464 +config GRKERNSEC_EXECVE
25465 + bool "Enforce RLIMIT_NPROC on execs"
25467 + If you say Y here, users with a resource limit on processes will
25468 + have the value checked during execve() calls. The current system
25469 + only checks the system limit during fork() calls. If the sysctl option
25470 + is enabled, a sysctl option with name "execve_limiting" is created.
25472 +config GRKERNSEC_DMESG
25473 + bool "Dmesg(8) restriction"
25475 + If you say Y here, non-root users will not be able to use dmesg(8)
25476 + to view up to the last 4kb of messages in the kernel's log buffer.
25477 + If the sysctl option is enabled, a sysctl option with name "dmesg" is
25480 +config GRKERNSEC_TPE
25481 + bool "Trusted Path Execution (TPE)"
25483 + If you say Y here, you will be able to choose a gid to add to the
25484 + supplementary groups of users you want to mark as "untrusted."
25485 + These users will not be able to execute any files that are not in
25486 + root-owned directories writable only by root. If the sysctl option
25487 + is enabled, a sysctl option with name "tpe" is created.
25489 +config GRKERNSEC_TPE_ALL
25490 + bool "Partially restrict non-root users"
25491 + depends on GRKERNSEC_TPE
25493 + If you say Y here, All non-root users other than the ones in the
25494 + group specified in the main TPE option will only be allowed to
25495 + execute files in directories they own that are not group or
25496 + world-writable, or in directories owned by root and writable only by
25497 + root. If the sysctl option is enabled, a sysctl option with name
25498 + "tpe_restrict_all" is created.
25500 +config GRKERNSEC_TPE_INVERT
25501 + bool "Invert GID option"
25502 + depends on GRKERNSEC_TPE
25504 + If you say Y here, the group you specify in the TPE configuration will
25505 + decide what group TPE restrictions will be *disabled* for. This
25506 + option is useful if you want TPE restrictions to be applied to most
25507 + users on the system.
25509 +config GRKERNSEC_TPE_GID
25510 + int "GID for untrusted users"
25511 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
25514 + If you have selected the "Invert GID option" above, setting this
25515 + GID determines what group TPE restrictions will be *disabled* for.
25516 + If you have not selected the "Invert GID option" above, setting this
25517 + GID determines what group TPE restrictions will be *enabled* for.
25518 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
25521 +config GRKERNSEC_TPE_GID
25522 + int "GID for trusted users"
25523 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
25526 + If you have selected the "Invert GID option" above, setting this
25527 + GID determines what group TPE restrictions will be *disabled* for.
25528 + If you have not selected the "Invert GID option" above, setting this
25529 + GID determines what group TPE restrictions will be *enabled* for.
25530 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
25534 +menu "Network Protections"
25535 +depends on GRKERNSEC
25537 +config GRKERNSEC_RANDNET
25538 + bool "Larger entropy pools"
25540 + If you say Y here, the entropy pools used for many features of Linux
25541 + and grsecurity will be doubled in size. Since several grsecurity
25542 + features use additional randomness, it is recommended that you say Y
25543 + here. Saying Y here has a similar effect as modifying
25544 + /proc/sys/kernel/random/poolsize.
25546 +config GRKERNSEC_SOCKET
25547 + bool "Socket restrictions"
25549 + If you say Y here, you will be able to choose from several options.
25550 + If you assign a GID on your system and add it to the supplementary
25551 + groups of users you want to restrict socket access to, this patch
25552 + will perform up to three things, based on the option(s) you choose.
25554 +config GRKERNSEC_SOCKET_ALL
25555 + bool "Deny any sockets to group"
25556 + depends on GRKERNSEC_SOCKET
25558 + If you say Y here, you will be able to choose a GID of whose users will
25559 + be unable to connect to other hosts from your machine or run server
25560 + applications from your machine. If the sysctl option is enabled, a
25561 + sysctl option with name "socket_all" is created.
25563 +config GRKERNSEC_SOCKET_ALL_GID
25564 + int "GID to deny all sockets for"
25565 + depends on GRKERNSEC_SOCKET_ALL
25568 + Here you can choose the GID to disable socket access for. Remember to
25569 + add the users you want socket access disabled for to the GID
25570 + specified here. If the sysctl option is enabled, a sysctl option
25571 + with name "socket_all_gid" is created.
25573 +config GRKERNSEC_SOCKET_CLIENT
25574 + bool "Deny client sockets to group"
25575 + depends on GRKERNSEC_SOCKET
25577 + If you say Y here, you will be able to choose a GID of whose users will
25578 + be unable to connect to other hosts from your machine, but will be
25579 + able to run servers. If this option is enabled, all users in the group
25580 + you specify will have to use passive mode when initiating ftp transfers
25581 + from the shell on your machine. If the sysctl option is enabled, a
25582 + sysctl option with name "socket_client" is created.
25584 +config GRKERNSEC_SOCKET_CLIENT_GID
25585 + int "GID to deny client sockets for"
25586 + depends on GRKERNSEC_SOCKET_CLIENT
25589 + Here you can choose the GID to disable client socket access for.
25590 + Remember to add the users you want client socket access disabled for to
25591 + the GID specified here. If the sysctl option is enabled, a sysctl
25592 + option with name "socket_client_gid" is created.
25594 +config GRKERNSEC_SOCKET_SERVER
25595 + bool "Deny server sockets to group"
25596 + depends on GRKERNSEC_SOCKET
25598 + If you say Y here, you will be able to choose a GID of whose users will
25599 + be unable to run server applications from your machine. If the sysctl
25600 + option is enabled, a sysctl option with name "socket_server" is created.
25602 +config GRKERNSEC_SOCKET_SERVER_GID
25603 + int "GID to deny server sockets for"
25604 + depends on GRKERNSEC_SOCKET_SERVER
25607 + Here you can choose the GID to disable server socket access for.
25608 + Remember to add the users you want server socket access disabled for to
25609 + the GID specified here. If the sysctl option is enabled, a sysctl
25610 + option with name "socket_server_gid" is created.
25613 +menu "Sysctl support"
25614 +depends on GRKERNSEC && SYSCTL
25616 +config GRKERNSEC_SYSCTL
25617 + bool "Sysctl support"
25619 + If you say Y here, you will be able to change the options that
25620 + grsecurity runs with at bootup, without having to recompile your
25621 + kernel. You can echo values to files in /proc/sys/kernel/grsecurity
25622 + to enable (1) or disable (0) various features. All the sysctl entries
25623 + are mutable until the "grsec_lock" entry is set to a non-zero value.
25624 + All features enabled in the kernel configuration are disabled at boot
25625 + if you do not say Y to the "Turn on features by default" option.
25626 + All options should be set at startup, and the grsec_lock entry should
25627 + be set to a non-zero value after all the options are set.
25628 + *THIS IS EXTREMELY IMPORTANT*
25630 +config GRKERNSEC_SYSCTL_ON
25631 + bool "Turn on features by default"
25632 + depends on GRKERNSEC_SYSCTL
25634 + If you say Y here, instead of having all features enabled in the
25635 + kernel configuration disabled at boot time, the features will be
25636 + enabled at boot time. It is recommended you say Y here unless
25637 + there is some reason you would want all sysctl-tunable features to
25638 + be disabled by default. As mentioned elsewhere, it is important
25639 + to enable the grsec_lock entry once you have finished modifying
25640 + the sysctl entries.
25643 +menu "Logging Options"
25644 +depends on GRKERNSEC
25646 +config GRKERNSEC_FLOODTIME
25647 + int "Seconds in between log messages (minimum)"
25650 + This option allows you to enforce the number of seconds between
25651 + grsecurity log messages. The default should be suitable for most
25652 + people, however, if you choose to change it, choose a value small enough
25653 + to allow informative logs to be produced, but large enough to
25654 + prevent flooding.
25656 +config GRKERNSEC_FLOODBURST
25657 + int "Number of messages in a burst (maximum)"
25660 + This option allows you to choose the maximum number of messages allowed
25661 + within the flood time interval you chose in a separate option. The
25662 + default should be suitable for most people, however if you find that
25663 + many of your logs are being interpreted as flooding, you may want to
25664 + raise this value.
25669 diff -urNp linux-2.6.27.4/grsecurity/Makefile linux-2.6.27.4/grsecurity/Makefile
25670 --- linux-2.6.27.4/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
25671 +++ linux-2.6.27.4/grsecurity/Makefile 2008-10-25 12:03:07.000000000 -0400
25673 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
25674 +# during 2001-2005 it has been completely redesigned by Brad Spengler
25675 +# into an RBAC system
25677 +# All code in this directory and various hooks inserted throughout the kernel
25678 +# are copyright Brad Spengler, and released under the GPL v2 or higher
25680 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
25681 + grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
25682 + grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
25684 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
25685 + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
25686 + gracl_learn.o grsec_log.o
25687 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
25689 +ifndef CONFIG_GRKERNSEC
25690 +obj-y += grsec_disabled.o
25693 diff -urNp linux-2.6.27.4/include/asm-cris/kmap_types.h linux-2.6.27.4/include/asm-cris/kmap_types.h
25694 --- linux-2.6.27.4/include/asm-cris/kmap_types.h 2008-10-22 17:38:01.000000000 -0400
25695 +++ linux-2.6.27.4/include/asm-cris/kmap_types.h 2008-10-27 22:36:18.000000000 -0400
25696 @@ -19,6 +19,7 @@ enum km_type {
25704 diff -urNp linux-2.6.27.4/include/asm-frv/kmap_types.h linux-2.6.27.4/include/asm-frv/kmap_types.h
25705 --- linux-2.6.27.4/include/asm-frv/kmap_types.h 2008-10-22 17:38:01.000000000 -0400
25706 +++ linux-2.6.27.4/include/asm-frv/kmap_types.h 2008-10-27 22:36:18.000000000 -0400
25707 @@ -23,6 +23,7 @@ enum km_type {
25715 diff -urNp linux-2.6.27.4/include/asm-generic/futex.h linux-2.6.27.4/include/asm-generic/futex.h
25716 --- linux-2.6.27.4/include/asm-generic/futex.h 2008-10-22 17:38:01.000000000 -0400
25717 +++ linux-2.6.27.4/include/asm-generic/futex.h 2008-10-27 22:36:18.000000000 -0400
25719 #include <asm/errno.h>
25722 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
25723 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
25725 int op = (encoded_op >> 28) & 7;
25726 int cmp = (encoded_op >> 24) & 15;
25727 @@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
25731 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
25732 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
25736 diff -urNp linux-2.6.27.4/include/asm-generic/vmlinux.lds.h linux-2.6.27.4/include/asm-generic/vmlinux.lds.h
25737 --- linux-2.6.27.4/include/asm-generic/vmlinux.lds.h 2008-10-22 17:38:01.000000000 -0400
25738 +++ linux-2.6.27.4/include/asm-generic/vmlinux.lds.h 2008-10-27 22:36:18.000000000 -0400
25740 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
25741 VMLINUX_SYMBOL(__start_rodata) = .; \
25742 *(.rodata) *(.rodata.*) \
25743 + *(.data.read_only) \
25744 *(__vermagic) /* Kernel version magic */ \
25745 *(__markers_strings) /* Markers: strings */ \
25747 diff -urNp linux-2.6.27.4/include/asm-m32r/kmap_types.h linux-2.6.27.4/include/asm-m32r/kmap_types.h
25748 --- linux-2.6.27.4/include/asm-m32r/kmap_types.h 2008-10-22 17:38:01.000000000 -0400
25749 +++ linux-2.6.27.4/include/asm-m32r/kmap_types.h 2008-10-27 22:36:18.000000000 -0400
25750 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
25755 +D(13) KM_CLEARPAGE,
25760 diff -urNp linux-2.6.27.4/include/asm-m68k/kmap_types.h linux-2.6.27.4/include/asm-m68k/kmap_types.h
25761 --- linux-2.6.27.4/include/asm-m68k/kmap_types.h 2008-10-22 17:38:01.000000000 -0400
25762 +++ linux-2.6.27.4/include/asm-m68k/kmap_types.h 2008-10-27 22:36:18.000000000 -0400
25763 @@ -15,6 +15,7 @@ enum km_type {
25771 diff -urNp linux-2.6.27.4/include/asm-mips/elf.h linux-2.6.27.4/include/asm-mips/elf.h
25772 --- linux-2.6.27.4/include/asm-mips/elf.h 2008-10-22 17:38:01.000000000 -0400
25773 +++ linux-2.6.27.4/include/asm-mips/elf.h 2008-10-27 22:36:18.000000000 -0400
25774 @@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
25775 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
25778 +#ifdef CONFIG_PAX_ASLR
25779 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
25781 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
25782 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
25785 #endif /* _ASM_ELF_H */
25786 diff -urNp linux-2.6.27.4/include/asm-mips/kmap_types.h linux-2.6.27.4/include/asm-mips/kmap_types.h
25787 --- linux-2.6.27.4/include/asm-mips/kmap_types.h 2008-10-22 17:38:01.000000000 -0400
25788 +++ linux-2.6.27.4/include/asm-mips/kmap_types.h 2008-10-27 22:36:18.000000000 -0400
25789 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
25794 +D(13) KM_CLEARPAGE,
25799 diff -urNp linux-2.6.27.4/include/asm-mips/page.h linux-2.6.27.4/include/asm-mips/page.h
25800 --- linux-2.6.27.4/include/asm-mips/page.h 2008-10-22 17:38:01.000000000 -0400
25801 +++ linux-2.6.27.4/include/asm-mips/page.h 2008-10-27 22:36:18.000000000 -0400
25802 @@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
25803 #ifdef CONFIG_CPU_MIPS32
25804 typedef struct { unsigned long pte_low, pte_high; } pte_t;
25805 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
25806 - #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
25807 + #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
25809 typedef struct { unsigned long long pte; } pte_t;
25810 #define pte_val(x) ((x).pte)
25811 diff -urNp linux-2.6.27.4/include/asm-mips/system.h linux-2.6.27.4/include/asm-mips/system.h
25812 --- linux-2.6.27.4/include/asm-mips/system.h 2008-10-22 17:38:01.000000000 -0400
25813 +++ linux-2.6.27.4/include/asm-mips/system.h 2008-10-27 22:36:18.000000000 -0400
25814 @@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
25816 #define __ARCH_WANT_UNLOCKED_CTXSW
25818 -extern unsigned long arch_align_stack(unsigned long sp);
25819 +#define arch_align_stack(x) ((x) & ALMASK)
25821 #endif /* _ASM_SYSTEM_H */
25822 diff -urNp linux-2.6.27.4/include/asm-parisc/elf.h linux-2.6.27.4/include/asm-parisc/elf.h
25823 --- linux-2.6.27.4/include/asm-parisc/elf.h 2008-10-22 17:38:01.000000000 -0400
25824 +++ linux-2.6.27.4/include/asm-parisc/elf.h 2008-10-27 22:36:18.000000000 -0400
25825 @@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
25827 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
25829 +#ifdef CONFIG_PAX_ASLR
25830 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
25832 +#define PAX_DELTA_MMAP_LEN 16
25833 +#define PAX_DELTA_STACK_LEN 16
25836 /* This yields a mask that user programs can use to figure out what
25837 instruction set this CPU supports. This could be done in user space,
25838 but it's not easy, and we've already done it here. */
25839 diff -urNp linux-2.6.27.4/include/asm-parisc/kmap_types.h linux-2.6.27.4/include/asm-parisc/kmap_types.h
25840 --- linux-2.6.27.4/include/asm-parisc/kmap_types.h 2008-10-22 17:38:01.000000000 -0400
25841 +++ linux-2.6.27.4/include/asm-parisc/kmap_types.h 2008-10-27 22:36:18.000000000 -0400
25842 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
25847 +D(13) KM_CLEARPAGE,
25852 diff -urNp linux-2.6.27.4/include/asm-parisc/pgtable.h linux-2.6.27.4/include/asm-parisc/pgtable.h
25853 --- linux-2.6.27.4/include/asm-parisc/pgtable.h 2008-10-22 17:38:01.000000000 -0400
25854 +++ linux-2.6.27.4/include/asm-parisc/pgtable.h 2008-10-27 22:36:18.000000000 -0400
25855 @@ -202,6 +202,17 @@
25856 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
25857 #define PAGE_COPY PAGE_EXECREAD
25858 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
25860 +#ifdef CONFIG_PAX_PAGEEXEC
25861 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
25862 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
25863 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
25865 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
25866 +# define PAGE_COPY_NOEXEC PAGE_COPY
25867 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
25870 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
25871 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
25872 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
25873 diff -urNp linux-2.6.27.4/include/asm-um/kmap_types.h linux-2.6.27.4/include/asm-um/kmap_types.h
25874 --- linux-2.6.27.4/include/asm-um/kmap_types.h 2008-10-22 17:38:01.000000000 -0400
25875 +++ linux-2.6.27.4/include/asm-um/kmap_types.h 2008-10-27 22:36:18.000000000 -0400
25876 @@ -23,6 +23,7 @@ enum km_type {
25884 diff -urNp linux-2.6.27.4/include/asm-um/page.h linux-2.6.27.4/include/asm-um/page.h
25885 --- linux-2.6.27.4/include/asm-um/page.h 2008-10-22 17:38:01.000000000 -0400
25886 +++ linux-2.6.27.4/include/asm-um/page.h 2008-10-27 22:36:18.000000000 -0400
25888 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
25889 #define PAGE_MASK (~(PAGE_SIZE-1))
25891 +#define ktla_ktva(addr) (addr)
25892 +#define ktva_ktla(addr) (addr)
25894 #ifndef __ASSEMBLY__
25897 diff -urNp linux-2.6.27.4/include/asm-x86/alternative.h linux-2.6.27.4/include/asm-x86/alternative.h
25898 --- linux-2.6.27.4/include/asm-x86/alternative.h 2008-10-22 17:38:01.000000000 -0400
25899 +++ linux-2.6.27.4/include/asm-x86/alternative.h 2008-10-27 22:36:18.000000000 -0400
25900 @@ -96,7 +96,7 @@ const unsigned char *const *find_nop_tab
25901 " .byte 662b-661b\n" /* sourcelen */ \
25902 " .byte 664f-663f\n" /* replacementlen */ \
25904 - ".section .altinstr_replacement,\"ax\"\n" \
25905 + ".section .altinstr_replacement,\"a\"\n" \
25906 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
25907 ".previous" :: "i" (feature) : "memory")
25909 @@ -120,7 +120,7 @@ const unsigned char *const *find_nop_tab
25910 " .byte 662b-661b\n" /* sourcelen */ \
25911 " .byte 664f-663f\n" /* replacementlen */ \
25913 - ".section .altinstr_replacement,\"ax\"\n" \
25914 + ".section .altinstr_replacement,\"a\"\n" \
25915 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
25916 ".previous" :: "i" (feature), ##input)
25918 @@ -135,7 +135,7 @@ const unsigned char *const *find_nop_tab
25919 " .byte 662b-661b\n" /* sourcelen */ \
25920 " .byte 664f-663f\n" /* replacementlen */ \
25922 - ".section .altinstr_replacement,\"ax\"\n" \
25923 + ".section .altinstr_replacement,\"a\"\n" \
25924 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
25925 ".previous" : output : [feat] "i" (feature), ##input)
25927 diff -urNp linux-2.6.27.4/include/asm-x86/atomic_32.h linux-2.6.27.4/include/asm-x86/atomic_32.h
25928 --- linux-2.6.27.4/include/asm-x86/atomic_32.h 2008-10-22 17:38:01.000000000 -0400
25929 +++ linux-2.6.27.4/include/asm-x86/atomic_32.h 2008-10-27 22:36:18.000000000 -0400
25930 @@ -47,7 +47,15 @@ typedef struct {
25932 static inline void atomic_add(int i, atomic_t *v)
25934 - asm volatile(LOCK_PREFIX "addl %1,%0"
25935 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
25937 +#ifdef CONFIG_PAX_REFCOUNT
25939 + LOCK_PREFIX "subl %1,%0\n"
25941 + _ASM_EXTABLE(0b, 0b)
25944 : "+m" (v->counter)
25947 @@ -61,7 +69,15 @@ static inline void atomic_add(int i, ato
25949 static inline void atomic_sub(int i, atomic_t *v)
25951 - asm volatile(LOCK_PREFIX "subl %1,%0"
25952 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
25954 +#ifdef CONFIG_PAX_REFCOUNT
25956 + LOCK_PREFIX "addl %1,%0\n"
25958 + _ASM_EXTABLE(0b, 0b)
25961 : "+m" (v->counter)
25964 @@ -79,7 +95,16 @@ static inline int atomic_sub_and_test(in
25968 - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
25969 + asm volatile(LOCK_PREFIX "subl %2,%0\n"
25971 +#ifdef CONFIG_PAX_REFCOUNT
25973 + LOCK_PREFIX "addl %2,%0\n"
25975 + _ASM_EXTABLE(0b, 0b)
25979 : "+m" (v->counter), "=qm" (c)
25980 : "ir" (i) : "memory");
25982 @@ -93,7 +118,18 @@ static inline int atomic_sub_and_test(in
25984 static inline void atomic_inc(atomic_t *v)
25986 - asm volatile(LOCK_PREFIX "incl %0"
25987 + asm volatile(LOCK_PREFIX "incl %0\n"
25989 +#ifdef CONFIG_PAX_REFCOUNT
25991 + ".pushsection .fixup,\"ax\"\n"
25993 + LOCK_PREFIX "decl %0\n"
25996 + _ASM_EXTABLE(0b, 1b)
25999 : "+m" (v->counter));
26002 @@ -105,7 +141,18 @@ static inline void atomic_inc(atomic_t *
26004 static inline void atomic_dec(atomic_t *v)
26006 - asm volatile(LOCK_PREFIX "decl %0"
26007 + asm volatile(LOCK_PREFIX "decl %0\n"
26009 +#ifdef CONFIG_PAX_REFCOUNT
26011 + ".pushsection .fixup,\"ax\"\n"
26013 + LOCK_PREFIX "incl %0\n"
26016 + _ASM_EXTABLE(0b, 1b)
26019 : "+m" (v->counter));
26022 @@ -121,7 +168,19 @@ static inline int atomic_dec_and_test(at
26026 - asm volatile(LOCK_PREFIX "decl %0; sete %1"
26027 + asm volatile(LOCK_PREFIX "decl %0\n"
26029 +#ifdef CONFIG_PAX_REFCOUNT
26031 + ".pushsection .fixup,\"ax\"\n"
26033 + LOCK_PREFIX "incl %0\n"
26036 + _ASM_EXTABLE(0b, 1b)
26040 : "+m" (v->counter), "=qm" (c)
26043 @@ -139,7 +198,19 @@ static inline int atomic_inc_and_test(at
26047 - asm volatile(LOCK_PREFIX "incl %0; sete %1"
26048 + asm volatile(LOCK_PREFIX "incl %0\n"
26050 +#ifdef CONFIG_PAX_REFCOUNT
26052 + ".pushsection .fixup,\"ax\"\n"
26054 + LOCK_PREFIX "decl %0\n"
26057 + _ASM_EXTABLE(0b, 1b)
26061 : "+m" (v->counter), "=qm" (c)
26064 @@ -158,7 +229,16 @@ static inline int atomic_add_negative(in
26068 - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
26069 + asm volatile(LOCK_PREFIX "addl %2,%0\n"
26071 +#ifdef CONFIG_PAX_REFCOUNT
26073 + LOCK_PREFIX "subl %2,%0\n"
26075 + _ASM_EXTABLE(0b, 0b)
26079 : "+m" (v->counter), "=qm" (c)
26080 : "ir" (i) : "memory");
26082 @@ -181,7 +261,15 @@ static inline int atomic_add_return(int
26084 /* Modern 486+ processor */
26086 - asm volatile(LOCK_PREFIX "xaddl %0, %1"
26087 + asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
26089 +#ifdef CONFIG_PAX_REFCOUNT
26093 + _ASM_EXTABLE(0b, 0b)
26096 : "+r" (i), "+m" (v->counter)
26099 diff -urNp linux-2.6.27.4/include/asm-x86/atomic_64.h linux-2.6.27.4/include/asm-x86/atomic_64.h
26100 --- linux-2.6.27.4/include/asm-x86/atomic_64.h 2008-10-22 17:38:01.000000000 -0400
26101 +++ linux-2.6.27.4/include/asm-x86/atomic_64.h 2008-10-27 22:36:18.000000000 -0400
26102 @@ -48,7 +48,15 @@ typedef struct {
26104 static inline void atomic_add(int i, atomic_t *v)
26106 - asm volatile(LOCK_PREFIX "addl %1,%0"
26107 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
26109 +#ifdef CONFIG_PAX_REFCOUNT
26111 + LOCK_PREFIX "subl %1,%0\n"
26113 + _ASM_EXTABLE(0b, 0b)
26116 : "=m" (v->counter)
26117 : "ir" (i), "m" (v->counter));
26119 @@ -62,7 +70,15 @@ static inline void atomic_add(int i, ato
26121 static inline void atomic_sub(int i, atomic_t *v)
26123 - asm volatile(LOCK_PREFIX "subl %1,%0"
26124 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
26126 +#ifdef CONFIG_PAX_REFCOUNT
26128 + LOCK_PREFIX "addl %1,%0\n"
26130 + _ASM_EXTABLE(0b, 0b)
26133 : "=m" (v->counter)
26134 : "ir" (i), "m" (v->counter));
26136 @@ -80,7 +96,16 @@ static inline int atomic_sub_and_test(in
26140 - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
26141 + asm volatile(LOCK_PREFIX "subl %2,%0\n"
26143 +#ifdef CONFIG_PAX_REFCOUNT
26145 + LOCK_PREFIX "addl %2,%0\n"
26147 + _ASM_EXTABLE(0b, 0b)
26151 : "=m" (v->counter), "=qm" (c)
26152 : "ir" (i), "m" (v->counter) : "memory");
26154 @@ -94,7 +119,19 @@ static inline int atomic_sub_and_test(in
26156 static inline void atomic_inc(atomic_t *v)
26158 - asm volatile(LOCK_PREFIX "incl %0"
26159 + asm volatile(LOCK_PREFIX "incl %0\n"
26161 +#ifdef CONFIG_PAX_REFCOUNT
26164 + ".pushsection .fixup,\"ax\"\n"
26166 + LOCK_PREFIX "decl %0\n"
26169 + _ASM_EXTABLE(0b, 1b)
26172 : "=m" (v->counter)
26173 : "m" (v->counter));
26175 @@ -107,7 +144,19 @@ static inline void atomic_inc(atomic_t *
26177 static inline void atomic_dec(atomic_t *v)
26179 - asm volatile(LOCK_PREFIX "decl %0"
26180 + asm volatile(LOCK_PREFIX "decl %0\n"
26182 +#ifdef CONFIG_PAX_REFCOUNT
26185 + ".pushsection .fixup,\"ax\"\n"
26187 + LOCK_PREFIX "incl %0\n"
26190 + _ASM_EXTABLE(0b, 1b)
26193 : "=m" (v->counter)
26194 : "m" (v->counter));
26196 @@ -124,7 +173,20 @@ static inline int atomic_dec_and_test(at
26200 - asm volatile(LOCK_PREFIX "decl %0; sete %1"
26201 + asm volatile(LOCK_PREFIX "decl %0\n"
26203 +#ifdef CONFIG_PAX_REFCOUNT
26206 + ".pushsection .fixup,\"ax\"\n"
26208 + LOCK_PREFIX "incl %0\n"
26211 + _ASM_EXTABLE(0b, 1b)
26215 : "=m" (v->counter), "=qm" (c)
26216 : "m" (v->counter) : "memory");
26218 @@ -142,7 +204,20 @@ static inline int atomic_inc_and_test(at
26222 - asm volatile(LOCK_PREFIX "incl %0; sete %1"
26223 + asm volatile(LOCK_PREFIX "incl %0\n"
26225 +#ifdef CONFIG_PAX_REFCOUNT
26228 + ".pushsection .fixup,\"ax\"\n"
26230 + LOCK_PREFIX "decl %0\n"
26233 + _ASM_EXTABLE(0b, 1b)
26237 : "=m" (v->counter), "=qm" (c)
26238 : "m" (v->counter) : "memory");
26240 @@ -161,7 +236,16 @@ static inline int atomic_add_negative(in
26244 - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
26245 + asm volatile(LOCK_PREFIX "addl %2,%0\n"
26247 +#ifdef CONFIG_PAX_REFCOUNT
26249 + LOCK_PREFIX "subl %2,%0\n"
26251 + _ASM_EXTABLE(0b, 0b)
26255 : "=m" (v->counter), "=qm" (c)
26256 : "ir" (i), "m" (v->counter) : "memory");
26258 @@ -177,7 +261,15 @@ static inline int atomic_add_negative(in
26259 static inline int atomic_add_return(int i, atomic_t *v)
26262 - asm volatile(LOCK_PREFIX "xaddl %0, %1"
26263 + asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
26265 +#ifdef CONFIG_PAX_REFCOUNT
26269 + _ASM_EXTABLE(0b, 0b)
26272 : "+r" (i), "+m" (v->counter)
26275 @@ -226,7 +318,15 @@ typedef struct {
26277 static inline void atomic64_add(long i, atomic64_t *v)
26279 - asm volatile(LOCK_PREFIX "addq %1,%0"
26280 + asm volatile(LOCK_PREFIX "addq %1,%0\n"
26282 +#ifdef CONFIG_PAX_REFCOUNT
26284 + LOCK_PREFIX "subq %1,%0\n"
26286 + _ASM_EXTABLE(0b, 0b)
26289 : "=m" (v->counter)
26290 : "er" (i), "m" (v->counter));
26292 @@ -240,7 +340,15 @@ static inline void atomic64_add(long i,
26294 static inline void atomic64_sub(long i, atomic64_t *v)
26296 - asm volatile(LOCK_PREFIX "subq %1,%0"
26297 + asm volatile(LOCK_PREFIX "subq %1,%0\n"
26299 +#ifdef CONFIG_PAX_REFCOUNT
26301 + LOCK_PREFIX "addq %1,%0\n"
26303 + _ASM_EXTABLE(0b, 0b)
26306 : "=m" (v->counter)
26307 : "er" (i), "m" (v->counter));
26309 @@ -258,7 +366,16 @@ static inline int atomic64_sub_and_test(
26313 - asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
26314 + asm volatile(LOCK_PREFIX "subq %2,%0\n"
26316 +#ifdef CONFIG_PAX_REFCOUNT
26318 + LOCK_PREFIX "addq %2,%0\n"
26320 + _ASM_EXTABLE(0b, 0b)
26324 : "=m" (v->counter), "=qm" (c)
26325 : "er" (i), "m" (v->counter) : "memory");
26327 @@ -272,7 +389,19 @@ static inline int atomic64_sub_and_test(
26329 static inline void atomic64_inc(atomic64_t *v)
26331 - asm volatile(LOCK_PREFIX "incq %0"
26332 + asm volatile(LOCK_PREFIX "incq %0\n"
26334 +#ifdef CONFIG_PAX_REFCOUNT
26337 + ".pushsection .fixup,\"ax\"\n"
26339 + LOCK_PREFIX "decq %0\n"
26342 + _ASM_EXTABLE(0b, 1b)
26345 : "=m" (v->counter)
26346 : "m" (v->counter));
26348 @@ -285,7 +414,19 @@ static inline void atomic64_inc(atomic64
26350 static inline void atomic64_dec(atomic64_t *v)
26352 - asm volatile(LOCK_PREFIX "decq %0"
26353 + asm volatile(LOCK_PREFIX "decq %0\n"
26355 +#ifdef CONFIG_PAX_REFCOUNT
26358 + ".pushsection .fixup,\"ax\"\n"
26360 + LOCK_PREFIX "incq %0\n"
26363 + _ASM_EXTABLE(0b, 1b)
26366 : "=m" (v->counter)
26367 : "m" (v->counter));
26369 @@ -302,7 +443,20 @@ static inline int atomic64_dec_and_test(
26373 - asm volatile(LOCK_PREFIX "decq %0; sete %1"
26374 + asm volatile(LOCK_PREFIX "decq %0\n"
26376 +#ifdef CONFIG_PAX_REFCOUNT
26379 + ".pushsection .fixup,\"ax\"\n"
26381 + LOCK_PREFIX "incq %0\n"
26384 + _ASM_EXTABLE(0b, 1b)
26388 : "=m" (v->counter), "=qm" (c)
26389 : "m" (v->counter) : "memory");
26391 @@ -320,7 +474,20 @@ static inline int atomic64_inc_and_test(
26395 - asm volatile(LOCK_PREFIX "incq %0; sete %1"
26396 + asm volatile(LOCK_PREFIX "incq %0\n"
26398 +#ifdef CONFIG_PAX_REFCOUNT
26401 + ".pushsection .fixup,\"ax\"\n"
26403 + LOCK_PREFIX "decq %0\n"
26406 + _ASM_EXTABLE(0b, 1b)
26410 : "=m" (v->counter), "=qm" (c)
26411 : "m" (v->counter) : "memory");
26413 @@ -339,7 +506,16 @@ static inline int atomic64_add_negative(
26417 - asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
26418 + asm volatile(LOCK_PREFIX "addq %2,%0\n"
26420 +#ifdef CONFIG_PAX_REFCOUNT
26422 + LOCK_PREFIX "subq %2,%0\n"
26424 + _ASM_EXTABLE(0b, 0b)
26428 : "=m" (v->counter), "=qm" (c)
26429 : "er" (i), "m" (v->counter) : "memory");
26431 @@ -355,7 +531,15 @@ static inline int atomic64_add_negative(
26432 static inline long atomic64_add_return(long i, atomic64_t *v)
26435 - asm volatile(LOCK_PREFIX "xaddq %0, %1;"
26436 + asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
26438 +#ifdef CONFIG_PAX_REFCOUNT
26442 + _ASM_EXTABLE(0b, 0b)
26445 : "+r" (i), "+m" (v->counter)
26448 diff -urNp linux-2.6.27.4/include/asm-x86/boot.h linux-2.6.27.4/include/asm-x86/boot.h
26449 --- linux-2.6.27.4/include/asm-x86/boot.h 2008-10-22 17:38:01.000000000 -0400
26450 +++ linux-2.6.27.4/include/asm-x86/boot.h 2008-10-27 22:36:18.000000000 -0400
26451 @@ -13,10 +13,15 @@
26452 #define ASK_VGA 0xfffd /* ask for it at bootup */
26454 /* Physical address where kernel should be loaded. */
26455 -#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
26456 +#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
26457 + (CONFIG_PHYSICAL_ALIGN - 1)) \
26458 & ~(CONFIG_PHYSICAL_ALIGN - 1))
26460 +#ifndef __ASSEMBLY__
26461 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
26462 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
26465 #ifdef CONFIG_X86_64
26466 #define BOOT_HEAP_SIZE 0x7000
26467 #define BOOT_STACK_SIZE 0x4000
26468 diff -urNp linux-2.6.27.4/include/asm-x86/cache.h linux-2.6.27.4/include/asm-x86/cache.h
26469 --- linux-2.6.27.4/include/asm-x86/cache.h 2008-10-22 17:38:01.000000000 -0400
26470 +++ linux-2.6.27.4/include/asm-x86/cache.h 2008-10-27 22:36:18.000000000 -0400
26472 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
26474 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
26475 +#define __read_only __attribute__((__section__(".data.read_only")))
26477 #ifdef CONFIG_X86_VSMP
26478 /* vSMP Internode cacheline shift */
26479 diff -urNp linux-2.6.27.4/include/asm-x86/checksum_32.h linux-2.6.27.4/include/asm-x86/checksum_32.h
26480 --- linux-2.6.27.4/include/asm-x86/checksum_32.h 2008-10-22 17:38:01.000000000 -0400
26481 +++ linux-2.6.27.4/include/asm-x86/checksum_32.h 2008-10-27 22:36:18.000000000 -0400
26482 @@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
26483 int len, __wsum sum,
26484 int *src_err_ptr, int *dst_err_ptr);
26486 +asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
26487 + int len, __wsum sum,
26488 + int *src_err_ptr, int *dst_err_ptr);
26490 +asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
26491 + int len, __wsum sum,
26492 + int *src_err_ptr, int *dst_err_ptr);
26495 * Note: when you get a NULL pointer exception here this means someone
26496 * passed in an incorrect kernel address to one of these functions.
26497 @@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
26501 - return csum_partial_copy_generic((__force void *)src, dst,
26502 + return csum_partial_copy_generic_from_user((__force void *)src, dst,
26503 len, sum, err_ptr, NULL);
26506 @@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
26509 if (access_ok(VERIFY_WRITE, dst, len))
26510 - return csum_partial_copy_generic(src, (__force void *)dst,
26511 + return csum_partial_copy_generic_to_user(src, (__force void *)dst,
26512 len, sum, NULL, err_ptr);
26515 diff -urNp linux-2.6.27.4/include/asm-x86/desc.h linux-2.6.27.4/include/asm-x86/desc.h
26516 --- linux-2.6.27.4/include/asm-x86/desc.h 2008-10-22 17:38:01.000000000 -0400
26517 +++ linux-2.6.27.4/include/asm-x86/desc.h 2008-10-27 22:36:18.000000000 -0400
26518 @@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
26519 desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
26520 desc->type = (info->read_exec_only ^ 1) << 1;
26521 desc->type |= info->contents << 2;
26522 + desc->type |= info->seg_not_present ^ 1;
26525 desc->p = info->seg_not_present ^ 1;
26526 @@ -27,16 +28,12 @@ static inline void fill_ldt(struct desc_
26529 extern struct desc_ptr idt_descr;
26530 -extern gate_desc idt_table[];
26533 - struct desc_struct gdt[GDT_ENTRIES];
26534 -} __attribute__((aligned(PAGE_SIZE)));
26535 -DECLARE_PER_CPU(struct gdt_page, gdt_page);
26536 +extern gate_desc idt_table[256];
26538 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
26539 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
26541 - return per_cpu(gdt_page, cpu).gdt;
26542 + return cpu_gdt_table[cpu];
26545 #ifdef CONFIG_X86_64
26546 @@ -65,7 +62,6 @@ static inline void pack_gate(gate_desc *
26547 gate->b = (base & 0xffff0000) |
26548 (((0x80 | type | (dpl << 5)) & 0xff) << 8);
26553 static inline int desc_empty(const void *ptr)
26554 @@ -102,19 +98,48 @@ static inline int desc_empty(const void
26555 static inline void native_write_idt_entry(gate_desc *idt, int entry,
26556 const gate_desc *gate)
26559 +#ifdef CONFIG_PAX_KERNEXEC
26560 + unsigned long cr0;
26562 + pax_open_kernel(cr0);
26565 memcpy(&idt[entry], gate, sizeof(*gate));
26567 +#ifdef CONFIG_PAX_KERNEXEC
26568 + pax_close_kernel(cr0);
26573 static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
26577 +#ifdef CONFIG_PAX_KERNEXEC
26578 + unsigned long cr0;
26580 + pax_open_kernel(cr0);
26583 memcpy(&ldt[entry], desc, 8);
26585 +#ifdef CONFIG_PAX_KERNEXEC
26586 + pax_close_kernel(cr0);
26591 static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
26592 const void *desc, int type)
26596 +#ifdef CONFIG_PAX_KERNEXEC
26597 + unsigned long cr0;
26602 size = sizeof(tss_desc);
26603 @@ -126,7 +151,17 @@ static inline void native_write_gdt_entr
26604 size = sizeof(struct desc_struct);
26608 +#ifdef CONFIG_PAX_KERNEXEC
26609 + pax_open_kernel(cr0);
26612 memcpy(&gdt[entry], desc, size);
26614 +#ifdef CONFIG_PAX_KERNEXEC
26615 + pax_close_kernel(cr0);
26620 static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
26621 @@ -198,7 +233,19 @@ static inline void native_set_ldt(const
26623 static inline void native_load_tr_desc(void)
26626 +#ifdef CONFIG_PAX_KERNEXEC
26627 + unsigned long cr0;
26629 + pax_open_kernel(cr0);
26632 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
26634 +#ifdef CONFIG_PAX_KERNEXEC
26635 + pax_close_kernel(cr0);
26640 static inline void native_load_gdt(const struct desc_ptr *dtr)
26641 @@ -233,8 +280,19 @@ static inline void native_load_tls(struc
26643 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
26645 +#ifdef CONFIG_PAX_KERNEXEC
26646 + unsigned long cr0;
26648 + pax_open_kernel(cr0);
26651 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
26652 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
26654 +#ifdef CONFIG_PAX_KERNEXEC
26655 + pax_close_kernel(cr0);
26660 #define _LDT_empty(info) \
26661 @@ -372,6 +430,18 @@ static inline void set_system_gate_ist(i
26662 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
26665 +#ifdef CONFIG_X86_32
26666 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
26668 + struct desc_struct d;
26670 + if (likely(limit))
26671 + limit = (limit - 1UL) >> PAGE_SHIFT;
26672 + pack_descriptor(&d, base, limit, 0xFB, 0xC);
26673 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
26679 * GET_DESC_BASE reads the descriptor base of the specified segment.
26680 diff -urNp linux-2.6.27.4/include/asm-x86/e820.h linux-2.6.27.4/include/asm-x86/e820.h
26681 --- linux-2.6.27.4/include/asm-x86/e820.h 2008-10-22 17:38:01.000000000 -0400
26682 +++ linux-2.6.27.4/include/asm-x86/e820.h 2008-10-27 22:36:18.000000000 -0400
26683 @@ -131,7 +131,7 @@ extern char *memory_setup(void);
26684 #define ISA_END_ADDRESS 0x100000
26685 #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
26687 -#define BIOS_BEGIN 0x000a0000
26688 +#define BIOS_BEGIN 0x000c0000
26689 #define BIOS_END 0x00100000
26692 diff -urNp linux-2.6.27.4/include/asm-x86/elf.h linux-2.6.27.4/include/asm-x86/elf.h
26693 --- linux-2.6.27.4/include/asm-x86/elf.h 2008-10-22 17:38:01.000000000 -0400
26694 +++ linux-2.6.27.4/include/asm-x86/elf.h 2008-10-27 22:36:18.000000000 -0400
26695 @@ -251,7 +251,25 @@ extern int force_personality32;
26696 the loader. We need to make sure that it is out of the way of the program
26697 that it will "exec", and that there is sufficient room for the brk. */
26699 +#ifdef CONFIG_PAX_SEGMEXEC
26700 +#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
26702 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
26705 +#ifdef CONFIG_PAX_ASLR
26706 +#ifdef CONFIG_X86_32
26707 +#define PAX_ELF_ET_DYN_BASE 0x10000000UL
26709 +#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
26710 +#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
26712 +#define PAX_ELF_ET_DYN_BASE 0x400000UL
26714 +#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
26715 +#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
26719 /* This yields a mask that user programs can use to figure out what
26720 instruction set this CPU supports. This could be done in user space,
26721 @@ -303,8 +321,7 @@ do { \
26722 #define ARCH_DLINFO \
26724 if (vdso_enabled) \
26725 - NEW_AUX_ENT(AT_SYSINFO_EHDR, \
26726 - (unsigned long)current->mm->context.vdso); \
26727 + NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
26730 #define AT_SYSINFO 32
26731 @@ -315,7 +332,7 @@ do { \
26733 #endif /* !CONFIG_X86_32 */
26735 -#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
26736 +#define VDSO_CURRENT_BASE (current->mm->context.vdso)
26738 #define VDSO_ENTRY \
26739 ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
26740 @@ -329,7 +346,4 @@ extern int arch_setup_additional_pages(s
26741 extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
26742 #define compat_arch_setup_additional_pages syscall32_setup_pages
26744 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
26745 -#define arch_randomize_brk arch_randomize_brk
26748 diff -urNp linux-2.6.27.4/include/asm-x86/futex.h linux-2.6.27.4/include/asm-x86/futex.h
26749 --- linux-2.6.27.4/include/asm-x86/futex.h 2008-10-22 17:38:01.000000000 -0400
26750 +++ linux-2.6.27.4/include/asm-x86/futex.h 2008-10-27 22:36:18.000000000 -0400
26752 #include <asm/processor.h>
26753 #include <asm/system.h>
26755 +#ifdef CONFIG_X86_32
26756 +#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
26758 + "movw\t%w6, %%ds\n" \
26759 + "1:\t" insn "\n" \
26760 + "2:\tpushl\t%%ss\n" \
26761 + "\tpopl\t%%ds\n" \
26762 + "\t.section .fixup,\"ax\"\n" \
26763 + "3:\tmov\t%3, %1\n" \
26765 + "\t.previous\n" \
26766 + _ASM_EXTABLE(1b, 3b) \
26767 + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
26768 + : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
26770 +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
26771 + asm volatile("movw\t%w7, %%es\n" \
26772 + "1:\tmovl\t%%es:%2, %0\n" \
26773 + "\tmovl\t%0, %3\n" \
26775 + "2:\tlock; cmpxchgl %3, %%es:%2\n" \
26777 + "3:\tpushl\t%%ss\n" \
26778 + "\tpopl\t%%es\n" \
26779 + "\t.section .fixup,\"ax\"\n" \
26780 + "4:\tmov\t%5, %1\n" \
26782 + "\t.previous\n" \
26783 + _ASM_EXTABLE(1b, 4b) \
26784 + _ASM_EXTABLE(2b, 4b) \
26785 + : "=&a" (oldval), "=&r" (ret), \
26786 + "+m" (*uaddr), "=&r" (tem) \
26787 + : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
26789 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
26790 asm volatile("1:\t" insn "\n" \
26791 "2:\t.section .fixup,\"ax\"\n" \
26793 : "=&a" (oldval), "=&r" (ret), \
26794 "+m" (*uaddr), "=&r" (tem) \
26795 : "r" (oparg), "i" (-EFAULT), "1" (0))
26798 -static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
26799 +static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
26801 int op = (encoded_op >> 28) & 7;
26802 int cmp = (encoded_op >> 24) & 15;
26803 @@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
26807 +#ifdef CONFIG_X86_32
26808 + __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
26810 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
26814 +#ifdef CONFIG_X86_32
26815 + __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
26818 __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
26823 __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
26824 @@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
26828 -static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
26829 +static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
26833 @@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
26834 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
26837 - asm volatile("1:\tlock; cmpxchgl %3, %1\n"
26839 +#ifdef CONFIG_X86_32
26840 + "\tmovw %w5, %%ds\n"
26841 + "1:\tlock; cmpxchgl %3, %1\n"
26842 + "2:\tpushl %%ss\n"
26844 + "\t.section .fixup, \"ax\"\n"
26846 + "1:\tlock; cmpxchgl %3, %1\n"
26847 "2:\t.section .fixup, \"ax\"\n"
26852 _ASM_EXTABLE(1b, 3b)
26853 : "=a" (oldval), "+m" (*uaddr)
26854 +#ifdef CONFIG_X86_32
26855 + : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
26857 : "i" (-EFAULT), "r" (newval), "0" (oldval)
26862 diff -urNp linux-2.6.27.4/include/asm-x86/i387.h linux-2.6.27.4/include/asm-x86/i387.h
26863 --- linux-2.6.27.4/include/asm-x86/i387.h 2008-10-22 17:38:01.000000000 -0400
26864 +++ linux-2.6.27.4/include/asm-x86/i387.h 2008-10-27 22:36:18.000000000 -0400
26865 @@ -159,13 +159,8 @@ static inline void restore_fpu(struct ta
26868 /* We need a safe address that is cheap to find and that is already
26869 - in L1 during context switch. The best choices are unfortunately
26870 - different for UP and SMP */
26872 -#define safe_address (__per_cpu_offset[0])
26874 -#define safe_address (kstat_cpu(0).cpustat.user)
26876 + in L1 during context switch. */
26877 +#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
26880 * These must be called with preempt disabled
26881 diff -urNp linux-2.6.27.4/include/asm-x86/io_64.h linux-2.6.27.4/include/asm-x86/io_64.h
26882 --- linux-2.6.27.4/include/asm-x86/io_64.h 2008-10-22 17:38:01.000000000 -0400
26883 +++ linux-2.6.27.4/include/asm-x86/io_64.h 2008-10-27 22:36:18.000000000 -0400
26884 @@ -158,6 +158,17 @@ static inline void *phys_to_virt(unsigne
26888 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
26889 +static inline int valid_phys_addr_range (unsigned long addr, size_t count)
26891 + return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
26894 +static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
26896 + return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
26900 * Change "struct page" to physical address.
26902 diff -urNp linux-2.6.27.4/include/asm-x86/irqflags.h linux-2.6.27.4/include/asm-x86/irqflags.h
26903 --- linux-2.6.27.4/include/asm-x86/irqflags.h 2008-10-22 17:38:01.000000000 -0400
26904 +++ linux-2.6.27.4/include/asm-x86/irqflags.h 2008-10-27 22:36:18.000000000 -0400
26905 @@ -141,6 +141,8 @@ static inline unsigned long __raw_local_
26906 #define INTERRUPT_RETURN iret
26907 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
26908 #define GET_CR0_INTO_EAX movl %cr0, %eax
26909 +#define GET_CR0_INTO_EDX movl %cr0, %edx
26910 +#define SET_CR0_FROM_EDX movl %edx, %cr0
26914 diff -urNp linux-2.6.27.4/include/asm-x86/kmap_types.h linux-2.6.27.4/include/asm-x86/kmap_types.h
26915 --- linux-2.6.27.4/include/asm-x86/kmap_types.h 2008-10-22 17:38:01.000000000 -0400
26916 +++ linux-2.6.27.4/include/asm-x86/kmap_types.h 2008-10-27 22:36:18.000000000 -0400
26917 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
26922 +D(13) KM_CLEARPAGE,
26927 diff -urNp linux-2.6.27.4/include/asm-x86/linkage.h linux-2.6.27.4/include/asm-x86/linkage.h
26928 --- linux-2.6.27.4/include/asm-x86/linkage.h 2008-10-22 17:38:01.000000000 -0400
26929 +++ linux-2.6.27.4/include/asm-x86/linkage.h 2008-10-27 22:36:18.000000000 -0400
26931 #ifdef CONFIG_X86_64
26932 #define __ALIGN .p2align 4,,15
26933 #define __ALIGN_STR ".p2align 4,,15"
26935 +#ifdef CONFIG_X86_ALIGNMENT_16
26936 +#define __ALIGN .align 16,0x90
26937 +#define __ALIGN_STR ".align 16,0x90"
26941 #ifdef CONFIG_X86_32
26946 -#ifdef CONFIG_X86_ALIGNMENT_16
26947 -#define __ALIGN .align 16,0x90
26948 -#define __ALIGN_STR ".align 16,0x90"
26953 diff -urNp linux-2.6.27.4/include/asm-x86/local.h linux-2.6.27.4/include/asm-x86/local.h
26954 --- linux-2.6.27.4/include/asm-x86/local.h 2008-10-22 17:38:01.000000000 -0400
26955 +++ linux-2.6.27.4/include/asm-x86/local.h 2008-10-27 22:36:18.000000000 -0400
26956 @@ -18,26 +18,90 @@ typedef struct {
26958 static inline void local_inc(local_t *l)
26960 - asm volatile(_ASM_INC "%0"
26961 + asm volatile(_ASM_INC "%0\n"
26963 +#ifdef CONFIG_PAX_REFCOUNT
26964 +#ifdef CONFIG_X86_32
26970 + ".pushsection .fixup,\"ax\"\n"
26975 + _ASM_EXTABLE(0b, 1b)
26978 : "+m" (l->a.counter));
26981 static inline void local_dec(local_t *l)
26983 - asm volatile(_ASM_DEC "%0"
26984 + asm volatile(_ASM_DEC "%0\n"
26986 +#ifdef CONFIG_PAX_REFCOUNT
26987 +#ifdef CONFIG_X86_32
26993 + ".pushsection .fixup,\"ax\"\n"
26998 + _ASM_EXTABLE(0b, 1b)
27001 : "+m" (l->a.counter));
27004 static inline void local_add(long i, local_t *l)
27006 - asm volatile(_ASM_ADD "%1,%0"
27007 + asm volatile(_ASM_ADD "%1,%0\n"
27009 +#ifdef CONFIG_PAX_REFCOUNT
27010 +#ifdef CONFIG_X86_32
27016 + ".pushsection .fixup,\"ax\"\n"
27018 + _ASM_SUB "%1,%0\n"
27021 + _ASM_EXTABLE(0b, 1b)
27024 : "+m" (l->a.counter)
27028 static inline void local_sub(long i, local_t *l)
27030 - asm volatile(_ASM_SUB "%1,%0"
27031 + asm volatile(_ASM_SUB "%1,%0\n"
27033 +#ifdef CONFIG_PAX_REFCOUNT
27034 +#ifdef CONFIG_X86_32
27040 + ".pushsection .fixup,\"ax\"\n"
27042 + _ASM_ADD "%1,%0\n"
27045 + _ASM_EXTABLE(0b, 1b)
27048 : "+m" (l->a.counter)
27051 @@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
27055 - asm volatile(_ASM_SUB "%2,%0; sete %1"
27056 + asm volatile(_ASM_SUB "%2,%0\n"
27058 +#ifdef CONFIG_PAX_REFCOUNT
27059 +#ifdef CONFIG_X86_32
27065 + ".pushsection .fixup,\"ax\"\n"
27067 + _ASM_ADD "%2,%0\n"
27070 + _ASM_EXTABLE(0b, 1b)
27074 : "+m" (l->a.counter), "=qm" (c)
27075 : "ir" (i) : "memory");
27077 @@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
27081 - asm volatile(_ASM_DEC "%0; sete %1"
27082 + asm volatile(_ASM_DEC "%0\n"
27084 +#ifdef CONFIG_PAX_REFCOUNT
27085 +#ifdef CONFIG_X86_32
27091 + ".pushsection .fixup,\"ax\"\n"
27096 + _ASM_EXTABLE(0b, 1b)
27100 : "+m" (l->a.counter), "=qm" (c)
27103 @@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
27107 - asm volatile(_ASM_INC "%0; sete %1"
27108 + asm volatile(_ASM_INC "%0\n"
27110 +#ifdef CONFIG_PAX_REFCOUNT
27111 +#ifdef CONFIG_X86_32
27117 + ".pushsection .fixup,\"ax\"\n"
27122 + _ASM_EXTABLE(0b, 1b)
27126 : "+m" (l->a.counter), "=qm" (c)
27129 @@ -110,7 +225,24 @@ static inline int local_add_negative(lon
27133 - asm volatile(_ASM_ADD "%2,%0; sets %1"
27134 + asm volatile(_ASM_ADD "%2,%0\n"
27136 +#ifdef CONFIG_PAX_REFCOUNT
27137 +#ifdef CONFIG_X86_32
27143 + ".pushsection .fixup,\"ax\"\n"
27145 + _ASM_SUB "%2,%0\n"
27148 + _ASM_EXTABLE(0b, 1b)
27152 : "+m" (l->a.counter), "=qm" (c)
27153 : "ir" (i) : "memory");
27155 @@ -133,7 +265,23 @@ static inline long local_add_return(long
27157 /* Modern 486+ processor */
27159 - asm volatile(_ASM_XADD "%0, %1;"
27160 + asm volatile(_ASM_XADD "%0, %1\n"
27162 +#ifdef CONFIG_PAX_REFCOUNT
27163 +#ifdef CONFIG_X86_32
27169 + ".pushsection .fixup,\"ax\"\n"
27171 + _ASM_MOV_UL "%0,%1\n"
27174 + _ASM_EXTABLE(0b, 1b)
27177 : "+r" (i), "+m" (l->a.counter)
27180 diff -urNp linux-2.6.27.4/include/asm-x86/mach-default/apm.h linux-2.6.27.4/include/asm-x86/mach-default/apm.h
27181 --- linux-2.6.27.4/include/asm-x86/mach-default/apm.h 2008-10-22 17:38:01.000000000 -0400
27182 +++ linux-2.6.27.4/include/asm-x86/mach-default/apm.h 2008-10-27 22:36:18.000000000 -0400
27183 @@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
27184 __asm__ __volatile__(APM_DO_ZERO_SEGS
27187 - "lcall *%%cs:apm_bios_entry\n\t"
27188 + "lcall *%%ss:apm_bios_entry\n\t"
27192 @@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
27193 __asm__ __volatile__(APM_DO_ZERO_SEGS
27196 - "lcall *%%cs:apm_bios_entry\n\t"
27197 + "lcall *%%ss:apm_bios_entry\n\t"
27201 diff -urNp linux-2.6.27.4/include/asm-x86/mman.h linux-2.6.27.4/include/asm-x86/mman.h
27202 --- linux-2.6.27.4/include/asm-x86/mman.h 2008-10-22 17:38:01.000000000 -0400
27203 +++ linux-2.6.27.4/include/asm-x86/mman.h 2008-10-27 22:36:18.000000000 -0400
27205 #define MCL_CURRENT 1 /* lock all current mappings */
27206 #define MCL_FUTURE 2 /* lock all future mappings */
27209 +#ifndef __ASSEMBLY__
27210 +#ifdef CONFIG_X86_32
27211 +#define arch_mmap_check i386_mmap_check
27212 +int i386_mmap_check(unsigned long addr, unsigned long len,
27213 + unsigned long flags);
27218 #endif /* _ASM_X86_MMAN_H */
27219 diff -urNp linux-2.6.27.4/include/asm-x86/mmu_context_32.h linux-2.6.27.4/include/asm-x86/mmu_context_32.h
27220 --- linux-2.6.27.4/include/asm-x86/mmu_context_32.h 2008-10-22 17:38:01.000000000 -0400
27221 +++ linux-2.6.27.4/include/asm-x86/mmu_context_32.h 2008-10-27 22:36:18.000000000 -0400
27222 @@ -33,6 +33,22 @@ static inline void switch_mm(struct mm_s
27224 if (unlikely(prev->context.ldt != next->context.ldt))
27225 load_LDT_nolock(&next->context);
27227 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27228 + if (!nx_enabled) {
27229 + smp_mb__before_clear_bit();
27230 + cpu_clear(cpu, prev->context.cpu_user_cs_mask);
27231 + smp_mb__after_clear_bit();
27232 + cpu_set(cpu, next->context.cpu_user_cs_mask);
27236 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27237 + if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
27238 + prev->context.user_cs_limit != next->context.user_cs_limit))
27239 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27245 @@ -45,6 +61,19 @@ static inline void switch_mm(struct mm_s
27247 load_cr3(next->pgd);
27248 load_LDT_nolock(&next->context);
27250 +#ifdef CONFIG_PAX_PAGEEXEC
27252 + cpu_set(cpu, next->context.cpu_user_cs_mask);
27255 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27256 +#ifdef CONFIG_PAX_PAGEEXEC
27257 + if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
27259 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27265 diff -urNp linux-2.6.27.4/include/asm-x86/mmu.h linux-2.6.27.4/include/asm-x86/mmu.h
27266 --- linux-2.6.27.4/include/asm-x86/mmu.h 2008-10-22 17:38:01.000000000 -0400
27267 +++ linux-2.6.27.4/include/asm-x86/mmu.h 2008-10-27 22:36:18.000000000 -0400
27268 @@ -11,13 +11,26 @@
27269 * cpu_vm_mask is used to optimize ldt flushing.
27273 + struct desc_struct *ldt;
27274 #ifdef CONFIG_X86_64
27280 + unsigned long vdso;
27282 +#ifdef CONFIG_X86_32
27283 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27284 + unsigned long user_cs_base;
27285 + unsigned long user_cs_limit;
27287 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27288 + cpumask_t cpu_user_cs_mask;
27297 diff -urNp linux-2.6.27.4/include/asm-x86/module.h linux-2.6.27.4/include/asm-x86/module.h
27298 --- linux-2.6.27.4/include/asm-x86/module.h 2008-10-22 17:38:01.000000000 -0400
27299 +++ linux-2.6.27.4/include/asm-x86/module.h 2008-10-25 12:03:07.000000000 -0400
27300 @@ -76,7 +76,12 @@ struct mod_arch_specific {};
27302 # define MODULE_STACKSIZE ""
27304 -# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
27305 +# ifdef CONFIG_GRKERNSEC
27306 +# define MODULE_GRSEC "GRSECURITY "
27308 +# define MODULE_GRSEC ""
27310 +# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
27313 #endif /* _ASM_MODULE_H */
27314 diff -urNp linux-2.6.27.4/include/asm-x86/page_32.h linux-2.6.27.4/include/asm-x86/page_32.h
27315 --- linux-2.6.27.4/include/asm-x86/page_32.h 2008-10-22 17:38:01.000000000 -0400
27316 +++ linux-2.6.27.4/include/asm-x86/page_32.h 2008-10-27 22:36:18.000000000 -0400
27319 #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
27321 +#ifdef CONFIG_PAX_KERNEXEC
27322 +#ifndef __ASSEMBLY__
27323 +extern unsigned char MODULES_VADDR[];
27324 +extern unsigned char MODULES_END[];
27325 +extern unsigned char KERNEL_TEXT_OFFSET[];
27326 +#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
27327 +#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
27330 +#define ktla_ktva(addr) (addr)
27331 +#define ktva_ktla(addr) (addr)
27334 +#ifdef CONFIG_PAX_PAGEEXEC
27335 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
27338 #ifdef CONFIG_4KSTACKS
27339 #define THREAD_ORDER 0
27341 diff -urNp linux-2.6.27.4/include/asm-x86/page_64.h linux-2.6.27.4/include/asm-x86/page_64.h
27342 --- linux-2.6.27.4/include/asm-x86/page_64.h 2008-10-22 17:38:01.000000000 -0400
27343 +++ linux-2.6.27.4/include/asm-x86/page_64.h 2008-10-27 22:36:18.000000000 -0400
27345 #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
27346 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
27348 +#define ktla_ktva(addr) (addr)
27349 +#define ktva_ktla(addr) (addr)
27351 /* See Documentation/x86_64/mm.txt for a description of the memory map. */
27352 #define __PHYSICAL_MASK_SHIFT 46
27353 #define __VIRTUAL_MASK_SHIFT 48
27354 @@ -101,5 +104,6 @@ extern void init_extra_mapping_wb(unsign
27355 #define pfn_valid(pfn) ((pfn) < max_pfn)
27358 +#define nx_enabled (1)
27360 #endif /* _X86_64_PAGE_H */
27361 diff -urNp linux-2.6.27.4/include/asm-x86/paravirt.h linux-2.6.27.4/include/asm-x86/paravirt.h
27362 --- linux-2.6.27.4/include/asm-x86/paravirt.h 2008-10-22 17:38:01.000000000 -0400
27363 +++ linux-2.6.27.4/include/asm-x86/paravirt.h 2008-10-27 22:36:18.000000000 -0400
27364 @@ -1557,7 +1557,7 @@ static inline unsigned long __raw_local_
27365 #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax
27366 #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
27367 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
27368 -#define PARA_INDIRECT(addr) *%cs:addr
27369 +#define PARA_INDIRECT(addr) *%ss:addr
27372 #define INTERRUPT_RETURN \
27373 diff -urNp linux-2.6.27.4/include/asm-x86/pda.h linux-2.6.27.4/include/asm-x86/pda.h
27374 --- linux-2.6.27.4/include/asm-x86/pda.h 2008-10-22 17:38:01.000000000 -0400
27375 +++ linux-2.6.27.4/include/asm-x86/pda.h 2008-10-27 22:36:18.000000000 -0400
27376 @@ -16,11 +16,9 @@ struct x8664_pda {
27377 unsigned long oldrsp; /* 24 user rsp for system call */
27378 int irqcount; /* 32 Irq nesting counter. Starts -1 */
27379 unsigned int cpunumber; /* 36 Logical CPU number */
27380 -#ifdef CONFIG_CC_STACKPROTECTOR
27381 unsigned long stack_canary; /* 40 stack canary value */
27382 /* gcc-ABI: this canary MUST be at
27386 short nodenumber; /* number of current node (32k max) */
27387 short in_bootmem; /* pda lives in bootmem */
27388 diff -urNp linux-2.6.27.4/include/asm-x86/percpu.h linux-2.6.27.4/include/asm-x86/percpu.h
27389 --- linux-2.6.27.4/include/asm-x86/percpu.h 2008-10-22 17:38:01.000000000 -0400
27390 +++ linux-2.6.27.4/include/asm-x86/percpu.h 2008-10-27 22:36:18.000000000 -0400
27391 @@ -93,6 +93,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
27393 #define __my_cpu_offset x86_read_percpu(this_cpu_off)
27395 +#include <asm-generic/sections.h>
27396 +#include <linux/threads.h>
27397 +#define __per_cpu_offset __per_cpu_offset
27398 +extern unsigned long __per_cpu_offset[NR_CPUS];
27399 +#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
27401 /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
27402 #define __percpu_seg "%%fs:"
27404 diff -urNp linux-2.6.27.4/include/asm-x86/pgalloc.h linux-2.6.27.4/include/asm-x86/pgalloc.h
27405 --- linux-2.6.27.4/include/asm-x86/pgalloc.h 2008-10-22 17:38:01.000000000 -0400
27406 +++ linux-2.6.27.4/include/asm-x86/pgalloc.h 2008-10-27 22:36:18.000000000 -0400
27407 @@ -51,7 +51,7 @@ static inline void pmd_populate_kernel(s
27408 pmd_t *pmd, pte_t *pte)
27410 paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
27411 - set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
27412 + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
27415 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
27416 diff -urNp linux-2.6.27.4/include/asm-x86/pgtable-2level.h linux-2.6.27.4/include/asm-x86/pgtable-2level.h
27417 --- linux-2.6.27.4/include/asm-x86/pgtable-2level.h 2008-10-22 17:38:01.000000000 -0400
27418 +++ linux-2.6.27.4/include/asm-x86/pgtable-2level.h 2008-10-27 22:36:18.000000000 -0400
27419 @@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
27421 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
27424 +#ifdef CONFIG_PAX_KERNEXEC
27425 + unsigned long cr0;
27427 + pax_open_kernel(cr0);
27432 +#ifdef CONFIG_PAX_KERNEXEC
27433 + pax_close_kernel(cr0);
27438 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
27439 diff -urNp linux-2.6.27.4/include/asm-x86/pgtable_32.h linux-2.6.27.4/include/asm-x86/pgtable_32.h
27440 --- linux-2.6.27.4/include/asm-x86/pgtable_32.h 2008-10-22 17:38:01.000000000 -0400
27441 +++ linux-2.6.27.4/include/asm-x86/pgtable_32.h 2008-10-27 22:36:18.000000000 -0400
27444 struct vm_area_struct;
27446 -extern pgd_t swapper_pg_dir[1024];
27448 static inline void pgtable_cache_init(void) { }
27449 static inline void check_pgt_cache(void) { }
27450 void paging_init(void);
27451 @@ -45,6 +43,11 @@ void paging_init(void);
27452 # include <asm/pgtable-2level-defs.h>
27455 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
27456 +#ifdef CONFIG_X86_PAE
27457 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
27460 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
27461 #define PGDIR_MASK (~(PGDIR_SIZE - 1))
27463 @@ -81,7 +84,7 @@ void paging_init(void);
27464 #undef TEST_ACCESS_OK
27466 /* The boot page tables (all created as a single array) */
27467 -extern unsigned long pg0[];
27468 +extern pte_t pg0[];
27470 #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
27472 @@ -173,6 +176,9 @@ do { \
27474 #endif /* !__ASSEMBLY__ */
27476 +#define HAVE_ARCH_UNMAPPED_AREA
27477 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
27480 * kern_addr_valid() is (1) for FLATMEM and (0) for
27481 * SPARSEMEM and DISCONTIGMEM
27482 diff -urNp linux-2.6.27.4/include/asm-x86/pgtable-3level.h linux-2.6.27.4/include/asm-x86/pgtable-3level.h
27483 --- linux-2.6.27.4/include/asm-x86/pgtable-3level.h 2008-10-22 17:38:01.000000000 -0400
27484 +++ linux-2.6.27.4/include/asm-x86/pgtable-3level.h 2008-10-27 22:36:18.000000000 -0400
27485 @@ -70,12 +70,36 @@ static inline void native_set_pte_atomic
27487 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
27490 +#ifdef CONFIG_PAX_KERNEXEC
27491 + unsigned long cr0;
27493 + pax_open_kernel(cr0);
27496 set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
27498 +#ifdef CONFIG_PAX_KERNEXEC
27499 + pax_close_kernel(cr0);
27504 static inline void native_set_pud(pud_t *pudp, pud_t pud)
27507 +#ifdef CONFIG_PAX_KERNEXEC
27508 + unsigned long cr0;
27510 + pax_open_kernel(cr0);
27513 set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
27515 +#ifdef CONFIG_PAX_KERNEXEC
27516 + pax_close_kernel(cr0);
27522 diff -urNp linux-2.6.27.4/include/asm-x86/pgtable_64.h linux-2.6.27.4/include/asm-x86/pgtable_64.h
27523 --- linux-2.6.27.4/include/asm-x86/pgtable_64.h 2008-10-22 17:38:01.000000000 -0400
27524 +++ linux-2.6.27.4/include/asm-x86/pgtable_64.h 2008-10-27 22:36:18.000000000 -0400
27527 extern pud_t level3_kernel_pgt[512];
27528 extern pud_t level3_ident_pgt[512];
27529 +extern pud_t level3_vmalloc_pgt[512];
27530 +extern pud_t level3_vmemmap_pgt[512];
27531 extern pmd_t level2_kernel_pgt[512];
27532 extern pmd_t level2_fixmap_pgt[512];
27533 extern pmd_t level2_ident_pgt[512];
27534 +extern pte_t level1_fixmap_pgt[512];
27535 extern pgd_t init_level4_pgt[];
27537 #define swapper_pg_dir init_level4_pgt
27538 @@ -106,7 +109,19 @@ static inline pte_t native_ptep_get_and_
27540 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
27543 +#ifdef CONFIG_PAX_KERNEXEC
27544 + unsigned long cr0;
27546 + pax_open_kernel(cr0);
27551 +#ifdef CONFIG_PAX_KERNEXEC
27552 + pax_close_kernel(cr0);
27557 static inline void native_pmd_clear(pmd_t *pmd)
27558 @@ -158,17 +173,17 @@ static inline void native_pgd_clear(pgd_
27560 static inline int pgd_bad(pgd_t pgd)
27562 - return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
27563 + return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
27566 static inline int pud_bad(pud_t pud)
27568 - return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
27569 + return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
27572 static inline int pmd_bad(pmd_t pmd)
27574 - return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
27575 + return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
27578 #define pte_none(x) (!pte_val((x)))
27579 diff -urNp linux-2.6.27.4/include/asm-x86/pgtable.h linux-2.6.27.4/include/asm-x86/pgtable.h
27580 --- linux-2.6.27.4/include/asm-x86/pgtable.h 2008-10-22 17:38:01.000000000 -0400
27581 +++ linux-2.6.27.4/include/asm-x86/pgtable.h 2008-10-27 22:36:18.000000000 -0400
27583 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
27586 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
27587 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
27589 #define __PAGE_KERNEL_EXEC \
27590 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
27591 #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
27593 #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
27594 #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
27595 #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
27596 -#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
27597 +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
27598 #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
27599 #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
27600 #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
27601 @@ -142,10 +145,17 @@ extern unsigned long empty_zero_page[PAG
27602 extern spinlock_t pgd_lock;
27603 extern struct list_head pgd_list;
27605 +extern pteval_t __supported_pte_mask;
27608 * The following only work if pte_present() is true.
27609 * Undefined behaviour if not..
27611 +static inline int pte_user(pte_t pte)
27613 + return pte_val(pte) & _PAGE_USER;
27616 static inline int pte_dirty(pte_t pte)
27618 return pte_flags(pte) & _PAGE_DIRTY;
27619 @@ -207,9 +217,29 @@ static inline pte_t pte_wrprotect(pte_t
27620 return __pte(pte_val(pte) & ~_PAGE_RW);
27623 +static inline pte_t pte_mkread(pte_t pte)
27625 + return __pte(pte_val(pte) | _PAGE_USER);
27628 static inline pte_t pte_mkexec(pte_t pte)
27630 - return __pte(pte_val(pte) & ~_PAGE_NX);
27631 +#ifdef CONFIG_X86_PAE
27632 + if (__supported_pte_mask & _PAGE_NX)
27633 + return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
27636 + return __pte(pte_val(pte) | _PAGE_USER);
27639 +static inline pte_t pte_exprotect(pte_t pte)
27641 +#ifdef CONFIG_X86_PAE
27642 + if (__supported_pte_mask & _PAGE_NX)
27643 + return __pte(pte_val(pte) | _PAGE_NX);
27646 + return __pte(pte_val(pte) & ~_PAGE_USER);
27649 static inline pte_t pte_mkdirty(pte_t pte)
27650 @@ -252,8 +282,6 @@ static inline pte_t pte_mkspecial(pte_t
27651 return __pte(pte_val(pte) | _PAGE_SPECIAL);
27654 -extern pteval_t __supported_pte_mask;
27656 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
27658 return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
27659 @@ -514,7 +542,19 @@ static inline void ptep_set_wrprotect(st
27661 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
27663 - memcpy(dst, src, count * sizeof(pgd_t));
27665 +#ifdef CONFIG_PAX_KERNEXEC
27666 + unsigned long cr0;
27668 + pax_open_kernel(cr0);
27671 + memcpy(dst, src, count * sizeof(pgd_t));
27673 +#ifdef CONFIG_PAX_KERNEXEC
27674 + pax_close_kernel(cr0);
27680 diff -urNp linux-2.6.27.4/include/asm-x86/processor.h linux-2.6.27.4/include/asm-x86/processor.h
27681 --- linux-2.6.27.4/include/asm-x86/processor.h 2008-10-22 17:38:01.000000000 -0400
27682 +++ linux-2.6.27.4/include/asm-x86/processor.h 2008-10-27 22:36:18.000000000 -0400
27683 @@ -269,7 +269,7 @@ struct tss_struct {
27685 } ____cacheline_aligned;
27687 -DECLARE_PER_CPU(struct tss_struct, init_tss);
27688 +extern struct tss_struct init_tss[NR_CPUS];
27691 * Save the original ist values for checking stack pointers during debugging
27692 @@ -832,11 +832,20 @@ static inline void spin_lock_prefetch(co
27693 * User space process size: 3GB (default).
27695 #define TASK_SIZE PAGE_OFFSET
27697 +#ifdef CONFIG_PAX_SEGMEXEC
27698 +#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
27701 +#ifdef CONFIG_PAX_SEGMEXEC
27702 +#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
27704 #define STACK_TOP TASK_SIZE
27705 -#define STACK_TOP_MAX STACK_TOP
27707 +#define STACK_TOP_MAX TASK_SIZE
27709 #define INIT_THREAD { \
27710 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
27711 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
27712 .vm86_info = NULL, \
27713 .sysenter_cs = __KERNEL_CS, \
27714 .io_bitmap_ptr = NULL, \
27715 @@ -851,7 +860,7 @@ static inline void spin_lock_prefetch(co
27717 #define INIT_TSS { \
27719 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
27720 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
27721 .ss0 = __KERNEL_DS, \
27722 .ss1 = __KERNEL_CS, \
27723 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
27724 @@ -862,11 +871,7 @@ static inline void spin_lock_prefetch(co
27725 extern unsigned long thread_saved_pc(struct task_struct *tsk);
27727 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
27728 -#define KSTK_TOP(info) \
27730 - unsigned long *__ptr = (unsigned long *)(info); \
27731 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
27733 +#define KSTK_TOP(info) ((info)->task.thread.sp0)
27736 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
27737 @@ -881,7 +886,7 @@ extern unsigned long thread_saved_pc(str
27738 #define task_pt_regs(task) \
27740 struct pt_regs *__regs__; \
27741 - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
27742 + __regs__ = (struct pt_regs *)((task)->thread.sp0); \
27746 @@ -897,7 +902,7 @@ extern unsigned long thread_saved_pc(str
27747 * space during mmap's.
27749 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
27750 - 0xc0000000 : 0xFFFFe000)
27751 + 0xc0000000 : 0xFFFFf000)
27753 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
27754 IA32_PAGE_OFFSET : TASK_SIZE64)
27755 @@ -934,6 +939,10 @@ extern void start_thread(struct pt_regs
27757 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
27759 +#ifdef CONFIG_PAX_SEGMEXEC
27760 +#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
27763 #define KSTK_EIP(task) (task_pt_regs(task)->ip)
27765 /* Get/set a process' ability to use the timestamp counter instruction */
27766 diff -urNp linux-2.6.27.4/include/asm-x86/ptrace.h linux-2.6.27.4/include/asm-x86/ptrace.h
27767 --- linux-2.6.27.4/include/asm-x86/ptrace.h 2008-10-22 17:38:01.000000000 -0400
27768 +++ linux-2.6.27.4/include/asm-x86/ptrace.h 2008-10-27 22:36:18.000000000 -0400
27769 @@ -131,6 +131,7 @@ struct pt_regs {
27771 /* the DS BTS struct is used for ptrace as well */
27772 #include <asm/ds.h>
27773 +#include <asm/segment.h>
27775 struct task_struct;
27777 @@ -154,28 +155,29 @@ static inline unsigned long regs_return_
27781 - * user_mode_vm(regs) determines whether a register set came from user mode.
27782 + * user_mode(regs) determines whether a register set came from user mode.
27783 * This is true if V8086 mode was enabled OR if the register set was from
27784 * protected mode with RPL-3 CS value. This tricky test checks that with
27785 * one comparison. Many places in the kernel can bypass this full check
27786 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
27787 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
27790 -static inline int user_mode(struct pt_regs *regs)
27791 +static inline int user_mode_novm(struct pt_regs *regs)
27793 #ifdef CONFIG_X86_32
27794 return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
27796 - return !!(regs->cs & 3);
27797 + return !!(regs->cs & SEGMENT_RPL_MASK);
27801 -static inline int user_mode_vm(struct pt_regs *regs)
27802 +static inline int user_mode(struct pt_regs *regs)
27804 #ifdef CONFIG_X86_32
27805 return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
27808 - return user_mode(regs);
27809 + return user_mode_novm(regs);
27813 diff -urNp linux-2.6.27.4/include/asm-x86/reboot.h linux-2.6.27.4/include/asm-x86/reboot.h
27814 --- linux-2.6.27.4/include/asm-x86/reboot.h 2008-10-22 17:38:01.000000000 -0400
27815 +++ linux-2.6.27.4/include/asm-x86/reboot.h 2008-10-27 22:36:18.000000000 -0400
27816 @@ -16,6 +16,6 @@ extern struct machine_ops machine_ops;
27818 void native_machine_crash_shutdown(struct pt_regs *regs);
27819 void native_machine_shutdown(void);
27820 -void machine_real_restart(const unsigned char *code, int length);
27821 +void machine_real_restart(const unsigned char *code, unsigned int length);
27823 #endif /* _ASM_REBOOT_H */
27824 diff -urNp linux-2.6.27.4/include/asm-x86/rwsem.h linux-2.6.27.4/include/asm-x86/rwsem.h
27825 --- linux-2.6.27.4/include/asm-x86/rwsem.h 2008-10-22 17:38:01.000000000 -0400
27826 +++ linux-2.6.27.4/include/asm-x86/rwsem.h 2008-10-27 22:36:18.000000000 -0400
27827 @@ -106,10 +106,26 @@ static inline void __down_read(struct rw
27829 asm volatile("# beginning down_read\n\t"
27830 LOCK_PREFIX " incl (%%eax)\n\t"
27832 +#ifdef CONFIG_PAX_REFCOUNT
27833 +#ifdef CONFIG_X86_32
27839 + ".pushsection .fixup,\"ax\"\n"
27841 + LOCK_PREFIX "decl (%%eax)\n"
27844 + _ASM_EXTABLE(0b, 1b)
27847 /* adds 0x00000001, returns the old value */
27850 " call call_rwsem_down_read_failed\n"
27853 "# ending down_read\n\t"
27854 : "+m" (sem->count)
27856 @@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
27858 asm volatile("# beginning __down_read_trylock\n\t"
27866 +#ifdef CONFIG_PAX_REFCOUNT
27867 +#ifdef CONFIG_X86_32
27873 + ".pushsection .fixup,\"ax\"\n"
27878 + _ASM_EXTABLE(0b, 1b)
27882 LOCK_PREFIX " cmpxchgl %2,%0\n\t"
27887 "# ending __down_read_trylock\n\t"
27888 : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
27889 : "i" (RWSEM_ACTIVE_READ_BIAS)
27890 @@ -148,12 +180,28 @@ static inline void __down_write_nested(s
27891 tmp = RWSEM_ACTIVE_WRITE_BIAS;
27892 asm volatile("# beginning down_write\n\t"
27893 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
27895 +#ifdef CONFIG_PAX_REFCOUNT
27896 +#ifdef CONFIG_X86_32
27902 + ".pushsection .fixup,\"ax\"\n"
27904 + "movl %%edx,(%%eax)\n"
27907 + _ASM_EXTABLE(0b, 1b)
27910 /* subtract 0x0000ffff, returns the old value */
27911 " testl %%edx,%%edx\n\t"
27912 /* was the count 0 before? */
27915 " call call_rwsem_down_write_failed\n"
27918 "# ending down_write"
27919 : "+m" (sem->count), "=d" (tmp)
27920 : "a" (sem), "1" (tmp)
27921 @@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
27922 __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
27923 asm volatile("# beginning __up_read\n\t"
27924 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
27926 +#ifdef CONFIG_PAX_REFCOUNT
27927 +#ifdef CONFIG_X86_32
27933 + ".pushsection .fixup,\"ax\"\n"
27935 + "movl %%edx,(%%eax)\n"
27938 + _ASM_EXTABLE(0b, 1b)
27941 /* subtracts 1, returns the old value */
27944 " call call_rwsem_wake\n"
27947 "# ending __up_read\n"
27948 : "+m" (sem->count), "=d" (tmp)
27949 : "a" (sem), "1" (tmp)
27950 @@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
27951 asm volatile("# beginning __up_write\n\t"
27952 " movl %2,%%edx\n\t"
27953 LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
27955 +#ifdef CONFIG_PAX_REFCOUNT
27956 +#ifdef CONFIG_X86_32
27962 + ".pushsection .fixup,\"ax\"\n"
27964 + "movl %%edx,(%%eax)\n"
27967 + _ASM_EXTABLE(0b, 1b)
27970 /* tries to transition
27971 0xffff0001 -> 0x00000000 */
27974 " call call_rwsem_wake\n"
27977 "# ending __up_write\n"
27978 : "+m" (sem->count)
27979 : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
27980 @@ -222,10 +302,26 @@ static inline void __downgrade_write(str
27982 asm volatile("# beginning __downgrade_write\n\t"
27983 LOCK_PREFIX " addl %2,(%%eax)\n\t"
27985 +#ifdef CONFIG_PAX_REFCOUNT
27986 +#ifdef CONFIG_X86_32
27992 + ".pushsection .fixup,\"ax\"\n"
27994 + LOCK_PREFIX "subl %2,(%%eax)\n"
27997 + _ASM_EXTABLE(0b, 1b)
28000 /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
28003 " call call_rwsem_downgrade_wake\n"
28006 "# ending __downgrade_write\n"
28007 : "+m" (sem->count)
28008 : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
28009 @@ -237,7 +333,23 @@ static inline void __downgrade_write(str
28011 static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
28013 - asm volatile(LOCK_PREFIX "addl %1,%0"
28014 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
28016 +#ifdef CONFIG_PAX_REFCOUNT
28017 +#ifdef CONFIG_X86_32
28023 + ".pushsection .fixup,\"ax\"\n"
28025 + LOCK_PREFIX "subl %1,%0\n"
28028 + _ASM_EXTABLE(0b, 1b)
28031 : "+m" (sem->count)
28034 @@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
28038 - asm volatile(LOCK_PREFIX "xadd %0,%1"
28039 + asm volatile(LOCK_PREFIX "xadd %0,%1\n"
28041 +#ifdef CONFIG_PAX_REFCOUNT
28042 +#ifdef CONFIG_X86_32
28048 + ".pushsection .fixup,\"ax\"\n"
28053 + _ASM_EXTABLE(0b, 1b)
28056 : "+r" (tmp), "+m" (sem->count)
28059 diff -urNp linux-2.6.27.4/include/asm-x86/segment.h linux-2.6.27.4/include/asm-x86/segment.h
28060 --- linux-2.6.27.4/include/asm-x86/segment.h 2008-10-22 17:38:01.000000000 -0400
28061 +++ linux-2.6.27.4/include/asm-x86/segment.h 2008-10-27 22:36:18.000000000 -0400
28062 @@ -88,13 +88,19 @@
28063 #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
28064 #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
28066 -#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
28067 +#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
28069 #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
28071 #define __KERNEL_PERCPU 0
28074 +#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
28075 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
28077 +#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
28078 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
28080 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
28083 @@ -135,10 +141,10 @@
28084 #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
28086 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
28087 -#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
28088 +#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
28090 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
28091 -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
28092 +#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
28096 diff -urNp linux-2.6.27.4/include/asm-x86/spinlock.h linux-2.6.27.4/include/asm-x86/spinlock.h
28097 --- linux-2.6.27.4/include/asm-x86/spinlock.h 2008-10-22 17:38:01.000000000 -0400
28098 +++ linux-2.6.27.4/include/asm-x86/spinlock.h 2008-10-27 22:36:18.000000000 -0400
28099 @@ -315,18 +315,50 @@ static inline int __raw_write_can_lock(r
28100 static inline void __raw_read_lock(raw_rwlock_t *rw)
28102 asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
28104 - "call __read_lock_failed\n\t"
28106 +#ifdef CONFIG_PAX_REFCOUNT
28107 +#ifdef CONFIG_X86_32
28113 + ".pushsection .fixup,\"ax\"\n"
28115 + LOCK_PREFIX " addl $1,(%0)\n"
28118 + _ASM_EXTABLE(0b, 1b)
28122 + "call __read_lock_failed\n\t"
28124 ::LOCK_PTR_REG (rw) : "memory");
28127 static inline void __raw_write_lock(raw_rwlock_t *rw)
28129 asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
28131 - "call __write_lock_failed\n\t"
28133 +#ifdef CONFIG_PAX_REFCOUNT
28134 +#ifdef CONFIG_X86_32
28140 + ".pushsection .fixup,\"ax\"\n"
28142 + LOCK_PREFIX " addl %1,(%0)\n"
28145 + _ASM_EXTABLE(0b, 1b)
28149 + "call __write_lock_failed\n\t"
28151 ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
28154 @@ -353,12 +385,45 @@ static inline int __raw_write_trylock(ra
28156 static inline void __raw_read_unlock(raw_rwlock_t *rw)
28158 - asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
28159 + asm volatile(LOCK_PREFIX "incl %0\n"
28161 +#ifdef CONFIG_PAX_REFCOUNT
28162 +#ifdef CONFIG_X86_32
28168 + ".pushsection .fixup,\"ax\"\n"
28170 + LOCK_PREFIX "decl %0\n"
28173 + _ASM_EXTABLE(0b, 1b)
28176 + :"+m" (rw->lock) : : "memory");
28179 static inline void __raw_write_unlock(raw_rwlock_t *rw)
28181 - asm volatile(LOCK_PREFIX "addl %1, %0"
28182 + asm volatile(LOCK_PREFIX "addl %1, %0\n"
28184 +#ifdef CONFIG_PAX_REFCOUNT
28185 +#ifdef CONFIG_X86_32
28191 + ".pushsection .fixup,\"ax\"\n"
28193 + LOCK_PREFIX "subl %1,%0\n"
28196 + _ASM_EXTABLE(0b, 1b)
28199 : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
28202 diff -urNp linux-2.6.27.4/include/asm-x86/system.h linux-2.6.27.4/include/asm-x86/system.h
28203 --- linux-2.6.27.4/include/asm-x86/system.h 2008-10-22 17:38:01.000000000 -0400
28204 +++ linux-2.6.27.4/include/asm-x86/system.h 2008-10-27 22:36:18.000000000 -0400
28205 @@ -92,6 +92,8 @@ do { \
28206 ".globl thread_return\n" \
28207 "thread_return:\n\t" \
28208 "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
28209 + "movq %P[task_canary](%%rsi),%%r8\n\t" \
28210 + "movq %%r8,%%gs:%P[pda_canary]\n\t" \
28211 "movq %P[thread_info](%%rsi),%%r8\n\t" \
28212 LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
28213 "movq %%rax,%%rdi\n\t" \
28214 @@ -103,7 +105,9 @@ do { \
28215 [ti_flags] "i" (offsetof(struct thread_info, flags)), \
28216 [tif_fork] "i" (TIF_FORK), \
28217 [thread_info] "i" (offsetof(struct task_struct, stack)), \
28218 - [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
28219 + [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
28220 + [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
28221 + [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
28222 : "memory", "cc" __EXTRA_CLOBBER)
28225 @@ -166,7 +170,7 @@ static inline unsigned long get_limit(un
28227 unsigned long __limit;
28228 asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
28229 - return __limit + 1;
28233 static inline void native_clts(void)
28234 @@ -292,6 +296,21 @@ static inline void native_wbinvd(void)
28236 #define stts() write_cr0(read_cr0() | X86_CR0_TS)
28238 +#define pax_open_kernel(cr0) \
28240 + typecheck(unsigned long, cr0); \
28241 + preempt_disable(); \
28242 + cr0 = read_cr0(); \
28243 + write_cr0(cr0 & ~X86_CR0_WP); \
28246 +#define pax_close_kernel(cr0) \
28248 + typecheck(unsigned long, cr0); \
28249 + write_cr0(cr0); \
28250 + preempt_enable_no_resched(); \
28253 #endif /* __KERNEL__ */
28255 static inline void clflush(volatile void *__p)
28256 @@ -306,7 +325,7 @@ void enable_hlt(void);
28258 void cpu_idle_wait(void);
28260 -extern unsigned long arch_align_stack(unsigned long sp);
28261 +#define arch_align_stack(x) ((x) & ~0xfUL)
28262 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
28264 void default_idle(void);
28265 diff -urNp linux-2.6.27.4/include/asm-x86/uaccess_64.h linux-2.6.27.4/include/asm-x86/uaccess_64.h
28266 --- linux-2.6.27.4/include/asm-x86/uaccess_64.h 2008-10-22 17:38:01.000000000 -0400
28267 +++ linux-2.6.27.4/include/asm-x86/uaccess_64.h 2008-10-27 22:36:18.000000000 -0400
28269 #include <linux/lockdep.h>
28270 #include <asm/page.h>
28272 +#define set_fs(x) (current_thread_info()->addr_limit = (x))
28275 * Copy To/From Userspace
28277 diff -urNp linux-2.6.27.4/include/asm-x86/uaccess.h linux-2.6.27.4/include/asm-x86/uaccess.h
28278 --- linux-2.6.27.4/include/asm-x86/uaccess.h 2008-10-22 17:38:01.000000000 -0400
28279 +++ linux-2.6.27.4/include/asm-x86/uaccess.h 2008-10-27 22:36:18.000000000 -0400
28281 #include <linux/string.h>
28282 #include <asm/asm.h>
28283 #include <asm/page.h>
28284 +#include <asm/segment.h>
28286 #define VERIFY_READ 0
28287 #define VERIFY_WRITE 1
28290 #define get_ds() (KERNEL_DS)
28291 #define get_fs() (current_thread_info()->addr_limit)
28292 +#ifdef CONFIG_X86_32
28293 +void __set_fs(mm_segment_t x, int cpu);
28294 +void set_fs(mm_segment_t x);
28296 #define set_fs(x) (current_thread_info()->addr_limit = (x))
28299 #define segment_eq(a, b) ((a).seg == (b).seg)
28301 @@ -97,6 +103,7 @@ struct exception_table_entry {
28304 extern int fixup_exception(struct pt_regs *regs);
28305 +#define ARCH_HAS_SORT_EXTABLE
28308 * These are the main single-value transfer routines. They automatically
28309 @@ -186,9 +193,12 @@ extern int __get_user_bad(void);
28311 #ifdef CONFIG_X86_32
28312 #define __put_user_u64(x, addr, err) \
28313 - asm volatile("1: movl %%eax,0(%2)\n" \
28314 - "2: movl %%edx,4(%2)\n" \
28315 + asm volatile(" movw %w5,%%ds\n" \
28316 + "1: movl %%eax,%%ds:0(%2)\n" \
28317 + "2: movl %%edx,%%ds:4(%2)\n" \
28319 + " pushl %%ss\n" \
28321 ".section .fixup,\"ax\"\n" \
28322 "4: movl %3,%0\n" \
28324 @@ -196,7 +206,8 @@ extern int __get_user_bad(void);
28325 _ASM_EXTABLE(1b, 4b) \
28326 _ASM_EXTABLE(2b, 4b) \
28328 - : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
28329 + : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err), \
28332 #define __put_user_x8(x, ptr, __ret_pu) \
28333 asm volatile("call __put_user_8" : "=a" (__ret_pu) \
28334 @@ -336,6 +347,22 @@ do { \
28338 +#ifdef CONFIG_X86_32
28339 +#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28340 + asm volatile(" movw %w5,%%ds\n" \
28341 + "1: mov"itype" %%ds:%2,%"rtype"1\n" \
28343 + " pushl %%ss\n" \
28345 + ".section .fixup,\"ax\"\n" \
28346 + "3: movl %3,%0\n" \
28347 + " xor"itype" %"rtype"1,%"rtype"1\n" \
28350 + _ASM_EXTABLE(1b, 3b) \
28351 + : "=r" (err), ltype (x) \
28352 + : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
28354 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28355 asm volatile("1: mov"itype" %2,%"rtype"1\n" \
28357 @@ -347,6 +374,7 @@ do { \
28358 _ASM_EXTABLE(1b, 3b) \
28359 : "=r" (err), ltype(x) \
28360 : "m" (__m(addr)), "i" (errret), "0" (err))
28363 #define __put_user_nocheck(x, ptr, size) \
28365 @@ -373,6 +401,22 @@ struct __large_struct { unsigned long bu
28366 * we do not write to any memory gcc knows about, so there are no
28369 +#ifdef CONFIG_X86_32
28370 +#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28371 + asm volatile(" movw %w5,%%ds\n" \
28372 + "1: mov"itype" %"rtype"1,%%ds:%2\n" \
28374 + " pushl %%ss\n" \
28376 + ".section .fixup,\"ax\"\n" \
28377 + "3: movl %3,%0\n" \
28380 + _ASM_EXTABLE(1b, 3b) \
28382 + : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
28385 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28386 asm volatile("1: mov"itype" %"rtype"1,%2\n" \
28388 @@ -383,6 +427,7 @@ struct __large_struct { unsigned long bu
28389 _ASM_EXTABLE(1b, 3b) \
28391 : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
28394 * __get_user: - Get a simple variable from user space, with less checking.
28395 * @x: Variable to store result.
28396 @@ -447,6 +492,7 @@ extern struct movsl_mask {
28397 # include "uaccess_32.h"
28399 # define ARCH_HAS_SEARCH_EXTABLE
28400 +# define ARCH_HAS_SORT_EXTABLE
28401 # include "uaccess_64.h"
28404 diff -urNp linux-2.6.27.4/include/asm-xtensa/kmap_types.h linux-2.6.27.4/include/asm-xtensa/kmap_types.h
28405 --- linux-2.6.27.4/include/asm-xtensa/kmap_types.h 2008-10-22 17:38:01.000000000 -0400
28406 +++ linux-2.6.27.4/include/asm-xtensa/kmap_types.h 2008-10-27 22:36:18.000000000 -0400
28407 @@ -25,6 +25,7 @@ enum km_type {
28415 diff -urNp linux-2.6.27.4/include/drm/drm_pciids.h linux-2.6.27.4/include/drm/drm_pciids.h
28416 --- linux-2.6.27.4/include/drm/drm_pciids.h 2008-10-22 17:38:01.000000000 -0400
28417 +++ linux-2.6.27.4/include/drm/drm_pciids.h 2008-10-27 22:36:18.000000000 -0400
28418 @@ -237,7 +237,7 @@
28419 {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
28420 {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
28421 {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
28423 + {0, 0, 0, 0, 0, 0}
28425 #define r128_PCI_IDS \
28426 {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28427 @@ -277,14 +277,14 @@
28428 {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28429 {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28430 {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28432 + {0, 0, 0, 0, 0, 0}
28434 #define mga_PCI_IDS \
28435 {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
28436 {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
28437 {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
28438 {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
28440 + {0, 0, 0, 0, 0, 0}
28442 #define mach64_PCI_IDS \
28443 {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28444 @@ -307,7 +307,7 @@
28445 {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28446 {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28447 {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28449 + {0, 0, 0, 0, 0, 0}
28451 #define sisdrv_PCI_IDS \
28452 {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28453 @@ -318,7 +318,7 @@
28454 {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28455 {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
28456 {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
28458 + {0, 0, 0, 0, 0, 0}
28460 #define tdfx_PCI_IDS \
28461 {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28462 @@ -327,7 +327,7 @@
28463 {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28464 {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28465 {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28467 + {0, 0, 0, 0, 0, 0}
28469 #define viadrv_PCI_IDS \
28470 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28471 @@ -339,25 +339,25 @@
28472 {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28473 {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
28474 {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
28476 + {0, 0, 0, 0, 0, 0}
28478 #define i810_PCI_IDS \
28479 {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28480 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28481 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28482 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28484 + {0, 0, 0, 0, 0, 0}
28486 #define i830_PCI_IDS \
28487 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28488 {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28489 {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28490 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28492 + {0, 0, 0, 0, 0, 0}
28494 #define gamma_PCI_IDS \
28495 {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28497 + {0, 0, 0, 0, 0, 0}
28499 #define savage_PCI_IDS \
28500 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
28501 @@ -383,10 +383,10 @@
28502 {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
28503 {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
28504 {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
28506 + {0, 0, 0, 0, 0, 0}
28508 #define ffb_PCI_IDS \
28510 + {0, 0, 0, 0, 0, 0}
28512 #define i915_PCI_IDS \
28513 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28514 @@ -412,4 +412,4 @@
28515 {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28516 {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28517 {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28519 + {0, 0, 0, 0, 0, 0}
28520 diff -urNp linux-2.6.27.4/include/linux/a.out.h linux-2.6.27.4/include/linux/a.out.h
28521 --- linux-2.6.27.4/include/linux/a.out.h 2008-10-22 17:38:01.000000000 -0400
28522 +++ linux-2.6.27.4/include/linux/a.out.h 2008-10-27 22:36:18.000000000 -0400
28523 @@ -39,6 +39,14 @@ enum machine_type {
28524 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
28527 +/* Constants for the N_FLAGS field */
28528 +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
28529 +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
28530 +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
28531 +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
28532 +/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
28533 +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
28535 #if !defined (N_MAGIC)
28536 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
28538 diff -urNp linux-2.6.27.4/include/linux/cache.h linux-2.6.27.4/include/linux/cache.h
28539 --- linux-2.6.27.4/include/linux/cache.h 2008-10-22 17:38:01.000000000 -0400
28540 +++ linux-2.6.27.4/include/linux/cache.h 2008-10-27 22:36:18.000000000 -0400
28542 #define __read_mostly
28545 +#ifndef __read_only
28546 +#define __read_only __read_mostly
28549 #ifndef ____cacheline_aligned
28550 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
28552 diff -urNp linux-2.6.27.4/include/linux/capability.h linux-2.6.27.4/include/linux/capability.h
28553 --- linux-2.6.27.4/include/linux/capability.h 2008-10-22 17:38:01.000000000 -0400
28554 +++ linux-2.6.27.4/include/linux/capability.h 2008-10-25 12:35:20.000000000 -0400
28555 @@ -516,6 +516,7 @@ kernel_cap_t cap_set_effective(const ker
28556 #define has_capability(t, cap) (security_capable((t), (cap)) == 0)
28558 extern int capable(int cap);
28559 +int capable_nolog(int cap);
28561 #endif /* __KERNEL__ */
28563 diff -urNp linux-2.6.27.4/include/linux/cpumask.h linux-2.6.27.4/include/linux/cpumask.h
28564 --- linux-2.6.27.4/include/linux/cpumask.h 2008-10-22 17:38:01.000000000 -0400
28565 +++ linux-2.6.27.4/include/linux/cpumask.h 2008-10-27 22:36:18.000000000 -0400
28566 @@ -139,7 +139,6 @@
28567 #include <linux/bitmap.h>
28569 typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
28570 -extern cpumask_t _unused_cpumask_arg_;
28572 #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
28573 static inline void __cpu_set(int cpu, volatile cpumask_t *dstp)
28574 diff -urNp linux-2.6.27.4/include/linux/elf.h linux-2.6.27.4/include/linux/elf.h
28575 --- linux-2.6.27.4/include/linux/elf.h 2008-10-22 17:38:01.000000000 -0400
28576 +++ linux-2.6.27.4/include/linux/elf.h 2008-10-27 22:36:18.000000000 -0400
28577 @@ -50,6 +50,16 @@ typedef __s64 Elf64_Sxword;
28579 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
28581 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
28583 +/* Constants for the e_flags field */
28584 +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
28585 +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
28586 +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
28587 +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
28588 +/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
28589 +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
28591 /* These constants define the different elf file types */
28594 @@ -84,6 +94,8 @@ typedef __s64 Elf64_Sxword;
28595 #define DT_DEBUG 21
28596 #define DT_TEXTREL 22
28597 #define DT_JMPREL 23
28598 +#define DT_FLAGS 30
28599 + #define DF_TEXTREL 0x00000004
28600 #define DT_ENCODING 32
28601 #define OLD_DT_LOOS 0x60000000
28602 #define DT_LOOS 0x6000000d
28603 @@ -230,6 +242,19 @@ typedef struct elf64_hdr {
28607 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
28608 +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
28609 +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
28610 +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
28611 +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
28612 +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
28613 +/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
28614 +/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
28615 +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
28616 +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
28617 +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
28618 +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
28620 typedef struct elf32_phdr{
28622 Elf32_Off p_offset;
28623 @@ -322,6 +347,8 @@ typedef struct elf64_shdr {
28629 #define ELFMAG0 0x7f /* EI_MAG */
28630 #define ELFMAG1 'E'
28631 #define ELFMAG2 'L'
28632 @@ -383,6 +410,7 @@ extern Elf32_Dyn _DYNAMIC [];
28633 #define elf_phdr elf32_phdr
28634 #define elf_note elf32_note
28635 #define elf_addr_t Elf32_Off
28636 +#define elf_dyn Elf32_Dyn
28640 @@ -391,6 +419,7 @@ extern Elf64_Dyn _DYNAMIC [];
28641 #define elf_phdr elf64_phdr
28642 #define elf_note elf64_note
28643 #define elf_addr_t Elf64_Off
28644 +#define elf_dyn Elf64_Dyn
28648 diff -urNp linux-2.6.27.4/include/linux/gracl.h linux-2.6.27.4/include/linux/gracl.h
28649 --- linux-2.6.27.4/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
28650 +++ linux-2.6.27.4/include/linux/gracl.h 2008-10-25 12:03:07.000000000 -0400
28655 +#include <linux/grdefs.h>
28656 +#include <linux/resource.h>
28657 +#include <linux/capability.h>
28658 +#include <linux/dcache.h>
28659 +#include <asm/resource.h>
28661 +/* Major status information */
28663 +#define GR_VERSION "grsecurity 2.1.12"
28664 +#define GRSECURITY_VERSION 0x2112
28679 +/* Password setup definitions
28680 + * kernel/grhash.c */
28683 + GR_SALT_LEN = 16,
28688 + GR_SPROLE_LEN = 64,
28691 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
28693 +/* Begin Data Structures */
28695 +struct sprole_pw {
28696 + unsigned char *rolename;
28697 + unsigned char salt[GR_SALT_LEN];
28698 + unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
28701 +struct name_entry {
28708 + struct name_entry *prev;
28709 + struct name_entry *next;
28712 +struct inodev_entry {
28713 + struct name_entry *nentry;
28714 + struct inodev_entry *prev;
28715 + struct inodev_entry *next;
28718 +struct acl_role_db {
28719 + struct acl_role_label **r_hash;
28723 +struct inodev_db {
28724 + struct inodev_entry **i_hash;
28729 + struct name_entry **n_hash;
28733 +struct crash_uid {
28735 + unsigned long expires;
28738 +struct gr_hash_struct {
28740 + void **nametable;
28742 + __u32 table_size;
28747 +/* Userspace Grsecurity ACL data structures */
28749 +struct acl_subject_label {
28754 + kernel_cap_t cap_mask;
28755 + kernel_cap_t cap_lower;
28757 + struct rlimit res[GR_NLIMITS];
28760 + __u8 user_trans_type;
28761 + __u8 group_trans_type;
28762 + uid_t *user_transitions;
28763 + gid_t *group_transitions;
28764 + __u16 user_trans_num;
28765 + __u16 group_trans_num;
28767 + __u32 ip_proto[8];
28769 + struct acl_ip_label **ips;
28773 + unsigned long expires;
28775 + struct acl_subject_label *parent_subject;
28776 + struct gr_hash_struct *hash;
28777 + struct acl_subject_label *prev;
28778 + struct acl_subject_label *next;
28780 + struct acl_object_label **obj_hash;
28781 + __u32 obj_hash_size;
28785 +struct role_allowed_ip {
28789 + struct role_allowed_ip *prev;
28790 + struct role_allowed_ip *next;
28793 +struct role_transition {
28796 + struct role_transition *prev;
28797 + struct role_transition *next;
28800 +struct acl_role_label {
28805 + __u16 auth_attempts;
28806 + unsigned long expires;
28808 + struct acl_subject_label *root_label;
28809 + struct gr_hash_struct *hash;
28811 + struct acl_role_label *prev;
28812 + struct acl_role_label *next;
28814 + struct role_transition *transitions;
28815 + struct role_allowed_ip *allowed_ips;
28816 + uid_t *domain_children;
28817 + __u16 domain_child_num;
28819 + struct acl_subject_label **subj_hash;
28820 + __u32 subj_hash_size;
28823 +struct user_acl_role_db {
28824 + struct acl_role_label **r_table;
28825 + __u32 num_pointers; /* Number of allocations to track */
28826 + __u32 num_roles; /* Number of roles */
28827 + __u32 num_domain_children; /* Number of domain children */
28828 + __u32 num_subjects; /* Number of subjects */
28829 + __u32 num_objects; /* Number of objects */
28832 +struct acl_object_label {
28838 + struct acl_subject_label *nested;
28839 + struct acl_object_label *globbed;
28841 + /* next two structures not used */
28843 + struct acl_object_label *prev;
28844 + struct acl_object_label *next;
28847 +struct acl_ip_label {
28856 + /* next two structures not used */
28858 + struct acl_ip_label *prev;
28859 + struct acl_ip_label *next;
28863 + struct user_acl_role_db role_db;
28864 + unsigned char pw[GR_PW_LEN];
28865 + unsigned char salt[GR_SALT_LEN];
28866 + unsigned char sum[GR_SHA_LEN];
28867 + unsigned char sp_role[GR_SPROLE_LEN];
28868 + struct sprole_pw *sprole_pws;
28869 + dev_t segv_device;
28870 + ino_t segv_inode;
28872 + __u16 num_sprole_pws;
28876 +struct gr_arg_wrapper {
28877 + struct gr_arg *arg;
28882 +struct subject_map {
28883 + struct acl_subject_label *user;
28884 + struct acl_subject_label *kernel;
28885 + struct subject_map *prev;
28886 + struct subject_map *next;
28889 +struct acl_subj_map_db {
28890 + struct subject_map **s_hash;
28894 +/* End Data Structures Section */
28896 +/* Hash functions generated by empirical testing by Brad Spengler
28897 + Makes good use of the low bits of the inode. Generally 0-1 times
28898 + in loop for successful match. 0-3 for unsuccessful match.
28899 + Shift/add algorithm with modulus of table size and an XOR*/
28901 +static __inline__ unsigned int
28902 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
28904 + return (((uid << type) + (uid ^ type)) % sz);
28907 + static __inline__ unsigned int
28908 +shash(const struct acl_subject_label *userp, const unsigned int sz)
28910 + return ((const unsigned long)userp % sz);
28913 +static __inline__ unsigned int
28914 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
28916 + return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
28919 +static __inline__ unsigned int
28920 +nhash(const char *name, const __u16 len, const unsigned int sz)
28922 + return full_name_hash(name, len) % sz;
28925 +#define FOR_EACH_ROLE_START(role,iter) \
28928 + while (iter < acl_role_set.r_size) { \
28929 + if (role == NULL) \
28930 + role = acl_role_set.r_hash[iter]; \
28931 + if (role == NULL) { \
28936 +#define FOR_EACH_ROLE_END(role,iter) \
28937 + role = role->next; \
28938 + if (role == NULL) \
28942 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
28945 + while (iter < role->subj_hash_size) { \
28946 + if (subj == NULL) \
28947 + subj = role->subj_hash[iter]; \
28948 + if (subj == NULL) { \
28953 +#define FOR_EACH_SUBJECT_END(subj,iter) \
28954 + subj = subj->next; \
28955 + if (subj == NULL) \
28960 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
28961 + subj = role->hash->first; \
28962 + while (subj != NULL) {
28964 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
28965 + subj = subj->next; \
28970 diff -urNp linux-2.6.27.4/include/linux/gralloc.h linux-2.6.27.4/include/linux/gralloc.h
28971 --- linux-2.6.27.4/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
28972 +++ linux-2.6.27.4/include/linux/gralloc.h 2008-10-25 12:03:07.000000000 -0400
28974 +#ifndef __GRALLOC_H
28975 +#define __GRALLOC_H
28977 +void acl_free_all(void);
28978 +int acl_alloc_stack_init(unsigned long size);
28979 +void *acl_alloc(unsigned long len);
28982 diff -urNp linux-2.6.27.4/include/linux/grdefs.h linux-2.6.27.4/include/linux/grdefs.h
28983 --- linux-2.6.27.4/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
28984 +++ linux-2.6.27.4/include/linux/grdefs.h 2008-10-25 12:03:07.000000000 -0400
28989 +/* Begin grsecurity status declarations */
28993 + GR_STATUS_INIT = 0x00 // disabled state
28996 +/* Begin ACL declarations */
29001 + GR_ROLE_USER = 0x0001,
29002 + GR_ROLE_GROUP = 0x0002,
29003 + GR_ROLE_DEFAULT = 0x0004,
29004 + GR_ROLE_SPECIAL = 0x0008,
29005 + GR_ROLE_AUTH = 0x0010,
29006 + GR_ROLE_NOPW = 0x0020,
29007 + GR_ROLE_GOD = 0x0040,
29008 + GR_ROLE_LEARN = 0x0080,
29009 + GR_ROLE_TPE = 0x0100,
29010 + GR_ROLE_DOMAIN = 0x0200,
29011 + GR_ROLE_PAM = 0x0400
29014 +/* ACL Subject and Object mode flags */
29016 + GR_DELETED = 0x80000000
29019 +/* ACL Object-only mode flags */
29021 + GR_READ = 0x00000001,
29022 + GR_APPEND = 0x00000002,
29023 + GR_WRITE = 0x00000004,
29024 + GR_EXEC = 0x00000008,
29025 + GR_FIND = 0x00000010,
29026 + GR_INHERIT = 0x00000020,
29027 + GR_SETID = 0x00000040,
29028 + GR_CREATE = 0x00000080,
29029 + GR_DELETE = 0x00000100,
29030 + GR_LINK = 0x00000200,
29031 + GR_AUDIT_READ = 0x00000400,
29032 + GR_AUDIT_APPEND = 0x00000800,
29033 + GR_AUDIT_WRITE = 0x00001000,
29034 + GR_AUDIT_EXEC = 0x00002000,
29035 + GR_AUDIT_FIND = 0x00004000,
29036 + GR_AUDIT_INHERIT= 0x00008000,
29037 + GR_AUDIT_SETID = 0x00010000,
29038 + GR_AUDIT_CREATE = 0x00020000,
29039 + GR_AUDIT_DELETE = 0x00040000,
29040 + GR_AUDIT_LINK = 0x00080000,
29041 + GR_PTRACERD = 0x00100000,
29042 + GR_NOPTRACE = 0x00200000,
29043 + GR_SUPPRESS = 0x00400000,
29044 + GR_NOLEARN = 0x00800000
29047 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
29048 + GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
29049 + GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
29051 +/* ACL subject-only mode flags */
29053 + GR_KILL = 0x00000001,
29054 + GR_VIEW = 0x00000002,
29055 + GR_PROTECTED = 0x00000004,
29056 + GR_LEARN = 0x00000008,
29057 + GR_OVERRIDE = 0x00000010,
29058 + /* just a placeholder, this mode is only used in userspace */
29059 + GR_DUMMY = 0x00000020,
29060 + GR_PROTSHM = 0x00000040,
29061 + GR_KILLPROC = 0x00000080,
29062 + GR_KILLIPPROC = 0x00000100,
29063 + /* just a placeholder, this mode is only used in userspace */
29064 + GR_NOTROJAN = 0x00000200,
29065 + GR_PROTPROCFD = 0x00000400,
29066 + GR_PROCACCT = 0x00000800,
29067 + GR_RELAXPTRACE = 0x00001000,
29068 + GR_NESTED = 0x00002000,
29069 + GR_INHERITLEARN = 0x00004000,
29070 + GR_PROCFIND = 0x00008000,
29071 + GR_POVERRIDE = 0x00010000,
29072 + GR_KERNELAUTH = 0x00020000,
29076 + GR_PAX_ENABLE_SEGMEXEC = 0x0001,
29077 + GR_PAX_ENABLE_PAGEEXEC = 0x0002,
29078 + GR_PAX_ENABLE_MPROTECT = 0x0004,
29079 + GR_PAX_ENABLE_RANDMMAP = 0x0008,
29080 + GR_PAX_ENABLE_EMUTRAMP = 0x0010,
29081 + GR_PAX_DISABLE_SEGMEXEC = 0x0100,
29082 + GR_PAX_DISABLE_PAGEEXEC = 0x0200,
29083 + GR_PAX_DISABLE_MPROTECT = 0x0400,
29084 + GR_PAX_DISABLE_RANDMMAP = 0x0800,
29085 + GR_PAX_DISABLE_EMUTRAMP = 0x1000,
29089 + GR_ID_USER = 0x01,
29090 + GR_ID_GROUP = 0x02,
29094 + GR_ID_ALLOW = 0x01,
29095 + GR_ID_DENY = 0x02,
29098 +#define GR_CRASH_RES 11
29099 +#define GR_UIDTABLE_MAX 500
29101 +/* begin resource learning section */
29103 + GR_RLIM_CPU_BUMP = 60,
29104 + GR_RLIM_FSIZE_BUMP = 50000,
29105 + GR_RLIM_DATA_BUMP = 10000,
29106 + GR_RLIM_STACK_BUMP = 1000,
29107 + GR_RLIM_CORE_BUMP = 10000,
29108 + GR_RLIM_RSS_BUMP = 500000,
29109 + GR_RLIM_NPROC_BUMP = 1,
29110 + GR_RLIM_NOFILE_BUMP = 5,
29111 + GR_RLIM_MEMLOCK_BUMP = 50000,
29112 + GR_RLIM_AS_BUMP = 500000,
29113 + GR_RLIM_LOCKS_BUMP = 2
29117 diff -urNp linux-2.6.27.4/include/linux/grinternal.h linux-2.6.27.4/include/linux/grinternal.h
29118 --- linux-2.6.27.4/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
29119 +++ linux-2.6.27.4/include/linux/grinternal.h 2008-10-25 12:03:07.000000000 -0400
29121 +#ifndef __GRINTERNAL_H
29122 +#define __GRINTERNAL_H
29124 +#ifdef CONFIG_GRKERNSEC
29126 +#include <linux/fs.h>
29127 +#include <linux/gracl.h>
29128 +#include <linux/grdefs.h>
29129 +#include <linux/grmsg.h>
29131 +void gr_add_learn_entry(const char *fmt, ...);
29132 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
29133 + const struct vfsmount *mnt);
29134 +__u32 gr_check_create(const struct dentry *new_dentry,
29135 + const struct dentry *parent,
29136 + const struct vfsmount *mnt, const __u32 mode);
29137 +int gr_check_protected_task(const struct task_struct *task);
29138 +__u32 to_gr_audit(const __u32 reqmode);
29139 +int gr_set_acls(const int type);
29141 +int gr_acl_is_enabled(void);
29142 +char gr_roletype_to_char(void);
29144 +void gr_handle_alertkill(struct task_struct *task);
29145 +char *gr_to_filename(const struct dentry *dentry,
29146 + const struct vfsmount *mnt);
29147 +char *gr_to_filename1(const struct dentry *dentry,
29148 + const struct vfsmount *mnt);
29149 +char *gr_to_filename2(const struct dentry *dentry,
29150 + const struct vfsmount *mnt);
29151 +char *gr_to_filename3(const struct dentry *dentry,
29152 + const struct vfsmount *mnt);
29154 +extern int grsec_enable_link;
29155 +extern int grsec_enable_fifo;
29156 +extern int grsec_enable_execve;
29157 +extern int grsec_enable_shm;
29158 +extern int grsec_enable_execlog;
29159 +extern int grsec_enable_signal;
29160 +extern int grsec_enable_forkfail;
29161 +extern int grsec_enable_time;
29162 +extern int grsec_enable_chroot_shmat;
29163 +extern int grsec_enable_chroot_findtask;
29164 +extern int grsec_enable_chroot_mount;
29165 +extern int grsec_enable_chroot_double;
29166 +extern int grsec_enable_chroot_pivot;
29167 +extern int grsec_enable_chroot_chdir;
29168 +extern int grsec_enable_chroot_chmod;
29169 +extern int grsec_enable_chroot_mknod;
29170 +extern int grsec_enable_chroot_fchdir;
29171 +extern int grsec_enable_chroot_nice;
29172 +extern int grsec_enable_chroot_execlog;
29173 +extern int grsec_enable_chroot_caps;
29174 +extern int grsec_enable_chroot_sysctl;
29175 +extern int grsec_enable_chroot_unix;
29176 +extern int grsec_enable_tpe;
29177 +extern int grsec_tpe_gid;
29178 +extern int grsec_enable_tpe_all;
29179 +extern int grsec_enable_sidcaps;
29180 +extern int grsec_enable_socket_all;
29181 +extern int grsec_socket_all_gid;
29182 +extern int grsec_enable_socket_client;
29183 +extern int grsec_socket_client_gid;
29184 +extern int grsec_enable_socket_server;
29185 +extern int grsec_socket_server_gid;
29186 +extern int grsec_audit_gid;
29187 +extern int grsec_enable_group;
29188 +extern int grsec_enable_audit_ipc;
29189 +extern int grsec_enable_audit_textrel;
29190 +extern int grsec_enable_mount;
29191 +extern int grsec_enable_chdir;
29192 +extern int grsec_resource_logging;
29193 +extern int grsec_lock;
29195 +extern spinlock_t grsec_alert_lock;
29196 +extern unsigned long grsec_alert_wtime;
29197 +extern unsigned long grsec_alert_fyet;
29199 +extern spinlock_t grsec_audit_lock;
29201 +extern rwlock_t grsec_exec_file_lock;
29203 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
29204 + gr_to_filename2(tsk->exec_file->f_path.dentry, \
29205 + tsk->exec_file->f_vfsmnt) : "/")
29207 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
29208 + gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
29209 + tsk->parent->exec_file->f_vfsmnt) : "/")
29211 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
29212 + gr_to_filename(tsk->exec_file->f_path.dentry, \
29213 + tsk->exec_file->f_vfsmnt) : "/")
29215 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
29216 + gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
29217 + tsk->parent->exec_file->f_vfsmnt) : "/")
29219 +#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
29220 + ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
29221 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
29222 + (tsk_a->fs->root.dentry->d_inode->i_ino != \
29223 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
29225 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
29226 + (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
29227 + tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
29228 + (tsk_a->fs->root.dentry->d_inode->i_ino == \
29229 + tsk_b->fs->root.dentry->d_inode->i_ino))
29231 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
29232 + task->pid, task->uid, \
29233 + task->euid, task->gid, task->egid, \
29234 + gr_parent_task_fullpath(task), \
29235 + task->parent->comm, task->parent->pid, \
29236 + task->parent->uid, task->parent->euid, \
29237 + task->parent->gid, task->parent->egid
29239 +#define GR_CHROOT_CAPS {{ \
29240 + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
29241 + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
29242 + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
29243 + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
29244 + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
29245 + CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
29247 +#define security_learn(normal_msg,args...) \
29249 + read_lock(&grsec_exec_file_lock); \
29250 + gr_add_learn_entry(normal_msg "\n", ## args); \
29251 + read_unlock(&grsec_exec_file_lock); \
29257 + GR_DONT_AUDIT_GOOD
29268 + GR_SYSCTL_HIDDEN,
29271 + GR_ONE_INT_TWO_STR,
29276 + GR_FIVE_INT_TWO_STR,
29282 + GR_FILENAME_TWO_INT,
29283 + GR_FILENAME_TWO_INT_STR,
29294 +#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
29295 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
29296 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
29297 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
29298 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
29299 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
29300 +#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)
29301 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
29302 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
29303 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
29304 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
29305 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
29306 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
29307 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
29308 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
29309 +#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)
29310 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
29311 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
29312 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
29313 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
29314 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
29315 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
29316 +#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)
29317 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
29318 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
29319 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
29320 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
29321 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
29322 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
29323 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
29324 +#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)
29326 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
29331 diff -urNp linux-2.6.27.4/include/linux/grmsg.h linux-2.6.27.4/include/linux/grmsg.h
29332 --- linux-2.6.27.4/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
29333 +++ linux-2.6.27.4/include/linux/grmsg.h 2008-10-26 02:47:18.000000000 -0400
29335 +#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"
29336 +#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"
29337 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
29338 +#define GR_STOPMOD_MSG "denied modification of module state by "
29339 +#define GR_IOPERM_MSG "denied use of ioperm() by "
29340 +#define GR_IOPL_MSG "denied use of iopl() by "
29341 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
29342 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
29343 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
29344 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
29345 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
29346 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
29347 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
29348 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
29349 +#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"
29350 +#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"
29351 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
29352 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
29353 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
29354 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
29355 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
29356 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
29357 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
29358 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
29359 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
29360 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
29361 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
29362 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
29363 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
29364 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
29365 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
29366 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
29367 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
29368 +#define GR_NPROC_MSG "denied overstep of process limit by "
29369 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
29370 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
29371 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
29372 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
29373 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
29374 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
29375 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
29376 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
29377 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
29378 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
29379 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
29380 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
29381 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
29382 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
29383 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
29384 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
29385 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
29386 +#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"
29387 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
29388 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
29389 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
29390 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
29391 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
29392 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
29393 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
29394 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
29395 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
29396 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
29397 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
29398 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
29399 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
29400 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
29401 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
29402 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
29403 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
29404 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
29405 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
29406 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
29407 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
29408 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
29409 +#define GR_NICE_CHROOT_MSG "denied priority change by "
29410 +#define GR_UNISIGLOG_MSG "signal %d sent to "
29411 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
29412 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
29413 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
29414 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
29415 +#define GR_TIME_MSG "time set by "
29416 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
29417 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
29418 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
29419 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
29420 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
29421 +#define GR_BIND_MSG "denied bind() by "
29422 +#define GR_CONNECT_MSG "denied connect() by "
29423 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
29424 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
29425 +#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"
29426 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
29427 +#define GR_CAP_ACL_MSG "use of %s denied for "
29428 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
29429 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
29430 +#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
29431 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
29432 +#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
29433 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
29434 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
29435 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
29436 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
29437 +#define GR_SEM_AUDIT_MSG "semaphore created by "
29438 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
29439 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
29440 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
29441 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
29442 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
29443 diff -urNp linux-2.6.27.4/include/linux/grsecurity.h linux-2.6.27.4/include/linux/grsecurity.h
29444 --- linux-2.6.27.4/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
29445 +++ linux-2.6.27.4/include/linux/grsecurity.h 2008-10-25 12:03:07.000000000 -0400
29447 +#ifndef GR_SECURITY_H
29448 +#define GR_SECURITY_H
29449 +#include <linux/fs.h>
29450 +#include <linux/binfmts.h>
29451 +#include <linux/gracl.h>
29453 +/* notify of brain-dead configs */
29454 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
29455 +#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
29457 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
29458 +#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
29460 +#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
29461 +#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
29463 +#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
29464 +#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
29466 +#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
29467 +#error "CONFIG_PAX enabled, but no PaX options are enabled."
29470 +void gr_handle_brute_attach(struct task_struct *p);
29471 +void gr_handle_brute_check(void);
29473 +char gr_roletype_to_char(void);
29475 +int gr_check_user_change(int real, int effective, int fs);
29476 +int gr_check_group_change(int real, int effective, int fs);
29478 +void gr_del_task_from_ip_table(struct task_struct *p);
29480 +int gr_pid_is_chrooted(struct task_struct *p);
29481 +int gr_handle_chroot_nice(void);
29482 +int gr_handle_chroot_sysctl(const int op);
29483 +int gr_handle_chroot_setpriority(struct task_struct *p,
29484 + const int niceval);
29485 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
29486 +int gr_handle_chroot_chroot(const struct dentry *dentry,
29487 + const struct vfsmount *mnt);
29488 +void gr_handle_chroot_caps(struct task_struct *task);
29489 +void gr_handle_chroot_chdir(struct path *path);
29490 +int gr_handle_chroot_chmod(const struct dentry *dentry,
29491 + const struct vfsmount *mnt, const int mode);
29492 +int gr_handle_chroot_mknod(const struct dentry *dentry,
29493 + const struct vfsmount *mnt, const int mode);
29494 +int gr_handle_chroot_mount(const struct dentry *dentry,
29495 + const struct vfsmount *mnt,
29496 + const char *dev_name);
29497 +int gr_handle_chroot_pivot(void);
29498 +int gr_handle_chroot_unix(const pid_t pid);
29500 +int gr_handle_rawio(const struct inode *inode);
29501 +int gr_handle_nproc(void);
29503 +void gr_handle_ioperm(void);
29504 +void gr_handle_iopl(void);
29506 +int gr_tpe_allow(const struct file *file);
29508 +int gr_random_pid(void);
29510 +void gr_log_forkfail(const int retval);
29511 +void gr_log_timechange(void);
29512 +void gr_log_signal(const int sig, const struct task_struct *t);
29513 +void gr_log_chdir(const struct dentry *dentry,
29514 + const struct vfsmount *mnt);
29515 +void gr_log_chroot_exec(const struct dentry *dentry,
29516 + const struct vfsmount *mnt);
29517 +void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
29518 +void gr_log_remount(const char *devname, const int retval);
29519 +void gr_log_unmount(const char *devname, const int retval);
29520 +void gr_log_mount(const char *from, const char *to, const int retval);
29521 +void gr_log_msgget(const int ret, const int msgflg);
29522 +void gr_log_msgrm(const uid_t uid, const uid_t cuid);
29523 +void gr_log_semget(const int err, const int semflg);
29524 +void gr_log_semrm(const uid_t uid, const uid_t cuid);
29525 +void gr_log_shmget(const int err, const int shmflg, const size_t size);
29526 +void gr_log_shmrm(const uid_t uid, const uid_t cuid);
29527 +void gr_log_textrel(struct vm_area_struct *vma);
29529 +int gr_handle_follow_link(const struct inode *parent,
29530 + const struct inode *inode,
29531 + const struct dentry *dentry,
29532 + const struct vfsmount *mnt);
29533 +int gr_handle_fifo(const struct dentry *dentry,
29534 + const struct vfsmount *mnt,
29535 + const struct dentry *dir, const int flag,
29536 + const int acc_mode);
29537 +int gr_handle_hardlink(const struct dentry *dentry,
29538 + const struct vfsmount *mnt,
29539 + struct inode *inode,
29540 + const int mode, const char *to);
29542 +int gr_task_is_capable(struct task_struct *task, const int cap);
29543 +int gr_is_capable_nolog(const int cap);
29544 +void gr_learn_resource(const struct task_struct *task, const int limit,
29545 + const unsigned long wanted, const int gt);
29546 +void gr_copy_label(struct task_struct *tsk);
29547 +void gr_handle_crash(struct task_struct *task, const int sig);
29548 +int gr_handle_signal(const struct task_struct *p, const int sig);
29549 +int gr_check_crash_uid(const uid_t uid);
29550 +int gr_check_protected_task(const struct task_struct *task);
29551 +int gr_acl_handle_mmap(const struct file *file,
29552 + const unsigned long prot);
29553 +int gr_acl_handle_mprotect(const struct file *file,
29554 + const unsigned long prot);
29555 +int gr_check_hidden_task(const struct task_struct *tsk);
29556 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
29557 + const struct vfsmount *mnt);
29558 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
29559 + const struct vfsmount *mnt);
29560 +__u32 gr_acl_handle_access(const struct dentry *dentry,
29561 + const struct vfsmount *mnt, const int fmode);
29562 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
29563 + const struct vfsmount *mnt, mode_t mode);
29564 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
29565 + const struct vfsmount *mnt, mode_t mode);
29566 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
29567 + const struct vfsmount *mnt);
29568 +int gr_handle_ptrace(struct task_struct *task, const long request);
29569 +int gr_handle_proc_ptrace(struct task_struct *task);
29570 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
29571 + const struct vfsmount *mnt);
29572 +int gr_check_crash_exec(const struct file *filp);
29573 +int gr_acl_is_enabled(void);
29574 +void gr_set_kernel_label(struct task_struct *task);
29575 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
29576 + const gid_t gid);
29577 +int gr_set_proc_label(const struct dentry *dentry,
29578 + const struct vfsmount *mnt);
29579 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
29580 + const struct vfsmount *mnt);
29581 +__u32 gr_acl_handle_open(const struct dentry *dentry,
29582 + const struct vfsmount *mnt, const int fmode);
29583 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
29584 + const struct dentry *p_dentry,
29585 + const struct vfsmount *p_mnt, const int fmode,
29586 + const int imode);
29587 +void gr_handle_create(const struct dentry *dentry,
29588 + const struct vfsmount *mnt);
29589 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
29590 + const struct dentry *parent_dentry,
29591 + const struct vfsmount *parent_mnt,
29593 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
29594 + const struct dentry *parent_dentry,
29595 + const struct vfsmount *parent_mnt);
29596 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
29597 + const struct vfsmount *mnt);
29598 +void gr_handle_delete(const ino_t ino, const dev_t dev);
29599 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
29600 + const struct vfsmount *mnt);
29601 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
29602 + const struct dentry *parent_dentry,
29603 + const struct vfsmount *parent_mnt,
29604 + const char *from);
29605 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
29606 + const struct dentry *parent_dentry,
29607 + const struct vfsmount *parent_mnt,
29608 + const struct dentry *old_dentry,
29609 + const struct vfsmount *old_mnt, const char *to);
29610 +int gr_acl_handle_rename(struct dentry *new_dentry,
29611 + struct dentry *parent_dentry,
29612 + const struct vfsmount *parent_mnt,
29613 + struct dentry *old_dentry,
29614 + struct inode *old_parent_inode,
29615 + struct vfsmount *old_mnt, const char *newname);
29616 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
29617 + struct dentry *old_dentry,
29618 + struct dentry *new_dentry,
29619 + struct vfsmount *mnt, const __u8 replace);
29620 +__u32 gr_check_link(const struct dentry *new_dentry,
29621 + const struct dentry *parent_dentry,
29622 + const struct vfsmount *parent_mnt,
29623 + const struct dentry *old_dentry,
29624 + const struct vfsmount *old_mnt);
29625 +int gr_acl_handle_filldir(const struct file *file, const char *name,
29626 + const unsigned int namelen, const ino_t ino);
29628 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
29629 + const struct vfsmount *mnt);
29630 +void gr_acl_handle_exit(void);
29631 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
29632 +int gr_acl_handle_procpidmem(const struct task_struct *task);
29634 +#ifdef CONFIG_GRKERNSEC
29635 +void gr_handle_mem_write(void);
29636 +void gr_handle_kmem_write(void);
29637 +void gr_handle_open_port(void);
29638 +int gr_handle_mem_mmap(const unsigned long offset,
29639 + struct vm_area_struct *vma);
29641 +extern int grsec_enable_dmesg;
29642 +extern int grsec_enable_randsrc;
29643 +extern int grsec_enable_shm;
29647 diff -urNp linux-2.6.27.4/include/linux/highmem.h linux-2.6.27.4/include/linux/highmem.h
29648 --- linux-2.6.27.4/include/linux/highmem.h 2008-10-22 17:38:01.000000000 -0400
29649 +++ linux-2.6.27.4/include/linux/highmem.h 2008-10-27 22:36:18.000000000 -0400
29650 @@ -122,6 +122,13 @@ static inline void clear_highpage(struct
29651 kunmap_atomic(kaddr, KM_USER0);
29654 +static inline void sanitize_highpage(struct page *page)
29656 + void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
29657 + clear_page(kaddr);
29658 + kunmap_atomic(kaddr, KM_CLEARPAGE);
29661 static inline void zero_user_segments(struct page *page,
29662 unsigned start1, unsigned end1,
29663 unsigned start2, unsigned end2)
29664 diff -urNp linux-2.6.27.4/include/linux/jbd2.h linux-2.6.27.4/include/linux/jbd2.h
29665 --- linux-2.6.27.4/include/linux/jbd2.h 2008-10-22 17:38:01.000000000 -0400
29666 +++ linux-2.6.27.4/include/linux/jbd2.h 2008-10-27 22:36:18.000000000 -0400
29667 @@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
29671 -#define jbd_debug(f, a...) /**/
29672 +#define jbd_debug(f, a...) do {} while (0)
29675 static inline void *jbd2_alloc(size_t size, gfp_t flags)
29676 diff -urNp linux-2.6.27.4/include/linux/jbd.h linux-2.6.27.4/include/linux/jbd.h
29677 --- linux-2.6.27.4/include/linux/jbd.h 2008-10-22 17:38:01.000000000 -0400
29678 +++ linux-2.6.27.4/include/linux/jbd.h 2008-10-27 22:36:18.000000000 -0400
29679 @@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
29683 -#define jbd_debug(f, a...) /**/
29684 +#define jbd_debug(f, a...) do {} while (0)
29687 static inline void *jbd_alloc(size_t size, gfp_t flags)
29688 diff -urNp linux-2.6.27.4/include/linux/libata.h linux-2.6.27.4/include/linux/libata.h
29689 --- linux-2.6.27.4/include/linux/libata.h 2008-10-22 17:38:01.000000000 -0400
29690 +++ linux-2.6.27.4/include/linux/libata.h 2008-10-27 22:36:18.000000000 -0400
29691 @@ -64,11 +64,11 @@
29692 #ifdef ATA_VERBOSE_DEBUG
29693 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
29695 -#define VPRINTK(fmt, args...)
29696 +#define VPRINTK(fmt, args...) do {} while (0)
29697 #endif /* ATA_VERBOSE_DEBUG */
29699 -#define DPRINTK(fmt, args...)
29700 -#define VPRINTK(fmt, args...)
29701 +#define DPRINTK(fmt, args...) do {} while (0)
29702 +#define VPRINTK(fmt, args...) do {} while (0)
29703 #endif /* ATA_DEBUG */
29705 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
29706 diff -urNp linux-2.6.27.4/include/linux/mm.h linux-2.6.27.4/include/linux/mm.h
29707 --- linux-2.6.27.4/include/linux/mm.h 2008-10-22 17:38:01.000000000 -0400
29708 +++ linux-2.6.27.4/include/linux/mm.h 2008-10-27 22:36:18.000000000 -0400
29709 @@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
29710 #include <asm/page.h>
29711 #include <asm/pgtable.h>
29712 #include <asm/processor.h>
29713 +#include <asm/mman.h>
29715 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
29717 @@ -114,6 +115,14 @@ extern unsigned int kobjsize(const void
29718 #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
29719 #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
29721 +#ifdef CONFIG_PAX_PAGEEXEC
29722 +#define VM_PAGEEXEC 0x40000000 /* vma->vm_page_prot needs special handling */
29725 +#ifdef CONFIG_PAX_MPROTECT
29726 +#define VM_MAYNOTWRITE 0x80000000 /* vma cannot be granted VM_WRITE any more */
29729 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
29730 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
29732 @@ -874,6 +883,8 @@ struct shrinker {
29733 extern void register_shrinker(struct shrinker *);
29734 extern void unregister_shrinker(struct shrinker *);
29736 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
29738 int vma_wants_writenotify(struct vm_area_struct *vma);
29740 extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
29741 @@ -1129,6 +1140,7 @@ out:
29744 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
29745 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
29747 extern unsigned long do_brk(unsigned long, unsigned long);
29749 @@ -1181,6 +1193,10 @@ extern struct vm_area_struct * find_vma(
29750 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
29751 struct vm_area_struct **pprev);
29753 +extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
29754 +extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
29755 +extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
29757 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
29758 NULL if none. Assume start_addr < end_addr. */
29759 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
29760 @@ -1197,7 +1213,6 @@ static inline unsigned long vma_pages(st
29761 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
29764 -pgprot_t vm_get_page_prot(unsigned long vm_flags);
29765 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
29766 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
29767 unsigned long pfn, unsigned long size, pgprot_t);
29768 @@ -1286,5 +1301,11 @@ int vmemmap_populate_basepages(struct pa
29769 int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
29770 void vmemmap_populate_print_last(void);
29772 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
29773 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
29775 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
29778 #endif /* __KERNEL__ */
29779 #endif /* _LINUX_MM_H */
29780 diff -urNp linux-2.6.27.4/include/linux/mm_types.h linux-2.6.27.4/include/linux/mm_types.h
29781 --- linux-2.6.27.4/include/linux/mm_types.h 2008-10-22 17:38:01.000000000 -0400
29782 +++ linux-2.6.27.4/include/linux/mm_types.h 2008-10-27 22:36:18.000000000 -0400
29783 @@ -158,6 +158,8 @@ struct vm_area_struct {
29785 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
29788 + struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
29791 struct core_thread {
29792 @@ -257,6 +259,24 @@ struct mm_struct {
29793 #ifdef CONFIG_MMU_NOTIFIER
29794 struct mmu_notifier_mm *mmu_notifier_mm;
29797 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
29798 + unsigned long pax_flags;
29801 +#ifdef CONFIG_PAX_DLRESOLVE
29802 + unsigned long call_dl_resolve;
29805 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
29806 + unsigned long call_syscall;
29809 +#ifdef CONFIG_PAX_ASLR
29810 + unsigned long delta_mmap; /* randomized offset */
29811 + unsigned long delta_stack; /* randomized offset */
29816 #endif /* _LINUX_MM_TYPES_H */
29817 diff -urNp linux-2.6.27.4/include/linux/module.h linux-2.6.27.4/include/linux/module.h
29818 --- linux-2.6.27.4/include/linux/module.h 2008-10-22 17:38:01.000000000 -0400
29819 +++ linux-2.6.27.4/include/linux/module.h 2008-10-27 22:36:18.000000000 -0400
29820 @@ -282,16 +282,16 @@ struct module
29823 /* If this is non-NULL, vfree after init() returns */
29824 - void *module_init;
29825 + void *module_init_rx, *module_init_rw;
29827 /* Here is the actual code + data, vfree'd on unload. */
29828 - void *module_core;
29829 + void *module_core_rx, *module_core_rw;
29831 /* Here are the sizes of the init and core sections */
29832 - unsigned int init_size, core_size;
29833 + unsigned int init_size_rw, core_size_rw;
29835 /* The size of the executable code in each section. */
29836 - unsigned int init_text_size, core_text_size;
29837 + unsigned int init_size_rx, core_size_rx;
29839 /* The handle returned from unwind_add_table. */
29841 diff -urNp linux-2.6.27.4/include/linux/moduleloader.h linux-2.6.27.4/include/linux/moduleloader.h
29842 --- linux-2.6.27.4/include/linux/moduleloader.h 2008-10-22 17:38:01.000000000 -0400
29843 +++ linux-2.6.27.4/include/linux/moduleloader.h 2008-10-27 22:36:18.000000000 -0400
29844 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
29845 sections. Returns NULL on failure. */
29846 void *module_alloc(unsigned long size);
29848 +#ifdef CONFIG_PAX_KERNEXEC
29849 +void *module_alloc_exec(unsigned long size);
29851 +#define module_alloc_exec(x) module_alloc(x)
29854 /* Free memory returned from module_alloc. */
29855 void module_free(struct module *mod, void *module_region);
29857 +#ifdef CONFIG_PAX_KERNEXEC
29858 +void module_free_exec(struct module *mod, void *module_region);
29860 +#define module_free_exec(x, y) module_free(x, y)
29863 /* Apply the given relocation to the (simplified) ELF. Return -error
29865 int apply_relocate(Elf_Shdr *sechdrs,
29866 diff -urNp linux-2.6.27.4/include/linux/namei.h linux-2.6.27.4/include/linux/namei.h
29867 --- linux-2.6.27.4/include/linux/namei.h 2008-10-22 17:38:01.000000000 -0400
29868 +++ linux-2.6.27.4/include/linux/namei.h 2008-10-27 22:36:18.000000000 -0400
29869 @@ -21,7 +21,7 @@ struct nameidata {
29870 unsigned int flags;
29873 - char *saved_names[MAX_NESTED_LINKS + 1];
29874 + const char *saved_names[MAX_NESTED_LINKS + 1];
29878 @@ -80,12 +80,12 @@ extern int follow_up(struct vfsmount **,
29879 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
29880 extern void unlock_rename(struct dentry *, struct dentry *);
29882 -static inline void nd_set_link(struct nameidata *nd, char *path)
29883 +static inline void nd_set_link(struct nameidata *nd, const char *path)
29885 nd->saved_names[nd->depth] = path;
29888 -static inline char *nd_get_link(struct nameidata *nd)
29889 +static inline const char *nd_get_link(struct nameidata *nd)
29891 return nd->saved_names[nd->depth];
29893 diff -urNp linux-2.6.27.4/include/linux/nodemask.h linux-2.6.27.4/include/linux/nodemask.h
29894 --- linux-2.6.27.4/include/linux/nodemask.h 2008-10-22 17:38:01.000000000 -0400
29895 +++ linux-2.6.27.4/include/linux/nodemask.h 2008-10-27 22:36:18.000000000 -0400
29896 @@ -442,11 +442,11 @@ static inline int num_node_state(enum no
29898 #define any_online_node(mask) \
29901 - for_each_node_mask(node, (mask)) \
29902 - if (node_online(node)) \
29904 + for_each_node_mask(__node, (mask)) \
29905 + if (node_online(__node)) \
29911 #define num_online_nodes() num_node_state(N_ONLINE)
29912 diff -urNp linux-2.6.27.4/include/linux/percpu.h linux-2.6.27.4/include/linux/percpu.h
29913 --- linux-2.6.27.4/include/linux/percpu.h 2008-10-22 17:38:01.000000000 -0400
29914 +++ linux-2.6.27.4/include/linux/percpu.h 2008-10-27 22:36:18.000000000 -0400
29918 #define PERCPU_ENOUGH_ROOM \
29919 - (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
29920 + ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
29921 #endif /* PERCPU_ENOUGH_ROOM */
29924 diff -urNp linux-2.6.27.4/include/linux/poison.h linux-2.6.27.4/include/linux/poison.h
29925 --- linux-2.6.27.4/include/linux/poison.h 2008-10-22 17:38:01.000000000 -0400
29926 +++ linux-2.6.27.4/include/linux/poison.h 2008-10-27 22:36:18.000000000 -0400
29928 * under normal circumstances, used to verify that nobody uses
29929 * non-initialized list entries.
29931 -#define LIST_POISON1 ((void *) 0x00100100)
29932 -#define LIST_POISON2 ((void *) 0x00200200)
29933 +#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
29934 +#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
29936 /********** include/linux/timer.h **********/
29938 diff -urNp linux-2.6.27.4/include/linux/random.h linux-2.6.27.4/include/linux/random.h
29939 --- linux-2.6.27.4/include/linux/random.h 2008-10-22 17:38:01.000000000 -0400
29940 +++ linux-2.6.27.4/include/linux/random.h 2008-10-27 22:36:18.000000000 -0400
29941 @@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
29942 u32 random32(void);
29943 void srandom32(u32 seed);
29945 +static inline unsigned long pax_get_random_long(void)
29947 + return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
29950 #endif /* __KERNEL___ */
29952 #endif /* _LINUX_RANDOM_H */
29953 diff -urNp linux-2.6.27.4/include/linux/sched.h linux-2.6.27.4/include/linux/sched.h
29954 --- linux-2.6.27.4/include/linux/sched.h 2008-10-22 17:38:01.000000000 -0400
29955 +++ linux-2.6.27.4/include/linux/sched.h 2008-10-27 22:36:18.000000000 -0400
29956 @@ -96,6 +96,7 @@ struct exec_domain;
29957 struct futex_pi_state;
29958 struct robust_list_head;
29960 +struct linux_binprm;
29963 * List of flags we want to share for kernel threads,
29964 @@ -545,6 +546,15 @@ struct signal_struct {
29965 unsigned audit_tty;
29966 struct tty_audit_buf *tty_audit_buf;
29969 +#ifdef CONFIG_GRKERNSEC
29975 + u8 used_accept:1;
29979 /* Context switch must be unlocked if interrupts are to be enabled */
29980 @@ -1026,7 +1036,7 @@ struct sched_rt_entity {
29982 struct task_struct {
29983 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
29985 + struct thread_info *stack;
29987 unsigned int flags; /* per process flags, defined below */
29988 unsigned int ptrace;
29989 @@ -1091,10 +1101,9 @@ struct task_struct {
29993 -#ifdef CONFIG_CC_STACKPROTECTOR
29994 /* Canary value for the -fstack-protector gcc feature */
29995 unsigned long stack_canary;
29999 * pointers to (original) parent process, youngest child, younger sibling,
30000 * older sibling, respectively. (p->father can be replaced with
30001 @@ -1122,8 +1131,8 @@ struct task_struct {
30002 struct list_head thread_group;
30004 struct completion *vfork_done; /* for vfork() */
30005 - int __user *set_child_tid; /* CLONE_CHILD_SETTID */
30006 - int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30007 + pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
30008 + pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30010 cputime_t utime, stime, utimescaled, stimescaled;
30012 @@ -1301,8 +1310,64 @@ struct task_struct {
30013 int latency_record_count;
30014 struct latency_record latency_record[LT_SAVECOUNT];
30017 +#ifdef CONFIG_GRKERNSEC
30019 + struct acl_subject_label *acl;
30020 + struct acl_role_label *role;
30021 + struct file *exec_file;
30030 +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
30031 +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
30032 +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
30033 +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
30034 +/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
30035 +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
30037 +#ifdef CONFIG_PAX_SOFTMODE
30038 +extern unsigned int pax_softmode;
30041 +extern int pax_check_flags(unsigned long *);
30043 +/* if tsk != current then task_lock must be held on it */
30044 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30045 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
30047 + if (likely(tsk->mm))
30048 + return tsk->mm->pax_flags;
30053 +/* if tsk != current then task_lock must be held on it */
30054 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
30056 + if (likely(tsk->mm)) {
30057 + tsk->mm->pax_flags = flags;
30064 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
30065 +extern void pax_set_initial_flags(struct linux_binprm *bprm);
30066 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
30067 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
30070 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
30071 +void pax_report_insns(void *pc, void *sp);
30072 +void pax_report_refcount_overflow(struct pt_regs *regs);
30075 * Priority of a process goes from 0..MAX_PRIO-1, valid RT
30076 * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
30077 @@ -1843,7 +1908,7 @@ extern void __cleanup_sighand(struct sig
30078 extern void exit_itimers(struct signal_struct *);
30079 extern void flush_itimer_signals(void);
30081 -extern NORET_TYPE void do_group_exit(int);
30082 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
30084 extern void daemonize(const char *, ...);
30085 extern int allow_signal(int);
30086 @@ -1946,8 +2011,8 @@ static inline void unlock_task_sighand(s
30088 #ifndef __HAVE_THREAD_FUNCTIONS
30090 -#define task_thread_info(task) ((struct thread_info *)(task)->stack)
30091 -#define task_stack_page(task) ((task)->stack)
30092 +#define task_thread_info(task) ((task)->stack)
30093 +#define task_stack_page(task) ((void *)(task)->stack)
30095 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
30097 diff -urNp linux-2.6.27.4/include/linux/screen_info.h linux-2.6.27.4/include/linux/screen_info.h
30098 --- linux-2.6.27.4/include/linux/screen_info.h 2008-10-22 17:38:01.000000000 -0400
30099 +++ linux-2.6.27.4/include/linux/screen_info.h 2008-10-27 22:36:18.000000000 -0400
30100 @@ -42,7 +42,8 @@ struct screen_info {
30101 __u16 pages; /* 0x32 */
30102 __u16 vesa_attributes; /* 0x34 */
30103 __u32 capabilities; /* 0x36 */
30104 - __u8 _reserved[6]; /* 0x3a */
30105 + __u16 vesapm_size; /* 0x3a */
30106 + __u8 _reserved[4]; /* 0x3c */
30107 } __attribute__((packed));
30109 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
30110 diff -urNp linux-2.6.27.4/include/linux/shm.h linux-2.6.27.4/include/linux/shm.h
30111 --- linux-2.6.27.4/include/linux/shm.h 2008-10-22 17:38:01.000000000 -0400
30112 +++ linux-2.6.27.4/include/linux/shm.h 2008-10-25 12:03:07.000000000 -0400
30113 @@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
30116 struct user_struct *mlock_user;
30117 +#ifdef CONFIG_GRKERNSEC
30118 + time_t shm_createtime;
30123 /* shm_mode upper byte flags */
30124 diff -urNp linux-2.6.27.4/include/linux/slab.h linux-2.6.27.4/include/linux/slab.h
30125 --- linux-2.6.27.4/include/linux/slab.h 2008-10-22 17:38:01.000000000 -0400
30126 +++ linux-2.6.27.4/include/linux/slab.h 2008-10-27 22:36:18.000000000 -0400
30128 * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
30129 * Both make kfree a no-op.
30131 -#define ZERO_SIZE_PTR ((void *)16)
30132 +#define ZERO_SIZE_PTR ((void *)-1024L)
30134 -#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
30135 - (unsigned long)ZERO_SIZE_PTR)
30136 +#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
30139 * struct kmem_cache related prototypes
30140 diff -urNp linux-2.6.27.4/include/linux/sysctl.h linux-2.6.27.4/include/linux/sysctl.h
30141 --- linux-2.6.27.4/include/linux/sysctl.h 2008-10-22 17:38:01.000000000 -0400
30142 +++ linux-2.6.27.4/include/linux/sysctl.h 2008-10-27 23:03:41.000000000 -0400
30143 @@ -165,7 +165,11 @@ enum
30144 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
30148 +#ifdef CONFIG_PAX_SOFTMODE
30150 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
30154 /* CTL_VM names: */
30156 diff -urNp linux-2.6.27.4/include/linux/thread_info.h linux-2.6.27.4/include/linux/thread_info.h
30157 --- linux-2.6.27.4/include/linux/thread_info.h 2008-10-22 17:38:01.000000000 -0400
30158 +++ linux-2.6.27.4/include/linux/thread_info.h 2008-10-27 22:36:18.000000000 -0400
30159 @@ -23,7 +23,7 @@ struct restart_block {
30161 /* For futex_wait */
30164 + u32 __user *uaddr;
30168 diff -urNp linux-2.6.27.4/include/linux/uaccess.h linux-2.6.27.4/include/linux/uaccess.h
30169 --- linux-2.6.27.4/include/linux/uaccess.h 2008-10-22 17:38:01.000000000 -0400
30170 +++ linux-2.6.27.4/include/linux/uaccess.h 2008-10-27 22:36:18.000000000 -0400
30171 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
30173 mm_segment_t old_fs = get_fs(); \
30175 - set_fs(KERNEL_DS); \
30176 pagefault_disable(); \
30177 + set_fs(KERNEL_DS); \
30178 ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
30179 - pagefault_enable(); \
30181 + pagefault_enable(); \
30185 diff -urNp linux-2.6.27.4/include/linux/vmalloc.h linux-2.6.27.4/include/linux/vmalloc.h
30186 --- linux-2.6.27.4/include/linux/vmalloc.h 2008-10-22 17:38:01.000000000 -0400
30187 +++ linux-2.6.27.4/include/linux/vmalloc.h 2008-10-27 22:36:18.000000000 -0400
30188 @@ -12,6 +12,11 @@ struct vm_area_struct; /* vma defining
30189 #define VM_MAP 0x00000004 /* vmap()ed pages */
30190 #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
30191 #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
30193 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
30194 +#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
30197 /* bits [20..32] reserved for arch specific ioremap internals */
30200 diff -urNp linux-2.6.27.4/include/net/sctp/sctp.h linux-2.6.27.4/include/net/sctp/sctp.h
30201 --- linux-2.6.27.4/include/net/sctp/sctp.h 2008-10-22 17:38:01.000000000 -0400
30202 +++ linux-2.6.27.4/include/net/sctp/sctp.h 2008-10-27 22:36:18.000000000 -0400
30203 @@ -309,8 +309,8 @@ extern int sctp_debug_flag;
30205 #else /* SCTP_DEBUG */
30207 -#define SCTP_DEBUG_PRINTK(whatever...)
30208 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
30209 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
30210 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
30211 #define SCTP_ENABLE_DEBUG
30212 #define SCTP_DISABLE_DEBUG
30213 #define SCTP_ASSERT(expr, str, func)
30214 diff -urNp linux-2.6.27.4/include/sound/core.h linux-2.6.27.4/include/sound/core.h
30215 --- linux-2.6.27.4/include/sound/core.h 2008-10-22 17:38:01.000000000 -0400
30216 +++ linux-2.6.27.4/include/sound/core.h 2008-10-27 22:36:18.000000000 -0400
30217 @@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
30219 #else /* !CONFIG_SND_DEBUG */
30221 -#define snd_printd(fmt, args...) /* nothing */
30222 +#define snd_printd(fmt, args...) do {} while (0)
30223 #define snd_assert(expr, args...) (void)(expr)
30224 -#define snd_BUG() /* nothing */
30225 +#define snd_BUG() do {} while (0)
30227 #endif /* CONFIG_SND_DEBUG */
30229 @@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
30231 #define snd_printdd(format, args...) snd_printk(format, ##args)
30233 -#define snd_printdd(format, args...) /* nothing */
30234 +#define snd_printdd(format, args...) do {} while (0)
30238 diff -urNp linux-2.6.27.4/include/video/uvesafb.h linux-2.6.27.4/include/video/uvesafb.h
30239 --- linux-2.6.27.4/include/video/uvesafb.h 2008-10-22 17:38:01.000000000 -0400
30240 +++ linux-2.6.27.4/include/video/uvesafb.h 2008-10-27 22:36:18.000000000 -0400
30241 @@ -175,6 +175,7 @@ struct uvesafb_par {
30242 u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
30243 u8 pmi_setpal; /* PMI for palette changes */
30244 u16 *pmi_base; /* protected mode interface location */
30245 + u8 *pmi_code; /* protected mode code location */
30248 u8 *vbe_state_orig; /*
30249 diff -urNp linux-2.6.27.4/init/do_mounts.c linux-2.6.27.4/init/do_mounts.c
30250 --- linux-2.6.27.4/init/do_mounts.c 2008-10-22 17:38:01.000000000 -0400
30251 +++ linux-2.6.27.4/init/do_mounts.c 2008-10-27 22:36:18.000000000 -0400
30252 @@ -214,11 +214,11 @@ static void __init get_fs_names(char *pa
30254 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
30256 - int err = sys_mount(name, "/root", fs, flags, data);
30257 + int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
30261 - sys_chdir("/root");
30262 + sys_chdir((char __user *)"/root");
30263 ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
30264 printk("VFS: Mounted root (%s filesystem)%s.\n",
30265 current->fs->pwd.mnt->mnt_sb->s_type->name,
30266 @@ -304,18 +304,18 @@ void __init change_floppy(char *fmt, ...
30267 va_start(args, fmt);
30268 vsprintf(buf, fmt, args);
30270 - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
30271 + fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
30273 sys_ioctl(fd, FDEJECT, 0);
30276 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
30277 - fd = sys_open("/dev/console", O_RDWR, 0);
30278 + fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
30280 sys_ioctl(fd, TCGETS, (long)&termios);
30281 termios.c_lflag &= ~ICANON;
30282 sys_ioctl(fd, TCSETSF, (long)&termios);
30283 - sys_read(fd, &c, 1);
30284 + sys_read(fd, (char __user *)&c, 1);
30285 termios.c_lflag |= ICANON;
30286 sys_ioctl(fd, TCSETSF, (long)&termios);
30288 @@ -402,7 +402,7 @@ void __init prepare_namespace(void)
30292 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
30294 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
30295 + sys_chroot((char __user *)".");
30298 diff -urNp linux-2.6.27.4/init/do_mounts.h linux-2.6.27.4/init/do_mounts.h
30299 --- linux-2.6.27.4/init/do_mounts.h 2008-10-22 17:38:01.000000000 -0400
30300 +++ linux-2.6.27.4/init/do_mounts.h 2008-10-27 22:36:18.000000000 -0400
30301 @@ -14,15 +14,15 @@ extern int root_mountflags;
30303 static inline int create_dev(char *name, dev_t dev)
30305 - sys_unlink(name);
30306 - return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
30307 + sys_unlink((char __user *)name);
30308 + return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
30311 #if BITS_PER_LONG == 32
30312 static inline u32 bstat(char *name)
30314 struct stat64 stat;
30315 - if (sys_stat64(name, &stat) != 0)
30316 + if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
30318 if (!S_ISBLK(stat.st_mode))
30320 diff -urNp linux-2.6.27.4/init/do_mounts_initrd.c linux-2.6.27.4/init/do_mounts_initrd.c
30321 --- linux-2.6.27.4/init/do_mounts_initrd.c 2008-10-22 17:38:01.000000000 -0400
30322 +++ linux-2.6.27.4/init/do_mounts_initrd.c 2008-10-27 22:36:18.000000000 -0400
30323 @@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
30324 sys_close(old_fd);sys_close(root_fd);
30325 sys_close(0);sys_close(1);sys_close(2);
30327 - (void) sys_open("/dev/console",O_RDWR,0);
30328 + (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
30331 return kernel_execve(shell, argv, envp_init);
30332 @@ -47,13 +47,13 @@ static void __init handle_initrd(void)
30333 create_dev("/dev/root.old", Root_RAM0);
30334 /* mount initrd on rootfs' /root */
30335 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
30336 - sys_mkdir("/old", 0700);
30337 - root_fd = sys_open("/", 0, 0);
30338 - old_fd = sys_open("/old", 0, 0);
30339 + sys_mkdir((const char __user *)"/old", 0700);
30340 + root_fd = sys_open((const char __user *)"/", 0, 0);
30341 + old_fd = sys_open((const char __user *)"/old", 0, 0);
30342 /* move initrd over / and chdir/chroot in initrd root */
30343 - sys_chdir("/root");
30344 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
30346 + sys_chdir((const char __user *)"/root");
30347 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
30348 + sys_chroot((const char __user *)".");
30351 * In case that a resume from disk is carried out by linuxrc or one of
30352 @@ -70,15 +70,15 @@ static void __init handle_initrd(void)
30354 /* move initrd to rootfs' /old */
30355 sys_fchdir(old_fd);
30356 - sys_mount("/", ".", NULL, MS_MOVE, NULL);
30357 + sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
30358 /* switch root and cwd back to / of rootfs */
30359 sys_fchdir(root_fd);
30361 + sys_chroot((const char __user *)".");
30363 sys_close(root_fd);
30365 if (new_decode_dev(real_root_dev) == Root_RAM0) {
30366 - sys_chdir("/old");
30367 + sys_chdir((const char __user *)"/old");
30371 @@ -86,17 +86,17 @@ static void __init handle_initrd(void)
30374 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
30375 - error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
30376 + error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
30380 - int fd = sys_open("/dev/root.old", O_RDWR, 0);
30381 + int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
30382 if (error == -ENOENT)
30383 printk("/initrd does not exist. Ignored.\n");
30385 printk("failed\n");
30386 printk(KERN_NOTICE "Unmounting old root\n");
30387 - sys_umount("/old", MNT_DETACH);
30388 + sys_umount((char __user *)"/old", MNT_DETACH);
30389 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
30392 @@ -119,11 +119,11 @@ int __init initrd_load(void)
30393 * mounted in the normal path.
30395 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
30396 - sys_unlink("/initrd.image");
30397 + sys_unlink((const char __user *)"/initrd.image");
30402 - sys_unlink("/initrd.image");
30403 + sys_unlink((const char __user *)"/initrd.image");
30406 diff -urNp linux-2.6.27.4/init/do_mounts_md.c linux-2.6.27.4/init/do_mounts_md.c
30407 --- linux-2.6.27.4/init/do_mounts_md.c 2008-10-22 17:38:01.000000000 -0400
30408 +++ linux-2.6.27.4/init/do_mounts_md.c 2008-10-27 22:36:18.000000000 -0400
30409 @@ -166,7 +166,7 @@ static void __init md_setup_drive(void)
30410 partitioned ? "_d" : "", minor,
30411 md_setup_args[ent].device_names);
30413 - fd = sys_open(name, 0, 0);
30414 + fd = sys_open((char __user *)name, 0, 0);
30416 printk(KERN_ERR "md: open failed - cannot start "
30417 "array %s\n", name);
30418 @@ -229,7 +229,7 @@ static void __init md_setup_drive(void)
30422 - fd = sys_open(name, 0, 0);
30423 + fd = sys_open((char __user *)name, 0, 0);
30424 sys_ioctl(fd, BLKRRPART, 0);
30427 @@ -270,7 +270,7 @@ void __init md_run_setup(void)
30428 if (raid_noautodetect)
30429 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
30431 - int fd = sys_open("/dev/md0", 0, 0);
30432 + int fd = sys_open((char __user *)"/dev/md0", 0, 0);
30434 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
30436 diff -urNp linux-2.6.27.4/init/initramfs.c linux-2.6.27.4/init/initramfs.c
30437 --- linux-2.6.27.4/init/initramfs.c 2008-10-22 17:38:01.000000000 -0400
30438 +++ linux-2.6.27.4/init/initramfs.c 2008-10-27 22:36:18.000000000 -0400
30439 @@ -230,7 +230,7 @@ static int __init maybe_link(void)
30441 char *old = find_link(major, minor, ino, mode, collected);
30443 - return (sys_link(old, collected) < 0) ? -1 : 1;
30444 + return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
30448 @@ -239,11 +239,11 @@ static void __init clean_path(char *path
30452 - if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
30453 + if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
30454 if (S_ISDIR(st.st_mode))
30456 + sys_rmdir((char __user *)path);
30458 - sys_unlink(path);
30459 + sys_unlink((char __user *)path);
30463 @@ -266,7 +266,7 @@ static int __init do_name(void)
30464 int openflags = O_WRONLY|O_CREAT;
30466 openflags |= O_TRUNC;
30467 - wfd = sys_open(collected, openflags, mode);
30468 + wfd = sys_open((char __user *)collected, openflags, mode);
30471 sys_fchown(wfd, uid, gid);
30472 @@ -275,15 +275,15 @@ static int __init do_name(void)
30475 } else if (S_ISDIR(mode)) {
30476 - sys_mkdir(collected, mode);
30477 - sys_chown(collected, uid, gid);
30478 - sys_chmod(collected, mode);
30479 + sys_mkdir((char __user *)collected, mode);
30480 + sys_chown((char __user *)collected, uid, gid);
30481 + sys_chmod((char __user *)collected, mode);
30482 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
30483 S_ISFIFO(mode) || S_ISSOCK(mode)) {
30484 if (maybe_link() == 0) {
30485 - sys_mknod(collected, mode, rdev);
30486 - sys_chown(collected, uid, gid);
30487 - sys_chmod(collected, mode);
30488 + sys_mknod((char __user *)collected, mode, rdev);
30489 + sys_chown((char __user *)collected, uid, gid);
30490 + sys_chmod((char __user *)collected, mode);
30494 @@ -292,13 +292,13 @@ static int __init do_name(void)
30495 static int __init do_copy(void)
30497 if (count >= body_len) {
30498 - sys_write(wfd, victim, body_len);
30499 + sys_write(wfd, (char __user *)victim, body_len);
30505 - sys_write(wfd, victim, count);
30506 + sys_write(wfd, (char __user *)victim, count);
30510 @@ -309,8 +309,8 @@ static int __init do_symlink(void)
30512 collected[N_ALIGN(name_len) + body_len] = '\0';
30513 clean_path(collected, 0);
30514 - sys_symlink(collected + N_ALIGN(name_len), collected);
30515 - sys_lchown(collected, uid, gid);
30516 + sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
30517 + sys_lchown((char __user *)collected, uid, gid);
30519 next_state = Reset;
30521 diff -urNp linux-2.6.27.4/init/Kconfig linux-2.6.27.4/init/Kconfig
30522 --- linux-2.6.27.4/init/Kconfig 2008-10-22 17:38:01.000000000 -0400
30523 +++ linux-2.6.27.4/init/Kconfig 2008-10-25 12:03:07.000000000 -0400
30524 @@ -561,6 +561,7 @@ config SYSCTL_SYSCALL
30526 bool "Load all symbols for debugging/ksymoops" if EMBEDDED
30528 + depends on !GRKERNSEC_HIDESYM
30530 Say Y here to let the kernel print out symbolic crash information and
30531 symbolic stack backtraces. This increases the size of the kernel
30532 @@ -780,8 +781,8 @@ config MARKERS
30533 source "arch/Kconfig"
30535 config PROC_PAGE_MONITOR
30537 - depends on PROC_FS && MMU
30539 + depends on PROC_FS && MMU && !GRKERNSEC
30540 bool "Enable /proc page monitoring" if EMBEDDED
30542 Various /proc files exist to monitor process memory utilization:
30543 @@ -797,9 +798,9 @@ config HAVE_GENERIC_DMA_COHERENT
30547 - depends on PROC_FS
30548 + depends on PROC_FS && !GRKERNSEC_PROC_ADD
30549 depends on SLAB || SLUB_DEBUG
30555 diff -urNp linux-2.6.27.4/init/main.c linux-2.6.27.4/init/main.c
30556 --- linux-2.6.27.4/init/main.c 2008-10-22 17:38:01.000000000 -0400
30557 +++ linux-2.6.27.4/init/main.c 2008-10-27 22:36:18.000000000 -0400
30558 @@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void)
30560 extern void tc_init(void);
30562 +extern void grsecurity_init(void);
30564 enum system_states system_state;
30565 EXPORT_SYMBOL(system_state);
30566 @@ -187,6 +188,40 @@ static int __init set_reset_devices(char
30568 __setup("reset_devices", set_reset_devices);
30570 +#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
30571 +static int __init setup_pax_nouderef(char *str)
30573 + unsigned int cpu;
30575 +#ifdef CONFIG_PAX_KERNEXEC
30576 + unsigned long cr0;
30578 + pax_open_kernel(cr0);
30581 + for (cpu = 0; cpu < NR_CPUS; cpu++)
30582 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
30584 +#ifdef CONFIG_PAX_KERNEXEC
30585 + pax_close_kernel(cr0);
30590 +__setup("pax_nouderef", setup_pax_nouderef);
30593 +#ifdef CONFIG_PAX_SOFTMODE
30594 +unsigned int pax_softmode;
30596 +static int __init setup_pax_softmode(char *str)
30598 + get_option(&str, &pax_softmode);
30601 +__setup("pax_softmode=", setup_pax_softmode);
30604 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
30605 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
30606 static const char *panic_later, *panic_param;
30607 @@ -385,7 +420,7 @@ static void __init setup_nr_cpu_ids(void
30610 #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
30611 -unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
30612 +unsigned long __per_cpu_offset[NR_CPUS] __read_only;
30614 EXPORT_SYMBOL(__per_cpu_offset);
30616 @@ -704,6 +739,7 @@ int do_one_initcall(initcall_t fn)
30618 int count = preempt_count();
30619 ktime_t t0, t1, delta;
30620 + const char *msg1 = "", *msg2 = "";
30624 @@ -729,15 +765,15 @@ int do_one_initcall(initcall_t fn)
30625 sprintf(msgbuf, "error code %d ", result);
30627 if (preempt_count() != count) {
30628 - strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
30629 + msg1 = " preemption imbalance";
30630 preempt_count() = count;
30632 if (irqs_disabled()) {
30633 - strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
30634 + msg2 = " disabled interrupts";
30635 local_irq_enable();
30638 - printk("initcall %pF returned with %s\n", fn, msgbuf);
30639 + if (msgbuf[0] || *msg1 || *msg2) {
30640 + printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
30644 @@ -876,6 +912,8 @@ static int __init kernel_init(void * unu
30645 prepare_namespace();
30648 + grsecurity_init();
30651 * Ok, we have completed the initial bootup, and
30652 * we're essentially up and running. Get rid of the
30653 diff -urNp linux-2.6.27.4/init/noinitramfs.c linux-2.6.27.4/init/noinitramfs.c
30654 --- linux-2.6.27.4/init/noinitramfs.c 2008-10-22 17:38:01.000000000 -0400
30655 +++ linux-2.6.27.4/init/noinitramfs.c 2008-10-27 22:36:18.000000000 -0400
30656 @@ -29,7 +29,7 @@ static int __init default_rootfs(void)
30660 - err = sys_mkdir("/dev", 0755);
30661 + err = sys_mkdir((const char __user *)"/dev", 0755);
30665 @@ -39,7 +39,7 @@ static int __init default_rootfs(void)
30669 - err = sys_mkdir("/root", 0700);
30670 + err = sys_mkdir((const char __user *)"/root", 0700);
30674 diff -urNp linux-2.6.27.4/ipc/ipc_sysctl.c linux-2.6.27.4/ipc/ipc_sysctl.c
30675 --- linux-2.6.27.4/ipc/ipc_sysctl.c 2008-10-22 17:38:01.000000000 -0400
30676 +++ linux-2.6.27.4/ipc/ipc_sysctl.c 2008-10-27 22:36:18.000000000 -0400
30677 @@ -268,7 +268,7 @@ static struct ctl_table ipc_kern_table[]
30682 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
30685 static struct ctl_table ipc_root_table[] = {
30686 @@ -278,7 +278,7 @@ static struct ctl_table ipc_root_table[]
30688 .child = ipc_kern_table,
30691 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
30694 static int __init ipc_sysctl_init(void)
30695 diff -urNp linux-2.6.27.4/ipc/msg.c linux-2.6.27.4/ipc/msg.c
30696 --- linux-2.6.27.4/ipc/msg.c 2008-10-22 17:38:01.000000000 -0400
30697 +++ linux-2.6.27.4/ipc/msg.c 2008-10-25 12:03:07.000000000 -0400
30699 #include <linux/nsproxy.h>
30700 #include <linux/ipc_namespace.h>
30701 #include <linux/vs_base.h>
30702 +#include <linux/grsecurity.h>
30704 #include <asm/current.h>
30705 #include <asm/uaccess.h>
30706 @@ -314,6 +315,7 @@ asmlinkage long sys_msgget(key_t key, in
30707 struct ipc_namespace *ns;
30708 struct ipc_ops msg_ops;
30709 struct ipc_params msg_params;
30712 ns = current->nsproxy->ipc_ns;
30714 @@ -324,7 +326,11 @@ asmlinkage long sys_msgget(key_t key, in
30715 msg_params.key = key;
30716 msg_params.flg = msgflg;
30718 - return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
30719 + err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
30721 + gr_log_msgget(err, msgflg);
30726 static inline unsigned long
30727 @@ -434,6 +440,7 @@ static int msgctl_down(struct ipc_namesp
30731 + gr_log_msgrm(ipcp->uid, ipcp->cuid);
30735 diff -urNp linux-2.6.27.4/ipc/sem.c linux-2.6.27.4/ipc/sem.c
30736 --- linux-2.6.27.4/ipc/sem.c 2008-10-22 17:38:01.000000000 -0400
30737 +++ linux-2.6.27.4/ipc/sem.c 2008-10-25 12:03:07.000000000 -0400
30739 #include <linux/ipc_namespace.h>
30740 #include <linux/vs_base.h>
30741 #include <linux/vs_limit.h>
30742 +#include <linux/grsecurity.h>
30744 #include <asm/uaccess.h>
30746 @@ -313,6 +314,7 @@ asmlinkage long sys_semget(key_t key, in
30747 struct ipc_namespace *ns;
30748 struct ipc_ops sem_ops;
30749 struct ipc_params sem_params;
30752 ns = current->nsproxy->ipc_ns;
30754 @@ -327,7 +329,11 @@ asmlinkage long sys_semget(key_t key, in
30755 sem_params.flg = semflg;
30756 sem_params.u.nsems = nsems;
30758 - return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
30759 + err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
30761 + gr_log_semget(err, semflg);
30767 @@ -870,6 +876,7 @@ static int semctl_down(struct ipc_namesp
30771 + gr_log_semrm(ipcp->uid, ipcp->cuid);
30775 diff -urNp linux-2.6.27.4/ipc/shm.c linux-2.6.27.4/ipc/shm.c
30776 --- linux-2.6.27.4/ipc/shm.c 2008-10-22 17:38:01.000000000 -0400
30777 +++ linux-2.6.27.4/ipc/shm.c 2008-10-25 12:03:07.000000000 -0400
30779 #include <linux/ipc_namespace.h>
30780 #include <linux/vs_context.h>
30781 #include <linux/vs_limit.h>
30782 +#include <linux/grsecurity.h>
30784 #include <asm/uaccess.h>
30786 @@ -69,6 +70,14 @@ static void shm_destroy (struct ipc_name
30787 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
30790 +#ifdef CONFIG_GRKERNSEC
30791 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
30792 + const time_t shm_createtime, const uid_t cuid,
30793 + const int shmid);
30794 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
30795 + const time_t shm_createtime);
30798 void shm_init_ns(struct ipc_namespace *ns)
30800 ns->shm_ctlmax = SHMMAX;
30801 @@ -87,6 +96,8 @@ static void do_shm_rmid(struct ipc_names
30802 struct shmid_kernel *shp;
30803 shp = container_of(ipcp, struct shmid_kernel, shm_perm);
30805 + gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
30807 if (shp->shm_nattch){
30808 shp->shm_perm.mode |= SHM_DEST;
30809 /* Do not find it any more */
30810 @@ -392,6 +403,14 @@ static int newseg(struct ipc_namespace *
30811 shp->shm_lprid = 0;
30812 shp->shm_atim = shp->shm_dtim = 0;
30813 shp->shm_ctim = get_seconds();
30814 +#ifdef CONFIG_GRKERNSEC
30816 + struct timespec timeval;
30817 + do_posix_clock_monotonic_gettime(&timeval);
30819 + shp->shm_createtime = timeval.tv_sec;
30822 shp->shm_segsz = size;
30823 shp->shm_nattch = 0;
30824 shp->shm_file = file;
30825 @@ -445,6 +464,7 @@ asmlinkage long sys_shmget (key_t key, s
30826 struct ipc_namespace *ns;
30827 struct ipc_ops shm_ops;
30828 struct ipc_params shm_params;
30831 ns = current->nsproxy->ipc_ns;
30833 @@ -456,7 +476,11 @@ asmlinkage long sys_shmget (key_t key, s
30834 shm_params.flg = shmflg;
30835 shm_params.u.size = size;
30837 - return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
30838 + err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
30840 + gr_log_shmget(err, shmflg, size);
30845 static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
30846 @@ -869,9 +893,21 @@ long do_shmat(int shmid, char __user *sh
30850 +#ifdef CONFIG_GRKERNSEC
30851 + if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
30852 + shp->shm_perm.cuid, shmid) ||
30853 + !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
30859 path.dentry = dget(shp->shm_file->f_path.dentry);
30860 path.mnt = shp->shm_file->f_path.mnt;
30862 +#ifdef CONFIG_GRKERNSEC
30863 + shp->shm_lapid = current->pid;
30865 size = i_size_read(path.dentry->d_inode);
30868 diff -urNp linux-2.6.27.4/kernel/acct.c linux-2.6.27.4/kernel/acct.c
30869 --- linux-2.6.27.4/kernel/acct.c 2008-10-22 17:38:01.000000000 -0400
30870 +++ linux-2.6.27.4/kernel/acct.c 2008-10-27 22:36:18.000000000 -0400
30871 @@ -573,7 +573,7 @@ static void do_acct_process(struct bsd_a
30873 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
30874 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
30875 - file->f_op->write(file, (char *)&ac,
30876 + file->f_op->write(file, (char __user *)&ac,
30877 sizeof(acct_t), &file->f_pos);
30878 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
30880 diff -urNp linux-2.6.27.4/kernel/capability.c linux-2.6.27.4/kernel/capability.c
30881 --- linux-2.6.27.4/kernel/capability.c 2008-10-22 17:38:01.000000000 -0400
30882 +++ linux-2.6.27.4/kernel/capability.c 2008-10-26 03:32:46.000000000 -0400
30884 #include <linux/syscalls.h>
30885 #include <linux/pid_namespace.h>
30886 #include <linux/vs_context.h>
30887 +#include <linux/grsecurity.h>
30888 #include <asm/uaccess.h>
30891 @@ -498,10 +499,21 @@ asmlinkage long sys_capset(cap_user_head
30892 /* here for now so we don't require task locking */
30893 if (vs_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap))
30895 - if (has_capability(current, cap)) {
30896 + if (has_capability(current, cap) && gr_task_is_capable(current, cap)) {
30897 current->flags |= PF_SUPERPRIV;
30903 +int capable_nolog(int cap)
30905 + if (has_capability(current, cap) && gr_is_capable_nolog(cap)) {
30906 + current->flags |= PF_SUPERPRIV;
30912 EXPORT_SYMBOL(capable);
30913 +EXPORT_SYMBOL(capable_nolog);
30914 diff -urNp linux-2.6.27.4/kernel/configs.c linux-2.6.27.4/kernel/configs.c
30915 --- linux-2.6.27.4/kernel/configs.c 2008-10-22 17:38:01.000000000 -0400
30916 +++ linux-2.6.27.4/kernel/configs.c 2008-10-25 12:03:07.000000000 -0400
30917 @@ -79,8 +79,19 @@ static int __init ikconfig_init(void)
30918 struct proc_dir_entry *entry;
30920 /* create the current config file */
30921 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
30922 +#ifdef CONFIG_GRKERNSEC_PROC_USER
30923 + entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
30924 + &ikconfig_file_ops);
30925 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
30926 + entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
30927 + &ikconfig_file_ops);
30930 entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
30931 &ikconfig_file_ops);
30937 diff -urNp linux-2.6.27.4/kernel/cpu.c linux-2.6.27.4/kernel/cpu.c
30938 --- linux-2.6.27.4/kernel/cpu.c 2008-10-22 17:38:01.000000000 -0400
30939 +++ linux-2.6.27.4/kernel/cpu.c 2008-10-27 22:36:18.000000000 -0400
30940 @@ -40,7 +40,7 @@ EXPORT_SYMBOL(cpu_possible_map);
30941 /* Serializes the updates to cpu_online_map, cpu_present_map */
30942 static DEFINE_MUTEX(cpu_add_remove_lock);
30944 -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
30945 +static RAW_NOTIFIER_HEAD(cpu_chain);
30947 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
30948 * Should always be manipulated under cpu_add_remove_lock
30949 diff -urNp linux-2.6.27.4/kernel/exit.c linux-2.6.27.4/kernel/exit.c
30950 --- linux-2.6.27.4/kernel/exit.c 2008-10-22 17:38:01.000000000 -0400
30951 +++ linux-2.6.27.4/kernel/exit.c 2008-10-27 22:36:18.000000000 -0400
30953 #include <linux/vs_network.h>
30954 #include <linux/vs_pid.h>
30955 #include <linux/vserver/global.h>
30956 +#include <linux/grsecurity.h>
30958 +#ifdef CONFIG_GRKERNSEC
30959 +extern rwlock_t grsec_exec_file_lock;
30962 #include <asm/uaccess.h>
30963 #include <asm/unistd.h>
30964 @@ -134,6 +139,7 @@ static void __exit_signal(struct task_st
30966 flush_sigqueue(&tsk->pending);
30968 + gr_del_task_from_ip_table(tsk);
30969 tsk->signal = NULL;
30970 tsk->sighand = NULL;
30971 spin_unlock(&sighand->siglock);
30972 @@ -321,11 +327,22 @@ static void reparent_to_kthreadd(void)
30974 write_lock_irq(&tasklist_lock);
30976 +#ifdef CONFIG_GRKERNSEC
30977 + write_lock(&grsec_exec_file_lock);
30978 + if (current->exec_file) {
30979 + fput(current->exec_file);
30980 + current->exec_file = NULL;
30982 + write_unlock(&grsec_exec_file_lock);
30985 ptrace_unlink(current);
30986 /* Reparent to init */
30987 current->real_parent = current->parent = kthreadd_task;
30988 list_move_tail(¤t->sibling, ¤t->real_parent->children);
30990 + gr_set_kernel_label(current);
30992 /* Set the exit signal to SIGCHLD so we signal init on exit */
30993 current->exit_signal = SIGCHLD;
30995 @@ -419,6 +436,17 @@ void daemonize(const char *name, ...)
30996 vsnprintf(current->comm, sizeof(current->comm), name, args);
30999 +#ifdef CONFIG_GRKERNSEC
31000 + write_lock(&grsec_exec_file_lock);
31001 + if (current->exec_file) {
31002 + fput(current->exec_file);
31003 + current->exec_file = NULL;
31005 + write_unlock(&grsec_exec_file_lock);
31008 + gr_set_kernel_label(current);
31011 * If we were started as result of loading a module, close all of the
31012 * user space pages. We don't need them, and if we didn't close them
31013 @@ -1070,6 +1098,9 @@ NORET_TYPE void do_exit(long code)
31014 tsk->exit_code = code;
31015 taskstats_exit(tsk, group_dead);
31017 + gr_acl_handle_psacct(tsk, code);
31018 + gr_acl_handle_exit();
31023 @@ -1272,7 +1303,7 @@ static int wait_task_zombie(struct task_
31024 if (unlikely(options & WNOWAIT)) {
31025 uid_t uid = p->uid;
31026 int exit_code = p->exit_code;
31030 get_task_struct(p);
31031 read_unlock(&tasklist_lock);
31032 diff -urNp linux-2.6.27.4/kernel/fork.c linux-2.6.27.4/kernel/fork.c
31033 --- linux-2.6.27.4/kernel/fork.c 2008-10-22 17:38:01.000000000 -0400
31034 +++ linux-2.6.27.4/kernel/fork.c 2008-10-27 22:36:18.000000000 -0400
31036 #include <linux/vs_limit.h>
31037 #include <linux/vs_memory.h>
31038 #include <linux/vserver/global.h>
31039 +#include <linux/grsecurity.h>
31041 #include <asm/pgtable.h>
31042 #include <asm/pgalloc.h>
31043 @@ -234,7 +235,7 @@ static struct task_struct *dup_task_stru
31044 setup_thread_stack(tsk, orig);
31046 #ifdef CONFIG_CC_STACKPROTECTOR
31047 - tsk->stack_canary = get_random_int();
31048 + tsk->stack_canary = pax_get_random_long();
31051 /* One for us, one for whoever does the "release_task()" (usually parent) */
31052 @@ -271,8 +272,8 @@ static int dup_mmap(struct mm_struct *mm
31055 mm->mmap_cache = NULL;
31056 - mm->free_area_cache = oldmm->mmap_base;
31057 - mm->cached_hole_size = ~0UL;
31058 + mm->free_area_cache = oldmm->free_area_cache;
31059 + mm->cached_hole_size = oldmm->cached_hole_size;
31061 cpus_clear(mm->cpu_vm_mask);
31062 mm->mm_rb = RB_ROOT;
31063 @@ -309,6 +310,7 @@ static int dup_mmap(struct mm_struct *mm
31064 tmp->vm_flags &= ~VM_LOCKED;
31066 tmp->vm_next = NULL;
31067 + tmp->vm_mirror = NULL;
31068 anon_vma_link(tmp);
31069 file = tmp->vm_file;
31071 @@ -353,6 +355,31 @@ static int dup_mmap(struct mm_struct *mm
31076 +#ifdef CONFIG_PAX_SEGMEXEC
31077 + if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
31078 + struct vm_area_struct *mpnt_m;
31080 + for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
31081 + BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
31083 + if (!mpnt->vm_mirror)
31086 + if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
31087 + BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
31088 + mpnt->vm_mirror = mpnt_m;
31090 + BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
31091 + mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
31092 + mpnt_m->vm_mirror->vm_mirror = mpnt_m;
31093 + mpnt->vm_mirror->vm_mirror = mpnt;
31100 /* a new mm has just been created */
31101 arch_dup_mmap(oldmm, mm);
31103 @@ -536,7 +563,7 @@ void mm_release(struct task_struct *tsk,
31104 if (tsk->clear_child_tid
31105 && !(tsk->flags & PF_SIGNALED)
31106 && atomic_read(&mm->mm_users) > 1) {
31107 - u32 __user * tidptr = tsk->clear_child_tid;
31108 + pid_t __user * tidptr = tsk->clear_child_tid;
31109 tsk->clear_child_tid = NULL;
31112 @@ -544,7 +571,7 @@ void mm_release(struct task_struct *tsk,
31113 * not set up a proper pointer then tough luck.
31115 put_user(0, tidptr);
31116 - sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31117 + sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31121 @@ -939,6 +966,9 @@ static struct task_struct *copy_process(
31122 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
31126 + gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
31128 if (!vx_nproc_avail(1))
31129 goto bad_fork_cleanup_vm;
31130 if (atomic_read(&p->user->processes) >=
31131 @@ -1105,6 +1135,8 @@ static struct task_struct *copy_process(
31132 goto bad_fork_free_pid;
31135 + gr_copy_label(p);
31137 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
31139 * Clear TID on mm_release()?
31140 @@ -1290,6 +1322,8 @@ bad_fork_cleanup_count:
31144 + gr_log_forkfail(retval);
31146 return ERR_PTR(retval);
31149 @@ -1366,6 +1400,8 @@ long do_fork(unsigned long clone_flags,
31150 if (clone_flags & CLONE_PARENT_SETTID)
31151 put_user(nr, parent_tidptr);
31153 + gr_handle_brute_check();
31155 if (clone_flags & CLONE_VFORK) {
31156 p->vfork_done = &vfork;
31157 init_completion(&vfork);
31158 diff -urNp linux-2.6.27.4/kernel/futex.c linux-2.6.27.4/kernel/futex.c
31159 --- linux-2.6.27.4/kernel/futex.c 2008-10-22 17:38:01.000000000 -0400
31160 +++ linux-2.6.27.4/kernel/futex.c 2008-10-27 22:36:18.000000000 -0400
31161 @@ -188,6 +188,11 @@ static int get_futex_key(u32 __user *uad
31165 +#ifdef CONFIG_PAX_SEGMEXEC
31166 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
31171 * The futex address must be "naturally" aligned.
31173 @@ -214,8 +219,8 @@ static int get_futex_key(u32 __user *uad
31174 * The futex is hashed differently depending on whether
31175 * it's in a shared or private mapping. So check vma first.
31177 - vma = find_extend_vma(mm, address);
31178 - if (unlikely(!vma))
31179 + vma = find_vma(mm, address);
31180 + if (unlikely(!vma || address < vma->vm_start))
31184 @@ -1345,7 +1350,7 @@ static int futex_wait(u32 __user *uaddr,
31185 struct restart_block *restart;
31186 restart = ¤t_thread_info()->restart_block;
31187 restart->fn = futex_wait_restart;
31188 - restart->futex.uaddr = (u32 *)uaddr;
31189 + restart->futex.uaddr = uaddr;
31190 restart->futex.val = val;
31191 restart->futex.time = abs_time->tv64;
31192 restart->futex.bitset = bitset;
31193 @@ -1906,7 +1911,7 @@ retry:
31195 static inline int fetch_robust_entry(struct robust_list __user **entry,
31196 struct robust_list __user * __user *head,
31198 + unsigned int *pi)
31200 unsigned long uentry;
31202 diff -urNp linux-2.6.27.4/kernel/irq/handle.c linux-2.6.27.4/kernel/irq/handle.c
31203 --- linux-2.6.27.4/kernel/irq/handle.c 2008-10-22 17:38:01.000000000 -0400
31204 +++ linux-2.6.27.4/kernel/irq/handle.c 2008-10-27 22:36:18.000000000 -0400
31205 @@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
31207 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
31209 - .affinity = CPU_MASK_ALL
31210 + .affinity = CPU_MASK_ALL,
31215 diff -urNp linux-2.6.27.4/kernel/kallsyms.c linux-2.6.27.4/kernel/kallsyms.c
31216 --- linux-2.6.27.4/kernel/kallsyms.c 2008-10-22 17:38:01.000000000 -0400
31217 +++ linux-2.6.27.4/kernel/kallsyms.c 2008-10-27 22:36:18.000000000 -0400
31218 @@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
31220 static inline int is_kernel(unsigned long addr)
31223 +#ifdef CONFIG_PAX_KERNEXEC
31225 +#ifdef CONFIG_MODULES
31226 + if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
31227 + ktla_ktva(addr) < (unsigned long)MODULES_END)
31231 + if (is_kernel_inittext(addr))
31235 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
31237 return in_gate_area_no_task(addr);
31238 @@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
31240 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
31242 - iter->name[0] = '\0';
31243 iter->nameoff = get_symbol_offset(new_pos);
31244 iter->pos = new_pos;
31246 @@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
31247 struct kallsym_iter *iter;
31250 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
31251 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
31254 reset_iter(iter, 0);
31255 @@ -472,7 +484,15 @@ static const struct file_operations kall
31257 static int __init kallsyms_init(void)
31259 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
31260 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31261 + proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
31262 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31263 + proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
31266 proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
31270 __initcall(kallsyms_init);
31271 diff -urNp linux-2.6.27.4/kernel/kmod.c linux-2.6.27.4/kernel/kmod.c
31272 --- linux-2.6.27.4/kernel/kmod.c 2008-10-22 17:38:01.000000000 -0400
31273 +++ linux-2.6.27.4/kernel/kmod.c 2008-10-27 22:36:18.000000000 -0400
31274 @@ -108,7 +108,7 @@ int request_module(const char *fmt, ...)
31278 - ret = call_usermodehelper(modprobe_path, argv, envp, 1);
31279 + ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
31280 atomic_dec(&kmod_concurrent);
31283 diff -urNp linux-2.6.27.4/kernel/kprobes.c linux-2.6.27.4/kernel/kprobes.c
31284 --- linux-2.6.27.4/kernel/kprobes.c 2008-10-22 17:38:01.000000000 -0400
31285 +++ linux-2.6.27.4/kernel/kprobes.c 2008-10-27 22:36:18.000000000 -0400
31286 @@ -182,7 +182,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
31287 * kernel image and loaded module images reside. This is required
31288 * so x86_64 can correctly handle the %rip-relative fixups.
31290 - kip->insns = module_alloc(PAGE_SIZE);
31291 + kip->insns = module_alloc_exec(PAGE_SIZE);
31295 @@ -214,7 +214,7 @@ static int __kprobes collect_one_slot(st
31296 hlist_add_head(&kip->hlist,
31297 &kprobe_insn_pages);
31299 - module_free(NULL, kip->insns);
31300 + module_free_exec(NULL, kip->insns);
31304 diff -urNp linux-2.6.27.4/kernel/lockdep.c linux-2.6.27.4/kernel/lockdep.c
31305 --- linux-2.6.27.4/kernel/lockdep.c 2008-10-22 17:38:01.000000000 -0400
31306 +++ linux-2.6.27.4/kernel/lockdep.c 2008-10-27 22:36:18.000000000 -0400
31307 @@ -627,6 +627,10 @@ static int static_obj(void *obj)
31311 +#ifdef CONFIG_PAX_KERNEXEC
31312 + start = (unsigned long )&_data;
31318 @@ -638,9 +642,12 @@ static int static_obj(void *obj)
31321 for_each_possible_cpu(i) {
31322 +#ifdef CONFIG_X86_32
31323 + start = per_cpu_offset(i);
31325 start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
31326 - end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
31327 - + per_cpu_offset(i);
31329 + end = start + PERCPU_ENOUGH_ROOM;
31331 if ((addr >= start) && (addr < end))
31333 diff -urNp linux-2.6.27.4/kernel/module.c linux-2.6.27.4/kernel/module.c
31334 --- linux-2.6.27.4/kernel/module.c 2008-10-22 17:38:01.000000000 -0400
31335 +++ linux-2.6.27.4/kernel/module.c 2008-10-27 22:36:18.000000000 -0400
31337 #include <linux/unwind.h>
31338 #include <asm/uaccess.h>
31339 #include <asm/cacheflush.h>
31341 +#ifdef CONFIG_PAX_KERNEXEC
31342 +#include <asm/desc.h>
31345 #include <linux/license.h>
31346 #include <asm/sections.h>
31348 @@ -71,7 +76,10 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
31349 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
31351 /* Bounds of module allocation, for speeding __module_text_address */
31352 -static unsigned long module_addr_min = -1UL, module_addr_max = 0;
31353 +static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
31354 +static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
31356 +extern int gr_check_modstop(void);
31358 int register_module_notifier(struct notifier_block * nb)
31360 @@ -217,7 +225,7 @@ static bool each_symbol(bool (*fn)(const
31363 list_for_each_entry(mod, &modules, list) {
31364 - struct symsearch arr[] = {
31365 + struct symsearch modarr[] = {
31366 { mod->syms, mod->syms + mod->num_syms, mod->crcs,
31367 NOT_GPL_ONLY, false },
31368 { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
31369 @@ -239,7 +247,7 @@ static bool each_symbol(bool (*fn)(const
31373 - if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
31374 + if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
31378 @@ -375,6 +383,8 @@ static inline unsigned int block_size(in
31382 +EXPORT_SYMBOL(__per_cpu_start);
31384 static void *percpu_modalloc(unsigned long size, unsigned long align,
31387 @@ -382,7 +392,7 @@ static void *percpu_modalloc(unsigned lo
31391 - if (align > PAGE_SIZE) {
31392 + if (align-1 >= PAGE_SIZE) {
31393 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
31394 name, align, PAGE_SIZE);
31396 @@ -464,7 +474,11 @@ static void percpu_modcopy(void *pcpudes
31399 for_each_possible_cpu(cpu)
31400 +#ifdef CONFIG_X86_32
31401 + memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
31403 memcpy(pcpudest + per_cpu_offset(cpu), from, size);
31407 static int percpu_modinit(void)
31408 @@ -722,6 +736,9 @@ sys_delete_module(const char __user *nam
31409 char name[MODULE_NAME_LEN];
31410 int ret, forced = 0;
31412 + if (gr_check_modstop())
31415 if (!capable(CAP_SYS_MODULE))
31418 @@ -1430,16 +1447,19 @@ static void free_module(struct module *m
31419 module_unload_free(mod);
31421 /* This may be NULL, but that's OK */
31422 - module_free(mod, mod->module_init);
31423 + module_free(mod, mod->module_init_rw);
31424 + module_free_exec(mod, mod->module_init_rx);
31427 percpu_modfree(mod->percpu);
31429 /* Free lock-classes: */
31430 - lockdep_free_key_range(mod->module_core, mod->core_size);
31431 + lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
31432 + lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
31434 /* Finally, free the core (containing the module structure) */
31435 - module_free(mod, mod->module_core);
31436 + module_free_exec(mod, mod->module_core_rx);
31437 + module_free(mod, mod->module_core_rw);
31440 void *__symbol_get(const char *symbol)
31441 @@ -1505,10 +1525,14 @@ static int simplify_symbols(Elf_Shdr *se
31442 struct module *mod)
31444 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
31445 - unsigned long secbase;
31446 + unsigned long secbase, symbol;
31447 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
31450 +#ifdef CONFIG_PAX_KERNEXEC
31451 + unsigned long cr0;
31454 for (i = 1; i < n; i++) {
31455 switch (sym[i].st_shndx) {
31457 @@ -1527,10 +1551,19 @@ static int simplify_symbols(Elf_Shdr *se
31462 - = resolve_symbol(sechdrs, versindex,
31463 + symbol = resolve_symbol(sechdrs, versindex,
31464 strtab + sym[i].st_name, mod);
31466 +#ifdef CONFIG_PAX_KERNEXEC
31467 + pax_open_kernel(cr0);
31470 + sym[i].st_value = symbol;
31472 +#ifdef CONFIG_PAX_KERNEXEC
31473 + pax_close_kernel(cr0);
31476 /* Ok if resolved. */
31477 if (!IS_ERR_VALUE(sym[i].st_value))
31479 @@ -1545,11 +1578,27 @@ static int simplify_symbols(Elf_Shdr *se
31482 /* Divert to percpu allocation if a percpu var. */
31483 - if (sym[i].st_shndx == pcpuindex)
31484 + if (sym[i].st_shndx == pcpuindex) {
31486 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
31487 + secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
31489 secbase = (unsigned long)mod->percpu;
31494 secbase = sechdrs[sym[i].st_shndx].sh_addr;
31496 +#ifdef CONFIG_PAX_KERNEXEC
31497 + pax_open_kernel(cr0);
31500 sym[i].st_value += secbase;
31502 +#ifdef CONFIG_PAX_KERNEXEC
31503 + pax_close_kernel(cr0);
31509 @@ -1601,11 +1650,14 @@ static void layout_sections(struct modul
31510 || strncmp(secstrings + s->sh_name,
31513 - s->sh_entsize = get_offset(&mod->core_size, s);
31514 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
31515 + s->sh_entsize = get_offset(&mod->core_size_rw, s);
31517 + s->sh_entsize = get_offset(&mod->core_size_rx, s);
31518 DEBUGP("\t%s\n", secstrings + s->sh_name);
31521 - mod->core_text_size = mod->core_size;
31522 + mod->core_size_rx = mod->core_size_rx;
31525 DEBUGP("Init section allocation order:\n");
31526 @@ -1619,12 +1671,15 @@ static void layout_sections(struct modul
31527 || strncmp(secstrings + s->sh_name,
31530 - s->sh_entsize = (get_offset(&mod->init_size, s)
31531 - | INIT_OFFSET_MASK);
31532 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
31533 + s->sh_entsize = get_offset(&mod->init_size_rw, s);
31535 + s->sh_entsize = get_offset(&mod->init_size_rx, s);
31536 + s->sh_entsize |= INIT_OFFSET_MASK;
31537 DEBUGP("\t%s\n", secstrings + s->sh_name);
31540 - mod->init_text_size = mod->init_size;
31541 + mod->init_size_rx = mod->init_size_rx;
31545 @@ -1764,14 +1819,31 @@ static void add_kallsyms(struct module *
31549 +#ifdef CONFIG_PAX_KERNEXEC
31550 + unsigned long cr0;
31553 mod->symtab = (void *)sechdrs[symindex].sh_addr;
31554 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
31555 mod->strtab = (void *)sechdrs[strindex].sh_addr;
31557 /* Set types up while we still have access to sections. */
31558 - for (i = 0; i < mod->num_symtab; i++)
31559 - mod->symtab[i].st_info
31560 - = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
31562 + for (i = 0; i < mod->num_symtab; i++) {
31563 + char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
31565 +#ifdef CONFIG_PAX_KERNEXEC
31566 + pax_open_kernel(cr0);
31569 + mod->symtab[i].st_info = type;
31571 +#ifdef CONFIG_PAX_KERNEXEC
31572 + pax_close_kernel(cr0);
31579 static inline void add_kallsyms(struct module *mod,
31580 @@ -1783,16 +1855,30 @@ static inline void add_kallsyms(struct m
31582 #endif /* CONFIG_KALLSYMS */
31584 -static void *module_alloc_update_bounds(unsigned long size)
31585 +static void *module_alloc_update_bounds_rw(unsigned long size)
31587 void *ret = module_alloc(size);
31590 /* Update module bounds. */
31591 - if ((unsigned long)ret < module_addr_min)
31592 - module_addr_min = (unsigned long)ret;
31593 - if ((unsigned long)ret + size > module_addr_max)
31594 - module_addr_max = (unsigned long)ret + size;
31595 + if ((unsigned long)ret < module_addr_min_rw)
31596 + module_addr_min_rw = (unsigned long)ret;
31597 + if ((unsigned long)ret + size > module_addr_max_rw)
31598 + module_addr_max_rw = (unsigned long)ret + size;
31603 +static void *module_alloc_update_bounds_rx(unsigned long size)
31605 + void *ret = module_alloc_exec(size);
31608 + /* Update module bounds. */
31609 + if ((unsigned long)ret < module_addr_min_rx)
31610 + module_addr_min_rx = (unsigned long)ret;
31611 + if ((unsigned long)ret + size > module_addr_max_rx)
31612 + module_addr_max_rx = (unsigned long)ret + size;
31616 @@ -1837,6 +1923,10 @@ static noinline struct module *load_modu
31617 struct exception_table_entry *extable;
31618 mm_segment_t old_fs;
31620 +#ifdef CONFIG_PAX_KERNEXEC
31621 + unsigned long cr0;
31624 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
31626 if (len < sizeof(*hdr))
31627 @@ -1998,22 +2088,57 @@ static noinline struct module *load_modu
31628 layout_sections(mod, hdr, sechdrs, secstrings);
31630 /* Do the allocs. */
31631 - ptr = module_alloc_update_bounds(mod->core_size);
31632 + ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
31637 - memset(ptr, 0, mod->core_size);
31638 - mod->module_core = ptr;
31639 + memset(ptr, 0, mod->core_size_rw);
31640 + mod->module_core_rw = ptr;
31642 + ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
31643 + if (!ptr && mod->init_size_rw) {
31645 + goto free_core_rw;
31647 + memset(ptr, 0, mod->init_size_rw);
31648 + mod->module_init_rw = ptr;
31650 + ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
31653 + goto free_init_rw;
31656 +#ifdef CONFIG_PAX_KERNEXEC
31657 + pax_open_kernel(cr0);
31660 + memset(ptr, 0, mod->core_size_rx);
31662 - ptr = module_alloc_update_bounds(mod->init_size);
31663 - if (!ptr && mod->init_size) {
31664 +#ifdef CONFIG_PAX_KERNEXEC
31665 + pax_close_kernel(cr0);
31668 + mod->module_core_rx = ptr;
31670 + ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
31671 + if (!ptr && mod->init_size_rx) {
31674 + goto free_core_rx;
31676 - memset(ptr, 0, mod->init_size);
31677 - mod->module_init = ptr;
31679 +#ifdef CONFIG_PAX_KERNEXEC
31680 + pax_open_kernel(cr0);
31683 + memset(ptr, 0, mod->init_size_rx);
31685 +#ifdef CONFIG_PAX_KERNEXEC
31686 + pax_close_kernel(cr0);
31689 + mod->module_init_rx = ptr;
31690 /* Transfer each section which specifies SHF_ALLOC */
31691 DEBUGP("final section addresses:\n");
31692 for (i = 0; i < hdr->e_shnum; i++) {
31693 @@ -2022,17 +2147,41 @@ static noinline struct module *load_modu
31694 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
31697 - if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
31698 - dest = mod->module_init
31699 - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
31701 - dest = mod->module_core + sechdrs[i].sh_entsize;
31702 + if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
31703 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
31704 + dest = mod->module_init_rw
31705 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
31707 + dest = mod->module_init_rx
31708 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
31710 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
31711 + dest = mod->module_core_rw + sechdrs[i].sh_entsize;
31713 + dest = mod->module_core_rx + sechdrs[i].sh_entsize;
31716 + if (sechdrs[i].sh_type != SHT_NOBITS) {
31718 - if (sechdrs[i].sh_type != SHT_NOBITS)
31719 - memcpy(dest, (void *)sechdrs[i].sh_addr,
31720 - sechdrs[i].sh_size);
31721 +#ifdef CONFIG_PAX_KERNEXEC
31722 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
31723 + pax_open_kernel(cr0);
31724 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
31725 + pax_close_kernel(cr0);
31729 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
31731 /* Update sh_addr to point to copy in image. */
31732 - sechdrs[i].sh_addr = (unsigned long)dest;
31734 +#ifdef CONFIG_PAX_KERNEXEC
31735 + if (sechdrs[i].sh_flags & SHF_EXECINSTR)
31736 + sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
31740 + sechdrs[i].sh_addr = (unsigned long)dest;
31741 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
31743 /* Module has been moved. */
31744 @@ -2120,8 +2269,8 @@ static noinline struct module *load_modu
31746 /* Now do relocations. */
31747 for (i = 1; i < hdr->e_shnum; i++) {
31748 - const char *strtab = (char *)sechdrs[strindex].sh_addr;
31749 unsigned int info = sechdrs[i].sh_info;
31750 + strtab = (char *)sechdrs[strindex].sh_addr;
31752 /* Not a valid relocation section? */
31753 if (info >= hdr->e_shnum)
31754 @@ -2180,12 +2329,12 @@ static noinline struct module *load_modu
31755 * Do it before processing of module parameters, so the module
31756 * can provide parameter accessor functions of its own.
31758 - if (mod->module_init)
31759 - flush_icache_range((unsigned long)mod->module_init,
31760 - (unsigned long)mod->module_init
31761 - + mod->init_size);
31762 - flush_icache_range((unsigned long)mod->module_core,
31763 - (unsigned long)mod->module_core + mod->core_size);
31764 + if (mod->module_init_rx)
31765 + flush_icache_range((unsigned long)mod->module_init_rx,
31766 + (unsigned long)mod->module_init_rx
31767 + + mod->init_size_rx);
31768 + flush_icache_range((unsigned long)mod->module_core_rx,
31769 + (unsigned long)mod->module_core_rx + mod->core_size_rx);
31773 @@ -2238,9 +2387,13 @@ static noinline struct module *load_modu
31774 kobject_put(&mod->mkobj.kobj);
31776 module_unload_free(mod);
31777 - module_free(mod, mod->module_init);
31779 - module_free(mod, mod->module_core);
31780 + module_free_exec(mod, mod->module_init_rx);
31782 + module_free_exec(mod, mod->module_core_rx);
31784 + module_free(mod, mod->module_init_rw);
31786 + module_free(mod, mod->module_core_rw);
31789 percpu_modfree(percpu);
31790 @@ -2265,6 +2418,9 @@ sys_init_module(void __user *umod,
31791 struct module *mod;
31794 + if (gr_check_modstop())
31797 /* Must have permission */
31798 if (!capable(CAP_SYS_MODULE))
31800 @@ -2320,10 +2476,12 @@ sys_init_module(void __user *umod,
31801 /* Drop initial reference. */
31803 unwind_remove_table(mod->unwind_info, 1);
31804 - module_free(mod, mod->module_init);
31805 - mod->module_init = NULL;
31806 - mod->init_size = 0;
31807 - mod->init_text_size = 0;
31808 + module_free(mod, mod->module_init_rw);
31809 + module_free_exec(mod, mod->module_init_rx);
31810 + mod->module_init_rw = NULL;
31811 + mod->module_init_rx = NULL;
31812 + mod->init_size_rw = 0;
31813 + mod->init_size_rx = 0;
31814 mutex_unlock(&module_mutex);
31817 @@ -2331,6 +2489,13 @@ sys_init_module(void __user *umod,
31819 static inline int within(unsigned long addr, void *start, unsigned long size)
31822 +#ifdef CONFIG_PAX_KERNEXEC
31823 + if (ktla_ktva(addr) >= (unsigned long)start &&
31824 + ktla_ktva(addr) < (unsigned long)start + size)
31828 return ((void *)addr >= start && (void *)addr < start + size);
31831 @@ -2354,10 +2519,14 @@ static const char *get_ksymbol(struct mo
31832 unsigned long nextval;
31834 /* At worse, next value is at end of module */
31835 - if (within(addr, mod->module_init, mod->init_size))
31836 - nextval = (unsigned long)mod->module_init+mod->init_text_size;
31837 + if (within(addr, mod->module_init_rx, mod->init_size_rx))
31838 + nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
31839 + else if (within(addr, mod->module_init_rw, mod->init_size_rw))
31840 + nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
31841 + else if (within(addr, mod->module_core_rx, mod->core_size_rx))
31842 + nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
31844 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
31845 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
31847 /* Scan for closest preceeding symbol, and next symbol. (ELF
31848 starts real symbols at 1). */
31849 @@ -2402,8 +2571,10 @@ const char *module_address_lookup(unsign
31852 list_for_each_entry(mod, &modules, list) {
31853 - if (within(addr, mod->module_init, mod->init_size)
31854 - || within(addr, mod->module_core, mod->core_size)) {
31855 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
31856 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
31857 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
31858 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
31860 *modname = mod->name;
31861 ret = get_ksymbol(mod, addr, size, offset);
31862 @@ -2425,8 +2596,10 @@ int lookup_module_symbol_name(unsigned l
31865 list_for_each_entry(mod, &modules, list) {
31866 - if (within(addr, mod->module_init, mod->init_size) ||
31867 - within(addr, mod->module_core, mod->core_size)) {
31868 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
31869 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
31870 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
31871 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
31874 sym = get_ksymbol(mod, addr, NULL, NULL);
31875 @@ -2449,8 +2622,10 @@ int lookup_module_symbol_attrs(unsigned
31878 list_for_each_entry(mod, &modules, list) {
31879 - if (within(addr, mod->module_init, mod->init_size) ||
31880 - within(addr, mod->module_core, mod->core_size)) {
31881 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
31882 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
31883 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
31884 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
31887 sym = get_ksymbol(mod, addr, size, offset);
31888 @@ -2581,7 +2756,7 @@ static int m_show(struct seq_file *m, vo
31891 seq_printf(m, "%s %u",
31892 - mod->name, mod->init_size + mod->core_size);
31893 + mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
31894 print_unload_info(m, mod);
31896 /* Informative for users. */
31897 @@ -2590,7 +2765,7 @@ static int m_show(struct seq_file *m, vo
31898 mod->state == MODULE_STATE_COMING ? "Loading":
31900 /* Used by oprofile and other similar tools. */
31901 - seq_printf(m, " 0x%p", mod->module_core);
31902 + seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
31906 @@ -2646,7 +2821,8 @@ int is_module_address(unsigned long addr
31909 list_for_each_entry(mod, &modules, list) {
31910 - if (within(addr, mod->module_core, mod->core_size)) {
31911 + if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
31912 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
31916 @@ -2663,12 +2839,12 @@ struct module *__module_text_address(uns
31918 struct module *mod;
31920 - if (addr < module_addr_min || addr > module_addr_max)
31921 + if (addr < module_addr_min_rx || addr > module_addr_max_rx)
31924 list_for_each_entry(mod, &modules, list)
31925 - if (within(addr, mod->module_init, mod->init_text_size)
31926 - || within(addr, mod->module_core, mod->core_text_size))
31927 + if (within(addr, mod->module_init_rx, mod->init_size_rx)
31928 + || within(addr, mod->module_core_rx, mod->core_size_rx))
31932 diff -urNp linux-2.6.27.4/kernel/mutex.c linux-2.6.27.4/kernel/mutex.c
31933 --- linux-2.6.27.4/kernel/mutex.c 2008-10-22 17:38:01.000000000 -0400
31934 +++ linux-2.6.27.4/kernel/mutex.c 2008-10-27 22:36:18.000000000 -0400
31935 @@ -83,7 +83,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
31937 * This function is similar to (but not equivalent to) down().
31939 -void inline __sched mutex_lock(struct mutex *lock)
31940 +inline void __sched mutex_lock(struct mutex *lock)
31944 diff -urNp linux-2.6.27.4/kernel/panic.c linux-2.6.27.4/kernel/panic.c
31945 --- linux-2.6.27.4/kernel/panic.c 2008-10-22 17:38:01.000000000 -0400
31946 +++ linux-2.6.27.4/kernel/panic.c 2008-10-27 22:36:18.000000000 -0400
31947 @@ -349,6 +349,8 @@ EXPORT_SYMBOL(warn_slowpath);
31949 void __stack_chk_fail(void)
31951 + print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
31953 panic("stack-protector: Kernel stack is corrupted");
31955 EXPORT_SYMBOL(__stack_chk_fail);
31956 diff -urNp linux-2.6.27.4/kernel/pid.c linux-2.6.27.4/kernel/pid.c
31957 --- linux-2.6.27.4/kernel/pid.c 2008-10-22 17:38:01.000000000 -0400
31958 +++ linux-2.6.27.4/kernel/pid.c 2008-10-27 22:36:18.000000000 -0400
31960 #include <linux/syscalls.h>
31961 #include <linux/vs_pid.h>
31962 #include <linux/vserver/global.h>
31963 +#include <linux/grsecurity.h>
31965 #define pid_hashfn(nr, ns) \
31966 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
31967 @@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
31969 int pid_max = PID_MAX_DEFAULT;
31971 -#define RESERVED_PIDS 300
31972 +#define RESERVED_PIDS 500
31974 int pid_max_min = RESERVED_PIDS + 1;
31975 int pid_max_max = PID_MAX_LIMIT;
31976 @@ -381,7 +382,14 @@ EXPORT_SYMBOL(pid_task);
31977 struct task_struct *find_task_by_pid_type_ns(int type, int nr,
31978 struct pid_namespace *ns)
31980 - return pid_task(find_pid_ns(nr, ns), type);
31981 + struct task_struct *task;
31983 + task = pid_task(find_pid_ns(nr, ns), type);
31985 + if (gr_pid_is_chrooted(task))
31991 EXPORT_SYMBOL(find_task_by_pid_type_ns);
31992 diff -urNp linux-2.6.27.4/kernel/posix-cpu-timers.c linux-2.6.27.4/kernel/posix-cpu-timers.c
31993 --- linux-2.6.27.4/kernel/posix-cpu-timers.c 2008-10-22 17:38:01.000000000 -0400
31994 +++ linux-2.6.27.4/kernel/posix-cpu-timers.c 2008-10-27 22:36:18.000000000 -0400
31996 #include <linux/posix-timers.h>
31997 #include <linux/errno.h>
31998 #include <linux/math64.h>
31999 +#include <linux/grsecurity.h>
32000 #include <asm/uaccess.h>
32002 static int check_clock(const clockid_t which_clock)
32003 @@ -1176,6 +1177,7 @@ static void check_process_timers(struct
32004 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
32007 + gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
32008 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
32010 * At the soft limit, send a SIGXCPU every second.
32011 @@ -1370,17 +1372,17 @@ void run_posix_cpu_timers(struct task_st
32012 * timer call will interfere.
32014 list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
32017 spin_lock(&timer->it_lock);
32018 list_del_init(&timer->it.cpu.entry);
32019 - firing = timer->it.cpu.firing;
32020 + __firing = timer->it.cpu.firing;
32021 timer->it.cpu.firing = 0;
32023 * The firing flag is -1 if we collided with a reset
32024 * of the timer, which already reported this
32025 * almost-firing as an overrun. So don't generate an event.
32027 - if (likely(firing >= 0)) {
32028 + if (likely(__firing >= 0)) {
32029 cpu_timer_fire(timer);
32031 spin_unlock(&timer->it_lock);
32032 diff -urNp linux-2.6.27.4/kernel/power/poweroff.c linux-2.6.27.4/kernel/power/poweroff.c
32033 --- linux-2.6.27.4/kernel/power/poweroff.c 2008-10-22 17:38:01.000000000 -0400
32034 +++ linux-2.6.27.4/kernel/power/poweroff.c 2008-10-27 22:36:18.000000000 -0400
32035 @@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
32036 .enable_mask = SYSRQ_ENABLE_BOOT,
32039 -static int pm_sysrq_init(void)
32040 +static int __init pm_sysrq_init(void)
32042 register_sysrq_key('o', &sysrq_poweroff_op);
32044 diff -urNp linux-2.6.27.4/kernel/printk.c linux-2.6.27.4/kernel/printk.c
32045 --- linux-2.6.27.4/kernel/printk.c 2008-10-22 17:38:01.000000000 -0400
32046 +++ linux-2.6.27.4/kernel/printk.c 2008-10-25 12:03:07.000000000 -0400
32048 #include <linux/bootmem.h>
32049 #include <linux/syscalls.h>
32050 #include <linux/vs_cvirt.h>
32051 +#include <linux/grsecurity.h>
32053 #include <asm/uaccess.h>
32055 @@ -293,6 +294,11 @@ int do_syslog(int type, char __user *buf
32059 +#ifdef CONFIG_GRKERNSEC_DMESG
32060 + if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
32064 error = security_syslog(type);
32067 diff -urNp linux-2.6.27.4/kernel/ptrace.c linux-2.6.27.4/kernel/ptrace.c
32068 --- linux-2.6.27.4/kernel/ptrace.c 2008-10-22 17:38:01.000000000 -0400
32069 +++ linux-2.6.27.4/kernel/ptrace.c 2008-10-25 12:03:07.000000000 -0400
32071 #include <linux/pid_namespace.h>
32072 #include <linux/syscalls.h>
32073 #include <linux/vs_context.h>
32074 +#include <linux/grsecurity.h>
32076 #include <asm/pgtable.h>
32077 #include <asm/uaccess.h>
32078 @@ -132,12 +133,12 @@ int __ptrace_may_access(struct task_stru
32079 (current->uid != task->uid) ||
32080 (current->gid != task->egid) ||
32081 (current->gid != task->sgid) ||
32082 - (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
32083 + (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
32087 dumpable = get_dumpable(task->mm);
32088 - if (!dumpable && !capable(CAP_SYS_PTRACE))
32089 + if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
32092 return security_ptrace_may_access(task, mode);
32093 @@ -193,7 +194,7 @@ repeat:
32096 task->ptrace |= PT_PTRACED;
32097 - if (capable(CAP_SYS_PTRACE))
32098 + if (capable_nolog(CAP_SYS_PTRACE))
32099 task->ptrace |= PT_PTRACE_CAP;
32101 __ptrace_link(task, current);
32102 @@ -582,6 +583,11 @@ asmlinkage long sys_ptrace(long request,
32104 goto out_put_task_struct;
32106 + if (gr_handle_ptrace(child, request)) {
32108 + goto out_put_task_struct;
32111 ret = arch_ptrace(child, request, addr, data);
32113 goto out_put_task_struct;
32114 diff -urNp linux-2.6.27.4/kernel/relay.c linux-2.6.27.4/kernel/relay.c
32115 --- linux-2.6.27.4/kernel/relay.c 2008-10-22 17:38:01.000000000 -0400
32116 +++ linux-2.6.27.4/kernel/relay.c 2008-10-27 22:36:18.000000000 -0400
32117 @@ -1291,7 +1291,7 @@ static int subbuf_splice_actor(struct fi
32120 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
32121 - if (ret < 0 || ret < total_len)
32122 + if ((int)ret < 0 || ret < total_len)
32125 if (read_start + ret == nonpad_end)
32126 diff -urNp linux-2.6.27.4/kernel/resource.c linux-2.6.27.4/kernel/resource.c
32127 --- linux-2.6.27.4/kernel/resource.c 2008-10-22 17:38:01.000000000 -0400
32128 +++ linux-2.6.27.4/kernel/resource.c 2008-10-25 12:03:07.000000000 -0400
32129 @@ -131,8 +131,18 @@ static const struct file_operations proc
32131 static int __init ioresources_init(void)
32133 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
32134 +#ifdef CONFIG_GRKERNSEC_PROC_USER
32135 + proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
32136 + proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
32137 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
32138 + proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
32139 + proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
32142 proc_create("ioports", 0, NULL, &proc_ioports_operations);
32143 proc_create("iomem", 0, NULL, &proc_iomem_operations);
32147 __initcall(ioresources_init);
32148 diff -urNp linux-2.6.27.4/kernel/sched.c linux-2.6.27.4/kernel/sched.c
32149 --- linux-2.6.27.4/kernel/sched.c 2008-10-22 17:38:01.000000000 -0400
32150 +++ linux-2.6.27.4/kernel/sched.c 2008-10-27 22:36:18.000000000 -0400
32152 #include <linux/ftrace.h>
32153 #include <linux/vs_sched.h>
32154 #include <linux/vs_cvirt.h>
32155 +#include <linux/grsecurity.h>
32157 #include <asm/tlb.h>
32158 #include <asm/irq_regs.h>
32159 @@ -4962,7 +4963,8 @@ asmlinkage long sys_nice(int increment)
32163 - if (increment < 0 && !can_nice(current, nice))
32164 + if (increment < 0 && (!can_nice(current, nice) ||
32165 + gr_handle_chroot_nice()))
32166 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
32168 retval = security_task_setnice(current, nice);
32169 @@ -6225,7 +6227,7 @@ static struct ctl_table sd_ctl_dir[] = {
32170 .procname = "sched_domain",
32174 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32177 static struct ctl_table sd_ctl_root[] = {
32178 @@ -6235,7 +6237,7 @@ static struct ctl_table sd_ctl_root[] =
32180 .child = sd_ctl_dir,
32183 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32186 static struct ctl_table *sd_alloc_ctl_entry(int n)
32187 diff -urNp linux-2.6.27.4/kernel/signal.c linux-2.6.27.4/kernel/signal.c
32188 --- linux-2.6.27.4/kernel/signal.c 2008-10-22 17:38:01.000000000 -0400
32189 +++ linux-2.6.27.4/kernel/signal.c 2008-10-27 22:36:18.000000000 -0400
32191 #include <linux/capability.h>
32192 #include <linux/freezer.h>
32193 #include <linux/pid_namespace.h>
32194 +#include <linux/grsecurity.h>
32195 #include <linux/nsproxy.h>
32196 #include <linux/vs_context.h>
32197 #include <linux/vs_pid.h>
32198 @@ -595,6 +596,9 @@ static int check_kill_permission(int sig
32202 + if (gr_handle_signal(t, sig))
32205 return security_task_kill(t, info, sig, 0);
32208 @@ -884,8 +888,8 @@ static void print_fatal_signal(struct pt
32209 for (i = 0; i < 16; i++) {
32210 unsigned char insn;
32212 - __get_user(insn, (unsigned char *)(regs->ip + i));
32213 - printk("%02x ", insn);
32214 + if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
32215 + printk("%02x ", insn);
32219 @@ -908,7 +912,7 @@ __group_send_sig_info(int sig, struct si
32220 return send_signal(sig, info, p, 1);
32225 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
32227 return send_signal(sig, info, t, 0);
32228 @@ -946,8 +950,12 @@ force_sig_info(int sig, struct siginfo *
32229 if (action->sa.sa_handler == SIG_DFL)
32230 t->signal->flags &= ~SIGNAL_UNKILLABLE;
32231 ret = specific_send_sig_info(sig, info, t);
32233 spin_unlock_irqrestore(&t->sighand->siglock, flags);
32235 + gr_log_signal(sig, t);
32236 + gr_handle_crash(t, sig);
32241 @@ -1018,6 +1026,8 @@ int group_send_sig_info(int sig, struct
32242 ret = __group_send_sig_info(sig, info, p);
32243 unlock_task_sighand(p, &flags);
32246 + gr_log_signal(sig, p);
32250 diff -urNp linux-2.6.27.4/kernel/softirq.c linux-2.6.27.4/kernel/softirq.c
32251 --- linux-2.6.27.4/kernel/softirq.c 2008-10-22 17:38:01.000000000 -0400
32252 +++ linux-2.6.27.4/kernel/softirq.c 2008-10-27 22:36:18.000000000 -0400
32253 @@ -453,9 +453,9 @@ void tasklet_kill(struct tasklet_struct
32254 printk("Attempt to kill tasklet from interrupt\n");
32256 while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
32260 - while (test_bit(TASKLET_STATE_SCHED, &t->state));
32261 + } while (test_bit(TASKLET_STATE_SCHED, &t->state));
32263 tasklet_unlock_wait(t);
32264 clear_bit(TASKLET_STATE_SCHED, &t->state);
32265 diff -urNp linux-2.6.27.4/kernel/sys.c linux-2.6.27.4/kernel/sys.c
32266 --- linux-2.6.27.4/kernel/sys.c 2008-10-22 17:38:01.000000000 -0400
32267 +++ linux-2.6.27.4/kernel/sys.c 2008-10-27 22:36:18.000000000 -0400
32269 #include <linux/task_io_accounting_ops.h>
32270 #include <linux/seccomp.h>
32271 #include <linux/cpu.h>
32272 +#include <linux/grsecurity.h>
32274 #include <linux/compat.h>
32275 #include <linux/syscalls.h>
32276 @@ -125,6 +126,12 @@ static int set_one_prio(struct task_stru
32281 + if (gr_handle_chroot_setpriority(p, niceval)) {
32286 no_nice = security_task_setnice(p, niceval);
32289 @@ -181,10 +188,10 @@ asmlinkage long sys_setpriority(int whic
32290 if ((who != current->uid) && !(user = find_user(who)))
32291 goto out_unlock; /* No processes for this user */
32293 - do_each_thread(g, p)
32294 + do_each_thread(g, p) {
32296 error = set_one_prio(p, niceval, error);
32297 - while_each_thread(g, p);
32298 + } while_each_thread(g, p);
32299 if (who != current->uid)
32300 free_uid(user); /* For find_user() */
32302 @@ -243,13 +250,13 @@ asmlinkage long sys_getpriority(int whic
32303 if ((who != current->uid) && !(user = find_user(who)))
32304 goto out_unlock; /* No processes for this user */
32306 - do_each_thread(g, p)
32307 + do_each_thread(g, p) {
32308 if (p->uid == who) {
32309 niceval = 20 - task_nice(p);
32310 if (niceval > retval)
32313 - while_each_thread(g, p);
32314 + } while_each_thread(g, p);
32315 if (who != current->uid)
32316 free_uid(user); /* for find_user() */
32318 @@ -499,6 +506,10 @@ asmlinkage long sys_setregid(gid_t rgid,
32323 + if (gr_check_group_change(new_rgid, new_egid, -1))
32326 if (new_egid != old_egid) {
32327 set_dumpable(current->mm, suid_dumpable);
32329 @@ -506,6 +517,9 @@ asmlinkage long sys_setregid(gid_t rgid,
32330 if (rgid != (gid_t) -1 ||
32331 (egid != (gid_t) -1 && egid != old_rgid))
32332 current->sgid = new_egid;
32334 + gr_set_role_label(current, current->uid, new_rgid);
32336 current->fsgid = new_egid;
32337 current->egid = new_egid;
32338 current->gid = new_rgid;
32339 @@ -528,11 +542,17 @@ asmlinkage long sys_setgid(gid_t gid)
32343 + if (gr_check_group_change(gid, gid, gid))
32346 if (capable(CAP_SETGID)) {
32347 if (old_egid != gid) {
32348 set_dumpable(current->mm, suid_dumpable);
32352 + gr_set_role_label(current, current->uid, gid);
32354 current->gid = current->egid = current->sgid = current->fsgid = gid;
32355 } else if ((gid == current->gid) || (gid == current->sgid)) {
32356 if (old_egid != gid) {
32357 @@ -570,6 +590,9 @@ static int set_user(uid_t new_ruid, int
32358 set_dumpable(current->mm, suid_dumpable);
32362 + gr_set_role_label(current, new_ruid, current->gid);
32364 current->uid = new_ruid;
32367 @@ -619,6 +642,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
32371 + if (gr_check_user_change(new_ruid, new_euid, -1))
32374 if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
32377 @@ -665,6 +691,12 @@ asmlinkage long sys_setuid(uid_t uid)
32378 old_suid = current->suid;
32379 new_suid = old_suid;
32381 + if (gr_check_crash_uid(uid))
32384 + if (gr_check_user_change(uid, uid, uid))
32387 if (capable(CAP_SETUID)) {
32388 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
32390 @@ -712,6 +744,10 @@ asmlinkage long sys_setresuid(uid_t ruid
32391 (suid != current->euid) && (suid != current->suid))
32395 + if (gr_check_user_change(ruid, euid, -1))
32398 if (ruid != (uid_t) -1) {
32399 if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
32401 @@ -766,6 +802,10 @@ asmlinkage long sys_setresgid(gid_t rgid
32402 (sgid != current->egid) && (sgid != current->sgid))
32406 + if (gr_check_group_change(rgid, egid, -1))
32409 if (egid != (gid_t) -1) {
32410 if (egid != current->egid) {
32411 set_dumpable(current->mm, suid_dumpable);
32412 @@ -774,8 +814,10 @@ asmlinkage long sys_setresgid(gid_t rgid
32413 current->egid = egid;
32415 current->fsgid = current->egid;
32416 - if (rgid != (gid_t) -1)
32417 + if (rgid != (gid_t) -1) {
32418 + gr_set_role_label(current, current->uid, rgid);
32419 current->gid = rgid;
32421 if (sgid != (gid_t) -1)
32422 current->sgid = sgid;
32424 @@ -810,6 +852,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
32425 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
32428 + if (gr_check_user_change(-1, -1, uid))
32429 + return old_fsuid;
32431 if (uid == current->uid || uid == current->euid ||
32432 uid == current->suid || uid == current->fsuid ||
32433 capable(CAP_SETUID)) {
32434 @@ -842,6 +887,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
32435 if (gid == current->gid || gid == current->egid ||
32436 gid == current->sgid || gid == current->fsgid ||
32437 capable(CAP_SETGID)) {
32438 + if (gr_check_group_change(-1, -1, gid))
32439 + return old_fsgid;
32441 if (gid != old_fsgid) {
32442 set_dumpable(current->mm, suid_dumpable);
32444 @@ -923,7 +971,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
32445 write_lock_irq(&tasklist_lock);
32448 - p = find_task_by_vpid(pid);
32449 + /* grsec: replaced find_task_by_vpid with equivalent call which
32450 + lacks the chroot restriction
32452 + p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
32456 @@ -1655,7 +1706,7 @@ asmlinkage long sys_prctl(int option, un
32457 error = get_dumpable(current->mm);
32459 case PR_SET_DUMPABLE:
32460 - if (arg2 < 0 || arg2 > 1) {
32465 diff -urNp linux-2.6.27.4/kernel/sysctl.c linux-2.6.27.4/kernel/sysctl.c
32466 --- linux-2.6.27.4/kernel/sysctl.c 2008-10-22 17:38:01.000000000 -0400
32467 +++ linux-2.6.27.4/kernel/sysctl.c 2008-10-27 22:36:18.000000000 -0400
32469 static int deprecated_sysctl_warning(struct __sysctl_args *args);
32471 #if defined(CONFIG_SYSCTL)
32472 +#include <linux/grsecurity.h>
32473 +#include <linux/grinternal.h>
32475 +extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
32476 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
32478 +extern int gr_handle_chroot_sysctl(const int op);
32480 /* External variables not in a header file. */
32482 @@ -155,6 +162,7 @@ static int proc_do_cad_pid(struct ctl_ta
32483 static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
32484 void __user *buffer, size_t *lenp, loff_t *ppos);
32486 +extern ctl_table grsecurity_table[];
32488 static struct ctl_table root_table[];
32489 static struct ctl_table_root sysctl_table_root;
32490 @@ -184,6 +192,21 @@ extern struct ctl_table inotify_table[];
32491 int sysctl_legacy_va_layout;
32494 +#ifdef CONFIG_PAX_SOFTMODE
32495 +static ctl_table pax_table[] = {
32497 + .ctl_name = CTL_UNNUMBERED,
32498 + .procname = "softmode",
32499 + .data = &pax_softmode,
32500 + .maxlen = sizeof(unsigned int),
32502 + .proc_handler = &proc_dointvec,
32505 + { .ctl_name = 0 }
32509 extern int prove_locking;
32510 extern int lock_stat;
32512 @@ -220,6 +243,7 @@ static struct ctl_table root_table[] = {
32514 .child = dev_table,
32518 * NOTE: do not add new entries to this table unless you have read
32519 * Documentation/sysctl/ctl_unnumbered.txt
32520 @@ -847,6 +871,25 @@ static struct ctl_table kern_table[] = {
32521 .proc_handler = &proc_dointvec,
32525 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
32527 + .ctl_name = CTL_UNNUMBERED,
32528 + .procname = "grsecurity",
32530 + .child = grsecurity_table,
32534 +#ifdef CONFIG_PAX_SOFTMODE
32536 + .ctl_name = CTL_UNNUMBERED,
32537 + .procname = "pax",
32539 + .child = pax_table,
32544 * NOTE: do not add new entries to this table unless you have read
32545 * Documentation/sysctl/ctl_unnumbered.txt
32546 @@ -1176,6 +1219,7 @@ static struct ctl_table vm_table[] = {
32552 * NOTE: do not add new entries to this table unless you have read
32553 * Documentation/sysctl/ctl_unnumbered.txt
32554 @@ -1543,6 +1587,8 @@ static int do_sysctl_strategy(struct ctl
32558 +static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
32560 static int parse_table(int __user *name, int nlen,
32561 void __user *oldval, size_t __user *oldlenp,
32562 void __user *newval, size_t newlen,
32563 @@ -1561,7 +1607,7 @@ repeat:
32564 if (n == table->ctl_name) {
32566 if (table->child) {
32567 - if (sysctl_perm(root, table, MAY_EXEC))
32568 + if (sysctl_perm_nochk(root, table, MAY_EXEC))
32572 @@ -1658,6 +1704,33 @@ int sysctl_perm(struct ctl_table_root *r
32573 return test_perm(mode, op);
32576 +int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
32581 + if (table->parent != NULL && table->parent->procname != NULL &&
32582 + table->procname != NULL &&
32583 + gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
32585 + if (gr_handle_chroot_sysctl(op))
32587 + error = gr_handle_sysctl(table, op);
32591 + error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
32595 + if (root->permissions)
32596 + mode = root->permissions(root, current->nsproxy, table);
32598 + mode = table->mode;
32600 + return test_perm(mode, op);
32603 static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
32605 for (; table->ctl_name || table->procname; table++) {
32606 diff -urNp linux-2.6.27.4/kernel/time/tick-broadcast.c linux-2.6.27.4/kernel/time/tick-broadcast.c
32607 --- linux-2.6.27.4/kernel/time/tick-broadcast.c 2008-10-22 17:38:01.000000000 -0400
32608 +++ linux-2.6.27.4/kernel/time/tick-broadcast.c 2008-10-27 22:36:18.000000000 -0400
32609 @@ -114,7 +114,7 @@ int tick_device_uses_broadcast(struct cl
32610 * then clear the broadcast bit.
32612 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
32613 - int cpu = smp_processor_id();
32614 + cpu = smp_processor_id();
32616 cpu_clear(cpu, tick_broadcast_mask);
32617 tick_broadcast_clear_oneshot(cpu);
32618 diff -urNp linux-2.6.27.4/kernel/time.c linux-2.6.27.4/kernel/time.c
32619 --- linux-2.6.27.4/kernel/time.c 2008-10-22 17:38:01.000000000 -0400
32620 +++ linux-2.6.27.4/kernel/time.c 2008-10-27 22:36:18.000000000 -0400
32622 #include <linux/fs.h>
32623 #include <linux/slab.h>
32624 #include <linux/math64.h>
32625 +#include <linux/grsecurity.h>
32627 #include <asm/uaccess.h>
32628 #include <asm/unistd.h>
32629 @@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user
32632 vx_settimeofday(&tv);
32634 + gr_log_timechange();
32639 @@ -200,6 +204,8 @@ asmlinkage long sys_settimeofday(struct
32643 + gr_log_timechange();
32645 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
32648 @@ -238,7 +244,7 @@ EXPORT_SYMBOL(current_fs_time);
32649 * Avoid unnecessary multiplications/divisions in the
32650 * two most common HZ cases:
32652 -unsigned int inline jiffies_to_msecs(const unsigned long j)
32653 +inline unsigned int jiffies_to_msecs(const unsigned long j)
32655 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
32656 return (MSEC_PER_SEC / HZ) * j;
32657 @@ -254,7 +260,7 @@ unsigned int inline jiffies_to_msecs(con
32659 EXPORT_SYMBOL(jiffies_to_msecs);
32661 -unsigned int inline jiffies_to_usecs(const unsigned long j)
32662 +inline unsigned int jiffies_to_usecs(const unsigned long j)
32664 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
32665 return (USEC_PER_SEC / HZ) * j;
32666 diff -urNp linux-2.6.27.4/kernel/utsname_sysctl.c linux-2.6.27.4/kernel/utsname_sysctl.c
32667 --- linux-2.6.27.4/kernel/utsname_sysctl.c 2008-10-22 17:38:01.000000000 -0400
32668 +++ linux-2.6.27.4/kernel/utsname_sysctl.c 2008-10-27 22:36:18.000000000 -0400
32669 @@ -124,7 +124,7 @@ static struct ctl_table uts_kern_table[]
32670 .proc_handler = proc_do_uts_string,
32671 .strategy = sysctl_uts_string,
32674 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32677 static struct ctl_table uts_root_table[] = {
32678 @@ -134,7 +134,7 @@ static struct ctl_table uts_root_table[]
32680 .child = uts_kern_table,
32683 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32686 static int __init utsname_sysctl_init(void)
32687 diff -urNp linux-2.6.27.4/lib/radix-tree.c linux-2.6.27.4/lib/radix-tree.c
32688 --- linux-2.6.27.4/lib/radix-tree.c 2008-10-22 17:38:01.000000000 -0400
32689 +++ linux-2.6.27.4/lib/radix-tree.c 2008-10-27 22:36:18.000000000 -0400
32690 @@ -81,7 +81,7 @@ struct radix_tree_preload {
32692 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
32694 -DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
32695 +DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
32697 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
32699 diff -urNp linux-2.6.27.4/localversion-grsec linux-2.6.27.4/localversion-grsec
32700 --- linux-2.6.27.4/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
32701 +++ linux-2.6.27.4/localversion-grsec 2008-10-25 12:03:07.000000000 -0400
32704 diff -urNp linux-2.6.27.4/Makefile linux-2.6.27.4/Makefile
32705 --- linux-2.6.27.4/Makefile 2008-10-27 22:25:00.000000000 -0400
32706 +++ linux-2.6.27.4/Makefile 2008-10-27 22:36:16.000000000 -0400
32707 @@ -221,7 +221,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
32711 -HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
32712 +HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
32715 # Decide whether to build built-in, modular, or both.
32716 @@ -619,7 +619,7 @@ export mod_strip_cmd
32719 ifeq ($(KBUILD_EXTMOD),)
32720 -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
32721 +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
32723 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
32724 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
32725 diff -urNp linux-2.6.27.4/mm/filemap.c linux-2.6.27.4/mm/filemap.c
32726 --- linux-2.6.27.4/mm/filemap.c 2008-10-22 17:38:01.000000000 -0400
32727 +++ linux-2.6.27.4/mm/filemap.c 2008-10-27 22:36:18.000000000 -0400
32729 #include <linux/cpuset.h>
32730 #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
32731 #include <linux/memcontrol.h>
32732 +#include <linux/grsecurity.h>
32733 #include "internal.h"
32736 @@ -1588,7 +1589,7 @@ int generic_file_mmap(struct file * file
32737 struct address_space *mapping = file->f_mapping;
32739 if (!mapping->a_ops->readpage)
32742 file_accessed(file);
32743 vma->vm_ops = &generic_file_vm_ops;
32744 vma->vm_flags |= VM_CAN_NONLINEAR;
32745 @@ -1949,6 +1950,7 @@ inline int generic_write_checks(struct f
32746 *pos = i_size_read(inode);
32748 if (limit != RLIM_INFINITY) {
32749 + gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
32750 if (*pos >= limit) {
32751 send_sig(SIGXFSZ, current, 0);
32753 diff -urNp linux-2.6.27.4/mm/fremap.c linux-2.6.27.4/mm/fremap.c
32754 --- linux-2.6.27.4/mm/fremap.c 2008-10-22 17:38:01.000000000 -0400
32755 +++ linux-2.6.27.4/mm/fremap.c 2008-10-27 22:36:19.000000000 -0400
32756 @@ -151,6 +151,13 @@ asmlinkage long sys_remap_file_pages(uns
32758 vma = find_vma(mm, start);
32760 +#ifdef CONFIG_PAX_SEGMEXEC
32761 + if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
32762 + up_read(&mm->mmap_sem);
32768 * Make sure the vma is shared, that it supports prefaulting,
32769 * and that the remapped range is valid and fully within
32770 diff -urNp linux-2.6.27.4/mm/hugetlb.c linux-2.6.27.4/mm/hugetlb.c
32771 --- linux-2.6.27.4/mm/hugetlb.c 2008-10-22 17:38:01.000000000 -0400
32772 +++ linux-2.6.27.4/mm/hugetlb.c 2008-10-27 22:36:19.000000000 -0400
32773 @@ -1787,6 +1787,26 @@ int unmap_ref_private(struct mm_struct *
32777 +#ifdef CONFIG_PAX_SEGMEXEC
32778 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
32780 + struct mm_struct *mm = vma->vm_mm;
32781 + struct vm_area_struct *vma_m;
32782 + unsigned long address_m;
32785 + vma_m = pax_find_mirror_vma(vma);
32789 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
32790 + address_m = address + SEGMEXEC_TASK_SIZE;
32791 + ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
32792 + get_page(page_m);
32793 + set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
32797 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
32798 unsigned long address, pte_t *ptep, pte_t pte,
32799 struct page *pagecache_page)
32800 @@ -1858,6 +1878,11 @@ retry_avoidcopy:
32801 huge_ptep_clear_flush(vma, address, ptep);
32802 set_huge_pte_at(mm, address, ptep,
32803 make_huge_pte(vma, new_page, 1));
32805 +#ifdef CONFIG_PAX_SEGMEXEC
32806 + pax_mirror_huge_pte(vma, address, new_page);
32809 /* Make the old page be freed below */
32810 new_page = old_page;
32812 @@ -1967,6 +1992,10 @@ retry:
32813 && (vma->vm_flags & VM_SHARED)));
32814 set_huge_pte_at(mm, address, ptep, new_pte);
32816 +#ifdef CONFIG_PAX_SEGMEXEC
32817 + pax_mirror_huge_pte(vma, address, page);
32820 if (write_access && !(vma->vm_flags & VM_SHARED)) {
32821 /* Optimization, do the COW without a second fault */
32822 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
32823 @@ -1995,6 +2024,28 @@ int hugetlb_fault(struct mm_struct *mm,
32824 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
32825 struct hstate *h = hstate_vma(vma);
32827 +#ifdef CONFIG_PAX_SEGMEXEC
32828 + struct vm_area_struct *vma_m;
32830 + vma_m = pax_find_mirror_vma(vma);
32832 + unsigned long address_m;
32834 + if (vma->vm_start > vma_m->vm_start) {
32835 + address_m = address;
32836 + address -= SEGMEXEC_TASK_SIZE;
32838 + h = hstate_vma(vma);
32840 + address_m = address + SEGMEXEC_TASK_SIZE;
32842 + if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
32843 + return VM_FAULT_OOM;
32844 + address_m &= HPAGE_MASK;
32845 + unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
32849 ptep = huge_pte_alloc(mm, address, huge_page_size(h));
32851 return VM_FAULT_OOM;
32852 diff -urNp linux-2.6.27.4/mm/madvise.c linux-2.6.27.4/mm/madvise.c
32853 --- linux-2.6.27.4/mm/madvise.c 2008-10-22 17:38:01.000000000 -0400
32854 +++ linux-2.6.27.4/mm/madvise.c 2008-10-27 22:36:19.000000000 -0400
32855 @@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
32857 int new_flags = vma->vm_flags;
32859 +#ifdef CONFIG_PAX_SEGMEXEC
32860 + struct vm_area_struct *vma_m;
32863 switch (behavior) {
32865 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
32866 @@ -92,6 +96,13 @@ success:
32868 * vm_flags is protected by the mmap_sem held in write mode.
32871 +#ifdef CONFIG_PAX_SEGMEXEC
32872 + vma_m = pax_find_mirror_vma(vma);
32874 + vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
32877 vma->vm_flags = new_flags;
32880 @@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
32882 case MADV_DONTNEED:
32883 error = madvise_dontneed(vma, prev, start, end);
32885 +#ifdef CONFIG_PAX_SEGMEXEC
32887 + struct vm_area_struct *vma_m, *prev_m;
32889 + vma_m = pax_find_mirror_vma(vma);
32891 + error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
32898 @@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
32902 +#ifdef CONFIG_PAX_SEGMEXEC
32903 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
32904 + if (end > SEGMEXEC_TASK_SIZE)
32909 + if (end > TASK_SIZE)
32915 diff -urNp linux-2.6.27.4/mm/memory.c linux-2.6.27.4/mm/memory.c
32916 --- linux-2.6.27.4/mm/memory.c 2008-10-22 17:38:01.000000000 -0400
32917 +++ linux-2.6.27.4/mm/memory.c 2008-10-27 22:36:19.000000000 -0400
32919 #include <linux/writeback.h>
32920 #include <linux/memcontrol.h>
32921 #include <linux/mmu_notifier.h>
32922 +#include <linux/grsecurity.h>
32924 #include <asm/pgalloc.h>
32925 #include <asm/uaccess.h>
32926 @@ -1146,11 +1147,11 @@ int get_user_pages(struct task_struct *t
32927 vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
32932 struct vm_area_struct *vma;
32933 unsigned int foll_flags;
32935 - vma = find_extend_vma(mm, start);
32936 + vma = find_vma(mm, start);
32937 if (!vma && in_gate_area(tsk, start)) {
32938 unsigned long pg = start & PAGE_MASK;
32939 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
32940 @@ -1190,7 +1191,7 @@ int get_user_pages(struct task_struct *t
32944 - if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
32945 + if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
32946 || !(vm_flags & vma->vm_flags))
32947 return i ? : -EFAULT;
32949 @@ -1263,7 +1264,7 @@ int get_user_pages(struct task_struct *t
32950 start += PAGE_SIZE;
32952 } while (len && start < vma->vm_end);
32957 EXPORT_SYMBOL(get_user_pages);
32958 @@ -1741,6 +1742,186 @@ static inline void cow_user_page(struct
32959 copy_user_highpage(dst, src, va, vma);
32962 +#ifdef CONFIG_PAX_SEGMEXEC
32963 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
32965 + struct mm_struct *mm = vma->vm_mm;
32967 + pte_t *pte, entry;
32969 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
32971 + if (!pte_present(entry)) {
32972 + if (!pte_none(entry)) {
32973 + BUG_ON(pte_file(entry));
32974 + free_swap_and_cache(pte_to_swp_entry(entry));
32975 + pte_clear_not_present_full(mm, address, pte, 0);
32978 + struct page *page;
32980 + flush_cache_page(vma, address, pte_pfn(entry));
32981 + entry = ptep_clear_flush(vma, address, pte);
32982 + BUG_ON(pte_dirty(entry));
32983 + page = vm_normal_page(vma, address, entry);
32985 + update_hiwater_rss(mm);
32986 + if (PageAnon(page))
32987 + dec_mm_counter(mm, anon_rss);
32989 + dec_mm_counter(mm, file_rss);
32990 + page_remove_rmap(page, vma);
32991 + page_cache_release(page);
32994 + pte_unmap_unlock(pte, ptl);
32997 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
32999 + * the ptl of the lower mapped page is held on entry and is not released on exit
33000 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
33002 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33004 + struct mm_struct *mm = vma->vm_mm;
33005 + unsigned long address_m;
33006 + spinlock_t *ptl_m;
33007 + struct vm_area_struct *vma_m;
33009 + pte_t *pte_m, entry_m;
33011 + BUG_ON(!page_m || !PageAnon(page_m));
33013 + vma_m = pax_find_mirror_vma(vma);
33017 + BUG_ON(!PageLocked(page_m));
33018 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33019 + address_m = address + SEGMEXEC_TASK_SIZE;
33020 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33021 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33022 + ptl_m = pte_lockptr(mm, pmd_m);
33023 + if (ptl != ptl_m) {
33024 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33025 + if (!pte_none(*pte_m))
33029 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33030 + page_cache_get(page_m);
33031 + page_add_anon_rmap(page_m, vma_m, address_m);
33032 + inc_mm_counter(mm, anon_rss);
33033 + set_pte_at(mm, address_m, pte_m, entry_m);
33034 + update_mmu_cache(vma_m, address_m, entry_m);
33036 + if (ptl != ptl_m)
33037 + spin_unlock(ptl_m);
33038 + pte_unmap_nested(pte_m);
33039 + unlock_page(page_m);
33042 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33044 + struct mm_struct *mm = vma->vm_mm;
33045 + unsigned long address_m;
33046 + spinlock_t *ptl_m;
33047 + struct vm_area_struct *vma_m;
33049 + pte_t *pte_m, entry_m;
33051 + BUG_ON(!page_m || PageAnon(page_m));
33053 + vma_m = pax_find_mirror_vma(vma);
33057 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33058 + address_m = address + SEGMEXEC_TASK_SIZE;
33059 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33060 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33061 + ptl_m = pte_lockptr(mm, pmd_m);
33062 + if (ptl != ptl_m) {
33063 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33064 + if (!pte_none(*pte_m))
33068 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33069 + page_cache_get(page_m);
33070 + page_add_file_rmap(page_m);
33071 + inc_mm_counter(mm, file_rss);
33072 + set_pte_at(mm, address_m, pte_m, entry_m);
33073 + update_mmu_cache(vma_m, address_m, entry_m);
33075 + if (ptl != ptl_m)
33076 + spin_unlock(ptl_m);
33077 + pte_unmap_nested(pte_m);
33080 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
33082 + struct mm_struct *mm = vma->vm_mm;
33083 + unsigned long address_m;
33084 + spinlock_t *ptl_m;
33085 + struct vm_area_struct *vma_m;
33087 + pte_t *pte_m, entry_m;
33089 + vma_m = pax_find_mirror_vma(vma);
33093 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33094 + address_m = address + SEGMEXEC_TASK_SIZE;
33095 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33096 + pte_m = pte_offset_map_nested(pmd_m, address_m);
33097 + ptl_m = pte_lockptr(mm, pmd_m);
33098 + if (ptl != ptl_m) {
33099 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33100 + if (!pte_none(*pte_m))
33104 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
33105 + set_pte_at(mm, address_m, pte_m, entry_m);
33107 + if (ptl != ptl_m)
33108 + spin_unlock(ptl_m);
33109 + pte_unmap_nested(pte_m);
33112 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
33114 + struct page *page_m;
33117 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
33121 + page_m = vm_normal_page(vma, address, entry);
33123 + pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
33124 + else if (PageAnon(page_m)) {
33125 + if (pax_find_mirror_vma(vma)) {
33126 + pte_unmap_unlock(pte, ptl);
33127 + lock_page(page_m);
33128 + pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
33129 + if (pte_same(entry, *pte))
33130 + pax_mirror_anon_pte(vma, address, page_m, ptl);
33132 + unlock_page(page_m);
33135 + pax_mirror_file_pte(vma, address, page_m, ptl);
33138 + pte_unmap_unlock(pte, ptl);
33143 * This routine handles present pages, when users try to write
33144 * to a shared page. It is done by copying the page to a new address
33145 @@ -1869,6 +2050,12 @@ gotten:
33147 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33148 if (likely(pte_same(*page_table, orig_pte))) {
33150 +#ifdef CONFIG_PAX_SEGMEXEC
33151 + if (pax_find_mirror_vma(vma))
33152 + BUG_ON(!trylock_page(new_page));
33156 if (!PageAnon(old_page)) {
33157 dec_mm_counter(mm, file_rss);
33158 @@ -1917,6 +2104,10 @@ gotten:
33159 page_remove_rmap(old_page, vma);
33162 +#ifdef CONFIG_PAX_SEGMEXEC
33163 + pax_mirror_anon_pte(vma, address, new_page, ptl);
33166 /* Free the old page.. */
33167 new_page = old_page;
33168 ret |= VM_FAULT_WRITE;
33169 @@ -2176,6 +2367,7 @@ int vmtruncate(struct inode * inode, lof
33170 unsigned long limit;
33172 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
33173 + gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
33174 if (limit != RLIM_INFINITY && offset > limit)
33176 if (offset > inode->i_sb->s_maxbytes)
33177 @@ -2326,6 +2518,11 @@ static int do_swap_page(struct mm_struct
33179 if (vm_swap_full())
33180 remove_exclusive_swap_page(page);
33182 +#ifdef CONFIG_PAX_SEGMEXEC
33183 + if (write_access || !pax_find_mirror_vma(vma))
33188 if (write_access) {
33189 @@ -2337,6 +2534,11 @@ static int do_swap_page(struct mm_struct
33191 /* No need to invalidate - it was non-present before */
33192 update_mmu_cache(vma, address, pte);
33194 +#ifdef CONFIG_PAX_SEGMEXEC
33195 + pax_mirror_anon_pte(vma, address, page, ptl);
33199 pte_unmap_unlock(page_table, ptl);
33201 @@ -2381,6 +2583,12 @@ static int do_anonymous_page(struct mm_s
33202 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33203 if (!pte_none(*page_table))
33206 +#ifdef CONFIG_PAX_SEGMEXEC
33207 + if (pax_find_mirror_vma(vma))
33208 + BUG_ON(!trylock_page(page));
33211 inc_mm_counter(mm, anon_rss);
33212 lru_cache_add_active(page);
33213 page_add_new_anon_rmap(page, vma, address);
33214 @@ -2388,6 +2596,11 @@ static int do_anonymous_page(struct mm_s
33216 /* No need to invalidate - it was non-present before */
33217 update_mmu_cache(vma, address, entry);
33219 +#ifdef CONFIG_PAX_SEGMEXEC
33220 + pax_mirror_anon_pte(vma, address, page, ptl);
33224 pte_unmap_unlock(page_table, ptl);
33226 @@ -2516,6 +2729,12 @@ static int __do_fault(struct mm_struct *
33228 /* Only go through if we didn't race with anybody else... */
33229 if (likely(pte_same(*page_table, orig_pte))) {
33231 +#ifdef CONFIG_PAX_SEGMEXEC
33232 + if (anon && pax_find_mirror_vma(vma))
33233 + BUG_ON(!trylock_page(page));
33236 flush_icache_page(vma, page);
33237 entry = mk_pte(page, vma->vm_page_prot);
33238 if (flags & FAULT_FLAG_WRITE)
33239 @@ -2536,6 +2755,14 @@ static int __do_fault(struct mm_struct *
33241 /* no need to invalidate: a not-present page won't be cached */
33242 update_mmu_cache(vma, address, entry);
33244 +#ifdef CONFIG_PAX_SEGMEXEC
33246 + pax_mirror_anon_pte(vma, address, page, ptl);
33248 + pax_mirror_file_pte(vma, address, page, ptl);
33252 mem_cgroup_uncharge_page(page);
33254 @@ -2668,6 +2895,12 @@ static inline int handle_pte_fault(struc
33256 flush_tlb_page(vma, address);
33259 +#ifdef CONFIG_PAX_SEGMEXEC
33260 + pax_mirror_pte(vma, address, pte, pmd, ptl);
33265 pte_unmap_unlock(pte, ptl);
33267 @@ -2684,6 +2917,10 @@ int handle_mm_fault(struct mm_struct *mm
33271 +#ifdef CONFIG_PAX_SEGMEXEC
33272 + struct vm_area_struct *vma_m;
33275 __set_current_state(TASK_RUNNING);
33277 count_vm_event(PGFAULT);
33278 @@ -2691,6 +2928,34 @@ int handle_mm_fault(struct mm_struct *mm
33279 if (unlikely(is_vm_hugetlb_page(vma)))
33280 return hugetlb_fault(mm, vma, address, write_access);
33282 +#ifdef CONFIG_PAX_SEGMEXEC
33283 + vma_m = pax_find_mirror_vma(vma);
33285 + unsigned long address_m;
33290 + if (vma->vm_start > vma_m->vm_start) {
33291 + address_m = address;
33292 + address -= SEGMEXEC_TASK_SIZE;
33295 + address_m = address + SEGMEXEC_TASK_SIZE;
33297 + pgd_m = pgd_offset(mm, address_m);
33298 + pud_m = pud_alloc(mm, pgd_m, address_m);
33300 + return VM_FAULT_OOM;
33301 + pmd_m = pmd_alloc(mm, pud_m, address_m);
33303 + return VM_FAULT_OOM;
33304 + if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
33305 + return VM_FAULT_OOM;
33306 + pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
33310 pgd = pgd_offset(mm, address);
33311 pud = pud_alloc(mm, pgd, address);
33313 @@ -2798,7 +3063,7 @@ static int __init gate_vma_init(void)
33314 gate_vma.vm_start = FIXADDR_USER_START;
33315 gate_vma.vm_end = FIXADDR_USER_END;
33316 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
33317 - gate_vma.vm_page_prot = __P101;
33318 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
33320 * Make sure the vDSO gets into every core dump.
33321 * Dumping its contents makes post-mortem fully interpretable later
33322 diff -urNp linux-2.6.27.4/mm/mempolicy.c linux-2.6.27.4/mm/mempolicy.c
33323 --- linux-2.6.27.4/mm/mempolicy.c 2008-10-22 17:38:01.000000000 -0400
33324 +++ linux-2.6.27.4/mm/mempolicy.c 2008-10-27 22:36:19.000000000 -0400
33325 @@ -555,6 +555,10 @@ static int mbind_range(struct vm_area_st
33326 struct vm_area_struct *next;
33329 +#ifdef CONFIG_PAX_SEGMEXEC
33330 + struct vm_area_struct *vma_m;
33334 for (; vma && vma->vm_start < end; vma = next) {
33335 next = vma->vm_next;
33336 @@ -566,6 +570,16 @@ static int mbind_range(struct vm_area_st
33337 err = policy_vma(vma, new);
33341 +#ifdef CONFIG_PAX_SEGMEXEC
33342 + vma_m = pax_find_mirror_vma(vma);
33344 + err = policy_vma(vma_m, new);
33353 @@ -951,6 +965,17 @@ static long do_mbind(unsigned long start
33358 +#ifdef CONFIG_PAX_SEGMEXEC
33359 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
33360 + if (end > SEGMEXEC_TASK_SIZE)
33365 + if (end > TASK_SIZE)
33371 diff -urNp linux-2.6.27.4/mm/mlock.c linux-2.6.27.4/mm/mlock.c
33372 --- linux-2.6.27.4/mm/mlock.c 2008-10-22 17:38:01.000000000 -0400
33373 +++ linux-2.6.27.4/mm/mlock.c 2008-10-27 22:36:19.000000000 -0400
33375 #include <linux/sched.h>
33376 #include <linux/module.h>
33377 #include <linux/vs_memory.h>
33378 +#include <linux/grsecurity.h>
33380 int can_do_mlock(void)
33382 @@ -93,6 +94,17 @@ static int do_mlock(unsigned long start,
33387 +#ifdef CONFIG_PAX_SEGMEXEC
33388 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
33389 + if (end > SEGMEXEC_TASK_SIZE)
33394 + if (end > TASK_SIZE)
33397 vma = find_vma_prev(current->mm, start, &prev);
33398 if (!vma || vma->vm_start > start)
33400 @@ -150,6 +162,7 @@ asmlinkage long sys_mlock(unsigned long
33401 lock_limit >>= PAGE_SHIFT;
33403 /* check against resource limits */
33404 + gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
33405 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
33406 error = do_mlock(start, len, 1);
33407 up_write(¤t->mm->mmap_sem);
33408 @@ -171,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
33409 static int do_mlockall(int flags)
33411 struct vm_area_struct * vma, * prev = NULL;
33412 - unsigned int def_flags = 0;
33413 + unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
33415 if (flags & MCL_FUTURE)
33416 - def_flags = VM_LOCKED;
33417 + def_flags |= VM_LOCKED;
33418 current->mm->def_flags = def_flags;
33419 if (flags == MCL_FUTURE)
33421 @@ -182,6 +195,12 @@ static int do_mlockall(int flags)
33422 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
33423 unsigned int newflags;
33425 +#ifdef CONFIG_PAX_SEGMEXEC
33426 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
33430 + BUG_ON(vma->vm_end > TASK_SIZE);
33431 newflags = vma->vm_flags | VM_LOCKED;
33432 if (!(flags & MCL_CURRENT))
33433 newflags &= ~VM_LOCKED;
33434 @@ -211,6 +230,7 @@ asmlinkage long sys_mlockall(int flags)
33435 lock_limit >>= PAGE_SHIFT;
33438 + gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
33439 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
33441 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
33442 diff -urNp linux-2.6.27.4/mm/mmap.c linux-2.6.27.4/mm/mmap.c
33443 --- linux-2.6.27.4/mm/mmap.c 2008-10-22 17:38:01.000000000 -0400
33444 +++ linux-2.6.27.4/mm/mmap.c 2008-10-27 22:36:19.000000000 -0400
33446 #include <linux/mempolicy.h>
33447 #include <linux/rmap.h>
33448 #include <linux/mmu_notifier.h>
33449 +#include <linux/grsecurity.h>
33451 #include <asm/uaccess.h>
33452 #include <asm/cacheflush.h>
33454 #define arch_rebalance_pgtables(addr, len) (addr)
33457 +static inline void verify_mm_writelocked(struct mm_struct *mm)
33459 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
33460 + if (unlikely(down_read_trylock(&mm->mmap_sem))) {
33461 + up_read(&mm->mmap_sem);
33467 static void unmap_region(struct mm_struct *mm,
33468 struct vm_area_struct *vma, struct vm_area_struct *prev,
33469 unsigned long start, unsigned long end);
33470 @@ -68,16 +79,25 @@ static void unmap_region(struct mm_struc
33471 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
33474 -pgprot_t protection_map[16] = {
33475 +pgprot_t protection_map[16] __read_only = {
33476 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
33477 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
33480 pgprot_t vm_get_page_prot(unsigned long vm_flags)
33482 - return __pgprot(pgprot_val(protection_map[vm_flags &
33483 + pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
33484 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
33485 pgprot_val(arch_vm_get_page_prot(vm_flags)));
33487 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
33488 + if (!nx_enabled &&
33489 + (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
33490 + (vm_flags & (VM_READ | VM_WRITE)))
33491 + prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
33496 EXPORT_SYMBOL(vm_get_page_prot);
33498 @@ -232,6 +252,7 @@ static struct vm_area_struct *remove_vma
33499 struct vm_area_struct *next = vma->vm_next;
33502 + BUG_ON(vma->vm_mirror);
33503 if (vma->vm_ops && vma->vm_ops->close)
33504 vma->vm_ops->close(vma);
33505 if (vma->vm_file) {
33506 @@ -268,6 +289,7 @@ asmlinkage unsigned long sys_brk(unsigne
33507 * not page aligned -Ram Gupta
33509 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
33510 + gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
33511 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
33512 (mm->end_data - mm->start_data) > rlim)
33514 @@ -697,6 +719,12 @@ static int
33515 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
33516 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
33519 +#ifdef CONFIG_PAX_SEGMEXEC
33520 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
33524 if (is_mergeable_vma(vma, file, vm_flags) &&
33525 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
33526 if (vma->vm_pgoff == vm_pgoff)
33527 @@ -716,6 +744,12 @@ static int
33528 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
33529 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
33532 +#ifdef CONFIG_PAX_SEGMEXEC
33533 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
33537 if (is_mergeable_vma(vma, file, vm_flags) &&
33538 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
33540 @@ -758,12 +792,19 @@ can_vma_merge_after(struct vm_area_struc
33541 struct vm_area_struct *vma_merge(struct mm_struct *mm,
33542 struct vm_area_struct *prev, unsigned long addr,
33543 unsigned long end, unsigned long vm_flags,
33544 - struct anon_vma *anon_vma, struct file *file,
33545 + struct anon_vma *anon_vma, struct file *file,
33546 pgoff_t pgoff, struct mempolicy *policy)
33548 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
33549 struct vm_area_struct *area, *next;
33551 +#ifdef CONFIG_PAX_SEGMEXEC
33552 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
33553 + struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
33555 + BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
33559 * We later require that vma->vm_flags == vm_flags,
33560 * so this tests vma->vm_flags & VM_SPECIAL, too.
33561 @@ -779,6 +820,15 @@ struct vm_area_struct *vma_merge(struct
33562 if (next && next->vm_end == end) /* cases 6, 7, 8 */
33563 next = next->vm_next;
33565 +#ifdef CONFIG_PAX_SEGMEXEC
33567 + prev_m = pax_find_mirror_vma(prev);
33569 + area_m = pax_find_mirror_vma(area);
33571 + next_m = pax_find_mirror_vma(next);
33575 * Can it merge with the predecessor?
33577 @@ -798,9 +848,24 @@ struct vm_area_struct *vma_merge(struct
33579 vma_adjust(prev, prev->vm_start,
33580 next->vm_end, prev->vm_pgoff, NULL);
33581 - } else /* cases 2, 5, 7 */
33583 +#ifdef CONFIG_PAX_SEGMEXEC
33585 + vma_adjust(prev_m, prev_m->vm_start,
33586 + next_m->vm_end, prev_m->vm_pgoff, NULL);
33589 + } else { /* cases 2, 5, 7 */
33590 vma_adjust(prev, prev->vm_start,
33591 end, prev->vm_pgoff, NULL);
33593 +#ifdef CONFIG_PAX_SEGMEXEC
33595 + vma_adjust(prev_m, prev_m->vm_start,
33596 + end_m, prev_m->vm_pgoff, NULL);
33603 @@ -811,12 +876,27 @@ struct vm_area_struct *vma_merge(struct
33604 mpol_equal(policy, vma_policy(next)) &&
33605 can_vma_merge_before(next, vm_flags,
33606 anon_vma, file, pgoff+pglen)) {
33607 - if (prev && addr < prev->vm_end) /* case 4 */
33608 + if (prev && addr < prev->vm_end) { /* case 4 */
33609 vma_adjust(prev, prev->vm_start,
33610 addr, prev->vm_pgoff, NULL);
33611 - else /* cases 3, 8 */
33613 +#ifdef CONFIG_PAX_SEGMEXEC
33615 + vma_adjust(prev_m, prev_m->vm_start,
33616 + addr_m, prev_m->vm_pgoff, NULL);
33619 + } else { /* cases 3, 8 */
33620 vma_adjust(area, addr, next->vm_end,
33621 next->vm_pgoff - pglen, NULL);
33623 +#ifdef CONFIG_PAX_SEGMEXEC
33625 + vma_adjust(area_m, addr_m, next_m->vm_end,
33626 + next_m->vm_pgoff - pglen, NULL);
33633 @@ -891,14 +971,11 @@ none:
33634 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
33635 struct file *file, long pages)
33637 - const unsigned long stack_flags
33638 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
33641 mm->shared_vm += pages;
33642 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
33643 mm->exec_vm += pages;
33644 - } else if (flags & stack_flags)
33645 + } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
33646 mm->stack_vm += pages;
33647 if (flags & (VM_RESERVED|VM_IO))
33648 mm->reserved_vm += pages;
33649 @@ -926,7 +1003,7 @@ unsigned long do_mmap_pgoff(struct file
33650 * (the exception is when the underlying filesystem is noexec
33651 * mounted, in which case we dont add PROT_EXEC.)
33653 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
33654 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
33655 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
33658 @@ -936,15 +1013,15 @@ unsigned long do_mmap_pgoff(struct file
33659 if (!(flags & MAP_FIXED))
33660 addr = round_hint_to_min(addr);
33662 - error = arch_mmap_check(addr, len, flags);
33666 /* Careful about overflows.. */
33667 len = PAGE_ALIGN(len);
33668 if (!len || len > TASK_SIZE)
33671 + error = arch_mmap_check(addr, len, flags);
33675 /* offset overflow? */
33676 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
33678 @@ -956,7 +1033,7 @@ unsigned long do_mmap_pgoff(struct file
33679 /* Obtain the address to map to. we verify (or select) it and ensure
33680 * that it represents a valid section of the address space.
33682 - addr = get_unmapped_area(file, addr, len, pgoff, flags);
33683 + addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
33684 if (addr & ~PAGE_MASK)
33687 @@ -967,6 +1044,26 @@ unsigned long do_mmap_pgoff(struct file
33688 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
33689 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
33691 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
33692 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
33694 +#ifdef CONFIG_PAX_MPROTECT
33695 + if (mm->pax_flags & MF_PAX_MPROTECT) {
33696 + if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
33697 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
33699 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
33706 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
33707 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
33708 + vm_flags &= ~VM_PAGEEXEC;
33711 if (flags & MAP_LOCKED) {
33712 if (!can_do_mlock())
33714 @@ -979,6 +1076,7 @@ unsigned long do_mmap_pgoff(struct file
33715 locked += mm->locked_vm;
33716 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
33717 lock_limit >>= PAGE_SHIFT;
33718 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
33719 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
33722 @@ -1051,6 +1149,9 @@ unsigned long do_mmap_pgoff(struct file
33726 + if (!gr_acl_handle_mmap(file, prot))
33729 return mmap_region(file, addr, len, flags, vm_flags, pgoff,
33732 @@ -1064,10 +1165,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
33734 int vma_wants_writenotify(struct vm_area_struct *vma)
33736 - unsigned int vm_flags = vma->vm_flags;
33737 + unsigned long vm_flags = vma->vm_flags;
33739 /* If it was private or non-writable, the write bit is already clear */
33740 - if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
33741 + if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
33744 /* The backer wishes to know when pages are first written to? */
33745 @@ -1101,14 +1202,24 @@ unsigned long mmap_region(struct file *f
33746 unsigned long charged = 0;
33747 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
33749 +#ifdef CONFIG_PAX_SEGMEXEC
33750 + struct vm_area_struct *vma_m = NULL;
33754 + * mm->mmap_sem is required to protect against another thread
33755 + * changing the mappings in case we sleep.
33757 + verify_mm_writelocked(mm);
33759 /* Clear old maps */
33762 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33763 if (vma && vma->vm_start < addr + len) {
33764 if (do_munmap(mm, addr, len))
33766 - goto munmap_back;
33767 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33768 + BUG_ON(vma && vma->vm_start < addr + len);
33771 /* Check against address space limit. */
33772 @@ -1155,6 +1266,16 @@ munmap_back:
33776 +#ifdef CONFIG_PAX_SEGMEXEC
33777 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
33778 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
33787 vma->vm_start = addr;
33788 vma->vm_end = addr + len;
33789 @@ -1177,6 +1298,19 @@ munmap_back:
33790 error = file->f_op->mmap(file, vma);
33792 goto unmap_and_free_vma;
33794 +#ifdef CONFIG_PAX_SEGMEXEC
33795 + if (vma_m && (vm_flags & VM_EXECUTABLE))
33796 + added_exe_file_vma(mm);
33799 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
33800 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
33801 + vma->vm_flags |= VM_PAGEEXEC;
33802 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
33806 if (vm_flags & VM_EXECUTABLE)
33807 added_exe_file_vma(mm);
33808 } else if (vm_flags & VM_SHARED) {
33809 @@ -1209,12 +1343,29 @@ munmap_back:
33810 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
33811 mpol_put(vma_policy(vma));
33812 kmem_cache_free(vm_area_cachep, vma);
33816 +#ifdef CONFIG_PAX_SEGMEXEC
33818 + kmem_cache_free(vm_area_cachep, vma_m);
33820 + if (vm_flags & VM_EXECUTABLE)
33821 + removed_exe_file_vma(mm);
33825 if (vm_flags & VM_EXECUTABLE)
33826 removed_exe_file_vma(mm);
33828 vma_link(mm, vma, prev, rb_link, rb_parent);
33829 file = vma->vm_file;
33831 +#ifdef CONFIG_PAX_SEGMEXEC
33833 + pax_mirror_vma(vma_m, vma);
33838 /* Once vma denies write, undo our temporary denial count */
33839 @@ -1223,6 +1374,7 @@ munmap_back:
33841 mm->total_vm += len >> PAGE_SHIFT;
33842 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
33843 + track_exec_limit(mm, addr, addr + len, vm_flags);
33844 if (vm_flags & VM_LOCKED) {
33845 mm->locked_vm += len >> PAGE_SHIFT;
33846 make_pages_present(addr, addr + len);
33847 @@ -1241,6 +1393,12 @@ unmap_and_free_vma:
33848 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
33852 +#ifdef CONFIG_PAX_SEGMEXEC
33854 + kmem_cache_free(vm_area_cachep, vma_m);
33857 kmem_cache_free(vm_area_cachep, vma);
33860 @@ -1274,6 +1432,10 @@ arch_get_unmapped_area(struct file *filp
33861 if (flags & MAP_FIXED)
33864 +#ifdef CONFIG_PAX_RANDMMAP
33865 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
33869 addr = PAGE_ALIGN(addr);
33870 vma = find_vma(mm, addr);
33871 @@ -1282,10 +1444,10 @@ arch_get_unmapped_area(struct file *filp
33874 if (len > mm->cached_hole_size) {
33875 - start_addr = addr = mm->free_area_cache;
33876 + start_addr = addr = mm->free_area_cache;
33878 - start_addr = addr = TASK_UNMAPPED_BASE;
33879 - mm->cached_hole_size = 0;
33880 + start_addr = addr = mm->mmap_base;
33881 + mm->cached_hole_size = 0;
33885 @@ -1296,9 +1458,8 @@ full_search:
33886 * Start a new search - just in case we missed
33889 - if (start_addr != TASK_UNMAPPED_BASE) {
33890 - addr = TASK_UNMAPPED_BASE;
33891 - start_addr = addr;
33892 + if (start_addr != mm->mmap_base) {
33893 + start_addr = addr = mm->mmap_base;
33894 mm->cached_hole_size = 0;
33897 @@ -1320,10 +1481,16 @@ full_search:
33899 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
33902 +#ifdef CONFIG_PAX_SEGMEXEC
33903 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
33908 * Is this a new hole at the lowest possible address?
33910 - if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
33911 + if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
33912 mm->free_area_cache = addr;
33913 mm->cached_hole_size = ~0UL;
33915 @@ -1341,7 +1508,7 @@ arch_get_unmapped_area_topdown(struct fi
33917 struct vm_area_struct *vma;
33918 struct mm_struct *mm = current->mm;
33919 - unsigned long addr = addr0;
33920 + unsigned long base = mm->mmap_base, addr = addr0;
33922 /* requested length too big for entire address space */
33923 if (len > TASK_SIZE)
33924 @@ -1350,6 +1517,10 @@ arch_get_unmapped_area_topdown(struct fi
33925 if (flags & MAP_FIXED)
33928 +#ifdef CONFIG_PAX_RANDMMAP
33929 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
33932 /* requesting a specific address */
33934 addr = PAGE_ALIGN(addr);
33935 @@ -1407,13 +1578,21 @@ bottomup:
33936 * can happen with large stack limits and large mmap()
33939 + mm->mmap_base = TASK_UNMAPPED_BASE;
33941 +#ifdef CONFIG_PAX_RANDMMAP
33942 + if (mm->pax_flags & MF_PAX_RANDMMAP)
33943 + mm->mmap_base += mm->delta_mmap;
33946 + mm->free_area_cache = mm->mmap_base;
33947 mm->cached_hole_size = ~0UL;
33948 - mm->free_area_cache = TASK_UNMAPPED_BASE;
33949 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
33951 * Restore the topdown base:
33953 - mm->free_area_cache = mm->mmap_base;
33954 + mm->mmap_base = base;
33955 + mm->free_area_cache = base;
33956 mm->cached_hole_size = ~0UL;
33959 @@ -1422,6 +1601,12 @@ bottomup:
33961 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
33964 +#ifdef CONFIG_PAX_SEGMEXEC
33965 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
33970 * Is this a new hole at the highest possible address?
33972 @@ -1429,8 +1614,10 @@ void arch_unmap_area_topdown(struct mm_s
33973 mm->free_area_cache = addr;
33975 /* dont allow allocations above current base */
33976 - if (mm->free_area_cache > mm->mmap_base)
33977 + if (mm->free_area_cache > mm->mmap_base) {
33978 mm->free_area_cache = mm->mmap_base;
33979 + mm->cached_hole_size = ~0UL;
33984 @@ -1530,6 +1717,33 @@ out:
33985 return prev ? prev->vm_next : vma;
33988 +#ifdef CONFIG_PAX_SEGMEXEC
33989 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
33991 + struct vm_area_struct *vma_m;
33993 + BUG_ON(!vma || vma->vm_start >= vma->vm_end);
33994 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
33995 + BUG_ON(vma->vm_mirror);
33998 + BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
33999 + vma_m = vma->vm_mirror;
34000 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
34001 + BUG_ON(vma->vm_file != vma_m->vm_file);
34002 + BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
34003 + BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
34005 +#ifdef CONFIG_PAX_MPROTECT
34006 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
34008 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
34016 * Verify that the stack growth is acceptable and
34017 * update accounting. This is shared with both the
34018 @@ -1546,6 +1760,7 @@ static int acct_stack_growth(struct vm_a
34021 /* Stack limit test */
34022 + gr_learn_resource(current, RLIMIT_STACK, size, 1);
34023 if (size > rlim[RLIMIT_STACK].rlim_cur)
34026 @@ -1555,6 +1770,7 @@ static int acct_stack_growth(struct vm_a
34027 unsigned long limit;
34028 locked = mm->locked_vm + grow;
34029 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
34030 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34031 if (locked > limit && !capable(CAP_IPC_LOCK))
34034 @@ -1569,7 +1785,7 @@ static int acct_stack_growth(struct vm_a
34035 * Overcommit.. This must be the final test, as it will
34036 * update security statistics.
34038 - if (security_vm_enough_memory(grow))
34039 + if (security_vm_enough_memory_mm(mm, grow))
34042 /* Ok, everything looks good - let it rip */
34043 @@ -1590,35 +1806,40 @@ static inline
34045 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
34048 + int error, locknext;
34050 if (!(vma->vm_flags & VM_GROWSUP))
34053 + /* Also guard against wrapping around to address 0. */
34054 + if (address < PAGE_ALIGN(address+1))
34055 + address = PAGE_ALIGN(address+1);
34060 * We must make sure the anon_vma is allocated
34061 * so that the anon_vma locking is not a noop.
34063 if (unlikely(anon_vma_prepare(vma)))
34065 + locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
34066 + if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
34068 anon_vma_lock(vma);
34070 + anon_vma_lock(vma->vm_next);
34073 * vma->vm_start/vm_end cannot change under us because the caller
34074 * is required to hold the mmap_sem in read mode. We need the
34075 - * anon_vma lock to serialize against concurrent expand_stacks.
34076 - * Also guard against wrapping around to address 0.
34077 + * anon_vma locks to serialize against concurrent expand_stacks
34078 + * and expand_upwards.
34080 - if (address < PAGE_ALIGN(address+4))
34081 - address = PAGE_ALIGN(address+4);
34083 - anon_vma_unlock(vma);
34088 /* Somebody else might have raced and expanded it already */
34089 - if (address > vma->vm_end) {
34090 + if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
34091 unsigned long size, grow;
34093 size = address - vma->vm_start;
34094 @@ -1628,6 +1849,8 @@ int expand_upwards(struct vm_area_struct
34096 vma->vm_end = address;
34099 + anon_vma_unlock(vma->vm_next);
34100 anon_vma_unlock(vma);
34103 @@ -1639,7 +1862,8 @@ int expand_upwards(struct vm_area_struct
34104 static inline int expand_downwards(struct vm_area_struct *vma,
34105 unsigned long address)
34108 + int error, lockprev = 0;
34109 + struct vm_area_struct *prev = NULL;
34112 * We must make sure the anon_vma is allocated
34113 @@ -1653,6 +1877,15 @@ static inline int expand_downwards(struc
34117 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
34118 + find_vma_prev(vma->vm_mm, address, &prev);
34119 + lockprev = prev && (prev->vm_flags & VM_GROWSUP);
34121 + if (lockprev && unlikely(anon_vma_prepare(prev)))
34124 + anon_vma_lock(prev);
34126 anon_vma_lock(vma);
34129 @@ -1662,9 +1895,15 @@ static inline int expand_downwards(struc
34132 /* Somebody else might have raced and expanded it already */
34133 - if (address < vma->vm_start) {
34134 + if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
34135 unsigned long size, grow;
34137 +#ifdef CONFIG_PAX_SEGMEXEC
34138 + struct vm_area_struct *vma_m;
34140 + vma_m = pax_find_mirror_vma(vma);
34143 size = vma->vm_end - address;
34144 grow = (vma->vm_start - address) >> PAGE_SHIFT;
34146 @@ -1672,9 +1911,20 @@ static inline int expand_downwards(struc
34148 vma->vm_start = address;
34149 vma->vm_pgoff -= grow;
34150 + track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
34152 +#ifdef CONFIG_PAX_SEGMEXEC
34154 + vma_m->vm_start -= grow << PAGE_SHIFT;
34155 + vma_m->vm_pgoff -= grow;
34161 anon_vma_unlock(vma);
34163 + anon_vma_unlock(prev);
34167 @@ -1746,6 +1996,13 @@ static void remove_vma_list(struct mm_st
34169 long nrpages = vma_pages(vma);
34171 +#ifdef CONFIG_PAX_SEGMEXEC
34172 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
34173 + vma = remove_vma(vma);
34178 vx_vmpages_sub(mm, nrpages);
34179 if (vma->vm_flags & VM_LOCKED)
34180 mm->locked_vm -= nrpages;
34181 @@ -1792,6 +2049,16 @@ detach_vmas_to_be_unmapped(struct mm_str
34183 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
34186 +#ifdef CONFIG_PAX_SEGMEXEC
34187 + if (vma->vm_mirror) {
34188 + BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
34189 + vma->vm_mirror->vm_mirror = NULL;
34190 + vma->vm_mirror->vm_flags &= ~VM_EXEC;
34191 + vma->vm_mirror = NULL;
34195 rb_erase(&vma->vm_rb, &mm->mm_rb);
34198 @@ -1811,6 +2078,108 @@ detach_vmas_to_be_unmapped(struct mm_str
34199 * Split a vma into two pieces at address 'addr', a new vma is allocated
34200 * either for the first part or the tail.
34203 +#ifdef CONFIG_PAX_SEGMEXEC
34204 +int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
34205 + unsigned long addr, int new_below)
34207 + struct mempolicy *pol;
34208 + struct vm_area_struct *new, *vma_m, *new_m = NULL;
34209 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
34211 + if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
34214 + vma_m = pax_find_mirror_vma(vma);
34216 + BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
34217 + if (mm->map_count >= sysctl_max_map_count-1)
34219 + } else if (mm->map_count >= sysctl_max_map_count)
34222 + new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34227 + new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34229 + kmem_cache_free(vm_area_cachep, new);
34234 + /* most fields are the same, copy all, and then fixup */
34238 + new->vm_end = addr;
34240 + new->vm_start = addr;
34241 + new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
34246 + new_m->vm_mirror = new;
34247 + new->vm_mirror = new_m;
34250 + new_m->vm_end = addr_m;
34252 + new_m->vm_start = addr_m;
34253 + new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
34257 + pol = mpol_dup(vma_policy(vma));
34258 + if (IS_ERR(pol)) {
34260 + kmem_cache_free(vm_area_cachep, new_m);
34261 + kmem_cache_free(vm_area_cachep, new);
34262 + return PTR_ERR(pol);
34264 + vma_set_policy(new, pol);
34266 + if (new->vm_file) {
34267 + get_file(new->vm_file);
34268 + if (vma->vm_flags & VM_EXECUTABLE)
34269 + added_exe_file_vma(mm);
34272 + if (new->vm_ops && new->vm_ops->open)
34273 + new->vm_ops->open(new);
34276 + vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
34277 + ((addr - new->vm_start) >> PAGE_SHIFT), new);
34279 + vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
34283 + vma_set_policy(new_m, pol);
34285 + if (new_m->vm_file) {
34286 + get_file(new_m->vm_file);
34287 + if (vma_m->vm_flags & VM_EXECUTABLE)
34288 + added_exe_file_vma(mm);
34291 + if (new_m->vm_ops && new_m->vm_ops->open)
34292 + new_m->vm_ops->open(new_m);
34295 + vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
34296 + ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
34298 + vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
34304 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
34305 unsigned long addr, int new_below)
34307 @@ -1862,17 +2231,37 @@ int split_vma(struct mm_struct * mm, str
34313 /* Munmap is split into 2 main parts -- this part which finds
34314 * what needs doing, and the areas themselves, which do the
34315 * work. This now handles partial unmappings.
34316 * Jeremy Fitzhardinge <jeremy@goop.org>
34318 +#ifdef CONFIG_PAX_SEGMEXEC
34319 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
34321 + int ret = __do_munmap(mm, start, len);
34322 + if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
34325 + return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
34328 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
34330 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
34334 struct vm_area_struct *vma, *prev, *last;
34337 + * mm->mmap_sem is required to protect against another thread
34338 + * changing the mappings in case we sleep.
34340 + verify_mm_writelocked(mm);
34342 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
34345 @@ -1922,6 +2311,8 @@ int do_munmap(struct mm_struct *mm, unsi
34346 /* Fix up all other VM information */
34347 remove_vma_list(mm, vma);
34349 + track_exec_limit(mm, start, end, 0UL);
34354 @@ -1934,22 +2325,18 @@ asmlinkage long sys_munmap(unsigned long
34356 profile_munmap(addr);
34358 +#ifdef CONFIG_PAX_SEGMEXEC
34359 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
34360 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
34364 down_write(&mm->mmap_sem);
34365 ret = do_munmap(mm, addr, len);
34366 up_write(&mm->mmap_sem);
34370 -static inline void verify_mm_writelocked(struct mm_struct *mm)
34372 -#ifdef CONFIG_DEBUG_VM
34373 - if (unlikely(down_read_trylock(&mm->mmap_sem))) {
34375 - up_read(&mm->mmap_sem);
34381 * this is really a simplified "do_mmap". it only handles
34382 * anonymous maps. eventually we may be able to do some
34383 @@ -1963,6 +2350,11 @@ unsigned long do_brk(unsigned long addr,
34384 struct rb_node ** rb_link, * rb_parent;
34385 pgoff_t pgoff = addr >> PAGE_SHIFT;
34387 + unsigned long charged;
34389 +#ifdef CONFIG_PAX_SEGMEXEC
34390 + struct vm_area_struct *vma_m = NULL;
34393 len = PAGE_ALIGN(len);
34395 @@ -1980,19 +2372,34 @@ unsigned long do_brk(unsigned long addr,
34397 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
34399 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
34400 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
34401 + flags &= ~VM_EXEC;
34403 +#ifdef CONFIG_PAX_MPROTECT
34404 + if (mm->pax_flags & MF_PAX_MPROTECT)
34405 + flags &= ~VM_MAYEXEC;
34411 error = arch_mmap_check(addr, len, flags);
34415 + charged = len >> PAGE_SHIFT;
34418 * mlock MCL_FUTURE?
34420 if (mm->def_flags & VM_LOCKED) {
34421 unsigned long locked, lock_limit;
34422 - locked = len >> PAGE_SHIFT;
34423 + locked = charged;
34424 locked += mm->locked_vm;
34425 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
34426 lock_limit >>= PAGE_SHIFT;
34427 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34428 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
34431 @@ -2006,23 +2413,23 @@ unsigned long do_brk(unsigned long addr,
34433 * Clear old maps. this also does some error checking for us
34436 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34437 if (vma && vma->vm_start < addr + len) {
34438 if (do_munmap(mm, addr, len))
34440 - goto munmap_back;
34441 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34442 + BUG_ON(vma && vma->vm_start < addr + len);
34445 /* Check against address space limits *after* clearing old maps... */
34446 - if (!may_expand_vm(mm, len >> PAGE_SHIFT))
34447 + if (!may_expand_vm(mm, charged))
34450 if (mm->map_count > sysctl_max_map_count)
34453 - if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
34454 - !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
34455 + if (security_vm_enough_memory(charged) ||
34456 + !vx_vmpages_avail(mm, charged))
34459 /* Can we just expand an old private anonymous mapping? */
34460 @@ -2034,10 +2441,21 @@ unsigned long do_brk(unsigned long addr,
34462 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34464 - vm_unacct_memory(len >> PAGE_SHIFT);
34465 + vm_unacct_memory(charged);
34469 +#ifdef CONFIG_PAX_SEGMEXEC
34470 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
34471 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34473 + kmem_cache_free(vm_area_cachep, vma);
34474 + vm_unacct_memory(charged);
34481 vma->vm_start = addr;
34482 vma->vm_end = addr + len;
34483 @@ -2045,12 +2463,19 @@ unsigned long do_brk(unsigned long addr,
34484 vma->vm_flags = flags;
34485 vma->vm_page_prot = vm_get_page_prot(flags);
34486 vma_link(mm, vma, prev, rb_link, rb_parent);
34488 +#ifdef CONFIG_PAX_SEGMEXEC
34490 + pax_mirror_vma(vma_m, vma);
34494 - vx_vmpages_add(mm, len >> PAGE_SHIFT);
34495 + vx_vmpages_add(mm, charged);
34496 if (flags & VM_LOCKED) {
34497 - vx_vmlocked_add(mm, len >> PAGE_SHIFT);
34498 + vx_vmlocked_add(mm, charged);
34499 make_pages_present(addr, addr + len);
34501 + track_exec_limit(mm, addr, addr + len, flags);
34505 @@ -2082,8 +2507,10 @@ void exit_mmap(struct mm_struct *mm)
34506 * Walk the list again, actually closing and freeing it,
34507 * with preemption enabled, without holding any MM locks.
34511 + vma->vm_mirror = NULL;
34512 vma = remove_vma(vma);
34515 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
34517 @@ -2097,6 +2524,10 @@ int insert_vm_struct(struct mm_struct *
34518 struct vm_area_struct * __vma, * prev;
34519 struct rb_node ** rb_link, * rb_parent;
34521 +#ifdef CONFIG_PAX_SEGMEXEC
34522 + struct vm_area_struct *vma_m = NULL;
34526 * The vm_pgoff of a purely anonymous vma should be irrelevant
34527 * until its first write fault, when page's anon_vma and index
34528 @@ -2119,7 +2550,22 @@ int insert_vm_struct(struct mm_struct *
34529 if ((vma->vm_flags & VM_ACCOUNT) &&
34530 security_vm_enough_memory_mm(mm, vma_pages(vma)))
34533 +#ifdef CONFIG_PAX_SEGMEXEC
34534 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
34535 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34541 vma_link(mm, vma, prev, rb_link, rb_parent);
34543 +#ifdef CONFIG_PAX_SEGMEXEC
34545 + pax_mirror_vma(vma_m, vma);
34551 @@ -2137,6 +2583,8 @@ struct vm_area_struct *copy_vma(struct v
34552 struct rb_node **rb_link, *rb_parent;
34553 struct mempolicy *pol;
34555 + BUG_ON(vma->vm_mirror);
34558 * If anonymous vma has not yet been faulted, update new pgoff
34559 * to match new location, to increase its chance of merging.
34560 @@ -2180,6 +2628,35 @@ struct vm_area_struct *copy_vma(struct v
34564 +#ifdef CONFIG_PAX_SEGMEXEC
34565 +void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
34567 + struct vm_area_struct *prev_m;
34568 + struct rb_node **rb_link_m, *rb_parent_m;
34569 + struct mempolicy *pol_m;
34571 + BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
34572 + BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
34573 + BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
34575 + pol_m = vma_policy(vma_m);
34577 + vma_set_policy(vma_m, pol_m);
34578 + vma_m->vm_start += SEGMEXEC_TASK_SIZE;
34579 + vma_m->vm_end += SEGMEXEC_TASK_SIZE;
34580 + vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
34581 + vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
34582 + if (vma_m->vm_file)
34583 + get_file(vma_m->vm_file);
34584 + if (vma_m->vm_ops && vma_m->vm_ops->open)
34585 + vma_m->vm_ops->open(vma_m);
34586 + find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
34587 + vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
34588 + vma_m->vm_mirror = vma;
34589 + vma->vm_mirror = vma_m;
34594 * Return true if the calling process may expand its vm space by the passed
34596 @@ -2190,7 +2667,7 @@ int may_expand_vm(struct mm_struct *mm,
34599 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
34601 + gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
34602 if (cur + npages > lim)
34605 @@ -2259,6 +2736,15 @@ int install_special_mapping(struct mm_st
34606 vma->vm_start = addr;
34607 vma->vm_end = addr + len;
34609 +#ifdef CONFIG_PAX_MPROTECT
34610 + if (mm->pax_flags & MF_PAX_MPROTECT) {
34611 + if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
34612 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
34614 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
34618 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
34619 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
34621 diff -urNp linux-2.6.27.4/mm/mprotect.c linux-2.6.27.4/mm/mprotect.c
34622 --- linux-2.6.27.4/mm/mprotect.c 2008-10-22 17:38:01.000000000 -0400
34623 +++ linux-2.6.27.4/mm/mprotect.c 2008-10-27 22:59:31.000000000 -0400
34624 @@ -22,10 +22,17 @@
34625 #include <linux/swap.h>
34626 #include <linux/swapops.h>
34627 #include <linux/mmu_notifier.h>
34628 +#include <linux/grsecurity.h>
34630 +#ifdef CONFIG_PAX_MPROTECT
34631 +#include <linux/elf.h>
34634 #include <asm/uaccess.h>
34635 #include <asm/pgtable.h>
34636 #include <asm/cacheflush.h>
34637 #include <asm/tlbflush.h>
34638 +#include <asm/mmu_context.h>
34640 #ifndef pgprot_modify
34641 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
34642 @@ -133,6 +140,48 @@ static void change_protection(struct vm_
34643 flush_tlb_range(vma, start, end);
34646 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
34647 +/* called while holding the mmap semaphor for writing except stack expansion */
34648 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
34650 + unsigned long oldlimit, newlimit = 0UL;
34652 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
34655 + spin_lock(&mm->page_table_lock);
34656 + oldlimit = mm->context.user_cs_limit;
34657 + if ((prot & VM_EXEC) && oldlimit < end)
34658 + /* USER_CS limit moved up */
34660 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
34661 + /* USER_CS limit moved down */
34662 + newlimit = start;
34665 + mm->context.user_cs_limit = newlimit;
34669 + cpus_clear(mm->context.cpu_user_cs_mask);
34670 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
34673 + set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
34675 + spin_unlock(&mm->page_table_lock);
34676 + if (newlimit == end) {
34677 + struct vm_area_struct *vma = find_vma(mm, oldlimit);
34679 + for (; vma && vma->vm_start < end; vma = vma->vm_next)
34680 + if (is_vm_hugetlb_page(vma))
34681 + hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
34683 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
34689 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
34690 unsigned long start, unsigned long end, unsigned long newflags)
34691 @@ -145,6 +194,14 @@ mprotect_fixup(struct vm_area_struct *vm
34693 int dirty_accountable = 0;
34695 +#ifdef CONFIG_PAX_SEGMEXEC
34696 + struct vm_area_struct *vma_m = NULL;
34697 + unsigned long start_m, end_m;
34699 + start_m = start + SEGMEXEC_TASK_SIZE;
34700 + end_m = end + SEGMEXEC_TASK_SIZE;
34703 if (newflags == oldflags) {
34706 @@ -165,6 +222,38 @@ mprotect_fixup(struct vm_area_struct *vm
34710 +#ifdef CONFIG_PAX_SEGMEXEC
34711 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
34712 + if (start != vma->vm_start) {
34713 + error = split_vma(mm, vma, start, 1);
34716 + BUG_ON(!*pprev || (*pprev)->vm_next == vma);
34717 + *pprev = (*pprev)->vm_next;
34720 + if (end != vma->vm_end) {
34721 + error = split_vma(mm, vma, end, 0);
34726 + if (pax_find_mirror_vma(vma)) {
34727 + error = __do_munmap(mm, start_m, end_m - start_m);
34731 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34736 + vma->vm_flags = newflags;
34737 + pax_mirror_vma(vma_m, vma);
34743 * First try to merge with previous and/or next vma.
34745 @@ -219,6 +308,70 @@ fail:
34749 +#ifdef CONFIG_PAX_MPROTECT
34750 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
34751 + * therefore we'll grant them VM_MAYWRITE once during their life.
34753 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
34754 + * basis because we want to allow the common case and not the special ones.
34756 +static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
34758 + struct elfhdr elf_h;
34759 + struct elf_phdr elf_p;
34760 + elf_addr_t dyn_offset = 0UL;
34762 + unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
34764 +#ifndef CONFIG_PAX_NOELFRELOCS
34765 + if ((vma->vm_start != start) ||
34767 + !(vma->vm_flags & VM_MAYEXEC) ||
34768 + (vma->vm_flags & VM_MAYNOTWRITE))
34773 + if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
34774 + memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
34776 +#ifdef CONFIG_PAX_ETEXECRELOCS
34777 + (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
34779 + elf_h.e_type != ET_DYN ||
34782 + !elf_check_arch(&elf_h) ||
34783 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
34784 + elf_h.e_phnum > j)
34787 + for (i = 0UL; i < elf_h.e_phnum; i++) {
34788 + if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
34790 + if (elf_p.p_type == PT_DYNAMIC) {
34791 + dyn_offset = elf_p.p_offset;
34795 + if (elf_h.e_phnum <= j)
34800 + if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
34802 + if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
34803 + vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
34804 + gr_log_textrel(vma);
34808 + } while (dyn.d_tag != DT_NULL);
34814 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
34816 @@ -238,6 +391,17 @@ sys_mprotect(unsigned long start, size_t
34821 +#ifdef CONFIG_PAX_SEGMEXEC
34822 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
34823 + if (end > SEGMEXEC_TASK_SIZE)
34828 + if (end > TASK_SIZE)
34831 if (!arch_validate_prot(prot))
34834 @@ -245,7 +409,7 @@ sys_mprotect(unsigned long start, size_t
34836 * Does the application expect PROT_READ to imply PROT_EXEC:
34838 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
34839 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
34842 vm_flags = calc_vm_prot_bits(prot);
34843 @@ -277,6 +441,16 @@ sys_mprotect(unsigned long start, size_t
34844 if (start > vma->vm_start)
34847 + if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
34852 +#ifdef CONFIG_PAX_MPROTECT
34853 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
34854 + pax_handle_maywrite(vma, start);
34857 for (nstart = start ; ; ) {
34858 unsigned long newflags;
34860 @@ -290,6 +464,12 @@ sys_mprotect(unsigned long start, size_t
34864 +#ifdef CONFIG_PAX_MPROTECT
34865 + /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
34866 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
34867 + newflags &= ~VM_MAYWRITE;
34870 error = security_file_mprotect(vma, reqprot, prot);
34873 @@ -300,6 +480,9 @@ sys_mprotect(unsigned long start, size_t
34874 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
34878 + track_exec_limit(current->mm, nstart, tmp, vm_flags);
34882 if (nstart < prev->vm_end)
34883 diff -urNp linux-2.6.27.4/mm/mremap.c linux-2.6.27.4/mm/mremap.c
34884 --- linux-2.6.27.4/mm/mremap.c 2008-10-22 17:38:01.000000000 -0400
34885 +++ linux-2.6.27.4/mm/mremap.c 2008-10-27 22:36:19.000000000 -0400
34886 @@ -111,6 +111,12 @@ static void move_ptes(struct vm_area_str
34888 pte = ptep_clear_flush(vma, old_addr, old_pte);
34889 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
34891 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
34892 + if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
34893 + pte = pte_exprotect(pte);
34896 set_pte_at(mm, new_addr, new_pte, pte);
34899 @@ -260,6 +266,7 @@ unsigned long do_mremap(unsigned long ad
34900 struct vm_area_struct *vma;
34901 unsigned long ret = -EINVAL;
34902 unsigned long charged = 0;
34903 + unsigned long pax_task_size = TASK_SIZE;
34905 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
34907 @@ -278,6 +285,15 @@ unsigned long do_mremap(unsigned long ad
34911 +#ifdef CONFIG_PAX_SEGMEXEC
34912 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
34913 + pax_task_size = SEGMEXEC_TASK_SIZE;
34916 + if (new_len > pax_task_size || addr > pax_task_size-new_len ||
34917 + old_len > pax_task_size || addr > pax_task_size-old_len)
34920 /* new_addr is only valid if MREMAP_FIXED is specified */
34921 if (flags & MREMAP_FIXED) {
34922 if (new_addr & ~PAGE_MASK)
34923 @@ -285,16 +301,13 @@ unsigned long do_mremap(unsigned long ad
34924 if (!(flags & MREMAP_MAYMOVE))
34927 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
34928 + if (new_addr > pax_task_size - new_len)
34931 /* Check if the location we're moving into overlaps the
34932 * old location at all, and fail if it does.
34934 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
34937 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
34938 + if (addr + old_len > new_addr && new_addr + new_len > addr)
34941 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
34942 @@ -332,6 +345,14 @@ unsigned long do_mremap(unsigned long ad
34947 +#ifdef CONFIG_PAX_SEGMEXEC
34948 + if (pax_find_mirror_vma(vma)) {
34954 /* We can't remap across vm area boundaries */
34955 if (old_len > vma->vm_end - addr)
34957 @@ -365,7 +386,7 @@ unsigned long do_mremap(unsigned long ad
34958 if (old_len == vma->vm_end - addr &&
34959 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
34960 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
34961 - unsigned long max_addr = TASK_SIZE;
34962 + unsigned long max_addr = pax_task_size;
34964 max_addr = vma->vm_next->vm_start;
34965 /* can we just expand the current mapping? */
34966 @@ -383,6 +404,7 @@ unsigned long do_mremap(unsigned long ad
34970 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
34974 @@ -393,8 +415,8 @@ unsigned long do_mremap(unsigned long ad
34977 if (flags & MREMAP_MAYMOVE) {
34978 + unsigned long map_flags = 0;
34979 if (!(flags & MREMAP_FIXED)) {
34980 - unsigned long map_flags = 0;
34981 if (vma->vm_flags & VM_MAYSHARE)
34982 map_flags |= MAP_SHARED;
34984 @@ -409,7 +431,12 @@ unsigned long do_mremap(unsigned long ad
34988 + map_flags = vma->vm_flags;
34989 ret = move_vma(vma, addr, old_len, new_len, new_addr);
34990 + if (!(ret & ~PAGE_MASK)) {
34991 + track_exec_limit(current->mm, addr, addr + old_len, 0UL);
34992 + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
34996 if (ret & ~PAGE_MASK)
34997 diff -urNp linux-2.6.27.4/mm/nommu.c linux-2.6.27.4/mm/nommu.c
34998 --- linux-2.6.27.4/mm/nommu.c 2008-10-22 17:38:01.000000000 -0400
34999 +++ linux-2.6.27.4/mm/nommu.c 2008-10-27 22:36:19.000000000 -0400
35000 @@ -437,15 +437,6 @@ struct vm_area_struct *find_vma(struct m
35002 EXPORT_SYMBOL(find_vma);
35006 - * - we don't extend stack VMAs under NOMMU conditions
35008 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
35010 - return find_vma(mm, addr);
35013 int expand_stack(struct vm_area_struct *vma, unsigned long address)
35016 diff -urNp linux-2.6.27.4/mm/page_alloc.c linux-2.6.27.4/mm/page_alloc.c
35017 --- linux-2.6.27.4/mm/page_alloc.c 2008-10-22 17:38:01.000000000 -0400
35018 +++ linux-2.6.27.4/mm/page_alloc.c 2008-10-27 22:36:19.000000000 -0400
35019 @@ -501,9 +501,20 @@ static void free_pages_bulk(struct zone
35021 static void free_one_page(struct zone *zone, struct page *page, int order)
35024 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35025 + unsigned long index = 1UL << order;
35028 spin_lock(&zone->lock);
35029 zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
35030 zone->pages_scanned = 0;
35032 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35033 + for (; index; --index)
35034 + sanitize_highpage(page + index - 1);
35037 __free_one_page(page, zone, order);
35038 spin_unlock(&zone->lock);
35040 @@ -621,8 +632,10 @@ static int prep_new_page(struct page *pa
35041 arch_alloc_page(page, order);
35042 kernel_map_pages(page, 1 << order, 1);
35044 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
35045 if (gfp_flags & __GFP_ZERO)
35046 prep_zero_page(page, order, gfp_flags);
35049 if (order && (gfp_flags & __GFP_COMP))
35050 prep_compound_page(page, order);
35051 @@ -995,6 +1008,11 @@ static void free_hot_cold_page(struct pa
35052 list_add(&page->lru, &pcp->list);
35053 set_page_private(page, get_pageblock_migratetype(page));
35056 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35057 + sanitize_highpage(page);
35060 if (pcp->count >= pcp->high) {
35061 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
35062 pcp->count -= pcp->batch;
35063 diff -urNp linux-2.6.27.4/mm/rmap.c linux-2.6.27.4/mm/rmap.c
35064 --- linux-2.6.27.4/mm/rmap.c 2008-10-27 22:25:01.000000000 -0400
35065 +++ linux-2.6.27.4/mm/rmap.c 2008-10-27 22:36:19.000000000 -0400
35066 @@ -91,6 +91,10 @@ int anon_vma_prepare(struct vm_area_stru
35067 struct mm_struct *mm = vma->vm_mm;
35068 struct anon_vma *allocated;
35070 +#ifdef CONFIG_PAX_SEGMEXEC
35071 + struct vm_area_struct *vma_m;
35074 anon_vma = find_mergeable_anon_vma(vma);
35077 @@ -104,6 +108,15 @@ int anon_vma_prepare(struct vm_area_stru
35078 /* page_table_lock to protect against threads */
35079 spin_lock(&mm->page_table_lock);
35080 if (likely(!vma->anon_vma)) {
35082 +#ifdef CONFIG_PAX_SEGMEXEC
35083 + vma_m = pax_find_mirror_vma(vma);
35085 + vma_m->anon_vma = anon_vma;
35086 + __anon_vma_link(vma_m);
35090 vma->anon_vma = anon_vma;
35091 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
35093 diff -urNp linux-2.6.27.4/mm/shmem.c linux-2.6.27.4/mm/shmem.c
35094 --- linux-2.6.27.4/mm/shmem.c 2008-10-22 17:38:01.000000000 -0400
35095 +++ linux-2.6.27.4/mm/shmem.c 2008-10-25 12:03:07.000000000 -0400
35096 @@ -2483,7 +2483,7 @@ static struct file_system_type tmpfs_fs_
35097 .get_sb = shmem_get_sb,
35098 .kill_sb = kill_litter_super,
35100 -static struct vfsmount *shm_mnt;
35101 +struct vfsmount *shm_mnt;
35103 static int __init init_tmpfs(void)
35105 diff -urNp linux-2.6.27.4/mm/slab.c linux-2.6.27.4/mm/slab.c
35106 --- linux-2.6.27.4/mm/slab.c 2008-10-22 17:38:01.000000000 -0400
35107 +++ linux-2.6.27.4/mm/slab.c 2008-10-27 22:36:19.000000000 -0400
35108 @@ -304,7 +304,7 @@ struct kmem_list3 {
35109 * Need this for bootstrapping a per node allocator.
35111 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
35112 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
35113 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
35114 #define CACHE_CACHE 0
35115 #define SIZE_AC MAX_NUMNODES
35116 #define SIZE_L3 (2 * MAX_NUMNODES)
35117 @@ -653,14 +653,14 @@ struct cache_names {
35118 static struct cache_names __initdata cache_names[] = {
35119 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
35120 #include <linux/kmalloc_sizes.h>
35126 static struct arraycache_init initarray_cache __initdata =
35127 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35128 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35129 static struct arraycache_init initarray_generic =
35130 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35131 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35133 /* internal cache of cache description objs */
35134 static struct kmem_cache cache_cache = {
35135 @@ -2996,7 +2996,7 @@ retry:
35136 * there must be at least one object available for
35139 - BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
35140 + BUG_ON(slabp->inuse >= cachep->num);
35142 while (slabp->inuse < cachep->num && batchcount--) {
35143 STATS_INC_ALLOCED(cachep);
35144 diff -urNp linux-2.6.27.4/mm/tiny-shmem.c linux-2.6.27.4/mm/tiny-shmem.c
35145 --- linux-2.6.27.4/mm/tiny-shmem.c 2008-10-22 17:38:01.000000000 -0400
35146 +++ linux-2.6.27.4/mm/tiny-shmem.c 2008-10-25 12:03:07.000000000 -0400
35147 @@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
35148 .kill_sb = kill_litter_super,
35151 -static struct vfsmount *shm_mnt;
35152 +struct vfsmount *shm_mnt;
35154 static int __init init_tmpfs(void)
35156 diff -urNp linux-2.6.27.4/mm/util.c linux-2.6.27.4/mm/util.c
35157 --- linux-2.6.27.4/mm/util.c 2008-10-22 17:38:01.000000000 -0400
35158 +++ linux-2.6.27.4/mm/util.c 2008-10-27 22:36:19.000000000 -0400
35159 @@ -167,6 +167,12 @@ EXPORT_SYMBOL(strndup_user);
35160 void arch_pick_mmap_layout(struct mm_struct *mm)
35162 mm->mmap_base = TASK_UNMAPPED_BASE;
35164 +#ifdef CONFIG_PAX_RANDMMAP
35165 + if (mm->pax_flags & MF_PAX_RANDMMAP)
35166 + mm->mmap_base += mm->delta_mmap;
35169 mm->get_unmapped_area = arch_get_unmapped_area;
35170 mm->unmap_area = arch_unmap_area;
35172 diff -urNp linux-2.6.27.4/mm/vmalloc.c linux-2.6.27.4/mm/vmalloc.c
35173 --- linux-2.6.27.4/mm/vmalloc.c 2008-10-22 17:38:01.000000000 -0400
35174 +++ linux-2.6.27.4/mm/vmalloc.c 2008-10-27 22:36:19.000000000 -0400
35175 @@ -98,19 +98,36 @@ static int vmap_pte_range(pmd_t *pmd, un
35176 unsigned long end, pgprot_t prot, struct page ***pages)
35179 + int ret = -ENOMEM;
35181 +#ifdef CONFIG_PAX_KERNEXEC
35182 + unsigned long cr0;
35185 pte = pte_alloc_kernel(pmd, addr);
35189 +#ifdef CONFIG_PAX_KERNEXEC
35190 + pax_open_kernel(cr0);
35194 struct page *page = **pages;
35195 WARN_ON(!pte_none(*pte));
35199 set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
35201 } while (pte++, addr += PAGE_SIZE, addr != end);
35206 +#ifdef CONFIG_PAX_KERNEXEC
35207 + pax_close_kernel(cr0);
35213 static inline int vmap_pmd_range(pud_t *pud, unsigned long addr,
35214 @@ -215,6 +232,16 @@ __get_vm_area_node(unsigned long size, u
35215 unsigned long addr;
35217 BUG_ON(in_interrupt());
35219 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35220 + if (flags & VM_KERNEXEC) {
35221 + if (start != VMALLOC_START || end != VMALLOC_END)
35223 + start = (unsigned long)MODULES_VADDR;
35224 + end = (unsigned long)MODULES_END;
35228 if (flags & VM_IOREMAP) {
35229 int bit = fls(size);
35231 @@ -248,20 +275,15 @@ __get_vm_area_node(unsigned long size, u
35232 (unsigned long)tmp->addr, align);
35235 - if ((size + addr) < addr)
35237 if (size + addr <= (unsigned long)tmp->addr)
35240 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
35241 - if (addr > end - size)
35244 if ((size + addr) < addr)
35246 if (addr > end - size)
35253 @@ -466,6 +488,11 @@ void *vmap(struct page **pages, unsigned
35254 if (count > num_physpages)
35257 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35258 + if (pgprot_val(prot) & _PAGE_NX)
35259 + flags |= VM_KERNEXEC;
35262 area = get_vm_area_caller((count << PAGE_SHIFT), flags,
35263 __builtin_return_address(0));
35265 @@ -560,6 +587,13 @@ static void *__vmalloc_node(unsigned lon
35266 if (!size || (size >> PAGE_SHIFT) > num_physpages)
35269 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35270 + if (pgprot_val(prot) & _PAGE_NX)
35271 + area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
35272 + node, gfp_mask, caller);
35276 area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
35277 node, gfp_mask, caller);
35279 @@ -651,7 +685,7 @@ EXPORT_SYMBOL(vmalloc_node);
35281 void *vmalloc_exec(unsigned long size)
35283 - return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
35284 + return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC);
35287 #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
35288 diff -urNp linux-2.6.27.4/net/bridge/br_stp_if.c linux-2.6.27.4/net/bridge/br_stp_if.c
35289 --- linux-2.6.27.4/net/bridge/br_stp_if.c 2008-10-22 17:38:01.000000000 -0400
35290 +++ linux-2.6.27.4/net/bridge/br_stp_if.c 2008-10-27 22:36:19.000000000 -0400
35291 @@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg
35292 char *envp[] = { NULL };
35294 if (br->stp_enabled == BR_USER_STP) {
35295 - r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
35296 + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
35297 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
35300 diff -urNp linux-2.6.27.4/net/core/flow.c linux-2.6.27.4/net/core/flow.c
35301 --- linux-2.6.27.4/net/core/flow.c 2008-10-22 17:38:01.000000000 -0400
35302 +++ linux-2.6.27.4/net/core/flow.c 2008-10-27 22:36:19.000000000 -0400
35303 @@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
35305 static u32 flow_hash_shift;
35306 #define flow_hash_size (1 << flow_hash_shift)
35307 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
35308 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
35310 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
35312 @@ -52,7 +52,7 @@ struct flow_percpu_info {
35316 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
35317 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
35319 #define flow_hash_rnd_recalc(cpu) \
35320 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
35321 @@ -69,7 +69,7 @@ struct flow_flush_info {
35323 struct completion completion;
35325 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
35326 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
35328 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
35330 diff -urNp linux-2.6.27.4/net/dccp/ccids/ccid3.c linux-2.6.27.4/net/dccp/ccids/ccid3.c
35331 --- linux-2.6.27.4/net/dccp/ccids/ccid3.c 2008-10-22 17:38:01.000000000 -0400
35332 +++ linux-2.6.27.4/net/dccp/ccids/ccid3.c 2008-10-27 22:36:19.000000000 -0400
35334 static int ccid3_debug;
35335 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
35337 -#define ccid3_pr_debug(format, a...)
35338 +#define ccid3_pr_debug(format, a...) do {} while (0)
35342 diff -urNp linux-2.6.27.4/net/dccp/dccp.h linux-2.6.27.4/net/dccp/dccp.h
35343 --- linux-2.6.27.4/net/dccp/dccp.h 2008-10-22 17:38:01.000000000 -0400
35344 +++ linux-2.6.27.4/net/dccp/dccp.h 2008-10-27 22:36:19.000000000 -0400
35345 @@ -43,8 +43,8 @@ extern int dccp_debug;
35346 #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
35347 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
35349 -#define dccp_pr_debug(format, a...)
35350 -#define dccp_pr_debug_cat(format, a...)
35351 +#define dccp_pr_debug(format, a...) do {} while (0)
35352 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
35355 extern struct inet_hashinfo dccp_hashinfo;
35356 diff -urNp linux-2.6.27.4/net/ipv4/inet_connection_sock.c linux-2.6.27.4/net/ipv4/inet_connection_sock.c
35357 --- linux-2.6.27.4/net/ipv4/inet_connection_sock.c 2008-10-22 17:38:01.000000000 -0400
35358 +++ linux-2.6.27.4/net/ipv4/inet_connection_sock.c 2008-10-25 12:03:07.000000000 -0400
35361 #include <linux/module.h>
35362 #include <linux/jhash.h>
35363 +#include <linux/grsecurity.h>
35365 #include <net/inet_connection_sock.h>
35366 #include <net/inet_hashtables.h>
35367 diff -urNp linux-2.6.27.4/net/ipv4/inet_hashtables.c linux-2.6.27.4/net/ipv4/inet_hashtables.c
35368 --- linux-2.6.27.4/net/ipv4/inet_hashtables.c 2008-10-22 17:38:01.000000000 -0400
35369 +++ linux-2.6.27.4/net/ipv4/inet_hashtables.c 2008-10-25 12:03:07.000000000 -0400
35370 @@ -18,12 +18,15 @@
35371 #include <linux/sched.h>
35372 #include <linux/slab.h>
35373 #include <linux/wait.h>
35374 +#include <linux/grsecurity.h>
35376 #include <net/inet_connection_sock.h>
35377 #include <net/inet_hashtables.h>
35378 #include <net/route.h>
35379 #include <net/ip.h>
35381 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
35384 * Allocate and initialize a new local port bind bucket.
35385 * The bindhash mutex for snum's hash chain must be held here.
35386 @@ -487,6 +490,8 @@ ok:
35388 spin_unlock(&head->lock);
35390 + gr_update_task_in_ip_table(current, inet_sk(sk));
35393 inet_twsk_deschedule(tw, death_row);
35395 diff -urNp linux-2.6.27.4/net/ipv4/netfilter/ipt_stealth.c linux-2.6.27.4/net/ipv4/netfilter/ipt_stealth.c
35396 --- linux-2.6.27.4/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
35397 +++ linux-2.6.27.4/net/ipv4/netfilter/ipt_stealth.c 2008-10-25 12:03:07.000000000 -0400
35399 +/* Kernel module to add stealth support.
35401 + * Copyright (C) 2002-2006 Brad Spengler <spender@grsecurity.net>
35405 +#include <linux/kernel.h>
35406 +#include <linux/module.h>
35407 +#include <linux/skbuff.h>
35408 +#include <linux/net.h>
35409 +#include <linux/sched.h>
35410 +#include <linux/inet.h>
35411 +#include <linux/stddef.h>
35413 +#include <net/ip.h>
35414 +#include <net/sock.h>
35415 +#include <net/tcp.h>
35416 +#include <net/udp.h>
35417 +#include <net/route.h>
35418 +#include <net/inet_common.h>
35420 +#include <linux/netfilter_ipv4/ip_tables.h>
35422 +MODULE_LICENSE("GPL");
35424 +extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
35427 +match(const struct sk_buff *skb,
35428 + const struct net_device *in,
35429 + const struct net_device *out,
35430 + const struct xt_match *match,
35431 + const void *matchinfo,
35433 + unsigned int protoff,
35436 + struct iphdr *ip = ip_hdr(skb);
35437 + struct tcphdr th;
35438 + struct udphdr uh;
35439 + struct sock *sk = NULL;
35441 + if (!ip || offset) return false;
35443 + switch(ip->protocol) {
35444 + case IPPROTO_TCP:
35445 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
35449 + if (!(th.syn && !th.ack)) return false;
35450 + sk = inet_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
35452 + case IPPROTO_UDP:
35453 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
35457 + sk = udp_v4_lookup(dev_net(skb->dev), ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
35463 + if(!sk) // port is being listened on, match this
35471 +/* Called when user tries to insert an entry of this type. */
35473 +checkentry(const char *tablename,
35475 + const struct xt_match *match,
35477 + unsigned int hook_mask)
35479 + const struct ipt_ip *ip = (const struct ipt_ip *)nip;
35481 + if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
35482 + ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
35483 + && (hook_mask & (1 << NF_INET_LOCAL_IN)))
35486 + printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
35492 +static struct xt_match stealth_match __read_mostly = {
35493 + .name = "stealth",
35494 + .family = AF_INET,
35496 + .checkentry = checkentry,
35498 + .me = THIS_MODULE
35501 +static int __init init(void)
35503 + return xt_register_match(&stealth_match);
35506 +static void __exit fini(void)
35508 + xt_unregister_match(&stealth_match);
35511 +module_init(init);
35512 +module_exit(fini);
35513 diff -urNp linux-2.6.27.4/net/ipv4/netfilter/Kconfig linux-2.6.27.4/net/ipv4/netfilter/Kconfig
35514 --- linux-2.6.27.4/net/ipv4/netfilter/Kconfig 2008-10-22 17:38:01.000000000 -0400
35515 +++ linux-2.6.27.4/net/ipv4/netfilter/Kconfig 2008-10-25 12:03:07.000000000 -0400
35516 @@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
35517 If you want to compile it as a module, say M here and read
35518 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
35520 +config IP_NF_MATCH_STEALTH
35521 + tristate "stealth match support"
35522 + depends on IP_NF_IPTABLES
35524 + Enabling this option will drop all syn packets coming to unserved tcp
35525 + ports as well as all packets coming to unserved udp ports. If you
35526 + are using your system to route any type of packets (ie. via NAT)
35527 + you should put this module at the end of your ruleset, since it will
35528 + drop packets that aren't going to ports that are listening on your
35529 + machine itself, it doesn't take into account that the packet might be
35530 + destined for someone on your internal network if you're using NAT for
35533 + To compile it as a module, choose M here. If unsure, say N.
35535 # `filter', generic and specific targets
35536 config IP_NF_FILTER
35537 tristate "Packet filtering"
35538 @@ -407,4 +422,3 @@ config IP_NF_ARP_MANGLE
35539 hardware and network addresses.
35543 diff -urNp linux-2.6.27.4/net/ipv4/netfilter/Makefile linux-2.6.27.4/net/ipv4/netfilter/Makefile
35544 --- linux-2.6.27.4/net/ipv4/netfilter/Makefile 2008-10-22 17:38:01.000000000 -0400
35545 +++ linux-2.6.27.4/net/ipv4/netfilter/Makefile 2008-10-25 12:03:07.000000000 -0400
35546 @@ -59,6 +59,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
35547 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
35548 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
35549 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
35550 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
35551 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
35552 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
35554 diff -urNp linux-2.6.27.4/net/ipv4/tcp_ipv4.c linux-2.6.27.4/net/ipv4/tcp_ipv4.c
35555 --- linux-2.6.27.4/net/ipv4/tcp_ipv4.c 2008-10-22 17:38:01.000000000 -0400
35556 +++ linux-2.6.27.4/net/ipv4/tcp_ipv4.c 2008-10-25 12:03:07.000000000 -0400
35558 #include <linux/jhash.h>
35559 #include <linux/init.h>
35560 #include <linux/times.h>
35561 +#include <linux/grsecurity.h>
35563 #include <net/net_namespace.h>
35564 #include <net/icmp.h>
35565 diff -urNp linux-2.6.27.4/net/ipv4/udp.c linux-2.6.27.4/net/ipv4/udp.c
35566 --- linux-2.6.27.4/net/ipv4/udp.c 2008-10-22 17:38:01.000000000 -0400
35567 +++ linux-2.6.27.4/net/ipv4/udp.c 2008-10-25 12:03:07.000000000 -0400
35569 #include <linux/skbuff.h>
35570 #include <linux/proc_fs.h>
35571 #include <linux/seq_file.h>
35572 +#include <linux/grsecurity.h>
35573 #include <net/net_namespace.h>
35574 #include <net/icmp.h>
35575 #include <net/route.h>
35576 @@ -104,6 +105,11 @@
35577 #include <net/xfrm.h>
35578 #include "udp_impl.h"
35580 +extern int gr_search_udp_recvmsg(const struct sock *sk,
35581 + const struct sk_buff *skb);
35582 +extern int gr_search_udp_sendmsg(const struct sock *sk,
35583 + const struct sockaddr_in *addr);
35586 * Snmp MIB for the UDP layer
35588 @@ -302,6 +308,13 @@ static struct sock *__udp4_lib_lookup(st
35592 +struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
35593 + __be32 daddr, __be16 dport, int dif)
35595 + return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
35599 static inline struct sock *udp_v4_mcast_next(struct sock *sk,
35600 __be16 loc_port, __be32 loc_addr,
35601 __be16 rmt_port, __be32 rmt_addr,
35602 @@ -591,9 +604,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
35603 dport = usin->sin_port;
35607 + if (!gr_search_udp_sendmsg(sk, usin))
35610 if (sk->sk_state != TCP_ESTABLISHED)
35611 return -EDESTADDRREQ;
35613 + if (!gr_search_udp_sendmsg(sk, NULL))
35616 daddr = inet->daddr;
35617 dport = inet->dport;
35618 /* Open fast path for connected socket.
35619 @@ -858,6 +878,11 @@ try_again:
35623 + if (!gr_search_udp_recvmsg(sk, skb)) {
35628 ulen = skb->len - sizeof(struct udphdr);
35631 diff -urNp linux-2.6.27.4/net/ipv6/exthdrs.c linux-2.6.27.4/net/ipv6/exthdrs.c
35632 --- linux-2.6.27.4/net/ipv6/exthdrs.c 2008-10-22 17:38:01.000000000 -0400
35633 +++ linux-2.6.27.4/net/ipv6/exthdrs.c 2008-10-27 22:36:19.000000000 -0400
35634 @@ -624,7 +624,7 @@ static struct tlvtype_proc tlvprochopopt
35635 .type = IPV6_TLV_JUMBO,
35636 .func = ipv6_hop_jumbo,
35642 int ipv6_parse_hopopts(struct sk_buff *skb)
35643 diff -urNp linux-2.6.27.4/net/ipv6/raw.c linux-2.6.27.4/net/ipv6/raw.c
35644 --- linux-2.6.27.4/net/ipv6/raw.c 2008-10-22 17:38:01.000000000 -0400
35645 +++ linux-2.6.27.4/net/ipv6/raw.c 2008-10-27 22:36:19.000000000 -0400
35646 @@ -600,7 +600,7 @@ out:
35650 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
35651 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
35652 struct flowi *fl, struct rt6_info *rt,
35653 unsigned int flags)
35655 diff -urNp linux-2.6.27.4/net/irda/ircomm/ircomm_tty.c linux-2.6.27.4/net/irda/ircomm/ircomm_tty.c
35656 --- linux-2.6.27.4/net/irda/ircomm/ircomm_tty.c 2008-10-22 17:38:01.000000000 -0400
35657 +++ linux-2.6.27.4/net/irda/ircomm/ircomm_tty.c 2008-10-27 22:36:19.000000000 -0400
35658 @@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
35659 IRDA_DEBUG(2, "%s()\n", __func__ );
35662 - if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
35663 + if (line >= IRCOMM_TTY_PORTS) {
35667 diff -urNp linux-2.6.27.4/net/sctp/socket.c linux-2.6.27.4/net/sctp/socket.c
35668 --- linux-2.6.27.4/net/sctp/socket.c 2008-10-22 17:38:01.000000000 -0400
35669 +++ linux-2.6.27.4/net/sctp/socket.c 2008-10-27 22:36:19.000000000 -0400
35670 @@ -1434,7 +1434,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
35671 struct sctp_sndrcvinfo *sinfo;
35672 struct sctp_initmsg *sinit;
35673 sctp_assoc_t associd = 0;
35674 - sctp_cmsgs_t cmsgs = { NULL };
35675 + sctp_cmsgs_t cmsgs = { NULL, NULL };
35677 sctp_scope_t scope;
35679 @@ -5616,7 +5616,6 @@ pp_found:
35681 int reuse = sk->sk_reuse;
35683 - struct hlist_node *node;
35685 SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
35686 if (pp->fastreuse && sk->sk_reuse &&
35687 diff -urNp linux-2.6.27.4/net/socket.c linux-2.6.27.4/net/socket.c
35688 --- linux-2.6.27.4/net/socket.c 2008-10-22 17:38:01.000000000 -0400
35689 +++ linux-2.6.27.4/net/socket.c 2008-10-26 04:06:08.000000000 -0400
35691 #include <linux/audit.h>
35692 #include <linux/wireless.h>
35693 #include <linux/nsproxy.h>
35694 +#include <linux/in.h>
35696 #include <asm/uaccess.h>
35697 #include <asm/unistd.h>
35699 #include <net/sock.h>
35700 #include <linux/netfilter.h>
35702 +extern void gr_attach_curr_ip(const struct sock *sk);
35703 +extern int gr_handle_sock_all(const int family, const int type,
35704 + const int protocol);
35705 +extern int gr_handle_sock_server(const struct sockaddr *sck);
35706 +extern int gr_handle_sock_server_other(const struct socket *sck);
35707 +extern int gr_handle_sock_client(const struct sockaddr *sck);
35708 +extern int gr_search_connect(const struct socket * sock,
35709 + const struct sockaddr_in * addr);
35710 +extern int gr_search_bind(const struct socket * sock,
35711 + const struct sockaddr_in * addr);
35712 +extern int gr_search_listen(const struct socket * sock);
35713 +extern int gr_search_accept(const struct socket * sock);
35714 +extern int gr_search_socket(const int domain, const int type,
35715 + const int protocol);
35717 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
35718 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
35719 unsigned long nr_segs, loff_t pos);
35720 @@ -300,7 +316,7 @@ static int sockfs_get_sb(struct file_sys
35724 -static struct vfsmount *sock_mnt __read_mostly;
35725 +struct vfsmount *sock_mnt __read_mostly;
35727 static struct file_system_type sock_fs_type = {
35729 @@ -1236,6 +1252,16 @@ asmlinkage long sys_socket(int family, i
35730 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
35731 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
35733 + if(!gr_search_socket(family, type, protocol)) {
35734 + retval = -EACCES;
35738 + if (gr_handle_sock_all(family, type, protocol)) {
35739 + retval = -EACCES;
35743 retval = sock_create(family, type, protocol, &sock);
35746 @@ -1375,6 +1401,12 @@ asmlinkage long sys_bind(int fd, struct
35748 err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
35750 + if (!gr_search_bind(sock, (struct sockaddr_in *)&address) ||
35751 + gr_handle_sock_server((struct sockaddr *)&address)) {
35756 err = security_socket_bind(sock,
35757 (struct sockaddr *)&address,
35759 @@ -1383,6 +1415,7 @@ asmlinkage long sys_bind(int fd, struct
35760 (struct sockaddr *)
35761 &address, addrlen);
35764 fput_light(sock->file, fput_needed);
35767 @@ -1406,10 +1439,17 @@ asmlinkage long sys_listen(int fd, int b
35768 if ((unsigned)backlog > somaxconn)
35769 backlog = somaxconn;
35771 + if (gr_handle_sock_server_other(sock) ||
35772 + !gr_search_listen(sock)) {
35777 err = security_socket_listen(sock, backlog);
35779 err = sock->ops->listen(sock, backlog);
35782 fput_light(sock->file, fput_needed);
35785 @@ -1452,6 +1492,13 @@ long do_accept(int fd, struct sockaddr _
35786 newsock->type = sock->type;
35787 newsock->ops = sock->ops;
35789 + if (gr_handle_sock_server_other(sock) ||
35790 + !gr_search_accept(sock)) {
35792 + sock_release(newsock);
35797 * We don't need try_module_get here, as the listening socket (sock)
35798 * has the protocol module (sock->ops->owner) held.
35799 @@ -1495,6 +1542,7 @@ long do_accept(int fd, struct sockaddr _
35802 security_socket_post_accept(sock, newsock);
35803 + gr_attach_curr_ip(newsock->sk);
35806 fput_light(sock->file, fput_needed);
35807 @@ -1589,6 +1637,7 @@ asmlinkage long sys_connect(int fd, stru
35810 struct socket *sock;
35811 + struct sockaddr *sck;
35812 struct sockaddr_storage address;
35813 int err, fput_needed;
35815 @@ -1599,6 +1648,13 @@ asmlinkage long sys_connect(int fd, stru
35819 + sck = (struct sockaddr *)&address;
35820 + if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
35821 + gr_handle_sock_client(sck)) {
35827 security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
35829 @@ -1866,6 +1922,7 @@ asmlinkage long sys_shutdown(int fd, int
35830 err = sock->ops->shutdown(sock, how);
35831 fput_light(sock->file, fput_needed);
35837 diff -urNp linux-2.6.27.4/net/unix/af_unix.c linux-2.6.27.4/net/unix/af_unix.c
35838 --- linux-2.6.27.4/net/unix/af_unix.c 2008-10-22 17:38:01.000000000 -0400
35839 +++ linux-2.6.27.4/net/unix/af_unix.c 2008-10-25 12:03:07.000000000 -0400
35840 @@ -114,6 +114,7 @@
35841 #include <linux/security.h>
35842 #include <linux/vs_context.h>
35843 #include <linux/vs_limit.h>
35844 +#include <linux/grsecurity.h>
35846 static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
35847 static DEFINE_SPINLOCK(unix_table_lock);
35848 @@ -725,6 +726,12 @@ static struct sock *unix_find_other(stru
35849 err = -ECONNREFUSED;
35850 if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
35853 + if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
35858 u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
35861 @@ -745,6 +752,13 @@ static struct sock *unix_find_other(stru
35863 struct dentry *dentry;
35864 dentry = unix_sk(u)->dentry;
35866 + if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
35873 touch_atime(unix_sk(u)->mnt, dentry);
35875 @@ -827,10 +841,20 @@ static int unix_bind(struct socket *sock
35876 err = mnt_want_write(nd.path.mnt);
35878 goto out_mknod_dput;
35880 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
35882 + mnt_drop_write(nd.path.mnt);
35883 + goto out_mknod_dput;
35886 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
35887 mnt_drop_write(nd.path.mnt);
35889 goto out_mknod_dput;
35891 + gr_handle_create(dentry, nd.path.mnt);
35893 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
35894 dput(nd.path.dentry);
35895 nd.path.dentry = dentry;
35896 @@ -848,6 +872,10 @@ static int unix_bind(struct socket *sock
35900 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
35901 + sk->sk_peercred.pid = current->pid;
35904 list = &unix_socket_table[addr->hash];
35906 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
35907 diff -urNp linux-2.6.27.4/scripts/pnmtologo.c linux-2.6.27.4/scripts/pnmtologo.c
35908 --- linux-2.6.27.4/scripts/pnmtologo.c 2008-10-22 17:38:01.000000000 -0400
35909 +++ linux-2.6.27.4/scripts/pnmtologo.c 2008-10-27 22:36:19.000000000 -0400
35910 @@ -237,14 +237,14 @@ static void write_header(void)
35911 fprintf(out, " * Linux logo %s\n", logoname);
35912 fputs(" */\n\n", out);
35913 fputs("#include <linux/linux_logo.h>\n\n", out);
35914 - fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
35915 + fprintf(out, "static unsigned char %s_data[] = {\n",
35919 static void write_footer(void)
35921 fputs("\n};\n\n", out);
35922 - fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
35923 + fprintf(out, "struct linux_logo %s = {\n", logoname);
35924 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
35925 fprintf(out, " .width\t= %d,\n", logo_width);
35926 fprintf(out, " .height\t= %d,\n", logo_height);
35927 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
35928 fputs("\n};\n\n", out);
35930 /* write logo clut */
35931 - fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
35932 + fprintf(out, "static unsigned char %s_clut[] = {\n",
35935 for (i = 0; i < logo_clutsize; i++) {
35936 diff -urNp linux-2.6.27.4/security/commoncap.c linux-2.6.27.4/security/commoncap.c
35937 --- linux-2.6.27.4/security/commoncap.c 2008-10-22 17:38:01.000000000 -0400
35938 +++ linux-2.6.27.4/security/commoncap.c 2008-10-25 12:03:07.000000000 -0400
35939 @@ -26,10 +26,13 @@
35940 #include <linux/prctl.h>
35941 #include <linux/securebits.h>
35942 #include <linux/vs_context.h>
35943 +#include <linux/grsecurity.h>
35945 +extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
35947 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
35949 - NETLINK_CB(skb).eff_cap = vx_mbcaps(current->cap_effective);
35950 + NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
35954 @@ -51,7 +54,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
35955 int cap_capable (struct task_struct *tsk, int cap)
35957 /* Derived from include/linux/sched.h:capable. */
35958 - if (vx_cap_raised(vxi, tsk->cap_effective, cap))
35959 + if (vx_cap_raised(vxi, tsk->cap_effective, cap))
35964 +int cap_capable_nolog (struct task_struct *tsk, int cap)
35966 + /* tsk = current for all callers */
35967 + if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
35971 @@ -379,8 +390,11 @@ void cap_bprm_apply_creds (struct linux_
35975 - current->suid = current->euid = current->fsuid = bprm->e_uid;
35976 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
35977 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
35978 + current->suid = current->euid = current->fsuid = bprm->e_uid;
35980 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
35981 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
35983 /* For init, we want to retain the capabilities set
35984 * in the init_task struct. Thus we skip the usual
35985 @@ -393,6 +407,8 @@ void cap_bprm_apply_creds (struct linux_
35986 cap_clear(current->cap_effective);
35989 + gr_handle_chroot_caps(current);
35991 /* AUD: Audit candidate if current->cap_effective is set */
35993 current->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
35994 @@ -705,7 +721,7 @@ int cap_vm_enough_memory(struct mm_struc
35996 int cap_sys_admin = 0;
35998 - if (cap_capable(current, CAP_SYS_ADMIN) == 0)
35999 + if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
36001 return __vm_enough_memory(mm, pages, cap_sys_admin);
36003 diff -urNp linux-2.6.27.4/security/Kconfig linux-2.6.27.4/security/Kconfig
36004 --- linux-2.6.27.4/security/Kconfig 2008-10-22 17:38:01.000000000 -0400
36005 +++ linux-2.6.27.4/security/Kconfig 2008-10-27 22:57:19.000000000 -0400
36008 menu "Security options"
36010 +source grsecurity/Kconfig
36015 + bool "Enable various PaX features"
36016 + depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
36018 + This allows you to enable various PaX features. PaX adds
36019 + intrusion prevention mechanisms to the kernel that reduce
36020 + the risks posed by exploitable memory corruption bugs.
36022 +menu "PaX Control"
36025 +config PAX_SOFTMODE
36026 + bool 'Support soft mode'
36028 + Enabling this option will allow you to run PaX in soft mode, that
36029 + is, PaX features will not be enforced by default, only on executables
36030 + marked explicitly. You must also enable PT_PAX_FLAGS support as it
36031 + is the only way to mark executables for soft mode use.
36033 + Soft mode can be activated by using the "pax_softmode=1" kernel command
36034 + line option on boot. Furthermore you can control various PaX features
36035 + at runtime via the entries in /proc/sys/kernel/pax.
36038 + bool 'Use legacy ELF header marking'
36040 + Enabling this option will allow you to control PaX features on
36041 + a per executable basis via the 'chpax' utility available at
36042 + http://pax.grsecurity.net/. The control flags will be read from
36043 + an otherwise reserved part of the ELF header. This marking has
36044 + numerous drawbacks (no support for soft-mode, toolchain does not
36045 + know about the non-standard use of the ELF header) therefore it
36046 + has been deprecated in favour of PT_PAX_FLAGS support.
36048 + If you have applications not marked by the PT_PAX_FLAGS ELF
36049 + program header then you MUST enable this option otherwise they
36050 + will not get any protection.
36052 + Note that if you enable PT_PAX_FLAGS marking support as well,
36053 + the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
36055 +config PAX_PT_PAX_FLAGS
36056 + bool 'Use ELF program header marking'
36058 + Enabling this option will allow you to control PaX features on
36059 + a per executable basis via the 'paxctl' utility available at
36060 + http://pax.grsecurity.net/. The control flags will be read from
36061 + a PaX specific ELF program header (PT_PAX_FLAGS). This marking
36062 + has the benefits of supporting both soft mode and being fully
36063 + integrated into the toolchain (the binutils patch is available
36064 + from http://pax.grsecurity.net).
36066 + If you have applications not marked by the PT_PAX_FLAGS ELF
36067 + program header then you MUST enable the EI_PAX marking support
36068 + otherwise they will not get any protection.
36070 + Note that if you enable the legacy EI_PAX marking support as well,
36071 + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
36074 + prompt 'MAC system integration'
36075 + default PAX_HAVE_ACL_FLAGS
36077 + Mandatory Access Control systems have the option of controlling
36078 + PaX flags on a per executable basis, choose the method supported
36079 + by your particular system.
36081 + - "none": if your MAC system does not interact with PaX,
36082 + - "direct": if your MAC system defines pax_set_initial_flags() itself,
36083 + - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
36085 + NOTE: this option is for developers/integrators only.
36087 + config PAX_NO_ACL_FLAGS
36090 + config PAX_HAVE_ACL_FLAGS
36093 + config PAX_HOOK_ACL_FLAGS
36099 +menu "Non-executable pages"
36103 + bool "Enforce non-executable pages"
36104 + 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)
36106 + By design some architectures do not allow for protecting memory
36107 + pages against execution or even if they do, Linux does not make
36108 + use of this feature. In practice this means that if a page is
36109 + readable (such as the stack or heap) it is also executable.
36111 + There is a well known exploit technique that makes use of this
36112 + fact and a common programming mistake where an attacker can
36113 + introduce code of his choice somewhere in the attacked program's
36114 + memory (typically the stack or the heap) and then execute it.
36116 + If the attacked program was running with different (typically
36117 + higher) privileges than that of the attacker, then he can elevate
36118 + his own privilege level (e.g. get a root shell, write to files for
36119 + which he does not have write access to, etc).
36121 + Enabling this option will let you choose from various features
36122 + that prevent the injection and execution of 'foreign' code in
36125 + This will also break programs that rely on the old behaviour and
36126 + expect that dynamically allocated memory via the malloc() family
36127 + of functions is executable (which it is not). Notable examples
36128 + are the XFree86 4.x server, the java runtime and wine.
36130 +config PAX_PAGEEXEC
36131 + bool "Paging based non-executable pages"
36132 + depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7)
36134 + This implementation is based on the paging feature of the CPU.
36135 + On i386 without hardware non-executable bit support there is a
36136 + variable but usually low performance impact, however on Intel's
36137 + P4 core based CPUs it is very high so you should not enable this
36138 + for kernels meant to be used on such CPUs.
36140 + On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
36141 + with hardware non-executable bit support there is no performance
36142 + impact, on ppc the impact is negligible.
36144 + Note that several architectures require various emulations due to
36145 + badly designed userland ABIs, this will cause a performance impact
36146 + but will disappear as soon as userland is fixed (e.g., ppc users
36147 + can make use of the secure-plt feature found in binutils).
36149 +config PAX_SEGMEXEC
36150 + bool "Segmentation based non-executable pages"
36151 + depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
36153 + This implementation is based on the segmentation feature of the
36154 + CPU and has a very small performance impact, however applications
36155 + will be limited to a 1.5 GB address space instead of the normal
36158 +config PAX_EMUTRAMP
36159 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
36160 + default y if PARISC || PPC32
36162 + There are some programs and libraries that for one reason or
36163 + another attempt to execute special small code snippets from
36164 + non-executable memory pages. Most notable examples are the
36165 + signal handler return code generated by the kernel itself and
36166 + the GCC trampolines.
36168 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
36169 + such programs will no longer work under your kernel.
36171 + As a remedy you can say Y here and use the 'chpax' or 'paxctl'
36172 + utilities to enable trampoline emulation for the affected programs
36173 + yet still have the protection provided by the non-executable pages.
36175 + On parisc and ppc you MUST enable this option and EMUSIGRT as
36176 + well, otherwise your system will not even boot.
36178 + Alternatively you can say N here and use the 'chpax' or 'paxctl'
36179 + utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
36180 + for the affected files.
36182 + NOTE: enabling this feature *may* open up a loophole in the
36183 + protection provided by non-executable pages that an attacker
36184 + could abuse. Therefore the best solution is to not have any
36185 + files on your system that would require this option. This can
36186 + be achieved by not using libc5 (which relies on the kernel
36187 + signal handler return code) and not using or rewriting programs
36188 + that make use of the nested function implementation of GCC.
36189 + Skilled users can just fix GCC itself so that it implements
36190 + nested function calls in a way that does not interfere with PaX.
36192 +config PAX_EMUSIGRT
36193 + bool "Automatically emulate sigreturn trampolines"
36194 + depends on PAX_EMUTRAMP && (PARISC || PPC32)
36197 + Enabling this option will have the kernel automatically detect
36198 + and emulate signal return trampolines executing on the stack
36199 + that would otherwise lead to task termination.
36201 + This solution is intended as a temporary one for users with
36202 + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
36203 + Modula-3 runtime, etc) or executables linked to such, basically
36204 + everything that does not specify its own SA_RESTORER function in
36205 + normal executable memory like glibc 2.1+ does.
36207 + On parisc and ppc you MUST enable this option, otherwise your
36208 + system will not even boot.
36210 + NOTE: this feature cannot be disabled on a per executable basis
36211 + and since it *does* open up a loophole in the protection provided
36212 + by non-executable pages, the best solution is to not have any
36213 + files on your system that would require this option.
36215 +config PAX_MPROTECT
36216 + bool "Restrict mprotect()"
36217 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
36219 + Enabling this option will prevent programs from
36220 + - changing the executable status of memory pages that were
36221 + not originally created as executable,
36222 + - making read-only executable pages writable again,
36223 + - creating executable pages from anonymous memory.
36225 + You should say Y here to complete the protection provided by
36226 + the enforcement of non-executable pages.
36228 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36229 + this feature on a per file basis.
36231 +config PAX_NOELFRELOCS
36232 + bool "Disallow ELF text relocations"
36233 + depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
36235 + Non-executable pages and mprotect() restrictions are effective
36236 + in preventing the introduction of new executable code into an
36237 + attacked task's address space. There remain only two venues
36238 + for this kind of attack: if the attacker can execute already
36239 + existing code in the attacked task then he can either have it
36240 + create and mmap() a file containing his code or have it mmap()
36241 + an already existing ELF library that does not have position
36242 + independent code in it and use mprotect() on it to make it
36243 + writable and copy his code there. While protecting against
36244 + the former approach is beyond PaX, the latter can be prevented
36245 + by having only PIC ELF libraries on one's system (which do not
36246 + need to relocate their code). If you are sure this is your case,
36247 + then enable this option otherwise be careful as you may not even
36248 + be able to boot or log on your system (for example, some PAM
36249 + modules are erroneously compiled as non-PIC by default).
36251 + NOTE: if you are using dynamic ELF executables (as suggested
36252 + when using ASLR) then you must have made sure that you linked
36253 + your files using the PIC version of crt1 (the et_dyn.tar.gz package
36254 + referenced there has already been updated to support this).
36256 +config PAX_ETEXECRELOCS
36257 + bool "Allow ELF ET_EXEC text relocations"
36258 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
36261 + On some architectures there are incorrectly created applications
36262 + that require text relocations and would not work without enabling
36263 + this option. If you are an alpha, ia64 or parisc user, you should
36264 + enable this option and disable it once you have made sure that
36265 + none of your applications need it.
36268 + bool "Automatically emulate ELF PLT"
36269 + depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
36272 + Enabling this option will have the kernel automatically detect
36273 + and emulate the Procedure Linkage Table entries in ELF files.
36274 + On some architectures such entries are in writable memory, and
36275 + become non-executable leading to task termination. Therefore
36276 + it is mandatory that you enable this option on alpha, parisc,
36277 + ppc (if secure-plt is not used throughout in userland), sparc
36278 + and sparc64, otherwise your system would not even boot.
36280 + NOTE: this feature *does* open up a loophole in the protection
36281 + provided by the non-executable pages, therefore the proper
36282 + solution is to modify the toolchain to produce a PLT that does
36283 + not need to be writable.
36285 +config PAX_DLRESOLVE
36287 + depends on PAX_EMUPLT && (SPARC32 || SPARC64)
36290 +config PAX_SYSCALL
36292 + depends on PAX_PAGEEXEC && PPC32
36295 +config PAX_KERNEXEC
36296 + bool "Enforce non-executable kernel pages"
36297 + depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
36299 + This is the kernel land equivalent of PAGEEXEC and MPROTECT,
36300 + that is, enabling this option will make it harder to inject
36301 + and execute 'foreign' code in kernel memory itself.
36305 +menu "Address Space Layout Randomization"
36309 + bool "Address Space Layout Randomization"
36310 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
36312 + Many if not most exploit techniques rely on the knowledge of
36313 + certain addresses in the attacked program. The following options
36314 + will allow the kernel to apply a certain amount of randomization
36315 + to specific parts of the program thereby forcing an attacker to
36316 + guess them in most cases. Any failed guess will most likely crash
36317 + the attacked program which allows the kernel to detect such attempts
36318 + and react on them. PaX itself provides no reaction mechanisms,
36319 + instead it is strongly encouraged that you make use of Nergal's
36320 + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
36321 + (http://www.grsecurity.net/) built-in crash detection features or
36322 + develop one yourself.
36324 + By saying Y here you can choose to randomize the following areas:
36325 + - top of the task's kernel stack
36326 + - top of the task's userland stack
36327 + - base address for mmap() requests that do not specify one
36328 + (this includes all libraries)
36329 + - base address of the main executable
36331 + It is strongly recommended to say Y here as address space layout
36332 + randomization has negligible impact on performance yet it provides
36333 + a very effective protection.
36335 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36336 + this feature on a per file basis.
36338 +config PAX_RANDKSTACK
36339 + bool "Randomize kernel stack base"
36340 + depends on PAX_ASLR && X86_TSC && X86_32
36342 + By saying Y here the kernel will randomize every task's kernel
36343 + stack on every system call. This will not only force an attacker
36344 + to guess it but also prevent him from making use of possible
36345 + leaked information about it.
36347 + Since the kernel stack is a rather scarce resource, randomization
36348 + may cause unexpected stack overflows, therefore you should very
36349 + carefully test your system. Note that once enabled in the kernel
36350 + configuration, this feature cannot be disabled on a per file basis.
36352 +config PAX_RANDUSTACK
36353 + bool "Randomize user stack base"
36354 + depends on PAX_ASLR
36356 + By saying Y here the kernel will randomize every task's userland
36357 + stack. The randomization is done in two steps where the second
36358 + one may apply a big amount of shift to the top of the stack and
36359 + cause problems for programs that want to use lots of memory (more
36360 + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
36361 + For this reason the second step can be controlled by 'chpax' or
36362 + 'paxctl' on a per file basis.
36364 +config PAX_RANDMMAP
36365 + bool "Randomize mmap() base"
36366 + depends on PAX_ASLR
36368 + By saying Y here the kernel will use a randomized base address for
36369 + mmap() requests that do not specify one themselves. As a result
36370 + all dynamically loaded libraries will appear at random addresses
36371 + and therefore be harder to exploit by a technique where an attacker
36372 + attempts to execute library code for his purposes (e.g. spawn a
36373 + shell from an exploited program that is running at an elevated
36374 + privilege level).
36376 + Furthermore, if a program is relinked as a dynamic ELF file, its
36377 + base address will be randomized as well, completing the full
36378 + randomization of the address space layout. Attacking such programs
36379 + becomes a guess game. You can find an example of doing this at
36380 + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
36381 + http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
36383 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
36384 + feature on a per file basis.
36388 +menu "Miscellaneous hardening features"
36390 +config PAX_MEMORY_SANITIZE
36391 + bool "Sanitize all freed memory"
36393 + By saying Y here the kernel will erase memory pages as soon as they
36394 + are freed. This in turn reduces the lifetime of data stored in the
36395 + pages, making it less likely that sensitive information such as
36396 + passwords, cryptographic secrets, etc stay in memory for too long.
36398 + This is especially useful for programs whose runtime is short, long
36399 + lived processes and the kernel itself benefit from this as long as
36400 + they operate on whole memory pages and ensure timely freeing of pages
36401 + that may hold sensitive information.
36403 + The tradeoff is performance impact, on a single CPU system kernel
36404 + compilation sees a 3% slowdown, other systems and workloads may vary
36405 + and you are advised to test this feature on your expected workload
36406 + before deploying it.
36408 + Note that this feature does not protect data stored in live pages,
36409 + e.g., process memory swapped to disk may stay there for a long time.
36411 +config PAX_MEMORY_UDEREF
36412 + bool "Prevent invalid userland pointer dereference"
36413 + depends on X86_32 && !COMPAT_VDSO && !UML_X86
36415 + By saying Y here the kernel will be prevented from dereferencing
36416 + userland pointers in contexts where the kernel expects only kernel
36417 + pointers. This is both a useful runtime debugging feature and a
36418 + security measure that prevents exploiting a class of kernel bugs.
36420 + The tradeoff is that some virtualization solutions may experience
36421 + a huge slowdown and therefore you should not enable this feature
36422 + for kernels meant to run in such environments. Whether a given VM
36423 + solution is affected or not is best determined by simply trying it
36424 + out, the performance impact will be obvious right on boot as this
36425 + mechanism engages from very early on. A good rule of thumb is that
36426 + VMs running on CPUs without hardware virtualization support (i.e.,
36427 + the majority of IA-32 CPUs) will likely experience the slowdown.
36429 +config PAX_REFCOUNT
36430 + bool "Prevent various kernel object reference counter overflows"
36433 + By saying Y here the kernel will detect and prevent overflowing
36434 + various (but not all) kinds of object reference counters. Such
36435 + overflows can normally occur due to bugs only and are often, if
36436 + not always, exploitable.
36438 + The tradeoff is that data structures protected by an oveflowed
36439 + refcount will never be freed and therefore will leak memory. Note
36440 + that this leak also happens even without this protection but in
36441 + that case the overflow can eventually trigger the freeing of the
36442 + data structure while it is still being used elsewhere, resulting
36443 + in the exploitable situation that this feature prevents.
36445 + Since this has a negligible performance impact, you should enable
36452 bool "Enable access key retention support"
36454 diff -urNp linux-2.6.27.4/sound/core/oss/pcm_oss.c linux-2.6.27.4/sound/core/oss/pcm_oss.c
36455 --- linux-2.6.27.4/sound/core/oss/pcm_oss.c 2008-10-22 17:38:01.000000000 -0400
36456 +++ linux-2.6.27.4/sound/core/oss/pcm_oss.c 2008-10-27 22:36:19.000000000 -0400
36457 @@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
36460 #else /* !CONFIG_SND_VERBOSE_PROCFS */
36461 -#define snd_pcm_oss_proc_init(pcm)
36462 -#define snd_pcm_oss_proc_done(pcm)
36463 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
36464 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
36465 #endif /* CONFIG_SND_VERBOSE_PROCFS */
36468 diff -urNp linux-2.6.27.4/sound/core/seq/seq_lock.h linux-2.6.27.4/sound/core/seq/seq_lock.h
36469 --- linux-2.6.27.4/sound/core/seq/seq_lock.h 2008-10-22 17:38:01.000000000 -0400
36470 +++ linux-2.6.27.4/sound/core/seq/seq_lock.h 2008-10-27 22:36:19.000000000 -0400
36471 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
36472 #else /* SMP || CONFIG_SND_DEBUG */
36474 typedef spinlock_t snd_use_lock_t; /* dummy */
36475 -#define snd_use_lock_init(lockp) /**/
36476 -#define snd_use_lock_use(lockp) /**/
36477 -#define snd_use_lock_free(lockp) /**/
36478 -#define snd_use_lock_sync(lockp) /**/
36479 +#define snd_use_lock_init(lockp) do {} while (0)
36480 +#define snd_use_lock_use(lockp) do {} while (0)
36481 +#define snd_use_lock_free(lockp) do {} while (0)
36482 +#define snd_use_lock_sync(lockp) do {} while (0)
36484 #endif /* SMP || CONFIG_SND_DEBUG */
36486 diff -urNp linux-2.6.27.4/sound/pci/ac97/ac97_patch.c linux-2.6.27.4/sound/pci/ac97/ac97_patch.c
36487 --- linux-2.6.27.4/sound/pci/ac97/ac97_patch.c 2008-10-22 17:38:01.000000000 -0400
36488 +++ linux-2.6.27.4/sound/pci/ac97/ac97_patch.c 2008-10-27 22:36:19.000000000 -0400
36489 @@ -1498,7 +1498,7 @@ static const struct snd_ac97_res_table a
36490 { AC97_VIDEO, 0x9f1f },
36491 { AC97_AUX, 0x9f1f },
36492 { AC97_PCM, 0x9f1f },
36493 - { } /* terminator */
36494 + { 0, 0 } /* terminator */
36497 static int patch_ad1819(struct snd_ac97 * ac97)
36498 @@ -3668,7 +3668,7 @@ static struct snd_ac97_res_table lm4550_
36499 { AC97_AUX, 0x1f1f },
36500 { AC97_PCM, 0x1f1f },
36501 { AC97_REC_GAIN, 0x0f0f },
36502 - { } /* terminator */
36503 + { 0, 0 } /* terminator */
36506 static int patch_lm4550(struct snd_ac97 *ac97)
36507 diff -urNp linux-2.6.27.4/sound/pci/ens1370.c linux-2.6.27.4/sound/pci/ens1370.c
36508 --- linux-2.6.27.4/sound/pci/ens1370.c 2008-10-22 17:38:01.000000000 -0400
36509 +++ linux-2.6.27.4/sound/pci/ens1370.c 2008-10-27 22:36:19.000000000 -0400
36510 @@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
36511 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
36512 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
36515 + { 0, 0, 0, 0, 0, 0, 0 }
36518 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
36519 diff -urNp linux-2.6.27.4/sound/pci/intel8x0.c linux-2.6.27.4/sound/pci/intel8x0.c
36520 --- linux-2.6.27.4/sound/pci/intel8x0.c 2008-10-22 17:38:01.000000000 -0400
36521 +++ linux-2.6.27.4/sound/pci/intel8x0.c 2008-10-27 22:36:19.000000000 -0400
36522 @@ -437,7 +437,7 @@ static struct pci_device_id snd_intel8x0
36523 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
36524 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
36525 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
36527 + { 0, 0, 0, 0, 0, 0, 0 }
36530 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
36531 @@ -2076,7 +2076,7 @@ static struct ac97_quirk ac97_quirks[] _
36532 .type = AC97_TUNE_HP_ONLY
36535 - { } /* terminator */
36536 + { 0, 0, 0, 0, NULL, 0 } /* terminator */
36539 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
36540 diff -urNp linux-2.6.27.4/sound/pci/intel8x0m.c linux-2.6.27.4/sound/pci/intel8x0m.c
36541 --- linux-2.6.27.4/sound/pci/intel8x0m.c 2008-10-22 17:38:01.000000000 -0400
36542 +++ linux-2.6.27.4/sound/pci/intel8x0m.c 2008-10-27 22:36:19.000000000 -0400
36543 @@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
36544 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
36545 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
36548 + { 0, 0, 0, 0, 0, 0, 0 }
36551 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
36552 @@ -1257,7 +1257,7 @@ static struct shortname_table {
36553 { 0x5455, "ALi M5455" },
36554 { 0x746d, "AMD AMD8111" },
36560 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
36561 diff -urNp linux-2.6.27.4/virt/kvm/kvm_main.c linux-2.6.27.4/virt/kvm/kvm_main.c
36562 --- linux-2.6.27.4/virt/kvm/kvm_main.c 2008-10-22 17:38:01.000000000 -0400
36563 +++ linux-2.6.27.4/virt/kvm/kvm_main.c 2008-10-27 22:36:19.000000000 -0400
36564 @@ -1469,6 +1469,9 @@ static struct miscdevice kvm_dev = {
36573 static void hardware_enable(void *junk)