1 diff -urNp linux-2.6.25.10/arch/alpha/kernel/module.c linux-2.6.25.10/arch/alpha/kernel/module.c
2 --- linux-2.6.25.10/arch/alpha/kernel/module.c 2008-07-02 23:46:47.000000000 -0400
3 +++ linux-2.6.25.10/arch/alpha/kernel/module.c 2008-07-03 16:53:24.000000000 -0400
4 @@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
6 /* The small sections were sorted to the end of the segment.
7 The following should definitely cover them. */
8 - gp = (u64)me->module_core + me->core_size - 0x8000;
9 + gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
10 got = sechdrs[me->arch.gotsecindex].sh_addr;
12 for (i = 0; i < n; i++) {
13 diff -urNp linux-2.6.25.10/arch/alpha/kernel/osf_sys.c linux-2.6.25.10/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.25.10/arch/alpha/kernel/osf_sys.c 2008-07-02 23:46:47.000000000 -0400
15 +++ linux-2.6.25.10/arch/alpha/kernel/osf_sys.c 2008-07-03 16:53:24.000000000 -0400
16 @@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
17 merely specific addresses, but regions of memory -- perhaps
18 this feature should be incorporated into all ports? */
20 +#ifdef CONFIG_PAX_RANDMMAP
21 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
25 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
26 if (addr != (unsigned long) -ENOMEM)
27 @@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
30 /* Next, try allocating at TASK_UNMAPPED_BASE. */
31 - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
33 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
35 if (addr != (unsigned long) -ENOMEM)
38 diff -urNp linux-2.6.25.10/arch/alpha/kernel/ptrace.c linux-2.6.25.10/arch/alpha/kernel/ptrace.c
39 --- linux-2.6.25.10/arch/alpha/kernel/ptrace.c 2008-07-02 23:46:47.000000000 -0400
40 +++ linux-2.6.25.10/arch/alpha/kernel/ptrace.c 2008-07-03 16:53:24.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.25.10/arch/alpha/mm/fault.c linux-2.6.25.10/arch/alpha/mm/fault.c
60 --- linux-2.6.25.10/arch/alpha/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
61 +++ linux-2.6.25.10/arch/alpha/mm/fault.c 2008-07-03 16:53:24.000000000 -0400
63 #include <linux/smp.h>
64 #include <linux/interrupt.h>
65 #include <linux/module.h>
66 +#include <linux/binfmts.h>
68 #include <asm/system.h>
69 #include <asm/uaccess.h>
70 @@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
74 +#ifdef CONFIG_PAX_PAGEEXEC
76 + * PaX: decide what to do with offenders (regs->pc = fault address)
78 + * returns 1 when task should be killed
79 + * 2 when patched PLT trampoline was detected
80 + * 3 when unpatched PLT trampoline was detected
82 +static int pax_handle_fetch_fault(struct pt_regs *regs)
85 +#ifdef CONFIG_PAX_EMUPLT
88 + do { /* PaX: patched PLT emulation #1 */
89 + unsigned int ldah, ldq, jmp;
91 + err = get_user(ldah, (unsigned int *)regs->pc);
92 + err |= get_user(ldq, (unsigned int *)(regs->pc+4));
93 + err |= get_user(jmp, (unsigned int *)(regs->pc+8));
98 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
99 + (ldq & 0xFFFF0000U) == 0xA77B0000U &&
100 + jmp == 0x6BFB0000U)
102 + unsigned long r27, addr;
103 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
104 + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
106 + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
107 + err = get_user(r27, (unsigned long *)addr);
117 + do { /* PaX: patched PLT emulation #2 */
118 + unsigned int ldah, lda, br;
120 + err = get_user(ldah, (unsigned int *)regs->pc);
121 + err |= get_user(lda, (unsigned int *)(regs->pc+4));
122 + err |= get_user(br, (unsigned int *)(regs->pc+8));
127 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
128 + (lda & 0xFFFF0000U) == 0xA77B0000U &&
129 + (br & 0xFFE00000U) == 0xC3E00000U)
131 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
132 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
133 + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
135 + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
136 + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
141 + do { /* PaX: unpatched PLT emulation */
144 + err = get_user(br, (unsigned int *)regs->pc);
146 + if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
147 + unsigned int br2, ldq, nop, jmp;
148 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
150 + addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
151 + err = get_user(br2, (unsigned int *)addr);
152 + err |= get_user(ldq, (unsigned int *)(addr+4));
153 + err |= get_user(nop, (unsigned int *)(addr+8));
154 + err |= get_user(jmp, (unsigned int *)(addr+12));
155 + err |= get_user(resolver, (unsigned long *)(addr+16));
160 + if (br2 == 0xC3600000U &&
161 + ldq == 0xA77B000CU &&
162 + nop == 0x47FF041FU &&
163 + jmp == 0x6B7B0000U)
165 + regs->r28 = regs->pc+4;
166 + regs->r27 = addr+16;
167 + regs->pc = resolver;
177 +void pax_report_insns(void *pc, void *sp)
181 + printk(KERN_ERR "PAX: bytes at PC: ");
182 + for (i = 0; i < 5; i++) {
184 + if (get_user(c, (unsigned int *)pc+i))
185 + printk(KERN_CONT "???????? ");
187 + printk(KERN_CONT "%08x ", c);
194 * This routine handles page faults. It determines the address,
195 @@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
197 si_code = SEGV_ACCERR;
199 - if (!(vma->vm_flags & VM_EXEC))
200 + if (!(vma->vm_flags & VM_EXEC)) {
202 +#ifdef CONFIG_PAX_PAGEEXEC
203 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
206 + up_read(&mm->mmap_sem);
207 + switch (pax_handle_fetch_fault(regs)) {
209 +#ifdef CONFIG_PAX_EMUPLT
216 + pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
217 + do_group_exit(SIGKILL);
224 /* Allow reads even for write-only mappings */
225 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
226 diff -urNp linux-2.6.25.10/arch/arm/mm/mmap.c linux-2.6.25.10/arch/arm/mm/mmap.c
227 --- linux-2.6.25.10/arch/arm/mm/mmap.c 2008-07-02 23:46:47.000000000 -0400
228 +++ linux-2.6.25.10/arch/arm/mm/mmap.c 2008-07-03 16:53:24.000000000 -0400
229 @@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
233 +#ifdef CONFIG_PAX_RANDMMAP
234 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
239 addr = COLOUR_ALIGN(addr, pgoff);
240 @@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
243 if (len > mm->cached_hole_size) {
244 - start_addr = addr = mm->free_area_cache;
245 + start_addr = addr = mm->free_area_cache;
247 - start_addr = addr = TASK_UNMAPPED_BASE;
248 - mm->cached_hole_size = 0;
249 + start_addr = addr = mm->mmap_base;
250 + mm->cached_hole_size = 0;
254 @@ -91,8 +95,8 @@ full_search:
255 * Start a new search - just in case we missed
258 - if (start_addr != TASK_UNMAPPED_BASE) {
259 - start_addr = addr = TASK_UNMAPPED_BASE;
260 + if (start_addr != mm->mmap_base) {
261 + start_addr = addr = mm->mmap_base;
262 mm->cached_hole_size = 0;
265 diff -urNp linux-2.6.25.10/arch/avr32/mm/fault.c linux-2.6.25.10/arch/avr32/mm/fault.c
266 --- linux-2.6.25.10/arch/avr32/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
267 +++ linux-2.6.25.10/arch/avr32/mm/fault.c 2008-07-03 16:53:24.000000000 -0400
268 @@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
270 int exception_trace = 1;
272 +#ifdef CONFIG_PAX_PAGEEXEC
273 +void pax_report_insns(void *pc, void *sp)
277 + printk(KERN_ERR "PAX: bytes at PC: ");
278 + for (i = 0; i < 20; i++) {
280 + if (get_user(c, (unsigned char *)pc+i))
281 + printk(KERN_CONT "???????? ");
283 + printk(KERN_CONT "%02x ", c);
290 * This routine handles page faults. It determines the address and the
291 * problem, and then passes it off to one of the appropriate routines.
292 @@ -157,6 +174,16 @@ bad_area:
293 up_read(&mm->mmap_sem);
295 if (user_mode(regs)) {
297 +#ifdef CONFIG_PAX_PAGEEXEC
298 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
299 + if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
300 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
301 + do_group_exit(SIGKILL);
306 if (exception_trace && printk_ratelimit())
307 printk("%s%s[%d]: segfault at %08lx pc %08lx "
308 "sp %08lx ecr %lu\n",
309 diff -urNp linux-2.6.25.10/arch/ia64/ia32/binfmt_elf32.c linux-2.6.25.10/arch/ia64/ia32/binfmt_elf32.c
310 --- linux-2.6.25.10/arch/ia64/ia32/binfmt_elf32.c 2008-07-02 23:46:47.000000000 -0400
311 +++ linux-2.6.25.10/arch/ia64/ia32/binfmt_elf32.c 2008-07-03 16:53:24.000000000 -0400
312 @@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
314 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
316 +#ifdef CONFIG_PAX_ASLR
317 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
319 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
320 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
323 /* Ugly but avoids duplication */
324 #include "../../../fs/binfmt_elf.c"
326 diff -urNp linux-2.6.25.10/arch/ia64/ia32/ia32priv.h linux-2.6.25.10/arch/ia64/ia32/ia32priv.h
327 --- linux-2.6.25.10/arch/ia64/ia32/ia32priv.h 2008-07-02 23:46:47.000000000 -0400
328 +++ linux-2.6.25.10/arch/ia64/ia32/ia32priv.h 2008-07-03 16:53:24.000000000 -0400
329 @@ -303,7 +303,14 @@ struct old_linux32_dirent {
330 #define ELF_DATA ELFDATA2LSB
331 #define ELF_ARCH EM_386
333 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
334 +#ifdef CONFIG_PAX_RANDUSTACK
335 +#define __IA32_DELTA_STACK (current->mm->delta_stack)
337 +#define __IA32_DELTA_STACK 0UL
340 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
342 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
343 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
345 diff -urNp linux-2.6.25.10/arch/ia64/kernel/module.c linux-2.6.25.10/arch/ia64/kernel/module.c
346 --- linux-2.6.25.10/arch/ia64/kernel/module.c 2008-07-02 23:46:47.000000000 -0400
347 +++ linux-2.6.25.10/arch/ia64/kernel/module.c 2008-07-03 16:53:24.000000000 -0400
348 @@ -321,7 +321,7 @@ module_alloc (unsigned long size)
350 module_free (struct module *mod, void *module_region)
352 - if (mod->arch.init_unw_table && module_region == mod->module_init) {
353 + if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
354 unw_remove_unwind_table(mod->arch.init_unw_table);
355 mod->arch.init_unw_table = NULL;
357 @@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
361 +in_init_rx (const struct module *mod, uint64_t addr)
363 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
367 +in_init_rw (const struct module *mod, uint64_t addr)
369 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
373 in_init (const struct module *mod, uint64_t addr)
375 - return addr - (uint64_t) mod->module_init < mod->init_size;
376 + return in_init_rx(mod, addr) || in_init_rw(mod, addr);
380 +in_core_rx (const struct module *mod, uint64_t addr)
382 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
386 +in_core_rw (const struct module *mod, uint64_t addr)
388 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
392 in_core (const struct module *mod, uint64_t addr)
394 - return addr - (uint64_t) mod->module_core < mod->core_size;
395 + return in_core_rx(mod, addr) || in_core_rw(mod, addr);
399 @@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
403 - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
404 + if (in_init_rx(mod, val))
405 + val -= (uint64_t) mod->module_init_rx;
406 + else if (in_init_rw(mod, val))
407 + val -= (uint64_t) mod->module_init_rw;
408 + else if (in_core_rx(mod, val))
409 + val -= (uint64_t) mod->module_core_rx;
410 + else if (in_core_rw(mod, val))
411 + val -= (uint64_t) mod->module_core_rw;
415 @@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
416 * addresses have been selected...
419 - if (mod->core_size > MAX_LTOFF)
420 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
422 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
423 * at the end of the module.
425 - gp = mod->core_size - MAX_LTOFF / 2;
426 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
428 - gp = mod->core_size / 2;
429 - gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
430 + gp = (mod->core_size_rx + mod->core_size_rw) / 2;
431 + gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
433 DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
435 diff -urNp linux-2.6.25.10/arch/ia64/kernel/sys_ia64.c linux-2.6.25.10/arch/ia64/kernel/sys_ia64.c
436 --- linux-2.6.25.10/arch/ia64/kernel/sys_ia64.c 2008-07-02 23:46:47.000000000 -0400
437 +++ linux-2.6.25.10/arch/ia64/kernel/sys_ia64.c 2008-07-03 16:53:24.000000000 -0400
438 @@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
439 if (REGION_NUMBER(addr) == RGN_HPAGE)
443 +#ifdef CONFIG_PAX_RANDMMAP
444 + if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
445 + addr = mm->free_area_cache;
450 addr = mm->free_area_cache;
452 @@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
453 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
454 /* At this point: (!vma || addr < vma->vm_end). */
455 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
456 - if (start_addr != TASK_UNMAPPED_BASE) {
457 + if (start_addr != mm->mmap_base) {
458 /* Start a new search --- just in case we missed some holes. */
459 - addr = TASK_UNMAPPED_BASE;
460 + addr = mm->mmap_base;
464 diff -urNp linux-2.6.25.10/arch/ia64/mm/fault.c linux-2.6.25.10/arch/ia64/mm/fault.c
465 --- linux-2.6.25.10/arch/ia64/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
466 +++ linux-2.6.25.10/arch/ia64/mm/fault.c 2008-07-03 16:53:24.000000000 -0400
468 #include <linux/kprobes.h>
469 #include <linux/kdebug.h>
470 #include <linux/vs_memory.h>
471 +#include <linux/binfmts.h>
473 #include <asm/pgtable.h>
474 #include <asm/processor.h>
475 @@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
476 return pte_present(pte);
479 +#ifdef CONFIG_PAX_PAGEEXEC
480 +void pax_report_insns(void *pc, void *sp)
484 + printk(KERN_ERR "PAX: bytes at PC: ");
485 + for (i = 0; i < 8; i++) {
487 + if (get_user(c, (unsigned int *)pc+i))
488 + printk(KERN_CONT "???????? ");
490 + printk(KERN_CONT "%08x ", c);
497 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
499 @@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres
500 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
501 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
503 - if ((vma->vm_flags & mask) != mask)
504 + if ((vma->vm_flags & mask) != mask) {
506 +#ifdef CONFIG_PAX_PAGEEXEC
507 + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
508 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
511 + up_read(&mm->mmap_sem);
512 + pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
513 + do_group_exit(SIGKILL);
523 * If for any reason at all we couldn't handle the fault, make
524 diff -urNp linux-2.6.25.10/arch/ia64/mm/init.c linux-2.6.25.10/arch/ia64/mm/init.c
525 --- linux-2.6.25.10/arch/ia64/mm/init.c 2008-07-02 23:46:47.000000000 -0400
526 +++ linux-2.6.25.10/arch/ia64/mm/init.c 2008-07-03 16:53:24.000000000 -0400
527 @@ -128,6 +128,19 @@ ia64_init_addr_space (void)
528 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
529 vma->vm_end = vma->vm_start + PAGE_SIZE;
530 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
532 +#ifdef CONFIG_PAX_PAGEEXEC
533 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
534 + vma->vm_flags &= ~VM_EXEC;
536 +#ifdef CONFIG_PAX_MPROTECT
537 + if (current->mm->pax_flags & MF_PAX_MPROTECT)
538 + vma->vm_flags &= ~VM_MAYEXEC;
544 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
545 down_write(¤t->mm->mmap_sem);
546 if (insert_vm_struct(current->mm, vma)) {
547 diff -urNp linux-2.6.25.10/arch/mips/kernel/binfmt_elfn32.c linux-2.6.25.10/arch/mips/kernel/binfmt_elfn32.c
548 --- linux-2.6.25.10/arch/mips/kernel/binfmt_elfn32.c 2008-07-02 23:46:47.000000000 -0400
549 +++ linux-2.6.25.10/arch/mips/kernel/binfmt_elfn32.c 2008-07-03 16:53:24.000000000 -0400
550 @@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
551 #undef ELF_ET_DYN_BASE
552 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
554 +#ifdef CONFIG_PAX_ASLR
555 +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
557 +#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
558 +#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
561 #include <asm/processor.h>
562 #include <linux/module.h>
563 #include <linux/elfcore.h>
564 diff -urNp linux-2.6.25.10/arch/mips/kernel/binfmt_elfo32.c linux-2.6.25.10/arch/mips/kernel/binfmt_elfo32.c
565 --- linux-2.6.25.10/arch/mips/kernel/binfmt_elfo32.c 2008-07-02 23:46:47.000000000 -0400
566 +++ linux-2.6.25.10/arch/mips/kernel/binfmt_elfo32.c 2008-07-03 16:53:24.000000000 -0400
567 @@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
568 #undef ELF_ET_DYN_BASE
569 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
571 +#ifdef CONFIG_PAX_ASLR
572 +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
574 +#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
575 +#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
578 #include <asm/processor.h>
579 #include <linux/module.h>
580 #include <linux/elfcore.h>
581 diff -urNp linux-2.6.25.10/arch/mips/kernel/syscall.c linux-2.6.25.10/arch/mips/kernel/syscall.c
582 --- linux-2.6.25.10/arch/mips/kernel/syscall.c 2008-07-02 23:46:47.000000000 -0400
583 +++ linux-2.6.25.10/arch/mips/kernel/syscall.c 2008-07-03 16:53:24.000000000 -0400
584 @@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str
586 if (filp || (flags & MAP_SHARED))
589 +#ifdef CONFIG_PAX_RANDMMAP
590 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
595 addr = COLOUR_ALIGN(addr, pgoff);
596 @@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str
597 (!vmm || addr + len <= vmm->vm_start))
600 - addr = TASK_UNMAPPED_BASE;
601 + addr = current->mm->mmap_base;
603 addr = COLOUR_ALIGN(addr, pgoff);
605 diff -urNp linux-2.6.25.10/arch/mips/mm/fault.c linux-2.6.25.10/arch/mips/mm/fault.c
606 --- linux-2.6.25.10/arch/mips/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
607 +++ linux-2.6.25.10/arch/mips/mm/fault.c 2008-07-03 16:53:24.000000000 -0400
609 #include <asm/ptrace.h>
610 #include <asm/highmem.h> /* For VMALLOC_END */
612 +#ifdef CONFIG_PAX_PAGEEXEC
613 +void pax_report_insns(void *pc)
617 + printk(KERN_ERR "PAX: bytes at PC: ");
618 + for (i = 0; i < 5; i++) {
620 + if (get_user(c, (unsigned int *)pc+i))
621 + printk(KERN_CONT "???????? ");
623 + printk(KERN_CONT "%08x ", c);
630 * This routine handles page faults. It determines the address,
631 * and the problem, and then passes it off to one of the appropriate
632 diff -urNp linux-2.6.25.10/arch/parisc/kernel/module.c linux-2.6.25.10/arch/parisc/kernel/module.c
633 --- linux-2.6.25.10/arch/parisc/kernel/module.c 2008-07-02 23:46:47.000000000 -0400
634 +++ linux-2.6.25.10/arch/parisc/kernel/module.c 2008-07-03 16:53:24.000000000 -0400
637 /* three functions to determine where in the module core
638 * or init pieces the location is */
639 +static inline int in_init_rx(struct module *me, void *loc)
641 + return (loc >= me->module_init_rx &&
642 + loc < (me->module_init_rx + me->init_size_rx));
645 +static inline int in_init_rw(struct module *me, void *loc)
647 + return (loc >= me->module_init_rw &&
648 + loc < (me->module_init_rw + me->init_size_rw));
651 static inline int in_init(struct module *me, void *loc)
653 - return (loc >= me->module_init &&
654 - loc <= (me->module_init + me->init_size));
655 + return in_init_rx(me, loc) || in_init_rw(me, loc);
658 +static inline int in_core_rx(struct module *me, void *loc)
660 + return (loc >= me->module_core_rx &&
661 + loc < (me->module_core_rx + me->core_size_rx));
664 +static inline int in_core_rw(struct module *me, void *loc)
666 + return (loc >= me->module_core_rw &&
667 + loc < (me->module_core_rw + me->core_size_rw));
670 static inline int in_core(struct module *me, void *loc)
672 - return (loc >= me->module_core &&
673 - loc <= (me->module_core + me->core_size));
674 + return in_core_rx(me, loc) || in_core_rw(me, loc);
677 static inline int in_local(struct module *me, void *loc)
678 @@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
681 /* align things a bit */
682 - me->core_size = ALIGN(me->core_size, 16);
683 - me->arch.got_offset = me->core_size;
684 - me->core_size += gots * sizeof(struct got_entry);
686 - me->core_size = ALIGN(me->core_size, 16);
687 - me->arch.fdesc_offset = me->core_size;
688 - me->core_size += fdescs * sizeof(Elf_Fdesc);
690 - me->core_size = ALIGN(me->core_size, 16);
691 - me->arch.stub_offset = me->core_size;
692 - me->core_size += stubs * sizeof(struct stub_entry);
694 - me->init_size = ALIGN(me->init_size, 16);
695 - me->arch.init_stub_offset = me->init_size;
696 - me->init_size += init_stubs * sizeof(struct stub_entry);
697 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
698 + me->arch.got_offset = me->core_size_rw;
699 + me->core_size_rw += gots * sizeof(struct got_entry);
701 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
702 + me->arch.fdesc_offset = me->core_size_rw;
703 + me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
705 + me->core_size_rx = ALIGN(me->core_size_rx, 16);
706 + me->arch.stub_offset = me->core_size_rx;
707 + me->core_size_rx += stubs * sizeof(struct stub_entry);
709 + me->init_size_rx = ALIGN(me->init_size_rx, 16);
710 + me->arch.init_stub_offset = me->init_size_rx;
711 + me->init_size_rx += init_stubs * sizeof(struct stub_entry);
713 me->arch.got_max = gots;
714 me->arch.fdesc_max = fdescs;
715 @@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
719 - got = me->module_core + me->arch.got_offset;
720 + got = me->module_core_rw + me->arch.got_offset;
721 for (i = 0; got[i].addr; i++)
722 if (got[i].addr == value)
724 @@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
726 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
728 - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
729 + Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
732 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
733 @@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
737 - fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
738 + fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
739 return (Elf_Addr)fdesc;
741 #endif /* CONFIG_64BIT */
742 @@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
744 i = me->arch.init_stub_count++;
745 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
746 - stub = me->module_init + me->arch.init_stub_offset +
747 + stub = me->module_init_rx + me->arch.init_stub_offset +
748 i * sizeof(struct stub_entry);
750 i = me->arch.stub_count++;
751 BUG_ON(me->arch.stub_count > me->arch.stub_max);
752 - stub = me->module_core + me->arch.stub_offset +
753 + stub = me->module_core_rx + me->arch.stub_offset +
754 i * sizeof(struct stub_entry);
757 @@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
759 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
760 end = table + sechdrs[me->arch.unwind_section].sh_size;
761 - gp = (Elf_Addr)me->module_core + me->arch.got_offset;
762 + gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
764 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
765 me->arch.unwind_section, table, end, gp);
766 diff -urNp linux-2.6.25.10/arch/parisc/kernel/sys_parisc.c linux-2.6.25.10/arch/parisc/kernel/sys_parisc.c
767 --- linux-2.6.25.10/arch/parisc/kernel/sys_parisc.c 2008-07-02 23:46:47.000000000 -0400
768 +++ linux-2.6.25.10/arch/parisc/kernel/sys_parisc.c 2008-07-03 16:53:24.000000000 -0400
769 @@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
770 if (flags & MAP_FIXED)
773 - addr = TASK_UNMAPPED_BASE;
774 + addr = current->mm->mmap_base;
777 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
778 diff -urNp linux-2.6.25.10/arch/parisc/kernel/traps.c linux-2.6.25.10/arch/parisc/kernel/traps.c
779 --- linux-2.6.25.10/arch/parisc/kernel/traps.c 2008-07-02 23:46:47.000000000 -0400
780 +++ linux-2.6.25.10/arch/parisc/kernel/traps.c 2008-07-03 16:53:24.000000000 -0400
781 @@ -732,9 +732,7 @@ void handle_interruption(int code, struc
783 down_read(¤t->mm->mmap_sem);
784 vma = find_vma(current->mm,regs->iaoq[0]);
785 - if (vma && (regs->iaoq[0] >= vma->vm_start)
786 - && (vma->vm_flags & VM_EXEC)) {
788 + if (vma && (regs->iaoq[0] >= vma->vm_start)) {
789 fault_address = regs->iaoq[0];
790 fault_space = regs->iasq[0];
792 diff -urNp linux-2.6.25.10/arch/parisc/mm/fault.c linux-2.6.25.10/arch/parisc/mm/fault.c
793 --- linux-2.6.25.10/arch/parisc/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
794 +++ linux-2.6.25.10/arch/parisc/mm/fault.c 2008-07-03 16:53:24.000000000 -0400
796 #include <linux/sched.h>
797 #include <linux/interrupt.h>
798 #include <linux/module.h>
799 +#include <linux/unistd.h>
800 +#include <linux/binfmts.h>
802 #include <asm/uaccess.h>
803 #include <asm/traps.h>
804 @@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
806 parisc_acctyp(unsigned long code, unsigned int inst)
808 - if (code == 6 || code == 16)
809 + if (code == 6 || code == 7 || code == 16)
812 switch (inst & 0xf0000000) {
813 @@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
817 +#ifdef CONFIG_PAX_PAGEEXEC
819 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
821 + * returns 1 when task should be killed
822 + * 2 when rt_sigreturn trampoline was detected
823 + * 3 when unpatched PLT trampoline was detected
825 +static int pax_handle_fetch_fault(struct pt_regs *regs)
828 +#ifdef CONFIG_PAX_EMUPLT
831 + do { /* PaX: unpatched PLT emulation */
832 + unsigned int bl, depwi;
834 + err = get_user(bl, (unsigned int *)instruction_pointer(regs));
835 + err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
840 + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
841 + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
843 + err = get_user(ldw, (unsigned int *)addr);
844 + err |= get_user(bv, (unsigned int *)(addr+4));
845 + err |= get_user(ldw2, (unsigned int *)(addr+8));
850 + if (ldw == 0x0E801096U &&
851 + bv == 0xEAC0C000U &&
852 + ldw2 == 0x0E881095U)
854 + unsigned int resolver, map;
856 + err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
857 + err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
861 + regs->gr[20] = instruction_pointer(regs)+8;
862 + regs->gr[21] = map;
863 + regs->gr[22] = resolver;
864 + regs->iaoq[0] = resolver | 3UL;
865 + regs->iaoq[1] = regs->iaoq[0] + 4;
872 +#ifdef CONFIG_PAX_EMUTRAMP
874 +#ifndef CONFIG_PAX_EMUSIGRT
875 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
879 + do { /* PaX: rt_sigreturn emulation */
880 + unsigned int ldi1, ldi2, bel, nop;
882 + err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
883 + err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
884 + err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
885 + err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
890 + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
891 + ldi2 == 0x3414015AU &&
892 + bel == 0xE4008200U &&
893 + nop == 0x08000240U)
895 + regs->gr[25] = (ldi1 & 2) >> 1;
896 + regs->gr[20] = __NR_rt_sigreturn;
897 + regs->gr[31] = regs->iaoq[1] + 16;
898 + regs->sr[0] = regs->iasq[1];
899 + regs->iaoq[0] = 0x100UL;
900 + regs->iaoq[1] = regs->iaoq[0] + 4;
901 + regs->iasq[0] = regs->sr[2];
902 + regs->iasq[1] = regs->sr[2];
911 +void pax_report_insns(void *pc, void *sp)
915 + printk(KERN_ERR "PAX: bytes at PC: ");
916 + for (i = 0; i < 5; i++) {
918 + if (get_user(c, (unsigned int *)pc+i))
919 + printk(KERN_CONT "???????? ");
921 + printk(KERN_CONT "%08x ", c);
927 void do_page_fault(struct pt_regs *regs, unsigned long code,
928 unsigned long address)
930 @@ -165,8 +277,33 @@ good_area:
932 acc_type = parisc_acctyp(code,regs->iir);
934 - if ((vma->vm_flags & acc_type) != acc_type)
935 + if ((vma->vm_flags & acc_type) != acc_type) {
937 +#ifdef CONFIG_PAX_PAGEEXEC
938 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
939 + (address & ~3UL) == instruction_pointer(regs))
941 + up_read(&mm->mmap_sem);
942 + switch (pax_handle_fetch_fault(regs)) {
944 +#ifdef CONFIG_PAX_EMUPLT
949 +#ifdef CONFIG_PAX_EMUTRAMP
955 + pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
956 + do_group_exit(SIGKILL);
964 * If for any reason at all we couldn't handle the fault, make
965 diff -urNp linux-2.6.25.10/arch/powerpc/kernel/module_32.c linux-2.6.25.10/arch/powerpc/kernel/module_32.c
966 --- linux-2.6.25.10/arch/powerpc/kernel/module_32.c 2008-07-02 23:46:47.000000000 -0400
967 +++ linux-2.6.25.10/arch/powerpc/kernel/module_32.c 2008-07-03 16:53:24.000000000 -0400
968 @@ -175,7 +175,7 @@ int module_frob_arch_sections(Elf32_Ehdr
969 me->arch.core_plt_section = i;
971 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
972 - printk("Module doesn't contain .plt or .init.plt sections.\n");
973 + printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
977 @@ -216,11 +216,16 @@ static uint32_t do_plt_call(void *locati
979 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
980 /* Init, or core PLT? */
981 - if (location >= mod->module_core
982 - && location < mod->module_core + mod->core_size)
983 + if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
984 + (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
985 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
987 + else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
988 + (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
989 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
991 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
995 /* Find this entry, or if that fails, the next avail. entry */
996 while (entry->jump[0]) {
997 diff -urNp linux-2.6.25.10/arch/powerpc/kernel/signal_32.c linux-2.6.25.10/arch/powerpc/kernel/signal_32.c
998 --- linux-2.6.25.10/arch/powerpc/kernel/signal_32.c 2008-07-02 23:46:47.000000000 -0400
999 +++ linux-2.6.25.10/arch/powerpc/kernel/signal_32.c 2008-07-03 16:53:24.000000000 -0400
1000 @@ -730,7 +730,7 @@ int handle_rt_signal32(unsigned long sig
1001 /* Save user registers on the stack */
1002 frame = &rt_sf->uc.uc_mcontext;
1004 - if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1005 + if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1006 if (save_user_regs(regs, frame, 0))
1008 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1009 diff -urNp linux-2.6.25.10/arch/powerpc/kernel/signal_64.c linux-2.6.25.10/arch/powerpc/kernel/signal_64.c
1010 --- linux-2.6.25.10/arch/powerpc/kernel/signal_64.c 2008-07-02 23:46:47.000000000 -0400
1011 +++ linux-2.6.25.10/arch/powerpc/kernel/signal_64.c 2008-07-03 16:53:24.000000000 -0400
1012 @@ -369,7 +369,7 @@ int handle_rt_signal64(int signr, struct
1013 current->thread.fpscr.val = 0;
1015 /* Set up to return from userspace. */
1016 - if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1017 + if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1018 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1020 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1021 diff -urNp linux-2.6.25.10/arch/powerpc/kernel/vdso.c linux-2.6.25.10/arch/powerpc/kernel/vdso.c
1022 --- linux-2.6.25.10/arch/powerpc/kernel/vdso.c 2008-07-02 23:46:47.000000000 -0400
1023 +++ linux-2.6.25.10/arch/powerpc/kernel/vdso.c 2008-07-03 16:53:24.000000000 -0400
1024 @@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
1025 vdso_base = VDSO32_MBASE;
1028 - current->mm->context.vdso_base = 0;
1029 + current->mm->context.vdso_base = ~0UL;
1031 /* vDSO has a problem and was disabled, just don't "enable" it for the
1033 @@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
1035 down_write(&mm->mmap_sem);
1036 vdso_base = get_unmapped_area(NULL, vdso_base,
1037 - vdso_pages << PAGE_SHIFT, 0, 0);
1038 + vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1039 if (IS_ERR_VALUE(vdso_base)) {
1042 diff -urNp linux-2.6.25.10/arch/powerpc/mm/fault.c linux-2.6.25.10/arch/powerpc/mm/fault.c
1043 --- linux-2.6.25.10/arch/powerpc/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
1044 +++ linux-2.6.25.10/arch/powerpc/mm/fault.c 2008-07-03 16:53:24.000000000 -0400
1046 #include <linux/module.h>
1047 #include <linux/kprobes.h>
1048 #include <linux/kdebug.h>
1049 +#include <linux/binfmts.h>
1050 +#include <linux/slab.h>
1051 +#include <linux/pagemap.h>
1052 +#include <linux/compiler.h>
1053 +#include <linux/binfmts.h>
1054 +#include <linux/unistd.h>
1056 #include <asm/page.h>
1057 #include <asm/pgtable.h>
1058 @@ -62,6 +68,366 @@ static inline int notify_page_fault(stru
1062 +#ifdef CONFIG_PAX_EMUSIGRT
1063 +void pax_syscall_close(struct vm_area_struct *vma)
1065 + vma->vm_mm->call_syscall = 0UL;
1068 +static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1070 + struct page *page;
1071 + unsigned int *kaddr;
1073 + page = alloc_page(GFP_HIGHUSER);
1075 + return NOPAGE_OOM;
1077 + kaddr = kmap(page);
1078 + memset(kaddr, 0, PAGE_SIZE);
1079 + kaddr[0] = 0x44000002U; /* sc */
1080 + __flush_dcache_icache(kaddr);
1083 + *type = VM_FAULT_MAJOR;
1087 +static struct vm_operations_struct pax_vm_ops = {
1088 + .close = pax_syscall_close,
1089 + .nopage = pax_syscall_nopage,
1092 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1096 + vma->vm_mm = current->mm;
1097 + vma->vm_start = addr;
1098 + vma->vm_end = addr + PAGE_SIZE;
1099 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1100 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1101 + vma->vm_ops = &pax_vm_ops;
1103 + ret = insert_vm_struct(current->mm, vma);
1107 + ++current->mm->total_vm;
1112 +#ifdef CONFIG_PAX_PAGEEXEC
1114 + * PaX: decide what to do with offenders (regs->nip = fault address)
1116 + * returns 1 when task should be killed
1117 + * 2 when patched GOT trampoline was detected
1118 + * 3 when patched PLT trampoline was detected
1119 + * 4 when unpatched PLT trampoline was detected
1120 + * 5 when sigreturn trampoline was detected
1121 + * 6 when rt_sigreturn trampoline was detected
1123 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1126 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1130 +#ifdef CONFIG_PAX_EMUPLT
1131 + do { /* PaX: patched GOT emulation */
1132 + unsigned int blrl;
1134 + err = get_user(blrl, (unsigned int *)regs->nip);
1136 + if (!err && blrl == 0x4E800021U) {
1137 + unsigned long temp = regs->nip;
1139 + regs->nip = regs->link & 0xFFFFFFFCUL;
1140 + regs->link = temp + 4UL;
1145 + do { /* PaX: patched PLT emulation #1 */
1148 + err = get_user(b, (unsigned int *)regs->nip);
1150 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
1151 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1156 + do { /* PaX: unpatched PLT emulation #1 */
1157 + unsigned int li, b;
1159 + err = get_user(li, (unsigned int *)regs->nip);
1160 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1162 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1163 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1164 + unsigned long addr = b | 0xFC000000UL;
1166 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1167 + err = get_user(rlwinm, (unsigned int *)addr);
1168 + err |= get_user(add, (unsigned int *)(addr+4));
1169 + err |= get_user(li2, (unsigned int *)(addr+8));
1170 + err |= get_user(addis2, (unsigned int *)(addr+12));
1171 + err |= get_user(mtctr, (unsigned int *)(addr+16));
1172 + err |= get_user(li3, (unsigned int *)(addr+20));
1173 + err |= get_user(addis3, (unsigned int *)(addr+24));
1174 + err |= get_user(bctr, (unsigned int *)(addr+28));
1179 + if (rlwinm == 0x556C083CU &&
1180 + add == 0x7D6C5A14U &&
1181 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1182 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1183 + mtctr == 0x7D8903A6U &&
1184 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1185 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1186 + bctr == 0x4E800420U)
1188 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1189 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1190 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1191 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1192 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1193 + regs->nip = regs->ctr;
1200 + do { /* PaX: unpatched PLT emulation #2 */
1201 + unsigned int lis, lwzu, b, bctr;
1203 + err = get_user(lis, (unsigned int *)regs->nip);
1204 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1205 + err |= get_user(b, (unsigned int *)(regs->nip+8));
1206 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1211 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
1212 + (lwzu & 0xU) == 0xU &&
1213 + (b & 0xFC000003U) == 0x48000000U &&
1214 + bctr == 0x4E800420U)
1216 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1217 + unsigned long addr = b | 0xFC000000UL;
1219 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1220 + err = get_user(addis, (unsigned int *)addr);
1221 + err |= get_user(addi, (unsigned int *)(addr+4));
1222 + err |= get_user(rlwinm, (unsigned int *)(addr+8));
1223 + err |= get_user(add, (unsigned int *)(addr+12));
1224 + err |= get_user(li2, (unsigned int *)(addr+16));
1225 + err |= get_user(addis2, (unsigned int *)(addr+20));
1226 + err |= get_user(mtctr, (unsigned int *)(addr+24));
1227 + err |= get_user(li3, (unsigned int *)(addr+28));
1228 + err |= get_user(addis3, (unsigned int *)(addr+32));
1229 + err |= get_user(bctr, (unsigned int *)(addr+36));
1234 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1235 + (addi & 0xFFFF0000U) == 0x396B0000U &&
1236 + rlwinm == 0x556C083CU &&
1237 + add == 0x7D6C5A14U &&
1238 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1239 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1240 + mtctr == 0x7D8903A6U &&
1241 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1242 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1243 + bctr == 0x4E800420U)
1245 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1246 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1247 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1248 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1249 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1250 + regs->nip = regs->ctr;
1257 + do { /* PaX: unpatched PLT emulation #3 */
1258 + unsigned int li, b;
1260 + err = get_user(li, (unsigned int *)regs->nip);
1261 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1263 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1264 + unsigned int addis, lwz, mtctr, bctr;
1265 + unsigned long addr = b | 0xFC000000UL;
1267 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1268 + err = get_user(addis, (unsigned int *)addr);
1269 + err |= get_user(lwz, (unsigned int *)(addr+4));
1270 + err |= get_user(mtctr, (unsigned int *)(addr+8));
1271 + err |= get_user(bctr, (unsigned int *)(addr+12));
1276 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1277 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
1278 + mtctr == 0x7D6903A6U &&
1279 + bctr == 0x4E800420U)
1283 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1284 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1286 + err = get_user(r11, (unsigned int *)addr);
1290 + regs->gpr[PT_R11] = r11;
1299 +#ifdef CONFIG_PAX_EMUSIGRT
1300 + do { /* PaX: sigreturn emulation */
1301 + unsigned int li, sc;
1303 + err = get_user(li, (unsigned int *)regs->nip);
1304 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1306 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1307 + struct vm_area_struct *vma;
1308 + unsigned long call_syscall;
1310 + down_read(¤t->mm->mmap_sem);
1311 + call_syscall = current->mm->call_syscall;
1312 + up_read(¤t->mm->mmap_sem);
1313 + if (likely(call_syscall))
1316 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1318 + down_write(¤t->mm->mmap_sem);
1319 + if (current->mm->call_syscall) {
1320 + call_syscall = current->mm->call_syscall;
1321 + up_write(¤t->mm->mmap_sem);
1323 + kmem_cache_free(vm_area_cachep, vma);
1327 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1328 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1329 + up_write(¤t->mm->mmap_sem);
1331 + kmem_cache_free(vm_area_cachep, vma);
1335 + if (pax_insert_vma(vma, call_syscall)) {
1336 + up_write(¤t->mm->mmap_sem);
1337 + kmem_cache_free(vm_area_cachep, vma);
1341 + current->mm->call_syscall = call_syscall;
1342 + up_write(¤t->mm->mmap_sem);
1345 + regs->gpr[PT_R0] = __NR_sigreturn;
1346 + regs->nip = call_syscall;
1351 + do { /* PaX: rt_sigreturn emulation */
1352 + unsigned int li, sc;
1354 + err = get_user(li, (unsigned int *)regs->nip);
1355 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1357 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1358 + struct vm_area_struct *vma;
1359 + unsigned int call_syscall;
1361 + down_read(¤t->mm->mmap_sem);
1362 + call_syscall = current->mm->call_syscall;
1363 + up_read(¤t->mm->mmap_sem);
1364 + if (likely(call_syscall))
1367 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1369 + down_write(¤t->mm->mmap_sem);
1370 + if (current->mm->call_syscall) {
1371 + call_syscall = current->mm->call_syscall;
1372 + up_write(¤t->mm->mmap_sem);
1374 + kmem_cache_free(vm_area_cachep, vma);
1378 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1379 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1380 + up_write(¤t->mm->mmap_sem);
1382 + kmem_cache_free(vm_area_cachep, vma);
1386 + if (pax_insert_vma(vma, call_syscall)) {
1387 + up_write(¤t->mm->mmap_sem);
1388 + kmem_cache_free(vm_area_cachep, vma);
1392 + current->mm->call_syscall = call_syscall;
1393 + up_write(¤t->mm->mmap_sem);
1396 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
1397 + regs->nip = call_syscall;
1406 +void pax_report_insns(void *pc, void *sp)
1410 + printk(KERN_ERR "PAX: bytes at PC: ");
1411 + for (i = 0; i < 5; i++) {
1413 + if (get_user(c, (unsigned int *)pc+i))
1414 + printk(KERN_CONT "???????? ");
1416 + printk(KERN_CONT "%08x ", c);
1423 * Check whether the instruction at regs->nip is a store using
1424 * an update addressing form which will update r1.
1425 @@ -157,7 +523,7 @@ int __kprobes do_page_fault(struct pt_re
1426 * indicate errors in DSISR but can validly be set in SRR1.
1429 - error_code &= 0x48200000;
1430 + error_code &= 0x58200000;
1432 is_write = error_code & DSISR_ISSTORE;
1434 @@ -355,6 +721,37 @@ bad_area:
1435 bad_area_nosemaphore:
1436 /* User mode accesses cause a SIGSEGV */
1437 if (user_mode(regs)) {
1439 +#ifdef CONFIG_PAX_PAGEEXEC
1440 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1441 +#ifdef CONFIG_PPC64
1442 + if (is_exec && (error_code & DSISR_PROTFAULT)) {
1444 + if (is_exec && regs->nip == address) {
1446 + switch (pax_handle_fetch_fault(regs)) {
1448 +#ifdef CONFIG_PAX_EMUPLT
1455 +#ifdef CONFIG_PAX_EMUSIGRT
1463 + pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
1464 + do_group_exit(SIGKILL);
1469 _exception(SIGSEGV, regs, code, address);
1472 diff -urNp linux-2.6.25.10/arch/powerpc/mm/mmap.c linux-2.6.25.10/arch/powerpc/mm/mmap.c
1473 --- linux-2.6.25.10/arch/powerpc/mm/mmap.c 2008-07-02 23:46:47.000000000 -0400
1474 +++ linux-2.6.25.10/arch/powerpc/mm/mmap.c 2008-07-03 16:53:24.000000000 -0400
1475 @@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1477 if (mmap_is_legacy()) {
1478 mm->mmap_base = TASK_UNMAPPED_BASE;
1480 +#ifdef CONFIG_PAX_RANDMMAP
1481 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1482 + mm->mmap_base += mm->delta_mmap;
1485 mm->get_unmapped_area = arch_get_unmapped_area;
1486 mm->unmap_area = arch_unmap_area;
1488 mm->mmap_base = mmap_base();
1490 +#ifdef CONFIG_PAX_RANDMMAP
1491 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1492 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1495 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1496 mm->unmap_area = arch_unmap_area_topdown;
1498 diff -urNp linux-2.6.25.10/arch/ppc/mm/fault.c linux-2.6.25.10/arch/ppc/mm/fault.c
1499 --- linux-2.6.25.10/arch/ppc/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
1500 +++ linux-2.6.25.10/arch/ppc/mm/fault.c 2008-07-03 16:53:24.000000000 -0400
1502 #include <linux/interrupt.h>
1503 #include <linux/highmem.h>
1504 #include <linux/module.h>
1505 +#include <linux/slab.h>
1506 +#include <linux/pagemap.h>
1507 +#include <linux/compiler.h>
1508 +#include <linux/binfmts.h>
1509 +#include <linux/unistd.h>
1511 #include <asm/page.h>
1512 #include <asm/pgtable.h>
1513 @@ -48,6 +53,366 @@ unsigned long pte_misses; /* updated by
1514 unsigned long pte_errors; /* updated by do_page_fault() */
1515 unsigned int probingmem;
1517 +#ifdef CONFIG_PAX_EMUSIGRT
1518 +void pax_syscall_close(struct vm_area_struct *vma)
1520 + vma->vm_mm->call_syscall = 0UL;
1523 +static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1525 + struct page *page;
1526 + unsigned int *kaddr;
1528 + page = alloc_page(GFP_HIGHUSER);
1530 + return NOPAGE_OOM;
1532 + kaddr = kmap(page);
1533 + memset(kaddr, 0, PAGE_SIZE);
1534 + kaddr[0] = 0x44000002U; /* sc */
1535 + __flush_dcache_icache(kaddr);
1538 + *type = VM_FAULT_MAJOR;
1542 +static struct vm_operations_struct pax_vm_ops = {
1543 + .close = pax_syscall_close,
1544 + .nopage = pax_syscall_nopage,
1547 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1551 + vma->vm_mm = current->mm;
1552 + vma->vm_start = addr;
1553 + vma->vm_end = addr + PAGE_SIZE;
1554 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1555 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1556 + vma->vm_ops = &pax_vm_ops;
1558 + ret = insert_vm_struct(current->mm, vma);
1562 + ++current->mm->total_vm;
1567 +#ifdef CONFIG_PAX_PAGEEXEC
1569 + * PaX: decide what to do with offenders (regs->nip = fault address)
1571 + * returns 1 when task should be killed
1572 + * 2 when patched GOT trampoline was detected
1573 + * 3 when patched PLT trampoline was detected
1574 + * 4 when unpatched PLT trampoline was detected
1575 + * 5 when sigreturn trampoline was detected
1576 + * 6 when rt_sigreturn trampoline was detected
1578 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1581 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1585 +#ifdef CONFIG_PAX_EMUPLT
1586 + do { /* PaX: patched GOT emulation */
1587 + unsigned int blrl;
1589 + err = get_user(blrl, (unsigned int *)regs->nip);
1591 + if (!err && blrl == 0x4E800021U) {
1592 + unsigned long temp = regs->nip;
1594 + regs->nip = regs->link & 0xFFFFFFFCUL;
1595 + regs->link = temp + 4UL;
1600 + do { /* PaX: patched PLT emulation #1 */
1603 + err = get_user(b, (unsigned int *)regs->nip);
1605 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
1606 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1611 + do { /* PaX: unpatched PLT emulation #1 */
1612 + unsigned int li, b;
1614 + err = get_user(li, (unsigned int *)regs->nip);
1615 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1617 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1618 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1619 + unsigned long addr = b | 0xFC000000UL;
1621 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1622 + err = get_user(rlwinm, (unsigned int *)addr);
1623 + err |= get_user(add, (unsigned int *)(addr+4));
1624 + err |= get_user(li2, (unsigned int *)(addr+8));
1625 + err |= get_user(addis2, (unsigned int *)(addr+12));
1626 + err |= get_user(mtctr, (unsigned int *)(addr+16));
1627 + err |= get_user(li3, (unsigned int *)(addr+20));
1628 + err |= get_user(addis3, (unsigned int *)(addr+24));
1629 + err |= get_user(bctr, (unsigned int *)(addr+28));
1634 + if (rlwinm == 0x556C083CU &&
1635 + add == 0x7D6C5A14U &&
1636 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1637 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1638 + mtctr == 0x7D8903A6U &&
1639 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1640 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1641 + bctr == 0x4E800420U)
1643 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1644 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1645 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1646 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1647 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1648 + regs->nip = regs->ctr;
1655 + do { /* PaX: unpatched PLT emulation #2 */
1656 + unsigned int lis, lwzu, b, bctr;
1658 + err = get_user(lis, (unsigned int *)regs->nip);
1659 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1660 + err |= get_user(b, (unsigned int *)(regs->nip+8));
1661 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1666 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
1667 + (lwzu & 0xU) == 0xU &&
1668 + (b & 0xFC000003U) == 0x48000000U &&
1669 + bctr == 0x4E800420U)
1671 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1672 + unsigned long addr = b | 0xFC000000UL;
1674 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1675 + err = get_user(addis, (unsigned int *)addr);
1676 + err |= get_user(addi, (unsigned int *)(addr+4));
1677 + err |= get_user(rlwinm, (unsigned int *)(addr+8));
1678 + err |= get_user(add, (unsigned int *)(addr+12));
1679 + err |= get_user(li2, (unsigned int *)(addr+16));
1680 + err |= get_user(addis2, (unsigned int *)(addr+20));
1681 + err |= get_user(mtctr, (unsigned int *)(addr+24));
1682 + err |= get_user(li3, (unsigned int *)(addr+28));
1683 + err |= get_user(addis3, (unsigned int *)(addr+32));
1684 + err |= get_user(bctr, (unsigned int *)(addr+36));
1689 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1690 + (addi & 0xFFFF0000U) == 0x396B0000U &&
1691 + rlwinm == 0x556C083CU &&
1692 + add == 0x7D6C5A14U &&
1693 + (li2 & 0xFFFF0000U) == 0x39800000U &&
1694 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1695 + mtctr == 0x7D8903A6U &&
1696 + (li3 & 0xFFFF0000U) == 0x39800000U &&
1697 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1698 + bctr == 0x4E800420U)
1700 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1701 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1702 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1703 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1704 + regs->ctr += (addis2 & 0xFFFFU) << 16;
1705 + regs->nip = regs->ctr;
1712 + do { /* PaX: unpatched PLT emulation #3 */
1713 + unsigned int li, b;
1715 + err = get_user(li, (unsigned int *)regs->nip);
1716 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1718 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1719 + unsigned int addis, lwz, mtctr, bctr;
1720 + unsigned long addr = b | 0xFC000000UL;
1722 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1723 + err = get_user(addis, (unsigned int *)addr);
1724 + err |= get_user(lwz, (unsigned int *)(addr+4));
1725 + err |= get_user(mtctr, (unsigned int *)(addr+8));
1726 + err |= get_user(bctr, (unsigned int *)(addr+12));
1731 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1732 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
1733 + mtctr == 0x7D6903A6U &&
1734 + bctr == 0x4E800420U)
1738 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1739 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1741 + err = get_user(r11, (unsigned int *)addr);
1745 + regs->gpr[PT_R11] = r11;
1754 +#ifdef CONFIG_PAX_EMUSIGRT
1755 + do { /* PaX: sigreturn emulation */
1756 + unsigned int li, sc;
1758 + err = get_user(li, (unsigned int *)regs->nip);
1759 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1761 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1762 + struct vm_area_struct *vma;
1763 + unsigned long call_syscall;
1765 + down_read(¤t->mm->mmap_sem);
1766 + call_syscall = current->mm->call_syscall;
1767 + up_read(¤t->mm->mmap_sem);
1768 + if (likely(call_syscall))
1771 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1773 + down_write(¤t->mm->mmap_sem);
1774 + if (current->mm->call_syscall) {
1775 + call_syscall = current->mm->call_syscall;
1776 + up_write(¤t->mm->mmap_sem);
1778 + kmem_cache_free(vm_area_cachep, vma);
1782 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1783 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1784 + up_write(¤t->mm->mmap_sem);
1786 + kmem_cache_free(vm_area_cachep, vma);
1790 + if (pax_insert_vma(vma, call_syscall)) {
1791 + up_write(¤t->mm->mmap_sem);
1792 + kmem_cache_free(vm_area_cachep, vma);
1796 + current->mm->call_syscall = call_syscall;
1797 + up_write(¤t->mm->mmap_sem);
1800 + regs->gpr[PT_R0] = __NR_sigreturn;
1801 + regs->nip = call_syscall;
1806 + do { /* PaX: rt_sigreturn emulation */
1807 + unsigned int li, sc;
1809 + err = get_user(li, (unsigned int *)regs->nip);
1810 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1812 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1813 + struct vm_area_struct *vma;
1814 + unsigned int call_syscall;
1816 + down_read(¤t->mm->mmap_sem);
1817 + call_syscall = current->mm->call_syscall;
1818 + up_read(¤t->mm->mmap_sem);
1819 + if (likely(call_syscall))
1822 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1824 + down_write(¤t->mm->mmap_sem);
1825 + if (current->mm->call_syscall) {
1826 + call_syscall = current->mm->call_syscall;
1827 + up_write(¤t->mm->mmap_sem);
1829 + kmem_cache_free(vm_area_cachep, vma);
1833 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1834 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1835 + up_write(¤t->mm->mmap_sem);
1837 + kmem_cache_free(vm_area_cachep, vma);
1841 + if (pax_insert_vma(vma, call_syscall)) {
1842 + up_write(¤t->mm->mmap_sem);
1843 + kmem_cache_free(vm_area_cachep, vma);
1847 + current->mm->call_syscall = call_syscall;
1848 + up_write(¤t->mm->mmap_sem);
1851 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
1852 + regs->nip = call_syscall;
1861 +void pax_report_insns(void *pc, void *sp)
1865 + printk(KERN_ERR "PAX: bytes at PC: ");
1866 + for (i = 0; i < 5; i++) {
1868 + if (get_user(c, (unsigned int *)pc+i))
1869 + printk(KERN_CONT "???????? ");
1871 + printk(KERN_CONT "%08x ", c);
1878 * Check whether the instruction at regs->nip is a store using
1879 * an update addressing form which will update r1.
1880 @@ -109,7 +474,7 @@ int do_page_fault(struct pt_regs *regs,
1881 * indicate errors in DSISR but can validly be set in SRR1.
1883 if (TRAP(regs) == 0x400)
1884 - error_code &= 0x48200000;
1885 + error_code &= 0x58200000;
1887 is_write = error_code & 0x02000000;
1888 #endif /* CONFIG_4xx || CONFIG_BOOKE */
1889 @@ -204,15 +569,14 @@ good_area:
1895 /* It would be nice to actually enforce the VM execute
1896 permission on CPUs which can do so, but far too
1897 much stuff in userspace doesn't get the permissions
1898 right, so we let any page be executed for now. */
1899 if (! (vma->vm_flags & VM_EXEC))
1904 /* Since 4xx/Book-E supports per-page execute permission,
1905 * we lazily flush dcache to icache. */
1907 @@ -235,6 +599,7 @@ good_area:
1908 pte_unmap_unlock(ptep, ptl);
1914 /* protection fault */
1915 @@ -278,6 +643,33 @@ bad_area:
1917 /* User mode accesses cause a SIGSEGV */
1918 if (user_mode(regs)) {
1920 +#ifdef CONFIG_PAX_PAGEEXEC
1921 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1922 + if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
1923 + switch (pax_handle_fetch_fault(regs)) {
1925 +#ifdef CONFIG_PAX_EMUPLT
1932 +#ifdef CONFIG_PAX_EMUSIGRT
1940 + pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
1941 + do_group_exit(SIGKILL);
1946 _exception(SIGSEGV, regs, code, address);
1949 diff -urNp linux-2.6.25.10/arch/s390/kernel/module.c linux-2.6.25.10/arch/s390/kernel/module.c
1950 --- linux-2.6.25.10/arch/s390/kernel/module.c 2008-07-02 23:46:47.000000000 -0400
1951 +++ linux-2.6.25.10/arch/s390/kernel/module.c 2008-07-03 16:53:24.000000000 -0400
1952 @@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
1954 /* Increase core size by size of got & plt and set start
1955 offsets for got and plt. */
1956 - me->core_size = ALIGN(me->core_size, 4);
1957 - me->arch.got_offset = me->core_size;
1958 - me->core_size += me->arch.got_size;
1959 - me->arch.plt_offset = me->core_size;
1960 - me->core_size += me->arch.plt_size;
1961 + me->core_size_rw = ALIGN(me->core_size_rw, 4);
1962 + me->arch.got_offset = me->core_size_rw;
1963 + me->core_size_rw += me->arch.got_size;
1964 + me->arch.plt_offset = me->core_size_rx;
1965 + me->core_size_rx += me->arch.plt_size;
1969 @@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1970 if (info->got_initialized == 0) {
1973 - gotent = me->module_core + me->arch.got_offset +
1974 + gotent = me->module_core_rw + me->arch.got_offset +
1977 info->got_initialized = 1;
1978 @@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1979 else if (r_type == R_390_GOTENT ||
1980 r_type == R_390_GOTPLTENT)
1981 *(unsigned int *) loc =
1982 - (val + (Elf_Addr) me->module_core - loc) >> 1;
1983 + (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
1984 else if (r_type == R_390_GOT64 ||
1985 r_type == R_390_GOTPLT64)
1986 *(unsigned long *) loc = val;
1987 @@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1988 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
1989 if (info->plt_initialized == 0) {
1991 - ip = me->module_core + me->arch.plt_offset +
1992 + ip = me->module_core_rx + me->arch.plt_offset +
1994 #ifndef CONFIG_64BIT
1995 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
1996 @@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1997 val = me->arch.plt_offset - me->arch.got_offset +
1998 info->plt_offset + rela->r_addend;
2000 - val = (Elf_Addr) me->module_core +
2001 + val = (Elf_Addr) me->module_core_rx +
2002 me->arch.plt_offset + info->plt_offset +
2003 rela->r_addend - loc;
2004 if (r_type == R_390_PLT16DBL)
2005 @@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2006 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
2007 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
2008 val = val + rela->r_addend -
2009 - ((Elf_Addr) me->module_core + me->arch.got_offset);
2010 + ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
2011 if (r_type == R_390_GOTOFF16)
2012 *(unsigned short *) loc = val;
2013 else if (r_type == R_390_GOTOFF32)
2014 @@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2016 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
2017 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
2018 - val = (Elf_Addr) me->module_core + me->arch.got_offset +
2019 + val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
2020 rela->r_addend - loc;
2021 if (r_type == R_390_GOTPC)
2022 *(unsigned int *) loc = val;
2023 diff -urNp linux-2.6.25.10/arch/sparc/kernel/sys_sparc.c linux-2.6.25.10/arch/sparc/kernel/sys_sparc.c
2024 --- linux-2.6.25.10/arch/sparc/kernel/sys_sparc.c 2008-07-02 23:46:47.000000000 -0400
2025 +++ linux-2.6.25.10/arch/sparc/kernel/sys_sparc.c 2008-07-03 16:53:24.000000000 -0400
2026 @@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
2027 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
2030 - addr = TASK_UNMAPPED_BASE;
2031 + addr = current->mm->mmap_base;
2033 if (flags & MAP_SHARED)
2034 addr = COLOUR_ALIGN(addr);
2035 diff -urNp linux-2.6.25.10/arch/sparc/Makefile linux-2.6.25.10/arch/sparc/Makefile
2036 --- linux-2.6.25.10/arch/sparc/Makefile 2008-07-02 23:46:47.000000000 -0400
2037 +++ linux-2.6.25.10/arch/sparc/Makefile 2008-07-03 16:53:24.000000000 -0400
2038 @@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
2039 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
2040 INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
2042 -CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
2043 +CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
2044 CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
2045 DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
2046 NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
2047 diff -urNp linux-2.6.25.10/arch/sparc/mm/fault.c linux-2.6.25.10/arch/sparc/mm/fault.c
2048 --- linux-2.6.25.10/arch/sparc/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
2049 +++ linux-2.6.25.10/arch/sparc/mm/fault.c 2008-07-03 16:53:24.000000000 -0400
2051 #include <linux/interrupt.h>
2052 #include <linux/module.h>
2053 #include <linux/kdebug.h>
2054 +#include <linux/slab.h>
2055 +#include <linux/pagemap.h>
2056 +#include <linux/compiler.h>
2057 +#include <linux/binfmts.h>
2059 #include <asm/system.h>
2060 #include <asm/page.h>
2061 @@ -216,6 +220,253 @@ static unsigned long compute_si_addr(str
2062 return safe_compute_effective_address(regs, insn);
2065 +#ifdef CONFIG_PAX_PAGEEXEC
2066 +void pax_emuplt_close(struct vm_area_struct *vma)
2068 + vma->vm_mm->call_dl_resolve = 0UL;
2071 +static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2073 + struct page *page;
2074 + unsigned int *kaddr;
2076 + page = alloc_page(GFP_HIGHUSER);
2078 + return NOPAGE_OOM;
2080 + kaddr = kmap(page);
2081 + memset(kaddr, 0, PAGE_SIZE);
2082 + kaddr[0] = 0x9DE3BFA8U; /* save */
2083 + flush_dcache_page(page);
2086 + *type = VM_FAULT_MAJOR;
2091 +static struct vm_operations_struct pax_vm_ops = {
2092 + .close = pax_emuplt_close,
2093 + .nopage = pax_emuplt_nopage,
2096 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2100 + vma->vm_mm = current->mm;
2101 + vma->vm_start = addr;
2102 + vma->vm_end = addr + PAGE_SIZE;
2103 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2104 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2105 + vma->vm_ops = &pax_vm_ops;
2107 + ret = insert_vm_struct(current->mm, vma);
2111 + ++current->mm->total_vm;
2116 + * PaX: decide what to do with offenders (regs->pc = fault address)
2118 + * returns 1 when task should be killed
2119 + * 2 when patched PLT trampoline was detected
2120 + * 3 when unpatched PLT trampoline was detected
2122 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2125 +#ifdef CONFIG_PAX_EMUPLT
2128 + do { /* PaX: patched PLT emulation #1 */
2129 + unsigned int sethi1, sethi2, jmpl;
2131 + err = get_user(sethi1, (unsigned int *)regs->pc);
2132 + err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
2133 + err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
2138 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2139 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2140 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2142 + unsigned int addr;
2144 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2145 + addr = regs->u_regs[UREG_G1];
2146 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2148 + regs->npc = addr+4;
2153 + { /* PaX: patched PLT emulation #2 */
2156 + err = get_user(ba, (unsigned int *)regs->pc);
2158 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2159 + unsigned int addr;
2161 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2163 + regs->npc = addr+4;
2168 + do { /* PaX: patched PLT emulation #3 */
2169 + unsigned int sethi, jmpl, nop;
2171 + err = get_user(sethi, (unsigned int *)regs->pc);
2172 + err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
2173 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
2178 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2179 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2180 + nop == 0x01000000U)
2182 + unsigned int addr;
2184 + addr = (sethi & 0x003FFFFFU) << 10;
2185 + regs->u_regs[UREG_G1] = addr;
2186 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2188 + regs->npc = addr+4;
2193 + do { /* PaX: unpatched PLT emulation step 1 */
2194 + unsigned int sethi, ba, nop;
2196 + err = get_user(sethi, (unsigned int *)regs->pc);
2197 + err |= get_user(ba, (unsigned int *)(regs->pc+4));
2198 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
2203 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2204 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2205 + nop == 0x01000000U)
2207 + unsigned int addr, save, call;
2209 + if ((ba & 0xFFC00000U) == 0x30800000U)
2210 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2212 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2214 + err = get_user(save, (unsigned int *)addr);
2215 + err |= get_user(call, (unsigned int *)(addr+4));
2216 + err |= get_user(nop, (unsigned int *)(addr+8));
2220 + if (save == 0x9DE3BFA8U &&
2221 + (call & 0xC0000000U) == 0x40000000U &&
2222 + nop == 0x01000000U)
2224 + struct vm_area_struct *vma;
2225 + unsigned long call_dl_resolve;
2227 + down_read(¤t->mm->mmap_sem);
2228 + call_dl_resolve = current->mm->call_dl_resolve;
2229 + up_read(¤t->mm->mmap_sem);
2230 + if (likely(call_dl_resolve))
2233 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2235 + down_write(¤t->mm->mmap_sem);
2236 + if (current->mm->call_dl_resolve) {
2237 + call_dl_resolve = current->mm->call_dl_resolve;
2238 + up_write(¤t->mm->mmap_sem);
2240 + kmem_cache_free(vm_area_cachep, vma);
2244 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2245 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2246 + up_write(¤t->mm->mmap_sem);
2248 + kmem_cache_free(vm_area_cachep, vma);
2252 + if (pax_insert_vma(vma, call_dl_resolve)) {
2253 + up_write(¤t->mm->mmap_sem);
2254 + kmem_cache_free(vm_area_cachep, vma);
2258 + current->mm->call_dl_resolve = call_dl_resolve;
2259 + up_write(¤t->mm->mmap_sem);
2262 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2263 + regs->pc = call_dl_resolve;
2264 + regs->npc = addr+4;
2270 + do { /* PaX: unpatched PLT emulation step 2 */
2271 + unsigned int save, call, nop;
2273 + err = get_user(save, (unsigned int *)(regs->pc-4));
2274 + err |= get_user(call, (unsigned int *)regs->pc);
2275 + err |= get_user(nop, (unsigned int *)(regs->pc+4));
2279 + if (save == 0x9DE3BFA8U &&
2280 + (call & 0xC0000000U) == 0x40000000U &&
2281 + nop == 0x01000000U)
2283 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2285 + regs->u_regs[UREG_RETPC] = regs->pc;
2286 + regs->pc = dl_resolve;
2287 + regs->npc = dl_resolve+4;
2296 +void pax_report_insns(void *pc, void *sp)
2300 + printk(KERN_ERR "PAX: bytes at PC: ");
2301 + for (i = 0; i < 5; i++) {
2303 + if (get_user(c, (unsigned int *)pc+i))
2304 + printk(KERN_CONT "???????? ");
2306 + printk(KERN_CONT "%08x ", c);
2312 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2313 unsigned long address)
2315 @@ -280,6 +531,24 @@ good_area:
2316 if(!(vma->vm_flags & VM_WRITE))
2320 +#ifdef CONFIG_PAX_PAGEEXEC
2321 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
2322 + up_read(&mm->mmap_sem);
2323 + switch (pax_handle_fetch_fault(regs)) {
2325 +#ifdef CONFIG_PAX_EMUPLT
2332 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2333 + do_group_exit(SIGKILL);
2337 /* Allow reads even for write-only mappings */
2338 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2340 diff -urNp linux-2.6.25.10/arch/sparc/mm/init.c linux-2.6.25.10/arch/sparc/mm/init.c
2341 --- linux-2.6.25.10/arch/sparc/mm/init.c 2008-07-02 23:46:47.000000000 -0400
2342 +++ linux-2.6.25.10/arch/sparc/mm/init.c 2008-07-03 16:53:24.000000000 -0400
2343 @@ -311,6 +311,9 @@ extern void device_scan(void);
2344 pgprot_t PAGE_SHARED __read_mostly;
2345 EXPORT_SYMBOL(PAGE_SHARED);
2347 +pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
2348 +EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
2350 void __init paging_init(void)
2352 switch(sparc_cpu_model) {
2353 @@ -336,17 +339,17 @@ void __init paging_init(void)
2355 /* Initialize the protection map with non-constant, MMU dependent values. */
2356 protection_map[0] = PAGE_NONE;
2357 - protection_map[1] = PAGE_READONLY;
2358 - protection_map[2] = PAGE_COPY;
2359 - protection_map[3] = PAGE_COPY;
2360 + protection_map[1] = PAGE_READONLY_NOEXEC;
2361 + protection_map[2] = PAGE_COPY_NOEXEC;
2362 + protection_map[3] = PAGE_COPY_NOEXEC;
2363 protection_map[4] = PAGE_READONLY;
2364 protection_map[5] = PAGE_READONLY;
2365 protection_map[6] = PAGE_COPY;
2366 protection_map[7] = PAGE_COPY;
2367 protection_map[8] = PAGE_NONE;
2368 - protection_map[9] = PAGE_READONLY;
2369 - protection_map[10] = PAGE_SHARED;
2370 - protection_map[11] = PAGE_SHARED;
2371 + protection_map[9] = PAGE_READONLY_NOEXEC;
2372 + protection_map[10] = PAGE_SHARED_NOEXEC;
2373 + protection_map[11] = PAGE_SHARED_NOEXEC;
2374 protection_map[12] = PAGE_READONLY;
2375 protection_map[13] = PAGE_READONLY;
2376 protection_map[14] = PAGE_SHARED;
2377 diff -urNp linux-2.6.25.10/arch/sparc/mm/srmmu.c linux-2.6.25.10/arch/sparc/mm/srmmu.c
2378 --- linux-2.6.25.10/arch/sparc/mm/srmmu.c 2008-07-02 23:46:47.000000000 -0400
2379 +++ linux-2.6.25.10/arch/sparc/mm/srmmu.c 2008-07-03 16:53:24.000000000 -0400
2380 @@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
2381 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
2382 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
2383 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
2385 +#ifdef CONFIG_PAX_PAGEEXEC
2386 + PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2387 + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2388 + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2391 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2392 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2394 diff -urNp linux-2.6.25.10/arch/sparc64/kernel/Makefile linux-2.6.25.10/arch/sparc64/kernel/Makefile
2395 --- linux-2.6.25.10/arch/sparc64/kernel/Makefile 2008-07-02 23:46:47.000000000 -0400
2396 +++ linux-2.6.25.10/arch/sparc64/kernel/Makefile 2008-07-03 16:53:24.000000000 -0400
2400 EXTRA_AFLAGS := -ansi
2401 -EXTRA_CFLAGS := -Werror
2402 +#EXTRA_CFLAGS := -Werror
2404 extra-y := head.o init_task.o vmlinux.lds
2406 diff -urNp linux-2.6.25.10/arch/sparc64/kernel/sys_sparc.c linux-2.6.25.10/arch/sparc64/kernel/sys_sparc.c
2407 --- linux-2.6.25.10/arch/sparc64/kernel/sys_sparc.c 2008-07-02 23:46:47.000000000 -0400
2408 +++ linux-2.6.25.10/arch/sparc64/kernel/sys_sparc.c 2008-07-03 16:53:24.000000000 -0400
2409 @@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
2410 /* We do not accept a shared mapping if it would violate
2411 * cache aliasing constraints.
2413 - if ((flags & MAP_SHARED) &&
2414 + if ((filp || (flags & MAP_SHARED)) &&
2415 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2418 @@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
2419 if (filp || (flags & MAP_SHARED))
2422 +#ifdef CONFIG_PAX_RANDMMAP
2423 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2428 addr = COLOUR_ALIGN(addr, pgoff);
2429 @@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
2432 if (len > mm->cached_hole_size) {
2433 - start_addr = addr = mm->free_area_cache;
2434 + start_addr = addr = mm->free_area_cache;
2436 - start_addr = addr = TASK_UNMAPPED_BASE;
2437 + start_addr = addr = mm->mmap_base;
2438 mm->cached_hole_size = 0;
2441 @@ -174,8 +178,8 @@ full_search:
2442 vma = find_vma(mm, VA_EXCLUDE_END);
2444 if (unlikely(task_size < addr)) {
2445 - if (start_addr != TASK_UNMAPPED_BASE) {
2446 - start_addr = addr = TASK_UNMAPPED_BASE;
2447 + if (start_addr != mm->mmap_base) {
2448 + start_addr = addr = mm->mmap_base;
2449 mm->cached_hole_size = 0;
2452 @@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
2453 /* We do not accept a shared mapping if it would violate
2454 * cache aliasing constraints.
2456 - if ((flags & MAP_SHARED) &&
2457 + if ((filp || (flags & MAP_SHARED)) &&
2458 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2461 @@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
2462 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2463 sysctl_legacy_va_layout) {
2464 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2466 +#ifdef CONFIG_PAX_RANDMMAP
2467 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2468 + mm->mmap_base += mm->delta_mmap;
2471 mm->get_unmapped_area = arch_get_unmapped_area;
2472 mm->unmap_area = arch_unmap_area;
2474 @@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
2475 gap = (task_size / 6 * 5);
2477 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2479 +#ifdef CONFIG_PAX_RANDMMAP
2480 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2481 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2484 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2485 mm->unmap_area = arch_unmap_area_topdown;
2487 diff -urNp linux-2.6.25.10/arch/sparc64/mm/fault.c linux-2.6.25.10/arch/sparc64/mm/fault.c
2488 --- linux-2.6.25.10/arch/sparc64/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
2489 +++ linux-2.6.25.10/arch/sparc64/mm/fault.c 2008-07-03 16:53:24.000000000 -0400
2491 #include <linux/kprobes.h>
2492 #include <linux/kallsyms.h>
2493 #include <linux/kdebug.h>
2494 +#include <linux/slab.h>
2495 +#include <linux/pagemap.h>
2496 +#include <linux/compiler.h>
2497 +#include <linux/binfmts.h>
2499 #include <asm/page.h>
2500 #include <asm/pgtable.h>
2501 @@ -262,6 +266,370 @@ cannot_handle:
2502 unhandled_fault (address, current, regs);
2505 +#ifdef CONFIG_PAX_PAGEEXEC
2506 +#ifdef CONFIG_PAX_EMUPLT
2507 +static void pax_emuplt_close(struct vm_area_struct *vma)
2509 + vma->vm_mm->call_dl_resolve = 0UL;
2512 +static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2514 + struct page *page;
2515 + unsigned int *kaddr;
2517 + page = alloc_page(GFP_HIGHUSER);
2519 + return NOPAGE_OOM;
2521 + kaddr = kmap(page);
2522 + memset(kaddr, 0, PAGE_SIZE);
2523 + kaddr[0] = 0x9DE3BFA8U; /* save */
2524 + flush_dcache_page(page);
2527 + *type = VM_FAULT_MAJOR;
2531 +static struct vm_operations_struct pax_vm_ops = {
2532 + .close = pax_emuplt_close,
2533 + .nopage = pax_emuplt_nopage,
2536 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2540 + vma->vm_mm = current->mm;
2541 + vma->vm_start = addr;
2542 + vma->vm_end = addr + PAGE_SIZE;
2543 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2544 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2545 + vma->vm_ops = &pax_vm_ops;
2547 + ret = insert_vm_struct(current->mm, vma);
2551 + ++current->mm->total_vm;
2557 + * PaX: decide what to do with offenders (regs->tpc = fault address)
2559 + * returns 1 when task should be killed
2560 + * 2 when patched PLT trampoline was detected
2561 + * 3 when unpatched PLT trampoline was detected
2563 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2566 +#ifdef CONFIG_PAX_EMUPLT
2569 + do { /* PaX: patched PLT emulation #1 */
2570 + unsigned int sethi1, sethi2, jmpl;
2572 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2573 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2574 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
2579 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2580 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2581 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2583 + unsigned long addr;
2585 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2586 + addr = regs->u_regs[UREG_G1];
2587 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2589 + regs->tnpc = addr+4;
2594 + { /* PaX: patched PLT emulation #2 */
2597 + err = get_user(ba, (unsigned int *)regs->tpc);
2599 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2600 + unsigned long addr;
2602 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2604 + regs->tnpc = addr+4;
2609 + do { /* PaX: patched PLT emulation #3 */
2610 + unsigned int sethi, jmpl, nop;
2612 + err = get_user(sethi, (unsigned int *)regs->tpc);
2613 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
2614 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2619 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2620 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2621 + nop == 0x01000000U)
2623 + unsigned long addr;
2625 + addr = (sethi & 0x003FFFFFU) << 10;
2626 + regs->u_regs[UREG_G1] = addr;
2627 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2629 + regs->tnpc = addr+4;
2634 + do { /* PaX: patched PLT emulation #4 */
2635 + unsigned int mov1, call, mov2;
2637 + err = get_user(mov1, (unsigned int *)regs->tpc);
2638 + err |= get_user(call, (unsigned int *)(regs->tpc+4));
2639 + err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
2644 + if (mov1 == 0x8210000FU &&
2645 + (call & 0xC0000000U) == 0x40000000U &&
2646 + mov2 == 0x9E100001U)
2648 + unsigned long addr;
2650 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2651 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2653 + regs->tnpc = addr+4;
2658 + do { /* PaX: patched PLT emulation #5 */
2659 + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
2661 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2662 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2663 + err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2664 + err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2665 + err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2666 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2667 + err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2672 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2673 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2674 + (or1 & 0xFFFFE000U) == 0x82106000U &&
2675 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
2676 + sllx == 0x83287020 &&
2677 + jmpl == 0x81C04005U &&
2678 + nop == 0x01000000U)
2680 + unsigned long addr;
2682 + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2683 + regs->u_regs[UREG_G1] <<= 32;
2684 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2685 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2687 + regs->tnpc = addr+4;
2692 + do { /* PaX: patched PLT emulation #6 */
2693 + unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
2695 + err = get_user(sethi1, (unsigned int *)regs->tpc);
2696 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2697 + err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2698 + err |= get_user(or, (unsigned int *)(regs->tpc+12));
2699 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2700 + err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2705 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2706 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2707 + sllx == 0x83287020 &&
2708 + (or & 0xFFFFE000U) == 0x8A116000U &&
2709 + jmpl == 0x81C04005U &&
2710 + nop == 0x01000000U)
2712 + unsigned long addr;
2714 + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2715 + regs->u_regs[UREG_G1] <<= 32;
2716 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2717 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2719 + regs->tnpc = addr+4;
2724 + do { /* PaX: patched PLT emulation #7 */
2725 + unsigned int sethi, ba, nop;
2727 + err = get_user(sethi, (unsigned int *)regs->tpc);
2728 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2729 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2734 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2735 + (ba & 0xFFF00000U) == 0x30600000U &&
2736 + nop == 0x01000000U)
2738 + unsigned long addr;
2740 + addr = (sethi & 0x003FFFFFU) << 10;
2741 + regs->u_regs[UREG_G1] = addr;
2742 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2744 + regs->tnpc = addr+4;
2749 + do { /* PaX: unpatched PLT emulation step 1 */
2750 + unsigned int sethi, ba, nop;
2752 + err = get_user(sethi, (unsigned int *)regs->tpc);
2753 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2754 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2759 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2760 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2761 + nop == 0x01000000U)
2763 + unsigned long addr;
2764 + unsigned int save, call;
2766 + if ((ba & 0xFFC00000U) == 0x30800000U)
2767 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2769 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2771 + err = get_user(save, (unsigned int *)addr);
2772 + err |= get_user(call, (unsigned int *)(addr+4));
2773 + err |= get_user(nop, (unsigned int *)(addr+8));
2777 + if (save == 0x9DE3BFA8U &&
2778 + (call & 0xC0000000U) == 0x40000000U &&
2779 + nop == 0x01000000U)
2781 + struct vm_area_struct *vma;
2782 + unsigned long call_dl_resolve;
2784 + down_read(¤t->mm->mmap_sem);
2785 + call_dl_resolve = current->mm->call_dl_resolve;
2786 + up_read(¤t->mm->mmap_sem);
2787 + if (likely(call_dl_resolve))
2790 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2792 + down_write(¤t->mm->mmap_sem);
2793 + if (current->mm->call_dl_resolve) {
2794 + call_dl_resolve = current->mm->call_dl_resolve;
2795 + up_write(¤t->mm->mmap_sem);
2797 + kmem_cache_free(vm_area_cachep, vma);
2801 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2802 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2803 + up_write(¤t->mm->mmap_sem);
2805 + kmem_cache_free(vm_area_cachep, vma);
2809 + if (pax_insert_vma(vma, call_dl_resolve)) {
2810 + up_write(¤t->mm->mmap_sem);
2811 + kmem_cache_free(vm_area_cachep, vma);
2815 + current->mm->call_dl_resolve = call_dl_resolve;
2816 + up_write(¤t->mm->mmap_sem);
2819 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2820 + regs->tpc = call_dl_resolve;
2821 + regs->tnpc = addr+4;
2827 + do { /* PaX: unpatched PLT emulation step 2 */
2828 + unsigned int save, call, nop;
2830 + err = get_user(save, (unsigned int *)(regs->tpc-4));
2831 + err |= get_user(call, (unsigned int *)regs->tpc);
2832 + err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2836 + if (save == 0x9DE3BFA8U &&
2837 + (call & 0xC0000000U) == 0x40000000U &&
2838 + nop == 0x01000000U)
2840 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2842 + regs->u_regs[UREG_RETPC] = regs->tpc;
2843 + regs->tpc = dl_resolve;
2844 + regs->tnpc = dl_resolve+4;
2853 +void pax_report_insns(void *pc, void *sp)
2857 + printk(KERN_ERR "PAX: bytes at PC: ");
2858 + for (i = 0; i < 5; i++) {
2860 + if (get_user(c, (unsigned int *)pc+i))
2861 + printk(KERN_CONT "???????? ");
2863 + printk(KERN_CONT "%08x ", c);
2869 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2871 struct mm_struct *mm = current->mm;
2872 @@ -303,8 +671,10 @@ asmlinkage void __kprobes do_sparc64_fau
2875 if (test_thread_flag(TIF_32BIT)) {
2876 - if (!(regs->tstate & TSTATE_PRIV))
2877 + if (!(regs->tstate & TSTATE_PRIV)) {
2878 regs->tpc &= 0xffffffff;
2879 + regs->tnpc &= 0xffffffff;
2881 address &= 0xffffffff;
2884 @@ -321,6 +691,29 @@ asmlinkage void __kprobes do_sparc64_fau
2888 +#ifdef CONFIG_PAX_PAGEEXEC
2889 + /* PaX: detect ITLB misses on non-exec pages */
2890 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2891 + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2893 + if (address != regs->tpc)
2896 + up_read(&mm->mmap_sem);
2897 + switch (pax_handle_fetch_fault(regs)) {
2899 +#ifdef CONFIG_PAX_EMUPLT
2906 + pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
2907 + do_group_exit(SIGKILL);
2911 /* Pure DTLB misses do not tell us whether the fault causing
2912 * load/store/atomic was a write or not, it only says that there
2913 * was no match. So in such a case we (carefully) read the
2914 diff -urNp linux-2.6.25.10/arch/sparc64/mm/Makefile linux-2.6.25.10/arch/sparc64/mm/Makefile
2915 --- linux-2.6.25.10/arch/sparc64/mm/Makefile 2008-07-02 23:46:47.000000000 -0400
2916 +++ linux-2.6.25.10/arch/sparc64/mm/Makefile 2008-07-03 16:53:24.000000000 -0400
2920 EXTRA_AFLAGS := -ansi
2921 -EXTRA_CFLAGS := -Werror
2922 +#EXTRA_CFLAGS := -Werror
2924 obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
2926 diff -urNp linux-2.6.25.10/arch/v850/kernel/module.c linux-2.6.25.10/arch/v850/kernel/module.c
2927 --- linux-2.6.25.10/arch/v850/kernel/module.c 2008-07-02 23:46:47.000000000 -0400
2928 +++ linux-2.6.25.10/arch/v850/kernel/module.c 2008-07-03 16:53:24.000000000 -0400
2929 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
2930 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
2932 /* Init, or core PLT? */
2933 - if (location >= mod->module_core
2934 - && location < mod->module_core + mod->core_size)
2935 + if (location >= mod->module_core_rx
2936 + && location < mod->module_core_rx + mod->core_size_rx)
2937 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
2939 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
2940 diff -urNp linux-2.6.25.10/arch/x86/boot/bitops.h linux-2.6.25.10/arch/x86/boot/bitops.h
2941 --- linux-2.6.25.10/arch/x86/boot/bitops.h 2008-07-02 23:46:47.000000000 -0400
2942 +++ linux-2.6.25.10/arch/x86/boot/bitops.h 2008-07-03 16:53:24.000000000 -0400
2943 @@ -28,7 +28,7 @@ static inline int variable_test_bit(int
2945 const u32 *p = (const u32 *)addr;
2947 - asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2948 + asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2952 @@ -39,7 +39,7 @@ static inline int variable_test_bit(int
2954 static inline void set_bit(int nr, void *addr)
2956 - asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2957 + asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2960 #endif /* BOOT_BITOPS_H */
2961 diff -urNp linux-2.6.25.10/arch/x86/boot/boot.h linux-2.6.25.10/arch/x86/boot/boot.h
2962 --- linux-2.6.25.10/arch/x86/boot/boot.h 2008-07-02 23:46:47.000000000 -0400
2963 +++ linux-2.6.25.10/arch/x86/boot/boot.h 2008-07-03 16:53:24.000000000 -0400
2964 @@ -78,7 +78,7 @@ static inline void io_delay(void)
2965 static inline u16 ds(void)
2968 - asm("movw %%ds,%0" : "=rm" (seg));
2969 + asm volatile("movw %%ds,%0" : "=rm" (seg));
2973 @@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t
2974 static inline int memcmp(const void *s1, const void *s2, size_t len)
2977 - asm("repe; cmpsb; setnz %0"
2978 + asm volatile("repe; cmpsb; setnz %0"
2979 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
2982 diff -urNp linux-2.6.25.10/arch/x86/boot/compressed/head_32.S linux-2.6.25.10/arch/x86/boot/compressed/head_32.S
2983 --- linux-2.6.25.10/arch/x86/boot/compressed/head_32.S 2008-07-02 23:46:47.000000000 -0400
2984 +++ linux-2.6.25.10/arch/x86/boot/compressed/head_32.S 2008-07-03 16:53:24.000000000 -0400
2985 @@ -70,7 +70,7 @@ startup_32:
2986 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
2987 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
2989 - movl $LOAD_PHYSICAL_ADDR, %ebx
2990 + movl $____LOAD_PHYSICAL_ADDR, %ebx
2993 /* Replace the compressed data size with the uncompressed size */
2994 @@ -105,7 +105,7 @@ startup_32:
2995 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
2996 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
2998 - movl $LOAD_PHYSICAL_ADDR, %ebp
2999 + movl $____LOAD_PHYSICAL_ADDR, %ebp
3003 @@ -159,16 +159,15 @@ relocated:
3004 * and where it was actually loaded.
3007 - subl $LOAD_PHYSICAL_ADDR, %ebx
3008 + subl $____LOAD_PHYSICAL_ADDR, %ebx
3009 jz 2f /* Nothing to be done if loaded at compiled addr. */
3011 * Process relocations.
3015 - movl 0(%edi), %ecx
3020 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
3023 diff -urNp linux-2.6.25.10/arch/x86/boot/compressed/misc.c linux-2.6.25.10/arch/x86/boot/compressed/misc.c
3024 --- linux-2.6.25.10/arch/x86/boot/compressed/misc.c 2008-07-02 23:46:47.000000000 -0400
3025 +++ linux-2.6.25.10/arch/x86/boot/compressed/misc.c 2008-07-03 16:53:24.000000000 -0400
3026 @@ -122,7 +122,8 @@ typedef unsigned char uch;
3027 typedef unsigned short ush;
3028 typedef unsigned long ulg;
3030 -#define WSIZE 0x80000000 /* Window size must be at least 32k,
3031 +#define WSIZE 0x80000000
3032 + /* Window size must be at least 32k,
3033 * and a power of two
3034 * We don't actually have a window just
3035 * a huge output buffer so I report
3036 @@ -400,7 +401,7 @@ asmlinkage void decompress_kernel(void *
3037 if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
3038 error("Destination address too large");
3039 #ifndef CONFIG_RELOCATABLE
3040 - if ((u32)output != LOAD_PHYSICAL_ADDR)
3041 + if ((u32)output != ____LOAD_PHYSICAL_ADDR)
3042 error("Wrong destination address");
3045 diff -urNp linux-2.6.25.10/arch/x86/boot/compressed/relocs.c linux-2.6.25.10/arch/x86/boot/compressed/relocs.c
3046 --- linux-2.6.25.10/arch/x86/boot/compressed/relocs.c 2008-07-02 23:46:47.000000000 -0400
3047 +++ linux-2.6.25.10/arch/x86/boot/compressed/relocs.c 2008-07-03 16:53:24.000000000 -0400
3052 +#include "../../../../include/linux/autoconf.h"
3054 +#define MAX_PHDRS 100
3055 #define MAX_SHDRS 100
3056 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3057 static Elf32_Ehdr ehdr;
3058 +static Elf32_Phdr phdr[MAX_PHDRS];
3059 static Elf32_Shdr shdr[MAX_SHDRS];
3060 static Elf32_Sym *symtab[MAX_SHDRS];
3061 static Elf32_Rel *reltab[MAX_SHDRS];
3062 @@ -241,6 +245,34 @@ static void read_ehdr(FILE *fp)
3066 +static void read_phdrs(FILE *fp)
3069 + if (ehdr.e_phnum > MAX_PHDRS) {
3070 + die("%d program headers supported: %d\n",
3071 + ehdr.e_phnum, MAX_PHDRS);
3073 + if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3074 + die("Seek to %d failed: %s\n",
3075 + ehdr.e_phoff, strerror(errno));
3077 + if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3078 + die("Cannot read ELF program headers: %s\n",
3081 + for(i = 0; i < ehdr.e_phnum; i++) {
3082 + phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
3083 + phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
3084 + phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
3085 + phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
3086 + phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
3087 + phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
3088 + phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
3089 + phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
3094 static void read_shdrs(FILE *fp)
3097 @@ -327,6 +359,8 @@ static void read_symtabs(FILE *fp)
3098 static void read_relocs(FILE *fp)
3103 for(i = 0; i < ehdr.e_shnum; i++) {
3104 if (shdr[i].sh_type != SHT_REL) {
3106 @@ -344,8 +378,17 @@ static void read_relocs(FILE *fp)
3107 die("Cannot read symbol table: %s\n",
3111 + for (j = 0; j < ehdr.e_phnum; j++) {
3112 + if (phdr[j].p_type != PT_LOAD )
3114 + if (shdr[shdr[i].sh_info].sh_offset < phdr[j].p_offset || shdr[shdr[i].sh_info].sh_offset > phdr[j].p_offset + phdr[j].p_filesz)
3116 + base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3119 for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
3120 - reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
3121 + reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
3122 reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info);
3125 @@ -482,6 +525,23 @@ static void walk_relocs(void (*visit)(El
3126 if (sym->st_shndx == SHN_ABS) {
3129 + /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
3130 + if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
3132 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3133 + /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3134 + if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
3136 + if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
3138 + if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3139 + if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3140 + strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3143 + if (!strcmp(sec_name(sym->st_shndx), ".text"))
3146 if (r_type == R_386_PC32) {
3147 /* PC relative relocations don't need to be adjusted */
3149 @@ -609,6 +669,7 @@ int main(int argc, char **argv)
3150 fname, strerror(errno));
3157 diff -urNp linux-2.6.25.10/arch/x86/boot/cpucheck.c linux-2.6.25.10/arch/x86/boot/cpucheck.c
3158 --- linux-2.6.25.10/arch/x86/boot/cpucheck.c 2008-07-02 23:46:47.000000000 -0400
3159 +++ linux-2.6.25.10/arch/x86/boot/cpucheck.c 2008-07-03 16:53:24.000000000 -0400
3160 @@ -84,7 +84,7 @@ static int has_fpu(void)
3161 u16 fcw = -1, fsw = -1;
3164 - asm("movl %%cr0,%0" : "=r" (cr0));
3165 + asm volatile("movl %%cr0,%0" : "=r" (cr0));
3166 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3167 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3168 asm volatile("movl %0,%%cr0" : : "r" (cr0));
3169 @@ -100,7 +100,7 @@ static int has_eflag(u32 mask)
3174 + asm volatile("pushfl ; "
3178 @@ -125,7 +125,7 @@ static void get_flags(void)
3179 set_bit(X86_FEATURE_FPU, cpu.flags);
3181 if (has_eflag(X86_EFLAGS_ID)) {
3183 + asm volatile("cpuid"
3184 : "=a" (max_intel_level),
3185 "=b" (cpu_vendor[0]),
3186 "=d" (cpu_vendor[1]),
3187 @@ -134,7 +134,7 @@ static void get_flags(void)
3189 if (max_intel_level >= 0x00000001 &&
3190 max_intel_level <= 0x0000ffff) {
3192 + asm volatile("cpuid"
3194 "=c" (cpu.flags[4]),
3196 @@ -146,7 +146,7 @@ static void get_flags(void)
3197 cpu.model += ((tfms >> 16) & 0xf) << 4;
3201 + asm volatile("cpuid"
3202 : "=a" (max_amd_level)
3204 : "ebx", "ecx", "edx");
3205 @@ -154,7 +154,7 @@ static void get_flags(void)
3206 if (max_amd_level >= 0x80000001 &&
3207 max_amd_level <= 0x8000ffff) {
3208 u32 eax = 0x80000001;
3210 + asm volatile("cpuid"
3212 "=c" (cpu.flags[6]),
3214 @@ -213,9 +213,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3215 u32 ecx = MSR_K7_HWCR;
3218 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3219 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3221 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3222 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3224 get_flags(); /* Make sure it really did something */
3225 err = check_flags();
3226 @@ -228,9 +228,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3227 u32 ecx = MSR_VIA_FCR;
3230 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3231 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3232 eax |= (1<<1)|(1<<7);
3233 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3234 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3236 set_bit(X86_FEATURE_CX8, cpu.flags);
3237 err = check_flags();
3238 @@ -241,12 +241,12 @@ int check_cpu(int *cpu_level_ptr, int *r
3242 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3243 - asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3245 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3246 + asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3247 + asm volatile("cpuid"
3248 : "+a" (level), "=d" (cpu.flags[0])
3250 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3251 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3253 err = check_flags();
3255 diff -urNp linux-2.6.25.10/arch/x86/boot/edd.c linux-2.6.25.10/arch/x86/boot/edd.c
3256 --- linux-2.6.25.10/arch/x86/boot/edd.c 2008-07-02 23:46:47.000000000 -0400
3257 +++ linux-2.6.25.10/arch/x86/boot/edd.c 2008-07-03 16:53:24.000000000 -0400
3258 @@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct
3262 - asm("pushfl; stc; int $0x13; setc %%al; popfl"
3263 + asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
3264 : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3267 @@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct
3268 ei->params.length = sizeof(ei->params);
3271 - asm("pushfl; int $0x13; popfl"
3272 + asm volatile("pushfl; int $0x13; popfl"
3273 : "+a" (ax), "+d" (dx), "=m" (ei->params)
3275 : "ebx", "ecx", "edi");
3276 @@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct
3280 - asm("pushw %%es; "
3281 + asm volatile("pushw %%es; "
3283 "pushfl; stc; int $0x13; setc %%al; popfl; "
3285 diff -urNp linux-2.6.25.10/arch/x86/boot/main.c linux-2.6.25.10/arch/x86/boot/main.c
3286 --- linux-2.6.25.10/arch/x86/boot/main.c 2008-07-02 23:46:47.000000000 -0400
3287 +++ linux-2.6.25.10/arch/x86/boot/main.c 2008-07-03 16:53:24.000000000 -0400
3288 @@ -75,7 +75,7 @@ static void keyboard_set_repeat(void)
3290 static void query_ist(void)
3293 + asm volatile("int $0x15"
3294 : "=a" (boot_params.ist_info.signature),
3295 "=b" (boot_params.ist_info.command),
3296 "=c" (boot_params.ist_info.event),
3297 diff -urNp linux-2.6.25.10/arch/x86/boot/mca.c linux-2.6.25.10/arch/x86/boot/mca.c
3298 --- linux-2.6.25.10/arch/x86/boot/mca.c 2008-07-02 23:46:47.000000000 -0400
3299 +++ linux-2.6.25.10/arch/x86/boot/mca.c 2008-07-03 16:53:24.000000000 -0400
3300 @@ -21,7 +21,7 @@ int query_mca(void)
3304 - asm("pushw %%es ; "
3305 + asm volatile("pushw %%es ; "
3309 diff -urNp linux-2.6.25.10/arch/x86/boot/memory.c linux-2.6.25.10/arch/x86/boot/memory.c
3310 --- linux-2.6.25.10/arch/x86/boot/memory.c 2008-07-02 23:46:47.000000000 -0400
3311 +++ linux-2.6.25.10/arch/x86/boot/memory.c 2008-07-03 16:53:24.000000000 -0400
3312 @@ -32,7 +32,7 @@ static int detect_memory_e820(void)
3313 /* Important: %edx is clobbered by some BIOSes,
3314 so it must be either used for the error output
3315 or explicitly marked clobbered. */
3316 - asm("int $0x15; setc %0"
3317 + asm volatile("int $0x15; setc %0"
3318 : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
3320 : "D" (desc), "d" (SMAP), "a" (0xe820));
3321 @@ -67,7 +67,7 @@ static int detect_memory_e801(void)
3325 - asm("stc; int $0x15; setc %0"
3326 + asm volatile("stc; int $0x15; setc %0"
3327 : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3330 @@ -97,7 +97,7 @@ static int detect_memory_88(void)
3334 - asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3335 + asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3337 boot_params.screen_info.ext_mem_k = ax;
3339 diff -urNp linux-2.6.25.10/arch/x86/boot/video.c linux-2.6.25.10/arch/x86/boot/video.c
3340 --- linux-2.6.25.10/arch/x86/boot/video.c 2008-07-02 23:46:47.000000000 -0400
3341 +++ linux-2.6.25.10/arch/x86/boot/video.c 2008-07-03 16:53:24.000000000 -0400
3342 @@ -40,7 +40,7 @@ static void store_cursor_position(void)
3347 + asm volatile(INT10
3348 : "=d" (curpos), "+a" (ax), "+b" (bx)
3349 : : "ecx", "esi", "edi");
3351 @@ -55,7 +55,7 @@ static void store_video_mode(void)
3352 /* N.B.: the saving of the video page here is a bit silly,
3353 since we pretty much assume page 0 everywhere. */
3356 + asm volatile(INT10
3357 : "+a" (ax), "=b" (page)
3358 : : "ecx", "edx", "esi", "edi");
3360 diff -urNp linux-2.6.25.10/arch/x86/boot/video-vesa.c linux-2.6.25.10/arch/x86/boot/video-vesa.c
3361 --- linux-2.6.25.10/arch/x86/boot/video-vesa.c 2008-07-02 23:46:47.000000000 -0400
3362 +++ linux-2.6.25.10/arch/x86/boot/video-vesa.c 2008-07-03 16:53:24.000000000 -0400
3363 @@ -39,7 +39,7 @@ static int vesa_probe(void)
3366 di = (size_t)&vginfo;
3368 + asm volatile(INT10
3369 : "+a" (ax), "+D" (di), "=m" (vginfo)
3370 : : "ebx", "ecx", "edx", "esi");
3372 @@ -66,7 +66,7 @@ static int vesa_probe(void)
3375 di = (size_t)&vminfo;
3377 + asm volatile(INT10
3378 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3379 : : "ebx", "edx", "esi");
3381 @@ -121,7 +121,7 @@ static int vesa_set_mode(struct mode_inf
3384 di = (size_t)&vminfo;
3386 + asm volatile(INT10
3387 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3388 : : "ebx", "edx", "esi");
3390 @@ -199,19 +199,20 @@ static void vesa_dac_set_8bits(void)
3391 /* Save the VESA protected mode info */
3392 static void vesa_store_pm_info(void)
3394 - u16 ax, bx, di, es;
3395 + u16 ax, bx, cx, di, es;
3399 - asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3400 - : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3401 - : : "ecx", "esi");
3403 + asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3404 + : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3410 boot_params.screen_info.vesapm_seg = es;
3411 boot_params.screen_info.vesapm_off = di;
3412 + boot_params.screen_info.vesapm_size = cx;
3416 @@ -265,7 +266,7 @@ void vesa_store_edid(void)
3417 /* Note: The VBE DDC spec is different from the main VESA spec;
3418 we genuinely have to assume all registers are destroyed here. */
3420 - asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3421 + asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3422 : "+a" (ax), "+b" (bx)
3423 : "c" (cx), "D" (di)
3425 @@ -281,7 +282,7 @@ void vesa_store_edid(void)
3426 cx = 0; /* Controller 0 */
3427 dx = 0; /* EDID block number */
3428 di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
3430 + asm volatile(INT10
3431 : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
3432 : "c" (cx), "D" (di)
3434 diff -urNp linux-2.6.25.10/arch/x86/boot/video-vga.c linux-2.6.25.10/arch/x86/boot/video-vga.c
3435 --- linux-2.6.25.10/arch/x86/boot/video-vga.c 2008-07-02 23:46:47.000000000 -0400
3436 +++ linux-2.6.25.10/arch/x86/boot/video-vga.c 2008-07-03 16:53:24.000000000 -0400
3437 @@ -225,7 +225,7 @@ static int vga_probe(void)
3442 + asm volatile(INT10
3443 : "=b" (boot_params.screen_info.orig_video_ega_bx)
3444 : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
3445 : "ecx", "edx", "esi", "edi");
3446 @@ -233,7 +233,7 @@ static int vga_probe(void)
3447 /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
3448 if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
3451 + asm volatile(INT10
3454 : "ebx", "ecx", "edx", "esi", "edi");
3455 diff -urNp linux-2.6.25.10/arch/x86/boot/voyager.c linux-2.6.25.10/arch/x86/boot/voyager.c
3456 --- linux-2.6.25.10/arch/x86/boot/voyager.c 2008-07-02 23:46:47.000000000 -0400
3457 +++ linux-2.6.25.10/arch/x86/boot/voyager.c 2008-07-03 16:53:24.000000000 -0400
3458 @@ -25,7 +25,7 @@ int query_voyager(void)
3460 data_ptr[0] = 0xff; /* Flag on config not found(?) */
3462 - asm("pushw %%es ; "
3463 + asm volatile("pushw %%es ; "
3467 diff -urNp linux-2.6.25.10/arch/x86/ia32/ia32_signal.c linux-2.6.25.10/arch/x86/ia32/ia32_signal.c
3468 --- linux-2.6.25.10/arch/x86/ia32/ia32_signal.c 2008-07-02 23:46:47.000000000 -0400
3469 +++ linux-2.6.25.10/arch/x86/ia32/ia32_signal.c 2008-07-03 16:53:25.000000000 -0400
3470 @@ -536,6 +536,7 @@ int ia32_setup_rt_frame(int sig, struct
3471 __NR_ia32_rt_sigreturn,
3477 frame = get_sigframe(ka, regs, sizeof(*frame));
3478 diff -urNp linux-2.6.25.10/arch/x86/Kconfig linux-2.6.25.10/arch/x86/Kconfig
3479 --- linux-2.6.25.10/arch/x86/Kconfig 2008-07-02 23:46:47.000000000 -0400
3480 +++ linux-2.6.25.10/arch/x86/Kconfig 2008-07-03 16:53:24.000000000 -0400
3481 @@ -819,7 +819,7 @@ config PAGE_OFFSET
3483 default 0xB0000000 if VMSPLIT_3G_OPT
3484 default 0x80000000 if VMSPLIT_2G
3485 - default 0x78000000 if VMSPLIT_2G_OPT
3486 + default 0x70000000 if VMSPLIT_2G_OPT
3487 default 0x40000000 if VMSPLIT_1G
3490 @@ -1113,8 +1113,7 @@ config CRASH_DUMP
3491 config PHYSICAL_START
3492 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
3493 default "0x1000000" if X86_NUMAQ
3494 - default "0x200000" if X86_64
3495 - default "0x100000"
3496 + default "0x200000"
3498 This gives the physical address where the kernel is loaded.
3500 @@ -1206,9 +1205,9 @@ config HOTPLUG_CPU
3506 prompt "Compat VDSO support"
3507 - depends on X86_32 || IA32_EMULATION
3508 + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
3510 Map the 32-bit VDSO to the predictable old-style address too.
3512 @@ -1395,7 +1394,7 @@ config PCI
3514 prompt "PCI access mode"
3515 depends on X86_32 && PCI && !X86_VISWS
3517 + default PCI_GODIRECT
3519 On PCI systems, the BIOS can be used to detect the PCI devices and
3520 determine their configuration. However, some old PCI motherboards
3521 diff -urNp linux-2.6.25.10/arch/x86/Kconfig.cpu linux-2.6.25.10/arch/x86/Kconfig.cpu
3522 --- linux-2.6.25.10/arch/x86/Kconfig.cpu 2008-07-02 23:46:47.000000000 -0400
3523 +++ linux-2.6.25.10/arch/x86/Kconfig.cpu 2008-07-03 16:53:24.000000000 -0400
3524 @@ -335,7 +335,7 @@ config X86_PPRO_FENCE
3528 - depends on M586MMX || M586TSC || M586 || M486 || M386
3529 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
3531 config X86_WP_WORKS_OK
3533 @@ -355,7 +355,7 @@ config X86_POPAD_OK
3535 config X86_ALIGNMENT_16
3537 - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3538 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3540 config X86_GOOD_APIC
3542 @@ -398,7 +398,7 @@ config X86_TSC
3546 - depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
3547 + depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
3549 config X86_MINIMUM_CPU_FAMILY
3551 diff -urNp linux-2.6.25.10/arch/x86/Kconfig.debug linux-2.6.25.10/arch/x86/Kconfig.debug
3552 --- linux-2.6.25.10/arch/x86/Kconfig.debug 2008-07-02 23:46:47.000000000 -0400
3553 +++ linux-2.6.25.10/arch/x86/Kconfig.debug 2008-07-03 16:53:24.000000000 -0400
3554 @@ -57,7 +57,7 @@ config DEBUG_PER_CPU_MAPS
3556 bool "Write protect kernel read-only data structures"
3558 - depends on DEBUG_KERNEL
3559 + depends on DEBUG_KERNEL && BROKEN
3561 Mark the kernel read-only data as write-protected in the pagetables,
3562 in order to catch accidental (and incorrect) writes to such const
3563 diff -urNp linux-2.6.25.10/arch/x86/kernel/acpi/boot.c linux-2.6.25.10/arch/x86/kernel/acpi/boot.c
3564 --- linux-2.6.25.10/arch/x86/kernel/acpi/boot.c 2008-07-02 23:46:47.000000000 -0400
3565 +++ linux-2.6.25.10/arch/x86/kernel/acpi/boot.c 2008-07-03 16:53:25.000000000 -0400
3566 @@ -1119,7 +1119,7 @@ static struct dmi_system_id __initdata a
3567 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
3571 + { NULL, NULL, {{0, NULL}}, NULL}
3574 #endif /* __i386__ */
3575 diff -urNp linux-2.6.25.10/arch/x86/kernel/acpi/sleep_32.c linux-2.6.25.10/arch/x86/kernel/acpi/sleep_32.c
3576 --- linux-2.6.25.10/arch/x86/kernel/acpi/sleep_32.c 2008-07-02 23:46:47.000000000 -0400
3577 +++ linux-2.6.25.10/arch/x86/kernel/acpi/sleep_32.c 2008-07-03 16:53:25.000000000 -0400
3578 @@ -28,7 +28,7 @@ static __initdata struct dmi_system_id a
3579 DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
3583 + { NULL, NULL, {{0, NULL}}, NULL}
3586 static int __init acpisleep_dmi_init(void)
3587 diff -urNp linux-2.6.25.10/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.25.10/arch/x86/kernel/acpi/wakeup_32.S
3588 --- linux-2.6.25.10/arch/x86/kernel/acpi/wakeup_32.S 2008-07-02 23:46:47.000000000 -0400
3589 +++ linux-2.6.25.10/arch/x86/kernel/acpi/wakeup_32.S 2008-07-03 16:53:25.000000000 -0400
3591 #include <linux/linkage.h>
3592 #include <asm/segment.h>
3593 #include <asm/page.h>
3594 +#include <asm/msr-index.h>
3597 # wakeup_code runs in real mode, and at unknown address (determined at run-time).
3598 @@ -79,7 +80,7 @@ wakeup_code:
3599 # restore efer setting
3600 movl real_save_efer_edx - wakeup_code, %edx
3601 movl real_save_efer_eax - wakeup_code, %eax
3602 - mov $0xc0000080, %ecx
3603 + mov $MSR_EFER, %ecx
3606 # make sure %cr4 is set correctly (features, etc)
3607 @@ -196,13 +197,11 @@ wakeup_pmode_return:
3608 # and restore the stack ... but you need gdt for this to work
3609 movl saved_context_esp, %esp
3611 - movl %cs:saved_magic, %eax
3612 - cmpl $0x12345678, %eax
3613 + cmpl $0x12345678, saved_magic
3616 # jump to place where we left off
3617 - movl saved_eip,%eax
3623 @@ -233,7 +232,7 @@ ENTRY(acpi_copy_wakeup_routine)
3627 - mov $0xc0000080, %ecx
3628 + mov $MSR_EFER, %ecx
3630 movl %edx, real_save_efer_edx - wakeup_start (%ebx)
3631 movl %eax, real_save_efer_eax - wakeup_start (%ebx)
3632 diff -urNp linux-2.6.25.10/arch/x86/kernel/alternative.c linux-2.6.25.10/arch/x86/kernel/alternative.c
3633 --- linux-2.6.25.10/arch/x86/kernel/alternative.c 2008-07-02 23:46:47.000000000 -0400
3634 +++ linux-2.6.25.10/arch/x86/kernel/alternative.c 2008-07-03 16:53:25.000000000 -0400
3635 @@ -403,7 +403,7 @@ void apply_paravirt(struct paravirt_patc
3637 BUG_ON(p->len > MAX_PATCH_LEN);
3638 /* prep the buffer with the original instructions */
3639 - memcpy(insnbuf, p->instr, p->len);
3640 + memcpy(insnbuf, ktla_ktva(p->instr), p->len);
3641 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
3642 (unsigned long)p->instr, p->len);
3644 @@ -485,7 +485,19 @@ void __init alternative_instructions(voi
3646 void __kprobes text_poke(void *addr, unsigned char *opcode, int len)
3648 - memcpy(addr, opcode, len);
3650 +#ifdef CONFIG_PAX_KERNEXEC
3651 + unsigned long cr0;
3653 + pax_open_kernel(cr0);
3656 + memcpy(ktla_ktva(addr), opcode, len);
3658 +#ifdef CONFIG_PAX_KERNEXEC
3659 + pax_close_kernel(cr0);
3663 /* Could also do a CLFLUSH here to speed up CPU recovery; but
3664 that causes hangs on some VIA CPUs. */
3665 diff -urNp linux-2.6.25.10/arch/x86/kernel/apm_32.c linux-2.6.25.10/arch/x86/kernel/apm_32.c
3666 --- linux-2.6.25.10/arch/x86/kernel/apm_32.c 2008-07-02 23:46:47.000000000 -0400
3667 +++ linux-2.6.25.10/arch/x86/kernel/apm_32.c 2008-07-03 16:53:25.000000000 -0400
3668 @@ -406,7 +406,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
3669 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
3670 static struct apm_user *user_list;
3671 static DEFINE_SPINLOCK(user_list_lock);
3672 -static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
3673 +static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
3675 static const char driver_version[] = "1.16ac"; /* no spaces */
3677 @@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
3678 struct desc_struct save_desc_40;
3679 struct desc_struct *gdt;
3681 +#ifdef CONFIG_PAX_KERNEXEC
3682 + unsigned long cr0;
3685 cpus = apm_save_cpus();
3688 gdt = get_cpu_gdt_table(cpu);
3689 save_desc_40 = gdt[0x40 / 8];
3691 +#ifdef CONFIG_PAX_KERNEXEC
3692 + pax_open_kernel(cr0);
3695 gdt[0x40 / 8] = bad_bios_desc;
3697 +#ifdef CONFIG_PAX_KERNEXEC
3698 + pax_close_kernel(cr0);
3701 apm_irq_save(flags);
3703 apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
3704 APM_DO_RESTORE_SEGS;
3705 apm_irq_restore(flags);
3707 +#ifdef CONFIG_PAX_KERNEXEC
3708 + pax_open_kernel(cr0);
3711 gdt[0x40 / 8] = save_desc_40;
3713 +#ifdef CONFIG_PAX_KERNEXEC
3714 + pax_close_kernel(cr0);
3718 apm_restore_cpus(cpus);
3720 @@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
3721 struct desc_struct save_desc_40;
3722 struct desc_struct *gdt;
3724 +#ifdef CONFIG_PAX_KERNEXEC
3725 + unsigned long cr0;
3728 cpus = apm_save_cpus();
3731 gdt = get_cpu_gdt_table(cpu);
3732 save_desc_40 = gdt[0x40 / 8];
3734 +#ifdef CONFIG_PAX_KERNEXEC
3735 + pax_open_kernel(cr0);
3738 gdt[0x40 / 8] = bad_bios_desc;
3740 +#ifdef CONFIG_PAX_KERNEXEC
3741 + pax_close_kernel(cr0);
3744 apm_irq_save(flags);
3746 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
3747 APM_DO_RESTORE_SEGS;
3748 apm_irq_restore(flags);
3750 +#ifdef CONFIG_PAX_KERNEXEC
3751 + pax_open_kernel(cr0);
3754 gdt[0x40 / 8] = save_desc_40;
3756 +#ifdef CONFIG_PAX_KERNEXEC
3757 + pax_close_kernel(cr0);
3761 apm_restore_cpus(cpus);
3763 @@ -925,7 +971,7 @@ recalc:
3765 static void apm_power_off(void)
3767 - unsigned char po_bios_call[] = {
3768 + const unsigned char po_bios_call[] = {
3769 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
3770 0x8e, 0xd0, /* movw ax,ss */
3771 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
3772 @@ -1881,7 +1927,10 @@ static const struct file_operations apm_
3773 static struct miscdevice apm_device = {
3784 @@ -2202,7 +2251,7 @@ static struct dmi_system_id __initdata a
3785 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
3789 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
3793 @@ -2221,6 +2270,10 @@ static int __init apm_init(void)
3794 struct desc_struct *gdt;
3797 +#ifdef CONFIG_PAX_KERNEXEC
3798 + unsigned long cr0;
3801 dmi_check_system(apm_dmi_table);
3803 if (apm_info.bios.version == 0 || paravirt_enabled()) {
3804 @@ -2294,9 +2347,18 @@ static int __init apm_init(void)
3805 * This is for buggy BIOS's that refer to (real mode) segment 0x40
3806 * even though they are called in protected mode.
3809 +#ifdef CONFIG_PAX_KERNEXEC
3810 + pax_open_kernel(cr0);
3813 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
3814 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
3816 +#ifdef CONFIG_PAX_KERNEXEC
3817 + pax_close_kernel(cr0);
3821 * Set up the long jump entry point to the APM BIOS, which is called
3822 * from inline assembly.
3823 @@ -2315,6 +2377,11 @@ static int __init apm_init(void)
3826 gdt = get_cpu_gdt_table(0);
3828 +#ifdef CONFIG_PAX_KERNEXEC
3829 + pax_open_kernel(cr0);
3832 set_base(gdt[APM_CS >> 3],
3833 __va((unsigned long)apm_info.bios.cseg << 4));
3834 set_base(gdt[APM_CS_16 >> 3],
3835 @@ -2322,6 +2389,10 @@ static int __init apm_init(void)
3836 set_base(gdt[APM_DS >> 3],
3837 __va((unsigned long)apm_info.bios.dseg << 4));
3839 +#ifdef CONFIG_PAX_KERNEXEC
3840 + pax_close_kernel(cr0);
3843 apm_proc = create_proc_entry("apm", 0, NULL);
3845 apm_proc->proc_fops = &apm_file_ops;
3846 diff -urNp linux-2.6.25.10/arch/x86/kernel/asm-offsets_32.c linux-2.6.25.10/arch/x86/kernel/asm-offsets_32.c
3847 --- linux-2.6.25.10/arch/x86/kernel/asm-offsets_32.c 2008-07-02 23:46:47.000000000 -0400
3848 +++ linux-2.6.25.10/arch/x86/kernel/asm-offsets_32.c 2008-07-03 16:53:25.000000000 -0400
3849 @@ -107,6 +107,7 @@ void foo(void)
3850 DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
3851 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
3852 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
3853 + DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
3855 OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
3857 @@ -120,6 +121,7 @@ void foo(void)
3858 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
3859 OFFSET(PV_CPU_irq_enable_syscall_ret, pv_cpu_ops, irq_enable_syscall_ret);
3860 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
3861 + OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
3865 diff -urNp linux-2.6.25.10/arch/x86/kernel/asm-offsets_64.c linux-2.6.25.10/arch/x86/kernel/asm-offsets_64.c
3866 --- linux-2.6.25.10/arch/x86/kernel/asm-offsets_64.c 2008-07-02 23:46:47.000000000 -0400
3867 +++ linux-2.6.25.10/arch/x86/kernel/asm-offsets_64.c 2008-07-03 16:53:25.000000000 -0400
3868 @@ -124,6 +124,7 @@ int main(void)
3872 + DEFINE(TSS_size, sizeof(struct tss_struct));
3873 DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
3875 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
3876 diff -urNp linux-2.6.25.10/arch/x86/kernel/cpu/common.c linux-2.6.25.10/arch/x86/kernel/cpu/common.c
3877 --- linux-2.6.25.10/arch/x86/kernel/cpu/common.c 2008-07-02 23:46:47.000000000 -0400
3878 +++ linux-2.6.25.10/arch/x86/kernel/cpu/common.c 2008-07-03 16:53:25.000000000 -0400
3880 #include <linux/smp.h>
3881 #include <linux/module.h>
3882 #include <linux/percpu.h>
3883 -#include <linux/bootmem.h>
3884 #include <asm/semaphore.h>
3885 #include <asm/processor.h>
3886 #include <asm/i387.h>
3891 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
3892 - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
3893 - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
3894 - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
3895 - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
3897 - * Segments used for calling PnP BIOS have byte granularity.
3898 - * They code segments and data segments have fixed 64k limits,
3899 - * the transfer segment sizes are set at run time.
3902 - [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
3904 - [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
3906 - [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
3908 - [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
3910 - [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
3912 - * The APM segments have byte granularity and their bases
3913 - * are set at run time. All have 64k limits.
3916 - [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
3918 - [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
3920 - [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
3922 - [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
3923 - [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
3925 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
3927 __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
3929 static int cachesize_override __cpuinitdata = -1;
3930 @@ -478,6 +441,10 @@ void __cpuinit identify_cpu(struct cpuin
3931 * we do "generic changes."
3934 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
3935 + setup_clear_cpu_cap(X86_FEATURE_SEP);
3938 /* If the model name is still unset, do table lookup. */
3939 if ( !c->x86_model_id[0] ) {
3941 @@ -614,7 +581,7 @@ static __init int setup_disablecpuid(cha
3943 __setup("clearcpuid=", setup_disablecpuid);
3945 -cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
3946 +cpumask_t cpu_initialized = CPU_MASK_NONE;
3948 /* This is hacky. :)
3949 * We're emulating future behavior.
3950 @@ -650,7 +617,7 @@ void switch_to_new_gdt(void)
3952 struct desc_ptr gdt_descr;
3954 - gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
3955 + gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
3956 gdt_descr.size = GDT_SIZE - 1;
3957 load_gdt(&gdt_descr);
3958 asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
3959 @@ -666,7 +633,7 @@ void __cpuinit cpu_init(void)
3961 int cpu = smp_processor_id();
3962 struct task_struct *curr = current;
3963 - struct tss_struct * t = &per_cpu(init_tss, cpu);
3964 + struct tss_struct *t = init_tss + cpu;
3965 struct thread_struct *thread = &curr->thread;
3967 if (cpu_test_and_set(cpu, cpu_initialized)) {
3968 @@ -721,7 +688,7 @@ void __cpuinit cpu_init(void)
3971 #ifdef CONFIG_HOTPLUG_CPU
3972 -void __cpuinit cpu_uninit(void)
3973 +void cpu_uninit(void)
3975 int cpu = raw_smp_processor_id();
3976 cpu_clear(cpu, cpu_initialized);
3977 diff -urNp linux-2.6.25.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.25.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
3978 --- linux-2.6.25.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-07-02 23:46:47.000000000 -0400
3979 +++ linux-2.6.25.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-07-03 16:53:25.000000000 -0400
3980 @@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
3981 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
3985 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
3989 diff -urNp linux-2.6.25.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.25.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
3990 --- linux-2.6.25.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-07-02 23:46:47.000000000 -0400
3991 +++ linux-2.6.25.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-07-03 16:53:25.000000000 -0400
3992 @@ -223,7 +223,7 @@ static struct cpu_model models[] =
3993 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
3994 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
3997 + { NULL, NULL, 0, NULL}
4001 diff -urNp linux-2.6.25.10/arch/x86/kernel/cpu/intel.c linux-2.6.25.10/arch/x86/kernel/cpu/intel.c
4002 --- linux-2.6.25.10/arch/x86/kernel/cpu/intel.c 2008-07-02 23:46:47.000000000 -0400
4003 +++ linux-2.6.25.10/arch/x86/kernel/cpu/intel.c 2008-07-03 16:53:25.000000000 -0400
4004 @@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
4005 * Update the IDT descriptor and reload the IDT so that
4006 * it uses the read-only mapped virtual address.
4008 - idt_descr.address = fix_to_virt(FIX_F00F_IDT);
4009 + idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
4010 load_idt(&idt_descr);
4013 diff -urNp linux-2.6.25.10/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.25.10/arch/x86/kernel/cpu/mcheck/mce_64.c
4014 --- linux-2.6.25.10/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-07-02 23:46:47.000000000 -0400
4015 +++ linux-2.6.25.10/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-07-03 16:53:25.000000000 -0400
4016 @@ -670,6 +670,7 @@ static struct miscdevice mce_log_device
4020 + {NULL, NULL}, NULL, NULL
4023 static unsigned long old_cr4 __initdata;
4024 diff -urNp linux-2.6.25.10/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.25.10/arch/x86/kernel/cpu/mtrr/generic.c
4025 --- linux-2.6.25.10/arch/x86/kernel/cpu/mtrr/generic.c 2008-07-02 23:46:47.000000000 -0400
4026 +++ linux-2.6.25.10/arch/x86/kernel/cpu/mtrr/generic.c 2008-07-03 16:53:25.000000000 -0400
4027 @@ -30,11 +30,11 @@ static struct fixed_range_block fixed_ra
4028 { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
4029 { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
4030 { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
4035 static unsigned long smp_changes_mask;
4036 -static struct mtrr_state mtrr_state = {};
4037 +static struct mtrr_state mtrr_state;
4039 #undef MODULE_PARAM_PREFIX
4040 #define MODULE_PARAM_PREFIX "mtrr."
4041 diff -urNp linux-2.6.25.10/arch/x86/kernel/crash.c linux-2.6.25.10/arch/x86/kernel/crash.c
4042 --- linux-2.6.25.10/arch/x86/kernel/crash.c 2008-07-02 23:46:47.000000000 -0400
4043 +++ linux-2.6.25.10/arch/x86/kernel/crash.c 2008-07-03 16:53:25.000000000 -0400
4044 @@ -62,7 +62,7 @@ static int crash_nmi_callback(struct not
4045 local_irq_disable();
4047 #ifdef CONFIG_X86_32
4048 - if (!user_mode_vm(regs)) {
4049 + if (!user_mode(regs)) {
4050 crash_fixup_ss_esp(&fixed_regs, regs);
4053 diff -urNp linux-2.6.25.10/arch/x86/kernel/doublefault_32.c linux-2.6.25.10/arch/x86/kernel/doublefault_32.c
4054 --- linux-2.6.25.10/arch/x86/kernel/doublefault_32.c 2008-07-02 23:46:47.000000000 -0400
4055 +++ linux-2.6.25.10/arch/x86/kernel/doublefault_32.c 2008-07-03 16:53:25.000000000 -0400
4058 #define DOUBLEFAULT_STACKSIZE (1024)
4059 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
4060 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
4061 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
4063 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
4065 @@ -21,7 +21,7 @@ static void doublefault_fn(void)
4066 unsigned long gdt, tss;
4068 store_gdt(&gdt_desc);
4069 - gdt = gdt_desc.address;
4070 + gdt = (unsigned long)gdt_desc.address;
4072 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
4074 @@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
4075 /* 0x2 bit is always set */
4076 .flags = X86_EFLAGS_SF | 0x2,
4079 + .es = __KERNEL_DS,
4083 + .ds = __KERNEL_DS,
4084 .fs = __KERNEL_PERCPU,
4086 .__cr3 = __pa(swapper_pg_dir)
4087 diff -urNp linux-2.6.25.10/arch/x86/kernel/efi_32.c linux-2.6.25.10/arch/x86/kernel/efi_32.c
4088 --- linux-2.6.25.10/arch/x86/kernel/efi_32.c 2008-07-02 23:46:47.000000000 -0400
4089 +++ linux-2.6.25.10/arch/x86/kernel/efi_32.c 2008-07-03 16:53:25.000000000 -0400
4093 static unsigned long efi_rt_eflags;
4094 -static pgd_t efi_bak_pg_dir_pointer[2];
4095 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
4097 -void efi_call_phys_prelog(void)
4098 +void __init efi_call_phys_prelog(void)
4100 - unsigned long cr4;
4101 - unsigned long temp;
4102 struct desc_ptr gdt_descr;
4104 local_irq_save(efi_rt_eflags);
4107 - * If I don't have PSE, I should just duplicate two entries in page
4108 - * directory. If I have PSE, I just need to duplicate one entry in
4113 - if (cr4 & X86_CR4_PSE) {
4114 - efi_bak_pg_dir_pointer[0].pgd =
4115 - swapper_pg_dir[pgd_index(0)].pgd;
4116 - swapper_pg_dir[0].pgd =
4117 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4119 - efi_bak_pg_dir_pointer[0].pgd =
4120 - swapper_pg_dir[pgd_index(0)].pgd;
4121 - efi_bak_pg_dir_pointer[1].pgd =
4122 - swapper_pg_dir[pgd_index(0x400000)].pgd;
4123 - swapper_pg_dir[pgd_index(0)].pgd =
4124 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4125 - temp = PAGE_OFFSET + 0x400000;
4126 - swapper_pg_dir[pgd_index(0x400000)].pgd =
4127 - swapper_pg_dir[pgd_index(temp)].pgd;
4129 + clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
4130 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
4131 + min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
4134 * After the lock is released, the original page table is restored.
4138 - gdt_descr.address = __pa(get_cpu_gdt_table(0));
4139 + gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
4140 gdt_descr.size = GDT_SIZE - 1;
4141 load_gdt(&gdt_descr);
4144 -void efi_call_phys_epilog(void)
4145 +void __init efi_call_phys_epilog(void)
4147 - unsigned long cr4;
4148 struct desc_ptr gdt_descr;
4150 - gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
4151 + gdt_descr.address = get_cpu_gdt_table(0);
4152 gdt_descr.size = GDT_SIZE - 1;
4153 load_gdt(&gdt_descr);
4157 - if (cr4 & X86_CR4_PSE) {
4158 - swapper_pg_dir[pgd_index(0)].pgd =
4159 - efi_bak_pg_dir_pointer[0].pgd;
4161 - swapper_pg_dir[pgd_index(0)].pgd =
4162 - efi_bak_pg_dir_pointer[0].pgd;
4163 - swapper_pg_dir[pgd_index(0x400000)].pgd =
4164 - efi_bak_pg_dir_pointer[1].pgd;
4166 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
4169 * After the lock is released, the original page table is restored.
4170 diff -urNp linux-2.6.25.10/arch/x86/kernel/efi_stub_32.S linux-2.6.25.10/arch/x86/kernel/efi_stub_32.S
4171 --- linux-2.6.25.10/arch/x86/kernel/efi_stub_32.S 2008-07-02 23:46:47.000000000 -0400
4172 +++ linux-2.6.25.10/arch/x86/kernel/efi_stub_32.S 2008-07-03 16:53:25.000000000 -0400
4176 #include <linux/linkage.h>
4177 +#include <linux/init.h>
4178 #include <asm/page.h>
4182 * service functions will comply with gcc calling convention, too.
4187 ENTRY(efi_call_phys)
4189 * 0. The function can only be called in Linux kernel. So CS has been
4190 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
4191 * The mapping of lower virtual memory has been created in prelog and
4195 - subl $__PAGE_OFFSET, %edx
4197 + jmp 1f-__PAGE_OFFSET
4201 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
4202 * parameter 2, ..., param n. To make things easy, we save the return
4203 * address of efi_call_phys in a global variable.
4206 - movl %edx, saved_return_addr
4207 - /* get the function pointer into ECX*/
4209 - movl %ecx, efi_rt_function_ptr
4211 - subl $__PAGE_OFFSET, %edx
4213 + popl (saved_return_addr)
4214 + popl (efi_rt_function_ptr)
4217 * 3. Clear PG bit in %CR0.
4218 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
4220 * 5. Call the physical function.
4223 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
4227 * 6. After EFI runtime service returns, control will return to
4228 * following instruction. We'd better readjust stack pointer first.
4229 @@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
4231 orl $0x80000000, %edx
4237 * 8. Now restore the virtual mode from flat mode by
4238 * adding EIP with PAGE_OFFSET.
4242 + jmp 1f+__PAGE_OFFSET
4246 * 9. Balance the stack. And because EAX contain the return value,
4247 * we'd better not clobber it.
4249 - leal efi_rt_function_ptr, %edx
4252 + pushl (efi_rt_function_ptr)
4255 - * 10. Push the saved return address onto the stack and return.
4256 + * 10. Return to the saved return address.
4258 - leal saved_return_addr, %edx
4262 + jmpl *(saved_return_addr)
4269 efi_rt_function_ptr:
4270 diff -urNp linux-2.6.25.10/arch/x86/kernel/entry_32.S linux-2.6.25.10/arch/x86/kernel/entry_32.S
4271 --- linux-2.6.25.10/arch/x86/kernel/entry_32.S 2008-07-02 23:46:47.000000000 -0400
4272 +++ linux-2.6.25.10/arch/x86/kernel/entry_32.S 2008-07-03 16:53:25.000000000 -0400
4273 @@ -97,7 +97,7 @@ VM_MASK = 0x00020000
4274 #define resume_userspace_sig resume_userspace
4278 +#define __SAVE_ALL(_DS) \
4281 CFI_ADJUST_CFA_OFFSET 4;\
4282 @@ -129,12 +129,26 @@ VM_MASK = 0x00020000
4284 CFI_ADJUST_CFA_OFFSET 4;\
4285 CFI_REL_OFFSET ebx, 0;\
4286 - movl $(__USER_DS), %edx; \
4287 + movl $(_DS), %edx; \
4290 movl $(__KERNEL_PERCPU), %edx; \
4293 +#ifdef CONFIG_PAX_KERNEXEC
4295 + __SAVE_ALL(__KERNEL_DS); \
4296 + GET_CR0_INTO_EDX; \
4297 + movl %edx, %esi; \
4298 + orl $X86_CR0_WP, %edx; \
4299 + xorl %edx, %esi; \
4301 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4302 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
4304 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
4307 #define RESTORE_INT_REGS \
4309 CFI_ADJUST_CFA_OFFSET -4;\
4310 @@ -225,6 +239,11 @@ ENTRY(ret_from_fork)
4311 CFI_ADJUST_CFA_OFFSET 4
4313 CFI_ADJUST_CFA_OFFSET -4
4315 +#ifdef CONFIG_PAX_KERNEXEC
4322 @@ -248,7 +267,17 @@ check_userspace:
4323 movb PT_CS(%esp), %al
4324 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
4325 cmpl $USER_RPL, %eax
4327 +#ifdef CONFIG_PAX_KERNEXEC
4328 + jae resume_userspace
4335 jb resume_kernel # not returning to v8086 or userspace
4338 ENTRY(resume_userspace)
4340 @@ -308,10 +337,9 @@ sysenter_past_esp:
4341 /*CFI_REL_OFFSET cs, 0*/
4343 * Push current_thread_info()->sysenter_return to the stack.
4344 - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
4345 - * pushed above; +8 corresponds to copy_thread's esp0 setting.
4347 - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
4348 + GET_THREAD_INFO(%ebp)
4349 + pushl TI_sysenter_return(%ebp)
4350 CFI_ADJUST_CFA_OFFSET 4
4351 CFI_REL_OFFSET eip, 0
4353 @@ -319,9 +347,17 @@ sysenter_past_esp:
4354 * Load the potential sixth argument from user stack.
4355 * Careful about security.
4357 + movl 12(%esp),%ebp
4359 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4361 +1: movl %ds:(%ebp),%ebp
4363 cmpl $__PAGE_OFFSET-3,%ebp
4368 .section __ex_table,"a"
4370 .long 1b,syscall_fault
4371 @@ -345,20 +381,37 @@ sysenter_past_esp:
4372 movl TI_flags(%ebp), %ecx
4373 testw $_TIF_ALLWORK_MASK, %cx
4374 jne syscall_exit_work
4376 +#ifdef CONFIG_PAX_RANDKSTACK
4378 + CFI_ADJUST_CFA_OFFSET 4
4379 + call pax_randomize_kstack
4381 + CFI_ADJUST_CFA_OFFSET -4
4384 /* if something modifies registers it must also disable sysexit */
4385 movl PT_EIP(%esp), %edx
4386 movl PT_OLDESP(%esp), %ecx
4389 1: mov PT_FS(%esp), %fs
4390 +2: mov PT_DS(%esp), %ds
4391 +3: mov PT_ES(%esp), %es
4392 ENABLE_INTERRUPTS_SYSCALL_RET
4394 .pushsection .fixup,"ax"
4395 -2: movl $0,PT_FS(%esp)
4396 +4: movl $0,PT_FS(%esp)
4398 +5: movl $0,PT_DS(%esp)
4400 +6: movl $0,PT_ES(%esp)
4402 .section __ex_table,"a"
4409 ENDPROC(ia32_sysenter_target)
4411 @@ -392,6 +445,10 @@ no_singlestep:
4412 testw $_TIF_ALLWORK_MASK, %cx # current->work
4413 jne syscall_exit_work
4415 +#ifdef CONFIG_PAX_RANDKSTACK
4416 + call pax_randomize_kstack
4420 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
4421 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
4422 @@ -485,25 +542,19 @@ work_resched:
4424 work_notifysig: # deal with pending signals and
4425 # notify-resume requests
4428 testl $VM_MASK, PT_EFLAGS(%esp)
4430 - jne work_notifysig_v86 # returning to kernel-space or
4431 + jz 1f # returning to kernel-space or
4434 - call do_notify_resume
4435 - jmp resume_userspace_sig
4438 -work_notifysig_v86:
4439 pushl %ecx # save ti_flags for do_notify_resume
4440 CFI_ADJUST_CFA_OFFSET 4
4441 call save_v86_state # %eax contains pt_regs pointer
4443 CFI_ADJUST_CFA_OFFSET -4
4450 call do_notify_resume
4451 @@ -557,17 +608,24 @@ syscall_badsys:
4455 -#define FIXUP_ESPFIX_STACK \
4456 - /* since we are on a wrong stack, we cant make it a C code :( */ \
4457 - PER_CPU(gdt_page, %ebx); \
4458 - GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
4459 - addl %esp, %eax; \
4460 - pushl $__KERNEL_DS; \
4461 - CFI_ADJUST_CFA_OFFSET 4; \
4463 - CFI_ADJUST_CFA_OFFSET 4; \
4464 - lss (%esp), %esp; \
4465 +.macro FIXUP_ESPFIX_STACK
4466 + /* since we are on a wrong stack, we cant make it a C code :( */
4468 + movl PER_CPU_VAR(cpu_number), %ebx;
4469 + shll $PAGE_SHIFT_asm, %ebx;
4470 + addl $cpu_gdt_table, %ebx;
4472 + movl $cpu_gdt_table, %ebx;
4474 + GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
4476 + pushl $__KERNEL_DS;
4477 + CFI_ADJUST_CFA_OFFSET 4;
4479 + CFI_ADJUST_CFA_OFFSET 4;
4481 CFI_ADJUST_CFA_OFFSET -8;
4483 #define UNWIND_ESPFIX_STACK \
4485 /* see if on espfix stack */ \
4486 @@ -584,7 +642,7 @@ END(syscall_badsys)
4487 * Build the entry stubs and pointer table with
4488 * some assembler magic.
4490 -.section .rodata,"a"
4491 +.section .rodata,"a",@progbits
4495 @@ -684,12 +742,21 @@ error_code:
4497 CFI_ADJUST_CFA_OFFSET -4
4498 /*CFI_REGISTER es, ecx*/
4500 +#ifdef CONFIG_PAX_KERNEXEC
4503 + orl $X86_CR0_WP, %edx
4508 movl PT_FS(%esp), %edi # get the function address
4509 movl PT_ORIG_EAX(%esp), %edx # get the error code
4510 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
4511 mov %ecx, PT_FS(%esp)
4512 /*CFI_REL_OFFSET fs, ES*/
4513 - movl $(__USER_DS), %ecx
4514 + movl $(__KERNEL_DS), %ecx
4517 movl %esp,%eax # pt_regs pointer
4518 @@ -823,6 +890,13 @@ nmi_stack_correct:
4519 xorl %edx,%edx # zero error code
4520 movl %esp,%eax # pt_regs pointer
4523 +#ifdef CONFIG_PAX_KERNEXEC
4529 jmp restore_nocheck_notrace
4532 @@ -863,6 +937,13 @@ nmi_espfix_stack:
4533 FIXUP_ESPFIX_STACK # %eax == %esp
4534 xorl %edx,%edx # zero error code
4537 +#ifdef CONFIG_PAX_KERNEXEC
4544 lss 12+4(%esp), %esp # back to espfix stack
4545 CFI_ADJUST_CFA_OFFSET -24
4546 @@ -1107,7 +1188,6 @@ ENDPROC(xen_failsafe_callback)
4548 #endif /* CONFIG_XEN */
4550 -.section .rodata,"a"
4551 #include "syscall_table_32.S"
4553 syscall_table_size=(.-sys_call_table)
4554 diff -urNp linux-2.6.25.10/arch/x86/kernel/entry_64.S linux-2.6.25.10/arch/x86/kernel/entry_64.S
4555 --- linux-2.6.25.10/arch/x86/kernel/entry_64.S 2008-07-02 23:46:47.000000000 -0400
4556 +++ linux-2.6.25.10/arch/x86/kernel/entry_64.S 2008-07-03 16:53:25.000000000 -0400
4557 @@ -769,17 +769,18 @@ END(spurious_interrupt)
4561 - movq %gs:pda_data_offset, %rbp
4562 + imul $TSS_size, %gs:pda_cpunumber, %ebp
4563 + lea init_tss(%rbp), %rbp
4566 movq ORIG_RAX(%rsp),%rsi
4567 movq $-1,ORIG_RAX(%rsp)
4569 - subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4570 + subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4574 - addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4575 + addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4577 DISABLE_INTERRUPTS(CLBR_NONE)
4579 diff -urNp linux-2.6.25.10/arch/x86/kernel/head_32.S linux-2.6.25.10/arch/x86/kernel/head_32.S
4580 --- linux-2.6.25.10/arch/x86/kernel/head_32.S 2008-07-02 23:46:47.000000000 -0400
4581 +++ linux-2.6.25.10/arch/x86/kernel/head_32.S 2008-07-03 16:53:25.000000000 -0400
4583 #include <asm/asm-offsets.h>
4584 #include <asm/setup.h>
4585 #include <asm/processor-flags.h>
4586 +#include <asm/msr-index.h>
4588 /* Physical address */
4589 #define pa(X) ((X) - __PAGE_OFFSET)
4590 @@ -65,17 +66,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
4591 LOW_PAGES = LOW_PAGES + 0x1000000
4594 -#if PTRS_PER_PMD > 1
4595 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
4597 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
4599 +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
4600 BOOTBITMAP_SIZE = LOW_PAGES / 8
4603 INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
4606 + * Real beginning of normal "text" segment
4611 +.section .text.startup,"ax",@progbits
4612 + ljmp $(__BOOT_CS),$phys_startup_32
4615 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
4616 * %esi points to the real-mode code as a 32-bit pointer.
4617 * CS and DS must be 4 GB flat segments, but we don't depend on
4618 @@ -83,6 +89,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
4621 .section .text.head,"ax",@progbits
4623 +#ifdef CONFIG_PAX_KERNEXEC
4624 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
4629 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
4630 us to not reload segments */
4631 @@ -100,6 +112,43 @@ ENTRY(startup_32)
4635 + movl $__per_cpu_start,%eax
4636 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
4638 + movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
4639 + movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
4640 + movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
4641 + subl $__per_cpu_start,%eax
4642 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
4644 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4645 + /* check for VMware */
4646 + movl $0x564d5868,%eax
4651 + cmpl $0x564d5868,%ebx
4654 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
4655 + movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
4659 +#ifdef CONFIG_PAX_KERNEXEC
4660 + movl $KERNEL_TEXT_OFFSET,%eax
4661 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
4663 + movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
4664 + movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
4666 + movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
4667 + movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
4669 + movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
4673 * Clear BSS first so that there are no surprises...
4675 @@ -143,9 +192,7 @@ ENTRY(startup_32)
4676 cmpl $num_subarch_entries, %eax
4679 - movl pa(subarch_entries)(,%eax,4), %eax
4680 - subl $__PAGE_OFFSET, %eax
4682 + jmp *pa(subarch_entries)(,%eax,4)
4686 @@ -157,9 +204,9 @@ WEAK(xen_entry)
4690 - .long default_entry /* normal x86/PC */
4691 - .long lguest_entry /* lguest hypervisor */
4692 - .long xen_entry /* Xen hypervisor */
4693 + .long pa(default_entry) /* normal x86/PC */
4694 + .long pa(lguest_entry) /* lguest hypervisor */
4695 + .long pa(xen_entry) /* Xen hypervisor */
4696 num_subarch_entries = (. - subarch_entries) / 4
4698 #endif /* CONFIG_PARAVIRT */
4699 @@ -173,7 +220,7 @@ num_subarch_entries = (. - subarch_entri
4701 * Note that the stack is not yet set up!
4703 -#define PTE_ATTR 0x007 /* PRESENT+RW+USER */
4704 +#define PTE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
4705 #define PDE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
4706 #define PGD_ATTR 0x001 /* PRESENT (no other attributes) */
4708 @@ -222,8 +269,7 @@ default_entry:
4709 movl %edi,pa(init_pg_tables_end)
4711 /* Do early initialization of the fixmap area */
4712 - movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4713 - movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4714 + movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4717 page_pde_offset = (__PAGE_OFFSET >> 20);
4718 @@ -252,8 +298,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
4719 movl %edi,pa(init_pg_tables_end)
4721 /* Do early initialization of the fixmap area */
4722 - movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4723 - movl %eax,pa(swapper_pg_dir+0xffc)
4724 + movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
4728 @@ -317,13 +362,16 @@ ENTRY(startup_32_smp)
4731 /* Setup EFER (Extended Feature Enable Register) */
4732 - movl $0xc0000080, %ecx
4733 + movl $MSR_EFER, %ecx
4737 /* Make changes effective */
4740 + btsl $63-32,pa(__supported_pte_mask+4)
4741 + movl $1,pa(nx_enabled)
4746 @@ -349,9 +397,7 @@ ENTRY(startup_32_smp)
4750 - jz 1f /* Initial CPU cleans BSS */
4753 + jnz checkCPUtype /* Initial CPU cleans BSS */
4754 #endif /* CONFIG_SMP */
4757 @@ -428,12 +474,12 @@ is386: movl $2,%ecx # set MP
4758 ljmp $(__KERNEL_CS),$1f
4759 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
4760 movl %eax,%ss # after changing gdt.
4761 - movl %eax,%fs # gets reset once there's real percpu
4763 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
4767 + movl $(__KERNEL_PERCPU), %eax
4768 + movl %eax,%fs # set this cpu's percpu
4770 xorl %eax,%eax # Clear GS and LDT
4773 @@ -444,11 +490,7 @@ is386: movl $2,%ecx # set MP
4776 cmpb $0,%cl # the first CPU calls start_kernel
4778 - movl $(__KERNEL_PERCPU), %eax
4779 - movl %eax,%fs # set this cpu's percpu
4780 - jmp initialize_secondary # all other CPUs call initialize_secondary
4782 + jne initialize_secondary # all other CPUs call initialize_secondary
4783 #endif /* CONFIG_SMP */
4786 @@ -534,15 +576,15 @@ early_page_fault:
4791 #ifdef CONFIG_PRINTK
4792 + cmpl $2,%ss:early_recursion_flag
4794 + incl %ss:early_recursion_flag
4797 movl $(__KERNEL_DS),%eax
4800 - cmpl $2,early_recursion_flag
4802 - incl early_recursion_flag
4805 pushl %edx /* trapno */
4806 @@ -552,8 +594,8 @@ early_fault:
4816 @@ -561,8 +603,11 @@ hlt_loop:
4817 /* This is the default interrupt "handler" :-) */
4821 #ifdef CONFIG_PRINTK
4822 + cmpl $2,%ss:early_recursion_flag
4824 + incl %ss:early_recursion_flag
4829 @@ -571,9 +616,6 @@ ignore_int:
4830 movl $(__KERNEL_DS),%eax
4833 - cmpl $2,early_recursion_flag
4835 - incl early_recursion_flag
4839 @@ -593,36 +635,41 @@ ignore_int:
4845 - * Real beginning of normal "text" segment
4853 -.section ".bss.page_aligned","wa"
4854 - .align PAGE_SIZE_asm
4855 #ifdef CONFIG_X86_PAE
4856 +.section .swapper_pg_pmd,"a",@progbits
4858 .fill 1024*KPMDS,4,0
4860 +.section .swapper_pg_dir,"a",@progbits
4861 ENTRY(swapper_pg_dir)
4867 +.section .empty_zero_page,"a",@progbits
4868 ENTRY(empty_zero_page)
4872 + * The IDT has to be page-aligned to simplify the Pentium
4873 + * F0 0F bug workaround.. We have a special link segment
4876 +.section .idt,"a",@progbits
4881 * This starts the data section.
4885 #ifdef CONFIG_X86_PAE
4886 -.section ".data.page_aligned","wa"
4887 - /* Page-aligned for the benefit of paravirt? */
4888 - .align PAGE_SIZE_asm
4889 +.section .swapper_pg_dir,"a",@progbits
4890 ENTRY(swapper_pg_dir)
4891 .long pa(swapper_pg_pmd+PGD_ATTR),0 /* low identity map */
4893 @@ -643,9 +690,9 @@ ENTRY(swapper_pg_dir)
4894 .align PAGE_SIZE_asm /* needs to be page-sized too */
4898 +.section .rodata,"a",@progbits
4900 - .long init_thread_union+THREAD_SIZE
4901 + .long init_thread_union+THREAD_SIZE-8
4905 @@ -695,7 +742,7 @@ idt_descr:
4906 .word 0 # 32 bit align gdt_desc.address
4907 ENTRY(early_gdt_descr)
4908 .word GDT_ENTRIES*8-1
4909 - .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
4910 + .long cpu_gdt_table /* Overwritten for secondary CPUs */
4913 * The boot_gdt must mirror the equivalent in setup.S and is
4914 @@ -704,5 +751,61 @@ ENTRY(early_gdt_descr)
4915 .align L1_CACHE_BYTES
4917 .fill GDT_ENTRY_BOOT_CS,8,0
4918 - .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
4919 - .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
4920 + .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
4921 + .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
4923 + .align PAGE_SIZE_asm
4924 +ENTRY(cpu_gdt_table)
4925 + .quad 0x0000000000000000 /* NULL descriptor */
4926 + .quad 0x0000000000000000 /* 0x0b reserved */
4927 + .quad 0x0000000000000000 /* 0x13 reserved */
4928 + .quad 0x0000000000000000 /* 0x1b reserved */
4929 + .quad 0x0000000000000000 /* 0x20 unused */
4930 + .quad 0x0000000000000000 /* 0x28 unused */
4931 + .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
4932 + .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
4933 + .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
4934 + .quad 0x0000000000000000 /* 0x4b reserved */
4935 + .quad 0x0000000000000000 /* 0x53 reserved */
4936 + .quad 0x0000000000000000 /* 0x5b reserved */
4938 + .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
4939 + .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
4940 + .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
4941 + .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
4943 + .quad 0x0000000000000000 /* 0x80 TSS descriptor */
4944 + .quad 0x0000000000000000 /* 0x88 LDT descriptor */
4947 + * Segments used for calling PnP BIOS have byte granularity.
4948 + * The code segments and data segments have fixed 64k limits,
4949 + * the transfer segment sizes are set at run time.
4951 + .quad 0x00409b000000ffff /* 0x90 32-bit code */
4952 + .quad 0x00009b000000ffff /* 0x98 16-bit code */
4953 + .quad 0x000093000000ffff /* 0xa0 16-bit data */
4954 + .quad 0x0000930000000000 /* 0xa8 16-bit data */
4955 + .quad 0x0000930000000000 /* 0xb0 16-bit data */
4958 + * The APM segments have byte granularity and their bases
4959 + * are set at run time. All have 64k limits.
4961 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
4962 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
4963 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
4965 + .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
4966 + .quad 0x0040930000000000 /* 0xd8 - PERCPU */
4967 + .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
4968 + .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
4969 + .quad 0x0000000000000000 /* 0xf0 - unused */
4970 + .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
4972 + /* Be sure this is zeroed to avoid false validations in Xen */
4973 + .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
4976 + .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
4978 diff -urNp linux-2.6.25.10/arch/x86/kernel/head64.c linux-2.6.25.10/arch/x86/kernel/head64.c
4979 --- linux-2.6.25.10/arch/x86/kernel/head64.c 2008-07-02 23:46:47.000000000 -0400
4980 +++ linux-2.6.25.10/arch/x86/kernel/head64.c 2008-07-03 16:53:25.000000000 -0400
4981 @@ -88,6 +88,11 @@ void __init x86_64_start_kernel(char * r
4982 /* Make NULL pointers segfault */
4983 zap_identity_mappings();
4985 + for (i = 0; i < NR_CPUS; i++)
4986 + cpu_pda(i) = &boot_cpu_pda[i];
4990 /* Cleanup the over mapped high alias */
4993 @@ -102,10 +107,6 @@ void __init x86_64_start_kernel(char * r
4995 early_printk("Kernel alive\n");
4997 - for (i = 0; i < NR_CPUS; i++)
4998 - cpu_pda(i) = &boot_cpu_pda[i];
5001 copy_bootdata(__va(real_mode_data));
5003 reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
5004 diff -urNp linux-2.6.25.10/arch/x86/kernel/head_64.S linux-2.6.25.10/arch/x86/kernel/head_64.S
5005 --- linux-2.6.25.10/arch/x86/kernel/head_64.S 2008-07-02 23:46:47.000000000 -0400
5006 +++ linux-2.6.25.10/arch/x86/kernel/head_64.S 2008-07-03 16:53:25.000000000 -0400
5007 @@ -185,6 +185,10 @@ ENTRY(secondary_startup_64)
5008 btl $20,%edi /* No Execute supported? */
5010 btsl $_EFER_NX, %eax
5011 + movq $(init_level4_pgt), %rdi
5012 + addq phys_base(%rip), %rdi
5013 + btsq $_PAGE_BIT_NX, 8*258(%rdi)
5014 + btsq $_PAGE_BIT_NX, 8*388(%rdi)
5015 1: wrmsr /* Make changes effective */
5018 @@ -254,6 +258,9 @@ ENTRY(secondary_startup_64)
5019 pushq %rax # target address in negative space
5025 /* SMP bootup changes these two */
5028 @@ -264,9 +271,7 @@ ENTRY(secondary_startup_64)
5030 .quad init_thread_union+THREAD_SIZE-8
5036 #ifdef CONFIG_EARLY_PRINTK
5037 .macro early_idt_tramp first, last
5039 @@ -319,15 +324,18 @@ ENTRY(early_idt_handler)
5042 #ifdef CONFIG_EARLY_PRINTK
5044 early_recursion_flag:
5047 + .section .rodata,"a",@progbits
5049 .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
5052 #endif /* CONFIG_EARLY_PRINTK */
5054 + .section .rodata,"a",@progbits
5057 #define NEXT_PAGE(name) \
5058 @@ -352,7 +360,9 @@ NEXT_PAGE(init_level4_pgt)
5059 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5061 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5064 + .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
5066 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
5067 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
5069 @@ -360,6 +370,9 @@ NEXT_PAGE(level3_ident_pgt)
5070 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5073 +NEXT_PAGE(level3_vmalloc_pgt)
5076 NEXT_PAGE(level3_kernel_pgt)
5078 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
5079 @@ -401,19 +414,12 @@ NEXT_PAGE(level2_spare_pgt)
5085 .globl cpu_gdt_descr
5087 - .word gdt_end-cpu_gdt_table-1
5099 /* This must match the first entry in level2_kernel_pgt */
5100 @@ -423,8 +429,7 @@ ENTRY(phys_base)
5101 * IRET will check the segment types kkeil 2000/10/28
5102 * Also sysret mandates a special GDT layout
5105 - .section .data.page_aligned, "aw"
5109 /* The TLS descriptors are currently at a different place compared to i386.
5110 @@ -443,15 +448,15 @@ ENTRY(cpu_gdt_table)
5112 .quad 0,0,0 /* three TLS descriptors */
5113 .quad 0x0000f40000000000 /* node/CPU stored in limit */
5115 /* asm/segment.h:GDT_ENTRIES must match this */
5116 /* This should be a multiple of the cache line size */
5117 - /* GDTs of other CPUs are now dynamically allocated */
5119 /* zero the remaining page */
5120 .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
5122 + .fill (NR_CPUS-1) * (PAGE_SIZE),1,0 /* other CPU's GDT */
5125 - .section .bss, "aw", @nobits
5126 .align L1_CACHE_BYTES
5129 diff -urNp linux-2.6.25.10/arch/x86/kernel/hpet.c linux-2.6.25.10/arch/x86/kernel/hpet.c
5130 --- linux-2.6.25.10/arch/x86/kernel/hpet.c 2008-07-02 23:46:47.000000000 -0400
5131 +++ linux-2.6.25.10/arch/x86/kernel/hpet.c 2008-07-03 16:53:25.000000000 -0400
5132 @@ -138,7 +138,7 @@ static void hpet_reserve_platform_timers
5133 hd.hd_irq[1] = HPET_LEGACY_RTC;
5135 for (i = 2; i < nrtimers; timer++, i++)
5136 - hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
5137 + hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
5138 Tn_INT_ROUTE_CNF_SHIFT;
5141 diff -urNp linux-2.6.25.10/arch/x86/kernel/i386_ksyms_32.c linux-2.6.25.10/arch/x86/kernel/i386_ksyms_32.c
5142 --- linux-2.6.25.10/arch/x86/kernel/i386_ksyms_32.c 2008-07-02 23:46:47.000000000 -0400
5143 +++ linux-2.6.25.10/arch/x86/kernel/i386_ksyms_32.c 2008-07-03 16:53:25.000000000 -0400
5145 #include <asm/desc.h>
5146 #include <asm/pgtable.h>
5148 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
5150 EXPORT_SYMBOL(__down_failed);
5151 EXPORT_SYMBOL(__down_failed_interruptible);
5152 EXPORT_SYMBOL(__down_failed_trylock);
5153 EXPORT_SYMBOL(__up_wakeup);
5154 /* Networking helper routines. */
5155 EXPORT_SYMBOL(csum_partial_copy_generic);
5156 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
5157 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
5159 EXPORT_SYMBOL(__get_user_1);
5160 EXPORT_SYMBOL(__get_user_2);
5161 @@ -24,3 +28,7 @@ EXPORT_SYMBOL(strstr);
5163 EXPORT_SYMBOL(csum_partial);
5164 EXPORT_SYMBOL(empty_zero_page);
5166 +#ifdef CONFIG_PAX_KERNEXEC
5167 +EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
5169 diff -urNp linux-2.6.25.10/arch/x86/kernel/init_task.c linux-2.6.25.10/arch/x86/kernel/init_task.c
5170 --- linux-2.6.25.10/arch/x86/kernel/init_task.c 2008-07-02 23:46:47.000000000 -0400
5171 +++ linux-2.6.25.10/arch/x86/kernel/init_task.c 2008-07-03 16:53:25.000000000 -0400
5172 @@ -43,5 +43,5 @@ EXPORT_SYMBOL(init_task);
5173 * section. Since TSS's are completely CPU-local, we want them
5174 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
5176 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
5178 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
5179 +EXPORT_SYMBOL(init_tss);
5180 diff -urNp linux-2.6.25.10/arch/x86/kernel/ioport.c linux-2.6.25.10/arch/x86/kernel/ioport.c
5181 --- linux-2.6.25.10/arch/x86/kernel/ioport.c 2008-07-02 23:46:47.000000000 -0400
5182 +++ linux-2.6.25.10/arch/x86/kernel/ioport.c 2008-07-03 16:53:25.000000000 -0400
5184 #include <linux/slab.h>
5185 #include <linux/thread_info.h>
5186 #include <linux/syscalls.h>
5187 +#include <linux/grsecurity.h>
5189 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
5190 static void set_bitmap(unsigned long *bitmap, unsigned int base,
5191 @@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
5193 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
5195 +#ifdef CONFIG_GRKERNSEC_IO
5197 + gr_handle_ioperm();
5201 if (turn_on && !capable(CAP_SYS_RAWIO))
5204 @@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
5205 * because the ->io_bitmap_max value must match the bitmap
5208 - tss = &per_cpu(init_tss, get_cpu());
5209 + tss = init_tss + get_cpu();
5211 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5213 diff -urNp linux-2.6.25.10/arch/x86/kernel/irq_32.c linux-2.6.25.10/arch/x86/kernel/irq_32.c
5214 --- linux-2.6.25.10/arch/x86/kernel/irq_32.c 2008-07-02 23:46:47.000000000 -0400
5215 +++ linux-2.6.25.10/arch/x86/kernel/irq_32.c 2008-07-03 16:53:25.000000000 -0400
5216 @@ -115,7 +115,7 @@ unsigned int do_IRQ(struct pt_regs *regs
5219 /* build the stack frame on the IRQ stack */
5220 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5221 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5222 irqctx->tinfo.task = curctx->tinfo.task;
5223 irqctx->tinfo.previous_esp = current_stack_pointer;
5225 @@ -211,7 +211,7 @@ asmlinkage void do_softirq(void)
5226 irqctx->tinfo.previous_esp = current_stack_pointer;
5228 /* build the stack frame on the softirq stack */
5229 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5230 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5233 " xchgl %%ebx,%%esp \n"
5234 diff -urNp linux-2.6.25.10/arch/x86/kernel/kprobes.c linux-2.6.25.10/arch/x86/kernel/kprobes.c
5235 --- linux-2.6.25.10/arch/x86/kernel/kprobes.c 2008-07-02 23:46:47.000000000 -0400
5236 +++ linux-2.6.25.10/arch/x86/kernel/kprobes.c 2008-07-03 16:53:25.000000000 -0400
5237 @@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
5240 } __attribute__((packed)) * jop;
5241 - jop = (struct __arch_jmp_op *)from;
5243 +#ifdef CONFIG_PAX_KERNEXEC
5244 + unsigned long cr0;
5247 + jop = (struct __arch_jmp_op *)(ktla_ktva(from));
5249 +#ifdef CONFIG_PAX_KERNEXEC
5250 + pax_open_kernel(cr0);
5253 jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
5254 jop->op = RELATIVEJUMP_INSTRUCTION;
5256 +#ifdef CONFIG_PAX_KERNEXEC
5257 + pax_close_kernel(cr0);
5263 @@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
5265 static void __kprobes arch_copy_kprobe(struct kprobe *p)
5267 - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5269 +#ifdef CONFIG_PAX_KERNEXEC
5270 + unsigned long cr0;
5273 +#ifdef CONFIG_PAX_KERNEXEC
5274 + pax_open_kernel(cr0);
5277 + memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5279 +#ifdef CONFIG_PAX_KERNEXEC
5280 + pax_close_kernel(cr0);
5285 - if (can_boost(p->addr))
5286 + if (can_boost(ktla_ktva(p->addr)))
5287 p->ainsn.boostable = 0;
5289 p->ainsn.boostable = -1;
5291 - p->opcode = *p->addr;
5292 + p->opcode = *(ktla_ktva(p->addr));
5295 int __kprobes arch_prepare_kprobe(struct kprobe *p)
5296 @@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
5297 if (p->opcode == BREAKPOINT_INSTRUCTION)
5298 regs->ip = (unsigned long)p->addr;
5300 - regs->ip = (unsigned long)p->ainsn.insn;
5301 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5304 /* Called with kretprobe_lock held */
5305 @@ -450,7 +478,7 @@ static void __kprobes setup_singlestep(s
5306 if (p->ainsn.boostable == 1 && !p->post_handler) {
5307 /* Boost up -- we can execute copied instructions directly */
5308 reset_current_kprobe();
5309 - regs->ip = (unsigned long)p->ainsn.insn;
5310 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5311 preempt_enable_no_resched();
5314 @@ -772,7 +800,7 @@ static void __kprobes resume_execution(s
5315 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
5317 unsigned long *tos = stack_addr(regs);
5318 - unsigned long copy_ip = (unsigned long)p->ainsn.insn;
5319 + unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
5320 unsigned long orig_ip = (unsigned long)p->addr;
5321 kprobe_opcode_t *insn = p->ainsn.insn;
5323 @@ -956,7 +984,7 @@ int __kprobes kprobe_exceptions_notify(s
5324 struct die_args *args = data;
5325 int ret = NOTIFY_DONE;
5327 - if (args->regs && user_mode_vm(args->regs))
5328 + if (args->regs && user_mode(args->regs))
5332 diff -urNp linux-2.6.25.10/arch/x86/kernel/ldt.c linux-2.6.25.10/arch/x86/kernel/ldt.c
5333 --- linux-2.6.25.10/arch/x86/kernel/ldt.c 2008-07-02 23:46:47.000000000 -0400
5334 +++ linux-2.6.25.10/arch/x86/kernel/ldt.c 2008-07-03 16:53:25.000000000 -0400
5335 @@ -65,7 +65,7 @@ static int alloc_ldt(mm_context_t *pc, i
5340 + load_LDT_nolock(pc);
5341 mask = cpumask_of_cpu(smp_processor_id());
5342 if (!cpus_equal(current->mm->cpu_vm_mask, mask))
5343 smp_call_function(flush_ldt, NULL, 1, 1);
5344 @@ -110,6 +110,24 @@ int init_new_context(struct task_struct
5345 retval = copy_ldt(&mm->context, &old_mm->context);
5346 mutex_unlock(&old_mm->context.lock);
5349 + if (tsk == current) {
5350 + mm->context.vdso = ~0UL;
5352 +#ifdef CONFIG_X86_32
5353 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5354 + mm->context.user_cs_base = 0UL;
5355 + mm->context.user_cs_limit = ~0UL;
5357 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5358 + cpus_clear(mm->context.cpu_user_cs_mask);
5369 @@ -223,6 +241,13 @@ static int write_ldt(void __user *ptr, u
5373 +#ifdef CONFIG_PAX_SEGMEXEC
5374 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
5380 fill_ldt(&ldt, &ldt_info);
5383 diff -urNp linux-2.6.25.10/arch/x86/kernel/machine_kexec_32.c linux-2.6.25.10/arch/x86/kernel/machine_kexec_32.c
5384 --- linux-2.6.25.10/arch/x86/kernel/machine_kexec_32.c 2008-07-02 23:46:47.000000000 -0400
5385 +++ linux-2.6.25.10/arch/x86/kernel/machine_kexec_32.c 2008-07-03 16:53:25.000000000 -0400
5386 @@ -30,7 +30,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
5387 static u32 kexec_pte0[1024] PAGE_ALIGNED;
5388 static u32 kexec_pte1[1024] PAGE_ALIGNED;
5390 -static void set_idt(void *newidt, __u16 limit)
5391 +static void set_idt(struct desc_struct *newidt, __u16 limit)
5393 struct desc_ptr curidt;
5395 @@ -42,7 +42,7 @@ static void set_idt(void *newidt, __u16
5399 -static void set_gdt(void *newgdt, __u16 limit)
5400 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
5402 struct desc_ptr curgdt;
5404 @@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim
5405 local_irq_disable();
5407 control_page = page_address(image->control_code_page);
5408 - memcpy(control_page, relocate_kernel, PAGE_SIZE);
5409 + memcpy(control_page, ktla_ktva(relocate_kernel), PAGE_SIZE);
5411 page_list[PA_CONTROL_PAGE] = __pa(control_page);
5412 - page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
5413 + page_list[VA_CONTROL_PAGE] = ktla_ktva((unsigned long)relocate_kernel);
5414 page_list[PA_PGD] = __pa(kexec_pgd);
5415 page_list[VA_PGD] = (unsigned long)kexec_pgd;
5416 #ifdef CONFIG_X86_PAE
5417 diff -urNp linux-2.6.25.10/arch/x86/kernel/module_32.c linux-2.6.25.10/arch/x86/kernel/module_32.c
5418 --- linux-2.6.25.10/arch/x86/kernel/module_32.c 2008-07-02 23:46:47.000000000 -0400
5419 +++ linux-2.6.25.10/arch/x86/kernel/module_32.c 2008-07-03 16:53:25.000000000 -0400
5421 #include <linux/kernel.h>
5422 #include <linux/bug.h>
5424 +#include <asm/desc.h>
5427 #define DEBUGP printk
5429 @@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
5434 +#ifdef CONFIG_PAX_KERNEXEC
5435 + return vmalloc(size);
5437 return vmalloc_exec(size);
5442 +#ifdef CONFIG_PAX_KERNEXEC
5443 +void *module_alloc_exec(unsigned long size)
5445 + struct vm_struct *area;
5450 + area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
5452 + return area->addr;
5458 /* Free memory returned from module_alloc */
5459 void module_free(struct module *mod, void *module_region)
5460 @@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
5464 +#ifdef CONFIG_PAX_KERNEXEC
5465 +void module_free_exec(struct module *mod, void *module_region)
5467 + struct vm_struct **p, *tmp;
5469 + if (!module_region)
5472 + if ((PAGE_SIZE-1) & (unsigned long)module_region) {
5473 + printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
5478 + write_lock(&vmlist_lock);
5479 + for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
5480 + if (tmp->addr == module_region)
5484 + unsigned long cr0;
5486 + pax_open_kernel(cr0);
5487 + memset(tmp->addr, 0xCC, tmp->size);
5488 + pax_close_kernel(cr0);
5493 + write_unlock(&vmlist_lock);
5496 + printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
5503 /* We don't need anything special. */
5504 int module_frob_arch_sections(Elf_Ehdr *hdr,
5506 @@ -63,14 +125,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5508 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
5510 - uint32_t *location;
5511 + uint32_t *plocation, location;
5513 +#ifdef CONFIG_PAX_KERNEXEC
5514 + unsigned long cr0;
5517 DEBUGP("Applying relocate section %u to %u\n", relsec,
5518 sechdrs[relsec].sh_info);
5519 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
5520 /* This is where to make the change */
5521 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
5522 - + rel[i].r_offset;
5523 + plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
5524 + location = (uint32_t)plocation;
5525 + if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
5526 + plocation = ktla_ktva((void *)plocation);
5527 /* This is the symbol it is referring to. Note that all
5528 undefined symbols have been resolved. */
5529 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
5530 @@ -78,12 +146,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5532 switch (ELF32_R_TYPE(rel[i].r_info)) {
5535 +#ifdef CONFIG_PAX_KERNEXEC
5536 + pax_open_kernel(cr0);
5539 /* We add the value into the location given */
5540 - *location += sym->st_value;
5541 + *plocation += sym->st_value;
5543 +#ifdef CONFIG_PAX_KERNEXEC
5544 + pax_close_kernel(cr0);
5550 +#ifdef CONFIG_PAX_KERNEXEC
5551 + pax_open_kernel(cr0);
5554 /* Add the value, subtract its postition */
5555 - *location += sym->st_value - (uint32_t)location;
5556 + *plocation += sym->st_value - location;
5558 +#ifdef CONFIG_PAX_KERNEXEC
5559 + pax_close_kernel(cr0);
5564 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
5565 diff -urNp linux-2.6.25.10/arch/x86/kernel/module_64.c linux-2.6.25.10/arch/x86/kernel/module_64.c
5566 --- linux-2.6.25.10/arch/x86/kernel/module_64.c 2008-07-02 23:46:47.000000000 -0400
5567 +++ linux-2.6.25.10/arch/x86/kernel/module_64.c 2008-07-03 16:53:25.000000000 -0400
5568 @@ -39,7 +39,7 @@ void module_free(struct module *mod, voi
5572 -void *module_alloc(unsigned long size)
5573 +static void *__module_alloc(unsigned long size, pgprot_t prot)
5575 struct vm_struct *area;
5577 @@ -53,8 +53,31 @@ void *module_alloc(unsigned long size)
5581 - return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
5582 + return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
5585 +#ifdef CONFIG_PAX_KERNEXEC
5586 +void *module_alloc(unsigned long size)
5588 + return __module_alloc(size, PAGE_KERNEL);
5591 +void module_free_exec(struct module *mod, void *module_region)
5593 + module_free(mod, module_region);
5596 +void *module_alloc_exec(unsigned long size)
5598 + return __module_alloc(size, PAGE_KERNEL_RX);
5601 +void *module_alloc(unsigned long size)
5603 + return __module_alloc(size, PAGE_KERNEL_EXEC);
5609 /* We don't need anything special. */
5610 @@ -76,7 +99,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
5611 Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
5617 +#ifdef CONFIG_PAX_KERNEXEC
5618 + unsigned long cr0;
5621 DEBUGP("Applying relocate section %u to %u\n", relsec,
5622 sechdrs[relsec].sh_info);
5623 @@ -100,21 +127,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
5628 +#ifdef CONFIG_PAX_KERNEXEC
5629 + pax_open_kernel(cr0);
5634 +#ifdef CONFIG_PAX_KERNEXEC
5635 + pax_close_kernel(cr0);
5641 +#ifdef CONFIG_PAX_KERNEXEC
5642 + pax_open_kernel(cr0);
5647 +#ifdef CONFIG_PAX_KERNEXEC
5648 + pax_close_kernel(cr0);
5651 if (val != *(u32 *)loc)
5656 +#ifdef CONFIG_PAX_KERNEXEC
5657 + pax_open_kernel(cr0);
5662 +#ifdef CONFIG_PAX_KERNEXEC
5663 + pax_close_kernel(cr0);
5666 if ((s64)val != *(s32 *)loc)
5672 +#ifdef CONFIG_PAX_KERNEXEC
5673 + pax_open_kernel(cr0);
5678 +#ifdef CONFIG_PAX_KERNEXEC
5679 + pax_close_kernel(cr0);
5683 if ((s64)val != *(s32 *)loc)
5685 diff -urNp linux-2.6.25.10/arch/x86/kernel/paravirt.c linux-2.6.25.10/arch/x86/kernel/paravirt.c
5686 --- linux-2.6.25.10/arch/x86/kernel/paravirt.c 2008-07-02 23:46:47.000000000 -0400
5687 +++ linux-2.6.25.10/arch/x86/kernel/paravirt.c 2008-07-03 16:53:25.000000000 -0400
5688 @@ -42,7 +42,7 @@ void _paravirt_nop(void)
5692 -static void __init default_banner(void)
5693 +static void default_banner(void)
5695 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
5697 @@ -159,7 +159,7 @@ unsigned paravirt_patch_insns(void *insn
5698 if (insn_len > len || start == NULL)
5701 - memcpy(insnbuf, start, insn_len);
5702 + memcpy(insnbuf, ktla_ktva(start), insn_len);
5706 @@ -277,21 +277,21 @@ enum paravirt_lazy_mode paravirt_get_laz
5707 return __get_cpu_var(paravirt_lazy_mode);
5710 -struct pv_info pv_info = {
5711 +struct pv_info pv_info __read_only = {
5712 .name = "bare hardware",
5713 .paravirt_enabled = 0,
5715 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
5718 -struct pv_init_ops pv_init_ops = {
5719 +struct pv_init_ops pv_init_ops __read_only = {
5720 .patch = native_patch,
5721 .banner = default_banner,
5722 .arch_setup = paravirt_nop,
5723 .memory_setup = machine_specific_memory_setup,
5726 -struct pv_time_ops pv_time_ops = {
5727 +struct pv_time_ops pv_time_ops __read_only = {
5728 .time_init = hpet_time_init,
5729 .get_wallclock = native_get_wallclock,
5730 .set_wallclock = native_set_wallclock,
5731 @@ -299,7 +299,7 @@ struct pv_time_ops pv_time_ops = {
5732 .get_cpu_khz = native_calculate_cpu_khz,
5735 -struct pv_irq_ops pv_irq_ops = {
5736 +struct pv_irq_ops pv_irq_ops __read_only = {
5737 .init_IRQ = native_init_IRQ,
5738 .save_fl = native_save_fl,
5739 .restore_fl = native_restore_fl,
5740 @@ -309,7 +309,7 @@ struct pv_irq_ops pv_irq_ops = {
5741 .halt = native_halt,
5744 -struct pv_cpu_ops pv_cpu_ops = {
5745 +struct pv_cpu_ops pv_cpu_ops __read_only = {
5746 .cpuid = native_cpuid,
5747 .get_debugreg = native_get_debugreg,
5748 .set_debugreg = native_set_debugreg,
5749 @@ -355,7 +355,7 @@ struct pv_cpu_ops pv_cpu_ops = {
5753 -struct pv_apic_ops pv_apic_ops = {
5754 +struct pv_apic_ops pv_apic_ops __read_only = {
5755 #ifdef CONFIG_X86_LOCAL_APIC
5756 .apic_write = native_apic_write,
5757 .apic_write_atomic = native_apic_write_atomic,
5758 @@ -366,7 +366,7 @@ struct pv_apic_ops pv_apic_ops = {
5762 -struct pv_mmu_ops pv_mmu_ops = {
5763 +struct pv_mmu_ops pv_mmu_ops __read_only = {
5764 #ifndef CONFIG_X86_64
5765 .pagetable_setup_start = native_pagetable_setup_start,
5766 .pagetable_setup_done = native_pagetable_setup_done,
5767 diff -urNp linux-2.6.25.10/arch/x86/kernel/process_32.c linux-2.6.25.10/arch/x86/kernel/process_32.c
5768 --- linux-2.6.25.10/arch/x86/kernel/process_32.c 2008-07-02 23:46:47.000000000 -0400
5769 +++ linux-2.6.25.10/arch/x86/kernel/process_32.c 2008-07-03 16:53:25.000000000 -0400
5770 @@ -66,8 +66,10 @@ EXPORT_SYMBOL(boot_option_idle_override)
5771 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
5772 EXPORT_PER_CPU_SYMBOL(current_task);
5775 DEFINE_PER_CPU(int, cpu_number);
5776 EXPORT_PER_CPU_SYMBOL(cpu_number);
5780 * Return saved PC of a blocked thread.
5781 @@ -75,6 +77,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
5782 unsigned long thread_saved_pc(struct task_struct *tsk)
5784 return ((unsigned long *)tsk->thread.sp)[3];
5785 +//XXX return tsk->thread.eip;
5789 @@ -333,7 +336,7 @@ void __show_registers(struct pt_regs *re
5791 unsigned short ss, gs;
5793 - if (user_mode_vm(regs)) {
5794 + if (user_mode(regs)) {
5796 ss = regs->ss & 0xffff;
5797 savesegment(gs, gs);
5798 @@ -411,8 +414,8 @@ int kernel_thread(int (*fn)(void *), voi
5799 regs.bx = (unsigned long) fn;
5800 regs.dx = (unsigned long) arg;
5802 - regs.ds = __USER_DS;
5803 - regs.es = __USER_DS;
5804 + regs.ds = __KERNEL_DS;
5805 + regs.es = __KERNEL_DS;
5806 regs.fs = __KERNEL_PERCPU;
5808 regs.ip = (unsigned long) kernel_thread_helper;
5809 @@ -434,7 +437,7 @@ void exit_thread(void)
5810 struct task_struct *tsk = current;
5811 struct thread_struct *t = &tsk->thread;
5812 int cpu = get_cpu();
5813 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
5814 + struct tss_struct *tss = init_tss + cpu;
5816 kfree(t->io_bitmap_ptr);
5817 t->io_bitmap_ptr = NULL;
5818 @@ -455,6 +458,7 @@ void flush_thread(void)
5820 struct task_struct *tsk = current;
5822 + __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
5823 tsk->thread.debugreg0 = 0;
5824 tsk->thread.debugreg1 = 0;
5825 tsk->thread.debugreg2 = 0;
5826 @@ -493,7 +497,7 @@ int copy_thread(int nr, unsigned long cl
5827 struct task_struct *tsk;
5830 - childregs = task_pt_regs(p);
5831 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
5835 @@ -522,6 +526,7 @@ int copy_thread(int nr, unsigned long cl
5836 * Set a new TLS for the child thread?
5838 if (clone_flags & CLONE_SETTLS)
5839 +//XXX needs set_fs()?
5840 err = do_set_thread_area(p, -1,
5841 (struct user_desc __user *)childregs->si, 0);
5843 @@ -668,7 +673,7 @@ struct task_struct * __switch_to(struct
5844 struct thread_struct *prev = &prev_p->thread,
5845 *next = &next_p->thread;
5846 int cpu = smp_processor_id();
5847 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
5848 + struct tss_struct *tss = init_tss + cpu;
5850 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
5852 @@ -696,6 +701,11 @@ struct task_struct * __switch_to(struct
5854 savesegment(gs, prev->gs);
5856 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5857 + if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
5858 + __set_fs(task_thread_info(next_p)->addr_limit, cpu);
5862 * Load the per-thread Thread-Local Storage descriptor.
5864 @@ -834,15 +844,27 @@ unsigned long get_wchan(struct task_stru
5868 -unsigned long arch_align_stack(unsigned long sp)
5869 +#ifdef CONFIG_PAX_RANDKSTACK
5870 +asmlinkage void pax_randomize_kstack(void)
5872 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
5873 - sp -= get_random_int() % 8192;
5876 + struct thread_struct *thread = ¤t->thread;
5877 + unsigned long time;
5879 -unsigned long arch_randomize_brk(struct mm_struct *mm)
5881 - unsigned long range_end = mm->brk + 0x02000000;
5882 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
5883 + if (!randomize_va_space)
5888 + /* P4 seems to return a 0 LSB, ignore it */
5889 +#ifdef CONFIG_MPENTIUM4
5897 + thread->sp0 ^= time;
5898 + load_sp0(init_tss + smp_processor_id(), thread);
5901 diff -urNp linux-2.6.25.10/arch/x86/kernel/process_64.c linux-2.6.25.10/arch/x86/kernel/process_64.c
5902 --- linux-2.6.25.10/arch/x86/kernel/process_64.c 2008-07-02 23:46:47.000000000 -0400
5903 +++ linux-2.6.25.10/arch/x86/kernel/process_64.c 2008-07-03 16:53:25.000000000 -0400
5904 @@ -166,6 +166,8 @@ static inline void play_dead(void)
5907 current_thread_info()->status |= TS_POLLING;
5908 + current->stack_canary = pax_get_random_long();
5909 + write_pda(stack_canary, current->stack_canary);
5910 /* endless idle loop with no priority at all */
5912 tick_nohz_stop_sched_tick();
5913 @@ -397,7 +399,7 @@ void exit_thread(void)
5914 struct thread_struct *t = &me->thread;
5916 if (me->thread.io_bitmap_ptr) {
5917 - struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
5918 + struct tss_struct *tss = init_tss + get_cpu();
5920 kfree(t->io_bitmap_ptr);
5921 t->io_bitmap_ptr = NULL;
5922 @@ -621,7 +623,7 @@ __switch_to(struct task_struct *prev_p,
5923 struct thread_struct *prev = &prev_p->thread,
5924 *next = &next_p->thread;
5925 int cpu = smp_processor_id();
5926 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
5927 + struct tss_struct *tss = init_tss + cpu;
5929 /* we're going to use this soon, after a few expensive things */
5930 if (next_p->fpu_counter>5)
5931 @@ -696,7 +698,6 @@ __switch_to(struct task_struct *prev_p,
5932 write_pda(kernelstack,
5933 (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
5934 #ifdef CONFIG_CC_STACKPROTECTOR
5935 - write_pda(stack_canary, next_p->stack_canary);
5937 * Build time only check to make sure the stack_canary is at
5938 * offset 40 in the pda; this is a gcc ABI requirement
5939 @@ -910,16 +911,3 @@ long sys_arch_prctl(int code, unsigned l
5941 return do_arch_prctl(current, code, addr);
5944 -unsigned long arch_align_stack(unsigned long sp)
5946 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
5947 - sp -= get_random_int() % 8192;
5951 -unsigned long arch_randomize_brk(struct mm_struct *mm)
5953 - unsigned long range_end = mm->brk + 0x02000000;
5954 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
5956 diff -urNp linux-2.6.25.10/arch/x86/kernel/ptrace.c linux-2.6.25.10/arch/x86/kernel/ptrace.c
5957 --- linux-2.6.25.10/arch/x86/kernel/ptrace.c 2008-07-02 23:46:47.000000000 -0400
5958 +++ linux-2.6.25.10/arch/x86/kernel/ptrace.c 2008-07-03 16:53:25.000000000 -0400
5959 @@ -1457,7 +1457,7 @@ void send_sigtrap(struct task_struct *ts
5960 info.si_code = TRAP_BRKPT;
5963 - info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
5964 + info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
5966 /* Send us the fake SIGTRAP */
5967 force_sig_info(SIGTRAP, &info, tsk);
5968 diff -urNp linux-2.6.25.10/arch/x86/kernel/reboot.c linux-2.6.25.10/arch/x86/kernel/reboot.c
5969 --- linux-2.6.25.10/arch/x86/kernel/reboot.c 2008-07-02 23:46:47.000000000 -0400
5970 +++ linux-2.6.25.10/arch/x86/kernel/reboot.c 2008-07-03 16:53:25.000000000 -0400
5971 @@ -28,7 +28,7 @@ void (*pm_power_off)(void);
5972 EXPORT_SYMBOL(pm_power_off);
5974 static long no_idt[3];
5975 -static int reboot_mode;
5976 +static unsigned short reboot_mode;
5977 enum reboot_type reboot_type = BOOT_KBD;
5980 @@ -186,7 +186,7 @@ static struct dmi_system_id __initdata r
5981 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
5985 + { NULL, NULL, {{0, NULL}}, NULL}
5988 static int __init reboot_init(void)
5989 @@ -202,15 +202,15 @@ core_initcall(reboot_init);
5990 controller to pulse the CPU reset line, which is more thorough, but
5991 doesn't work with at least one type of 486 motherboard. It is easy
5992 to stop this code working; hence the copious comments. */
5993 -static unsigned long long
5994 -real_mode_gdt_entries [3] =
5995 +static struct desc_struct
5996 +real_mode_gdt_entries [3] __read_only =
5998 - 0x0000000000000000ULL, /* Null descriptor */
5999 - 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
6000 - 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
6001 + {{{0x00000000, 0x00000000}}}, /* Null descriptor */
6002 + {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
6003 + {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
6006 -static struct desc_ptr
6007 +static const struct desc_ptr
6008 real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
6009 real_mode_idt = { 0x3ff, 0 };
6011 @@ -232,7 +232,7 @@ real_mode_idt = { 0x3ff, 0 };
6013 More could be done here to set up the registers as if a CPU reset had
6014 occurred; hopefully real BIOSs don't assume much. */
6015 -static unsigned char real_mode_switch [] =
6016 +static const unsigned char real_mode_switch [] =
6018 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
6019 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
6020 @@ -246,7 +246,7 @@ static unsigned char real_mode_switch []
6021 0x24, 0x10, /* f: andb $0x10,al */
6022 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
6024 -static unsigned char jump_to_bios [] =
6025 +static const unsigned char jump_to_bios [] =
6027 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
6029 @@ -256,7 +256,7 @@ static unsigned char jump_to_bios [] =
6030 * specified by the code and length parameters.
6031 * We assume that length will aways be less that 100!
6033 -void machine_real_restart(unsigned char *code, int length)
6034 +void machine_real_restart(const unsigned char *code, unsigned int length)
6036 local_irq_disable();
6038 @@ -276,8 +276,8 @@ void machine_real_restart(unsigned char
6039 /* Remap the kernel at virtual address zero, as well as offset zero
6040 from the kernel segment. This assumes the kernel segment starts at
6041 virtual address PAGE_OFFSET. */
6042 - memcpy(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
6043 - sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
6044 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
6045 + min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
6048 * Use `swapper_pg_dir' as our page directory.
6049 @@ -289,16 +289,15 @@ void machine_real_restart(unsigned char
6050 boot)". This seems like a fairly standard thing that gets set by
6051 REBOOT.COM programs, and the previous reset routine did this
6053 - *((unsigned short *)0x472) = reboot_mode;
6054 + *(unsigned short *)(__va(0x472)) = reboot_mode;
6056 /* For the switch to real mode, copy some code to low memory. It has
6057 to be in the first 64k because it is running in 16-bit mode, and it
6058 has to have the same physical and virtual address, because it turns
6059 off paging. Copy it near the end of the first page, out of the way
6060 of BIOS variables. */
6061 - memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
6062 - real_mode_switch, sizeof (real_mode_switch));
6063 - memcpy((void *)(0x1000 - 100), code, length);
6064 + memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
6065 + memcpy(__va(0x1000 - 100), code, length);
6067 /* Set up the IDT for real mode. */
6068 load_idt(&real_mode_idt);
6069 diff -urNp linux-2.6.25.10/arch/x86/kernel/setup_32.c linux-2.6.25.10/arch/x86/kernel/setup_32.c
6070 --- linux-2.6.25.10/arch/x86/kernel/setup_32.c 2008-07-02 23:46:47.000000000 -0400
6071 +++ linux-2.6.25.10/arch/x86/kernel/setup_32.c 2008-07-03 16:53:25.000000000 -0400
6073 #include <setup_arch.h>
6074 #include <bios_ebda.h>
6075 #include <asm/cacheflush.h>
6076 +#include <asm/boot.h>
6078 /* This value is set up by the early boot code to point to the value
6079 immediately after the boot time page tables. It contains a *physical*
6080 @@ -613,8 +614,8 @@ void __init setup_bootmem_allocator(void
6081 * the (very unlikely) case of us accidentally initializing the
6082 * bootmem allocator with an invalid RAM area.
6084 - reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
6085 - bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text),
6086 + reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
6087 + bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR,
6091 @@ -743,14 +744,14 @@ void __init setup_arch(char **cmdline_p)
6093 if (!boot_params.hdr.root_flags)
6094 root_mountflags &= ~MS_RDONLY;
6095 - init_mm.start_code = (unsigned long) _text;
6096 - init_mm.end_code = (unsigned long) _etext;
6097 + init_mm.start_code = ktla_ktva((unsigned long) _text);
6098 + init_mm.end_code = ktla_ktva((unsigned long) _etext);
6099 init_mm.end_data = (unsigned long) _edata;
6100 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
6102 - code_resource.start = virt_to_phys(_text);
6103 - code_resource.end = virt_to_phys(_etext)-1;
6104 - data_resource.start = virt_to_phys(_etext);
6105 + code_resource.start = virt_to_phys(ktla_ktva(_text));
6106 + code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
6107 + data_resource.start = virt_to_phys(_data);
6108 data_resource.end = virt_to_phys(_edata)-1;
6109 bss_resource.start = virt_to_phys(&__bss_start);
6110 bss_resource.end = virt_to_phys(&__bss_stop)-1;
6111 diff -urNp linux-2.6.25.10/arch/x86/kernel/setup64.c linux-2.6.25.10/arch/x86/kernel/setup64.c
6112 --- linux-2.6.25.10/arch/x86/kernel/setup64.c 2008-07-02 23:46:47.000000000 -0400
6113 +++ linux-2.6.25.10/arch/x86/kernel/setup64.c 2008-07-03 16:53:25.000000000 -0400
6114 @@ -36,15 +36,13 @@ struct x8664_pda *_cpu_pda[NR_CPUS] __re
6115 EXPORT_SYMBOL(_cpu_pda);
6116 struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
6118 -struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
6119 +struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
6121 char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
6123 unsigned long __supported_pte_mask __read_mostly = ~0UL;
6124 EXPORT_SYMBOL_GPL(__supported_pte_mask);
6126 -static int do_not_nx __cpuinitdata = 0;
6129 Control non executable mappings for 64bit processes.
6131 @@ -57,16 +55,14 @@ static int __init nonx_setup(char *str)
6133 if (!strncmp(str, "on", 2)) {
6134 __supported_pte_mask |= _PAGE_NX;
6136 } else if (!strncmp(str, "off", 3)) {
6138 __supported_pte_mask &= ~_PAGE_NX;
6142 early_param("noexec", nonx_setup);
6144 -int force_personality32 = 0;
6145 +int force_personality32;
6148 Control non executable heap for 32bit processes.
6149 @@ -226,7 +222,7 @@ void __cpuinit check_efer(void)
6152 rdmsrl(MSR_EFER, efer);
6153 - if (!(efer & EFER_NX) || do_not_nx) {
6154 + if (!(efer & EFER_NX)) {
6155 __supported_pte_mask &= ~_PAGE_NX;
6158 @@ -249,12 +245,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
6159 void __cpuinit cpu_init (void)
6161 int cpu = stack_smp_processor_id();
6162 - struct tss_struct *t = &per_cpu(init_tss, cpu);
6163 + struct tss_struct *t = init_tss + cpu;
6164 struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
6166 char *estacks = NULL;
6167 struct task_struct *me;
6169 + struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)get_cpu_gdt_table(cpu)};
6171 /* CPU 0 is initialised in head64.c */
6173 @@ -272,14 +269,12 @@ void __cpuinit cpu_init (void)
6174 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
6177 - * Initialize the per-CPU GDT with the boot GDT,
6178 - * and set up the GDT descriptor:
6179 + * Initialize the per-CPU GDT with the boot GDT:
6182 - memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE);
6183 + memcpy(get_cpu_gdt_table(cpu), get_cpu_gdt_table(0), GDT_SIZE);
6185 - cpu_gdt_descr[cpu].size = GDT_SIZE;
6186 - load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
6187 + load_gdt(&cpu_gdt_descr);
6188 load_idt((const struct desc_ptr *)&idt_descr);
6190 memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
6191 diff -urNp linux-2.6.25.10/arch/x86/kernel/signal_32.c linux-2.6.25.10/arch/x86/kernel/signal_32.c
6192 --- linux-2.6.25.10/arch/x86/kernel/signal_32.c 2008-07-02 23:46:47.000000000 -0400
6193 +++ linux-2.6.25.10/arch/x86/kernel/signal_32.c 2008-07-03 16:53:25.000000000 -0400
6194 @@ -366,9 +366,9 @@ static int setup_frame(int sig, struct k
6197 if (current->binfmt->hasvdso)
6198 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
6199 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
6201 - restorer = &frame->retcode;
6202 + restorer = (void __user *)&frame->retcode;
6203 if (ka->sa.sa_flags & SA_RESTORER)
6204 restorer = ka->sa.sa_restorer;
6206 @@ -463,7 +463,7 @@ static int setup_rt_frame(int sig, struc
6209 /* Set up to return from userspace. */
6210 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6211 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6212 if (ka->sa.sa_flags & SA_RESTORER)
6213 restorer = ka->sa.sa_restorer;
6214 err |= __put_user(restorer, &frame->pretcode);
6215 @@ -593,7 +593,7 @@ static void do_signal(struct pt_regs *re
6216 * before reaching here, so testing against kernel
6219 - if (!user_mode(regs))
6220 + if (!user_mode_novm(regs))
6223 if (test_thread_flag(TIF_RESTORE_SIGMASK))
6224 diff -urNp linux-2.6.25.10/arch/x86/kernel/signal_64.c linux-2.6.25.10/arch/x86/kernel/signal_64.c
6225 --- linux-2.6.25.10/arch/x86/kernel/signal_64.c 2008-07-02 23:46:47.000000000 -0400
6226 +++ linux-2.6.25.10/arch/x86/kernel/signal_64.c 2008-07-03 16:53:25.000000000 -0400
6227 @@ -252,8 +252,8 @@ static int setup_rt_frame(int sig, struc
6228 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
6229 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
6230 if (sizeof(*set) == 16) {
6231 - __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6232 - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6233 + err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6234 + err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6236 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
6238 diff -urNp linux-2.6.25.10/arch/x86/kernel/smp_32.c linux-2.6.25.10/arch/x86/kernel/smp_32.c
6239 --- linux-2.6.25.10/arch/x86/kernel/smp_32.c 2008-07-02 23:46:47.000000000 -0400
6240 +++ linux-2.6.25.10/arch/x86/kernel/smp_32.c 2008-07-03 16:53:25.000000000 -0400
6242 * about nothing of note with C stepping upwards.
6245 -DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
6246 +DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
6249 * the following functions deal with sending IPIs between CPUs.
6250 diff -urNp linux-2.6.25.10/arch/x86/kernel/smpboot_32.c linux-2.6.25.10/arch/x86/kernel/smpboot_32.c
6251 --- linux-2.6.25.10/arch/x86/kernel/smpboot_32.c 2008-07-02 23:46:47.000000000 -0400
6252 +++ linux-2.6.25.10/arch/x86/kernel/smpboot_32.c 2008-07-03 16:53:25.000000000 -0400
6253 @@ -768,6 +768,10 @@ static int __cpuinit do_boot_cpu(int api
6254 unsigned long start_eip;
6255 unsigned short nmi_high = 0, nmi_low = 0;
6257 +#ifdef CONFIG_PAX_KERNEXEC
6258 + unsigned long cr0;
6262 * Save current MTRR state in case it was changed since early boot
6263 * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
6264 @@ -784,8 +788,17 @@ static int __cpuinit do_boot_cpu(int api
6267 per_cpu(current_task, cpu) = idle;
6269 +#ifdef CONFIG_PAX_KERNEXEC
6270 + pax_open_kernel(cr0);
6273 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
6275 +#ifdef CONFIG_PAX_KERNEXEC
6276 + pax_close_kernel(cr0);
6279 idle->thread.ip = (unsigned long) start_secondary;
6280 /* start_eip had better be page-aligned! */
6281 start_eip = setup_trampoline();
6282 diff -urNp linux-2.6.25.10/arch/x86/kernel/smpboot_64.c linux-2.6.25.10/arch/x86/kernel/smpboot_64.c
6283 --- linux-2.6.25.10/arch/x86/kernel/smpboot_64.c 2008-07-02 23:46:47.000000000 -0400
6284 +++ linux-2.6.25.10/arch/x86/kernel/smpboot_64.c 2008-07-03 16:53:25.000000000 -0400
6285 @@ -559,13 +559,6 @@ static int __cpuinit do_boot_cpu(int cpu
6287 INIT_WORK(&c_idle.work, do_fork_idle);
6289 - /* allocate memory for gdts of secondary cpus. Hotplug is considered */
6290 - if (!cpu_gdt_descr[cpu].address &&
6291 - !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
6292 - printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu);
6296 /* Allocate node local memory for AP pdas */
6297 if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) {
6298 struct x8664_pda *newpda, *pda;
6299 @@ -624,7 +617,7 @@ do_rest:
6300 start_rip = setup_trampoline();
6302 init_rsp = c_idle.idle->thread.sp;
6303 - load_sp0(&per_cpu(init_tss, cpu), &c_idle.idle->thread);
6304 + load_sp0(init_tss + cpu, &c_idle.idle->thread);
6305 initial_code = start_secondary;
6306 clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
6308 diff -urNp linux-2.6.25.10/arch/x86/kernel/smpcommon_32.c linux-2.6.25.10/arch/x86/kernel/smpcommon_32.c
6309 --- linux-2.6.25.10/arch/x86/kernel/smpcommon_32.c 2008-07-02 23:46:47.000000000 -0400
6310 +++ linux-2.6.25.10/arch/x86/kernel/smpcommon_32.c 2008-07-03 16:53:25.000000000 -0400
6313 #include <linux/module.h>
6314 #include <asm/smp.h>
6315 +#include <asm/sections.h>
6317 -DEFINE_PER_CPU(unsigned long, this_cpu_off);
6318 +DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
6319 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6321 /* Initialize the CPU's GDT. This is either the boot CPU doing itself
6322 @@ -12,15 +13,22 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6323 secondary which will soon come up. */
6324 __cpuinit void init_gdt(int cpu)
6326 - struct desc_struct *gdt = get_cpu_gdt_table(cpu);
6327 + struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
6328 + unsigned long base, limit;
6330 - pack_descriptor(&gdt[GDT_ENTRY_PERCPU],
6331 - __per_cpu_offset[cpu], 0xFFFFF,
6332 - 0x2 | DESCTYPE_S, 0x8);
6334 + memcpy(gdt, get_cpu_gdt_table(0), GDT_SIZE);
6336 - gdt[GDT_ENTRY_PERCPU].s = 1;
6337 + base = __per_cpu_offset[cpu] + (unsigned long)__per_cpu_start;
6338 + limit = PERCPU_ENOUGH_ROOM - 1;
6339 + if (limit < 64*1024)
6340 + pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
6342 + pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
6344 - per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
6345 + write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
6347 + per_cpu(this_cpu_off, cpu) = base;
6348 per_cpu(cpu_number, cpu) = cpu;
6351 diff -urNp linux-2.6.25.10/arch/x86/kernel/step.c linux-2.6.25.10/arch/x86/kernel/step.c
6352 --- linux-2.6.25.10/arch/x86/kernel/step.c 2008-07-02 23:46:47.000000000 -0400
6353 +++ linux-2.6.25.10/arch/x86/kernel/step.c 2008-07-03 16:53:25.000000000 -0400
6354 @@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
6355 * and APM bios ones we just ignore here.
6357 if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
6359 + struct desc_struct *desc;
6365 mutex_lock(&child->mm->context.lock);
6366 - if (unlikely((seg >> 3) >= child->mm->context.size))
6367 - addr = -1L; /* bogus selector, access would fault */
6368 + if (unlikely(seg >= child->mm->context.size))
6371 - desc = child->mm->context.ldt + seg;
6372 - base = ((desc[0] >> 16) |
6373 - ((desc[1] & 0xff) << 16) |
6374 - (desc[1] & 0xff000000));
6375 + desc = &child->mm->context.ldt[seg];
6376 + base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
6378 /* 16-bit code segment? */
6379 - if (!((desc[1] >> 22) & 1))
6380 + if (!((desc->b >> 22) & 1))
6384 @@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
6385 unsigned char opcode[15];
6386 unsigned long addr = convert_ip_to_linear(child, regs);
6388 + if (addr == -EINVAL)
6391 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6392 for (i = 0; i < copied; i++) {
6393 switch (opcode[i]) {
6394 diff -urNp linux-2.6.25.10/arch/x86/kernel/syscall_table_32.S linux-2.6.25.10/arch/x86/kernel/syscall_table_32.S
6395 --- linux-2.6.25.10/arch/x86/kernel/syscall_table_32.S 2008-07-02 23:46:47.000000000 -0400
6396 +++ linux-2.6.25.10/arch/x86/kernel/syscall_table_32.S 2008-07-03 16:53:25.000000000 -0400
6398 +.section .rodata,"a",@progbits
6399 ENTRY(sys_call_table)
6400 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
6402 diff -urNp linux-2.6.25.10/arch/x86/kernel/sys_i386_32.c linux-2.6.25.10/arch/x86/kernel/sys_i386_32.c
6403 --- linux-2.6.25.10/arch/x86/kernel/sys_i386_32.c 2008-07-02 23:46:47.000000000 -0400
6404 +++ linux-2.6.25.10/arch/x86/kernel/sys_i386_32.c 2008-07-03 16:53:25.000000000 -0400
6405 @@ -39,6 +39,21 @@ asmlinkage int sys_pipe(unsigned long __
6409 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
6411 + unsigned long pax_task_size = TASK_SIZE;
6413 +#ifdef CONFIG_PAX_SEGMEXEC
6414 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
6415 + pax_task_size = SEGMEXEC_TASK_SIZE;
6418 + if (len > pax_task_size || addr > pax_task_size - len)
6424 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
6425 unsigned long prot, unsigned long flags,
6426 unsigned long fd, unsigned long pgoff)
6427 @@ -98,6 +113,205 @@ out:
6432 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
6433 + unsigned long len, unsigned long pgoff, unsigned long flags)
6435 + struct mm_struct *mm = current->mm;
6436 + struct vm_area_struct *vma;
6437 + unsigned long start_addr, pax_task_size = TASK_SIZE;
6439 +#ifdef CONFIG_PAX_SEGMEXEC
6440 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6441 + pax_task_size = SEGMEXEC_TASK_SIZE;
6444 + if (len > pax_task_size)
6447 + if (flags & MAP_FIXED)
6450 +#ifdef CONFIG_PAX_RANDMMAP
6451 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6455 + addr = PAGE_ALIGN(addr);
6456 + vma = find_vma(mm, addr);
6457 + if (pax_task_size - len >= addr &&
6458 + (!vma || addr + len <= vma->vm_start))
6461 + if (len > mm->cached_hole_size) {
6462 + start_addr = addr = mm->free_area_cache;
6464 + start_addr = addr = mm->mmap_base;
6465 + mm->cached_hole_size = 0;
6468 +#ifdef CONFIG_PAX_PAGEEXEC
6469 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
6470 + start_addr = 0x00110000UL;
6472 +#ifdef CONFIG_PAX_RANDMMAP
6473 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6474 + start_addr += mm->delta_mmap & 0x03FFF000UL;
6477 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
6478 + start_addr = addr = mm->mmap_base;
6480 + addr = start_addr;
6485 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6486 + /* At this point: (!vma || addr < vma->vm_end). */
6487 + if (pax_task_size - len < addr) {
6489 + * Start a new search - just in case we missed
6492 + if (start_addr != mm->mmap_base) {
6493 + start_addr = addr = mm->mmap_base;
6494 + mm->cached_hole_size = 0;
6499 + if (!vma || addr + len <= vma->vm_start) {
6501 + * Remember the place where we stopped the search:
6503 + mm->free_area_cache = addr + len;
6506 + if (addr + mm->cached_hole_size < vma->vm_start)
6507 + mm->cached_hole_size = vma->vm_start - addr;
6508 + addr = vma->vm_end;
6509 + if (mm->start_brk <= addr && addr < mm->mmap_base) {
6510 + start_addr = addr = mm->mmap_base;
6511 + mm->cached_hole_size = 0;
6518 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
6519 + const unsigned long len, const unsigned long pgoff,
6520 + const unsigned long flags)
6522 + struct vm_area_struct *vma;
6523 + struct mm_struct *mm = current->mm;
6524 + unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
6526 +#ifdef CONFIG_PAX_SEGMEXEC
6527 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6528 + pax_task_size = SEGMEXEC_TASK_SIZE;
6531 + /* requested length too big for entire address space */
6532 + if (len > pax_task_size)
6535 + if (flags & MAP_FIXED)
6538 +#ifdef CONFIG_PAX_PAGEEXEC
6539 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
6543 +#ifdef CONFIG_PAX_RANDMMAP
6544 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6547 + /* requesting a specific address */
6549 + addr = PAGE_ALIGN(addr);
6550 + vma = find_vma(mm, addr);
6551 + if (pax_task_size - len >= addr &&
6552 + (!vma || addr + len <= vma->vm_start))
6556 + /* check if free_area_cache is useful for us */
6557 + if (len <= mm->cached_hole_size) {
6558 + mm->cached_hole_size = 0;
6559 + mm->free_area_cache = mm->mmap_base;
6562 + /* either no address requested or can't fit in requested address hole */
6563 + addr = mm->free_area_cache;
6565 + /* make sure it can fit in the remaining address space */
6567 + vma = find_vma(mm, addr-len);
6568 + if (!vma || addr <= vma->vm_start)
6569 + /* remember the address as a hint for next time */
6570 + return (mm->free_area_cache = addr-len);
6573 + if (mm->mmap_base < len)
6576 + addr = mm->mmap_base-len;
6580 + * Lookup failure means no vma is above this address,
6581 + * else if new region fits below vma->vm_start,
6582 + * return with success:
6584 + vma = find_vma(mm, addr);
6585 + if (!vma || addr+len <= vma->vm_start)
6586 + /* remember the address as a hint for next time */
6587 + return (mm->free_area_cache = addr);
6589 + /* remember the largest hole we saw so far */
6590 + if (addr + mm->cached_hole_size < vma->vm_start)
6591 + mm->cached_hole_size = vma->vm_start - addr;
6593 + /* try just below the current vma->vm_start */
6594 + addr = vma->vm_start-len;
6595 + } while (len < vma->vm_start);
6599 + * A failed mmap() very likely causes application failure,
6600 + * so fall back to the bottom-up function here. This scenario
6601 + * can happen with large stack limits and large mmap()
6605 +#ifdef CONFIG_PAX_SEGMEXEC
6606 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6607 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
6611 + mm->mmap_base = TASK_UNMAPPED_BASE;
6613 +#ifdef CONFIG_PAX_RANDMMAP
6614 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6615 + mm->mmap_base += mm->delta_mmap;
6618 + mm->free_area_cache = mm->mmap_base;
6619 + mm->cached_hole_size = ~0UL;
6620 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6622 + * Restore the topdown base:
6624 + mm->mmap_base = base;
6625 + mm->free_area_cache = base;
6626 + mm->cached_hole_size = ~0UL;
6631 struct sel_arg_struct {
6633 diff -urNp linux-2.6.25.10/arch/x86/kernel/sys_x86_64.c linux-2.6.25.10/arch/x86/kernel/sys_x86_64.c
6634 --- linux-2.6.25.10/arch/x86/kernel/sys_x86_64.c 2008-07-02 23:46:47.000000000 -0400
6635 +++ linux-2.6.25.10/arch/x86/kernel/sys_x86_64.c 2008-07-03 16:53:25.000000000 -0400
6636 @@ -62,8 +62,8 @@ out:
6640 -static void find_start_end(unsigned long flags, unsigned long *begin,
6641 - unsigned long *end)
6642 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
6643 + unsigned long *begin, unsigned long *end)
6645 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
6646 unsigned long new_begin;
6647 @@ -82,7 +82,7 @@ static void find_start_end(unsigned long
6651 - *begin = TASK_UNMAPPED_BASE;
6652 + *begin = mm->mmap_base;
6656 @@ -99,11 +99,15 @@ arch_get_unmapped_area(struct file *filp
6657 if (flags & MAP_FIXED)
6660 - find_start_end(flags, &begin, &end);
6661 + find_start_end(mm, flags, &begin, &end);
6666 +#ifdef CONFIG_PAX_RANDMMAP
6667 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6671 addr = PAGE_ALIGN(addr);
6672 vma = find_vma(mm, addr);
6673 @@ -158,7 +162,7 @@ arch_get_unmapped_area_topdown(struct fi
6675 struct vm_area_struct *vma;
6676 struct mm_struct *mm = current->mm;
6677 - unsigned long addr = addr0;
6678 + unsigned long base = mm->mmap_base, addr = addr0;
6680 /* requested length too big for entire address space */
6681 if (len > TASK_SIZE)
6682 @@ -171,6 +175,10 @@ arch_get_unmapped_area_topdown(struct fi
6683 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
6686 +#ifdef CONFIG_PAX_RANDMMAP
6687 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
6690 /* requesting a specific address */
6692 addr = PAGE_ALIGN(addr);
6693 @@ -228,13 +236,21 @@ bottomup:
6694 * can happen with large stack limits and large mmap()
6697 + mm->mmap_base = TASK_UNMAPPED_BASE;
6699 +#ifdef CONFIG_PAX_RANDMMAP
6700 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6701 + mm->mmap_base += mm->delta_mmap;
6704 + mm->free_area_cache = mm->mmap_base;
6705 mm->cached_hole_size = ~0UL;
6706 - mm->free_area_cache = TASK_UNMAPPED_BASE;
6707 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6709 * Restore the topdown base:
6711 - mm->free_area_cache = mm->mmap_base;
6712 + mm->mmap_base = base;
6713 + mm->free_area_cache = base;
6714 mm->cached_hole_size = ~0UL;
6717 diff -urNp linux-2.6.25.10/arch/x86/kernel/time_32.c linux-2.6.25.10/arch/x86/kernel/time_32.c
6718 --- linux-2.6.25.10/arch/x86/kernel/time_32.c 2008-07-02 23:46:47.000000000 -0400
6719 +++ linux-2.6.25.10/arch/x86/kernel/time_32.c 2008-07-03 16:53:25.000000000 -0400
6720 @@ -52,20 +52,30 @@ unsigned long profile_pc(struct pt_regs
6721 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
6722 in_lock_functions(pc)) {
6723 #ifdef CONFIG_FRAME_POINTER
6724 - return *(unsigned long *)(regs->bp + 4);
6725 + return ktla_ktva(*(unsigned long *)(regs->bp + 4));
6727 unsigned long *sp = (unsigned long *)®s->sp;
6729 /* Return address is either directly at stack pointer
6730 or above a saved flags. Eflags has bits 22-31 zero,
6731 kernel addresses don't. */
6733 +#ifdef CONFIG_PAX_KERNEXEC
6734 + return ktla_ktva(sp[0]);
6746 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
6747 + pc = ktla_ktva(pc);
6751 EXPORT_SYMBOL(profile_pc);
6752 diff -urNp linux-2.6.25.10/arch/x86/kernel/tls.c linux-2.6.25.10/arch/x86/kernel/tls.c
6753 --- linux-2.6.25.10/arch/x86/kernel/tls.c 2008-07-02 23:46:47.000000000 -0400
6754 +++ linux-2.6.25.10/arch/x86/kernel/tls.c 2008-07-03 16:53:25.000000000 -0400
6755 @@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
6756 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6759 +#ifdef CONFIG_PAX_SEGMEXEC
6760 + if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6764 set_tls_desc(p, idx, &info, 1);
6767 diff -urNp linux-2.6.25.10/arch/x86/kernel/traps_32.c linux-2.6.25.10/arch/x86/kernel/traps_32.c
6768 --- linux-2.6.25.10/arch/x86/kernel/traps_32.c 2008-07-02 23:46:47.000000000 -0400
6769 +++ linux-2.6.25.10/arch/x86/kernel/traps_32.c 2008-07-03 16:53:25.000000000 -0400
6771 #include <linux/uaccess.h>
6772 #include <linux/nmi.h>
6773 #include <linux/bug.h>
6774 +#include <linux/binfmts.h>
6777 #include <linux/ioport.h>
6778 @@ -71,14 +72,6 @@ asmlinkage int system_call(void);
6779 /* Do we ignore FPU interrupts ? */
6780 char ignore_fpu_irq = 0;
6783 - * The IDT has to be page-aligned to simplify the Pentium
6784 - * F0 0F bug workaround.. We have a special link segment
6787 -gate_desc idt_table[256]
6788 - __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
6790 asmlinkage void divide_error(void);
6791 asmlinkage void debug(void);
6792 asmlinkage void nmi(void);
6793 @@ -330,22 +323,23 @@ void show_registers(struct pt_regs *regs
6794 * When in-kernel, we also print out the stack and code at the
6795 * time of the fault..
6797 - if (!user_mode_vm(regs)) {
6798 + if (!user_mode(regs)) {
6800 unsigned int code_prologue = code_bytes * 43 / 64;
6801 unsigned int code_len = code_bytes;
6803 + unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
6805 printk("\n" KERN_EMERG "Stack: ");
6806 show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG);
6808 printk(KERN_EMERG "Code: ");
6810 - ip = (u8 *)regs->ip - code_prologue;
6811 + ip = (u8 *)regs->ip - code_prologue + cs_base;
6812 if (ip < (u8 *)PAGE_OFFSET ||
6813 probe_kernel_address(ip, c)) {
6814 /* try starting at EIP */
6815 - ip = (u8 *)regs->ip;
6816 + ip = (u8 *)regs->ip + cs_base;
6817 code_len = code_len - code_prologue + 1;
6819 for (i = 0; i < code_len; i++, ip++) {
6820 @@ -354,7 +348,7 @@ void show_registers(struct pt_regs *regs
6821 printk(" Bad EIP value.");
6824 - if (ip == (u8 *)regs->ip)
6825 + if (ip == (u8 *)regs->ip + cs_base)
6826 printk("<%02x> ", c);
6829 @@ -367,6 +361,7 @@ int is_valid_bugaddr(unsigned long ip)
6833 + ip = ktla_ktva(ip);
6834 if (ip < PAGE_OFFSET)
6836 if (probe_kernel_address((unsigned short *)ip, ud2))
6837 @@ -476,7 +471,7 @@ void die(const char * str, struct pt_reg
6839 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
6841 - if (!user_mode_vm(regs))
6842 + if (!user_mode(regs))
6843 die(str, regs, err);
6846 @@ -492,7 +487,7 @@ static void __kprobes do_trap(int trapnr
6850 - if (!user_mode(regs))
6851 + if (!user_mode_novm(regs))
6855 @@ -598,7 +593,7 @@ void __kprobes do_general_protection(str
6858 int cpu = get_cpu();
6859 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
6860 + struct tss_struct *tss = &init_tss[cpu];
6861 struct thread_struct *thread = ¤t->thread;
6864 @@ -631,9 +626,25 @@ void __kprobes do_general_protection(str
6865 if (regs->flags & VM_MASK)
6868 - if (!user_mode(regs))
6869 + if (!user_mode_novm(regs))
6872 +#ifdef CONFIG_PAX_PAGEEXEC
6873 + if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
6874 + struct mm_struct *mm = current->mm;
6875 + unsigned long limit;
6877 + down_write(&mm->mmap_sem);
6878 + limit = mm->context.user_cs_limit;
6879 + if (limit < TASK_SIZE) {
6880 + track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
6881 + up_write(&mm->mmap_sem);
6884 + up_write(&mm->mmap_sem);
6888 current->thread.error_code = error_code;
6889 current->thread.trap_no = 13;
6890 if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
6891 @@ -661,6 +672,13 @@ gp_in_kernel:
6892 if (notify_die(DIE_GPF, "general protection fault", regs,
6893 error_code, 13, SIGSEGV) == NOTIFY_STOP)
6896 +#ifdef CONFIG_PAX_KERNEXEC
6897 + if ((regs->cs & 0xFFFF) == __KERNEL_CS)
6898 + die("PAX: suspicious general protection fault", regs, error_code);
6902 die("general protection fault", regs, error_code);
6905 @@ -750,7 +768,7 @@ void __kprobes die_nmi(struct pt_regs *r
6906 /* If we are in kernel we are probably nested up pretty bad
6907 * and might aswell get out now while we still can.
6909 - if (!user_mode_vm(regs)) {
6910 + if (!user_mode(regs)) {
6911 current->thread.trap_no = 2;
6914 @@ -907,7 +925,7 @@ void __kprobes do_debug(struct pt_regs *
6915 * check for kernel mode by just checking the CPL
6918 - if (!user_mode(regs))
6919 + if (!user_mode_novm(regs))
6920 goto clear_TF_reenable;
6923 @@ -1085,18 +1103,14 @@ void do_spurious_interrupt_bug(struct pt
6924 unsigned long patch_espfix_desc(unsigned long uesp,
6927 - struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
6928 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
6929 unsigned long new_kesp = kesp - base;
6930 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
6931 - __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
6932 + struct desc_struct ss;
6934 /* Set up base for espfix segment */
6935 - desc &= 0x00f0ff0000000000ULL;
6936 - desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
6937 - ((((__u64)base) << 32) & 0xff00000000000000ULL) |
6938 - ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
6939 - (lim_pages & 0xffff);
6940 - *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
6941 + pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
6942 + write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
6946 diff -urNp linux-2.6.25.10/arch/x86/kernel/tsc_32.c linux-2.6.25.10/arch/x86/kernel/tsc_32.c
6947 --- linux-2.6.25.10/arch/x86/kernel/tsc_32.c 2008-07-02 23:46:47.000000000 -0400
6948 +++ linux-2.6.25.10/arch/x86/kernel/tsc_32.c 2008-07-03 16:53:25.000000000 -0400
6949 @@ -338,7 +338,7 @@ static struct dmi_system_id __initdata b
6950 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
6954 + { NULL, NULL, {{0, NULL}}, NULL}
6958 diff -urNp linux-2.6.25.10/arch/x86/kernel/vm86_32.c linux-2.6.25.10/arch/x86/kernel/vm86_32.c
6959 --- linux-2.6.25.10/arch/x86/kernel/vm86_32.c 2008-07-02 23:46:47.000000000 -0400
6960 +++ linux-2.6.25.10/arch/x86/kernel/vm86_32.c 2008-07-03 16:53:25.000000000 -0400
6961 @@ -145,7 +145,7 @@ struct pt_regs * save_v86_state(struct k
6965 - tss = &per_cpu(init_tss, get_cpu());
6966 + tss = init_tss + get_cpu();
6967 current->thread.sp0 = current->thread.saved_sp0;
6968 current->thread.sysenter_cs = __KERNEL_CS;
6969 load_sp0(tss, ¤t->thread);
6970 @@ -321,7 +321,7 @@ static void do_sys_vm86(struct kernel_vm
6971 tsk->thread.saved_fs = info->regs32->fs;
6972 savesegment(gs, tsk->thread.saved_gs);
6974 - tss = &per_cpu(init_tss, get_cpu());
6975 + tss = init_tss + get_cpu();
6976 tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
6978 tsk->thread.sysenter_cs = 0;
6979 diff -urNp linux-2.6.25.10/arch/x86/kernel/vmi_32.c linux-2.6.25.10/arch/x86/kernel/vmi_32.c
6980 --- linux-2.6.25.10/arch/x86/kernel/vmi_32.c 2008-07-02 23:46:47.000000000 -0400
6981 +++ linux-2.6.25.10/arch/x86/kernel/vmi_32.c 2008-07-03 16:53:25.000000000 -0400
6982 @@ -101,18 +101,43 @@ static unsigned patch_internal(int call,
6985 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
6987 +#ifdef CONFIG_PAX_KERNEXEC
6988 + unsigned long cr0;
6991 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
6993 case VMI_RELOCATION_CALL_REL:
6996 +#ifdef CONFIG_PAX_KERNEXEC
6997 + pax_open_kernel(cr0);
7000 *(char *)insnbuf = MNEM_CALL;
7001 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
7003 +#ifdef CONFIG_PAX_KERNEXEC
7004 + pax_close_kernel(cr0);
7009 case VMI_RELOCATION_JUMP_REL:
7012 +#ifdef CONFIG_PAX_KERNEXEC
7013 + pax_open_kernel(cr0);
7016 *(char *)insnbuf = MNEM_JMP;
7017 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
7019 +#ifdef CONFIG_PAX_KERNEXEC
7020 + pax_close_kernel(cr0);
7025 case VMI_RELOCATION_NOP:
7026 @@ -515,14 +540,14 @@ static void vmi_set_pud(pud_t *pudp, pud
7028 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
7030 - const pte_t pte = { .pte = 0 };
7031 + const pte_t pte = __pte(0ULL);
7032 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
7033 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
7036 static void vmi_pmd_clear(pmd_t *pmd)
7038 - const pte_t pte = { .pte = 0 };
7039 + const pte_t pte = __pte(0ULL);
7040 vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
7041 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
7043 @@ -551,8 +576,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
7044 ap.ss = __KERNEL_DS;
7045 ap.esp = (unsigned long) start_esp;
7047 - ap.ds = __USER_DS;
7048 - ap.es = __USER_DS;
7049 + ap.ds = __KERNEL_DS;
7050 + ap.es = __KERNEL_DS;
7051 ap.fs = __KERNEL_PERCPU;
7054 @@ -747,12 +772,20 @@ static inline int __init activate_vmi(vo
7056 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
7058 +#ifdef CONFIG_PAX_KERNEXEC
7059 + unsigned long cr0;
7062 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
7063 printk(KERN_ERR "VMI ROM failed to initialize!");
7066 savesegment(cs, kernel_cs);
7068 +#ifdef CONFIG_PAX_KERNEXEC
7069 + pax_open_kernel(cr0);
7072 pv_info.paravirt_enabled = 1;
7073 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
7074 pv_info.name = "vmi";
7075 @@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
7077 para_fill(pv_irq_ops.safe_halt, Halt);
7079 +#ifdef CONFIG_PAX_KERNEXEC
7080 + pax_close_kernel(cr0);
7084 * Alternative instruction rewriting doesn't happen soon enough
7085 * to convert VMI_IRET to a call instead of a jump; so we have
7086 diff -urNp linux-2.6.25.10/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.25.10/arch/x86/kernel/vmlinux_32.lds.S
7087 --- linux-2.6.25.10/arch/x86/kernel/vmlinux_32.lds.S 2008-07-02 23:46:47.000000000 -0400
7088 +++ linux-2.6.25.10/arch/x86/kernel/vmlinux_32.lds.S 2008-07-03 16:53:25.000000000 -0400
7090 #include <asm/page.h>
7091 #include <asm/cache.h>
7092 #include <asm/boot.h>
7093 +#include <asm/segment.h>
7095 +#ifdef CONFIG_X86_PAE
7096 +#define PMD_SHIFT 21
7098 +#define PMD_SHIFT 22
7100 +#define PMD_SIZE (1 << PMD_SHIFT)
7102 +#ifdef CONFIG_PAX_KERNEXEC
7103 +#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
7105 +#define __KERNEL_TEXT_OFFSET 0
7108 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
7110 @@ -22,90 +36,23 @@ ENTRY(phys_startup_32)
7111 jiffies = jiffies_64;
7114 - text PT_LOAD FLAGS(5); /* R_E */
7115 - data PT_LOAD FLAGS(7); /* RWE */
7116 - note PT_NOTE FLAGS(0); /* ___ */
7117 + initdata PT_LOAD FLAGS(6); /* RW_ */
7118 + percpu PT_LOAD FLAGS(6); /* RW_ */
7119 + inittext PT_LOAD FLAGS(5); /* R_E */
7120 + text PT_LOAD FLAGS(5); /* R_E */
7121 + rodata PT_LOAD FLAGS(4); /* R__ */
7122 + data PT_LOAD FLAGS(6); /* RW_ */
7123 + note PT_NOTE FLAGS(0); /* ___ */
7127 - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
7128 - phys_startup_32 = startup_32 - LOAD_OFFSET;
7130 - .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
7131 - _text = .; /* Text and read-only data */
7136 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
7137 - . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
7138 - *(.text.page_aligned)
7145 - _etext = .; /* End of text section */
7148 - . = ALIGN(16); /* Exception table */
7149 - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7150 - __start___ex_table = .;
7152 - __stop___ex_table = .;
7160 - .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
7161 - __tracedata_start = .;
7163 - __tracedata_end = .;
7165 + . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
7170 - . = ALIGN(PAGE_SIZE);
7171 - .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7176 - . = ALIGN(PAGE_SIZE);
7177 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
7178 - __nosave_begin = .;
7180 - . = ALIGN(PAGE_SIZE);
7184 - . = ALIGN(PAGE_SIZE);
7185 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7186 - *(.data.page_aligned)
7191 - .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7192 - *(.data.cacheline_aligned)
7195 - /* rarely changed data like cpu maps */
7197 - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
7198 - *(.data.read_mostly)
7199 - _edata = .; /* End of data section */
7202 - . = ALIGN(THREAD_SIZE); /* init_task */
7203 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7204 - *(.data.init_task)
7206 + .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
7207 + __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
7208 + phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
7212 /* might get freed after init */
7213 . = ALIGN(PAGE_SIZE);
7214 @@ -123,14 +70,8 @@ SECTIONS
7215 . = ALIGN(PAGE_SIZE);
7217 /* will be freed after init */
7218 - . = ALIGN(PAGE_SIZE); /* Init code and data */
7219 - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
7225 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
7230 @@ -165,11 +106,6 @@ SECTIONS
7231 *(.parainstructions)
7232 __parainstructions_end = .;
7234 - /* .exit.text is discard at runtime, not link time, to deal with references
7235 - from .altinstructions and .eh_frame */
7236 - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
7239 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
7242 @@ -182,17 +118,144 @@ SECTIONS
7245 . = ALIGN(PAGE_SIZE);
7246 - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
7247 - __per_cpu_start = .;
7248 + per_cpu_start = .;
7249 + .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
7250 + __per_cpu_start = . + per_cpu_start;
7253 *(.data.percpu.shared_aligned)
7254 - __per_cpu_end = .;
7256 + __per_cpu_end = . + per_cpu_start;
7258 + . += per_cpu_start;
7259 . = ALIGN(PAGE_SIZE);
7260 /* freed after init ends here */
7262 + . = ALIGN(PAGE_SIZE); /* Init code and data */
7263 + .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7269 + /* .exit.text is discard at runtime, not link time, to deal with references
7270 + from .altinstructions and .eh_frame */
7271 + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7275 + .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7277 + . = ALIGN(2*PMD_SIZE) - 1;
7280 + /* freed after init ends here */
7282 + .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7283 + __init_end = . + __KERNEL_TEXT_OFFSET;
7284 + KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
7285 + _text = .; /* Text and read-only data */
7290 + .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7291 + . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
7292 + *(.text.page_aligned)
7299 + _etext = .; /* End of text section */
7302 + . += __KERNEL_TEXT_OFFSET;
7303 + . = ALIGN(4096); /* Exception table */
7304 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7305 + __start___ex_table = .;
7307 + __stop___ex_table = .;
7310 + NOTES :rodata :note
7315 + .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
7316 + __tracedata_start = .;
7318 + __tracedata_end = .;
7321 + RO_DATA(PAGE_SIZE)
7323 + . = ALIGN(PAGE_SIZE);
7324 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
7326 + . = ALIGN(PAGE_SIZE);
7327 + *(.empty_zero_page)
7328 + *(.swapper_pg_pmd)
7329 + *(.swapper_pg_dir)
7332 +#ifdef CONFIG_PAX_KERNEXEC
7334 +#ifdef CONFIG_MODULES
7335 + . = ALIGN(PAGE_SIZE);
7336 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
7337 + MODULES_VADDR = .;
7339 + . += (6 * 1024 * 1024);
7340 + . = ALIGN( PMD_SIZE) - 1;
7344 + . = ALIGN(PMD_SIZE) - 1;
7350 + . = ALIGN(PAGE_SIZE);
7351 + .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7357 + . = ALIGN(PAGE_SIZE);
7358 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
7359 + __nosave_begin = .;
7361 + . = ALIGN(PAGE_SIZE);
7365 + . = ALIGN(PAGE_SIZE);
7366 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7367 + *(.data.page_aligned)
7371 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7372 + *(.data.cacheline_aligned)
7375 + /* rarely changed data like cpu maps */
7377 + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
7378 + *(.data.read_mostly)
7379 + _edata = .; /* End of data section */
7382 + . = ALIGN(THREAD_SIZE); /* init_task */
7383 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7384 + *(.data.init_task)
7387 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7389 __bss_start = .; /* BSS */
7390 *(.bss.page_aligned)
7392 diff -urNp linux-2.6.25.10/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.25.10/arch/x86/kernel/vmlinux_64.lds.S
7393 --- linux-2.6.25.10/arch/x86/kernel/vmlinux_64.lds.S 2008-07-02 23:46:47.000000000 -0400
7394 +++ linux-2.6.25.10/arch/x86/kernel/vmlinux_64.lds.S 2008-07-03 16:53:25.000000000 -0400
7395 @@ -16,8 +16,8 @@ jiffies_64 = jiffies;
7398 text PT_LOAD FLAGS(5); /* R_E */
7399 - data PT_LOAD FLAGS(7); /* RWE */
7400 - user PT_LOAD FLAGS(7); /* RWE */
7401 + data PT_LOAD FLAGS(6); /* RW_ */
7402 + user PT_LOAD FLAGS(7); /* RWX */
7403 data.init PT_LOAD FLAGS(7); /* RWE */
7404 note PT_NOTE FLAGS(4); /* R__ */
7406 @@ -51,7 +51,7 @@ SECTIONS
7411 + RO_DATA(PAGE_SIZE)
7414 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
7415 @@ -60,15 +60,18 @@ SECTIONS
7416 __tracedata_end = .;
7419 +#ifdef CONFIG_PAX_KERNEXEC
7420 + . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
7422 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
7426 .data : AT(ADDR(.data) - LOAD_OFFSET) {
7431 - _edata = .; /* End of data section */
7433 . = ALIGN(PAGE_SIZE);
7434 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
7435 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7436 @@ -79,9 +82,27 @@ SECTIONS
7437 *(.data.read_mostly)
7440 + . = ALIGN(THREAD_SIZE); /* init_task */
7441 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7442 + *(.data.init_task)
7445 + . = ALIGN(PAGE_SIZE);
7446 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7447 + *(.data.page_aligned)
7450 + . = ALIGN(PAGE_SIZE);
7451 + __nosave_begin = .;
7452 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7453 + . = ALIGN(PAGE_SIZE);
7456 + _edata = .; /* End of data section */
7458 #define VSYSCALL_ADDR (-10*1024*1024)
7459 -#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7460 -#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7461 +#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7462 +#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7464 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
7465 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
7466 @@ -129,23 +150,13 @@ SECTIONS
7470 - . = ALIGN(THREAD_SIZE); /* init_task */
7471 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7472 - *(.data.init_task)
7475 - . = ALIGN(PAGE_SIZE);
7476 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7477 - *(.data.page_aligned)
7480 /* might get freed after init */
7481 . = ALIGN(PAGE_SIZE);
7482 __smp_alt_begin = .;
7484 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7488 __smp_locks_end = .;
7489 . = ALIGN(PAGE_SIZE);
7491 @@ -222,12 +233,6 @@ SECTIONS
7492 . = ALIGN(PAGE_SIZE);
7495 - . = ALIGN(PAGE_SIZE);
7496 - __nosave_begin = .;
7497 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7498 - . = ALIGN(PAGE_SIZE);
7501 __bss_start = .; /* BSS */
7502 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7503 *(.bss.page_aligned)
7504 @@ -235,6 +240,7 @@ SECTIONS
7508 + . = ALIGN(2*1024*1024);
7511 /* Sections to be discarded */
7512 diff -urNp linux-2.6.25.10/arch/x86/kernel/vsyscall_64.c linux-2.6.25.10/arch/x86/kernel/vsyscall_64.c
7513 --- linux-2.6.25.10/arch/x86/kernel/vsyscall_64.c 2008-07-02 23:46:47.000000000 -0400
7514 +++ linux-2.6.25.10/arch/x86/kernel/vsyscall_64.c 2008-07-03 16:53:25.000000000 -0400
7515 @@ -235,13 +235,13 @@ static ctl_table kernel_table2[] = {
7516 .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
7518 .proc_handler = vsyscall_sysctl_change },
7520 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7523 static ctl_table kernel_root_table2[] = {
7524 { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
7525 .child = kernel_table2 },
7527 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7531 @@ -251,6 +251,11 @@ static void __cpuinit vsyscall_set_cpu(i
7534 unsigned long node = 0;
7536 +#ifdef CONFIG_PAX_KERNEXEC
7537 + unsigned long cr0;
7541 node = cpu_to_node(cpu);
7543 @@ -261,10 +266,20 @@ static void __cpuinit vsyscall_set_cpu(i
7544 in user space in vgetcpu.
7545 12 bits for the CPU and 8 bits for the node. */
7546 d = (unsigned long *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_PER_CPU);
7548 +#ifdef CONFIG_PAX_KERNEXEC
7549 + pax_open_kernel(cr0);
7552 *d = 0x0f40000000000ULL;
7554 *d |= (node & 0xf) << 12;
7555 *d |= (node >> 4) << 48;
7557 +#ifdef CONFIG_PAX_KERNEXEC
7558 + pax_close_kernel(cr0);
7563 static void __cpuinit cpu_vsyscall_init(void *arg)
7564 diff -urNp linux-2.6.25.10/arch/x86/kernel/x8664_ksyms_64.c linux-2.6.25.10/arch/x86/kernel/x8664_ksyms_64.c
7565 --- linux-2.6.25.10/arch/x86/kernel/x8664_ksyms_64.c 2008-07-02 23:46:47.000000000 -0400
7566 +++ linux-2.6.25.10/arch/x86/kernel/x8664_ksyms_64.c 2008-07-03 16:53:25.000000000 -0400
7567 @@ -54,8 +54,3 @@ EXPORT_SYMBOL(init_level4_pgt);
7568 EXPORT_SYMBOL(load_gs_index);
7570 EXPORT_SYMBOL(_proxy_pda);
7572 -#ifdef CONFIG_PARAVIRT
7573 -/* Virtualized guests may want to use it */
7574 -EXPORT_SYMBOL_GPL(cpu_gdt_descr);
7576 diff -urNp linux-2.6.25.10/arch/x86/kvm/svm.c linux-2.6.25.10/arch/x86/kvm/svm.c
7577 --- linux-2.6.25.10/arch/x86/kvm/svm.c 2008-07-02 23:46:47.000000000 -0400
7578 +++ linux-2.6.25.10/arch/x86/kvm/svm.c 2008-07-03 16:53:25.000000000 -0400
7579 @@ -1329,8 +1329,20 @@ static void reload_tss(struct kvm_vcpu *
7580 int cpu = raw_smp_processor_id();
7582 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
7584 +#ifdef CONFIG_PAX_KERNEXEC
7585 + unsigned long cr0;
7587 + pax_open_kernel(cr0);
7590 svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
7593 +#ifdef CONFIG_PAX_KERNEXEC
7594 + pax_close_kernel(cr0);
7599 static void pre_svm_run(struct vcpu_svm *svm)
7600 diff -urNp linux-2.6.25.10/arch/x86/kvm/vmx.c linux-2.6.25.10/arch/x86/kvm/vmx.c
7601 --- linux-2.6.25.10/arch/x86/kvm/vmx.c 2008-07-02 23:46:47.000000000 -0400
7602 +++ linux-2.6.25.10/arch/x86/kvm/vmx.c 2008-07-03 16:53:25.000000000 -0400
7603 @@ -355,10 +355,24 @@ static void reload_tss(void)
7604 struct descriptor_table gdt;
7605 struct segment_descriptor *descs;
7607 +#ifdef CONFIG_PAX_KERNEXEC
7608 + unsigned long cr0;
7612 descs = (void *)gdt.base;
7614 +#ifdef CONFIG_PAX_KERNEXEC
7615 + pax_open_kernel(cr0);
7618 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
7621 +#ifdef CONFIG_PAX_KERNEXEC
7622 + pax_close_kernel(cr0);
7627 static void load_transition_efer(struct vcpu_vmx *vmx)
7628 @@ -2464,7 +2478,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
7629 vcpu->arch.interrupt_window_open =
7630 (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
7632 - asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
7633 + asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
7636 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
7637 diff -urNp linux-2.6.25.10/arch/x86/kvm/x86.c linux-2.6.25.10/arch/x86/kvm/x86.c
7638 --- linux-2.6.25.10/arch/x86/kvm/x86.c 2008-07-02 23:46:47.000000000 -0400
7639 +++ linux-2.6.25.10/arch/x86/kvm/x86.c 2008-07-03 16:53:25.000000000 -0400
7640 @@ -52,33 +52,33 @@ static int kvm_dev_ioctl_get_supported_c
7641 struct kvm_x86_ops *kvm_x86_ops;
7643 struct kvm_stats_debugfs_item debugfs_entries[] = {
7644 - { "pf_fixed", VCPU_STAT(pf_fixed) },
7645 - { "pf_guest", VCPU_STAT(pf_guest) },
7646 - { "tlb_flush", VCPU_STAT(tlb_flush) },
7647 - { "invlpg", VCPU_STAT(invlpg) },
7648 - { "exits", VCPU_STAT(exits) },
7649 - { "io_exits", VCPU_STAT(io_exits) },
7650 - { "mmio_exits", VCPU_STAT(mmio_exits) },
7651 - { "signal_exits", VCPU_STAT(signal_exits) },
7652 - { "irq_window", VCPU_STAT(irq_window_exits) },
7653 - { "halt_exits", VCPU_STAT(halt_exits) },
7654 - { "halt_wakeup", VCPU_STAT(halt_wakeup) },
7655 - { "request_irq", VCPU_STAT(request_irq_exits) },
7656 - { "irq_exits", VCPU_STAT(irq_exits) },
7657 - { "host_state_reload", VCPU_STAT(host_state_reload) },
7658 - { "efer_reload", VCPU_STAT(efer_reload) },
7659 - { "fpu_reload", VCPU_STAT(fpu_reload) },
7660 - { "insn_emulation", VCPU_STAT(insn_emulation) },
7661 - { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
7662 - { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
7663 - { "mmu_pte_write", VM_STAT(mmu_pte_write) },
7664 - { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
7665 - { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
7666 - { "mmu_flooded", VM_STAT(mmu_flooded) },
7667 - { "mmu_recycled", VM_STAT(mmu_recycled) },
7668 - { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
7669 - { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
7671 + { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
7672 + { "pf_guest", VCPU_STAT(pf_guest), NULL },
7673 + { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
7674 + { "invlpg", VCPU_STAT(invlpg), NULL },
7675 + { "exits", VCPU_STAT(exits), NULL },
7676 + { "io_exits", VCPU_STAT(io_exits), NULL },
7677 + { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
7678 + { "signal_exits", VCPU_STAT(signal_exits), NULL },
7679 + { "irq_window", VCPU_STAT(irq_window_exits), NULL },
7680 + { "halt_exits", VCPU_STAT(halt_exits), NULL },
7681 + { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
7682 + { "request_irq", VCPU_STAT(request_irq_exits), NULL },
7683 + { "irq_exits", VCPU_STAT(irq_exits), NULL },
7684 + { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
7685 + { "efer_reload", VCPU_STAT(efer_reload), NULL },
7686 + { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
7687 + { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
7688 + { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
7689 + { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
7690 + { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
7691 + { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
7692 + { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
7693 + { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
7694 + { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
7695 + { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
7696 + { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
7697 + { NULL, 0, KVM_STAT_VM, NULL }
7701 @@ -1065,7 +1065,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
7702 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
7703 struct kvm_interrupt *irq)
7705 - if (irq->irq < 0 || irq->irq >= 256)
7706 + if (irq->irq >= 256)
7708 if (irqchip_in_kernel(vcpu->kvm))
7710 diff -urNp linux-2.6.25.10/arch/x86/lib/checksum_32.S linux-2.6.25.10/arch/x86/lib/checksum_32.S
7711 --- linux-2.6.25.10/arch/x86/lib/checksum_32.S 2008-07-02 23:46:47.000000000 -0400
7712 +++ linux-2.6.25.10/arch/x86/lib/checksum_32.S 2008-07-03 16:53:25.000000000 -0400
7714 #include <linux/linkage.h>
7715 #include <asm/dwarf2.h>
7716 #include <asm/errno.h>
7718 +#include <asm/segment.h>
7721 * computes a partial checksum, e.g. for TCP/UDP fragments
7723 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
7728 -ENTRY(csum_partial_copy_generic)
7730 +ENTRY(csum_partial_copy_generic_to_user)
7732 + pushl $(__USER_DS)
7733 + CFI_ADJUST_CFA_OFFSET 4
7735 + CFI_ADJUST_CFA_OFFSET -4
7736 + jmp csum_partial_copy_generic
7738 +ENTRY(csum_partial_copy_generic_from_user)
7739 + pushl $(__USER_DS)
7740 + CFI_ADJUST_CFA_OFFSET 4
7742 + CFI_ADJUST_CFA_OFFSET -4
7744 +ENTRY(csum_partial_copy_generic)
7746 CFI_ADJUST_CFA_OFFSET 4
7748 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
7750 SRC(1: movw (%esi), %bx )
7752 -DST( movw %bx, (%edi) )
7753 +DST( movw %bx, %es:(%edi) )
7757 @@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
7758 SRC(1: movl (%esi), %ebx )
7759 SRC( movl 4(%esi), %edx )
7761 -DST( movl %ebx, (%edi) )
7762 +DST( movl %ebx, %es:(%edi) )
7764 -DST( movl %edx, 4(%edi) )
7765 +DST( movl %edx, %es:4(%edi) )
7767 SRC( movl 8(%esi), %ebx )
7768 SRC( movl 12(%esi), %edx )
7770 -DST( movl %ebx, 8(%edi) )
7771 +DST( movl %ebx, %es:8(%edi) )
7773 -DST( movl %edx, 12(%edi) )
7774 +DST( movl %edx, %es:12(%edi) )
7776 SRC( movl 16(%esi), %ebx )
7777 SRC( movl 20(%esi), %edx )
7779 -DST( movl %ebx, 16(%edi) )
7780 +DST( movl %ebx, %es:16(%edi) )
7782 -DST( movl %edx, 20(%edi) )
7783 +DST( movl %edx, %es:20(%edi) )
7785 SRC( movl 24(%esi), %ebx )
7786 SRC( movl 28(%esi), %edx )
7788 -DST( movl %ebx, 24(%edi) )
7789 +DST( movl %ebx, %es:24(%edi) )
7791 -DST( movl %edx, 28(%edi) )
7792 +DST( movl %edx, %es:28(%edi) )
7796 @@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
7797 shrl $2, %edx # This clears CF
7798 SRC(3: movl (%esi), %ebx )
7800 -DST( movl %ebx, (%edi) )
7801 +DST( movl %ebx, %es:(%edi) )
7805 @@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
7807 SRC( movw (%esi), %cx )
7809 -DST( movw %cx, (%edi) )
7810 +DST( movw %cx, %es:(%edi) )
7814 SRC(5: movb (%esi), %cl )
7815 -DST( movb %cl, (%edi) )
7816 +DST( movb %cl, %es:(%edi) )
7820 @@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
7823 movl ARGBASE+20(%esp), %ebx # src_err_ptr
7824 - movl $-EFAULT, (%ebx)
7825 + movl $-EFAULT, %ss:(%ebx)
7827 # zero the complete destination - computing the rest
7829 @@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
7832 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
7833 - movl $-EFAULT,(%ebx)
7834 + movl $-EFAULT,%ss:(%ebx)
7840 + CFI_ADJUST_CFA_OFFSET 4
7842 + CFI_ADJUST_CFA_OFFSET -4
7844 + CFI_ADJUST_CFA_OFFSET 4
7846 + CFI_ADJUST_CFA_OFFSET -4
7848 CFI_ADJUST_CFA_OFFSET -4
7850 @@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
7851 CFI_ADJUST_CFA_OFFSET -4
7854 -ENDPROC(csum_partial_copy_generic)
7855 +ENDPROC(csum_partial_copy_generic_to_user)
7859 /* Version for PentiumII/PPro */
7863 SRC(movl x(%esi), %ebx ) ; \
7865 - DST(movl %ebx, x(%edi) ) ;
7866 + DST(movl %ebx, %es:x(%edi)) ;
7870 SRC(movl x(%esi), %ebx ) ; \
7872 - DST(movl %ebx, x(%edi) ) ;
7873 + DST(movl %ebx, %es:x(%edi)) ;
7877 -ENTRY(csum_partial_copy_generic)
7879 +ENTRY(csum_partial_copy_generic_to_user)
7881 + pushl $(__USER_DS)
7882 + CFI_ADJUST_CFA_OFFSET 4
7884 + CFI_ADJUST_CFA_OFFSET -4
7885 + jmp csum_partial_copy_generic
7887 +ENTRY(csum_partial_copy_generic_from_user)
7888 + pushl $(__USER_DS)
7889 + CFI_ADJUST_CFA_OFFSET 4
7891 + CFI_ADJUST_CFA_OFFSET -4
7893 +ENTRY(csum_partial_copy_generic)
7895 CFI_ADJUST_CFA_OFFSET 4
7896 CFI_REL_OFFSET ebx, 0
7897 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
7901 - lea 3f(%ebx,%ebx), %ebx
7902 + lea 3f(%ebx,%ebx,2), %ebx
7906 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
7908 SRC( movw (%esi), %dx )
7910 -DST( movw %dx, (%edi) )
7911 +DST( movw %dx, %es:(%edi) )
7916 SRC( movb (%esi), %dl )
7917 -DST( movb %dl, (%edi) )
7918 +DST( movb %dl, %es:(%edi) )
7922 .section .fixup, "ax"
7923 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
7924 - movl $-EFAULT, (%ebx)
7925 + movl $-EFAULT, %ss:(%ebx)
7926 # zero the complete destination (computing the rest is too much work)
7927 movl ARGBASE+8(%esp),%edi # dst
7928 movl ARGBASE+12(%esp),%ecx # len
7929 @@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
7932 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
7933 - movl $-EFAULT, (%ebx)
7934 + movl $-EFAULT, %ss:(%ebx)
7939 + CFI_ADJUST_CFA_OFFSET 4
7941 + CFI_ADJUST_CFA_OFFSET -4
7943 + CFI_ADJUST_CFA_OFFSET 4
7945 + CFI_ADJUST_CFA_OFFSET -4
7947 CFI_ADJUST_CFA_OFFSET -4
7949 @@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
7953 -ENDPROC(csum_partial_copy_generic)
7954 +ENDPROC(csum_partial_copy_generic_to_user)
7958 diff -urNp linux-2.6.25.10/arch/x86/lib/clear_page_64.S linux-2.6.25.10/arch/x86/lib/clear_page_64.S
7959 --- linux-2.6.25.10/arch/x86/lib/clear_page_64.S 2008-07-02 23:46:47.000000000 -0400
7960 +++ linux-2.6.25.10/arch/x86/lib/clear_page_64.S 2008-07-03 16:53:25.000000000 -0400
7961 @@ -44,7 +44,7 @@ ENDPROC(clear_page)
7963 #include <asm/cpufeature.h>
7965 - .section .altinstr_replacement,"ax"
7966 + .section .altinstr_replacement,"a"
7967 1: .byte 0xeb /* jmp <disp8> */
7968 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
7970 diff -urNp linux-2.6.25.10/arch/x86/lib/copy_page_64.S linux-2.6.25.10/arch/x86/lib/copy_page_64.S
7971 --- linux-2.6.25.10/arch/x86/lib/copy_page_64.S 2008-07-02 23:46:47.000000000 -0400
7972 +++ linux-2.6.25.10/arch/x86/lib/copy_page_64.S 2008-07-03 16:53:25.000000000 -0400
7973 @@ -104,7 +104,7 @@ ENDPROC(copy_page)
7975 #include <asm/cpufeature.h>
7977 - .section .altinstr_replacement,"ax"
7978 + .section .altinstr_replacement,"a"
7979 1: .byte 0xeb /* jmp <disp8> */
7980 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
7982 diff -urNp linux-2.6.25.10/arch/x86/lib/copy_user_64.S linux-2.6.25.10/arch/x86/lib/copy_user_64.S
7983 --- linux-2.6.25.10/arch/x86/lib/copy_user_64.S 2008-07-02 23:46:47.000000000 -0400
7984 +++ linux-2.6.25.10/arch/x86/lib/copy_user_64.S 2008-07-03 16:53:25.000000000 -0400
7986 .byte 0xe9 /* 32bit jump */
7987 .long \orig-1f /* by default jump to orig */
7989 - .section .altinstr_replacement,"ax"
7990 + .section .altinstr_replacement,"a"
7991 2: .byte 0xe9 /* near jump with 32bit immediate */
7992 .long \alt-1b /* offset */ /* or alternatively to alt */
7994 @@ -76,6 +76,8 @@ ENDPROC(copy_from_user)
7995 /* must zero dest */
8003 diff -urNp linux-2.6.25.10/arch/x86/lib/getuser_32.S linux-2.6.25.10/arch/x86/lib/getuser_32.S
8004 --- linux-2.6.25.10/arch/x86/lib/getuser_32.S 2008-07-02 23:46:47.000000000 -0400
8005 +++ linux-2.6.25.10/arch/x86/lib/getuser_32.S 2008-07-03 16:53:25.000000000 -0400
8007 #include <linux/linkage.h>
8008 #include <asm/dwarf2.h>
8009 #include <asm/thread_info.h>
8011 +#include <asm/segment.h>
8015 @@ -31,7 +31,11 @@ ENTRY(__get_user_1)
8016 GET_THREAD_INFO(%edx)
8017 cmpl TI_addr_limit(%edx),%eax
8019 + pushl $(__USER_DS)
8021 1: movzbl (%eax),%edx
8027 @@ -44,7 +48,11 @@ ENTRY(__get_user_2)
8028 GET_THREAD_INFO(%edx)
8029 cmpl TI_addr_limit(%edx),%eax
8031 + pushl $(__USER_DS)
8033 2: movzwl -1(%eax),%edx
8039 @@ -57,7 +65,11 @@ ENTRY(__get_user_4)
8040 GET_THREAD_INFO(%edx)
8041 cmpl TI_addr_limit(%edx),%eax
8043 + pushl $(__USER_DS)
8045 3: movl -3(%eax),%edx
8051 @@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
8060 diff -urNp linux-2.6.25.10/arch/x86/lib/memcpy_64.S linux-2.6.25.10/arch/x86/lib/memcpy_64.S
8061 --- linux-2.6.25.10/arch/x86/lib/memcpy_64.S 2008-07-02 23:46:47.000000000 -0400
8062 +++ linux-2.6.25.10/arch/x86/lib/memcpy_64.S 2008-07-03 16:53:25.000000000 -0400
8063 @@ -114,7 +114,7 @@ ENDPROC(__memcpy)
8064 /* Some CPUs run faster using the string copy instructions.
8065 It is also a lot simpler. Use this when possible */
8067 - .section .altinstr_replacement,"ax"
8068 + .section .altinstr_replacement,"a"
8069 1: .byte 0xeb /* jmp <disp8> */
8070 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
8072 diff -urNp linux-2.6.25.10/arch/x86/lib/memset_64.S linux-2.6.25.10/arch/x86/lib/memset_64.S
8073 --- linux-2.6.25.10/arch/x86/lib/memset_64.S 2008-07-02 23:46:47.000000000 -0400
8074 +++ linux-2.6.25.10/arch/x86/lib/memset_64.S 2008-07-03 16:53:25.000000000 -0400
8075 @@ -118,7 +118,7 @@ ENDPROC(__memset)
8077 #include <asm/cpufeature.h>
8079 - .section .altinstr_replacement,"ax"
8080 + .section .altinstr_replacement,"a"
8081 1: .byte 0xeb /* jmp <disp8> */
8082 .byte (memset_c - memset) - (2f - 1b) /* offset */
8084 diff -urNp linux-2.6.25.10/arch/x86/lib/mmx_32.c linux-2.6.25.10/arch/x86/lib/mmx_32.c
8085 --- linux-2.6.25.10/arch/x86/lib/mmx_32.c 2008-07-02 23:46:47.000000000 -0400
8086 +++ linux-2.6.25.10/arch/x86/lib/mmx_32.c 2008-07-03 16:53:25.000000000 -0400
8087 @@ -31,6 +31,7 @@ void *_mmx_memcpy(void *to, const void *
8091 + unsigned long cr0;
8093 if (unlikely(in_interrupt()))
8094 return __memcpy(to, from, len);
8095 @@ -41,46 +42,74 @@ void *_mmx_memcpy(void *to, const void *
8098 __asm__ __volatile__ (
8099 - "1: prefetch (%0)\n" /* This set is 28 bytes */
8100 - " prefetch 64(%0)\n"
8101 - " prefetch 128(%0)\n"
8102 - " prefetch 192(%0)\n"
8103 - " prefetch 256(%0)\n"
8104 + "1: prefetch (%1)\n" /* This set is 28 bytes */
8105 + " prefetch 64(%1)\n"
8106 + " prefetch 128(%1)\n"
8107 + " prefetch 192(%1)\n"
8108 + " prefetch 256(%1)\n"
8110 ".section .fixup, \"ax\"\n"
8111 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8114 +#ifdef CONFIG_PAX_KERNEXEC
8115 + " movl %%cr0, %0\n"
8116 + " movl %0, %%eax\n"
8117 + " andl $0xFFFEFFFF, %%eax\n"
8118 + " movl %%eax, %%cr0\n"
8121 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8123 +#ifdef CONFIG_PAX_KERNEXEC
8124 + " movl %0, %%cr0\n"
8131 + : "=&r" (cr0) : "r" (from) : "ax");
8136 __asm__ __volatile__ (
8137 - "1: prefetch 320(%0)\n"
8138 - "2: movq (%0), %%mm0\n"
8139 - " movq 8(%0), %%mm1\n"
8140 - " movq 16(%0), %%mm2\n"
8141 - " movq 24(%0), %%mm3\n"
8142 - " movq %%mm0, (%1)\n"
8143 - " movq %%mm1, 8(%1)\n"
8144 - " movq %%mm2, 16(%1)\n"
8145 - " movq %%mm3, 24(%1)\n"
8146 - " movq 32(%0), %%mm0\n"
8147 - " movq 40(%0), %%mm1\n"
8148 - " movq 48(%0), %%mm2\n"
8149 - " movq 56(%0), %%mm3\n"
8150 - " movq %%mm0, 32(%1)\n"
8151 - " movq %%mm1, 40(%1)\n"
8152 - " movq %%mm2, 48(%1)\n"
8153 - " movq %%mm3, 56(%1)\n"
8154 + "1: prefetch 320(%1)\n"
8155 + "2: movq (%1), %%mm0\n"
8156 + " movq 8(%1), %%mm1\n"
8157 + " movq 16(%1), %%mm2\n"
8158 + " movq 24(%1), %%mm3\n"
8159 + " movq %%mm0, (%2)\n"
8160 + " movq %%mm1, 8(%2)\n"
8161 + " movq %%mm2, 16(%2)\n"
8162 + " movq %%mm3, 24(%2)\n"
8163 + " movq 32(%1), %%mm0\n"
8164 + " movq 40(%1), %%mm1\n"
8165 + " movq 48(%1), %%mm2\n"
8166 + " movq 56(%1), %%mm3\n"
8167 + " movq %%mm0, 32(%2)\n"
8168 + " movq %%mm1, 40(%2)\n"
8169 + " movq %%mm2, 48(%2)\n"
8170 + " movq %%mm3, 56(%2)\n"
8171 ".section .fixup, \"ax\"\n"
8172 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8175 +#ifdef CONFIG_PAX_KERNEXEC
8176 + " movl %%cr0, %0\n"
8177 + " movl %0, %%eax\n"
8178 + " andl $0xFFFEFFFF, %%eax\n"
8179 + " movl %%eax, %%cr0\n"
8182 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8184 +#ifdef CONFIG_PAX_KERNEXEC
8185 + " movl %0, %%cr0\n"
8191 - : : "r" (from), "r" (to) : "memory");
8192 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8196 @@ -159,6 +188,7 @@ static void fast_clear_page(void *page)
8197 static void fast_copy_page(void *to, void *from)
8200 + unsigned long cr0;
8204 @@ -166,45 +196,73 @@ static void fast_copy_page(void *to, voi
8205 * but that is for later. -AV
8207 __asm__ __volatile__ (
8208 - "1: prefetch (%0)\n"
8209 - " prefetch 64(%0)\n"
8210 - " prefetch 128(%0)\n"
8211 - " prefetch 192(%0)\n"
8212 - " prefetch 256(%0)\n"
8213 + "1: prefetch (%1)\n"
8214 + " prefetch 64(%1)\n"
8215 + " prefetch 128(%1)\n"
8216 + " prefetch 192(%1)\n"
8217 + " prefetch 256(%1)\n"
8219 ".section .fixup, \"ax\"\n"
8220 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8223 +#ifdef CONFIG_PAX_KERNEXEC
8224 + " movl %%cr0, %0\n"
8225 + " movl %0, %%eax\n"
8226 + " andl $0xFFFEFFFF, %%eax\n"
8227 + " movl %%eax, %%cr0\n"
8230 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8232 +#ifdef CONFIG_PAX_KERNEXEC
8233 + " movl %0, %%cr0\n"
8240 + : "=&r" (cr0) : "r" (from) : "ax");
8242 for(i=0; i<(4096-320)/64; i++)
8244 __asm__ __volatile__ (
8245 - "1: prefetch 320(%0)\n"
8246 - "2: movq (%0), %%mm0\n"
8247 - " movntq %%mm0, (%1)\n"
8248 - " movq 8(%0), %%mm1\n"
8249 - " movntq %%mm1, 8(%1)\n"
8250 - " movq 16(%0), %%mm2\n"
8251 - " movntq %%mm2, 16(%1)\n"
8252 - " movq 24(%0), %%mm3\n"
8253 - " movntq %%mm3, 24(%1)\n"
8254 - " movq 32(%0), %%mm4\n"
8255 - " movntq %%mm4, 32(%1)\n"
8256 - " movq 40(%0), %%mm5\n"
8257 - " movntq %%mm5, 40(%1)\n"
8258 - " movq 48(%0), %%mm6\n"
8259 - " movntq %%mm6, 48(%1)\n"
8260 - " movq 56(%0), %%mm7\n"
8261 - " movntq %%mm7, 56(%1)\n"
8262 + "1: prefetch 320(%1)\n"
8263 + "2: movq (%1), %%mm0\n"
8264 + " movntq %%mm0, (%2)\n"
8265 + " movq 8(%1), %%mm1\n"
8266 + " movntq %%mm1, 8(%2)\n"
8267 + " movq 16(%1), %%mm2\n"
8268 + " movntq %%mm2, 16(%2)\n"
8269 + " movq 24(%1), %%mm3\n"
8270 + " movntq %%mm3, 24(%2)\n"
8271 + " movq 32(%1), %%mm4\n"
8272 + " movntq %%mm4, 32(%2)\n"
8273 + " movq 40(%1), %%mm5\n"
8274 + " movntq %%mm5, 40(%2)\n"
8275 + " movq 48(%1), %%mm6\n"
8276 + " movntq %%mm6, 48(%2)\n"
8277 + " movq 56(%1), %%mm7\n"
8278 + " movntq %%mm7, 56(%2)\n"
8279 ".section .fixup, \"ax\"\n"
8280 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8283 +#ifdef CONFIG_PAX_KERNEXEC
8284 + " movl %%cr0, %0\n"
8285 + " movl %0, %%eax\n"
8286 + " andl $0xFFFEFFFF, %%eax\n"
8287 + " movl %%eax, %%cr0\n"
8290 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8292 +#ifdef CONFIG_PAX_KERNEXEC
8293 + " movl %0, %%cr0\n"
8299 - : : "r" (from), "r" (to) : "memory");
8300 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8304 @@ -285,50 +343,78 @@ static void fast_clear_page(void *page)
8305 static void fast_copy_page(void *to, void *from)
8310 + unsigned long cr0;
8314 __asm__ __volatile__ (
8315 - "1: prefetch (%0)\n"
8316 - " prefetch 64(%0)\n"
8317 - " prefetch 128(%0)\n"
8318 - " prefetch 192(%0)\n"
8319 - " prefetch 256(%0)\n"
8320 + "1: prefetch (%1)\n"
8321 + " prefetch 64(%1)\n"
8322 + " prefetch 128(%1)\n"
8323 + " prefetch 192(%1)\n"
8324 + " prefetch 256(%1)\n"
8326 ".section .fixup, \"ax\"\n"
8327 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8330 +#ifdef CONFIG_PAX_KERNEXEC
8331 + " movl %%cr0, %0\n"
8332 + " movl %0, %%eax\n"
8333 + " andl $0xFFFEFFFF, %%eax\n"
8334 + " movl %%eax, %%cr0\n"
8337 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8339 +#ifdef CONFIG_PAX_KERNEXEC
8340 + " movl %0, %%cr0\n"
8347 + : "=&r" (cr0) : "r" (from) : "ax");
8349 for(i=0; i<4096/64; i++)
8351 __asm__ __volatile__ (
8352 - "1: prefetch 320(%0)\n"
8353 - "2: movq (%0), %%mm0\n"
8354 - " movq 8(%0), %%mm1\n"
8355 - " movq 16(%0), %%mm2\n"
8356 - " movq 24(%0), %%mm3\n"
8357 - " movq %%mm0, (%1)\n"
8358 - " movq %%mm1, 8(%1)\n"
8359 - " movq %%mm2, 16(%1)\n"
8360 - " movq %%mm3, 24(%1)\n"
8361 - " movq 32(%0), %%mm0\n"
8362 - " movq 40(%0), %%mm1\n"
8363 - " movq 48(%0), %%mm2\n"
8364 - " movq 56(%0), %%mm3\n"
8365 - " movq %%mm0, 32(%1)\n"
8366 - " movq %%mm1, 40(%1)\n"
8367 - " movq %%mm2, 48(%1)\n"
8368 - " movq %%mm3, 56(%1)\n"
8369 + "1: prefetch 320(%1)\n"
8370 + "2: movq (%1), %%mm0\n"
8371 + " movq 8(%1), %%mm1\n"
8372 + " movq 16(%1), %%mm2\n"
8373 + " movq 24(%1), %%mm3\n"
8374 + " movq %%mm0, (%2)\n"
8375 + " movq %%mm1, 8(%2)\n"
8376 + " movq %%mm2, 16(%2)\n"
8377 + " movq %%mm3, 24(%2)\n"
8378 + " movq 32(%1), %%mm0\n"
8379 + " movq 40(%1), %%mm1\n"
8380 + " movq 48(%1), %%mm2\n"
8381 + " movq 56(%1), %%mm3\n"
8382 + " movq %%mm0, 32(%2)\n"
8383 + " movq %%mm1, 40(%2)\n"
8384 + " movq %%mm2, 48(%2)\n"
8385 + " movq %%mm3, 56(%2)\n"
8386 ".section .fixup, \"ax\"\n"
8387 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8390 +#ifdef CONFIG_PAX_KERNEXEC
8391 + " movl %%cr0, %0\n"
8392 + " movl %0, %%eax\n"
8393 + " andl $0xFFFEFFFF, %%eax\n"
8394 + " movl %%eax, %%cr0\n"
8397 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8399 +#ifdef CONFIG_PAX_KERNEXEC
8400 + " movl %0, %%cr0\n"
8406 - : : "r" (from), "r" (to) : "memory");
8407 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8411 diff -urNp linux-2.6.25.10/arch/x86/lib/putuser_32.S linux-2.6.25.10/arch/x86/lib/putuser_32.S
8412 --- linux-2.6.25.10/arch/x86/lib/putuser_32.S 2008-07-02 23:46:47.000000000 -0400
8413 +++ linux-2.6.25.10/arch/x86/lib/putuser_32.S 2008-07-03 16:53:25.000000000 -0400
8415 #include <linux/linkage.h>
8416 #include <asm/dwarf2.h>
8417 #include <asm/thread_info.h>
8419 +#include <asm/segment.h>
8423 @@ -41,7 +41,11 @@ ENTRY(__put_user_1)
8425 cmpl TI_addr_limit(%ebx),%ecx
8427 + pushl $(__USER_DS)
8434 ENDPROC(__put_user_1)
8435 @@ -52,7 +56,11 @@ ENTRY(__put_user_2)
8439 + pushl $(__USER_DS)
8446 ENDPROC(__put_user_2)
8447 @@ -63,7 +71,11 @@ ENTRY(__put_user_4)
8451 + pushl $(__USER_DS)
8458 ENDPROC(__put_user_4)
8459 @@ -74,8 +86,12 @@ ENTRY(__put_user_8)
8463 + pushl $(__USER_DS)
8466 5: movl %edx,4(%ecx)
8471 ENDPROC(__put_user_8)
8472 @@ -85,6 +101,10 @@ bad_put_user:
8473 CFI_DEF_CFA esp, 2*4
8474 CFI_OFFSET eip, -1*4
8475 CFI_OFFSET ebx, -2*4
8477 + CFI_ADJUST_CFA_OFFSET 4
8479 + CFI_ADJUST_CFA_OFFSET -4
8483 diff -urNp linux-2.6.25.10/arch/x86/lib/usercopy_32.c linux-2.6.25.10/arch/x86/lib/usercopy_32.c
8484 --- linux-2.6.25.10/arch/x86/lib/usercopy_32.c 2008-07-02 23:46:47.000000000 -0400
8485 +++ linux-2.6.25.10/arch/x86/lib/usercopy_32.c 2008-07-03 16:53:25.000000000 -0400
8486 @@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
8487 * Copy a null terminated string from userspace.
8490 -#define __do_strncpy_from_user(dst,src,count,res) \
8492 - int __d0, __d1, __d2; \
8494 - __asm__ __volatile__( \
8495 - " testl %1,%1\n" \
8499 - " testb %%al,%%al\n" \
8503 - "1: subl %1,%0\n" \
8505 - ".section .fixup,\"ax\"\n" \
8506 - "3: movl %5,%0\n" \
8509 - _ASM_EXTABLE(0b,3b) \
8510 - : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
8512 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
8515 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
8517 + int __d0, __d1, __d2;
8518 + long res = -EFAULT;
8521 + __asm__ __volatile__(
8522 + " movw %w10,%%ds\n"
8527 + " testb %%al,%%al\n"
8535 + ".section .fixup,\"ax\"\n"
8539 + _ASM_EXTABLE(0b,3b)
8540 + : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
8542 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
8549 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
8550 @@ -78,9 +85,7 @@ do { \
8552 __strncpy_from_user(char *dst, const char __user *src, long count)
8555 - __do_strncpy_from_user(dst, src, count, res);
8557 + return __do_strncpy_from_user(dst, src, count);
8559 EXPORT_SYMBOL(__strncpy_from_user);
8561 @@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char
8564 if (access_ok(VERIFY_READ, src, 1))
8565 - __do_strncpy_from_user(dst, src, count, res);
8566 + res = __do_strncpy_from_user(dst, src, count);
8569 EXPORT_SYMBOL(strncpy_from_user);
8570 @@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
8574 -#define __do_clear_user(addr,size) \
8578 - __asm__ __volatile__( \
8579 - "0: rep; stosl\n" \
8581 - "1: rep; stosb\n" \
8583 - ".section .fixup,\"ax\"\n" \
8584 - "3: lea 0(%2,%0,4),%0\n" \
8587 - _ASM_EXTABLE(0b,3b) \
8588 - _ASM_EXTABLE(1b,2b) \
8589 - : "=&c"(size), "=&D" (__d0) \
8590 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
8592 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
8597 + __asm__ __volatile__(
8598 + " movw %w6,%%es\n"
8605 + ".section .fixup,\"ax\"\n"
8606 + "3: lea 0(%2,%0,4),%0\n"
8609 + _ASM_EXTABLE(0b,3b)
8610 + _ASM_EXTABLE(1b,2b)
8611 + : "=&c"(size), "=&D" (__d0)
8612 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
8618 * clear_user: - Zero a block of memory in user space.
8619 @@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
8622 if (access_ok(VERIFY_WRITE, to, n))
8623 - __do_clear_user(to, n);
8624 + n = __do_clear_user(to, n);
8627 EXPORT_SYMBOL(clear_user);
8628 @@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
8630 __clear_user(void __user *to, unsigned long n)
8632 - __do_clear_user(to, n);
8634 + return __do_clear_user(to, n);
8636 EXPORT_SYMBOL(__clear_user);
8638 @@ -193,14 +203,17 @@ long strnlen_user(const char __user *s,
8641 __asm__ __volatile__(
8642 + " movw %w8,%%es\n"
8645 - " andl %0,%%ecx\n"
8646 + " movl %0,%%ecx\n"
8654 ".section .fixup,\"ax\"\n"
8655 "2: xorl %%eax,%%eax\n"
8657 @@ -212,7 +225,7 @@ long strnlen_user(const char __user *s,
8660 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
8661 - :"0" (n), "1" (s), "2" (0), "3" (mask)
8662 + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
8666 @@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
8668 #ifdef CONFIG_X86_INTEL_USERCOPY
8669 static unsigned long
8670 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
8671 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
8674 __asm__ __volatile__(
8675 + " movw %w6, %%es\n"
8677 "1: movl 32(%4), %%eax\n"
8679 @@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
8681 "3: movl 0(%4), %%eax\n"
8682 "4: movl 4(%4), %%edx\n"
8683 - "5: movl %%eax, 0(%3)\n"
8684 - "6: movl %%edx, 4(%3)\n"
8685 + "5: movl %%eax, %%es:0(%3)\n"
8686 + "6: movl %%edx, %%es:4(%3)\n"
8687 "7: movl 8(%4), %%eax\n"
8688 "8: movl 12(%4),%%edx\n"
8689 - "9: movl %%eax, 8(%3)\n"
8690 - "10: movl %%edx, 12(%3)\n"
8691 + "9: movl %%eax, %%es:8(%3)\n"
8692 + "10: movl %%edx, %%es:12(%3)\n"
8693 "11: movl 16(%4), %%eax\n"
8694 "12: movl 20(%4), %%edx\n"
8695 - "13: movl %%eax, 16(%3)\n"
8696 - "14: movl %%edx, 20(%3)\n"
8697 + "13: movl %%eax, %%es:16(%3)\n"
8698 + "14: movl %%edx, %%es:20(%3)\n"
8699 "15: movl 24(%4), %%eax\n"
8700 "16: movl 28(%4), %%edx\n"
8701 - "17: movl %%eax, 24(%3)\n"
8702 - "18: movl %%edx, 28(%3)\n"
8703 + "17: movl %%eax, %%es:24(%3)\n"
8704 + "18: movl %%edx, %%es:28(%3)\n"
8705 "19: movl 32(%4), %%eax\n"
8706 "20: movl 36(%4), %%edx\n"
8707 - "21: movl %%eax, 32(%3)\n"
8708 - "22: movl %%edx, 36(%3)\n"
8709 + "21: movl %%eax, %%es:32(%3)\n"
8710 + "22: movl %%edx, %%es:36(%3)\n"
8711 "23: movl 40(%4), %%eax\n"
8712 "24: movl 44(%4), %%edx\n"
8713 - "25: movl %%eax, 40(%3)\n"
8714 - "26: movl %%edx, 44(%3)\n"
8715 + "25: movl %%eax, %%es:40(%3)\n"
8716 + "26: movl %%edx, %%es:44(%3)\n"
8717 "27: movl 48(%4), %%eax\n"
8718 "28: movl 52(%4), %%edx\n"
8719 - "29: movl %%eax, 48(%3)\n"
8720 - "30: movl %%edx, 52(%3)\n"
8721 + "29: movl %%eax, %%es:48(%3)\n"
8722 + "30: movl %%edx, %%es:52(%3)\n"
8723 "31: movl 56(%4), %%eax\n"
8724 "32: movl 60(%4), %%edx\n"
8725 - "33: movl %%eax, 56(%3)\n"
8726 - "34: movl %%edx, 60(%3)\n"
8727 + "33: movl %%eax, %%es:56(%3)\n"
8728 + "34: movl %%edx, %%es:60(%3)\n"
8732 @@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
8733 "36: movl %%eax, %0\n"
8738 ".section .fixup,\"ax\"\n"
8739 "101: lea 0(%%eax,%0,4),%0\n"
8741 @@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
8744 : "=&c"(size), "=&D" (d0), "=&S" (d1)
8745 - : "1"(to), "2"(from), "0"(size)
8746 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8747 + : "eax", "edx", "memory");
8751 +static unsigned long
8752 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
8755 + __asm__ __volatile__(
8756 + " movw %w6, %%ds\n"
8757 + " .align 2,0x90\n"
8758 + "1: movl 32(%4), %%eax\n"
8761 + "2: movl 64(%4), %%eax\n"
8762 + " .align 2,0x90\n"
8763 + "3: movl 0(%4), %%eax\n"
8764 + "4: movl 4(%4), %%edx\n"
8765 + "5: movl %%eax, %%es:0(%3)\n"
8766 + "6: movl %%edx, %%es:4(%3)\n"
8767 + "7: movl 8(%4), %%eax\n"
8768 + "8: movl 12(%4),%%edx\n"
8769 + "9: movl %%eax, %%es:8(%3)\n"
8770 + "10: movl %%edx, %%es:12(%3)\n"
8771 + "11: movl 16(%4), %%eax\n"
8772 + "12: movl 20(%4), %%edx\n"
8773 + "13: movl %%eax, %%es:16(%3)\n"
8774 + "14: movl %%edx, %%es:20(%3)\n"
8775 + "15: movl 24(%4), %%eax\n"
8776 + "16: movl 28(%4), %%edx\n"
8777 + "17: movl %%eax, %%es:24(%3)\n"
8778 + "18: movl %%edx, %%es:28(%3)\n"
8779 + "19: movl 32(%4), %%eax\n"
8780 + "20: movl 36(%4), %%edx\n"
8781 + "21: movl %%eax, %%es:32(%3)\n"
8782 + "22: movl %%edx, %%es:36(%3)\n"
8783 + "23: movl 40(%4), %%eax\n"
8784 + "24: movl 44(%4), %%edx\n"
8785 + "25: movl %%eax, %%es:40(%3)\n"
8786 + "26: movl %%edx, %%es:44(%3)\n"
8787 + "27: movl 48(%4), %%eax\n"
8788 + "28: movl 52(%4), %%edx\n"
8789 + "29: movl %%eax, %%es:48(%3)\n"
8790 + "30: movl %%edx, %%es:52(%3)\n"
8791 + "31: movl 56(%4), %%eax\n"
8792 + "32: movl 60(%4), %%edx\n"
8793 + "33: movl %%eax, %%es:56(%3)\n"
8794 + "34: movl %%edx, %%es:60(%3)\n"
8795 + " addl $-64, %0\n"
8800 + "35: movl %0, %%eax\n"
8802 + " andl $3, %%eax\n"
8804 + "99: rep; movsl\n"
8805 + "36: movl %%eax, %0\n"
8806 + "37: rep; movsb\n"
8810 + ".section .fixup,\"ax\"\n"
8811 + "101: lea 0(%%eax,%0,4),%0\n"
8814 + ".section __ex_table,\"a\"\n"
8816 + " .long 1b,100b\n"
8817 + " .long 2b,100b\n"
8818 + " .long 3b,100b\n"
8819 + " .long 4b,100b\n"
8820 + " .long 5b,100b\n"
8821 + " .long 6b,100b\n"
8822 + " .long 7b,100b\n"
8823 + " .long 8b,100b\n"
8824 + " .long 9b,100b\n"
8825 + " .long 10b,100b\n"
8826 + " .long 11b,100b\n"
8827 + " .long 12b,100b\n"
8828 + " .long 13b,100b\n"
8829 + " .long 14b,100b\n"
8830 + " .long 15b,100b\n"
8831 + " .long 16b,100b\n"
8832 + " .long 17b,100b\n"
8833 + " .long 18b,100b\n"
8834 + " .long 19b,100b\n"
8835 + " .long 20b,100b\n"
8836 + " .long 21b,100b\n"
8837 + " .long 22b,100b\n"
8838 + " .long 23b,100b\n"
8839 + " .long 24b,100b\n"
8840 + " .long 25b,100b\n"
8841 + " .long 26b,100b\n"
8842 + " .long 27b,100b\n"
8843 + " .long 28b,100b\n"
8844 + " .long 29b,100b\n"
8845 + " .long 30b,100b\n"
8846 + " .long 31b,100b\n"
8847 + " .long 32b,100b\n"
8848 + " .long 33b,100b\n"
8849 + " .long 34b,100b\n"
8850 + " .long 35b,100b\n"
8851 + " .long 36b,100b\n"
8852 + " .long 37b,100b\n"
8853 + " .long 99b,101b\n"
8855 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
8856 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8857 : "eax", "edx", "memory");
8860 @@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
8863 __asm__ __volatile__(
8864 + " movw %w6, %%ds\n"
8866 "0: movl 32(%4), %%eax\n"
8868 @@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
8870 "2: movl 0(%4), %%eax\n"
8871 "21: movl 4(%4), %%edx\n"
8872 - " movl %%eax, 0(%3)\n"
8873 - " movl %%edx, 4(%3)\n"
8874 + " movl %%eax, %%es:0(%3)\n"
8875 + " movl %%edx, %%es:4(%3)\n"
8876 "3: movl 8(%4), %%eax\n"
8877 "31: movl 12(%4),%%edx\n"
8878 - " movl %%eax, 8(%3)\n"
8879 - " movl %%edx, 12(%3)\n"
8880 + " movl %%eax, %%es:8(%3)\n"
8881 + " movl %%edx, %%es:12(%3)\n"
8882 "4: movl 16(%4), %%eax\n"
8883 "41: movl 20(%4), %%edx\n"
8884 - " movl %%eax, 16(%3)\n"
8885 - " movl %%edx, 20(%3)\n"
8886 + " movl %%eax, %%es:16(%3)\n"
8887 + " movl %%edx, %%es:20(%3)\n"
8888 "10: movl 24(%4), %%eax\n"
8889 "51: movl 28(%4), %%edx\n"
8890 - " movl %%eax, 24(%3)\n"
8891 - " movl %%edx, 28(%3)\n"
8892 + " movl %%eax, %%es:24(%3)\n"
8893 + " movl %%edx, %%es:28(%3)\n"
8894 "11: movl 32(%4), %%eax\n"
8895 "61: movl 36(%4), %%edx\n"
8896 - " movl %%eax, 32(%3)\n"
8897 - " movl %%edx, 36(%3)\n"
8898 + " movl %%eax, %%es:32(%3)\n"
8899 + " movl %%edx, %%es:36(%3)\n"
8900 "12: movl 40(%4), %%eax\n"
8901 "71: movl 44(%4), %%edx\n"
8902 - " movl %%eax, 40(%3)\n"
8903 - " movl %%edx, 44(%3)\n"
8904 + " movl %%eax, %%es:40(%3)\n"
8905 + " movl %%edx, %%es:44(%3)\n"
8906 "13: movl 48(%4), %%eax\n"
8907 "81: movl 52(%4), %%edx\n"
8908 - " movl %%eax, 48(%3)\n"
8909 - " movl %%edx, 52(%3)\n"
8910 + " movl %%eax, %%es:48(%3)\n"
8911 + " movl %%edx, %%es:52(%3)\n"
8912 "14: movl 56(%4), %%eax\n"
8913 "91: movl 60(%4), %%edx\n"
8914 - " movl %%eax, 56(%3)\n"
8915 - " movl %%edx, 60(%3)\n"
8916 + " movl %%eax, %%es:56(%3)\n"
8917 + " movl %%edx, %%es:60(%3)\n"
8921 @@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
8927 ".section .fixup,\"ax\"\n"
8928 "9: lea 0(%%eax,%0,4),%0\n"
8930 @@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
8933 : "=&c"(size), "=&D" (d0), "=&S" (d1)
8934 - : "1"(to), "2"(from), "0"(size)
8935 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8936 : "eax", "edx", "memory");
8939 @@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
8942 __asm__ __volatile__(
8943 + " movw %w6, %%ds\n"
8945 "0: movl 32(%4), %%eax\n"
8947 @@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
8949 "2: movl 0(%4), %%eax\n"
8950 "21: movl 4(%4), %%edx\n"
8951 - " movnti %%eax, 0(%3)\n"
8952 - " movnti %%edx, 4(%3)\n"
8953 + " movnti %%eax, %%es:0(%3)\n"
8954 + " movnti %%edx, %%es:4(%3)\n"
8955 "3: movl 8(%4), %%eax\n"
8956 "31: movl 12(%4),%%edx\n"
8957 - " movnti %%eax, 8(%3)\n"
8958 - " movnti %%edx, 12(%3)\n"
8959 + " movnti %%eax, %%es:8(%3)\n"
8960 + " movnti %%edx, %%es:12(%3)\n"
8961 "4: movl 16(%4), %%eax\n"
8962 "41: movl 20(%4), %%edx\n"
8963 - " movnti %%eax, 16(%3)\n"
8964 - " movnti %%edx, 20(%3)\n"
8965 + " movnti %%eax, %%es:16(%3)\n"
8966 + " movnti %%edx, %%es:20(%3)\n"
8967 "10: movl 24(%4), %%eax\n"
8968 "51: movl 28(%4), %%edx\n"
8969 - " movnti %%eax, 24(%3)\n"
8970 - " movnti %%edx, 28(%3)\n"
8971 + " movnti %%eax, %%es:24(%3)\n"
8972 + " movnti %%edx, %%es:28(%3)\n"
8973 "11: movl 32(%4), %%eax\n"
8974 "61: movl 36(%4), %%edx\n"
8975 - " movnti %%eax, 32(%3)\n"
8976 - " movnti %%edx, 36(%3)\n"
8977 + " movnti %%eax, %%es:32(%3)\n"
8978 + " movnti %%edx, %%es:36(%3)\n"
8979 "12: movl 40(%4), %%eax\n"
8980 "71: movl 44(%4), %%edx\n"
8981 - " movnti %%eax, 40(%3)\n"
8982 - " movnti %%edx, 44(%3)\n"
8983 + " movnti %%eax, %%es:40(%3)\n"
8984 + " movnti %%edx, %%es:44(%3)\n"
8985 "13: movl 48(%4), %%eax\n"
8986 "81: movl 52(%4), %%edx\n"
8987 - " movnti %%eax, 48(%3)\n"
8988 - " movnti %%edx, 52(%3)\n"
8989 + " movnti %%eax, %%es:48(%3)\n"
8990 + " movnti %%edx, %%es:52(%3)\n"
8991 "14: movl 56(%4), %%eax\n"
8992 "91: movl 60(%4), %%edx\n"
8993 - " movnti %%eax, 56(%3)\n"
8994 - " movnti %%edx, 60(%3)\n"
8995 + " movnti %%eax, %%es:56(%3)\n"
8996 + " movnti %%edx, %%es:60(%3)\n"
9000 @@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
9006 ".section .fixup,\"ax\"\n"
9007 "9: lea 0(%%eax,%0,4),%0\n"
9009 @@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
9012 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9013 - : "1"(to), "2"(from), "0"(size)
9014 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9015 : "eax", "edx", "memory");
9018 @@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
9021 __asm__ __volatile__(
9022 + " movw %w6, %%ds\n"
9024 "0: movl 32(%4), %%eax\n"
9026 @@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
9028 "2: movl 0(%4), %%eax\n"
9029 "21: movl 4(%4), %%edx\n"
9030 - " movnti %%eax, 0(%3)\n"
9031 - " movnti %%edx, 4(%3)\n"
9032 + " movnti %%eax, %%es:0(%3)\n"
9033 + " movnti %%edx, %%es:4(%3)\n"
9034 "3: movl 8(%4), %%eax\n"
9035 "31: movl 12(%4),%%edx\n"
9036 - " movnti %%eax, 8(%3)\n"
9037 - " movnti %%edx, 12(%3)\n"
9038 + " movnti %%eax, %%es:8(%3)\n"
9039 + " movnti %%edx, %%es:12(%3)\n"
9040 "4: movl 16(%4), %%eax\n"
9041 "41: movl 20(%4), %%edx\n"
9042 - " movnti %%eax, 16(%3)\n"
9043 - " movnti %%edx, 20(%3)\n"
9044 + " movnti %%eax, %%es:16(%3)\n"
9045 + " movnti %%edx, %%es:20(%3)\n"
9046 "10: movl 24(%4), %%eax\n"
9047 "51: movl 28(%4), %%edx\n"
9048 - " movnti %%eax, 24(%3)\n"
9049 - " movnti %%edx, 28(%3)\n"
9050 + " movnti %%eax, %%es:24(%3)\n"
9051 + " movnti %%edx, %%es:28(%3)\n"
9052 "11: movl 32(%4), %%eax\n"
9053 "61: movl 36(%4), %%edx\n"
9054 - " movnti %%eax, 32(%3)\n"
9055 - " movnti %%edx, 36(%3)\n"
9056 + " movnti %%eax, %%es:32(%3)\n"
9057 + " movnti %%edx, %%es:36(%3)\n"
9058 "12: movl 40(%4), %%eax\n"
9059 "71: movl 44(%4), %%edx\n"
9060 - " movnti %%eax, 40(%3)\n"
9061 - " movnti %%edx, 44(%3)\n"
9062 + " movnti %%eax, %%es:40(%3)\n"
9063 + " movnti %%edx, %%es:44(%3)\n"
9064 "13: movl 48(%4), %%eax\n"
9065 "81: movl 52(%4), %%edx\n"
9066 - " movnti %%eax, 48(%3)\n"
9067 - " movnti %%edx, 52(%3)\n"
9068 + " movnti %%eax, %%es:48(%3)\n"
9069 + " movnti %%edx, %%es:52(%3)\n"
9070 "14: movl 56(%4), %%eax\n"
9071 "91: movl 60(%4), %%edx\n"
9072 - " movnti %%eax, 56(%3)\n"
9073 - " movnti %%edx, 60(%3)\n"
9074 + " movnti %%eax, %%es:56(%3)\n"
9075 + " movnti %%edx, %%es:60(%3)\n"
9079 @@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
9085 ".section .fixup,\"ax\"\n"
9086 "9: lea 0(%%eax,%0,4),%0\n"
9088 @@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
9091 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9092 - : "1"(to), "2"(from), "0"(size)
9093 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9094 : "eax", "edx", "memory");
9097 @@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
9099 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
9100 unsigned long size);
9101 -unsigned long __copy_user_intel(void __user *to, const void *from,
9102 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
9103 + unsigned long size);
9104 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
9105 unsigned long size);
9106 unsigned long __copy_user_zeroing_intel_nocache(void *to,
9107 const void __user *from, unsigned long size);
9108 #endif /* CONFIG_X86_INTEL_USERCOPY */
9110 /* Generic arbitrary sized copy. */
9111 -#define __copy_user(to,from,size) \
9113 - int __d0, __d1, __d2; \
9114 - __asm__ __volatile__( \
9121 - "4: rep; movsb\n" \
9125 - " .align 2,0x90\n" \
9126 - "0: rep; movsl\n" \
9128 - "1: rep; movsb\n" \
9130 - ".section .fixup,\"ax\"\n" \
9131 - "5: addl %3,%0\n" \
9133 - "3: lea 0(%3,%0,4),%0\n" \
9136 - ".section __ex_table,\"a\"\n" \
9138 - " .long 4b,5b\n" \
9139 - " .long 0b,3b\n" \
9140 - " .long 1b,2b\n" \
9142 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9143 - : "3"(size), "0"(size), "1"(to), "2"(from) \
9147 -#define __copy_user_zeroing(to,from,size) \
9149 - int __d0, __d1, __d2; \
9150 - __asm__ __volatile__( \
9157 - "4: rep; movsb\n" \
9161 - " .align 2,0x90\n" \
9162 - "0: rep; movsl\n" \
9164 - "1: rep; movsb\n" \
9166 - ".section .fixup,\"ax\"\n" \
9167 - "5: addl %3,%0\n" \
9169 - "3: lea 0(%3,%0,4),%0\n" \
9171 - " pushl %%eax\n" \
9172 - " xorl %%eax,%%eax\n" \
9178 - ".section __ex_table,\"a\"\n" \
9180 - " .long 4b,5b\n" \
9181 - " .long 0b,3b\n" \
9182 - " .long 1b,6b\n" \
9184 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9185 - : "3"(size), "0"(size), "1"(to), "2"(from) \
9188 +static unsigned long
9189 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
9191 + int __d0, __d1, __d2;
9193 + __asm__ __volatile__(
9194 + " movw %w8,%%es\n"
9205 + " .align 2,0x90\n"
9212 + ".section .fixup,\"ax\"\n"
9215 + "3: lea 0(%3,%0,4),%0\n"
9218 + ".section __ex_table,\"a\"\n"
9224 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9225 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9230 +static unsigned long
9231 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
9233 + int __d0, __d1, __d2;
9235 + __asm__ __volatile__(
9236 + " movw %w8,%%ds\n"
9247 + " .align 2,0x90\n"
9254 + ".section .fixup,\"ax\"\n"
9257 + "3: lea 0(%3,%0,4),%0\n"
9260 + ".section __ex_table,\"a\"\n"
9266 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9267 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9272 +static unsigned long
9273 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
9275 + int __d0, __d1, __d2;
9277 + __asm__ __volatile__(
9278 + " movw %w8,%%ds\n"
9289 + " .align 2,0x90\n"
9296 + ".section .fixup,\"ax\"\n"
9299 + "3: lea 0(%3,%0,4),%0\n"
9302 + " xorl %%eax,%%eax\n"
9308 + ".section __ex_table,\"a\"\n"
9314 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9315 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9320 unsigned long __copy_to_user_ll(void __user *to, const void *from,
9322 @@ -768,9 +959,9 @@ survive:
9325 if (movsl_is_ok(to, from, n))
9326 - __copy_user(to, from, n);
9327 + n = __generic_copy_to_user(to, from, n);
9329 - n = __copy_user_intel(to, from, n);
9330 + n = __generic_copy_to_user_intel(to, from, n);
9333 EXPORT_SYMBOL(__copy_to_user_ll);
9334 @@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
9337 if (movsl_is_ok(to, from, n))
9338 - __copy_user_zeroing(to, from, n);
9339 + n = __copy_user_zeroing(to, from, n);
9341 n = __copy_user_zeroing_intel(to, from, n);
9343 @@ -790,9 +981,9 @@ unsigned long __copy_from_user_ll_nozero
9346 if (movsl_is_ok(to, from, n))
9347 - __copy_user(to, from, n);
9348 + n = __generic_copy_from_user(to, from, n);
9350 - n = __copy_user_intel((void __user *)to,
9351 + n = __generic_copy_from_user_intel((void __user *)to,
9352 (const void *)from, n);
9355 @@ -803,11 +994,11 @@ unsigned long __copy_from_user_ll_nocach
9357 #ifdef CONFIG_X86_INTEL_USERCOPY
9358 if ( n > 64 && cpu_has_xmm2)
9359 - n = __copy_user_zeroing_intel_nocache(to, from, n);
9360 + n = __copy_user_zeroing_intel_nocache(to, from, n);
9362 - __copy_user_zeroing(to, from, n);
9363 + n = __copy_user_zeroing(to, from, n);
9365 - __copy_user_zeroing(to, from, n);
9366 + n = __copy_user_zeroing(to, from, n);
9370 @@ -818,11 +1009,11 @@ unsigned long __copy_from_user_ll_nocach
9372 #ifdef CONFIG_X86_INTEL_USERCOPY
9373 if ( n > 64 && cpu_has_xmm2)
9374 - n = __copy_user_intel_nocache(to, from, n);
9375 + n = __copy_user_intel_nocache(to, from, n);
9377 - __copy_user(to, from, n);
9378 + n = __generic_copy_from_user(to, from, n);
9380 - __copy_user(to, from, n);
9381 + n = __generic_copy_from_user(to, from, n);
9385 @@ -871,8 +1062,35 @@ copy_from_user(void *to, const void __us
9387 if (access_ok(VERIFY_READ, from, n))
9388 n = __copy_from_user(to, from, n);
9390 + else if ((long)n > 0)
9394 EXPORT_SYMBOL(copy_from_user);
9396 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9397 +void __set_fs(mm_segment_t x, int cpu)
9399 + unsigned long limit = x.seg;
9400 + struct desc_struct d;
9402 + current_thread_info()->addr_limit = x;
9403 + if (likely(limit))
9404 + limit = (limit - 1UL) >> PAGE_SHIFT;
9405 + pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
9406 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
9409 +void set_fs(mm_segment_t x)
9411 + __set_fs(x, get_cpu());
9412 + put_cpu_no_resched();
9415 +void set_fs(mm_segment_t x)
9417 + current_thread_info()->addr_limit = x;
9421 +EXPORT_SYMBOL(set_fs);
9422 diff -urNp linux-2.6.25.10/arch/x86/mach-voyager/voyager_basic.c linux-2.6.25.10/arch/x86/mach-voyager/voyager_basic.c
9423 --- linux-2.6.25.10/arch/x86/mach-voyager/voyager_basic.c 2008-07-02 23:46:47.000000000 -0400
9424 +++ linux-2.6.25.10/arch/x86/mach-voyager/voyager_basic.c 2008-07-03 16:53:25.000000000 -0400
9425 @@ -125,7 +125,7 @@ int __init voyager_memory_detect(int reg
9428 unsigned long map_addr;
9429 - unsigned long old;
9432 if (region >= CLICK_ENTRIES) {
9433 printk("Voyager: Illegal ClickMap region %d\n", region);
9434 @@ -140,7 +140,7 @@ int __init voyager_memory_detect(int reg
9436 /* steal page 0 for this */
9438 - pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9439 + pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9441 /* now clear everything out but page 0 */
9442 map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
9443 diff -urNp linux-2.6.25.10/arch/x86/mach-voyager/voyager_smp.c linux-2.6.25.10/arch/x86/mach-voyager/voyager_smp.c
9444 --- linux-2.6.25.10/arch/x86/mach-voyager/voyager_smp.c 2008-07-02 23:46:47.000000000 -0400
9445 +++ linux-2.6.25.10/arch/x86/mach-voyager/voyager_smp.c 2008-07-03 16:53:25.000000000 -0400
9446 @@ -540,6 +540,10 @@ static void __init do_boot_cpu(__u8 cpu)
9447 __u32 *hijack_vector;
9448 __u32 start_phys_address = setup_trampoline();
9450 +#ifdef CONFIG_PAX_KERNEXEC
9451 + unsigned long cr0;
9454 /* There's a clever trick to this: The linux trampoline is
9455 * compiled to begin at absolute location zero, so make the
9456 * address zero but have the data segment selector compensate
9457 @@ -559,7 +563,17 @@ static void __init do_boot_cpu(__u8 cpu)
9460 per_cpu(current_task, cpu) = idle;
9461 - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9463 +#ifdef CONFIG_PAX_KERNEXEC
9464 + pax_open_kernel(cr0);
9467 + early_gdt_descr.address = get_cpu_gdt_table(cpu);
9469 +#ifdef CONFIG_PAX_KERNEXEC
9470 + pax_close_kernel(cr0);
9475 /* Note: Don't modify initial ss override */
9476 @@ -1242,7 +1256,7 @@ void smp_local_timer_interrupt(void)
9477 per_cpu(prof_counter, cpu);
9480 - update_process_times(user_mode_vm(get_irq_regs()));
9481 + update_process_times(user_mode(get_irq_regs()));
9484 if (((1 << cpu) & voyager_extended_vic_processors) == 0)
9485 diff -urNp linux-2.6.25.10/arch/x86/mm/extable.c linux-2.6.25.10/arch/x86/mm/extable.c
9486 --- linux-2.6.25.10/arch/x86/mm/extable.c 2008-07-02 23:46:47.000000000 -0400
9487 +++ linux-2.6.25.10/arch/x86/mm/extable.c 2008-07-03 16:53:25.000000000 -0400
9489 #include <linux/module.h>
9490 #include <linux/spinlock.h>
9491 +#include <linux/sort.h>
9492 #include <asm/uaccess.h>
9495 + * The exception table needs to be sorted so that the binary
9496 + * search that we use to find entries in it works properly.
9497 + * This is used both for the kernel exception table and for
9498 + * the exception tables of modules that get loaded.
9500 +static int cmp_ex(const void *a, const void *b)
9502 + const struct exception_table_entry *x = a, *y = b;
9504 + /* avoid overflow */
9505 + if (x->insn > y->insn)
9507 + if (x->insn < y->insn)
9512 +static void swap_ex(void *a, void *b, int size)
9514 + struct exception_table_entry t, *x = a, *y = b;
9516 +#ifdef CONFIG_PAX_KERNEXEC
9517 + unsigned long cr0;
9522 +#ifdef CONFIG_PAX_KERNEXEC
9523 + pax_open_kernel(cr0);
9529 +#ifdef CONFIG_PAX_KERNEXEC
9530 + pax_close_kernel(cr0);
9535 +void sort_extable(struct exception_table_entry *start,
9536 + struct exception_table_entry *finish)
9538 + sort(start, finish - start, sizeof(struct exception_table_entry),
9542 int fixup_exception(struct pt_regs *regs)
9544 const struct exception_table_entry *fixup;
9546 #ifdef CONFIG_PNPBIOS
9547 - if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
9548 + if (unlikely(!(regs->flags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->cs))) {
9549 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
9550 extern u32 pnp_bios_is_utter_crap;
9551 pnp_bios_is_utter_crap = 1;
9552 diff -urNp linux-2.6.25.10/arch/x86/mm/fault.c linux-2.6.25.10/arch/x86/mm/fault.c
9553 --- linux-2.6.25.10/arch/x86/mm/fault.c 2008-07-02 23:46:47.000000000 -0400
9554 +++ linux-2.6.25.10/arch/x86/mm/fault.c 2008-07-03 16:53:25.000000000 -0400
9556 #include <linux/uaccess.h>
9557 #include <linux/kdebug.h>
9558 #include <linux/suspend.h>
9559 +#include <linux/unistd.h>
9560 +#include <linux/compiler.h>
9561 +#include <linux/binfmts.h>
9563 #include <asm/system.h>
9564 #include <asm/desc.h>
9566 #include <asm/tlbflush.h>
9567 #include <asm/proto.h>
9568 #include <asm-generic/sections.h>
9569 +#include <asm/tlbflush.h>
9572 * Page fault error code bits
9573 @@ -55,11 +59,7 @@ static inline int notify_page_fault(stru
9576 /* kprobe_running() needs smp_processor_id() */
9577 -#ifdef CONFIG_X86_32
9578 - if (!user_mode_vm(regs)) {
9580 if (!user_mode(regs)) {
9583 if (kprobe_running() && kprobe_fault_handler(regs, 14))
9585 @@ -257,6 +257,30 @@ bad:
9589 +#ifdef CONFIG_PAX_EMUTRAMP
9590 +static int pax_handle_fetch_fault(struct pt_regs *regs);
9593 +#ifdef CONFIG_PAX_PAGEEXEC
9594 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
9600 + pgd = pgd_offset(mm, address);
9601 + if (!pgd_present(*pgd))
9603 + pud = pud_offset(pgd, address);
9604 + if (!pud_present(*pud))
9606 + pmd = pmd_offset(pud, address);
9607 + if (!pmd_present(*pmd))
9613 #ifdef CONFIG_X86_32
9614 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
9616 @@ -343,7 +367,7 @@ static int is_errata93(struct pt_regs *r
9617 static int is_errata100(struct pt_regs *regs, unsigned long address)
9619 #ifdef CONFIG_X86_64
9620 - if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
9621 + if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
9625 @@ -380,17 +404,32 @@ static void show_fault_oops(struct pt_re
9628 #ifdef CONFIG_X86_PAE
9629 - if (error_code & PF_INSTR) {
9630 + if (nx_enabled && (error_code & PF_INSTR)) {
9632 pte_t *pte = lookup_address(address, &level);
9634 if (pte && pte_present(*pte) && !pte_exec(*pte))
9635 printk(KERN_CRIT "kernel tried to execute "
9636 "NX-protected page - exploit attempt? "
9637 - "(uid: %d)\n", current->uid);
9638 + "(uid: %d, task: %s, pid: %d)\n",
9639 + current->uid, current->comm, task_pid_nr(current));
9643 +#ifdef CONFIG_PAX_KERNEXEC
9644 +#ifdef CONFIG_MODULES
9645 + if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
9647 + if (init_mm.start_code <= address && address < init_mm.end_code)
9649 + if (current->signal->curr_ip)
9650 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9651 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
9653 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9654 + current->comm, task_pid_nr(current), current->uid, current->euid);
9657 printk(KERN_ALERT "BUG: unable to handle kernel ");
9658 if (address < PAGE_SIZE)
9659 printk(KERN_CONT "NULL pointer dereference");
9660 @@ -578,13 +617,22 @@ void __kprobes do_page_fault(struct pt_r
9661 struct task_struct *tsk;
9662 struct mm_struct *mm;
9663 struct vm_area_struct *vma;
9664 - unsigned long address;
9667 #ifdef CONFIG_X86_64
9668 unsigned long flags;
9671 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9675 + unsigned char pte_mask;
9678 + /* get the address */
9679 + const unsigned long address = read_cr2();
9682 * We can fault from pretty much anywhere, with unknown IRQ state.
9684 @@ -594,9 +642,6 @@ void __kprobes do_page_fault(struct pt_r
9686 prefetchw(&mm->mmap_sem);
9688 - /* get the address */
9689 - address = read_cr2();
9691 si_code = SEGV_MAPERR;
9693 if (notify_page_fault(regs))
9694 @@ -647,7 +692,7 @@ void __kprobes do_page_fault(struct pt_r
9695 * atomic region then we must not take the fault.
9697 if (in_atomic() || !mm)
9698 - goto bad_area_nosemaphore;
9699 + goto bad_area_nopax;
9700 #else /* CONFIG_X86_64 */
9701 if (likely(regs->flags & X86_EFLAGS_IF))
9703 @@ -660,13 +705,13 @@ void __kprobes do_page_fault(struct pt_r
9704 * atomic region then we must not take the fault.
9706 if (unlikely(in_atomic() || !mm))
9707 - goto bad_area_nosemaphore;
9708 + goto bad_area_nopax;
9711 * User-mode registers count as a user access even for any
9712 * potential system fault or CPU buglet.
9714 - if (user_mode_vm(regs))
9715 + if (user_mode(regs))
9716 error_code |= PF_USER;
9719 @@ -688,10 +733,104 @@ again:
9720 if (!down_read_trylock(&mm->mmap_sem)) {
9721 if ((error_code & PF_USER) == 0 &&
9722 !search_exception_tables(regs->ip))
9723 - goto bad_area_nosemaphore;
9724 + goto bad_area_nopax;
9725 down_read(&mm->mmap_sem);
9728 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9729 + if (nx_enabled || (error_code & 5) != 5 || (regs->flags & X86_EFLAGS_VM) ||
9730 + !(mm->pax_flags & MF_PAX_PAGEEXEC))
9731 + goto not_pax_fault;
9733 + /* PaX: it's our fault, let's handle it if we can */
9735 + /* PaX: take a look at read faults before acquiring any locks */
9736 + if (unlikely(!(error_code & 2) && (regs->ip == address))) {
9737 + /* instruction fetch attempt from a protected page in user mode */
9738 + up_read(&mm->mmap_sem);
9740 +#ifdef CONFIG_PAX_EMUTRAMP
9741 + switch (pax_handle_fetch_fault(regs)) {
9747 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
9748 + do_group_exit(SIGKILL);
9751 + pmd = pax_get_pmd(mm, address);
9752 + if (unlikely(!pmd))
9753 + goto not_pax_fault;
9755 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
9756 + if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
9757 + pte_unmap_unlock(pte, ptl);
9758 + goto not_pax_fault;
9761 + if (unlikely((error_code & 2) && !pte_write(*pte))) {
9762 + /* write attempt to a protected page in user mode */
9763 + pte_unmap_unlock(pte, ptl);
9764 + goto not_pax_fault;
9768 + if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
9770 + if (likely(address > get_limit(regs->cs)))
9773 + set_pte(pte, pte_mkread(*pte));
9774 + __flush_tlb_one(address);
9775 + pte_unmap_unlock(pte, ptl);
9776 + up_read(&mm->mmap_sem);
9780 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
9783 + * PaX: fill DTLB with user rights and retry
9785 + __asm__ __volatile__ (
9786 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9790 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
9792 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
9793 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
9794 + * page fault when examined during a TLB load attempt. this is true not only
9795 + * for PTEs holding a non-present entry but also present entries that will
9796 + * raise a page fault (such as those set up by PaX, or the copy-on-write
9797 + * mechanism). in effect it means that we do *not* need to flush the TLBs
9798 + * for our target pages since their PTEs are simply not in the TLBs at all.
9800 + * the best thing in omitting it is that we gain around 15-20% speed in the
9801 + * fast path of the page fault handler and can get rid of tracing since we
9802 + * can no longer flush unintended entries.
9806 + "testb $0,%%es:(%0)\n"
9808 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9813 + : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
9814 + : "memory", "cc");
9815 + pte_unmap_unlock(pte, ptl);
9816 + up_read(&mm->mmap_sem);
9822 vma = find_vma(mm, address);
9825 @@ -709,6 +848,12 @@ again:
9826 if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
9830 +#ifdef CONFIG_PAX_SEGMEXEC
9831 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
9835 if (expand_stack(vma, address))
9838 @@ -718,6 +863,8 @@ again:
9840 si_code = SEGV_ACCERR;
9842 + if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
9844 switch (error_code & (PF_PROT|PF_WRITE)) {
9845 default: /* 3: write, present */
9847 @@ -775,6 +922,49 @@ bad_area:
9848 up_read(&mm->mmap_sem);
9850 bad_area_nosemaphore:
9852 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
9853 + if (mm && (error_code & 4) && !(regs->flags & X86_EFLAGS_VM)) {
9855 + * It's possible to have interrupts off here.
9857 + local_irq_enable();
9859 +#ifdef CONFIG_PAX_PAGEEXEC
9860 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
9861 + ((nx_enabled && ((error_code & PF_INSTR) || !(error_code & (PF_PROT | PF_WRITE))) && (regs->ip == address)))) {
9863 +#ifdef CONFIG_PAX_EMUTRAMP
9864 + switch (pax_handle_fetch_fault(regs)) {
9870 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
9871 + do_group_exit(SIGKILL);
9875 +#ifdef CONFIG_PAX_SEGMEXEC
9876 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
9878 +#ifdef CONFIG_PAX_EMUTRAMP
9879 + switch (pax_handle_fetch_fault(regs)) {
9885 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
9886 + do_group_exit(SIGKILL);
9894 /* User mode accesses just cause a SIGSEGV */
9895 if (error_code & PF_USER) {
9897 @@ -857,7 +1047,7 @@ no_context:
9898 #ifdef CONFIG_X86_32
9899 die("Oops", regs, error_code);
9902 + do_group_exit(SIGKILL);
9904 if (__die("Oops", regs, error_code))
9906 @@ -871,17 +1061,17 @@ no_context:
9907 * us unable to handle the page fault gracefully.
9910 - up_read(&mm->mmap_sem);
9911 if (is_global_init(tsk)) {
9913 #ifdef CONFIG_X86_32
9914 - down_read(&mm->mmap_sem);
9917 + up_read(&mm->mmap_sem);
9922 + up_read(&mm->mmap_sem);
9923 printk("VM: killing process %s\n", tsk->comm);
9924 if (error_code & PF_USER)
9925 do_group_exit(SIGKILL);
9926 @@ -982,3 +1172,174 @@ void vmalloc_sync_all(void)
9927 (__START_KERNEL & PGDIR_MASK)));
9931 +#ifdef CONFIG_PAX_EMUTRAMP
9932 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
9936 + do { /* PaX: gcc trampoline emulation #1 */
9937 + unsigned char mov1, mov2;
9938 + unsigned short jmp;
9939 + unsigned int addr1, addr2;
9941 +#ifdef CONFIG_X86_64
9942 + if ((regs->ip + 11) >> 32)
9946 + err = get_user(mov1, (unsigned char __user *)regs->ip);
9947 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
9948 + err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
9949 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
9950 + err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
9955 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
9963 + do { /* PaX: gcc trampoline emulation #2 */
9964 + unsigned char mov, jmp;
9965 + unsigned int addr1, addr2;
9967 +#ifdef CONFIG_X86_64
9968 + if ((regs->ip + 9) >> 32)
9972 + err = get_user(mov, (unsigned char __user *)regs->ip);
9973 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
9974 + err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
9975 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
9980 + if (mov == 0xB9 && jmp == 0xE9) {
9982 + regs->ip = (unsigned int)(regs->ip + addr2 + 10);
9987 + return 1; /* PaX in action */
9990 +#ifdef CONFIG_X86_64
9991 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
9995 + do { /* PaX: gcc trampoline emulation #1 */
9996 + unsigned short mov1, mov2, jmp1;
9997 + unsigned char jmp2;
9998 + unsigned int addr1;
9999 + unsigned long addr2;
10001 + err = get_user(mov1, (unsigned short __user *)regs->ip);
10002 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
10003 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
10004 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
10005 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
10006 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
10011 + if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10012 + regs->r11 = addr1;
10013 + regs->r10 = addr2;
10014 + regs->ip = addr1;
10019 + do { /* PaX: gcc trampoline emulation #2 */
10020 + unsigned short mov1, mov2, jmp1;
10021 + unsigned char jmp2;
10022 + unsigned long addr1, addr2;
10024 + err = get_user(mov1, (unsigned short __user *)regs->ip);
10025 + err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
10026 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
10027 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
10028 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
10029 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
10034 + if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10035 + regs->r11 = addr1;
10036 + regs->r10 = addr2;
10037 + regs->ip = addr1;
10042 + return 1; /* PaX in action */
10047 + * PaX: decide what to do with offenders (regs->ip = fault address)
10049 + * returns 1 when task should be killed
10050 + * 2 when gcc trampoline was detected
10052 +static int pax_handle_fetch_fault(struct pt_regs *regs)
10054 + if (regs->flags & X86_EFLAGS_VM)
10057 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10060 +#ifdef CONFIG_X86_32
10061 + return pax_handle_fetch_fault_32(regs);
10063 + if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
10064 + return pax_handle_fetch_fault_32(regs);
10066 + return pax_handle_fetch_fault_64(regs);
10071 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10072 +void pax_report_insns(void *pc, void *sp)
10076 + printk(KERN_ERR "PAX: bytes at PC: ");
10077 + for (i = 0; i < 20; i++) {
10079 + if (get_user(c, (unsigned char __user *)pc+i))
10080 + printk(KERN_CONT "?? ");
10082 + printk(KERN_CONT "%02x ", c);
10086 + printk(KERN_ERR "PAX: bytes at SP-%u: ", sizeof(long));
10087 + for (i = -1; i < 80 / sizeof(long); i++) {
10089 + if (get_user(c, (unsigned long __user *)sp+i))
10090 +#ifdef CONFIG_X86_32
10091 + printk(KERN_CONT "???????? ");
10093 + printk(KERN_CONT "???????????????? ");
10096 + printk(KERN_CONT "%0*lx ", 2 * sizeof(long), c);
10101 diff -urNp linux-2.6.25.10/arch/x86/mm/highmem_32.c linux-2.6.25.10/arch/x86/mm/highmem_32.c
10102 --- linux-2.6.25.10/arch/x86/mm/highmem_32.c 2008-07-02 23:46:47.000000000 -0400
10103 +++ linux-2.6.25.10/arch/x86/mm/highmem_32.c 2008-07-03 16:53:25.000000000 -0400
10104 @@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
10105 enum fixed_addresses idx;
10106 unsigned long vaddr;
10108 +#ifdef CONFIG_PAX_KERNEXEC
10109 + unsigned long cr0;
10112 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
10113 pagefault_disable();
10115 @@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
10116 idx = type + KM_TYPE_NR*smp_processor_id();
10117 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10118 BUG_ON(!pte_none(*(kmap_pte-idx)));
10120 +#ifdef CONFIG_PAX_KERNEXEC
10121 + pax_open_kernel(cr0);
10124 set_pte(kmap_pte-idx, mk_pte(page, prot));
10126 +#ifdef CONFIG_PAX_KERNEXEC
10127 + pax_close_kernel(cr0);
10130 arch_flush_lazy_mmu_mode();
10132 return (void *)vaddr;
10133 @@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
10134 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
10135 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
10137 +#ifdef CONFIG_PAX_KERNEXEC
10138 + unsigned long cr0;
10142 * Force other mappings to Oops if they'll try to access this pte
10143 * without first remap it. Keeping stale mappings around is a bad idea
10144 * also, in case the page changes cacheability attributes or becomes
10145 * a protected page in a hypervisor.
10147 - if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
10148 + if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
10150 +#ifdef CONFIG_PAX_KERNEXEC
10151 + pax_open_kernel(cr0);
10154 kpte_clear_flush(kmap_pte-idx, vaddr);
10157 +#ifdef CONFIG_PAX_KERNEXEC
10158 + pax_close_kernel(cr0);
10162 #ifdef CONFIG_DEBUG_HIGHMEM
10163 BUG_ON(vaddr < PAGE_OFFSET);
10164 BUG_ON(vaddr >= (unsigned long)high_memory);
10165 @@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
10166 enum fixed_addresses idx;
10167 unsigned long vaddr;
10169 +#ifdef CONFIG_PAX_KERNEXEC
10170 + unsigned long cr0;
10173 pagefault_disable();
10175 idx = type + KM_TYPE_NR*smp_processor_id();
10176 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10178 +#ifdef CONFIG_PAX_KERNEXEC
10179 + pax_open_kernel(cr0);
10182 set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
10184 +#ifdef CONFIG_PAX_KERNEXEC
10185 + pax_close_kernel(cr0);
10188 arch_flush_lazy_mmu_mode();
10190 return (void*) vaddr;
10191 diff -urNp linux-2.6.25.10/arch/x86/mm/hugetlbpage.c linux-2.6.25.10/arch/x86/mm/hugetlbpage.c
10192 --- linux-2.6.25.10/arch/x86/mm/hugetlbpage.c 2008-07-02 23:46:47.000000000 -0400
10193 +++ linux-2.6.25.10/arch/x86/mm/hugetlbpage.c 2008-07-03 16:53:25.000000000 -0400
10194 @@ -230,13 +230,18 @@ static unsigned long hugetlb_get_unmappe
10196 struct mm_struct *mm = current->mm;
10197 struct vm_area_struct *vma;
10198 - unsigned long start_addr;
10199 + unsigned long start_addr, pax_task_size = TASK_SIZE;
10201 +#ifdef CONFIG_PAX_SEGMEXEC
10202 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10203 + pax_task_size = SEGMEXEC_TASK_SIZE;
10206 if (len > mm->cached_hole_size) {
10207 - start_addr = mm->free_area_cache;
10208 + start_addr = mm->free_area_cache;
10210 - start_addr = TASK_UNMAPPED_BASE;
10211 - mm->cached_hole_size = 0;
10212 + start_addr = mm->mmap_base;
10213 + mm->cached_hole_size = 0;
10217 @@ -244,13 +249,13 @@ full_search:
10219 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
10220 /* At this point: (!vma || addr < vma->vm_end). */
10221 - if (TASK_SIZE - len < addr) {
10222 + if (pax_task_size - len < addr) {
10224 * Start a new search - just in case we missed
10227 - if (start_addr != TASK_UNMAPPED_BASE) {
10228 - start_addr = TASK_UNMAPPED_BASE;
10229 + if (start_addr != mm->mmap_base) {
10230 + start_addr = mm->mmap_base;
10231 mm->cached_hole_size = 0;
10234 @@ -272,9 +277,8 @@ static unsigned long hugetlb_get_unmappe
10236 struct mm_struct *mm = current->mm;
10237 struct vm_area_struct *vma, *prev_vma;
10238 - unsigned long base = mm->mmap_base, addr = addr0;
10239 + unsigned long base = mm->mmap_base, addr;
10240 unsigned long largest_hole = mm->cached_hole_size;
10241 - int first_time = 1;
10243 /* don't allow allocations above current base */
10244 if (mm->free_area_cache > base)
10245 @@ -284,7 +288,7 @@ static unsigned long hugetlb_get_unmappe
10247 mm->free_area_cache = base;
10251 /* make sure it can fit in the remaining address space */
10252 if (mm->free_area_cache < len)
10254 @@ -326,22 +330,26 @@ try_again:
10258 - * if hint left us with no space for the requested
10259 - * mapping then try again:
10261 - if (first_time) {
10262 - mm->free_area_cache = base;
10263 - largest_hole = 0;
10268 * A failed mmap() very likely causes application failure,
10269 * so fall back to the bottom-up function here. This scenario
10270 * can happen with large stack limits and large mmap()
10273 - mm->free_area_cache = TASK_UNMAPPED_BASE;
10275 +#ifdef CONFIG_PAX_SEGMEXEC
10276 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10277 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
10281 + mm->mmap_base = TASK_UNMAPPED_BASE;
10283 +#ifdef CONFIG_PAX_RANDMMAP
10284 + if (mm->pax_flags & MF_PAX_RANDMMAP)
10285 + mm->mmap_base += mm->delta_mmap;
10288 + mm->free_area_cache = mm->mmap_base;
10289 mm->cached_hole_size = ~0UL;
10290 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
10291 len, pgoff, flags);
10292 @@ -349,6 +357,7 @@ fail:
10294 * Restore the topdown base:
10296 + mm->mmap_base = base;
10297 mm->free_area_cache = base;
10298 mm->cached_hole_size = ~0UL;
10300 @@ -361,10 +370,17 @@ hugetlb_get_unmapped_area(struct file *f
10302 struct mm_struct *mm = current->mm;
10303 struct vm_area_struct *vma;
10304 + unsigned long pax_task_size = TASK_SIZE;
10306 if (len & ~HPAGE_MASK)
10308 - if (len > TASK_SIZE)
10310 +#ifdef CONFIG_PAX_SEGMEXEC
10311 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10312 + pax_task_size = SEGMEXEC_TASK_SIZE;
10315 + if (len > pax_task_size)
10318 if (flags & MAP_FIXED) {
10319 @@ -376,7 +392,7 @@ hugetlb_get_unmapped_area(struct file *f
10321 addr = ALIGN(addr, HPAGE_SIZE);
10322 vma = find_vma(mm, addr);
10323 - if (TASK_SIZE - len >= addr &&
10324 + if (pax_task_size - len >= addr &&
10325 (!vma || addr + len <= vma->vm_start))
10328 diff -urNp linux-2.6.25.10/arch/x86/mm/init_32.c linux-2.6.25.10/arch/x86/mm/init_32.c
10329 --- linux-2.6.25.10/arch/x86/mm/init_32.c 2008-07-02 23:46:47.000000000 -0400
10330 +++ linux-2.6.25.10/arch/x86/mm/init_32.c 2008-07-03 16:53:25.000000000 -0400
10332 #include <asm/paravirt.h>
10333 #include <asm/setup.h>
10334 #include <asm/cacheflush.h>
10335 +#include <asm/desc.h>
10337 unsigned int __VMALLOC_RESERVE = 128 << 20;
10339 @@ -57,32 +58,6 @@ unsigned long highstart_pfn, highend_pfn
10340 static noinline int do_test_wp_bit(void);
10343 - * Creates a middle page table and puts a pointer to it in the
10344 - * given global directory entry. This only returns the gd entry
10345 - * in non-PAE compilation mode, since the middle layer is folded.
10347 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
10350 - pmd_t *pmd_table;
10352 -#ifdef CONFIG_X86_PAE
10353 - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
10354 - pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
10356 - paravirt_alloc_pd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
10357 - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
10358 - pud = pud_offset(pgd, 0);
10359 - BUG_ON(pmd_table != pmd_offset(pud, 0));
10362 - pud = pud_offset(pgd, 0);
10363 - pmd_table = pmd_offset(pud, 0);
10365 - return pmd_table;
10369 * Create a page table and place a pointer to it in a middle page
10372 @@ -100,7 +75,11 @@ static pte_t * __init one_page_table_ini
10375 paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
10376 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10377 + set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
10379 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
10381 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
10384 @@ -122,6 +101,7 @@ page_table_range_init(unsigned long star
10385 int pgd_idx, pmd_idx;
10386 unsigned long vaddr;
10392 @@ -130,8 +110,13 @@ page_table_range_init(unsigned long star
10393 pgd = pgd_base + pgd_idx;
10395 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
10396 - pmd = one_md_table_init(pgd);
10397 - pmd = pmd + pmd_index(vaddr);
10398 + pud = pud_offset(pgd, vaddr);
10399 + pmd = pmd_offset(pud, vaddr);
10401 +#ifdef CONFIG_X86_PAE
10402 + paravirt_alloc_pd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10405 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
10406 pmd++, pmd_idx++) {
10407 one_page_table_init(pmd);
10408 @@ -142,11 +127,23 @@ page_table_range_init(unsigned long star
10412 -static inline int is_kernel_text(unsigned long addr)
10413 +static inline int is_kernel_text(unsigned long start, unsigned long end)
10415 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
10418 + unsigned long etext;
10420 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
10421 + etext = ktva_ktla((unsigned long)&MODULES_END);
10423 + etext = (unsigned long)&_etext;
10426 + if ((start > ktla_ktva(etext) ||
10427 + end <= ktla_ktva((unsigned long)_stext)) &&
10428 + (start > ktla_ktva((unsigned long)_einittext) ||
10429 + end <= ktla_ktva((unsigned long)_sinittext)) &&
10430 + (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
10436 @@ -156,9 +153,10 @@ static inline int is_kernel_text(unsigne
10438 static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
10440 - int pgd_idx, pmd_idx, pte_ofs;
10441 + unsigned int pgd_idx, pmd_idx, pte_ofs;
10448 @@ -166,29 +164,27 @@ static void __init kernel_physical_mappi
10449 pgd = pgd_base + pgd_idx;
10452 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
10453 - pmd = one_md_table_init(pgd);
10454 - if (pfn >= max_low_pfn)
10456 + for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
10457 + pud = pud_offset(pgd, 0);
10458 + pmd = pmd_offset(pud, 0);
10460 +#ifdef CONFIG_X86_PAE
10461 + paravirt_alloc_pd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10465 pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn;
10466 pmd++, pmd_idx++) {
10467 - unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
10468 + unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
10471 * Map with big pages if possible, otherwise
10472 * create normal page tables:
10474 - if (cpu_has_pse) {
10475 - unsigned int addr2;
10476 + if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
10477 pgprot_t prot = PAGE_KERNEL_LARGE;
10479 - addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
10480 - PAGE_OFFSET + PAGE_SIZE-1;
10482 - if (is_kernel_text(addr) ||
10483 - is_kernel_text(addr2))
10484 + if (is_kernel_text(address, address + PMD_SIZE))
10485 prot = PAGE_KERNEL_LARGE_EXEC;
10487 set_pmd(pmd, pfn_pmd(pfn, prot));
10488 @@ -200,10 +196,10 @@ static void __init kernel_physical_mappi
10491 pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
10492 - pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
10493 + pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
10494 pgprot_t prot = PAGE_KERNEL;
10496 - if (is_kernel_text(addr))
10497 + if (is_kernel_text(address, address + PAGE_SIZE))
10498 prot = PAGE_KERNEL_EXEC;
10500 set_pte(pte, pfn_pte(pfn, prot));
10501 @@ -323,10 +319,10 @@ static void __init set_highmem_pages_ini
10502 # define set_highmem_pages_init(bad_ppro) do { } while (0)
10503 #endif /* CONFIG_HIGHMEM */
10505 -pteval_t __PAGE_KERNEL = _PAGE_KERNEL;
10506 +pteval_t __PAGE_KERNEL __read_only = _PAGE_KERNEL;
10507 EXPORT_SYMBOL(__PAGE_KERNEL);
10509 -pteval_t __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
10510 +pteval_t __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
10512 void __init native_pagetable_setup_start(pgd_t *base)
10514 @@ -348,7 +344,7 @@ void __init native_pagetable_setup_start
10516 pud = pud_offset(pgd, va);
10517 pmd = pmd_offset(pud, va);
10518 - if (!pmd_present(*pmd))
10519 + if (!pmd_present(*pmd) || pmd_huge(*pmd))
10522 pte = pte_offset_kernel(pmd, va);
10523 @@ -424,12 +420,12 @@ static void __init pagetable_init(void)
10524 * ACPI suspend needs this for resume, because things like the intel-agp
10525 * driver might have split up a kernel 4MB mapping.
10527 -char swsusp_pg_dir[PAGE_SIZE]
10528 +pgd_t swsusp_pg_dir[PTRS_PER_PGD]
10529 __attribute__ ((aligned(PAGE_SIZE)));
10531 static inline void save_pg_dir(void)
10533 - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
10534 + clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
10536 #else /* !CONFIG_ACPI_SLEEP */
10537 static inline void save_pg_dir(void)
10538 @@ -461,13 +457,11 @@ void zap_low_mappings(void)
10542 -pteval_t __supported_pte_mask __read_mostly = ~_PAGE_NX;
10543 +pteval_t __supported_pte_mask __read_only = ~_PAGE_NX;
10544 EXPORT_SYMBOL_GPL(__supported_pte_mask);
10546 #ifdef CONFIG_X86_PAE
10548 -static int disable_nx __initdata;
10553 @@ -476,40 +470,33 @@ static int disable_nx __initdata;
10557 +#if !defined(CONFIG_PAX_PAGEEXEC)
10558 static int __init noexec_setup(char *str)
10560 if (!str || !strcmp(str, "on")) {
10561 - if (cpu_has_nx) {
10562 - __supported_pte_mask |= _PAGE_NX;
10568 - if (!strcmp(str, "off")) {
10570 - __supported_pte_mask &= ~_PAGE_NX;
10572 + if (!strcmp(str, "off"))
10581 early_param("noexec", noexec_setup);
10584 static void __init set_nx(void)
10586 - unsigned int v[4], l, h;
10588 - if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
10589 - cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
10590 + if (!nx_enabled && cpu_has_nx) {
10593 - if ((v[3] & (1 << 20)) && !disable_nx) {
10594 - rdmsr(MSR_EFER, l, h);
10596 - wrmsr(MSR_EFER, l, h);
10598 - __supported_pte_mask |= _PAGE_NX;
10600 + __supported_pte_mask &= ~_PAGE_NX;
10601 + rdmsr(MSR_EFER, l, h);
10603 + wrmsr(MSR_EFER, l, h);
10607 @@ -601,7 +588,7 @@ void __init mem_init(void)
10608 set_highmem_pages_init(bad_ppro);
10610 codesize = (unsigned long) &_etext - (unsigned long) &_text;
10611 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
10612 + datasize = (unsigned long) &_edata - (unsigned long) &_data;
10613 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
10615 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
10616 @@ -648,10 +635,10 @@ void __init mem_init(void)
10617 ((unsigned long)&__init_end -
10618 (unsigned long)&__init_begin) >> 10,
10620 - (unsigned long)&_etext, (unsigned long)&_edata,
10621 - ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
10622 + (unsigned long)&_data, (unsigned long)&_edata,
10623 + ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
10625 - (unsigned long)&_text, (unsigned long)&_etext,
10626 + ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
10627 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
10629 #ifdef CONFIG_HIGHMEM
10630 @@ -794,6 +781,46 @@ void free_init_pages(char *what, unsigne
10632 void free_initmem(void)
10635 +#ifdef CONFIG_PAX_KERNEXEC
10636 + /* PaX: limit KERNEL_CS to actual size */
10637 + unsigned long addr, limit;
10638 + struct desc_struct d;
10644 +#ifdef CONFIG_MODULES
10645 + limit = ktva_ktla((unsigned long)&MODULES_END);
10647 + limit = (unsigned long)&_etext;
10649 + limit = (limit - 1UL) >> PAGE_SHIFT;
10651 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
10652 + pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
10653 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
10656 + /* PaX: make KERNEL_CS read-only */
10657 + for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
10658 + pgd = pgd_offset_k(addr);
10659 + pud = pud_offset(pgd, addr);
10660 + pmd = pmd_offset(pud, addr);
10661 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10663 +#ifdef CONFIG_X86_PAE
10664 + for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
10665 + pgd = pgd_offset_k(addr);
10666 + pud = pud_offset(pgd, addr);
10667 + pmd = pmd_offset(pud, addr);
10668 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10674 free_init_pages("unused kernel memory",
10675 (unsigned long)(&__init_begin),
10676 (unsigned long)(&__init_end));
10677 diff -urNp linux-2.6.25.10/arch/x86/mm/init_64.c linux-2.6.25.10/arch/x86/mm/init_64.c
10678 --- linux-2.6.25.10/arch/x86/mm/init_64.c 2008-07-02 23:46:47.000000000 -0400
10679 +++ linux-2.6.25.10/arch/x86/mm/init_64.c 2008-07-03 16:53:25.000000000 -0400
10680 @@ -129,6 +129,10 @@ set_pte_phys(unsigned long vaddr, unsign
10682 pte_t *pte, new_pte;
10684 +#ifdef CONFIG_PAX_KERNEXEC
10685 + unsigned long cr0;
10688 pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys);
10690 pgd = pgd_offset_k(vaddr);
10691 @@ -140,7 +144,7 @@ set_pte_phys(unsigned long vaddr, unsign
10692 pud = pud_offset(pgd, vaddr);
10693 if (pud_none(*pud)) {
10694 pmd = (pmd_t *) spp_getpage();
10695 - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
10696 + set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
10697 if (pmd != pmd_offset(pud, 0)) {
10698 printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
10699 pmd, pmd_offset(pud, 0));
10700 @@ -150,7 +154,7 @@ set_pte_phys(unsigned long vaddr, unsign
10701 pmd = pmd_offset(pud, vaddr);
10702 if (pmd_none(*pmd)) {
10703 pte = (pte_t *) spp_getpage();
10704 - set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
10705 + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
10706 if (pte != pte_offset_kernel(pmd, 0)) {
10707 printk(KERN_ERR "PAGETABLE BUG #02!\n");
10709 @@ -162,8 +166,17 @@ set_pte_phys(unsigned long vaddr, unsign
10710 if (!pte_none(*pte) &&
10711 pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
10714 +#ifdef CONFIG_PAX_KERNEXEC
10715 + pax_open_kernel(cr0);
10718 set_pte(pte, new_pte);
10720 +#ifdef CONFIG_PAX_KERNEXEC
10721 + pax_close_kernel(cr0);
10725 * It's enough to flush this one mapping.
10726 * (PGE mappings get flushed as well)
10727 @@ -585,6 +598,39 @@ void free_init_pages(char *what, unsigne
10729 void free_initmem(void)
10732 +#ifdef CONFIG_PAX_KERNEXEC
10733 + unsigned long addr, end;
10738 + /* PaX: make kernel code/rodata read-only, rest non-executable */
10739 + for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
10740 + pgd = pgd_offset_k(addr);
10741 + pud = pud_offset(pgd, addr);
10742 + pmd = pmd_offset(pud, addr);
10743 + if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
10744 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10746 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10749 + addr = (unsigned long)__va(__pa(__START_KERNEL_map));
10750 + end = addr + KERNEL_IMAGE_SIZE;
10751 + for (; addr < end; addr += PMD_SIZE) {
10752 + pgd = pgd_offset_k(addr);
10753 + pud = pud_offset(pgd, addr);
10754 + pmd = pmd_offset(pud, addr);
10755 + if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
10756 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10758 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10764 free_init_pages("unused kernel memory",
10765 (unsigned long)(&__init_begin),
10766 (unsigned long)(&__init_end));
10767 @@ -753,7 +799,7 @@ int in_gate_area_no_task(unsigned long a
10769 const char *arch_vma_name(struct vm_area_struct *vma)
10771 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
10772 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
10774 if (vma == &gate_vma)
10775 return "[vsyscall]";
10776 diff -urNp linux-2.6.25.10/arch/x86/mm/ioremap.c linux-2.6.25.10/arch/x86/mm/ioremap.c
10777 --- linux-2.6.25.10/arch/x86/mm/ioremap.c 2008-07-02 23:46:47.000000000 -0400
10778 +++ linux-2.6.25.10/arch/x86/mm/ioremap.c 2008-07-03 16:53:25.000000000 -0400
10779 @@ -148,6 +148,8 @@ static void __iomem *__ioremap(resource_
10783 + prot = canon_pgprot(prot);
10786 * Mappings have to be page-aligned
10788 diff -urNp linux-2.6.25.10/arch/x86/mm/mmap.c linux-2.6.25.10/arch/x86/mm/mmap.c
10789 --- linux-2.6.25.10/arch/x86/mm/mmap.c 2008-07-02 23:46:47.000000000 -0400
10790 +++ linux-2.6.25.10/arch/x86/mm/mmap.c 2008-07-03 16:53:25.000000000 -0400
10792 * Leave an at least ~128 MB hole.
10794 #define MIN_GAP (128*1024*1024)
10795 -#define MAX_GAP (TASK_SIZE/6*5)
10796 +#define MAX_GAP (pax_task_size/6*5)
10799 * True on X86_32 or when emulating IA32 on X86_64
10800 @@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
10801 return rnd << PAGE_SHIFT;
10804 -static unsigned long mmap_base(void)
10805 +static unsigned long mmap_base(struct mm_struct *mm)
10807 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
10808 + unsigned long pax_task_size = TASK_SIZE;
10810 +#ifdef CONFIG_PAX_SEGMEXEC
10811 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10812 + pax_task_size = SEGMEXEC_TASK_SIZE;
10817 else if (gap > MAX_GAP)
10820 - return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
10821 + return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
10825 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
10826 * does, but not when emulating X86_32
10828 -static unsigned long mmap_legacy_base(void)
10829 +static unsigned long mmap_legacy_base(struct mm_struct *mm)
10831 - if (mmap_is_ia32())
10832 + if (mmap_is_ia32()) {
10834 +#ifdef CONFIG_PAX_SEGMEXEC
10835 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10836 + return SEGMEXEC_TASK_UNMAPPED_BASE;
10840 return TASK_UNMAPPED_BASE;
10843 return TASK_UNMAPPED_BASE + mmap_rnd();
10846 @@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
10847 void arch_pick_mmap_layout(struct mm_struct *mm)
10849 if (mmap_is_legacy()) {
10850 - mm->mmap_base = mmap_legacy_base();
10851 + mm->mmap_base = mmap_legacy_base(mm);
10853 +#ifdef CONFIG_PAX_RANDMMAP
10854 + if (mm->pax_flags & MF_PAX_RANDMMAP)
10855 + mm->mmap_base += mm->delta_mmap;
10858 mm->get_unmapped_area = arch_get_unmapped_area;
10859 mm->unmap_area = arch_unmap_area;
10861 - mm->mmap_base = mmap_base();
10862 + mm->mmap_base = mmap_base(mm);
10864 +#ifdef CONFIG_PAX_RANDMMAP
10865 + if (mm->pax_flags & MF_PAX_RANDMMAP)
10866 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
10869 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
10870 mm->unmap_area = arch_unmap_area_topdown;
10872 diff -urNp linux-2.6.25.10/arch/x86/mm/numa_64.c linux-2.6.25.10/arch/x86/mm/numa_64.c
10873 --- linux-2.6.25.10/arch/x86/mm/numa_64.c 2008-07-02 23:46:47.000000000 -0400
10874 +++ linux-2.6.25.10/arch/x86/mm/numa_64.c 2008-07-03 16:53:25.000000000 -0400
10876 #include <asm/k8.h>
10879 -#define Dprintk(x...)
10880 +#define Dprintk(x...) do {} while (0)
10883 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
10884 diff -urNp linux-2.6.25.10/arch/x86/mm/pageattr.c linux-2.6.25.10/arch/x86/mm/pageattr.c
10885 --- linux-2.6.25.10/arch/x86/mm/pageattr.c 2008-07-02 23:46:47.000000000 -0400
10886 +++ linux-2.6.25.10/arch/x86/mm/pageattr.c 2008-07-03 16:53:25.000000000 -0400
10888 #include <asm/uaccess.h>
10889 #include <asm/pgalloc.h>
10890 #include <asm/proto.h>
10891 +#include <asm/desc.h>
10894 * The current flushing context - we pass it instead of 5 arguments:
10895 @@ -168,7 +169,7 @@ static inline pgprot_t static_protection
10896 * Does not cover __inittext since that is gone later on. On
10897 * 64bit we do not enforce !NX on the low mapping
10899 - if (within(address, (unsigned long)_text, (unsigned long)_etext))
10900 + if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
10901 pgprot_val(forbidden) |= _PAGE_NX;
10904 @@ -229,8 +230,20 @@ pte_t *lookup_address(unsigned long addr
10906 static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
10909 +#ifdef CONFIG_PAX_KERNEXEC
10910 + unsigned long cr0;
10912 + pax_open_kernel(cr0);
10915 /* change init_mm */
10916 set_pte_atomic(kpte, pte);
10918 +#ifdef CONFIG_PAX_KERNEXEC
10919 + pax_close_kernel(cr0);
10922 #ifdef CONFIG_X86_32
10923 if (!SHARED_KERNEL_PMD) {
10925 diff -urNp linux-2.6.25.10/arch/x86/mm/pgtable_32.c linux-2.6.25.10/arch/x86/mm/pgtable_32.c
10926 --- linux-2.6.25.10/arch/x86/mm/pgtable_32.c 2008-07-02 23:46:47.000000000 -0400
10927 +++ linux-2.6.25.10/arch/x86/mm/pgtable_32.c 2008-07-03 16:53:25.000000000 -0400
10928 @@ -83,6 +83,10 @@ static void set_pte_pfn(unsigned long va
10932 +#ifdef CONFIG_PAX_KERNEXEC
10933 + unsigned long cr0;
10936 pgd = swapper_pg_dir + pgd_index(vaddr);
10937 if (pgd_none(*pgd)) {
10939 @@ -99,11 +103,20 @@ static void set_pte_pfn(unsigned long va
10942 pte = pte_offset_kernel(pmd, vaddr);
10944 +#ifdef CONFIG_PAX_KERNEXEC
10945 + pax_open_kernel(cr0);
10948 if (pgprot_val(flags))
10949 set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
10951 pte_clear(&init_mm, vaddr, pte);
10953 +#ifdef CONFIG_PAX_KERNEXEC
10954 + pax_close_kernel(cr0);
10958 * It's enough to flush this one mapping.
10959 * (PGE mappings get flushed as well)
10960 diff -urNp linux-2.6.25.10/arch/x86/oprofile/backtrace.c linux-2.6.25.10/arch/x86/oprofile/backtrace.c
10961 --- linux-2.6.25.10/arch/x86/oprofile/backtrace.c 2008-07-02 23:46:47.000000000 -0400
10962 +++ linux-2.6.25.10/arch/x86/oprofile/backtrace.c 2008-07-03 16:53:25.000000000 -0400
10963 @@ -37,7 +37,7 @@ static void backtrace_address(void *data
10964 unsigned int *depth = data;
10967 - oprofile_add_trace(addr);
10968 + oprofile_add_trace(ktla_ktva(addr));
10971 static struct stacktrace_ops backtrace_ops = {
10972 @@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
10973 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
10974 unsigned long stack = kernel_trap_sp(regs);
10976 - if (!user_mode_vm(regs)) {
10977 + if (!user_mode(regs)) {
10979 dump_trace(NULL, regs, (unsigned long *)stack, 0,
10980 &backtrace_ops, &depth);
10981 diff -urNp linux-2.6.25.10/arch/x86/oprofile/op_model_p4.c linux-2.6.25.10/arch/x86/oprofile/op_model_p4.c
10982 --- linux-2.6.25.10/arch/x86/oprofile/op_model_p4.c 2008-07-02 23:46:47.000000000 -0400
10983 +++ linux-2.6.25.10/arch/x86/oprofile/op_model_p4.c 2008-07-03 16:53:25.000000000 -0400
10984 @@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
10988 -static int inline addr_increment(void)
10989 +static inline int addr_increment(void)
10992 return smp_num_siblings == 2 ? 2 : 1;
10993 diff -urNp linux-2.6.25.10/arch/x86/pci/common.c linux-2.6.25.10/arch/x86/pci/common.c
10994 --- linux-2.6.25.10/arch/x86/pci/common.c 2008-07-02 23:46:47.000000000 -0400
10995 +++ linux-2.6.25.10/arch/x86/pci/common.c 2008-07-03 16:53:25.000000000 -0400
10996 @@ -352,7 +352,7 @@ static struct dmi_system_id __devinitdat
10997 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
11001 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
11004 void __init dmi_check_pciprobe(void)
11005 diff -urNp linux-2.6.25.10/arch/x86/pci/early.c linux-2.6.25.10/arch/x86/pci/early.c
11006 --- linux-2.6.25.10/arch/x86/pci/early.c 2008-07-02 23:46:47.000000000 -0400
11007 +++ linux-2.6.25.10/arch/x86/pci/early.c 2008-07-03 16:53:25.000000000 -0400
11009 /* Direct PCI access. This is used for PCI accesses in early boot before
11010 the PCI subsystem works. */
11012 -#define PDprintk(x...)
11013 +#define PDprintk(x...) do {} while (0)
11015 u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
11017 diff -urNp linux-2.6.25.10/arch/x86/pci/fixup.c linux-2.6.25.10/arch/x86/pci/fixup.c
11018 --- linux-2.6.25.10/arch/x86/pci/fixup.c 2008-07-02 23:46:47.000000000 -0400
11019 +++ linux-2.6.25.10/arch/x86/pci/fixup.c 2008-07-03 16:53:25.000000000 -0400
11020 @@ -364,7 +364,7 @@ static struct dmi_system_id __devinitdat
11021 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
11025 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11029 @@ -435,7 +435,7 @@ static struct dmi_system_id __devinitdat
11030 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
11034 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11037 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
11038 diff -urNp linux-2.6.25.10/arch/x86/pci/irq.c linux-2.6.25.10/arch/x86/pci/irq.c
11039 --- linux-2.6.25.10/arch/x86/pci/irq.c 2008-07-02 23:46:47.000000000 -0400
11040 +++ linux-2.6.25.10/arch/x86/pci/irq.c 2008-07-03 16:53:25.000000000 -0400
11041 @@ -540,7 +540,7 @@ static __init int intel_router_probe(str
11042 static struct pci_device_id __initdata pirq_440gx[] = {
11043 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
11044 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
11046 + { PCI_DEVICE(0, 0) }
11049 /* 440GX has a proprietary PIRQ router -- don't use it */
11050 @@ -1106,7 +1106,7 @@ static struct dmi_system_id __initdata p
11051 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
11055 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11058 static int __init pcibios_irq_init(void)
11059 diff -urNp linux-2.6.25.10/arch/x86/pci/pcbios.c linux-2.6.25.10/arch/x86/pci/pcbios.c
11060 --- linux-2.6.25.10/arch/x86/pci/pcbios.c 2008-07-02 23:46:47.000000000 -0400
11061 +++ linux-2.6.25.10/arch/x86/pci/pcbios.c 2008-07-03 16:53:25.000000000 -0400
11062 @@ -57,50 +57,120 @@ union bios32 {
11064 unsigned long address;
11065 unsigned short segment;
11066 -} bios32_indirect = { 0, __KERNEL_CS };
11067 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
11070 * Returns the entry point for the given service, NULL on error
11073 -static unsigned long bios32_service(unsigned long service)
11074 +static unsigned long __devinit bios32_service(unsigned long service)
11076 unsigned char return_code; /* %al */
11077 unsigned long address; /* %ebx */
11078 unsigned long length; /* %ecx */
11079 unsigned long entry; /* %edx */
11080 unsigned long flags;
11081 + struct desc_struct d, *gdt;
11083 +#ifdef CONFIG_PAX_KERNEXEC
11084 + unsigned long cr0;
11087 local_irq_save(flags);
11088 - __asm__("lcall *(%%edi); cld"
11090 + gdt = get_cpu_gdt_table(smp_processor_id());
11092 +#ifdef CONFIG_PAX_KERNEXEC
11093 + pax_open_kernel(cr0);
11096 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
11097 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
11098 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
11099 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
11101 +#ifdef CONFIG_PAX_KERNEXEC
11102 + pax_close_kernel(cr0);
11105 + __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
11106 : "=a" (return_code),
11112 - "D" (&bios32_indirect));
11113 + "D" (&bios32_indirect),
11114 + "r"(__PCIBIOS_DS)
11117 +#ifdef CONFIG_PAX_KERNEXEC
11118 + pax_open_kernel(cr0);
11121 + gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
11122 + gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
11123 + gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
11124 + gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
11126 +#ifdef CONFIG_PAX_KERNEXEC
11127 + pax_close_kernel(cr0);
11130 local_irq_restore(flags);
11132 switch (return_code) {
11134 - return address + entry;
11135 - case 0x80: /* Not present */
11136 - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
11138 - default: /* Shouldn't happen */
11139 - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
11140 - service, return_code);
11143 + unsigned char flags;
11145 + printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
11146 + if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
11147 + printk(KERN_WARNING "bios32_service: not valid\n");
11150 + address = address + PAGE_OFFSET;
11151 + length += 16UL; /* some BIOSs underreport this... */
11153 + if (length >= 64*1024*1024) {
11154 + length >>= PAGE_SHIFT;
11158 +#ifdef CONFIG_PAX_KERNEXEC
11159 + pax_open_kernel(cr0);
11162 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
11163 + gdt = get_cpu_gdt_table(cpu);
11164 + pack_descriptor(&d, address, length, 0x9b, flags);
11165 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
11166 + pack_descriptor(&d, address, length, 0x93, flags);
11167 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
11170 +#ifdef CONFIG_PAX_KERNEXEC
11171 + pax_close_kernel(cr0);
11176 + case 0x80: /* Not present */
11177 + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
11179 + default: /* Shouldn't happen */
11180 + printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
11181 + service, return_code);
11187 unsigned long address;
11188 unsigned short segment;
11189 -} pci_indirect = { 0, __KERNEL_CS };
11190 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
11192 -static int pci_bios_present;
11193 +static int pci_bios_present __read_only;
11195 static int __devinit check_pcibios(void)
11197 @@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
11198 unsigned long flags, pcibios_entry;
11200 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
11201 - pci_indirect.address = pcibios_entry + PAGE_OFFSET;
11202 + pci_indirect.address = pcibios_entry;
11204 local_irq_save(flags);
11206 - "lcall *(%%edi); cld\n\t"
11207 + __asm__("movw %w6, %%ds\n\t"
11208 + "lcall *%%ss:(%%edi); cld\n\t"
11214 @@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
11217 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
11218 - "D" (&pci_indirect)
11219 + "D" (&pci_indirect),
11220 + "r" (__PCIBIOS_DS)
11222 local_irq_restore(flags);
11224 @@ -158,7 +231,10 @@ static int __devinit pci_bios_find_devic
11226 unsigned short ret;
11228 - __asm__("lcall *(%%edi); cld\n\t"
11229 + __asm__("movw %w7, %%ds\n\t"
11230 + "lcall *%%ss:(%%edi); cld\n\t"
11236 @@ -168,7 +244,8 @@ static int __devinit pci_bios_find_devic
11240 - "D" (&pci_indirect));
11241 + "D" (&pci_indirect),
11242 + "r" (__PCIBIOS_DS));
11243 *bus = (bx >> 8) & 0xff;
11244 *device_fn = bx & 0xff;
11245 return (int) (ret & 0xff00) >> 8;
11246 @@ -188,7 +265,10 @@ static int pci_bios_read(unsigned int se
11250 - __asm__("lcall *(%%esi); cld\n\t"
11251 + __asm__("movw %w6, %%ds\n\t"
11252 + "lcall *%%ss:(%%esi); cld\n\t"
11258 @@ -197,7 +277,8 @@ static int pci_bios_read(unsigned int se
11259 : "1" (PCIBIOS_READ_CONFIG_BYTE),
11262 - "S" (&pci_indirect));
11263 + "S" (&pci_indirect),
11264 + "r" (__PCIBIOS_DS));
11266 * Zero-extend the result beyond 8 bits, do not trust the
11267 * BIOS having done it:
11268 @@ -205,7 +286,10 @@ static int pci_bios_read(unsigned int se
11272 - __asm__("lcall *(%%esi); cld\n\t"
11273 + __asm__("movw %w6, %%ds\n\t"
11274 + "lcall *%%ss:(%%esi); cld\n\t"
11280 @@ -214,7 +298,8 @@ static int pci_bios_read(unsigned int se
11281 : "1" (PCIBIOS_READ_CONFIG_WORD),
11284 - "S" (&pci_indirect));
11285 + "S" (&pci_indirect),
11286 + "r" (__PCIBIOS_DS));
11288 * Zero-extend the result beyond 16 bits, do not trust the
11289 * BIOS having done it:
11290 @@ -222,7 +307,10 @@ static int pci_bios_read(unsigned int se
11294 - __asm__("lcall *(%%esi); cld\n\t"
11295 + __asm__("movw %w6, %%ds\n\t"
11296 + "lcall *%%ss:(%%esi); cld\n\t"
11302 @@ -231,7 +319,8 @@ static int pci_bios_read(unsigned int se
11303 : "1" (PCIBIOS_READ_CONFIG_DWORD),
11306 - "S" (&pci_indirect));
11307 + "S" (&pci_indirect),
11308 + "r" (__PCIBIOS_DS));
11312 @@ -254,7 +343,10 @@ static int pci_bios_write(unsigned int s
11316 - __asm__("lcall *(%%esi); cld\n\t"
11317 + __asm__("movw %w6, %%ds\n\t"
11318 + "lcall *%%ss:(%%esi); cld\n\t"
11324 @@ -263,10 +355,14 @@ static int pci_bios_write(unsigned int s
11328 - "S" (&pci_indirect));
11329 + "S" (&pci_indirect),
11330 + "r" (__PCIBIOS_DS));
11333 - __asm__("lcall *(%%esi); cld\n\t"
11334 + __asm__("movw %w6, %%ds\n\t"
11335 + "lcall *%%ss:(%%esi); cld\n\t"
11341 @@ -275,10 +371,14 @@ static int pci_bios_write(unsigned int s
11345 - "S" (&pci_indirect));
11346 + "S" (&pci_indirect),
11347 + "r" (__PCIBIOS_DS));
11350 - __asm__("lcall *(%%esi); cld\n\t"
11351 + __asm__("movw %w6, %%ds\n\t"
11352 + "lcall *%%ss:(%%esi); cld\n\t"
11358 @@ -287,7 +387,8 @@ static int pci_bios_write(unsigned int s
11362 - "S" (&pci_indirect));
11363 + "S" (&pci_indirect),
11364 + "r" (__PCIBIOS_DS));
11368 @@ -440,10 +541,13 @@ struct irq_routing_table * pcibios_get_i
11370 DBG("PCI: Fetching IRQ routing table... ");
11371 __asm__("push %%es\n\t"
11372 + "movw %w8, %%ds\n\t"
11375 - "lcall *(%%esi); cld\n\t"
11376 + "lcall *%%ss:(%%esi); cld\n\t"
11383 @@ -454,7 +558,8 @@ struct irq_routing_table * pcibios_get_i
11386 "S" (&pci_indirect),
11389 + "r" (__PCIBIOS_DS)
11391 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
11393 @@ -478,7 +583,10 @@ int pcibios_set_irq_routing(struct pci_d
11397 - __asm__("lcall *(%%esi); cld\n\t"
11398 + __asm__("movw %w5, %%ds\n\t"
11399 + "lcall *%%ss:(%%esi); cld\n\t"
11405 @@ -486,7 +594,8 @@ int pcibios_set_irq_routing(struct pci_d
11406 : "0" (PCIBIOS_SET_PCI_HW_INT),
11407 "b" ((dev->bus->number << 8) | dev->devfn),
11408 "c" ((irq << 8) | (pin + 10)),
11409 - "S" (&pci_indirect));
11410 + "S" (&pci_indirect),
11411 + "r" (__PCIBIOS_DS));
11412 return !(ret & 0xff00);
11414 EXPORT_SYMBOL(pcibios_set_irq_routing);
11415 diff -urNp linux-2.6.25.10/arch/x86/power/cpu_32.c linux-2.6.25.10/arch/x86/power/cpu_32.c
11416 --- linux-2.6.25.10/arch/x86/power/cpu_32.c 2008-07-02 23:46:47.000000000 -0400
11417 +++ linux-2.6.25.10/arch/x86/power/cpu_32.c 2008-07-03 16:53:25.000000000 -0400
11418 @@ -64,10 +64,20 @@ static void do_fpu_end(void)
11419 static void fix_processor_context(void)
11421 int cpu = smp_processor_id();
11422 - struct tss_struct * t = &per_cpu(init_tss, cpu);
11423 + struct tss_struct *t = init_tss + cpu;
11425 +#ifdef CONFIG_PAX_KERNEXEC
11426 + unsigned long cr0;
11428 + pax_open_kernel(cr0);
11431 set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
11433 +#ifdef CONFIG_PAX_KERNEXEC
11434 + pax_close_kernel(cr0);
11437 load_TR_desc(); /* This does ltr */
11438 load_LDT(¤t->active_mm->context); /* This does lldt */
11440 diff -urNp linux-2.6.25.10/arch/x86/power/cpu_64.c linux-2.6.25.10/arch/x86/power/cpu_64.c
11441 --- linux-2.6.25.10/arch/x86/power/cpu_64.c 2008-07-02 23:46:47.000000000 -0400
11442 +++ linux-2.6.25.10/arch/x86/power/cpu_64.c 2008-07-03 16:53:25.000000000 -0400
11443 @@ -136,7 +136,13 @@ void restore_processor_state(void)
11444 static void fix_processor_context(void)
11446 int cpu = smp_processor_id();
11447 - struct tss_struct *t = &per_cpu(init_tss, cpu);
11448 + struct tss_struct *t = init_tss + cpu;
11450 +#ifdef CONFIG_PAX_KERNEXEC
11451 + unsigned long cr0;
11453 + pax_open_kernel(cr0);
11457 * This just modifies memory; should not be necessary. But... This
11458 @@ -147,6 +153,10 @@ static void fix_processor_context(void)
11460 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
11462 +#ifdef CONFIG_PAX_KERNEXEC
11463 + pax_close_kernel(cr0);
11466 syscall_init(); /* This sets MSR_*STAR and related */
11467 load_TR_desc(); /* This does ltr */
11468 load_LDT(¤t->active_mm->context); /* This does lldt */
11469 diff -urNp linux-2.6.25.10/arch/x86/vdso/vdso32-setup.c linux-2.6.25.10/arch/x86/vdso/vdso32-setup.c
11470 --- linux-2.6.25.10/arch/x86/vdso/vdso32-setup.c 2008-07-02 23:46:47.000000000 -0400
11471 +++ linux-2.6.25.10/arch/x86/vdso/vdso32-setup.c 2008-07-03 16:53:25.000000000 -0400
11472 @@ -235,7 +235,7 @@ static inline void map_compat_vdso(int m
11473 void enable_sep_cpu(void)
11475 int cpu = get_cpu();
11476 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
11477 + struct tss_struct *tss = init_tss + cpu;
11479 if (!boot_cpu_has(X86_FEATURE_SEP)) {
11481 @@ -258,7 +258,7 @@ static int __init gate_vma_init(void)
11482 gate_vma.vm_start = FIXADDR_USER_START;
11483 gate_vma.vm_end = FIXADDR_USER_END;
11484 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
11485 - gate_vma.vm_page_prot = __P101;
11486 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
11488 * Make sure the vDSO gets into every core dump.
11489 * Dumping its contents makes post-mortem fully interpretable later
11490 @@ -336,7 +336,7 @@ int arch_setup_additional_pages(struct l
11492 addr = VDSO_HIGH_BASE;
11494 - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
11495 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
11496 if (IS_ERR_VALUE(addr)) {
11499 @@ -363,7 +363,7 @@ int arch_setup_additional_pages(struct l
11503 - current->mm->context.vdso = (void *)addr;
11504 + current->mm->context.vdso = addr;
11505 current_thread_info()->sysenter_return =
11506 VDSO32_SYMBOL(addr, SYSENTER_RETURN);
11508 @@ -389,7 +389,7 @@ static ctl_table abi_table2[] = {
11510 .proc_handler = proc_dointvec
11513 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11516 static ctl_table abi_root_table2[] = {
11517 @@ -399,7 +399,7 @@ static ctl_table abi_root_table2[] = {
11519 .child = abi_table2
11522 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11525 static __init int ia32_binfmt_init(void)
11526 @@ -414,8 +414,14 @@ __initcall(ia32_binfmt_init);
11528 const char *arch_vma_name(struct vm_area_struct *vma)
11530 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
11531 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
11534 +#ifdef CONFIG_PAX_SEGMEXEC
11535 + if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
11542 @@ -424,7 +430,7 @@ struct vm_area_struct *get_gate_vma(stru
11543 struct mm_struct *mm = tsk->mm;
11545 /* Check to see if this task was created in compat vdso mode */
11546 - if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
11547 + if (mm && mm->context.vdso == VDSO_HIGH_BASE)
11551 diff -urNp linux-2.6.25.10/arch/x86/vdso/vma.c linux-2.6.25.10/arch/x86/vdso/vma.c
11552 --- linux-2.6.25.10/arch/x86/vdso/vma.c 2008-07-02 23:46:47.000000000 -0400
11553 +++ linux-2.6.25.10/arch/x86/vdso/vma.c 2008-07-03 16:53:25.000000000 -0400
11554 @@ -122,7 +122,7 @@ int arch_setup_additional_pages(struct l
11558 - current->mm->context.vdso = (void *)addr;
11559 + current->mm->context.vdso = addr;
11561 up_write(&mm->mmap_sem);
11563 diff -urNp linux-2.6.25.10/arch/x86/xen/enlighten.c linux-2.6.25.10/arch/x86/xen/enlighten.c
11564 --- linux-2.6.25.10/arch/x86/xen/enlighten.c 2008-07-02 23:46:47.000000000 -0400
11565 +++ linux-2.6.25.10/arch/x86/xen/enlighten.c 2008-07-03 16:53:25.000000000 -0400
11566 @@ -293,7 +293,7 @@ static void xen_set_ldt(const void *addr
11567 static void xen_load_gdt(const struct desc_ptr *dtr)
11569 unsigned long *frames;
11570 - unsigned long va = dtr->address;
11571 + unsigned long va = (unsigned long)dtr->address;
11572 unsigned int size = dtr->size + 1;
11573 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
11575 @@ -308,7 +308,7 @@ static void xen_load_gdt(const struct de
11576 mcs = xen_mc_entry(sizeof(*frames) * pages);
11579 - for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
11580 + for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
11581 frames[f] = virt_to_mfn(va);
11582 make_lowmem_page_readonly((void *)va);
11584 @@ -401,7 +401,7 @@ static void xen_write_idt_entry(gate_des
11588 - start = __get_cpu_var(idt_desc).address;
11589 + start = (unsigned long)__get_cpu_var(idt_desc).address;
11590 end = start + __get_cpu_var(idt_desc).size + 1;
11593 diff -urNp linux-2.6.25.10/arch/x86/xen/smp.c linux-2.6.25.10/arch/x86/xen/smp.c
11594 --- linux-2.6.25.10/arch/x86/xen/smp.c 2008-07-02 23:46:47.000000000 -0400
11595 +++ linux-2.6.25.10/arch/x86/xen/smp.c 2008-07-03 16:53:25.000000000 -0400
11596 @@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi
11598 /* We've switched to the "real" per-cpu gdt, so make sure the
11599 old memory can be recycled */
11600 - make_lowmem_page_readwrite(&per_cpu__gdt_page);
11601 + make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
11603 for_each_possible_cpu(cpu) {
11604 cpus_clear(per_cpu(cpu_sibling_map, cpu));
11605 @@ -208,7 +208,7 @@ static __cpuinit int
11606 cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
11608 struct vcpu_guest_context *ctxt;
11609 - struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
11610 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
11612 if (cpu_test_and_set(cpu, cpu_initialized_map))
11614 @@ -218,8 +218,8 @@ cpu_initialize_context(unsigned int cpu,
11617 ctxt->flags = VGCF_IN_KERNEL;
11618 - ctxt->user_regs.ds = __USER_DS;
11619 - ctxt->user_regs.es = __USER_DS;
11620 + ctxt->user_regs.ds = __KERNEL_DS;
11621 + ctxt->user_regs.es = __KERNEL_DS;
11622 ctxt->user_regs.fs = __KERNEL_PERCPU;
11623 ctxt->user_regs.gs = 0;
11624 ctxt->user_regs.ss = __KERNEL_DS;
11625 @@ -232,11 +232,11 @@ cpu_initialize_context(unsigned int cpu,
11627 ctxt->ldt_ents = 0;
11629 - BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
11630 - make_lowmem_page_readonly(gdt->gdt);
11631 + BUG_ON((unsigned long)gdt & ~PAGE_MASK);
11632 + make_lowmem_page_readonly(gdt);
11634 - ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
11635 - ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
11636 + ctxt->gdt_frames[0] = virt_to_mfn(gdt);
11637 + ctxt->gdt_ents = GDT_ENTRIES;
11639 ctxt->user_regs.cs = __KERNEL_CS;
11640 ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
11641 diff -urNp linux-2.6.25.10/crypto/async_tx/async_tx.c linux-2.6.25.10/crypto/async_tx/async_tx.c
11642 --- linux-2.6.25.10/crypto/async_tx/async_tx.c 2008-07-02 23:46:47.000000000 -0400
11643 +++ linux-2.6.25.10/crypto/async_tx/async_tx.c 2008-07-03 16:53:25.000000000 -0400
11644 @@ -341,8 +341,8 @@ async_tx_init(void)
11646 printk(KERN_ERR "async_tx: initialization failure\n");
11648 - while (--cap >= 0)
11649 - free_percpu(channel_table[cap]);
11651 + free_percpu(channel_table[--cap]);
11655 diff -urNp linux-2.6.25.10/crypto/lrw.c linux-2.6.25.10/crypto/lrw.c
11656 --- linux-2.6.25.10/crypto/lrw.c 2008-07-02 23:46:47.000000000 -0400
11657 +++ linux-2.6.25.10/crypto/lrw.c 2008-07-03 16:53:25.000000000 -0400
11658 @@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
11659 struct priv *ctx = crypto_tfm_ctx(parent);
11660 struct crypto_cipher *child = ctx->child;
11662 - be128 tmp = { 0 };
11663 + be128 tmp = { 0, 0 };
11664 int bsize = crypto_cipher_blocksize(child);
11666 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
11667 diff -urNp linux-2.6.25.10/Documentation/dontdiff linux-2.6.25.10/Documentation/dontdiff
11668 --- linux-2.6.25.10/Documentation/dontdiff 2008-07-02 23:46:47.000000000 -0400
11669 +++ linux-2.6.25.10/Documentation/dontdiff 2008-07-03 16:53:24.000000000 -0400
11678 @@ -55,6 +56,7 @@ ChangeSet
11686 @@ -89,6 +91,7 @@ config_data.gz*
11688 consolemap_deftbl.c*
11694 @@ -137,11 +140,13 @@ miboot*
11708 @@ -172,20 +177,24 @@ sm_tbl*
11736 diff -urNp linux-2.6.25.10/drivers/acpi/blacklist.c linux-2.6.25.10/drivers/acpi/blacklist.c
11737 --- linux-2.6.25.10/drivers/acpi/blacklist.c 2008-07-02 23:46:47.000000000 -0400
11738 +++ linux-2.6.25.10/drivers/acpi/blacklist.c 2008-07-03 16:53:25.000000000 -0400
11739 @@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
11740 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
11741 "Incorrect _ADR", 1},
11744 + {"", "", 0, 0, 0, all_versions, 0}
11747 #if CONFIG_ACPI_BLACKLIST_YEAR
11748 diff -urNp linux-2.6.25.10/drivers/acpi/osl.c linux-2.6.25.10/drivers/acpi/osl.c
11749 --- linux-2.6.25.10/drivers/acpi/osl.c 2008-07-02 23:46:47.000000000 -0400
11750 +++ linux-2.6.25.10/drivers/acpi/osl.c 2008-07-03 16:53:25.000000000 -0400
11751 @@ -489,6 +489,8 @@ acpi_os_read_memory(acpi_physical_addres
11752 void __iomem *virt_addr;
11754 virt_addr = ioremap(phys_addr, width);
11756 + return AE_NO_MEMORY;
11760 @@ -517,6 +519,8 @@ acpi_os_write_memory(acpi_physical_addre
11761 void __iomem *virt_addr;
11763 virt_addr = ioremap(phys_addr, width);
11765 + return AE_NO_MEMORY;
11769 diff -urNp linux-2.6.25.10/drivers/acpi/processor_core.c linux-2.6.25.10/drivers/acpi/processor_core.c
11770 --- linux-2.6.25.10/drivers/acpi/processor_core.c 2008-07-02 23:46:47.000000000 -0400
11771 +++ linux-2.6.25.10/drivers/acpi/processor_core.c 2008-07-03 16:53:25.000000000 -0400
11772 @@ -632,7 +632,7 @@ static int __cpuinit acpi_processor_star
11776 - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
11777 + BUG_ON(pr->id >= nr_cpu_ids);
11781 diff -urNp linux-2.6.25.10/drivers/acpi/processor_idle.c linux-2.6.25.10/drivers/acpi/processor_idle.c
11782 --- linux-2.6.25.10/drivers/acpi/processor_idle.c 2008-07-02 23:46:47.000000000 -0400
11783 +++ linux-2.6.25.10/drivers/acpi/processor_idle.c 2008-07-03 16:53:25.000000000 -0400
11784 @@ -181,7 +181,7 @@ static struct dmi_system_id __cpuinitdat
11785 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
11786 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
11789 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
11792 static inline u32 ticks_elapsed(u32 t1, u32 t2)
11793 diff -urNp linux-2.6.25.10/drivers/acpi/sleep/main.c linux-2.6.25.10/drivers/acpi/sleep/main.c
11794 --- linux-2.6.25.10/drivers/acpi/sleep/main.c 2008-07-02 23:46:47.000000000 -0400
11795 +++ linux-2.6.25.10/drivers/acpi/sleep/main.c 2008-07-03 16:53:25.000000000 -0400
11796 @@ -250,7 +250,7 @@ static struct dmi_system_id __initdata a
11797 .ident = "Toshiba Satellite 4030cdt",
11798 .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
11801 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
11803 #endif /* CONFIG_SUSPEND */
11805 diff -urNp linux-2.6.25.10/drivers/acpi/tables/tbfadt.c linux-2.6.25.10/drivers/acpi/tables/tbfadt.c
11806 --- linux-2.6.25.10/drivers/acpi/tables/tbfadt.c 2008-07-02 23:46:47.000000000 -0400
11807 +++ linux-2.6.25.10/drivers/acpi/tables/tbfadt.c 2008-07-03 16:53:25.000000000 -0400
11809 ACPI_MODULE_NAME("tbfadt")
11811 /* Local prototypes */
11812 -static void inline
11813 +static inline void
11814 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
11815 u8 bit_width, u64 address);
11817 @@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
11819 ******************************************************************************/
11821 -static void inline
11822 +static inline void
11823 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
11824 u8 bit_width, u64 address)
11826 diff -urNp linux-2.6.25.10/drivers/acpi/tables/tbxface.c linux-2.6.25.10/drivers/acpi/tables/tbxface.c
11827 --- linux-2.6.25.10/drivers/acpi/tables/tbxface.c 2008-07-02 23:46:47.000000000 -0400
11828 +++ linux-2.6.25.10/drivers/acpi/tables/tbxface.c 2008-07-03 16:53:25.000000000 -0400
11829 @@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespac
11830 acpi_tb_print_table_header(0, table);
11832 if (no_auto_ssdt == 0) {
11833 - printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
11834 + printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
11838 diff -urNp linux-2.6.25.10/drivers/ata/ahci.c linux-2.6.25.10/drivers/ata/ahci.c
11839 --- linux-2.6.25.10/drivers/ata/ahci.c 2008-07-02 23:46:47.000000000 -0400
11840 +++ linux-2.6.25.10/drivers/ata/ahci.c 2008-07-03 16:53:25.000000000 -0400
11841 @@ -598,7 +598,7 @@ static const struct pci_device_id ahci_p
11842 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
11843 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
11845 - { } /* terminate list */
11846 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
11850 diff -urNp linux-2.6.25.10/drivers/ata/ata_piix.c linux-2.6.25.10/drivers/ata/ata_piix.c
11851 --- linux-2.6.25.10/drivers/ata/ata_piix.c 2008-07-02 23:46:47.000000000 -0400
11852 +++ linux-2.6.25.10/drivers/ata/ata_piix.c 2008-07-03 16:53:25.000000000 -0400
11853 @@ -276,7 +276,7 @@ static const struct pci_device_id piix_p
11854 /* SATA Controller IDE (ICH10) */
11855 { 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
11857 - { } /* terminate list */
11858 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
11861 static struct pci_driver piix_pci_driver = {
11862 @@ -723,7 +723,7 @@ static const struct ich_laptop ich_lapto
11863 { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
11864 { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
11871 @@ -1307,7 +1307,7 @@ static int piix_broken_suspend(void)
11875 - { } /* terminate list */
11876 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
11878 static const char *oemstrs[] = {
11880 diff -urNp linux-2.6.25.10/drivers/ata/libata-core.c linux-2.6.25.10/drivers/ata/libata-core.c
11881 --- linux-2.6.25.10/drivers/ata/libata-core.c 2008-07-02 23:46:47.000000000 -0400
11882 +++ linux-2.6.25.10/drivers/ata/libata-core.c 2008-07-03 16:53:25.000000000 -0400
11883 @@ -725,7 +725,7 @@ static const struct ata_xfer_ent {
11884 { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
11885 { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
11886 { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
11892 @@ -3043,7 +3043,7 @@ static const struct ata_timing ata_timin
11893 { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
11894 { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
11897 + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
11900 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
11901 @@ -4465,7 +4465,7 @@ static const struct ata_blacklist_entry
11902 { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
11906 + { NULL, NULL, 0 }
11909 static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
11910 diff -urNp linux-2.6.25.10/drivers/char/agp/frontend.c linux-2.6.25.10/drivers/char/agp/frontend.c
11911 --- linux-2.6.25.10/drivers/char/agp/frontend.c 2008-07-02 23:46:47.000000000 -0400
11912 +++ linux-2.6.25.10/drivers/char/agp/frontend.c 2008-07-03 16:53:25.000000000 -0400
11913 @@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
11914 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
11917 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
11918 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
11921 client = agp_find_client_by_pid(reserve.pid);
11922 diff -urNp linux-2.6.25.10/drivers/char/agp/intel-agp.c linux-2.6.25.10/drivers/char/agp/intel-agp.c
11923 --- linux-2.6.25.10/drivers/char/agp/intel-agp.c 2008-07-02 23:46:47.000000000 -0400
11924 +++ linux-2.6.25.10/drivers/char/agp/intel-agp.c 2008-07-03 16:53:25.000000000 -0400
11925 @@ -2254,7 +2254,7 @@ static struct pci_device_id agp_intel_pc
11926 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
11927 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
11928 ID(PCI_DEVICE_ID_INTEL_IGD_HB),
11930 + { 0, 0, 0, 0, 0, 0, 0 }
11933 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
11934 diff -urNp linux-2.6.25.10/drivers/char/drm/drm_pciids.h linux-2.6.25.10/drivers/char/drm/drm_pciids.h
11935 --- linux-2.6.25.10/drivers/char/drm/drm_pciids.h 2008-07-02 23:46:47.000000000 -0400
11936 +++ linux-2.6.25.10/drivers/char/drm/drm_pciids.h 2008-07-03 16:53:25.000000000 -0400
11937 @@ -348,7 +348,7 @@
11938 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
11939 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
11940 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
11942 + {0, 0, 0, 0, 0, 0, 0 }
11944 #define i830_PCI_IDS \
11945 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
11946 diff -urNp linux-2.6.25.10/drivers/char/hpet.c linux-2.6.25.10/drivers/char/hpet.c
11947 --- linux-2.6.25.10/drivers/char/hpet.c 2008-07-02 23:46:47.000000000 -0400
11948 +++ linux-2.6.25.10/drivers/char/hpet.c 2008-07-03 16:53:25.000000000 -0400
11949 @@ -953,7 +953,7 @@ static struct acpi_driver hpet_acpi_driv
11953 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
11954 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
11956 static int __init hpet_init(void)
11958 diff -urNp linux-2.6.25.10/drivers/char/keyboard.c linux-2.6.25.10/drivers/char/keyboard.c
11959 --- linux-2.6.25.10/drivers/char/keyboard.c 2008-07-02 23:46:47.000000000 -0400
11960 +++ linux-2.6.25.10/drivers/char/keyboard.c 2008-07-03 16:53:25.000000000 -0400
11961 @@ -630,6 +630,16 @@ static void k_spec(struct vc_data *vc, u
11962 kbd->kbdmode == VC_MEDIUMRAW) &&
11963 value != KVAL(K_SAK))
11964 return; /* SAK is allowed even in raw mode */
11966 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
11968 + void *func = fn_handler[value];
11969 + if (func == fn_show_state || func == fn_show_ptregs ||
11970 + func == fn_show_mem)
11975 fn_handler[value](vc);
11978 @@ -1384,7 +1394,7 @@ static const struct input_device_id kbd_
11979 .evbit = { BIT_MASK(EV_SND) },
11982 - { }, /* Terminating entry */
11983 + { 0 }, /* Terminating entry */
11986 MODULE_DEVICE_TABLE(input, kbd_ids);
11987 diff -urNp linux-2.6.25.10/drivers/char/mem.c linux-2.6.25.10/drivers/char/mem.c
11988 --- linux-2.6.25.10/drivers/char/mem.c 2008-07-02 23:46:47.000000000 -0400
11989 +++ linux-2.6.25.10/drivers/char/mem.c 2008-07-03 16:53:25.000000000 -0400
11991 #include <linux/bootmem.h>
11992 #include <linux/splice.h>
11993 #include <linux/pfn.h>
11994 +#include <linux/grsecurity.h>
11996 #include <asm/uaccess.h>
11997 #include <asm/io.h>
11999 # include <linux/efi.h>
12002 +#ifdef CONFIG_GRKERNSEC
12003 +extern struct file_operations grsec_fops;
12007 * Architectures vary in how they handle caching for addresses
12008 * outside of main memory.
12009 @@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f
12010 if (!valid_phys_addr_range(p, count))
12013 +#ifdef CONFIG_GRKERNSEC_KMEM
12014 + gr_handle_mem_write();
12020 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
12021 @@ -281,6 +291,11 @@ static int mmap_mem(struct file * file,
12022 if (!private_mapping_ok(vma))
12025 +#ifdef CONFIG_GRKERNSEC_KMEM
12026 + if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
12030 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
12032 vma->vm_page_prot);
12033 @@ -512,6 +527,11 @@ static ssize_t write_kmem(struct file *
12035 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
12037 +#ifdef CONFIG_GRKERNSEC_KMEM
12038 + gr_handle_kmem_write();
12042 if (p < (unsigned long) high_memory) {
12045 @@ -714,6 +734,16 @@ static loff_t memory_lseek(struct file *
12047 static int open_port(struct inode * inode, struct file * filp)
12049 +#ifdef CONFIG_GRKERNSEC_KMEM
12050 + gr_handle_open_port();
12054 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12057 +static int open_mem(struct inode * inode, struct file * filp)
12059 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12062 @@ -721,7 +751,6 @@ static int open_port(struct inode * inod
12063 #define full_lseek null_lseek
12064 #define write_zero write_null
12065 #define read_full read_zero
12066 -#define open_mem open_port
12067 #define open_kmem open_mem
12068 #define open_oldmem open_mem
12070 @@ -854,6 +883,11 @@ static int memory_open(struct inode * in
12071 filp->f_op = &oldmem_fops;
12074 +#ifdef CONFIG_GRKERNSEC
12076 + filp->f_op = &grsec_fops;
12082 @@ -886,6 +920,9 @@ static const struct {
12083 #ifdef CONFIG_CRASH_DUMP
12084 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
12086 +#ifdef CONFIG_GRKERNSEC
12087 + {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
12091 static struct class *mem_class;
12092 diff -urNp linux-2.6.25.10/drivers/char/nvram.c linux-2.6.25.10/drivers/char/nvram.c
12093 --- linux-2.6.25.10/drivers/char/nvram.c 2008-07-02 23:46:47.000000000 -0400
12094 +++ linux-2.6.25.10/drivers/char/nvram.c 2008-07-03 16:53:25.000000000 -0400
12095 @@ -430,7 +430,10 @@ static const struct file_operations nvra
12096 static struct miscdevice nvram_dev = {
12107 diff -urNp linux-2.6.25.10/drivers/char/random.c linux-2.6.25.10/drivers/char/random.c
12108 --- linux-2.6.25.10/drivers/char/random.c 2008-07-02 23:46:47.000000000 -0400
12109 +++ linux-2.6.25.10/drivers/char/random.c 2008-07-03 16:53:25.000000000 -0400
12110 @@ -248,8 +248,13 @@
12112 * Configuration information
12114 +#ifdef CONFIG_GRKERNSEC_RANDNET
12115 +#define INPUT_POOL_WORDS 512
12116 +#define OUTPUT_POOL_WORDS 128
12118 #define INPUT_POOL_WORDS 128
12119 #define OUTPUT_POOL_WORDS 32
12121 #define SEC_XFER_SIZE 512
12124 @@ -286,10 +291,17 @@ static struct poolinfo {
12126 int tap1, tap2, tap3, tap4, tap5;
12127 } poolinfo_table[] = {
12128 +#ifdef CONFIG_GRKERNSEC_RANDNET
12129 + /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
12130 + { 512, 411, 308, 208, 104, 1 },
12131 + /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
12132 + { 128, 103, 76, 51, 25, 1 },
12134 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
12135 { 128, 103, 76, 51, 25, 1 },
12136 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
12137 { 32, 26, 20, 14, 7, 1 },
12140 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
12141 { 2048, 1638, 1231, 819, 411, 1 },
12142 @@ -1171,7 +1183,7 @@ EXPORT_SYMBOL(generate_random_uuid);
12143 #include <linux/sysctl.h>
12145 static int min_read_thresh = 8, min_write_thresh;
12146 -static int max_read_thresh = INPUT_POOL_WORDS * 32;
12147 +static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
12148 static int max_write_thresh = INPUT_POOL_WORDS * 32;
12149 static char sysctl_bootid[16];
12151 diff -urNp linux-2.6.25.10/drivers/char/tpm/tpm.c linux-2.6.25.10/drivers/char/tpm/tpm.c
12152 --- linux-2.6.25.10/drivers/char/tpm/tpm.c 2008-07-02 23:46:47.000000000 -0400
12153 +++ linux-2.6.25.10/drivers/char/tpm/tpm.c 2008-07-03 16:53:25.000000000 -0400
12154 @@ -970,7 +970,7 @@ ssize_t tpm_write(struct file *file, con
12156 mutex_lock(&chip->buffer_mutex);
12158 - if (in_size > TPM_BUFSIZE)
12159 + if (in_size > (unsigned int)TPM_BUFSIZE)
12160 in_size = TPM_BUFSIZE;
12163 diff -urNp linux-2.6.25.10/drivers/char/vt_ioctl.c linux-2.6.25.10/drivers/char/vt_ioctl.c
12164 --- linux-2.6.25.10/drivers/char/vt_ioctl.c 2008-07-02 23:46:47.000000000 -0400
12165 +++ linux-2.6.25.10/drivers/char/vt_ioctl.c 2008-07-03 16:53:25.000000000 -0400
12166 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
12171 +#ifdef CONFIG_GRKERNSEC
12172 + if (!capable(CAP_SYS_TTY_CONFIG))
12176 if (!i && v == K_NOSUCHMAP) {
12177 /* deallocate map */
12178 key_map = key_maps[s];
12179 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
12183 +#ifdef CONFIG_GRKERNSEC
12184 + if (!capable(CAP_SYS_TTY_CONFIG)) {
12191 first_free = funcbufptr + (funcbufsize - funcbufleft);
12192 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
12193 diff -urNp linux-2.6.25.10/drivers/edac/edac_core.h linux-2.6.25.10/drivers/edac/edac_core.h
12194 --- linux-2.6.25.10/drivers/edac/edac_core.h 2008-07-02 23:46:47.000000000 -0400
12195 +++ linux-2.6.25.10/drivers/edac/edac_core.h 2008-07-03 16:53:25.000000000 -0400
12196 @@ -86,11 +86,11 @@ extern int edac_debug_level;
12198 #else /* !CONFIG_EDAC_DEBUG */
12200 -#define debugf0( ... )
12201 -#define debugf1( ... )
12202 -#define debugf2( ... )
12203 -#define debugf3( ... )
12204 -#define debugf4( ... )
12205 +#define debugf0( ... ) do {} while (0)
12206 +#define debugf1( ... ) do {} while (0)
12207 +#define debugf2( ... ) do {} while (0)
12208 +#define debugf3( ... ) do {} while (0)
12209 +#define debugf4( ... ) do {} while (0)
12211 #endif /* !CONFIG_EDAC_DEBUG */
12213 diff -urNp linux-2.6.25.10/drivers/firmware/dmi_scan.c linux-2.6.25.10/drivers/firmware/dmi_scan.c
12214 --- linux-2.6.25.10/drivers/firmware/dmi_scan.c 2008-07-02 23:46:47.000000000 -0400
12215 +++ linux-2.6.25.10/drivers/firmware/dmi_scan.c 2008-07-03 16:53:25.000000000 -0400
12216 @@ -379,11 +379,6 @@ void __init dmi_scan_machine(void)
12221 - * no iounmap() for that ioremap(); it would be a no-op, but
12222 - * it's so early in setup that sucker gets confused into doing
12223 - * what it shouldn't if we actually call it.
12225 p = dmi_ioremap(0xF0000, 0x10000);
12228 diff -urNp linux-2.6.25.10/drivers/hwmon/fscpos.c linux-2.6.25.10/drivers/hwmon/fscpos.c
12229 --- linux-2.6.25.10/drivers/hwmon/fscpos.c 2008-07-02 23:46:47.000000000 -0400
12230 +++ linux-2.6.25.10/drivers/hwmon/fscpos.c 2008-07-03 16:53:25.000000000 -0400
12231 @@ -230,7 +230,6 @@ static ssize_t set_pwm(struct i2c_client
12232 unsigned long v = simple_strtoul(buf, NULL, 10);
12234 /* Range: 0..255 */
12235 - if (v < 0) v = 0;
12236 if (v > 255) v = 255;
12238 mutex_lock(&data->update_lock);
12239 diff -urNp linux-2.6.25.10/drivers/hwmon/k8temp.c linux-2.6.25.10/drivers/hwmon/k8temp.c
12240 --- linux-2.6.25.10/drivers/hwmon/k8temp.c 2008-07-02 23:46:47.000000000 -0400
12241 +++ linux-2.6.25.10/drivers/hwmon/k8temp.c 2008-07-03 16:53:25.000000000 -0400
12242 @@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
12244 static struct pci_device_id k8temp_ids[] = {
12245 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
12247 + { 0, 0, 0, 0, 0, 0, 0 },
12250 MODULE_DEVICE_TABLE(pci, k8temp_ids);
12251 diff -urNp linux-2.6.25.10/drivers/hwmon/sis5595.c linux-2.6.25.10/drivers/hwmon/sis5595.c
12252 --- linux-2.6.25.10/drivers/hwmon/sis5595.c 2008-07-02 23:46:47.000000000 -0400
12253 +++ linux-2.6.25.10/drivers/hwmon/sis5595.c 2008-07-03 16:53:25.000000000 -0400
12254 @@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
12256 static struct pci_device_id sis5595_pci_ids[] = {
12257 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12259 + { 0, 0, 0, 0, 0, 0, 0 }
12262 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
12263 diff -urNp linux-2.6.25.10/drivers/hwmon/via686a.c linux-2.6.25.10/drivers/hwmon/via686a.c
12264 --- linux-2.6.25.10/drivers/hwmon/via686a.c 2008-07-02 23:46:47.000000000 -0400
12265 +++ linux-2.6.25.10/drivers/hwmon/via686a.c 2008-07-03 16:53:25.000000000 -0400
12266 @@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
12268 static struct pci_device_id via686a_pci_ids[] = {
12269 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
12271 + { 0, 0, 0, 0, 0, 0, 0 }
12274 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
12275 diff -urNp linux-2.6.25.10/drivers/hwmon/vt8231.c linux-2.6.25.10/drivers/hwmon/vt8231.c
12276 --- linux-2.6.25.10/drivers/hwmon/vt8231.c 2008-07-02 23:46:47.000000000 -0400
12277 +++ linux-2.6.25.10/drivers/hwmon/vt8231.c 2008-07-03 16:53:25.000000000 -0400
12278 @@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
12280 static struct pci_device_id vt8231_pci_ids[] = {
12281 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
12283 + { 0, 0, 0, 0, 0, 0, 0 }
12286 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
12287 diff -urNp linux-2.6.25.10/drivers/hwmon/w83791d.c linux-2.6.25.10/drivers/hwmon/w83791d.c
12288 --- linux-2.6.25.10/drivers/hwmon/w83791d.c 2008-07-02 23:46:47.000000000 -0400
12289 +++ linux-2.6.25.10/drivers/hwmon/w83791d.c 2008-07-03 16:53:25.000000000 -0400
12290 @@ -290,8 +290,8 @@ static int w83791d_attach_adapter(struct
12291 static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
12292 static int w83791d_detach_client(struct i2c_client *client);
12294 -static int w83791d_read(struct i2c_client *client, u8 register);
12295 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
12296 +static int w83791d_read(struct i2c_client *client, u8 reg);
12297 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
12298 static struct w83791d_data *w83791d_update_device(struct device *dev);
12301 diff -urNp linux-2.6.25.10/drivers/i2c/busses/i2c-i801.c linux-2.6.25.10/drivers/i2c/busses/i2c-i801.c
12302 --- linux-2.6.25.10/drivers/i2c/busses/i2c-i801.c 2008-07-02 23:46:47.000000000 -0400
12303 +++ linux-2.6.25.10/drivers/i2c/busses/i2c-i801.c 2008-07-03 16:53:25.000000000 -0400
12304 @@ -592,7 +592,7 @@ static struct pci_device_id i801_ids[] =
12305 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
12306 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
12307 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
12309 + { 0, 0, 0, 0, 0, 0, 0 }
12312 MODULE_DEVICE_TABLE (pci, i801_ids);
12313 diff -urNp linux-2.6.25.10/drivers/i2c/busses/i2c-i810.c linux-2.6.25.10/drivers/i2c/busses/i2c-i810.c
12314 --- linux-2.6.25.10/drivers/i2c/busses/i2c-i810.c 2008-07-02 23:46:47.000000000 -0400
12315 +++ linux-2.6.25.10/drivers/i2c/busses/i2c-i810.c 2008-07-03 16:53:25.000000000 -0400
12316 @@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
12317 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
12318 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
12319 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
12321 + { 0, 0, 0, 0, 0, 0, 0 },
12324 MODULE_DEVICE_TABLE (pci, i810_ids);
12325 diff -urNp linux-2.6.25.10/drivers/i2c/busses/i2c-piix4.c linux-2.6.25.10/drivers/i2c/busses/i2c-piix4.c
12326 --- linux-2.6.25.10/drivers/i2c/busses/i2c-piix4.c 2008-07-02 23:46:47.000000000 -0400
12327 +++ linux-2.6.25.10/drivers/i2c/busses/i2c-piix4.c 2008-07-03 16:53:25.000000000 -0400
12328 @@ -133,7 +133,7 @@ static struct dmi_system_id __devinitdat
12330 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
12333 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
12336 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
12337 @@ -428,7 +428,7 @@ static struct pci_device_id piix4_ids[]
12338 PCI_DEVICE_ID_SERVERWORKS_CSB6) },
12339 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
12340 PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
12342 + { 0, 0, 0, 0, 0, 0, 0 }
12345 MODULE_DEVICE_TABLE (pci, piix4_ids);
12346 diff -urNp linux-2.6.25.10/drivers/i2c/busses/i2c-sis630.c linux-2.6.25.10/drivers/i2c/busses/i2c-sis630.c
12347 --- linux-2.6.25.10/drivers/i2c/busses/i2c-sis630.c 2008-07-02 23:46:47.000000000 -0400
12348 +++ linux-2.6.25.10/drivers/i2c/busses/i2c-sis630.c 2008-07-03 16:53:25.000000000 -0400
12349 @@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
12350 static struct pci_device_id sis630_ids[] __devinitdata = {
12351 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12352 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
12354 + { 0, 0, 0, 0, 0, 0, 0 }
12357 MODULE_DEVICE_TABLE (pci, sis630_ids);
12358 diff -urNp linux-2.6.25.10/drivers/i2c/busses/i2c-sis96x.c linux-2.6.25.10/drivers/i2c/busses/i2c-sis96x.c
12359 --- linux-2.6.25.10/drivers/i2c/busses/i2c-sis96x.c 2008-07-02 23:46:47.000000000 -0400
12360 +++ linux-2.6.25.10/drivers/i2c/busses/i2c-sis96x.c 2008-07-03 16:53:25.000000000 -0400
12361 @@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
12363 static struct pci_device_id sis96x_ids[] = {
12364 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
12366 + { 0, 0, 0, 0, 0, 0, 0 }
12369 MODULE_DEVICE_TABLE (pci, sis96x_ids);
12370 diff -urNp linux-2.6.25.10/drivers/ide/ide-cd.c linux-2.6.25.10/drivers/ide/ide-cd.c
12371 --- linux-2.6.25.10/drivers/ide/ide-cd.c 2008-07-02 23:46:47.000000000 -0400
12372 +++ linux-2.6.25.10/drivers/ide/ide-cd.c 2008-07-03 16:53:25.000000000 -0400
12373 @@ -182,8 +182,6 @@ void cdrom_analyze_sense_data(ide_drive_
12374 sector &= ~(bio_sectors -1);
12375 valid = (sector - failed_command->sector) << 9;
12379 if (sector < get_capacity(info->disk) &&
12380 drive->probed_capacity - sector < 4 * 75) {
12381 set_capacity(info->disk, sector);
12382 diff -urNp linux-2.6.25.10/drivers/ieee1394/dv1394.c linux-2.6.25.10/drivers/ieee1394/dv1394.c
12383 --- linux-2.6.25.10/drivers/ieee1394/dv1394.c 2008-07-02 23:46:47.000000000 -0400
12384 +++ linux-2.6.25.10/drivers/ieee1394/dv1394.c 2008-07-03 16:53:25.000000000 -0400
12385 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
12386 based upon DIF section and sequence
12389 -static void inline
12390 +static inline void
12391 frame_put_packet (struct frame *f, struct packet *p)
12393 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
12394 @@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
12395 /* default SYT offset is 3 cycles */
12396 init->syt_offset = 3;
12398 - if ( (init->channel > 63) || (init->channel < 0) )
12399 + if (init->channel > 63)
12400 init->channel = 63;
12402 chan_mask = (u64)1 << init->channel;
12403 @@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
12404 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
12405 .version = AVC_SW_VERSION_ENTRY & 0xffffff
12408 + { 0, 0, 0, 0, 0, 0 }
12411 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
12412 diff -urNp linux-2.6.25.10/drivers/ieee1394/eth1394.c linux-2.6.25.10/drivers/ieee1394/eth1394.c
12413 --- linux-2.6.25.10/drivers/ieee1394/eth1394.c 2008-07-02 23:46:47.000000000 -0400
12414 +++ linux-2.6.25.10/drivers/ieee1394/eth1394.c 2008-07-03 16:53:26.000000000 -0400
12415 @@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
12416 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
12417 .version = ETHER1394_GASP_VERSION,
12420 + { 0, 0, 0, 0, 0, 0 }
12423 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
12424 diff -urNp linux-2.6.25.10/drivers/ieee1394/hosts.c linux-2.6.25.10/drivers/ieee1394/hosts.c
12425 --- linux-2.6.25.10/drivers/ieee1394/hosts.c 2008-07-02 23:46:47.000000000 -0400
12426 +++ linux-2.6.25.10/drivers/ieee1394/hosts.c 2008-07-03 16:53:26.000000000 -0400
12427 @@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
12430 static struct hpsb_host_driver dummy_driver = {
12432 .transmit_packet = dummy_transmit_packet,
12433 .devctl = dummy_devctl,
12434 .isoctl = dummy_isoctl
12435 diff -urNp linux-2.6.25.10/drivers/ieee1394/ohci1394.c linux-2.6.25.10/drivers/ieee1394/ohci1394.c
12436 --- linux-2.6.25.10/drivers/ieee1394/ohci1394.c 2008-07-02 23:46:47.000000000 -0400
12437 +++ linux-2.6.25.10/drivers/ieee1394/ohci1394.c 2008-07-03 16:53:26.000000000 -0400
12438 @@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
12439 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
12441 /* Module Parameters */
12442 -static int phys_dma = 1;
12443 +static int phys_dma;
12444 module_param(phys_dma, int, 0444);
12445 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
12446 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
12448 static void dma_trm_tasklet(unsigned long data);
12449 static void dma_trm_reset(struct dma_trm_ctx *d);
12450 @@ -3400,7 +3400,7 @@ static struct pci_device_id ohci1394_pci
12451 .subvendor = PCI_ANY_ID,
12452 .subdevice = PCI_ANY_ID,
12455 + { 0, 0, 0, 0, 0, 0, 0 },
12458 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
12459 diff -urNp linux-2.6.25.10/drivers/ieee1394/raw1394.c linux-2.6.25.10/drivers/ieee1394/raw1394.c
12460 --- linux-2.6.25.10/drivers/ieee1394/raw1394.c 2008-07-02 23:46:47.000000000 -0400
12461 +++ linux-2.6.25.10/drivers/ieee1394/raw1394.c 2008-07-03 16:53:26.000000000 -0400
12462 @@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394
12463 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12464 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12465 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
12467 + { 0, 0, 0, 0, 0, 0 }
12470 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
12471 diff -urNp linux-2.6.25.10/drivers/ieee1394/sbp2.c linux-2.6.25.10/drivers/ieee1394/sbp2.c
12472 --- linux-2.6.25.10/drivers/ieee1394/sbp2.c 2008-07-02 23:46:47.000000000 -0400
12473 +++ linux-2.6.25.10/drivers/ieee1394/sbp2.c 2008-07-03 16:53:26.000000000 -0400
12474 @@ -283,7 +283,7 @@ static struct ieee1394_device_id sbp2_id
12475 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12476 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
12477 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
12479 + { 0, 0, 0, 0, 0, 0 }
12481 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
12483 @@ -2108,7 +2108,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
12484 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
12485 MODULE_LICENSE("GPL");
12487 -static int sbp2_module_init(void)
12488 +static int __init sbp2_module_init(void)
12492 diff -urNp linux-2.6.25.10/drivers/ieee1394/video1394.c linux-2.6.25.10/drivers/ieee1394/video1394.c
12493 --- linux-2.6.25.10/drivers/ieee1394/video1394.c 2008-07-02 23:46:47.000000000 -0400
12494 +++ linux-2.6.25.10/drivers/ieee1394/video1394.c 2008-07-03 16:53:26.000000000 -0400
12495 @@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
12496 if (unlikely(d == NULL))
12499 - if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
12500 + if (unlikely(v.buffer>=d->num_desc - 1)) {
12501 PRINT(KERN_ERR, ohci->host->id,
12502 "Buffer %d out of range",v.buffer);
12504 @@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
12505 if (unlikely(d == NULL))
12508 - if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
12509 + if (unlikely(v.buffer>d->num_desc - 1)) {
12510 PRINT(KERN_ERR, ohci->host->id,
12511 "Buffer %d out of range",v.buffer);
12513 @@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
12514 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12515 if (d == NULL) return -EFAULT;
12517 - if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
12518 + if (v.buffer>=d->num_desc - 1) {
12519 PRINT(KERN_ERR, ohci->host->id,
12520 "Buffer %d out of range",v.buffer);
12522 @@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
12523 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12524 if (d == NULL) return -EFAULT;
12526 - if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
12527 + if (v.buffer>=d->num_desc-1) {
12528 PRINT(KERN_ERR, ohci->host->id,
12529 "Buffer %d out of range",v.buffer);
12531 @@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
12532 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12533 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
12536 + { 0, 0, 0, 0, 0, 0 }
12539 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
12540 diff -urNp linux-2.6.25.10/drivers/input/keyboard/atkbd.c linux-2.6.25.10/drivers/input/keyboard/atkbd.c
12541 --- linux-2.6.25.10/drivers/input/keyboard/atkbd.c 2008-07-02 23:46:47.000000000 -0400
12542 +++ linux-2.6.25.10/drivers/input/keyboard/atkbd.c 2008-07-03 16:53:26.000000000 -0400
12543 @@ -1113,7 +1113,7 @@ static struct serio_device_id atkbd_seri
12545 .extra = SERIO_ANY,
12551 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
12552 diff -urNp linux-2.6.25.10/drivers/input/mouse/lifebook.c linux-2.6.25.10/drivers/input/mouse/lifebook.c
12553 --- linux-2.6.25.10/drivers/input/mouse/lifebook.c 2008-07-02 23:46:47.000000000 -0400
12554 +++ linux-2.6.25.10/drivers/input/mouse/lifebook.c 2008-07-03 16:53:26.000000000 -0400
12555 @@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
12556 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
12560 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
12563 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
12564 diff -urNp linux-2.6.25.10/drivers/input/mouse/psmouse-base.c linux-2.6.25.10/drivers/input/mouse/psmouse-base.c
12565 --- linux-2.6.25.10/drivers/input/mouse/psmouse-base.c 2008-07-02 23:46:47.000000000 -0400
12566 +++ linux-2.6.25.10/drivers/input/mouse/psmouse-base.c 2008-07-03 16:53:26.000000000 -0400
12567 @@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
12569 .extra = SERIO_ANY,
12575 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
12576 diff -urNp linux-2.6.25.10/drivers/input/mouse/synaptics.c linux-2.6.25.10/drivers/input/mouse/synaptics.c
12577 --- linux-2.6.25.10/drivers/input/mouse/synaptics.c 2008-07-02 23:46:47.000000000 -0400
12578 +++ linux-2.6.25.10/drivers/input/mouse/synaptics.c 2008-07-03 16:53:26.000000000 -0400
12579 @@ -417,7 +417,7 @@ static void synaptics_process_packet(str
12582 if (SYN_MODEL_PEN(priv->model_id))
12583 - ; /* Nothing, treat a pen as a single finger */
12584 + break; /* Nothing, treat a pen as a single finger */
12587 if (SYN_CAP_PALMDETECT(priv->capabilities))
12588 @@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
12589 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
12593 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12597 diff -urNp linux-2.6.25.10/drivers/input/mousedev.c linux-2.6.25.10/drivers/input/mousedev.c
12598 --- linux-2.6.25.10/drivers/input/mousedev.c 2008-07-02 23:46:47.000000000 -0400
12599 +++ linux-2.6.25.10/drivers/input/mousedev.c 2008-07-03 16:53:26.000000000 -0400
12600 @@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han
12602 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
12603 static struct miscdevice psaux_mouse = {
12604 - PSMOUSE_MINOR, "psaux", &mousedev_fops
12605 + PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
12607 static int psaux_registered;
12609 diff -urNp linux-2.6.25.10/drivers/input/serio/i8042-x86ia64io.h linux-2.6.25.10/drivers/input/serio/i8042-x86ia64io.h
12610 --- linux-2.6.25.10/drivers/input/serio/i8042-x86ia64io.h 2008-07-02 23:46:47.000000000 -0400
12611 +++ linux-2.6.25.10/drivers/input/serio/i8042-x86ia64io.h 2008-07-03 16:53:26.000000000 -0400
12612 @@ -118,7 +118,7 @@ static struct dmi_system_id __initdata i
12613 DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
12617 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12621 @@ -284,7 +284,7 @@ static struct dmi_system_id __initdata i
12622 DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
12626 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12630 diff -urNp linux-2.6.25.10/drivers/input/serio/serio_raw.c linux-2.6.25.10/drivers/input/serio/serio_raw.c
12631 --- linux-2.6.25.10/drivers/input/serio/serio_raw.c 2008-07-02 23:46:47.000000000 -0400
12632 +++ linux-2.6.25.10/drivers/input/serio/serio_raw.c 2008-07-03 16:53:26.000000000 -0400
12633 @@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
12635 .extra = SERIO_ANY,
12641 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
12642 diff -urNp linux-2.6.25.10/drivers/md/bitmap.c linux-2.6.25.10/drivers/md/bitmap.c
12643 --- linux-2.6.25.10/drivers/md/bitmap.c 2008-07-02 23:46:47.000000000 -0400
12644 +++ linux-2.6.25.10/drivers/md/bitmap.c 2008-07-03 16:53:26.000000000 -0400
12647 # define PRINTK(x...) printk(KERN_DEBUG x)
12649 -# define PRINTK(x...)
12650 +# define PRINTK(x...) do {} while (0)
12654 diff -urNp linux-2.6.25.10/drivers/mtd/devices/doc2000.c linux-2.6.25.10/drivers/mtd/devices/doc2000.c
12655 --- linux-2.6.25.10/drivers/mtd/devices/doc2000.c 2008-07-02 23:46:47.000000000 -0400
12656 +++ linux-2.6.25.10/drivers/mtd/devices/doc2000.c 2008-07-03 16:53:26.000000000 -0400
12657 @@ -779,7 +779,7 @@ static int doc_write(struct mtd_info *mt
12659 /* The ECC will not be calculated correctly if less than 512 is written */
12661 - if (len != 0x200 && eccbuf)
12662 + if (len != 0x200)
12663 printk(KERN_WARNING
12664 "ECC needs a full sector write (adr: %lx size %lx)\n",
12665 (long) to, (long) len);
12666 diff -urNp linux-2.6.25.10/drivers/mtd/devices/doc2001.c linux-2.6.25.10/drivers/mtd/devices/doc2001.c
12667 --- linux-2.6.25.10/drivers/mtd/devices/doc2001.c 2008-07-02 23:46:47.000000000 -0400
12668 +++ linux-2.6.25.10/drivers/mtd/devices/doc2001.c 2008-07-03 16:53:26.000000000 -0400
12669 @@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt
12670 /* Don't allow read past end of device */
12671 if (from >= this->totlen)
12676 /* Don't allow a single read to cross a 512-byte block boundary */
12677 if (from + len > ((from | 0x1ff) + 1))
12678 diff -urNp linux-2.6.25.10/drivers/mtd/devices/slram.c linux-2.6.25.10/drivers/mtd/devices/slram.c
12679 --- linux-2.6.25.10/drivers/mtd/devices/slram.c 2008-07-02 23:46:47.000000000 -0400
12680 +++ linux-2.6.25.10/drivers/mtd/devices/slram.c 2008-07-03 16:53:26.000000000 -0400
12681 @@ -270,7 +270,7 @@ static int parse_cmdline(char *devname,
12683 T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
12684 devname, devstart, devlength);
12685 - if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
12686 + if (devlength % SLRAM_BLK_SZ != 0) {
12687 E("slram: Illegal start / length parameter.\n");
12690 diff -urNp linux-2.6.25.10/drivers/mtd/ubi/build.c linux-2.6.25.10/drivers/mtd/ubi/build.c
12691 --- linux-2.6.25.10/drivers/mtd/ubi/build.c 2008-07-02 23:46:47.000000000 -0400
12692 +++ linux-2.6.25.10/drivers/mtd/ubi/build.c 2008-07-03 16:53:26.000000000 -0400
12693 @@ -1059,7 +1059,7 @@ static int __init bytes_str_to_int(const
12694 unsigned long result;
12696 result = simple_strtoul(str, &endp, 0);
12697 - if (str == endp || result < 0) {
12698 + if (str == endp) {
12699 printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
12702 diff -urNp linux-2.6.25.10/drivers/net/eepro100.c linux-2.6.25.10/drivers/net/eepro100.c
12703 --- linux-2.6.25.10/drivers/net/eepro100.c 2008-07-02 23:46:47.000000000 -0400
12704 +++ linux-2.6.25.10/drivers/net/eepro100.c 2008-07-03 16:53:26.000000000 -0400
12705 @@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
12706 # define rx_align(skb) skb_reserve((skb), 2)
12707 # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
12709 -# define rx_align(skb)
12710 +# define rx_align(skb) do {} while (0)
12711 # define RxFD_ALIGNMENT
12714 @@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
12717 static struct pci_device_id eepro100_pci_tbl[] = {
12718 - { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
12719 - { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
12720 - { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
12721 - { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
12722 - { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
12723 - { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
12724 - { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
12725 - { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
12726 - { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
12727 - { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
12728 - { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
12729 - { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
12730 - { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
12731 - { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
12732 - { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
12733 - { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
12734 - { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
12735 - { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
12736 - { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
12737 - { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
12738 - { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
12739 - { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
12740 - { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
12741 - { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
12742 - { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
12743 - { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
12745 + { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12746 + { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12747 + { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12748 + { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12749 + { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12750 + { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12751 + { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12752 + { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12753 + { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12754 + { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12755 + { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12756 + { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12757 + { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12758 + { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12759 + { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12760 + { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12761 + { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12762 + { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12763 + { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12764 + { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12765 + { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12766 + { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12767 + { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12768 + { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12769 + { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12770 + { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12771 + { 0, 0, 0, 0, 0, 0, 0 }
12773 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
12775 diff -urNp linux-2.6.25.10/drivers/net/irda/vlsi_ir.c linux-2.6.25.10/drivers/net/irda/vlsi_ir.c
12776 --- linux-2.6.25.10/drivers/net/irda/vlsi_ir.c 2008-07-02 23:46:47.000000000 -0400
12777 +++ linux-2.6.25.10/drivers/net/irda/vlsi_ir.c 2008-07-03 16:53:26.000000000 -0400
12778 @@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
12779 /* no race - tx-ring already empty */
12780 vlsi_set_baud(idev, iobase);
12781 netif_wake_queue(ndev);
12786 /* keep the speed change pending like it would
12787 * for any len>0 packet. tx completion interrupt
12788 * will apply it when the tx ring becomes empty.
12791 spin_unlock_irqrestore(&idev->lock, flags);
12792 dev_kfree_skb_any(skb);
12794 diff -urNp linux-2.6.25.10/drivers/net/pcnet32.c linux-2.6.25.10/drivers/net/pcnet32.c
12795 --- linux-2.6.25.10/drivers/net/pcnet32.c 2008-07-02 23:46:47.000000000 -0400
12796 +++ linux-2.6.25.10/drivers/net/pcnet32.c 2008-07-03 16:53:26.000000000 -0400
12797 @@ -82,7 +82,7 @@ static int cards_found;
12799 * VLB I/O addresses
12801 -static unsigned int pcnet32_portlist[] __initdata =
12802 +static unsigned int pcnet32_portlist[] __devinitdata =
12803 { 0x300, 0x320, 0x340, 0x360, 0 };
12805 static int pcnet32_debug = 0;
12806 diff -urNp linux-2.6.25.10/drivers/net/tg3.h linux-2.6.25.10/drivers/net/tg3.h
12807 --- linux-2.6.25.10/drivers/net/tg3.h 2008-07-02 23:46:47.000000000 -0400
12808 +++ linux-2.6.25.10/drivers/net/tg3.h 2008-07-03 16:53:26.000000000 -0400
12809 @@ -102,6 +102,7 @@
12810 #define CHIPREV_ID_5750_A0 0x4000
12811 #define CHIPREV_ID_5750_A1 0x4001
12812 #define CHIPREV_ID_5750_A3 0x4003
12813 +#define CHIPREV_ID_5750_C1 0x4201
12814 #define CHIPREV_ID_5750_C2 0x4202
12815 #define CHIPREV_ID_5752_A0_HW 0x5000
12816 #define CHIPREV_ID_5752_A0 0x6000
12817 diff -urNp linux-2.6.25.10/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.25.10/drivers/pci/hotplug/cpqphp_nvram.c
12818 --- linux-2.6.25.10/drivers/pci/hotplug/cpqphp_nvram.c 2008-07-02 23:46:47.000000000 -0400
12819 +++ linux-2.6.25.10/drivers/pci/hotplug/cpqphp_nvram.c 2008-07-03 16:53:26.000000000 -0400
12820 @@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
12822 void compaq_nvram_init (void __iomem *rom_start)
12825 +#ifndef CONFIG_PAX_KERNEXEC
12827 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
12831 dbg("int15 entry = %p\n", compaq_int15_entry_point);
12833 /* initialize our int15 lock */
12834 diff -urNp linux-2.6.25.10/drivers/pci/pcie/aer/aerdrv.c linux-2.6.25.10/drivers/pci/pcie/aer/aerdrv.c
12835 --- linux-2.6.25.10/drivers/pci/pcie/aer/aerdrv.c 2008-07-02 23:46:47.000000000 -0400
12836 +++ linux-2.6.25.10/drivers/pci/pcie/aer/aerdrv.c 2008-07-03 16:53:26.000000000 -0400
12837 @@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
12838 .port_type = PCIE_RC_PORT,
12839 .service_type = PCIE_PORT_SERVICE_AER,
12841 - { /* end: all zeroes */ }
12842 + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
12845 static struct pci_error_handlers aer_error_handlers = {
12846 diff -urNp linux-2.6.25.10/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.25.10/drivers/pci/pcie/aer/aerdrv_core.c
12847 --- linux-2.6.25.10/drivers/pci/pcie/aer/aerdrv_core.c 2008-07-02 23:46:47.000000000 -0400
12848 +++ linux-2.6.25.10/drivers/pci/pcie/aer/aerdrv_core.c 2008-07-03 16:53:26.000000000 -0400
12849 @@ -661,7 +661,7 @@ static void aer_isr_one_error(struct pci
12850 struct aer_err_source *e_src)
12852 struct device *s_device;
12853 - struct aer_err_info e_info = {0, 0, 0,};
12854 + struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
12858 diff -urNp linux-2.6.25.10/drivers/pci/pcie/portdrv_pci.c linux-2.6.25.10/drivers/pci/pcie/portdrv_pci.c
12859 --- linux-2.6.25.10/drivers/pci/pcie/portdrv_pci.c 2008-07-02 23:46:47.000000000 -0400
12860 +++ linux-2.6.25.10/drivers/pci/pcie/portdrv_pci.c 2008-07-03 16:53:26.000000000 -0400
12861 @@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
12862 static const struct pci_device_id port_pci_ids[] = { {
12863 /* handle any PCI-Express port */
12864 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
12865 - }, { /* end: all zeroes */ }
12866 + }, { 0, 0, 0, 0, 0, 0, 0 }
12868 MODULE_DEVICE_TABLE(pci, port_pci_ids);
12870 diff -urNp linux-2.6.25.10/drivers/pci/proc.c linux-2.6.25.10/drivers/pci/proc.c
12871 --- linux-2.6.25.10/drivers/pci/proc.c 2008-07-02 23:46:47.000000000 -0400
12872 +++ linux-2.6.25.10/drivers/pci/proc.c 2008-07-03 16:53:26.000000000 -0400
12873 @@ -472,7 +472,15 @@ static int __init pci_proc_init(void)
12875 struct proc_dir_entry *entry;
12876 struct pci_dev *dev = NULL;
12877 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
12878 +#ifdef CONFIG_GRKERNSEC_PROC_USER
12879 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
12880 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
12881 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
12884 proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
12886 entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
12888 entry->proc_fops = &proc_bus_pci_dev_operations;
12889 diff -urNp linux-2.6.25.10/drivers/pcmcia/ti113x.h linux-2.6.25.10/drivers/pcmcia/ti113x.h
12890 --- linux-2.6.25.10/drivers/pcmcia/ti113x.h 2008-07-02 23:46:47.000000000 -0400
12891 +++ linux-2.6.25.10/drivers/pcmcia/ti113x.h 2008-07-03 16:53:26.000000000 -0400
12892 @@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
12893 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
12894 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
12897 + { 0, 0, 0, 0, 0, 0, 0 }
12900 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
12901 diff -urNp linux-2.6.25.10/drivers/pcmcia/yenta_socket.c linux-2.6.25.10/drivers/pcmcia/yenta_socket.c
12902 --- linux-2.6.25.10/drivers/pcmcia/yenta_socket.c 2008-07-02 23:46:47.000000000 -0400
12903 +++ linux-2.6.25.10/drivers/pcmcia/yenta_socket.c 2008-07-03 16:53:26.000000000 -0400
12904 @@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
12906 /* match any cardbus bridge */
12907 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
12908 - { /* all zeroes */ }
12909 + { 0, 0, 0, 0, 0, 0, 0 }
12911 MODULE_DEVICE_TABLE(pci, yenta_table);
12913 diff -urNp linux-2.6.25.10/drivers/pnp/pnpbios/bioscalls.c linux-2.6.25.10/drivers/pnp/pnpbios/bioscalls.c
12914 --- linux-2.6.25.10/drivers/pnp/pnpbios/bioscalls.c 2008-07-02 23:46:47.000000000 -0400
12915 +++ linux-2.6.25.10/drivers/pnp/pnpbios/bioscalls.c 2008-07-03 16:53:26.000000000 -0400
12916 @@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
12917 set_limit(gdt[(selname) >> 3], size); \
12920 -static struct desc_struct bad_bios_desc;
12921 +static struct desc_struct bad_bios_desc __read_only;
12924 * At some point we want to use this stack frame pointer to unwind
12925 @@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func
12926 struct desc_struct save_desc_40;
12929 +#ifdef CONFIG_PAX_KERNEXEC
12930 + unsigned long cr0;
12934 * PnP BIOSes are generally not terribly re-entrant.
12935 * Also, don't rely on them to save everything correctly.
12936 @@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func
12939 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
12941 +#ifdef CONFIG_PAX_KERNEXEC
12942 + pax_open_kernel(cr0);
12945 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
12947 +#ifdef CONFIG_PAX_KERNEXEC
12948 + pax_close_kernel(cr0);
12951 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
12952 spin_lock_irqsave(&pnp_bios_lock, flags);
12954 @@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func
12956 spin_unlock_irqrestore(&pnp_bios_lock, flags);
12958 +#ifdef CONFIG_PAX_KERNEXEC
12959 + pax_open_kernel(cr0);
12962 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
12964 +#ifdef CONFIG_PAX_KERNEXEC
12965 + pax_close_kernel(cr0);
12970 /* If we get here and this is set then the PnP BIOS faulted on us. */
12971 @@ -469,16 +491,24 @@ int pnp_bios_read_escd(char *data, u32 n
12975 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
12976 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
12980 +#ifdef CONFIG_PAX_KERNEXEC
12981 + unsigned long cr0;
12984 spin_lock_init(&pnp_bios_lock);
12985 pnp_bios_callpoint.offset = header->fields.pm16offset;
12986 pnp_bios_callpoint.segment = PNP_CS16;
12988 +#ifdef CONFIG_PAX_KERNEXEC
12989 + pax_open_kernel(cr0);
12992 bad_bios_desc.a = 0;
12993 - bad_bios_desc.b = 0x00409200;
12994 + bad_bios_desc.b = 0x00409300;
12996 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
12997 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
12998 @@ -492,4 +522,9 @@ void pnpbios_calls_init(union pnp_bios_i
12999 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
13000 __va(header->fields.pm16dseg));
13003 +#ifdef CONFIG_PAX_KERNEXEC
13004 + pax_close_kernel(cr0);
13008 diff -urNp linux-2.6.25.10/drivers/pnp/quirks.c linux-2.6.25.10/drivers/pnp/quirks.c
13009 --- linux-2.6.25.10/drivers/pnp/quirks.c 2008-07-02 23:46:47.000000000 -0400
13010 +++ linux-2.6.25.10/drivers/pnp/quirks.c 2008-07-03 16:53:26.000000000 -0400
13011 @@ -201,7 +201,7 @@ static struct pnp_fixup pnp_fixups[] = {
13012 {"CTL0045", quirk_sb16audio_resources},
13013 {"PNP0c01", quirk_system_pci_resources},
13014 {"PNP0c02", quirk_system_pci_resources},
13019 void pnp_fixup_device(struct pnp_dev *dev)
13020 diff -urNp linux-2.6.25.10/drivers/pnp/resource.c linux-2.6.25.10/drivers/pnp/resource.c
13021 --- linux-2.6.25.10/drivers/pnp/resource.c 2008-07-02 23:46:47.000000000 -0400
13022 +++ linux-2.6.25.10/drivers/pnp/resource.c 2008-07-03 16:53:26.000000000 -0400
13023 @@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i
13026 /* check if the resource is valid */
13027 - if (*irq < 0 || *irq > 15)
13031 /* check if the resource is reserved */
13032 @@ -414,7 +414,7 @@ int pnp_check_dma(struct pnp_dev *dev, i
13035 /* check if the resource is valid */
13036 - if (*dma < 0 || *dma == 4 || *dma > 7)
13037 + if (*dma == 4 || *dma > 7)
13040 /* check if the resource is reserved */
13041 diff -urNp linux-2.6.25.10/drivers/scsi/scsi_logging.h linux-2.6.25.10/drivers/scsi/scsi_logging.h
13042 --- linux-2.6.25.10/drivers/scsi/scsi_logging.h 2008-07-02 23:46:47.000000000 -0400
13043 +++ linux-2.6.25.10/drivers/scsi/scsi_logging.h 2008-07-03 16:53:26.000000000 -0400
13044 @@ -51,7 +51,7 @@ do { \
13048 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
13049 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
13050 #endif /* CONFIG_SCSI_LOGGING */
13053 diff -urNp linux-2.6.25.10/drivers/serial/8250_pci.c linux-2.6.25.10/drivers/serial/8250_pci.c
13054 --- linux-2.6.25.10/drivers/serial/8250_pci.c 2008-07-02 23:46:47.000000000 -0400
13055 +++ linux-2.6.25.10/drivers/serial/8250_pci.c 2008-07-03 16:53:26.000000000 -0400
13056 @@ -2837,7 +2837,7 @@ static struct pci_device_id serial_pci_t
13057 PCI_ANY_ID, PCI_ANY_ID,
13058 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
13059 0xffff00, pbn_default },
13061 + { 0, 0, 0, 0, 0, 0, 0 }
13064 static struct pci_driver serial_pci_driver = {
13065 diff -urNp linux-2.6.25.10/drivers/usb/class/cdc-acm.c linux-2.6.25.10/drivers/usb/class/cdc-acm.c
13066 --- linux-2.6.25.10/drivers/usb/class/cdc-acm.c 2008-07-02 23:46:47.000000000 -0400
13067 +++ linux-2.6.25.10/drivers/usb/class/cdc-acm.c 2008-07-03 16:53:26.000000000 -0400
13068 @@ -1261,7 +1261,7 @@ static struct usb_device_id acm_ids[] =
13069 USB_CDC_ACM_PROTO_AT_CDMA) },
13071 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
13073 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13076 MODULE_DEVICE_TABLE (usb, acm_ids);
13077 diff -urNp linux-2.6.25.10/drivers/usb/class/usblp.c linux-2.6.25.10/drivers/usb/class/usblp.c
13078 --- linux-2.6.25.10/drivers/usb/class/usblp.c 2008-07-02 23:46:47.000000000 -0400
13079 +++ linux-2.6.25.10/drivers/usb/class/usblp.c 2008-07-03 16:53:26.000000000 -0400
13080 @@ -227,7 +227,7 @@ static const struct quirk_printer_struct
13081 { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
13082 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
13083 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
13088 static int usblp_wwait(struct usblp *usblp, int nonblock);
13089 @@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
13090 { USB_INTERFACE_INFO(7, 1, 2) },
13091 { USB_INTERFACE_INFO(7, 1, 3) },
13092 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
13093 - { } /* Terminating entry */
13094 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13097 MODULE_DEVICE_TABLE (usb, usblp_ids);
13098 diff -urNp linux-2.6.25.10/drivers/usb/core/hub.c linux-2.6.25.10/drivers/usb/core/hub.c
13099 --- linux-2.6.25.10/drivers/usb/core/hub.c 2008-07-02 23:46:47.000000000 -0400
13100 +++ linux-2.6.25.10/drivers/usb/core/hub.c 2008-07-03 16:53:26.000000000 -0400
13101 @@ -2909,7 +2909,7 @@ static struct usb_device_id hub_id_table
13102 .bDeviceClass = USB_CLASS_HUB},
13103 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
13104 .bInterfaceClass = USB_CLASS_HUB},
13105 - { } /* Terminating entry */
13106 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13109 MODULE_DEVICE_TABLE (usb, hub_id_table);
13110 diff -urNp linux-2.6.25.10/drivers/usb/host/ehci-pci.c linux-2.6.25.10/drivers/usb/host/ehci-pci.c
13111 --- linux-2.6.25.10/drivers/usb/host/ehci-pci.c 2008-07-02 23:46:47.000000000 -0400
13112 +++ linux-2.6.25.10/drivers/usb/host/ehci-pci.c 2008-07-03 16:53:26.000000000 -0400
13113 @@ -389,7 +389,7 @@ static const struct pci_device_id pci_id
13114 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
13115 .driver_data = (unsigned long) &ehci_pci_hc_driver,
13117 - { /* end: all zeroes */ }
13118 + { 0, 0, 0, 0, 0, 0, 0 }
13120 MODULE_DEVICE_TABLE(pci, pci_ids);
13122 diff -urNp linux-2.6.25.10/drivers/usb/host/uhci-hcd.c linux-2.6.25.10/drivers/usb/host/uhci-hcd.c
13123 --- linux-2.6.25.10/drivers/usb/host/uhci-hcd.c 2008-07-02 23:46:47.000000000 -0400
13124 +++ linux-2.6.25.10/drivers/usb/host/uhci-hcd.c 2008-07-03 16:53:26.000000000 -0400
13125 @@ -893,7 +893,7 @@ static const struct pci_device_id uhci_p
13126 /* handle any USB UHCI controller */
13127 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
13128 .driver_data = (unsigned long) &uhci_driver,
13129 - }, { /* end: all zeroes */ }
13130 + }, { 0, 0, 0, 0, 0, 0, 0 }
13133 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
13134 diff -urNp linux-2.6.25.10/drivers/usb/storage/debug.h linux-2.6.25.10/drivers/usb/storage/debug.h
13135 --- linux-2.6.25.10/drivers/usb/storage/debug.h 2008-07-02 23:46:47.000000000 -0400
13136 +++ linux-2.6.25.10/drivers/usb/storage/debug.h 2008-07-03 16:53:26.000000000 -0400
13137 @@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
13138 #define US_DEBUGPX(x...) printk( x )
13139 #define US_DEBUG(x) x
13141 -#define US_DEBUGP(x...)
13142 -#define US_DEBUGPX(x...)
13143 -#define US_DEBUG(x)
13144 +#define US_DEBUGP(x...) do {} while (0)
13145 +#define US_DEBUGPX(x...) do {} while (0)
13146 +#define US_DEBUG(x) do {} while (0)
13150 diff -urNp linux-2.6.25.10/drivers/usb/storage/usb.c linux-2.6.25.10/drivers/usb/storage/usb.c
13151 --- linux-2.6.25.10/drivers/usb/storage/usb.c 2008-07-02 23:46:47.000000000 -0400
13152 +++ linux-2.6.25.10/drivers/usb/storage/usb.c 2008-07-03 16:53:26.000000000 -0400
13153 @@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_
13156 /* Terminating entry */
13158 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13161 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
13162 @@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_
13165 /* Terminating entry */
13167 + { NULL, NULL, 0, 0, NULL }
13171 diff -urNp linux-2.6.25.10/drivers/video/fbcmap.c linux-2.6.25.10/drivers/video/fbcmap.c
13172 --- linux-2.6.25.10/drivers/video/fbcmap.c 2008-07-02 23:46:47.000000000 -0400
13173 +++ linux-2.6.25.10/drivers/video/fbcmap.c 2008-07-03 16:53:26.000000000 -0400
13174 @@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
13175 int rc, size = cmap->len * sizeof(u16);
13176 struct fb_cmap umap;
13178 - if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
13179 - !info->fbops->fb_setcmap))
13180 + if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
13183 memset(&umap, 0, sizeof(struct fb_cmap));
13184 diff -urNp linux-2.6.25.10/drivers/video/fbmem.c linux-2.6.25.10/drivers/video/fbmem.c
13185 --- linux-2.6.25.10/drivers/video/fbmem.c 2008-07-02 23:46:47.000000000 -0400
13186 +++ linux-2.6.25.10/drivers/video/fbmem.c 2008-07-03 16:53:26.000000000 -0400
13187 @@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in
13188 image->dx += image->width + 8;
13190 } else if (rotate == FB_ROTATE_UD) {
13191 - for (x = 0; x < num && image->dx >= 0; x++) {
13192 + for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
13193 info->fbops->fb_imageblit(info, image);
13194 image->dx -= image->width + 8;
13196 @@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in
13197 image->dy += image->height + 8;
13199 } else if (rotate == FB_ROTATE_CCW) {
13200 - for (x = 0; x < num && image->dy >= 0; x++) {
13201 + for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
13202 info->fbops->fb_imageblit(info, image);
13203 image->dy -= image->height + 8;
13205 @@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil
13206 case FBIOPUT_CON2FBMAP:
13207 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
13209 - if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
13210 + if (con2fb.console > MAX_NR_CONSOLES)
13212 - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
13213 + if (con2fb.framebuffer >= FB_MAX)
13216 if (!registered_fb[con2fb.framebuffer])
13217 diff -urNp linux-2.6.25.10/drivers/video/fbmon.c linux-2.6.25.10/drivers/video/fbmon.c
13218 --- linux-2.6.25.10/drivers/video/fbmon.c 2008-07-02 23:46:47.000000000 -0400
13219 +++ linux-2.6.25.10/drivers/video/fbmon.c 2008-07-03 16:53:26.000000000 -0400
13222 #define DPRINTK(fmt, args...) printk(fmt,## args)
13224 -#define DPRINTK(fmt, args...)
13225 +#define DPRINTK(fmt, args...) do {} while (0)
13228 #define FBMON_FIX_HEADER 1
13229 diff -urNp linux-2.6.25.10/drivers/video/i810/i810_accel.c linux-2.6.25.10/drivers/video/i810/i810_accel.c
13230 --- linux-2.6.25.10/drivers/video/i810/i810_accel.c 2008-07-02 23:46:47.000000000 -0400
13231 +++ linux-2.6.25.10/drivers/video/i810/i810_accel.c 2008-07-03 16:53:26.000000000 -0400
13232 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct
13235 printk("ringbuffer lockup!!!\n");
13236 + printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
13237 i810_report_error(mmio);
13238 par->dev_flags |= LOCKUP;
13239 info->pixmap.scan_align = 1;
13240 diff -urNp linux-2.6.25.10/drivers/video/i810/i810_main.c linux-2.6.25.10/drivers/video/i810/i810_main.c
13241 --- linux-2.6.25.10/drivers/video/i810/i810_main.c 2008-07-02 23:46:47.000000000 -0400
13242 +++ linux-2.6.25.10/drivers/video/i810/i810_main.c 2008-07-03 16:53:26.000000000 -0400
13243 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
13244 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
13245 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
13246 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
13248 + { 0, 0, 0, 0, 0, 0, 0 },
13251 static struct pci_driver i810fb_driver = {
13252 @@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
13253 int size = ((cursor->image.width + 7) >> 3) *
13254 cursor->image.height;
13256 - u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
13257 + u8 *data = kmalloc(64 * 8, GFP_KERNEL);
13261 diff -urNp linux-2.6.25.10/drivers/video/modedb.c linux-2.6.25.10/drivers/video/modedb.c
13262 --- linux-2.6.25.10/drivers/video/modedb.c 2008-07-02 23:46:47.000000000 -0400
13263 +++ linux-2.6.25.10/drivers/video/modedb.c 2008-07-03 16:53:26.000000000 -0400
13264 @@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
13266 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
13267 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
13268 - 0, FB_VMODE_NONINTERLACED
13269 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13271 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
13272 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
13273 - 0, FB_VMODE_NONINTERLACED
13274 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13276 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
13277 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
13278 - 0, FB_VMODE_NONINTERLACED
13279 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13281 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
13282 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
13283 - 0, FB_VMODE_INTERLACED
13284 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13286 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
13287 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
13288 - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13289 + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13291 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
13292 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
13293 - 0, FB_VMODE_NONINTERLACED
13294 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13296 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
13297 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
13298 - 0, FB_VMODE_NONINTERLACED
13299 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13301 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
13302 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
13303 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13304 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13306 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
13307 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
13308 - 0, FB_VMODE_NONINTERLACED
13309 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13311 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
13312 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
13313 - 0, FB_VMODE_INTERLACED
13314 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13316 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
13317 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
13318 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13319 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13321 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
13322 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
13323 - 0, FB_VMODE_NONINTERLACED
13324 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13326 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
13327 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
13328 - 0, FB_VMODE_NONINTERLACED
13329 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13331 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
13332 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
13333 - 0, FB_VMODE_NONINTERLACED
13334 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13336 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
13337 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
13338 - 0, FB_VMODE_NONINTERLACED
13339 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13341 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
13342 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
13343 - 0, FB_VMODE_NONINTERLACED
13344 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13346 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
13347 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
13348 - 0, FB_VMODE_INTERLACED
13349 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13351 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
13352 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
13353 - 0, FB_VMODE_NONINTERLACED
13354 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13356 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
13357 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
13358 - 0, FB_VMODE_NONINTERLACED
13359 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13361 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
13362 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
13363 - 0, FB_VMODE_NONINTERLACED
13364 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13366 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
13367 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
13368 - 0, FB_VMODE_NONINTERLACED
13369 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13371 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
13372 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
13373 - 0, FB_VMODE_NONINTERLACED
13374 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13376 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
13377 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
13378 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13379 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13381 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
13382 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
13383 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13384 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13386 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
13387 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
13388 - 0, FB_VMODE_NONINTERLACED
13389 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13391 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
13392 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
13393 - 0, FB_VMODE_NONINTERLACED
13394 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13396 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
13397 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
13398 - 0, FB_VMODE_NONINTERLACED
13399 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13401 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
13402 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
13403 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13404 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13406 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
13407 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
13408 - 0, FB_VMODE_NONINTERLACED
13409 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13411 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
13412 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
13413 - 0, FB_VMODE_NONINTERLACED
13414 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13416 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
13417 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
13418 - 0, FB_VMODE_NONINTERLACED
13419 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13421 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
13422 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
13423 - 0, FB_VMODE_NONINTERLACED
13424 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13426 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
13427 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
13428 - 0, FB_VMODE_NONINTERLACED
13429 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13431 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
13432 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
13433 - 0, FB_VMODE_NONINTERLACED
13434 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13436 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
13437 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
13438 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13439 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13441 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
13442 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
13443 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13444 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13446 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
13447 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
13448 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13449 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13451 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
13452 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
13453 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13454 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13456 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
13457 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
13458 - 0, FB_VMODE_NONINTERLACED
13459 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13461 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
13462 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
13463 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13464 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13466 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
13467 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
13468 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13469 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13471 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
13472 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
13473 - 0, FB_VMODE_NONINTERLACED
13474 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13476 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
13477 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
13478 - 0, FB_VMODE_NONINTERLACED
13479 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13481 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
13482 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
13483 - 0, FB_VMODE_DOUBLE
13484 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13486 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
13487 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
13488 - 0, FB_VMODE_DOUBLE
13489 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13491 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
13492 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
13493 - 0, FB_VMODE_DOUBLE
13494 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13496 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
13497 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
13498 - 0, FB_VMODE_DOUBLE
13499 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13501 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
13502 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
13503 - 0, FB_VMODE_DOUBLE
13504 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13506 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
13507 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
13508 - 0, FB_VMODE_DOUBLE
13509 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13511 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
13512 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
13513 - 0, FB_VMODE_DOUBLE
13514 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13516 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
13517 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
13518 - 0, FB_VMODE_DOUBLE
13519 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13521 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
13522 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
13523 - 0, FB_VMODE_DOUBLE
13524 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13526 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
13527 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
13528 - 0, FB_VMODE_DOUBLE
13529 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13531 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
13532 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
13533 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
13534 - FB_VMODE_NONINTERLACED
13535 + FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13537 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
13538 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
13539 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13540 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13542 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
13543 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
13544 - 0, FB_VMODE_NONINTERLACED
13545 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13547 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
13548 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
13549 - 0, FB_VMODE_NONINTERLACED
13550 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13554 diff -urNp linux-2.6.25.10/drivers/video/uvesafb.c linux-2.6.25.10/drivers/video/uvesafb.c
13555 --- linux-2.6.25.10/drivers/video/uvesafb.c 2008-07-02 23:46:47.000000000 -0400
13556 +++ linux-2.6.25.10/drivers/video/uvesafb.c 2008-07-03 16:53:26.000000000 -0400
13557 @@ -117,7 +117,7 @@ static int uvesafb_helper_start(void)
13561 - return call_usermodehelper(v86d_path, argv, envp, 1);
13562 + return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
13566 diff -urNp linux-2.6.25.10/drivers/video/vesafb.c linux-2.6.25.10/drivers/video/vesafb.c
13567 --- linux-2.6.25.10/drivers/video/vesafb.c 2008-07-02 23:46:47.000000000 -0400
13568 +++ linux-2.6.25.10/drivers/video/vesafb.c 2008-07-03 16:53:26.000000000 -0400
13572 #include <linux/module.h>
13573 +#include <linux/moduleloader.h>
13574 #include <linux/kernel.h>
13575 #include <linux/errno.h>
13576 #include <linux/string.h>
13577 @@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
13578 static int vram_total __initdata; /* Set total amount of memory */
13579 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
13580 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
13581 -static void (*pmi_start)(void) __read_mostly;
13582 -static void (*pmi_pal) (void) __read_mostly;
13583 +static void (*pmi_start)(void) __read_only;
13584 +static void (*pmi_pal) (void) __read_only;
13585 static int depth __read_mostly;
13586 static int vga_compat __read_mostly;
13587 /* --------------------------------------------------------------------- */
13588 @@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
13589 unsigned int size_vmode;
13590 unsigned int size_remap;
13591 unsigned int size_total;
13592 + void *pmi_code = NULL;
13594 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
13596 @@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
13597 size_remap = size_total;
13598 vesafb_fix.smem_len = size_remap;
13601 - screen_info.vesapm_seg = 0;
13604 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
13605 printk(KERN_WARNING
13606 "vesafb: cannot reserve video memory at 0x%lx\n",
13607 @@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
13608 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
13609 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
13613 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13614 + pmi_code = module_alloc_exec(screen_info.vesapm_size);
13616 +#elif !defined(CONFIG_PAX_KERNEXEC)
13621 + screen_info.vesapm_seg = 0;
13623 if (screen_info.vesapm_seg) {
13624 - printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
13625 - screen_info.vesapm_seg,screen_info.vesapm_off);
13626 + printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
13627 + screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
13630 if (screen_info.vesapm_seg < 0xc000)
13631 @@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
13633 if (ypan || pmi_setpal) {
13634 unsigned short *pmi_base;
13635 - pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13636 - pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
13637 - pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
13639 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13640 + unsigned long cr0;
13643 + pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13645 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13646 + pax_open_kernel(cr0);
13647 + memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
13649 + pmi_code = pmi_base;
13652 + pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
13653 + pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
13655 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13656 + pmi_start = ktva_ktla(pmi_start);
13657 + pmi_pal = ktva_ktla(pmi_pal);
13658 + pax_close_kernel(cr0);
13661 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
13663 printk(KERN_INFO "vesafb: pmi: ports = ");
13664 @@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
13665 info->node, info->fix.id);
13669 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13670 + module_free_exec(NULL, pmi_code);
13673 if (info->screen_base)
13674 iounmap(info->screen_base);
13675 framebuffer_release(info);
13676 diff -urNp linux-2.6.25.10/fs/9p/vfs_inode.c linux-2.6.25.10/fs/9p/vfs_inode.c
13677 --- linux-2.6.25.10/fs/9p/vfs_inode.c 2008-07-02 23:46:47.000000000 -0400
13678 +++ linux-2.6.25.10/fs/9p/vfs_inode.c 2008-07-03 16:53:26.000000000 -0400
13679 @@ -1001,7 +1001,7 @@ static void *v9fs_vfs_follow_link(struct
13681 static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
13683 - char *s = nd_get_link(nd);
13684 + const char *s = nd_get_link(nd);
13686 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
13688 diff -urNp linux-2.6.25.10/fs/aio.c linux-2.6.25.10/fs/aio.c
13689 --- linux-2.6.25.10/fs/aio.c 2008-07-02 23:46:47.000000000 -0400
13690 +++ linux-2.6.25.10/fs/aio.c 2008-07-03 16:53:26.000000000 -0400
13691 @@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
13692 size += sizeof(struct io_event) * nr_events;
13693 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
13695 - if (nr_pages < 0)
13696 + if (nr_pages <= 0)
13699 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
13700 diff -urNp linux-2.6.25.10/fs/autofs4/symlink.c linux-2.6.25.10/fs/autofs4/symlink.c
13701 --- linux-2.6.25.10/fs/autofs4/symlink.c 2008-07-02 23:46:47.000000000 -0400
13702 +++ linux-2.6.25.10/fs/autofs4/symlink.c 2008-07-03 16:53:26.000000000 -0400
13704 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
13706 struct autofs_info *ino = autofs4_dentry_ino(dentry);
13707 - nd_set_link(nd, (char *)ino->u.symlink);
13708 + nd_set_link(nd, ino->u.symlink);
13712 diff -urNp linux-2.6.25.10/fs/befs/linuxvfs.c linux-2.6.25.10/fs/befs/linuxvfs.c
13713 --- linux-2.6.25.10/fs/befs/linuxvfs.c 2008-07-02 23:46:47.000000000 -0400
13714 +++ linux-2.6.25.10/fs/befs/linuxvfs.c 2008-07-03 16:53:26.000000000 -0400
13715 @@ -489,7 +489,7 @@ static void befs_put_link(struct dentry
13717 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
13718 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
13719 - char *p = nd_get_link(nd);
13720 + const char *p = nd_get_link(nd);
13724 diff -urNp linux-2.6.25.10/fs/binfmt_aout.c linux-2.6.25.10/fs/binfmt_aout.c
13725 --- linux-2.6.25.10/fs/binfmt_aout.c 2008-07-02 23:46:47.000000000 -0400
13726 +++ linux-2.6.25.10/fs/binfmt_aout.c 2008-07-03 16:53:26.000000000 -0400
13728 #include <linux/personality.h>
13729 #include <linux/init.h>
13730 #include <linux/vs_memory.h>
13731 +#include <linux/grsecurity.h>
13733 #include <asm/system.h>
13734 #include <asm/uaccess.h>
13735 @@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
13736 /* If the size of the dump file exceeds the rlimit, then see what would happen
13737 if we wrote the stack, but not the data area. */
13739 + gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
13740 if ((dump.u_dsize + dump.u_ssize) > limit)
13743 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
13744 if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
13748 /* Make sure we have enough room to write the stack and data areas. */
13750 + gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
13751 if (dump.u_ssize > limit)
13754 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
13755 if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
13758 @@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
13759 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
13760 if (rlim >= RLIM_INFINITY)
13763 + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
13764 if (ex.a_data + ex.a_bss > rlim)
13767 @@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
13769 compute_creds(bprm);
13770 current->flags &= ~PF_FORKNOEXEC;
13772 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13773 + current->mm->pax_flags = 0UL;
13776 +#ifdef CONFIG_PAX_PAGEEXEC
13777 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
13778 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
13780 +#ifdef CONFIG_PAX_EMUTRAMP
13781 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
13782 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
13785 +#ifdef CONFIG_PAX_MPROTECT
13786 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
13787 + current->mm->pax_flags |= MF_PAX_MPROTECT;
13794 if (N_MAGIC(ex) == NMAGIC) {
13795 loff_t pos = fd_offset;
13796 @@ -417,7 +446,7 @@ static int load_aout_binary(struct linux
13798 down_write(¤t->mm->mmap_sem);
13799 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
13800 - PROT_READ | PROT_WRITE | PROT_EXEC,
13801 + PROT_READ | PROT_WRITE,
13802 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
13803 fd_offset + ex.a_text);
13804 up_write(¤t->mm->mmap_sem);
13805 diff -urNp linux-2.6.25.10/fs/binfmt_elf.c linux-2.6.25.10/fs/binfmt_elf.c
13806 --- linux-2.6.25.10/fs/binfmt_elf.c 2008-07-02 23:46:47.000000000 -0400
13807 +++ linux-2.6.25.10/fs/binfmt_elf.c 2008-07-03 16:53:26.000000000 -0400
13808 @@ -39,10 +39,16 @@
13809 #include <linux/elf.h>
13810 #include <linux/utsname.h>
13811 #include <linux/vs_memory.h>
13812 +#include <linux/grsecurity.h>
13814 #include <asm/uaccess.h>
13815 #include <asm/param.h>
13816 #include <asm/page.h>
13818 +#ifdef CONFIG_PAX_SEGMEXEC
13819 +#include <asm/desc.h>
13822 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
13823 static int load_elf_library(struct file *);
13824 static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
13825 @@ -85,6 +91,8 @@ static struct linux_binfmt elf_format =
13827 static int set_brk(unsigned long start, unsigned long end)
13829 + unsigned long e = end;
13831 start = ELF_PAGEALIGN(start);
13832 end = ELF_PAGEALIGN(end);
13834 @@ -95,7 +103,7 @@ static int set_brk(unsigned long start,
13835 if (BAD_ADDR(addr))
13838 - current->mm->start_brk = current->mm->brk = end;
13839 + current->mm->start_brk = current->mm->brk = e;
13843 @@ -352,10 +360,10 @@ static unsigned long load_elf_interp(str
13845 struct elf_phdr *elf_phdata;
13846 struct elf_phdr *eppnt;
13847 - unsigned long load_addr = 0;
13848 + unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
13849 int load_addr_set = 0;
13850 unsigned long last_bss = 0, elf_bss = 0;
13851 - unsigned long error = ~0UL;
13852 + unsigned long error = -EINVAL;
13853 unsigned long total_size;
13854 int retval, i, size;
13856 @@ -401,6 +409,11 @@ static unsigned long load_elf_interp(str
13860 +#ifdef CONFIG_PAX_SEGMEXEC
13861 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
13862 + pax_task_size = SEGMEXEC_TASK_SIZE;
13865 eppnt = elf_phdata;
13866 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
13867 if (eppnt->p_type == PT_LOAD) {
13868 @@ -444,8 +457,8 @@ static unsigned long load_elf_interp(str
13869 k = load_addr + eppnt->p_vaddr;
13871 eppnt->p_filesz > eppnt->p_memsz ||
13872 - eppnt->p_memsz > TASK_SIZE ||
13873 - TASK_SIZE - eppnt->p_memsz < k) {
13874 + eppnt->p_memsz > pax_task_size ||
13875 + pax_task_size - eppnt->p_memsz < k) {
13879 @@ -499,6 +512,177 @@ out:
13883 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
13884 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
13886 + unsigned long pax_flags = 0UL;
13888 +#ifdef CONFIG_PAX_PAGEEXEC
13889 + if (elf_phdata->p_flags & PF_PAGEEXEC)
13890 + pax_flags |= MF_PAX_PAGEEXEC;
13893 +#ifdef CONFIG_PAX_SEGMEXEC
13894 + if (elf_phdata->p_flags & PF_SEGMEXEC)
13895 + pax_flags |= MF_PAX_SEGMEXEC;
13898 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
13899 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13901 + pax_flags &= ~MF_PAX_SEGMEXEC;
13903 + pax_flags &= ~MF_PAX_PAGEEXEC;
13907 +#ifdef CONFIG_PAX_EMUTRAMP
13908 + if (elf_phdata->p_flags & PF_EMUTRAMP)
13909 + pax_flags |= MF_PAX_EMUTRAMP;
13912 +#ifdef CONFIG_PAX_MPROTECT
13913 + if (elf_phdata->p_flags & PF_MPROTECT)
13914 + pax_flags |= MF_PAX_MPROTECT;
13917 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
13918 + if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
13919 + pax_flags |= MF_PAX_RANDMMAP;
13922 + return pax_flags;
13926 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
13927 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
13929 + unsigned long pax_flags = 0UL;
13931 +#ifdef CONFIG_PAX_PAGEEXEC
13932 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
13933 + pax_flags |= MF_PAX_PAGEEXEC;
13936 +#ifdef CONFIG_PAX_SEGMEXEC
13937 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
13938 + pax_flags |= MF_PAX_SEGMEXEC;
13941 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
13942 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13944 + pax_flags &= ~MF_PAX_SEGMEXEC;
13946 + pax_flags &= ~MF_PAX_PAGEEXEC;
13950 +#ifdef CONFIG_PAX_EMUTRAMP
13951 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
13952 + pax_flags |= MF_PAX_EMUTRAMP;
13955 +#ifdef CONFIG_PAX_MPROTECT
13956 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
13957 + pax_flags |= MF_PAX_MPROTECT;
13960 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
13961 + if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
13962 + pax_flags |= MF_PAX_RANDMMAP;
13965 + return pax_flags;
13969 +#ifdef CONFIG_PAX_EI_PAX
13970 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
13972 + unsigned long pax_flags = 0UL;
13974 +#ifdef CONFIG_PAX_PAGEEXEC
13975 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
13976 + pax_flags |= MF_PAX_PAGEEXEC;
13979 +#ifdef CONFIG_PAX_SEGMEXEC
13980 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
13981 + pax_flags |= MF_PAX_SEGMEXEC;
13984 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
13985 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13987 + pax_flags &= ~MF_PAX_SEGMEXEC;
13989 + pax_flags &= ~MF_PAX_PAGEEXEC;
13993 +#ifdef CONFIG_PAX_EMUTRAMP
13994 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
13995 + pax_flags |= MF_PAX_EMUTRAMP;
13998 +#ifdef CONFIG_PAX_MPROTECT
13999 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
14000 + pax_flags |= MF_PAX_MPROTECT;
14003 +#ifdef CONFIG_PAX_ASLR
14004 + if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
14005 + pax_flags |= MF_PAX_RANDMMAP;
14008 + return pax_flags;
14012 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14013 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
14015 + unsigned long pax_flags = 0UL;
14017 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14021 +#ifdef CONFIG_PAX_EI_PAX
14022 + pax_flags = pax_parse_ei_pax(elf_ex);
14025 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14026 + for (i = 0UL; i < elf_ex->e_phnum; i++)
14027 + if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
14028 + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
14029 + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
14030 + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
14031 + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
14032 + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
14035 +#ifdef CONFIG_PAX_SOFTMODE
14036 + if (pax_softmode)
14037 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
14041 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
14046 + if (0 > pax_check_flags(&pax_flags))
14049 + current->mm->pax_flags = pax_flags;
14055 * These are the functions used to load ELF style executables and shared
14056 * libraries. There is no binary dependent code anywhere else.
14057 @@ -515,6 +699,11 @@ static unsigned long randomize_stack_top
14059 unsigned int random_variable = 0;
14061 +#ifdef CONFIG_PAX_RANDUSTACK
14062 + if (randomize_va_space)
14063 + return stack_top - current->mm->delta_stack;
14066 if ((current->flags & PF_RANDOMIZE) &&
14067 !(current->personality & ADDR_NO_RANDOMIZE)) {
14068 random_variable = get_random_int() & STACK_RND_MASK;
14069 @@ -533,7 +722,7 @@ static int load_elf_binary(struct linux_
14070 unsigned long load_addr = 0, load_bias = 0;
14071 int load_addr_set = 0;
14072 char * elf_interpreter = NULL;
14073 - unsigned long error;
14074 + unsigned long error = 0;
14075 struct elf_phdr *elf_ppnt, *elf_phdata;
14076 unsigned long elf_bss, elf_brk;
14077 int elf_exec_fileno;
14078 @@ -545,12 +734,12 @@ static int load_elf_binary(struct linux_
14079 unsigned long reloc_func_desc = 0;
14080 struct files_struct *files;
14081 int executable_stack = EXSTACK_DEFAULT;
14082 - unsigned long def_flags = 0;
14084 struct elfhdr elf_ex;
14085 struct elfhdr interp_elf_ex;
14086 struct exec interp_ex;
14088 + unsigned long pax_task_size = TASK_SIZE;
14090 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
14092 @@ -736,7 +925,73 @@ static int load_elf_binary(struct linux_
14094 /* OK, This is the point of no return */
14095 current->flags &= ~PF_FORKNOEXEC;
14096 - current->mm->def_flags = def_flags;
14098 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14099 + current->mm->pax_flags = 0UL;
14102 +#ifdef CONFIG_PAX_DLRESOLVE
14103 + current->mm->call_dl_resolve = 0UL;
14106 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
14107 + current->mm->call_syscall = 0UL;
14110 +#ifdef CONFIG_PAX_ASLR
14111 + current->mm->delta_mmap = 0UL;
14112 + current->mm->delta_stack = 0UL;
14115 + current->mm->def_flags = 0;
14117 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14118 + if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
14119 + send_sig(SIGKILL, current, 0);
14120 + goto out_free_dentry;
14124 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14125 + pax_set_initial_flags(bprm);
14126 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
14127 + if (pax_set_initial_flags_func)
14128 + (pax_set_initial_flags_func)(bprm);
14131 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14132 + if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
14133 + current->mm->context.user_cs_limit = PAGE_SIZE;
14134 + current->mm->def_flags |= VM_PAGEEXEC;
14138 +#ifdef CONFIG_PAX_SEGMEXEC
14139 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
14140 + current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
14141 + current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
14142 + pax_task_size = SEGMEXEC_TASK_SIZE;
14146 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
14147 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14148 + set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
14149 + put_cpu_no_resched();
14153 +#ifdef CONFIG_PAX_ASLR
14154 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
14155 + current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
14156 + current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
14160 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14161 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14162 + executable_stack = EXSTACK_DEFAULT;
14165 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
14166 may depend on the personality. */
14167 @@ -821,6 +1076,20 @@ static int load_elf_binary(struct linux_
14169 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
14172 +#ifdef CONFIG_PAX_RANDMMAP
14173 + /* PaX: randomize base address at the default exe base if requested */
14174 + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
14175 +#ifdef CONFIG_SPARC64
14176 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
14178 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
14180 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
14181 + elf_flags |= MAP_FIXED;
14187 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
14188 @@ -853,9 +1122,9 @@ static int load_elf_binary(struct linux_
14189 * allowed task size. Note that p_filesz must always be
14190 * <= p_memsz so it is only necessary to check p_memsz.
14192 - if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14193 - elf_ppnt->p_memsz > TASK_SIZE ||
14194 - TASK_SIZE - elf_ppnt->p_memsz < k) {
14195 + if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14196 + elf_ppnt->p_memsz > pax_task_size ||
14197 + pax_task_size - elf_ppnt->p_memsz < k) {
14198 /* set_brk can never work. Avoid overflows. */
14199 send_sig(SIGKILL, current, 0);
14201 @@ -883,6 +1152,11 @@ static int load_elf_binary(struct linux_
14202 start_data += load_bias;
14203 end_data += load_bias;
14205 +#ifdef CONFIG_PAX_RANDMMAP
14206 + if (current->mm->pax_flags & MF_PAX_RANDMMAP)
14207 + elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
14210 /* Calling set_brk effectively mmaps the pages that we need
14211 * for the bss and break sections. We must do this before
14212 * mapping in the interpreter, to make sure it doesn't wind
14213 @@ -894,9 +1168,11 @@ static int load_elf_binary(struct linux_
14214 goto out_free_dentry;
14216 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
14217 - send_sig(SIGSEGV, current, 0);
14218 - retval = -EFAULT; /* Nobody gets to see this, but.. */
14219 - goto out_free_dentry;
14221 + * This bss-zeroing can fail if the ELF
14222 + * file specifies odd protections. So
14223 + * we don't check the return value
14227 if (elf_interpreter) {
14228 @@ -1142,8 +1418,10 @@ static int dump_seek(struct file *file,
14229 unsigned long n = off;
14232 - if (!dump_write(file, buf, n))
14233 + if (!dump_write(file, buf, n)) {
14234 + free_page((unsigned long)buf);
14239 free_page((unsigned long)buf);
14240 @@ -1155,7 +1433,7 @@ static int dump_seek(struct file *file,
14241 * Decide what to dump of a segment, part, all or none.
14243 static unsigned long vma_dump_size(struct vm_area_struct *vma,
14244 - unsigned long mm_flags)
14245 + unsigned long mm_flags, long signr)
14247 /* The vma can be set up to tell us the answer directly. */
14248 if (vma->vm_flags & VM_ALWAYSDUMP)
14249 @@ -1181,7 +1459,7 @@ static unsigned long vma_dump_size(struc
14250 if (vma->vm_file == NULL)
14253 - if (FILTER(MAPPED_PRIVATE))
14254 + if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
14258 @@ -1267,8 +1545,11 @@ static int writenote(struct memelfnote *
14261 #define DUMP_WRITE(addr, nr) \
14263 + gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
14264 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
14265 - goto end_coredump;
14266 + goto end_coredump; \
14268 #define DUMP_SEEK(off) \
14269 if (!dump_seek(file, (off))) \
14271 @@ -1985,7 +2266,7 @@ static int elf_core_dump(long signr, str
14272 phdr.p_offset = offset;
14273 phdr.p_vaddr = vma->vm_start;
14275 - phdr.p_filesz = vma_dump_size(vma, mm_flags);
14276 + phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
14277 phdr.p_memsz = vma->vm_end - vma->vm_start;
14278 offset += phdr.p_filesz;
14279 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
14280 @@ -2017,7 +2298,7 @@ static int elf_core_dump(long signr, str
14281 unsigned long addr;
14284 - end = vma->vm_start + vma_dump_size(vma, mm_flags);
14285 + end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
14287 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
14289 @@ -2037,6 +2318,7 @@ static int elf_core_dump(long signr, str
14290 flush_cache_page(vma, addr,
14291 page_to_pfn(page));
14292 kaddr = kmap(page);
14293 + gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
14294 if ((size += PAGE_SIZE) > limit ||
14295 !dump_write(file, kaddr,
14297 diff -urNp linux-2.6.25.10/fs/binfmt_flat.c linux-2.6.25.10/fs/binfmt_flat.c
14298 --- linux-2.6.25.10/fs/binfmt_flat.c 2008-07-02 23:46:47.000000000 -0400
14299 +++ linux-2.6.25.10/fs/binfmt_flat.c 2008-07-03 16:53:26.000000000 -0400
14300 @@ -560,7 +560,9 @@ static int load_flat_file(struct linux_b
14301 realdatastart = (unsigned long) -ENOMEM;
14302 printk("Unable to allocate RAM for process data, errno %d\n",
14303 (int)-realdatastart);
14304 + down_write(¤t->mm->mmap_sem);
14305 do_munmap(current->mm, textpos, text_len);
14306 + up_write(¤t->mm->mmap_sem);
14307 ret = realdatastart;
14310 @@ -582,8 +584,10 @@ static int load_flat_file(struct linux_b
14312 if (result >= (unsigned long)-4096) {
14313 printk("Unable to read data+bss, errno %d\n", (int)-result);
14314 + down_write(¤t->mm->mmap_sem);
14315 do_munmap(current->mm, textpos, text_len);
14316 do_munmap(current->mm, realdatastart, data_len + extra);
14317 + up_write(¤t->mm->mmap_sem);
14321 @@ -656,8 +660,10 @@ static int load_flat_file(struct linux_b
14323 if (result >= (unsigned long)-4096) {
14324 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
14325 + down_write(¤t->mm->mmap_sem);
14326 do_munmap(current->mm, textpos, text_len + data_len + extra +
14327 MAX_SHARED_LIBS * sizeof(unsigned long));
14328 + up_write(¤t->mm->mmap_sem);
14332 diff -urNp linux-2.6.25.10/fs/binfmt_misc.c linux-2.6.25.10/fs/binfmt_misc.c
14333 --- linux-2.6.25.10/fs/binfmt_misc.c 2008-07-02 23:46:47.000000000 -0400
14334 +++ linux-2.6.25.10/fs/binfmt_misc.c 2008-07-03 16:53:26.000000000 -0400
14335 @@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
14336 struct files_struct *files = NULL;
14340 + if (!enabled || bprm->misc)
14345 /* to keep locking time low, we copy the interpreter string */
14346 read_lock(&entries_lock);
14347 fmt = check_file(bprm);
14348 @@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl
14349 static struct tree_descr bm_files[] = {
14350 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
14351 [3] = {"register", &bm_register_operations, S_IWUSR},
14352 - /* last one */ {""}
14353 + /* last one */ {"", NULL, 0}
14355 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
14357 diff -urNp linux-2.6.25.10/fs/buffer.c linux-2.6.25.10/fs/buffer.c
14358 --- linux-2.6.25.10/fs/buffer.c 2008-07-02 23:46:47.000000000 -0400
14359 +++ linux-2.6.25.10/fs/buffer.c 2008-07-03 16:53:26.000000000 -0400
14361 #include <linux/bitops.h>
14362 #include <linux/mpage.h>
14363 #include <linux/bit_spinlock.h>
14364 +#include <linux/grsecurity.h>
14366 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
14368 @@ -2188,6 +2189,7 @@ int generic_cont_expand_simple(struct in
14371 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
14372 + gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
14373 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
14374 send_sig(SIGXFSZ, current, 0);
14376 diff -urNp linux-2.6.25.10/fs/cifs/cifs_uniupr.h linux-2.6.25.10/fs/cifs/cifs_uniupr.h
14377 --- linux-2.6.25.10/fs/cifs/cifs_uniupr.h 2008-07-02 23:46:47.000000000 -0400
14378 +++ linux-2.6.25.10/fs/cifs/cifs_uniupr.h 2008-07-03 16:53:26.000000000 -0400
14379 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
14380 {0x0490, 0x04cc, UniCaseRangeU0490},
14381 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
14382 {0xff40, 0xff5a, UniCaseRangeUff40},
14388 diff -urNp linux-2.6.25.10/fs/cifs/link.c linux-2.6.25.10/fs/cifs/link.c
14389 --- linux-2.6.25.10/fs/cifs/link.c 2008-07-02 23:46:47.000000000 -0400
14390 +++ linux-2.6.25.10/fs/cifs/link.c 2008-07-03 16:53:26.000000000 -0400
14391 @@ -355,7 +355,7 @@ cifs_readlink(struct dentry *direntry, c
14393 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
14395 - char *p = nd_get_link(nd);
14396 + const char *p = nd_get_link(nd);
14400 diff -urNp linux-2.6.25.10/fs/compat.c linux-2.6.25.10/fs/compat.c
14401 --- linux-2.6.25.10/fs/compat.c 2008-07-02 23:46:47.000000000 -0400
14402 +++ linux-2.6.25.10/fs/compat.c 2008-07-03 16:53:26.000000000 -0400
14404 #include <linux/poll.h>
14405 #include <linux/mm.h>
14406 #include <linux/eventpoll.h>
14407 +#include <linux/grsecurity.h>
14409 #include <asm/uaccess.h>
14410 #include <asm/mmu_context.h>
14411 @@ -1293,14 +1294,12 @@ static int compat_copy_strings(int argc,
14412 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
14415 -#ifdef CONFIG_STACK_GROWSUP
14416 ret = expand_stack_downwards(bprm->vma, pos);
14418 /* We've exceed the stack rlimit. */
14423 ret = get_user_pages(current, bprm->mm, pos,
14424 1, 1, 1, &page, NULL);
14426 @@ -1346,6 +1345,11 @@ int compat_do_execve(char * filename,
14427 compat_uptr_t __user *envp,
14428 struct pt_regs * regs)
14430 +#ifdef CONFIG_GRKERNSEC
14431 + struct file *old_exec_file;
14432 + struct acl_subject_label *old_acl;
14433 + struct rlimit old_rlim[RLIM_NLIMITS];
14435 struct linux_binprm *bprm;
14438 @@ -1366,6 +1370,14 @@ int compat_do_execve(char * filename,
14439 bprm->filename = filename;
14440 bprm->interp = filename;
14442 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
14443 + retval = -EAGAIN;
14444 + if (gr_handle_nproc())
14446 + retval = -EACCES;
14447 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
14450 retval = bprm_mm_init(bprm);
14453 @@ -1399,8 +1411,36 @@ int compat_do_execve(char * filename,
14457 + if (!gr_tpe_allow(file)) {
14458 + retval = -EACCES;
14462 + if (gr_check_crash_exec(file)) {
14463 + retval = -EACCES;
14467 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14469 + gr_handle_exec_args(bprm, (char __user * __user *)argv);
14471 +#ifdef CONFIG_GRKERNSEC
14472 + old_acl = current->acl;
14473 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14474 + old_exec_file = current->exec_file;
14476 + current->exec_file = file;
14479 + gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14481 retval = search_binary_handler(bprm, regs);
14483 +#ifdef CONFIG_GRKERNSEC
14484 + if (old_exec_file)
14485 + fput(old_exec_file);
14487 /* execve success */
14488 security_bprm_free(bprm);
14489 acct_update_integrals(current);
14490 @@ -1408,6 +1448,13 @@ int compat_do_execve(char * filename,
14494 +#ifdef CONFIG_GRKERNSEC
14495 + current->acl = old_acl;
14496 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14497 + fput(current->exec_file);
14498 + current->exec_file = old_exec_file;
14502 if (bprm->security)
14503 security_bprm_free(bprm);
14504 diff -urNp linux-2.6.25.10/fs/compat_ioctl.c linux-2.6.25.10/fs/compat_ioctl.c
14505 --- linux-2.6.25.10/fs/compat_ioctl.c 2008-07-02 23:46:47.000000000 -0400
14506 +++ linux-2.6.25.10/fs/compat_ioctl.c 2008-07-03 16:53:26.000000000 -0400
14507 @@ -1889,15 +1889,15 @@ struct ioctl_trans {
14510 #define HANDLE_IOCTL(cmd,handler) \
14511 - { (cmd), (ioctl_trans_handler_t)(handler) },
14512 + { (cmd), (ioctl_trans_handler_t)(handler), NULL },
14514 /* pointer to compatible structure or no argument */
14515 #define COMPATIBLE_IOCTL(cmd) \
14516 - { (cmd), do_ioctl32_pointer },
14517 + { (cmd), do_ioctl32_pointer, NULL },
14519 /* argument is an unsigned long integer, not a pointer */
14520 #define ULONG_IOCTL(cmd) \
14521 - { (cmd), (ioctl_trans_handler_t)sys_ioctl },
14522 + { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
14524 /* ioctl should not be warned about even if it's not implemented.
14525 Valid reasons to use this:
14526 diff -urNp linux-2.6.25.10/fs/debugfs/inode.c linux-2.6.25.10/fs/debugfs/inode.c
14527 --- linux-2.6.25.10/fs/debugfs/inode.c 2008-07-02 23:46:47.000000000 -0400
14528 +++ linux-2.6.25.10/fs/debugfs/inode.c 2008-07-03 16:53:26.000000000 -0400
14529 @@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
14531 static int debug_fill_super(struct super_block *sb, void *data, int silent)
14533 - static struct tree_descr debug_files[] = {{""}};
14534 + static struct tree_descr debug_files[] = {{"", NULL, 0}};
14536 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
14538 diff -urNp linux-2.6.25.10/fs/exec.c linux-2.6.25.10/fs/exec.c
14539 --- linux-2.6.25.10/fs/exec.c 2008-07-02 23:46:47.000000000 -0400
14540 +++ linux-2.6.25.10/fs/exec.c 2008-07-03 16:53:26.000000000 -0400
14542 #include <linux/tsacct_kern.h>
14543 #include <linux/cn_proc.h>
14544 #include <linux/audit.h>
14545 +#include <linux/random.h>
14546 +#include <linux/grsecurity.h>
14548 #include <asm/uaccess.h>
14549 #include <asm/mmu_context.h>
14551 #include <linux/kmod.h>
14554 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
14555 +void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
14556 +EXPORT_SYMBOL(pax_set_initial_flags_func);
14560 char core_pattern[CORENAME_MAX_SIZE] = "core";
14561 int suid_dumpable = 0;
14562 @@ -158,18 +165,10 @@ static struct page *get_arg_page(struct
14568 -#ifdef CONFIG_STACK_GROWSUP
14570 - ret = expand_stack_downwards(bprm->vma, pos);
14575 - ret = get_user_pages(current, bprm->mm, pos,
14576 - 1, write, 1, &page, NULL);
14578 + if (0 > expand_stack_downwards(bprm->vma, pos))
14580 + if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
14584 @@ -242,6 +241,11 @@ static int __bprm_mm_init(struct linux_b
14585 vma->vm_start = vma->vm_end - PAGE_SIZE;
14587 vma->vm_flags = VM_STACK_FLAGS;
14589 +#ifdef CONFIG_PAX_SEGMEXEC
14590 + vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
14593 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
14594 err = insert_vm_struct(mm, vma);
14596 @@ -254,6 +258,11 @@ static int __bprm_mm_init(struct linux_b
14598 bprm->p = vma->vm_end - sizeof(void *);
14600 +#ifdef CONFIG_PAX_RANDUSTACK
14601 + if (randomize_va_space)
14602 + bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
14608 @@ -377,7 +386,7 @@ static int count(char __user * __user *
14617 @@ -517,6 +526,10 @@ static int shift_arg_pages(struct vm_are
14618 if (vma != find_vma(mm, new_start))
14621 +#ifdef CONFIG_PAX_SEGMEXEC
14622 + BUG_ON(pax_find_mirror_vma(vma));
14626 * cover the whole range: [new_start, old_end)
14628 @@ -605,8 +618,20 @@ int setup_arg_pages(struct linux_binprm
14629 bprm->exec -= stack_shift;
14631 down_write(&mm->mmap_sem);
14633 + /* Move stack pages down in memory. */
14634 + if (stack_shift) {
14635 + ret = shift_arg_pages(vma, stack_shift);
14640 vm_flags = vma->vm_flags;
14642 +#ifdef CONFIG_PAX_SEGMEXEC
14643 + vm_flags |= VM_STACK_FLAGS & (VM_EXEC | VM_MAYEXEC);
14647 * Adjust stack execute permissions; explicitly enable for
14648 * EXSTACK_ENABLE_X, disable for EXSTACK_DISABLE_X and leave alone
14649 @@ -618,21 +643,24 @@ int setup_arg_pages(struct linux_binprm
14650 vm_flags &= ~VM_EXEC;
14651 vm_flags |= mm->def_flags;
14653 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14654 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14655 + vm_flags &= ~VM_EXEC;
14657 +#ifdef CONFIG_PAX_MPROTECT
14658 + if (mm->pax_flags & MF_PAX_MPROTECT)
14659 + vm_flags &= ~VM_MAYEXEC;
14665 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
14669 BUG_ON(prev != vma);
14671 - /* Move stack pages down in memory. */
14672 - if (stack_shift) {
14673 - ret = shift_arg_pages(vma, stack_shift);
14675 - up_write(&mm->mmap_sem);
14680 #ifdef CONFIG_STACK_GROWSUP
14681 stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
14683 @@ -644,7 +672,7 @@ int setup_arg_pages(struct linux_binprm
14686 up_write(&mm->mmap_sem);
14690 EXPORT_SYMBOL(setup_arg_pages);
14692 @@ -663,7 +691,7 @@ struct file *open_exec(const char *name)
14693 struct inode *inode = nd.path.dentry->d_inode;
14694 file = ERR_PTR(-EACCES);
14695 if (S_ISREG(inode->i_mode)) {
14696 - int err = vfs_permission(&nd, MAY_EXEC);
14697 + err = vfs_permission(&nd, MAY_EXEC);
14698 file = ERR_PTR(err);
14700 file = nameidata_to_filp(&nd,
14701 @@ -1280,6 +1308,11 @@ int do_execve(char * filename,
14702 char __user *__user *envp,
14703 struct pt_regs * regs)
14705 +#ifdef CONFIG_GRKERNSEC
14706 + struct file *old_exec_file;
14707 + struct acl_subject_label *old_acl;
14708 + struct rlimit old_rlim[RLIM_NLIMITS];
14710 struct linux_binprm *bprm;
14712 unsigned long env_p;
14713 @@ -1295,6 +1328,20 @@ int do_execve(char * filename,
14717 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
14719 + if (gr_handle_nproc()) {
14720 + allow_write_access(file);
14725 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
14726 + allow_write_access(file);
14734 @@ -1336,8 +1383,38 @@ int do_execve(char * filename,
14736 bprm->argv_len = env_p - bprm->p;
14738 + if (!gr_tpe_allow(file)) {
14739 + retval = -EACCES;
14743 + if (gr_check_crash_exec(file)) {
14744 + retval = -EACCES;
14748 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14750 + gr_handle_exec_args(bprm, argv);
14752 +#ifdef CONFIG_GRKERNSEC
14753 + old_acl = current->acl;
14754 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14755 + old_exec_file = current->exec_file;
14757 + current->exec_file = file;
14760 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14764 retval = search_binary_handler(bprm,regs);
14766 +#ifdef CONFIG_GRKERNSEC
14767 + if (old_exec_file)
14768 + fput(old_exec_file);
14770 /* execve success */
14771 free_arg_pages(bprm);
14772 security_bprm_free(bprm);
14773 @@ -1346,6 +1423,14 @@ int do_execve(char * filename,
14778 +#ifdef CONFIG_GRKERNSEC
14779 + current->acl = old_acl;
14780 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14781 + fput(current->exec_file);
14782 + current->exec_file = old_exec_file;
14786 free_arg_pages(bprm);
14787 if (bprm->security)
14788 @@ -1510,6 +1595,116 @@ out:
14792 +int pax_check_flags(unsigned long *flags)
14796 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
14797 + if (*flags & MF_PAX_SEGMEXEC)
14799 + *flags &= ~MF_PAX_SEGMEXEC;
14800 + retval = -EINVAL;
14804 + if ((*flags & MF_PAX_PAGEEXEC)
14806 +#ifdef CONFIG_PAX_PAGEEXEC
14807 + && (*flags & MF_PAX_SEGMEXEC)
14812 + *flags &= ~MF_PAX_PAGEEXEC;
14813 + retval = -EINVAL;
14816 + if ((*flags & MF_PAX_MPROTECT)
14818 +#ifdef CONFIG_PAX_MPROTECT
14819 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14824 + *flags &= ~MF_PAX_MPROTECT;
14825 + retval = -EINVAL;
14828 + if ((*flags & MF_PAX_EMUTRAMP)
14830 +#ifdef CONFIG_PAX_EMUTRAMP
14831 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14836 + *flags &= ~MF_PAX_EMUTRAMP;
14837 + retval = -EINVAL;
14843 +EXPORT_SYMBOL(pax_check_flags);
14845 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14846 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
14848 + struct task_struct *tsk = current;
14849 + struct mm_struct *mm = current->mm;
14850 + char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
14851 + char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
14852 + char *path_exec = NULL;
14853 + char *path_fault = NULL;
14854 + unsigned long start = 0UL, end = 0UL, offset = 0UL;
14856 + if (buffer_exec && buffer_fault) {
14857 + struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
14859 + down_read(&mm->mmap_sem);
14861 + while (vma && (!vma_exec || !vma_fault)) {
14862 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
14864 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
14866 + vma = vma->vm_next;
14869 + struct path path = {vma_exec->vm_file->f_path.mnt, vma_exec->vm_file->f_path.dentry};
14870 + path_exec = d_path(&path, buffer_exec, PAGE_SIZE);
14871 + if (IS_ERR(path_exec))
14872 + path_exec = "<path too long>";
14875 + start = vma_fault->vm_start;
14876 + end = vma_fault->vm_end;
14877 + offset = vma_fault->vm_pgoff << PAGE_SHIFT;
14878 + if (vma_fault->vm_file) {
14879 + struct path path = {vma_fault->vm_file->f_path.mnt, vma_fault->vm_file->f_path.dentry};
14880 + path_fault = d_path(&path, buffer_fault, PAGE_SIZE);
14881 + if (IS_ERR(path_fault))
14882 + path_fault = "<path too long>";
14884 + path_fault = "<anonymous mapping>";
14886 + up_read(&mm->mmap_sem);
14888 + if (tsk->signal->curr_ip)
14889 + 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);
14891 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
14892 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
14893 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
14894 + tsk->uid, tsk->euid, pc, sp);
14895 + free_page((unsigned long)buffer_exec);
14896 + free_page((unsigned long)buffer_fault);
14897 + pax_report_insns(pc, sp);
14898 + do_coredump(SIGKILL, SIGKILL, regs);
14902 static void zap_process(struct task_struct *start)
14904 struct task_struct *t;
14905 @@ -1707,6 +1902,10 @@ int do_coredump(long signr, int exit_cod
14907 clear_thread_flag(TIF_SIGPENDING);
14909 + if (signr == SIGKILL || signr == SIGILL)
14910 + gr_handle_brute_attach(current);
14911 + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
14914 * lock_kernel() because format_corename() is controlled by sysctl, which
14915 * uses lock_kernel()
14916 @@ -1727,6 +1926,8 @@ int do_coredump(long signr, int exit_cod
14919 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
14920 + if (!helper_argv)
14921 + goto fail_unlock;
14922 /* Terminate the string before the first option */
14923 delimit = strchr(corename, ' ');
14925 diff -urNp linux-2.6.25.10/fs/ext2/balloc.c linux-2.6.25.10/fs/ext2/balloc.c
14926 --- linux-2.6.25.10/fs/ext2/balloc.c 2008-07-02 23:46:47.000000000 -0400
14927 +++ linux-2.6.25.10/fs/ext2/balloc.c 2008-07-03 16:53:26.000000000 -0400
14928 @@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
14930 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
14931 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
14932 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
14933 + if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
14934 sbi->s_resuid != current->fsuid &&
14935 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
14937 diff -urNp linux-2.6.25.10/fs/ext3/balloc.c linux-2.6.25.10/fs/ext3/balloc.c
14938 --- linux-2.6.25.10/fs/ext3/balloc.c 2008-07-02 23:46:47.000000000 -0400
14939 +++ linux-2.6.25.10/fs/ext3/balloc.c 2008-07-03 16:53:26.000000000 -0400
14940 @@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
14943 cond = (free_blocks < root_blocks + 1 &&
14944 - !capable(CAP_SYS_RESOURCE) &&
14945 + !capable_nolog(CAP_SYS_RESOURCE) &&
14946 sbi->s_resuid != current->fsuid &&
14947 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
14949 diff -urNp linux-2.6.25.10/fs/ext3/namei.c linux-2.6.25.10/fs/ext3/namei.c
14950 --- linux-2.6.25.10/fs/ext3/namei.c 2008-07-02 23:46:47.000000000 -0400
14951 +++ linux-2.6.25.10/fs/ext3/namei.c 2008-07-03 16:53:26.000000000 -0400
14952 @@ -1166,9 +1166,9 @@ static struct ext3_dir_entry_2 *do_split
14954 struct dx_map_entry *map;
14955 char *data1 = (*bh)->b_data, *data2;
14956 - unsigned split, move, size, i;
14957 + unsigned split, move, size;
14958 struct ext3_dir_entry_2 *de = NULL, *de2;
14962 bh2 = ext3_append (handle, dir, &newblock, &err);
14964 diff -urNp linux-2.6.25.10/fs/ext3/xattr.c linux-2.6.25.10/fs/ext3/xattr.c
14965 --- linux-2.6.25.10/fs/ext3/xattr.c 2008-07-02 23:46:47.000000000 -0400
14966 +++ linux-2.6.25.10/fs/ext3/xattr.c 2008-07-03 16:53:26.000000000 -0400
14971 -# define ea_idebug(f...)
14972 -# define ea_bdebug(f...)
14973 +# define ea_idebug(f...) do {} while (0)
14974 +# define ea_bdebug(f...) do {} while (0)
14977 static void ext3_xattr_cache_insert(struct buffer_head *);
14978 diff -urNp linux-2.6.25.10/fs/ext4/balloc.c linux-2.6.25.10/fs/ext4/balloc.c
14979 --- linux-2.6.25.10/fs/ext4/balloc.c 2008-07-02 23:46:47.000000000 -0400
14980 +++ linux-2.6.25.10/fs/ext4/balloc.c 2008-07-03 16:53:26.000000000 -0400
14981 @@ -1557,7 +1557,7 @@ static int ext4_has_free_blocks(struct e
14984 cond = (free_blocks < root_blocks + 1 &&
14985 - !capable(CAP_SYS_RESOURCE) &&
14986 + !capable_nolog(CAP_SYS_RESOURCE) &&
14987 sbi->s_resuid != current->fsuid &&
14988 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
14990 diff -urNp linux-2.6.25.10/fs/ext4/namei.c linux-2.6.25.10/fs/ext4/namei.c
14991 --- linux-2.6.25.10/fs/ext4/namei.c 2008-07-02 23:46:47.000000000 -0400
14992 +++ linux-2.6.25.10/fs/ext4/namei.c 2008-07-03 16:53:26.000000000 -0400
14993 @@ -1168,9 +1168,9 @@ static struct ext4_dir_entry_2 *do_split
14995 struct dx_map_entry *map;
14996 char *data1 = (*bh)->b_data, *data2;
14997 - unsigned split, move, size, i;
14998 + unsigned split, move, size;
14999 struct ext4_dir_entry_2 *de = NULL, *de2;
15003 bh2 = ext4_append (handle, dir, &newblock, &err);
15005 diff -urNp linux-2.6.25.10/fs/fcntl.c linux-2.6.25.10/fs/fcntl.c
15006 --- linux-2.6.25.10/fs/fcntl.c 2008-07-02 23:46:47.000000000 -0400
15007 +++ linux-2.6.25.10/fs/fcntl.c 2008-07-03 16:53:26.000000000 -0400
15009 #include <linux/rcupdate.h>
15010 #include <linux/pid_namespace.h>
15011 #include <linux/vs_limit.h>
15012 +#include <linux/grsecurity.h>
15014 #include <asm/poll.h>
15015 #include <asm/siginfo.h>
15016 @@ -64,6 +65,7 @@ static int locate_fd(struct files_struct
15017 struct fdtable *fdt;
15020 + gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
15021 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15024 @@ -83,6 +85,7 @@ repeat:
15025 fdt->max_fds, start);
15028 + gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
15029 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15032 @@ -144,6 +147,8 @@ asmlinkage long sys_dup2(unsigned int ol
15033 struct files_struct * files = current->files;
15034 struct fdtable *fdt;
15036 + gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
15038 spin_lock(&files->file_lock);
15039 if (!(file = fcheck(oldfd)))
15041 @@ -463,7 +468,8 @@ static inline int sigio_perm(struct task
15042 return (((fown->euid == 0) ||
15043 (fown->euid == p->suid) || (fown->euid == p->uid) ||
15044 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
15045 - !security_file_send_sigiotask(p, fown, sig));
15046 + !security_file_send_sigiotask(p, fown, sig) &&
15047 + !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
15050 static void send_sigio_to_task(struct task_struct *p,
15051 diff -urNp linux-2.6.25.10/fs/fuse/control.c linux-2.6.25.10/fs/fuse/control.c
15052 --- linux-2.6.25.10/fs/fuse/control.c 2008-07-02 23:46:47.000000000 -0400
15053 +++ linux-2.6.25.10/fs/fuse/control.c 2008-07-03 16:53:26.000000000 -0400
15054 @@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
15056 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
15058 - struct tree_descr empty_descr = {""};
15059 + struct tree_descr empty_descr = {"", NULL, 0};
15060 struct fuse_conn *fc;
15063 diff -urNp linux-2.6.25.10/fs/fuse/dir.c linux-2.6.25.10/fs/fuse/dir.c
15064 --- linux-2.6.25.10/fs/fuse/dir.c 2008-07-02 23:46:47.000000000 -0400
15065 +++ linux-2.6.25.10/fs/fuse/dir.c 2008-07-03 16:53:26.000000000 -0400
15066 @@ -1031,7 +1031,7 @@ static char *read_link(struct dentry *de
15070 -static void free_link(char *link)
15071 +static void free_link(const char *link)
15074 free_page((unsigned long) link);
15075 diff -urNp linux-2.6.25.10/fs/hfs/inode.c linux-2.6.25.10/fs/hfs/inode.c
15076 --- linux-2.6.25.10/fs/hfs/inode.c 2008-07-02 23:46:47.000000000 -0400
15077 +++ linux-2.6.25.10/fs/hfs/inode.c 2008-07-03 16:53:26.000000000 -0400
15078 @@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
15080 if (S_ISDIR(main_inode->i_mode)) {
15081 if (fd.entrylength < sizeof(struct hfs_cat_dir))
15084 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15085 sizeof(struct hfs_cat_dir));
15086 if (rec.type != HFS_CDR_DIR ||
15087 @@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
15088 sizeof(struct hfs_cat_file));
15090 if (fd.entrylength < sizeof(struct hfs_cat_file))
15093 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15094 sizeof(struct hfs_cat_file));
15095 if (rec.type != HFS_CDR_FIL ||
15096 diff -urNp linux-2.6.25.10/fs/hfsplus/inode.c linux-2.6.25.10/fs/hfsplus/inode.c
15097 --- linux-2.6.25.10/fs/hfsplus/inode.c 2008-07-02 23:46:47.000000000 -0400
15098 +++ linux-2.6.25.10/fs/hfsplus/inode.c 2008-07-03 16:53:26.000000000 -0400
15099 @@ -422,7 +422,7 @@ int hfsplus_cat_read_inode(struct inode
15100 struct hfsplus_cat_folder *folder = &entry.folder;
15102 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
15105 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15106 sizeof(struct hfsplus_cat_folder));
15107 hfsplus_get_perms(inode, &folder->permissions, 1);
15108 @@ -439,7 +439,7 @@ int hfsplus_cat_read_inode(struct inode
15109 struct hfsplus_cat_file *file = &entry.file;
15111 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
15114 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15115 sizeof(struct hfsplus_cat_file));
15117 @@ -495,7 +495,7 @@ int hfsplus_cat_write_inode(struct inode
15118 struct hfsplus_cat_folder *folder = &entry.folder;
15120 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
15123 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15124 sizeof(struct hfsplus_cat_folder));
15125 /* simple node checks? */
15126 @@ -517,7 +517,7 @@ int hfsplus_cat_write_inode(struct inode
15127 struct hfsplus_cat_file *file = &entry.file;
15129 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
15132 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15133 sizeof(struct hfsplus_cat_file));
15134 hfsplus_inode_write_fork(inode, &file->data_fork);
15135 diff -urNp linux-2.6.25.10/fs/jffs2/debug.h linux-2.6.25.10/fs/jffs2/debug.h
15136 --- linux-2.6.25.10/fs/jffs2/debug.h 2008-07-02 23:46:47.000000000 -0400
15137 +++ linux-2.6.25.10/fs/jffs2/debug.h 2008-07-03 16:53:26.000000000 -0400
15138 @@ -51,13 +51,13 @@
15139 #if CONFIG_JFFS2_FS_DEBUG > 0
15143 +#define D1(x) do {} while (0);
15146 #if CONFIG_JFFS2_FS_DEBUG > 1
15150 +#define D2(x) do {} while (0);
15153 /* The prefixes of JFFS2 messages */
15154 @@ -113,68 +113,68 @@
15155 #ifdef JFFS2_DBG_READINODE_MESSAGES
15156 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15158 -#define dbg_readinode(fmt, ...)
15159 +#define dbg_readinode(fmt, ...) do {} while (0)
15162 /* Fragtree build debugging messages */
15163 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
15164 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15166 -#define dbg_fragtree(fmt, ...)
15167 +#define dbg_fragtree(fmt, ...) do {} while (0)
15169 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
15170 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15172 -#define dbg_fragtree2(fmt, ...)
15173 +#define dbg_fragtree2(fmt, ...) do {} while (0)
15176 /* Directory entry list manilulation debugging messages */
15177 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
15178 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15180 -#define dbg_dentlist(fmt, ...)
15181 +#define dbg_dentlist(fmt, ...) do {} while (0)
15184 /* Print the messages about manipulating node_refs */
15185 #ifdef JFFS2_DBG_NODEREF_MESSAGES
15186 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15188 -#define dbg_noderef(fmt, ...)
15189 +#define dbg_noderef(fmt, ...) do {} while (0)
15192 /* Manipulations with the list of inodes (JFFS2 inocache) */
15193 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
15194 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15196 -#define dbg_inocache(fmt, ...)
15197 +#define dbg_inocache(fmt, ...) do {} while (0)
15200 /* Summary debugging messages */
15201 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
15202 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15204 -#define dbg_summary(fmt, ...)
15205 +#define dbg_summary(fmt, ...) do {} while (0)
15208 /* File system build messages */
15209 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
15210 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15212 -#define dbg_fsbuild(fmt, ...)
15213 +#define dbg_fsbuild(fmt, ...) do {} while (0)
15216 /* Watch the object allocations */
15217 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
15218 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15220 -#define dbg_memalloc(fmt, ...)
15221 +#define dbg_memalloc(fmt, ...) do {} while (0)
15224 /* Watch the XATTR subsystem */
15225 #ifdef JFFS2_DBG_XATTR_MESSAGES
15226 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15228 -#define dbg_xattr(fmt, ...)
15229 +#define dbg_xattr(fmt, ...) do {} while (0)
15232 /* "Sanity" checks */
15233 diff -urNp linux-2.6.25.10/fs/jffs2/erase.c linux-2.6.25.10/fs/jffs2/erase.c
15234 --- linux-2.6.25.10/fs/jffs2/erase.c 2008-07-02 23:46:47.000000000 -0400
15235 +++ linux-2.6.25.10/fs/jffs2/erase.c 2008-07-03 16:53:26.000000000 -0400
15236 @@ -425,7 +425,8 @@ static void jffs2_mark_erased_block(stru
15237 struct jffs2_unknown_node marker = {
15238 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
15239 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15240 - .totlen = cpu_to_je32(c->cleanmarker_size)
15241 + .totlen = cpu_to_je32(c->cleanmarker_size),
15242 + .hdr_crc = cpu_to_je32(0)
15245 jffs2_prealloc_raw_node_refs(c, jeb, 1);
15246 diff -urNp linux-2.6.25.10/fs/jffs2/summary.h linux-2.6.25.10/fs/jffs2/summary.h
15247 --- linux-2.6.25.10/fs/jffs2/summary.h 2008-07-02 23:46:47.000000000 -0400
15248 +++ linux-2.6.25.10/fs/jffs2/summary.h 2008-07-03 16:53:26.000000000 -0400
15249 @@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
15251 #define jffs2_sum_active() (0)
15252 #define jffs2_sum_init(a) (0)
15253 -#define jffs2_sum_exit(a)
15254 -#define jffs2_sum_disable_collecting(a)
15255 +#define jffs2_sum_exit(a) do {} while (0)
15256 +#define jffs2_sum_disable_collecting(a) do {} while (0)
15257 #define jffs2_sum_is_disabled(a) (0)
15258 -#define jffs2_sum_reset_collected(a)
15259 +#define jffs2_sum_reset_collected(a) do {} while (0)
15260 #define jffs2_sum_add_kvec(a,b,c,d) (0)
15261 -#define jffs2_sum_move_collected(a,b)
15262 +#define jffs2_sum_move_collected(a,b) do {} while (0)
15263 #define jffs2_sum_write_sumnode(a) (0)
15264 -#define jffs2_sum_add_padding_mem(a,b)
15265 -#define jffs2_sum_add_inode_mem(a,b,c)
15266 -#define jffs2_sum_add_dirent_mem(a,b,c)
15267 -#define jffs2_sum_add_xattr_mem(a,b,c)
15268 -#define jffs2_sum_add_xref_mem(a,b,c)
15269 +#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
15270 +#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
15271 +#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
15272 +#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
15273 +#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
15274 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
15276 #endif /* CONFIG_JFFS2_SUMMARY */
15277 diff -urNp linux-2.6.25.10/fs/jffs2/wbuf.c linux-2.6.25.10/fs/jffs2/wbuf.c
15278 --- linux-2.6.25.10/fs/jffs2/wbuf.c 2008-07-02 23:46:47.000000000 -0400
15279 +++ linux-2.6.25.10/fs/jffs2/wbuf.c 2008-07-03 16:53:26.000000000 -0400
15280 @@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
15282 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
15283 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15284 - .totlen = constant_cpu_to_je32(8)
15285 + .totlen = constant_cpu_to_je32(8),
15286 + .hdr_crc = constant_cpu_to_je32(0)
15290 diff -urNp linux-2.6.25.10/fs/Kconfig linux-2.6.25.10/fs/Kconfig
15291 --- linux-2.6.25.10/fs/Kconfig 2008-07-02 23:46:47.000000000 -0400
15292 +++ linux-2.6.25.10/fs/Kconfig 2008-07-03 16:53:26.000000000 -0400
15293 @@ -899,7 +899,7 @@ config PROC_FS
15296 bool "/proc/kcore support" if !ARM
15297 - depends on PROC_FS && MMU
15298 + depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
15301 bool "/proc/vmcore support (EXPERIMENTAL)"
15302 diff -urNp linux-2.6.25.10/fs/namei.c linux-2.6.25.10/fs/namei.c
15303 --- linux-2.6.25.10/fs/namei.c 2008-07-02 23:46:47.000000000 -0400
15304 +++ linux-2.6.25.10/fs/namei.c 2008-07-03 16:53:26.000000000 -0400
15306 #include <linux/vs_cowbl.h>
15307 #include <linux/vs_device.h>
15308 #include <linux/vs_context.h>
15309 +#include <linux/grsecurity.h>
15310 #include <asm/namei.h>
15311 #include <asm/uaccess.h>
15313 @@ -662,7 +663,7 @@ static __always_inline int __do_follow_l
15314 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
15315 error = PTR_ERR(cookie);
15316 if (!IS_ERR(cookie)) {
15317 - char *s = nd_get_link(nd);
15318 + const char *s = nd_get_link(nd);
15321 error = __vfs_follow_link(nd, s);
15322 @@ -693,6 +694,13 @@ static inline int do_follow_link(struct
15323 err = security_inode_follow_link(path->dentry, nd);
15327 + if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
15328 + path->dentry->d_inode, path->dentry, nd->path.mnt)) {
15333 current->link_count++;
15334 current->total_link_count++;
15336 @@ -1041,11 +1049,18 @@ return_reval:
15340 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
15341 + path_put(&nd->path);
15346 path_put_conditional(&next, nd);
15349 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
15352 path_put(&nd->path);
15355 @@ -1683,9 +1698,17 @@ static int open_namei_create(struct name
15357 struct dentry *dir = nd->path.dentry;
15359 + if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
15361 + goto out_unlock_dput;
15364 if (!IS_POSIXACL(dir->d_inode))
15365 mode &= ~current->fs->umask;
15366 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
15368 + gr_handle_create(path->dentry, nd->path.mnt);
15370 mutex_unlock(&dir->d_inode->i_mutex);
15371 dput(nd->path.dentry);
15372 nd->path.dentry = path->dentry;
15373 @@ -1736,6 +1759,17 @@ int open_namei(int dfd, const char *path
15378 + if (gr_handle_rawio(nd->path.dentry->d_inode)) {
15383 + if (!gr_acl_handle_open(nd->path.dentry, nd->path.mnt, flag)) {
15391 @@ -1785,6 +1819,23 @@ do_last:
15393 * It already exists.
15396 + if (gr_handle_rawio(path.dentry->d_inode)) {
15397 + mutex_unlock(&dir->d_inode->i_mutex);
15401 + if (!gr_acl_handle_open(path.dentry, nd->path.mnt, flag)) {
15402 + mutex_unlock(&dir->d_inode->i_mutex);
15406 + if (gr_handle_fifo(path.dentry, nd->path.mnt, dir, flag, acc_mode)) {
15407 + mutex_unlock(&dir->d_inode->i_mutex);
15412 mutex_unlock(&dir->d_inode->i_mutex);
15413 audit_inode(pathname, path.dentry);
15415 @@ -1840,6 +1891,13 @@ do_link:
15416 error = security_inode_follow_link(path.dentry, nd);
15420 + if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
15421 + path.dentry, nd->path.mnt)) {
15426 error = __do_follow_link(&path, nd);
15428 /* Does someone understand code flow here? Or it is only
15429 @@ -1968,6 +2026,16 @@ asmlinkage long sys_mknodat(int dfd, con
15430 if (!IS_POSIXACL(nd.path.dentry->d_inode))
15431 mode &= ~current->fs->umask;
15432 if (!IS_ERR(dentry)) {
15433 + if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
15438 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
15443 switch (mode & S_IFMT) {
15444 case 0: case S_IFREG:
15445 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
15446 @@ -1985,6 +2053,11 @@ asmlinkage long sys_mknodat(int dfd, con
15452 + gr_handle_create(dentry, nd.path.mnt);
15457 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
15458 @@ -2042,9 +2115,18 @@ asmlinkage long sys_mkdirat(int dfd, con
15459 if (IS_ERR(dentry))
15462 + if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
15464 + goto out_unlock_dput;
15467 if (!IS_POSIXACL(nd.path.dentry->d_inode))
15468 mode &= ~current->fs->umask;
15469 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode, &nd);
15472 + gr_handle_create(dentry, nd.path.mnt);
15476 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
15477 @@ -2126,6 +2208,8 @@ static long do_rmdir(int dfd, const char
15479 struct dentry *dentry;
15480 struct nameidata nd;
15481 + ino_t saved_ino = 0;
15482 + dev_t saved_dev = 0;
15484 name = getname(pathname);
15486 @@ -2151,7 +2235,23 @@ static long do_rmdir(int dfd, const char
15487 error = PTR_ERR(dentry);
15488 if (IS_ERR(dentry))
15491 + if (dentry->d_inode != NULL) {
15492 + if (dentry->d_inode->i_nlink <= 1) {
15493 + saved_ino = dentry->d_inode->i_ino;
15494 + saved_dev = dentry->d_inode->i_sb->s_dev;
15497 + if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
15503 error = vfs_rmdir(nd.path.dentry->d_inode, dentry, &nd);
15504 + if (!error && (saved_dev || saved_ino))
15505 + gr_handle_delete(saved_ino, saved_dev);
15509 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
15510 @@ -2211,6 +2311,8 @@ static long do_unlinkat(int dfd, const c
15511 struct dentry *dentry;
15512 struct nameidata nd;
15513 struct inode *inode = NULL;
15514 + ino_t saved_ino = 0;
15515 + dev_t saved_dev = 0;
15517 name = getname(pathname);
15519 @@ -2226,13 +2328,26 @@ static long do_unlinkat(int dfd, const c
15520 dentry = lookup_hash(&nd);
15521 error = PTR_ERR(dentry);
15522 if (!IS_ERR(dentry)) {
15524 /* Why not before? Because we want correct error value */
15525 if (nd.last.name[nd.last.len])
15527 inode = dentry->d_inode;
15530 + if (inode->i_nlink <= 1) {
15531 + saved_ino = inode->i_ino;
15532 + saved_dev = inode->i_sb->s_dev;
15535 + if (!gr_acl_handle_unlink(dentry, nd.path.mnt))
15538 atomic_inc(&inode->i_count);
15539 - error = vfs_unlink(nd.path.dentry->d_inode, dentry, &nd);
15542 + error = vfs_unlink(nd.path.dentry->d_inode, dentry, &nd);
15543 + if (!error && (saved_ino || saved_dev))
15544 + gr_handle_delete(saved_ino, saved_dev);
15548 @@ -2313,8 +2428,18 @@ asmlinkage long sys_symlinkat(const char
15549 if (IS_ERR(dentry))
15552 + if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
15554 + goto out_dput_unlock;
15557 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from,
15561 + gr_handle_create(dentry, nd.path.mnt);
15566 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
15567 @@ -2408,8 +2533,27 @@ asmlinkage long sys_linkat(int olddfd, c
15568 error = PTR_ERR(new_dentry);
15569 if (IS_ERR(new_dentry))
15572 + if (gr_handle_hardlink(old_nd.path.dentry, old_nd.path.mnt,
15573 + old_nd.path.dentry->d_inode,
15574 + old_nd.path.dentry->d_inode->i_mode, to)) {
15576 + goto out_unlock_dput;
15579 + if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
15580 + old_nd.path.dentry, old_nd.path.mnt, to)) {
15582 + goto out_unlock_dput;
15585 error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode,
15589 + gr_handle_create(new_dentry, nd.path.mnt);
15594 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
15595 @@ -2634,8 +2778,16 @@ static int do_rename(int olddfd, const c
15596 if (new_dentry == trap)
15599 - error = vfs_rename(old_dir->d_inode, old_dentry,
15600 + error = gr_acl_handle_rename(new_dentry, newnd.path.dentry, newnd.path.mnt,
15601 + old_dentry, old_dir->d_inode, oldnd.path.mnt,
15605 + error = vfs_rename(old_dir->d_inode, old_dentry,
15606 new_dir->d_inode, new_dentry);
15608 + gr_handle_rename(old_dir->d_inode, newnd.path.dentry->d_inode, old_dentry,
15609 + new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
15613 diff -urNp linux-2.6.25.10/fs/namespace.c linux-2.6.25.10/fs/namespace.c
15614 --- linux-2.6.25.10/fs/namespace.c 2008-07-02 23:46:47.000000000 -0400
15615 +++ linux-2.6.25.10/fs/namespace.c 2008-07-03 16:53:26.000000000 -0400
15617 #include <linux/vs_tag.h>
15618 #include <linux/vserver/space.h>
15619 #include <linux/vserver/global.h>
15620 +#include <linux/grsecurity.h>
15621 #include <asm/uaccess.h>
15622 #include <asm/unistd.h>
15624 @@ -644,6 +645,8 @@ static int do_umount(struct vfsmount *mn
15626 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
15629 + gr_log_remount(mnt->mnt_devname, retval);
15631 up_write(&sb->s_umount);
15633 @@ -667,6 +670,9 @@ static int do_umount(struct vfsmount *mn
15634 security_sb_umount_busy(mnt);
15635 up_write(&namespace_sem);
15636 release_mounts(&umount_list);
15638 + gr_log_unmount(mnt->mnt_devname, retval);
15643 @@ -1438,6 +1444,11 @@ long do_mount(char *dev_name, char *dir_
15647 + if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
15652 if (flags & MS_REMOUNT)
15653 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
15655 @@ -1452,6 +1463,9 @@ long do_mount(char *dev_name, char *dir_
15656 dev_name, data_page);
15658 path_put(&nd.path);
15660 + gr_log_mount(dev_name, dir_name, retval);
15665 @@ -1681,6 +1695,9 @@ asmlinkage long sys_pivot_root(const cha
15666 if (!capable(CAP_SYS_ADMIN))
15669 + if (gr_handle_chroot_pivot())
15674 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
15675 diff -urNp linux-2.6.25.10/fs/nfs/nfs4proc.c linux-2.6.25.10/fs/nfs/nfs4proc.c
15676 --- linux-2.6.25.10/fs/nfs/nfs4proc.c 2008-07-02 23:46:47.000000000 -0400
15677 +++ linux-2.6.25.10/fs/nfs/nfs4proc.c 2008-07-03 16:53:26.000000000 -0400
15678 @@ -653,7 +653,7 @@ static int _nfs4_do_open_reclaim(struct
15679 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
15681 struct nfs_server *server = NFS_SERVER(state->inode);
15682 - struct nfs4_exception exception = { };
15683 + struct nfs4_exception exception = {0, 0};
15686 err = _nfs4_do_open_reclaim(ctx, state);
15687 @@ -695,7 +695,7 @@ static int _nfs4_open_delegation_recall(
15689 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
15691 - struct nfs4_exception exception = { };
15692 + struct nfs4_exception exception = {0, 0};
15693 struct nfs_server *server = NFS_SERVER(state->inode);
15696 @@ -991,7 +991,7 @@ static int _nfs4_open_expired(struct nfs
15697 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
15699 struct nfs_server *server = NFS_SERVER(state->inode);
15700 - struct nfs4_exception exception = { };
15701 + struct nfs4_exception exception = {0, 0};
15705 @@ -1093,7 +1093,7 @@ out_err:
15707 static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
15709 - struct nfs4_exception exception = { };
15710 + struct nfs4_exception exception = {0, 0};
15711 struct nfs4_state *res;
15714 @@ -1182,7 +1182,7 @@ static int nfs4_do_setattr(struct inode
15715 struct iattr *sattr, struct nfs4_state *state)
15717 struct nfs_server *server = NFS_SERVER(inode);
15718 - struct nfs4_exception exception = { };
15719 + struct nfs4_exception exception = {0, 0};
15722 err = nfs4_handle_exception(server,
15723 @@ -1495,7 +1495,7 @@ static int _nfs4_server_capabilities(str
15725 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
15727 - struct nfs4_exception exception = { };
15728 + struct nfs4_exception exception = {0, 0};
15731 err = nfs4_handle_exception(server,
15732 @@ -1528,7 +1528,7 @@ static int _nfs4_lookup_root(struct nfs_
15733 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
15734 struct nfs_fsinfo *info)
15736 - struct nfs4_exception exception = { };
15737 + struct nfs4_exception exception = {0, 0};
15740 err = nfs4_handle_exception(server,
15741 @@ -1617,7 +1617,7 @@ static int _nfs4_proc_getattr(struct nfs
15743 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15745 - struct nfs4_exception exception = { };
15746 + struct nfs4_exception exception = {0, 0};
15749 err = nfs4_handle_exception(server,
15750 @@ -1707,7 +1707,7 @@ static int nfs4_proc_lookupfh(struct nfs
15751 struct qstr *name, struct nfs_fh *fhandle,
15752 struct nfs_fattr *fattr)
15754 - struct nfs4_exception exception = { };
15755 + struct nfs4_exception exception = {0, 0};
15758 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
15759 @@ -1736,7 +1736,7 @@ static int _nfs4_proc_lookup(struct inod
15761 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15763 - struct nfs4_exception exception = { };
15764 + struct nfs4_exception exception = {0, 0};
15767 err = nfs4_handle_exception(NFS_SERVER(dir),
15768 @@ -1800,7 +1800,7 @@ static int _nfs4_proc_access(struct inod
15770 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
15772 - struct nfs4_exception exception = { };
15773 + struct nfs4_exception exception = {0, 0};
15776 err = nfs4_handle_exception(NFS_SERVER(inode),
15777 @@ -1855,7 +1855,7 @@ static int _nfs4_proc_readlink(struct in
15778 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
15779 unsigned int pgbase, unsigned int pglen)
15781 - struct nfs4_exception exception = { };
15782 + struct nfs4_exception exception = {0, 0};
15785 err = nfs4_handle_exception(NFS_SERVER(inode),
15786 @@ -1951,7 +1951,7 @@ static int _nfs4_proc_remove(struct inod
15788 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
15790 - struct nfs4_exception exception = { };
15791 + struct nfs4_exception exception = {0, 0};
15794 err = nfs4_handle_exception(NFS_SERVER(dir),
15795 @@ -2023,7 +2023,7 @@ static int _nfs4_proc_rename(struct inod
15796 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
15797 struct inode *new_dir, struct qstr *new_name)
15799 - struct nfs4_exception exception = { };
15800 + struct nfs4_exception exception = {0, 0};
15803 err = nfs4_handle_exception(NFS_SERVER(old_dir),
15804 @@ -2070,7 +2070,7 @@ static int _nfs4_proc_link(struct inode
15806 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
15808 - struct nfs4_exception exception = { };
15809 + struct nfs4_exception exception = {0, 0};
15812 err = nfs4_handle_exception(NFS_SERVER(inode),
15813 @@ -2127,7 +2127,7 @@ static int _nfs4_proc_symlink(struct ino
15814 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
15815 struct page *page, unsigned int len, struct iattr *sattr)
15817 - struct nfs4_exception exception = { };
15818 + struct nfs4_exception exception = {0, 0};
15821 err = nfs4_handle_exception(NFS_SERVER(dir),
15822 @@ -2180,7 +2180,7 @@ static int _nfs4_proc_mkdir(struct inode
15823 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
15824 struct iattr *sattr)
15826 - struct nfs4_exception exception = { };
15827 + struct nfs4_exception exception = {0, 0};
15830 err = nfs4_handle_exception(NFS_SERVER(dir),
15831 @@ -2229,7 +2229,7 @@ static int _nfs4_proc_readdir(struct den
15832 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
15833 u64 cookie, struct page *page, unsigned int count, int plus)
15835 - struct nfs4_exception exception = { };
15836 + struct nfs4_exception exception = {0, 0};
15839 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
15840 @@ -2299,7 +2299,7 @@ static int _nfs4_proc_mknod(struct inode
15841 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
15842 struct iattr *sattr, dev_t rdev)
15844 - struct nfs4_exception exception = { };
15845 + struct nfs4_exception exception = {0, 0};
15848 err = nfs4_handle_exception(NFS_SERVER(dir),
15849 @@ -2328,7 +2328,7 @@ static int _nfs4_proc_statfs(struct nfs_
15851 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
15853 - struct nfs4_exception exception = { };
15854 + struct nfs4_exception exception = {0, 0};
15857 err = nfs4_handle_exception(server,
15858 @@ -2356,7 +2356,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
15860 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
15862 - struct nfs4_exception exception = { };
15863 + struct nfs4_exception exception = {0, 0};
15867 @@ -2399,7 +2399,7 @@ static int _nfs4_proc_pathconf(struct nf
15868 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
15869 struct nfs_pathconf *pathconf)
15871 - struct nfs4_exception exception = { };
15872 + struct nfs4_exception exception = {0, 0};
15876 @@ -2686,7 +2686,7 @@ out_free:
15878 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
15880 - struct nfs4_exception exception = { };
15881 + struct nfs4_exception exception = {0, 0};
15884 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
15885 @@ -2740,7 +2740,7 @@ static int __nfs4_proc_set_acl(struct in
15887 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
15889 - struct nfs4_exception exception = { };
15890 + struct nfs4_exception exception = {0, 0};
15893 err = nfs4_handle_exception(NFS_SERVER(inode),
15894 @@ -3032,7 +3032,7 @@ out:
15895 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
15897 struct nfs_server *server = NFS_SERVER(inode);
15898 - struct nfs4_exception exception = { };
15899 + struct nfs4_exception exception = {0, 0};
15902 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
15903 @@ -3107,7 +3107,7 @@ out:
15905 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
15907 - struct nfs4_exception exception = { };
15908 + struct nfs4_exception exception = {0, 0};
15912 @@ -3453,7 +3453,7 @@ static int _nfs4_do_setlk(struct nfs4_st
15913 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
15915 struct nfs_server *server = NFS_SERVER(state->inode);
15916 - struct nfs4_exception exception = { };
15917 + struct nfs4_exception exception = {0, 0};
15921 @@ -3471,7 +3471,7 @@ static int nfs4_lock_reclaim(struct nfs4
15922 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
15924 struct nfs_server *server = NFS_SERVER(state->inode);
15925 - struct nfs4_exception exception = { };
15926 + struct nfs4_exception exception = {0, 0};
15929 err = nfs4_set_lock_state(state, request);
15930 @@ -3532,7 +3532,7 @@ out:
15932 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
15934 - struct nfs4_exception exception = { };
15935 + struct nfs4_exception exception = {0, 0};
15939 @@ -3582,7 +3582,7 @@ nfs4_proc_lock(struct file *filp, int cm
15940 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
15942 struct nfs_server *server = NFS_SERVER(state->inode);
15943 - struct nfs4_exception exception = { };
15944 + struct nfs4_exception exception = {0, 0};
15947 err = nfs4_set_lock_state(state, fl);
15948 diff -urNp linux-2.6.25.10/fs/nfsd/export.c linux-2.6.25.10/fs/nfsd/export.c
15949 --- linux-2.6.25.10/fs/nfsd/export.c 2008-07-02 23:46:47.000000000 -0400
15950 +++ linux-2.6.25.10/fs/nfsd/export.c 2008-07-03 16:53:26.000000000 -0400
15951 @@ -472,7 +472,7 @@ static int secinfo_parse(char **mesg, ch
15952 * probably discover the problem when someone fails to
15955 - if (f->pseudoflavor < 0)
15956 + if ((s32)f->pseudoflavor < 0)
15958 err = get_int(mesg, &f->flags);
15960 diff -urNp linux-2.6.25.10/fs/nls/nls_base.c linux-2.6.25.10/fs/nls/nls_base.c
15961 --- linux-2.6.25.10/fs/nls/nls_base.c 2008-07-02 23:46:47.000000000 -0400
15962 +++ linux-2.6.25.10/fs/nls/nls_base.c 2008-07-03 16:53:26.000000000 -0400
15963 @@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
15964 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
15965 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
15966 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
15967 - {0, /* end of table */}
15968 + {0, 0, 0, 0, 0, /* end of table */}
15972 diff -urNp linux-2.6.25.10/fs/ntfs/file.c linux-2.6.25.10/fs/ntfs/file.c
15973 --- linux-2.6.25.10/fs/ntfs/file.c 2008-07-02 23:46:47.000000000 -0400
15974 +++ linux-2.6.25.10/fs/ntfs/file.c 2008-07-03 16:53:26.000000000 -0400
15975 @@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
15976 #endif /* NTFS_RW */
15979 -const struct file_operations ntfs_empty_file_ops = {};
15980 +const struct file_operations ntfs_empty_file_ops;
15982 -const struct inode_operations ntfs_empty_inode_ops = {};
15983 +const struct inode_operations ntfs_empty_inode_ops;
15984 diff -urNp linux-2.6.25.10/fs/open.c linux-2.6.25.10/fs/open.c
15985 --- linux-2.6.25.10/fs/open.c 2008-07-02 23:46:47.000000000 -0400
15986 +++ linux-2.6.25.10/fs/open.c 2008-07-03 16:53:26.000000000 -0400
15988 #include <linux/vs_dlimit.h>
15989 #include <linux/vs_tag.h>
15990 #include <linux/vs_cowbl.h>
15991 +#include <linux/grsecurity.h>
15993 int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
15995 @@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
15999 + if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
16002 newattrs.ia_size = length;
16003 newattrs.ia_valid = ATTR_SIZE | time_attrs;
16005 @@ -461,6 +465,9 @@ asmlinkage long sys_faccessat(int dfd, c
16006 if(IS_RDONLY(nd.path.dentry->d_inode))
16009 + if (!res && !gr_acl_handle_access(nd.path.dentry, nd.path.mnt, mode))
16013 path_put(&nd.path);
16015 @@ -490,6 +497,8 @@ asmlinkage long sys_chdir(const char __u
16019 + gr_log_chdir(nd.path.dentry, nd.path.mnt);
16021 set_fs_pwd(current->fs, &nd.path);
16024 @@ -516,6 +525,13 @@ asmlinkage long sys_fchdir(unsigned int
16027 error = file_permission(file, MAY_EXEC);
16029 + if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
16033 + gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
16036 set_fs_pwd(current->fs, &file->f_path);
16038 @@ -541,8 +557,16 @@ asmlinkage long sys_chroot(const char __
16039 if (!capable(CAP_SYS_CHROOT))
16042 + if (gr_handle_chroot_chroot(nd.path.dentry, nd.path.mnt))
16043 + goto dput_and_out;
16045 set_fs_root(current->fs, &nd.path);
16048 + gr_handle_chroot_caps(current);
16050 + gr_handle_chroot_chdir(&nd.path);
16054 path_put(&nd.path);
16055 @@ -573,9 +597,22 @@ asmlinkage long sys_fchmod(unsigned int
16057 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
16060 + if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
16065 mutex_lock(&inode->i_mutex);
16066 if (mode == (mode_t) -1)
16067 mode = inode->i_mode;
16069 + if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
16071 + mutex_unlock(&inode->i_mutex);
16075 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16076 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16077 err = notify_change(dentry, &newattrs);
16078 @@ -608,9 +645,21 @@ asmlinkage long sys_fchmodat(int dfd, co
16079 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
16082 + if (!gr_acl_handle_chmod(nd.path.dentry, nd.path.mnt, mode)) {
16084 + goto dput_and_out;
16087 mutex_lock(&inode->i_mutex);
16088 if (mode == (mode_t) -1)
16089 mode = inode->i_mode;
16091 + if (gr_handle_chroot_chmod(nd.path.dentry, nd.path.mnt, mode)) {
16093 + mutex_unlock(&inode->i_mutex);
16094 + goto dput_and_out;
16097 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16098 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16099 error = notify_change(nd.path.dentry, &newattrs);
16100 @@ -644,6 +693,12 @@ static int chown_common(struct dentry *
16102 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
16105 + if (!gr_acl_handle_chown(dentry, mnt)) {
16110 newattrs.ia_valid = ATTR_CTIME;
16111 if (user != (uid_t) -1) {
16112 newattrs.ia_valid |= ATTR_UID;
16113 @@ -948,6 +1003,7 @@ repeat:
16114 * N.B. For clone tasks sharing a files structure, this test
16115 * will limit the total number of files that can be opened.
16117 + gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
16118 if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
16121 diff -urNp linux-2.6.25.10/fs/partitions/efi.c linux-2.6.25.10/fs/partitions/efi.c
16122 --- linux-2.6.25.10/fs/partitions/efi.c 2008-07-02 23:46:47.000000000 -0400
16123 +++ linux-2.6.25.10/fs/partitions/efi.c 2008-07-03 16:53:26.000000000 -0400
16126 #define Dprintk(x...) printk(KERN_DEBUG x)
16128 -#define Dprintk(x...)
16129 +#define Dprintk(x...) do {} while (0)
16132 /* This allows a kernel command line option 'gpt' to override
16133 diff -urNp linux-2.6.25.10/fs/pipe.c linux-2.6.25.10/fs/pipe.c
16134 --- linux-2.6.25.10/fs/pipe.c 2008-07-02 23:46:47.000000000 -0400
16135 +++ linux-2.6.25.10/fs/pipe.c 2008-07-03 16:53:26.000000000 -0400
16136 @@ -885,7 +885,7 @@ void free_pipe_info(struct inode *inode)
16137 inode->i_pipe = NULL;
16140 -static struct vfsmount *pipe_mnt __read_mostly;
16141 +struct vfsmount *pipe_mnt __read_mostly;
16142 static int pipefs_delete_dentry(struct dentry *dentry)
16145 diff -urNp linux-2.6.25.10/fs/proc/array.c linux-2.6.25.10/fs/proc/array.c
16146 --- linux-2.6.25.10/fs/proc/array.c 2008-07-02 23:46:47.000000000 -0400
16147 +++ linux-2.6.25.10/fs/proc/array.c 2008-07-03 16:53:26.000000000 -0400
16148 @@ -308,6 +308,21 @@ static inline void task_context_switch_c
16152 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16153 +static inline void task_pax(struct seq_file *m, struct task_struct *p)
16156 + seq_printf(m, "PaX:\t%c%c%c%c%c\n",
16157 + p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
16158 + p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
16159 + p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
16160 + p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
16161 + p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
16163 + seq_printf(m, "PaX:\t-----\n");
16167 int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
16168 struct pid *pid, struct task_struct *task)
16170 @@ -327,6 +342,11 @@ int proc_pid_status(struct seq_file *m,
16171 task_show_regs(m, task);
16173 task_context_switch_counts(m, task);
16175 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16176 + task_pax(m, task);
16182 @@ -389,6 +409,12 @@ static cputime_t task_gtime(struct task_
16186 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16187 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
16188 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
16189 + _mm->pax_flags & MF_PAX_SEGMEXEC))
16192 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
16193 struct pid *pid, struct task_struct *task, int whole)
16195 @@ -481,6 +507,19 @@ static int do_task_stat(struct seq_file
16196 gtime = task_gtime(task);
16199 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16200 + if (PAX_RAND_FLAGS(mm)) {
16206 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16212 /* scale priority and nice values from timeslices to -20..20 */
16213 /* to make it look like a "normal" Unix priority/nice value */
16214 priority = task_prio(task);
16215 @@ -521,9 +560,15 @@ static int do_task_stat(struct seq_file
16217 mm ? get_mm_rss(mm) : 0,
16219 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16220 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
16221 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
16222 + PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
16224 mm ? mm->start_code : 0,
16225 mm ? mm->end_code : 0,
16226 mm ? mm->start_stack : 0,
16230 /* The signal information here is obsolete.
16231 @@ -576,3 +621,10 @@ int proc_pid_statm(struct seq_file *m, s
16236 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16237 +int proc_pid_ipaddr(struct task_struct *task, char *buffer)
16239 + return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
16242 diff -urNp linux-2.6.25.10/fs/proc/base.c linux-2.6.25.10/fs/proc/base.c
16243 --- linux-2.6.25.10/fs/proc/base.c 2008-07-02 23:46:47.000000000 -0400
16244 +++ linux-2.6.25.10/fs/proc/base.c 2008-07-03 16:53:26.000000000 -0400
16246 #include <linux/pid_namespace.h>
16247 #include <linux/vs_context.h>
16248 #include <linux/vs_network.h>
16249 +#include <linux/grsecurity.h>
16251 #include "internal.h"
16254 @@ -145,7 +147,7 @@ static unsigned int pid_entry_count_dirs
16259 +int maps_protect = 1;
16260 EXPORT_SYMBOL(maps_protect);
16262 static struct fs_struct *get_fs_struct(struct task_struct *task)
16263 @@ -219,7 +221,7 @@ static int proc_root_link(struct inode *
16264 (task->parent == current && \
16265 (task->ptrace & PT_PTRACED) && \
16266 (task_is_stopped_or_traced(task)) && \
16267 - security_ptrace(current,task) == 0))
16268 + security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
16270 struct mm_struct *mm_for_maps(struct task_struct *task)
16272 @@ -284,9 +286,9 @@ static int proc_pid_auxv(struct task_str
16273 struct mm_struct *mm = get_task_mm(task);
16275 unsigned int nwords = 0;
16279 - while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16280 + } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16281 res = nwords * sizeof(mm->saved_auxv[0]);
16282 if (res > PAGE_SIZE)
16284 @@ -734,7 +736,7 @@ static ssize_t mem_read(struct file * fi
16288 - if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
16289 + if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
16293 @@ -804,7 +806,7 @@ static ssize_t mem_write(struct file * f
16297 - if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
16298 + if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
16302 @@ -1307,7 +1309,11 @@ static struct inode *proc_pid_make_inode
16304 if (task_dumpable(task)) {
16305 inode->i_uid = task->euid;
16306 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16307 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16309 inode->i_gid = task->egid;
16312 /* procfs is xid tagged */
16313 inode->i_tag = (tag_t)vx_task_xid(task);
16314 @@ -1323,17 +1329,45 @@ static int pid_getattr(struct vfsmount *
16316 struct inode *inode = dentry->d_inode;
16317 struct task_struct *task;
16318 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16319 + struct task_struct *tmp = current;
16322 generic_fillattr(inode, stat);
16327 task = pid_task(proc_pid(inode), PIDTYPE_PID);
16330 + if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
16331 + rcu_read_unlock();
16337 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16338 + && (!tmp->uid || (tmp->uid == task->uid)
16339 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16340 + || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16345 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16346 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16347 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16348 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16349 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16351 task_dumpable(task)) {
16352 stat->uid = task->euid;
16353 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16354 + stat->gid = CONFIG_GRKERNSEC_PROC_GID;
16356 stat->gid = task->egid;
16361 @@ -1361,11 +1395,21 @@ static int pid_revalidate(struct dentry
16363 struct inode *inode = dentry->d_inode;
16364 struct task_struct *task = get_proc_task(inode);
16367 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16368 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16369 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16370 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16371 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16373 task_dumpable(task)) {
16374 inode->i_uid = task->euid;
16375 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16376 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16378 inode->i_gid = task->egid;
16383 @@ -1736,12 +1780,22 @@ static int proc_fd_permission(struct ino
16384 struct nameidata *nd)
16387 + struct task_struct *task;
16389 rv = generic_permission(inode, mask, NULL);
16393 if (task_pid(current) == proc_pid(inode))
16396 + task = get_proc_task(inode);
16397 + if (task == NULL)
16400 + if (gr_acl_handle_procpidmem(task))
16403 + put_task_struct(task);
16408 @@ -1852,6 +1906,9 @@ static struct dentry *proc_pident_lookup
16412 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16415 /* TODO: maybe we can come up with a generic approach? */
16416 if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
16417 (dentry->d_name.len == 5) &&
16418 @@ -1896,6 +1953,9 @@ static int proc_pident_readdir(struct fi
16422 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16428 @@ -2258,6 +2318,9 @@ static struct dentry *proc_base_lookup(s
16432 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16435 error = proc_base_instantiate(dir, dentry, task, p);
16438 @@ -2369,6 +2432,9 @@ static const struct pid_entry tgid_base_
16439 INF("io", S_IRUGO, pid_io_accounting),
16441 ONE("nsproxy", S_IRUGO, pid_nsproxy),
16442 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16443 + INF("ipaddr", S_IRUSR, pid_ipaddr),
16447 static int proc_tgid_base_readdir(struct file * filp,
16448 @@ -2498,7 +2564,14 @@ static struct dentry *proc_pid_instantia
16452 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16453 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
16454 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16455 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16456 + inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
16458 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
16460 inode->i_op = &proc_tgid_base_inode_operations;
16461 inode->i_fop = &proc_tgid_base_operations;
16462 inode->i_flags|=S_IMMUTABLE;
16463 @@ -2540,7 +2613,11 @@ struct dentry *proc_pid_lookup(struct in
16467 + if (gr_check_hidden_task(task))
16468 + goto out_put_task;
16470 result = proc_pid_instantiate(dir, dentry, task, NULL);
16472 put_task_struct(task);
16475 @@ -2605,6 +2682,9 @@ int proc_pid_readdir(struct file * filp,
16477 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
16478 struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
16479 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16480 + struct task_struct *tmp = current;
16482 struct tgid_iter iter;
16483 struct pid_namespace *ns;
16485 @@ -2623,6 +2703,17 @@ int proc_pid_readdir(struct file * filp,
16486 for (iter = next_tgid(ns, iter);
16488 iter.tgid += 1, iter = next_tgid(ns, iter)) {
16489 + if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
16490 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16491 + || (tmp->uid && (iter.task->uid != tmp->uid)
16492 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16493 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16500 filp->f_pos = iter.tgid + TGID_OFFSET;
16501 if (!vx_proc_task_visible(iter.task))
16503 diff -urNp linux-2.6.25.10/fs/proc/inode.c linux-2.6.25.10/fs/proc/inode.c
16504 --- linux-2.6.25.10/fs/proc/inode.c 2008-07-02 23:46:47.000000000 -0400
16505 +++ linux-2.6.25.10/fs/proc/inode.c 2008-07-03 16:53:26.000000000 -0400
16506 @@ -406,7 +406,11 @@ struct inode *proc_get_inode(struct supe
16508 inode->i_mode = de->mode;
16509 inode->i_uid = de->uid;
16510 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16511 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16513 inode->i_gid = de->gid;
16517 PROC_I(inode)->vx_flags = de->vx_flags;
16518 diff -urNp linux-2.6.25.10/fs/proc/internal.h linux-2.6.25.10/fs/proc/internal.h
16519 --- linux-2.6.25.10/fs/proc/internal.h 2008-07-02 23:46:47.000000000 -0400
16520 +++ linux-2.6.25.10/fs/proc/internal.h 2008-07-03 16:53:26.000000000 -0400
16521 @@ -57,6 +57,9 @@ extern int proc_pid_status(struct seq_fi
16522 struct pid *pid, struct task_struct *task);
16523 extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
16524 struct pid *pid, struct task_struct *task);
16525 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16526 +extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
16529 extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
16531 diff -urNp linux-2.6.25.10/fs/proc/proc_misc.c linux-2.6.25.10/fs/proc/proc_misc.c
16532 --- linux-2.6.25.10/fs/proc/proc_misc.c 2008-07-02 23:46:47.000000000 -0400
16533 +++ linux-2.6.25.10/fs/proc/proc_misc.c 2008-07-03 16:53:26.000000000 -0400
16534 @@ -822,6 +822,8 @@ void create_seq_entry(char *name, mode_t
16536 void __init proc_misc_init(void)
16542 int (*read_proc)(char*,char**,off_t,int,int*,void*);
16543 @@ -837,13 +839,24 @@ void __init proc_misc_init(void)
16544 {"stram", stram_read_proc},
16546 {"filesystems", filesystems_read_proc},
16547 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
16548 {"cmdline", cmdline_read_proc},
16550 {"execdomains", execdomains_read_proc},
16553 for (p = simple_ones; p->name; p++)
16554 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
16556 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16557 + gr_mode = S_IRUSR;
16558 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16559 + gr_mode = S_IRUSR | S_IRGRP;
16561 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
16562 + create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
16565 proc_symlink("mounts", NULL, "self/mounts");
16567 /* And now for trickier ones */
16568 @@ -856,7 +869,11 @@ void __init proc_misc_init(void)
16571 create_seq_entry("locks", 0, &proc_locks_operations);
16572 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
16573 + create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
16575 create_seq_entry("devices", 0, &proc_devinfo_operations);
16577 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
16578 #ifdef CONFIG_BLOCK
16579 create_seq_entry("partitions", 0, &proc_partitions_operations);
16580 @@ -864,7 +881,11 @@ void __init proc_misc_init(void)
16581 create_seq_entry("stat", 0, &proc_stat_operations);
16582 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
16583 #ifdef CONFIG_SLABINFO
16584 +#ifdef CONFIG_GRKRENSEC_PROC_ADD
16585 + create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
16587 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
16589 #ifdef CONFIG_DEBUG_SLAB_LEAK
16590 create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
16592 @@ -882,7 +903,7 @@ void __init proc_misc_init(void)
16593 #ifdef CONFIG_SCHEDSTATS
16594 create_seq_entry("schedstat", 0, &proc_schedstat_operations);
16596 -#ifdef CONFIG_PROC_KCORE
16597 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
16598 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
16599 if (proc_root_kcore) {
16600 proc_root_kcore->proc_fops = &proc_kcore_operations;
16601 diff -urNp linux-2.6.25.10/fs/proc/proc_net.c linux-2.6.25.10/fs/proc/proc_net.c
16602 --- linux-2.6.25.10/fs/proc/proc_net.c 2008-07-02 23:46:47.000000000 -0400
16603 +++ linux-2.6.25.10/fs/proc/proc_net.c 2008-07-03 16:53:26.000000000 -0400
16604 @@ -69,6 +69,14 @@ static struct net *get_proc_task_net(str
16605 struct nsproxy *ns;
16606 struct net *net = NULL;
16608 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16609 + if (current->fsuid)
16611 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16612 + if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
16617 task = pid_task(proc_pid(dir), PIDTYPE_PID);
16618 if (task != NULL) {
16619 diff -urNp linux-2.6.25.10/fs/proc/proc_sysctl.c linux-2.6.25.10/fs/proc/proc_sysctl.c
16620 --- linux-2.6.25.10/fs/proc/proc_sysctl.c 2008-07-02 23:46:47.000000000 -0400
16621 +++ linux-2.6.25.10/fs/proc/proc_sysctl.c 2008-07-03 16:53:26.000000000 -0400
16623 #include <linux/security.h>
16624 #include "internal.h"
16626 +extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
16628 static struct dentry_operations proc_sys_dentry_operations;
16629 static const struct file_operations proc_sys_file_operations;
16630 static const struct inode_operations proc_sys_inode_operations;
16631 @@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st
16635 + if (gr_handle_sysctl(table, 001))
16638 err = ERR_PTR(-ENOMEM);
16639 inode = proc_sys_make_inode(dir, table);
16641 @@ -360,6 +365,9 @@ static int proc_sys_readdir(struct file
16642 if (pos < filp->f_pos)
16645 + if (gr_handle_sysctl(table, 0))
16648 if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
16650 filp->f_pos = pos + 1;
16651 @@ -422,6 +430,30 @@ out:
16655 +/* Eric Biederman is to blame */
16656 +static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
16659 + struct ctl_table_header *head;
16660 + struct ctl_table *table;
16662 + table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
16663 + /* Has the sysctl entry disappeared on us? */
16667 + if (gr_handle_sysctl(table, 001)) {
16673 + sysctl_head_finish(head);
16675 + generic_fillattr(dentry->d_inode, stat);
16679 static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
16681 struct inode *inode = dentry->d_inode;
16682 @@ -450,6 +482,7 @@ static const struct inode_operations pro
16683 .lookup = proc_sys_lookup,
16684 .permission = proc_sys_permission,
16685 .setattr = proc_sys_setattr,
16686 + .getattr = proc_sys_getattr,
16689 static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
16690 diff -urNp linux-2.6.25.10/fs/proc/root.c linux-2.6.25.10/fs/proc/root.c
16691 --- linux-2.6.25.10/fs/proc/root.c 2008-07-02 23:46:47.000000000 -0400
16692 +++ linux-2.6.25.10/fs/proc/root.c 2008-07-03 16:53:26.000000000 -0400
16693 @@ -137,7 +137,15 @@ void __init proc_root_init(void)
16694 #ifdef CONFIG_PROC_DEVICETREE
16695 proc_device_tree_init();
16697 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
16698 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16699 + proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
16700 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16701 + proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
16704 proc_bus = proc_mkdir("bus", NULL);
16709 diff -urNp linux-2.6.25.10/fs/proc/task_mmu.c linux-2.6.25.10/fs/proc/task_mmu.c
16710 --- linux-2.6.25.10/fs/proc/task_mmu.c 2008-07-02 23:46:47.000000000 -0400
16711 +++ linux-2.6.25.10/fs/proc/task_mmu.c 2008-07-03 16:53:26.000000000 -0400
16712 @@ -48,15 +48,26 @@ void task_mem(struct seq_file *m, struct
16713 "VmStk:\t%8lu kB\n"
16714 "VmExe:\t%8lu kB\n"
16715 "VmLib:\t%8lu kB\n"
16716 - "VmPTE:\t%8lu kB\n",
16717 - hiwater_vm << (PAGE_SHIFT-10),
16718 + "VmPTE:\t%8lu kB\n"
16720 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16721 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
16724 + ,hiwater_vm << (PAGE_SHIFT-10),
16725 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
16726 mm->locked_vm << (PAGE_SHIFT-10),
16727 hiwater_rss << (PAGE_SHIFT-10),
16728 total_rss << (PAGE_SHIFT-10),
16729 data << (PAGE_SHIFT-10),
16730 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
16731 - (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
16732 + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
16734 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16735 + , mm->context.user_cs_base, mm->context.user_cs_limit
16741 unsigned long task_vsize(struct mm_struct *mm)
16742 @@ -234,6 +245,12 @@ static int do_maps_open(struct inode *in
16746 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16747 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
16748 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
16749 + _mm->pax_flags & MF_PAX_SEGMEXEC))
16752 static int show_map(struct seq_file *m, void *v)
16754 struct proc_maps_private *priv = m->private;
16755 @@ -256,13 +273,22 @@ static int show_map(struct seq_file *m,
16758 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
16759 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16760 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
16761 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
16766 flags & VM_READ ? 'r' : '-',
16767 flags & VM_WRITE ? 'w' : '-',
16768 flags & VM_EXEC ? 'x' : '-',
16769 flags & VM_MAYSHARE ? 's' : 'p',
16770 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16771 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
16773 vma->vm_pgoff << PAGE_SHIFT,
16775 MAJOR(dev), MINOR(dev), ino, &len);
16778 @@ -276,11 +302,11 @@ static int show_map(struct seq_file *m,
16779 const char *name = arch_vma_name(vma);
16782 - if (vma->vm_start <= mm->start_brk &&
16783 - vma->vm_end >= mm->brk) {
16784 + if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
16786 - } else if (vma->vm_start <= mm->start_stack &&
16787 - vma->vm_end >= mm->start_stack) {
16788 + } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
16789 + (vma->vm_start <= mm->start_stack &&
16790 + vma->vm_end >= mm->start_stack)) {
16794 @@ -404,10 +430,17 @@ static int show_smap(struct seq_file *m,
16797 memset(&mss, 0, sizeof mss);
16799 - if (vma->vm_mm && !is_vm_hugetlb_page(vma))
16800 - walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end,
16801 - &smaps_walk, &mss);
16803 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16804 + if (!PAX_RAND_FLAGS(vma->vm_mm)) {
16807 + if (vma->vm_mm && !is_vm_hugetlb_page(vma))
16808 + walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end,
16809 + &smaps_walk, &mss);
16810 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16814 ret = show_map(m, v);
16816 @@ -422,7 +455,11 @@ static int show_smap(struct seq_file *m,
16817 "Private_Clean: %8lu kB\n"
16818 "Private_Dirty: %8lu kB\n"
16819 "Referenced: %8lu kB\n",
16820 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16821 + PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
16823 (vma->vm_end - vma->vm_start) >> 10,
16825 mss.resident >> 10,
16826 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
16827 mss.shared_clean >> 10,
16828 diff -urNp linux-2.6.25.10/fs/readdir.c linux-2.6.25.10/fs/readdir.c
16829 --- linux-2.6.25.10/fs/readdir.c 2008-07-02 23:46:47.000000000 -0400
16830 +++ linux-2.6.25.10/fs/readdir.c 2008-07-03 16:53:26.000000000 -0400
16832 #include <linux/security.h>
16833 #include <linux/syscalls.h>
16834 #include <linux/unistd.h>
16835 +#include <linux/namei.h>
16836 +#include <linux/grsecurity.h>
16838 #include <asm/uaccess.h>
16840 @@ -67,6 +69,7 @@ struct old_linux_dirent {
16842 struct readdir_callback {
16843 struct old_linux_dirent __user * dirent;
16844 + struct file * file;
16848 @@ -82,6 +85,10 @@ static int fillonedir(void * __buf, cons
16850 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
16853 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
16857 dirent = buf->dirent;
16858 if (!access_ok(VERIFY_WRITE, dirent,
16859 @@ -113,6 +120,7 @@ asmlinkage long old_readdir(unsigned int
16862 buf.dirent = dirent;
16865 error = vfs_readdir(file, fillonedir, &buf);
16867 @@ -139,6 +147,7 @@ struct linux_dirent {
16868 struct getdents_callback {
16869 struct linux_dirent __user * current_dir;
16870 struct linux_dirent __user * previous;
16871 + struct file * file;
16875 @@ -157,6 +166,10 @@ static int filldir(void * __buf, const c
16877 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
16880 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
16883 dirent = buf->previous;
16885 if (__put_user(offset, &dirent->d_off))
16886 @@ -203,6 +216,7 @@ asmlinkage long sys_getdents(unsigned in
16887 buf.previous = NULL;
16892 error = vfs_readdir(file, filldir, &buf);
16894 @@ -225,6 +239,7 @@ out:
16895 struct getdents_callback64 {
16896 struct linux_dirent64 __user * current_dir;
16897 struct linux_dirent64 __user * previous;
16898 + struct file *file;
16902 @@ -239,6 +254,10 @@ static int filldir64(void * __buf, const
16903 buf->error = -EINVAL; /* only used if we fail.. */
16904 if (reclen > buf->count)
16907 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
16910 dirent = buf->previous;
16912 if (__put_user(offset, &dirent->d_off))
16913 @@ -285,6 +304,7 @@ asmlinkage long sys_getdents64(unsigned
16915 buf.current_dir = dirent;
16916 buf.previous = NULL;
16921 diff -urNp linux-2.6.25.10/fs/smbfs/symlink.c linux-2.6.25.10/fs/smbfs/symlink.c
16922 --- linux-2.6.25.10/fs/smbfs/symlink.c 2008-07-02 23:46:47.000000000 -0400
16923 +++ linux-2.6.25.10/fs/smbfs/symlink.c 2008-07-03 16:53:26.000000000 -0400
16924 @@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
16926 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
16928 - char *s = nd_get_link(nd);
16929 + const char *s = nd_get_link(nd);
16933 diff -urNp linux-2.6.25.10/fs/sysfs/symlink.c linux-2.6.25.10/fs/sysfs/symlink.c
16934 --- linux-2.6.25.10/fs/sysfs/symlink.c 2008-07-02 23:46:47.000000000 -0400
16935 +++ linux-2.6.25.10/fs/sysfs/symlink.c 2008-07-03 16:53:26.000000000 -0400
16936 @@ -168,7 +168,7 @@ static void *sysfs_follow_link(struct de
16938 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
16940 - char *page = nd_get_link(nd);
16941 + const char *page = nd_get_link(nd);
16943 free_page((unsigned long)page);
16945 diff -urNp linux-2.6.25.10/fs/udf/balloc.c linux-2.6.25.10/fs/udf/balloc.c
16946 --- linux-2.6.25.10/fs/udf/balloc.c 2008-07-02 23:46:47.000000000 -0400
16947 +++ linux-2.6.25.10/fs/udf/balloc.c 2008-07-03 16:53:26.000000000 -0400
16948 @@ -170,9 +170,7 @@ static void udf_bitmap_free_blocks(struc
16949 unsigned long overflow;
16951 mutex_lock(&sbi->s_alloc_mutex);
16952 - if (bloc.logicalBlockNum < 0 ||
16953 - (bloc.logicalBlockNum + count) >
16954 - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
16955 + if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
16956 udf_debug("%d < %d || %d + %d > %d\n",
16957 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
16958 sbi->s_partmaps[bloc.partitionReferenceNum].
16959 @@ -240,7 +238,7 @@ static int udf_bitmap_prealloc_blocks(st
16961 mutex_lock(&sbi->s_alloc_mutex);
16962 part_len = sbi->s_partmaps[partition].s_partition_len;
16963 - if (first_block < 0 || first_block >= part_len)
16964 + if (first_block >= part_len)
16967 if (first_block + block_count > part_len)
16968 @@ -301,7 +299,7 @@ static int udf_bitmap_new_block(struct s
16969 mutex_lock(&sbi->s_alloc_mutex);
16972 - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
16973 + if (goal >= sbi->s_partmaps[partition].s_partition_len)
16976 nr_groups = bitmap->s_nr_groups;
16977 @@ -439,9 +437,7 @@ static void udf_table_free_blocks(struct
16978 struct udf_inode_info *iinfo;
16980 mutex_lock(&sbi->s_alloc_mutex);
16981 - if (bloc.logicalBlockNum < 0 ||
16982 - (bloc.logicalBlockNum + count) >
16983 - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
16984 + if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
16985 udf_debug("%d < %d || %d + %d > %d\n",
16986 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
16987 sbi->s_partmaps[bloc.partitionReferenceNum].
16988 @@ -676,8 +672,7 @@ static int udf_table_prealloc_blocks(str
16990 struct udf_inode_info *iinfo;
16992 - if (first_block < 0 ||
16993 - first_block >= sbi->s_partmaps[partition].s_partition_len)
16994 + if (first_block >= sbi->s_partmaps[partition].s_partition_len)
16997 iinfo = UDF_I(table);
16998 @@ -755,7 +750,7 @@ static int udf_table_new_block(struct su
17001 mutex_lock(&sbi->s_alloc_mutex);
17002 - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
17003 + if (goal >= sbi->s_partmaps[partition].s_partition_len)
17006 /* We search for the closest matching block to goal. If we find
17007 diff -urNp linux-2.6.25.10/fs/udf/inode.c linux-2.6.25.10/fs/udf/inode.c
17008 --- linux-2.6.25.10/fs/udf/inode.c 2008-07-02 23:46:47.000000000 -0400
17009 +++ linux-2.6.25.10/fs/udf/inode.c 2008-07-03 16:53:26.000000000 -0400
17010 @@ -323,9 +323,6 @@ static int udf_get_block(struct inode *i
17015 - goto abort_negative;
17017 iinfo = UDF_I(inode);
17018 if (block == iinfo->i_next_alloc_block + 1) {
17019 iinfo->i_next_alloc_block++;
17020 @@ -347,10 +344,6 @@ static int udf_get_block(struct inode *i
17026 - udf_warning(inode->i_sb, "udf_get_block", "block < 0");
17030 static struct buffer_head *udf_getblk(struct inode *inode, long block,
17031 diff -urNp linux-2.6.25.10/fs/ufs/inode.c linux-2.6.25.10/fs/ufs/inode.c
17032 --- linux-2.6.25.10/fs/ufs/inode.c 2008-07-02 23:46:47.000000000 -0400
17033 +++ linux-2.6.25.10/fs/ufs/inode.c 2008-07-03 16:53:26.000000000 -0400
17034 @@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
17037 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
17038 - if (i_block < 0) {
17039 - ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
17040 - } else if (i_block < direct_blocks) {
17041 + if (i_block < direct_blocks) {
17042 offsets[n++] = i_block;
17043 } else if ((i_block -= direct_blocks) < indirect_blocks) {
17044 offsets[n++] = UFS_IND_BLOCK;
17045 @@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
17048 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
17049 - if (fragment < 0)
17050 - goto abort_negative;
17052 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
17053 << uspi->s_fpbshift))
17054 @@ -504,10 +500,6 @@ abort:
17059 - ufs_warning(sb, "ufs_get_block", "block < 0");
17063 ufs_warning(sb, "ufs_get_block", "block > big");
17065 diff -urNp linux-2.6.25.10/fs/utimes.c linux-2.6.25.10/fs/utimes.c
17066 --- linux-2.6.25.10/fs/utimes.c 2008-07-02 23:46:47.000000000 -0400
17067 +++ linux-2.6.25.10/fs/utimes.c 2008-07-03 16:53:26.000000000 -0400
17069 #include <linux/syscalls.h>
17070 #include <linux/mount.h>
17071 #include <linux/vs_cowbl.h>
17072 +#include <linux/grsecurity.h>
17073 #include <asm/uaccess.h>
17074 #include <asm/unistd.h>
17076 @@ -61,6 +62,7 @@ long do_utimes(int dfd, char __user *fil
17078 struct nameidata nd;
17079 struct dentry *dentry;
17080 + struct vfsmount *mnt;
17081 struct inode *inode;
17082 struct iattr newattrs;
17083 struct file *f = NULL;
17084 @@ -84,6 +86,7 @@ long do_utimes(int dfd, char __user *fil
17087 dentry = f->f_path.dentry;
17088 + mnt = f->f_path.mnt;
17090 error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
17092 @@ -90,6 +93,7 @@ long do_utimes(int dfd, char __user *fil
17095 dentry = nd.path.dentry;
17096 + mnt = nd.path.mnt;
17099 inode = dentry->d_inode;
17100 @@ -144,6 +148,12 @@ long do_utimes(int dfd, char __user *fil
17105 + if (!gr_acl_handle_utime(dentry, mnt)) {
17107 + goto dput_and_out;
17110 mutex_lock(&inode->i_mutex);
17111 error = notify_change(dentry, &newattrs);
17112 mutex_unlock(&inode->i_mutex);
17113 diff -urNp linux-2.6.25.10/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.25.10/fs/xfs/linux-2.6/xfs_iops.c
17114 --- linux-2.6.25.10/fs/xfs/linux-2.6/xfs_iops.c 2008-07-02 23:46:47.000000000 -0400
17115 +++ linux-2.6.25.10/fs/xfs/linux-2.6/xfs_iops.c 2008-07-03 16:53:26.000000000 -0400
17116 @@ -547,7 +547,7 @@ xfs_vn_put_link(
17117 struct nameidata *nd,
17120 - char *s = nd_get_link(nd);
17121 + const char *s = nd_get_link(nd);
17125 diff -urNp linux-2.6.25.10/fs/xfs/xfs_bmap.c linux-2.6.25.10/fs/xfs/xfs_bmap.c
17126 --- linux-2.6.25.10/fs/xfs/xfs_bmap.c 2008-07-02 23:46:47.000000000 -0400
17127 +++ linux-2.6.25.10/fs/xfs/xfs_bmap.c 2008-07-03 16:53:26.000000000 -0400
17128 @@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
17132 -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
17133 +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
17136 #if defined(XFS_RW_TRACE)
17137 diff -urNp linux-2.6.25.10/grsecurity/gracl_alloc.c linux-2.6.25.10/grsecurity/gracl_alloc.c
17138 --- linux-2.6.25.10/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
17139 +++ linux-2.6.25.10/grsecurity/gracl_alloc.c 2008-07-03 16:53:26.000000000 -0400
17141 +#include <linux/kernel.h>
17142 +#include <linux/mm.h>
17143 +#include <linux/slab.h>
17144 +#include <linux/vmalloc.h>
17145 +#include <linux/gracl.h>
17146 +#include <linux/grsecurity.h>
17148 +static unsigned long alloc_stack_next = 1;
17149 +static unsigned long alloc_stack_size = 1;
17150 +static void **alloc_stack;
17152 +static __inline__ int
17155 + if (alloc_stack_next == 1)
17158 + kfree(alloc_stack[alloc_stack_next - 2]);
17160 + alloc_stack_next--;
17165 +static __inline__ void
17166 +alloc_push(void *buf)
17168 + if (alloc_stack_next >= alloc_stack_size)
17171 + alloc_stack[alloc_stack_next - 1] = buf;
17173 + alloc_stack_next++;
17179 +acl_alloc(unsigned long len)
17183 + if (len > PAGE_SIZE)
17186 + ret = kmalloc(len, GFP_KERNEL);
17195 +acl_free_all(void)
17197 + if (gr_acl_is_enabled() || !alloc_stack)
17200 + while (alloc_pop()) ;
17202 + if (alloc_stack) {
17203 + if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
17204 + kfree(alloc_stack);
17206 + vfree(alloc_stack);
17209 + alloc_stack = NULL;
17210 + alloc_stack_size = 1;
17211 + alloc_stack_next = 1;
17217 +acl_alloc_stack_init(unsigned long size)
17219 + if ((size * sizeof (void *)) <= PAGE_SIZE)
17221 + (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
17223 + alloc_stack = (void **) vmalloc(size * sizeof (void *));
17225 + alloc_stack_size = size;
17227 + if (!alloc_stack)
17232 diff -urNp linux-2.6.25.10/grsecurity/gracl.c linux-2.6.25.10/grsecurity/gracl.c
17233 --- linux-2.6.25.10/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
17234 +++ linux-2.6.25.10/grsecurity/gracl.c 2008-07-03 16:53:26.000000000 -0400
17236 +#include <linux/kernel.h>
17237 +#include <linux/module.h>
17238 +#include <linux/sched.h>
17239 +#include <linux/mm.h>
17240 +#include <linux/file.h>
17241 +#include <linux/fs.h>
17242 +#include <linux/namei.h>
17243 +#include <linux/mount.h>
17244 +#include <linux/tty.h>
17245 +#include <linux/proc_fs.h>
17246 +#include <linux/smp_lock.h>
17247 +#include <linux/slab.h>
17248 +#include <linux/vmalloc.h>
17249 +#include <linux/types.h>
17250 +#include <linux/sysctl.h>
17251 +#include <linux/netdevice.h>
17252 +#include <linux/ptrace.h>
17253 +#include <linux/gracl.h>
17254 +#include <linux/gralloc.h>
17255 +#include <linux/grsecurity.h>
17256 +#include <linux/grinternal.h>
17257 +#include <linux/pid_namespace.h>
17258 +#include <linux/percpu.h>
17260 +#include <asm/uaccess.h>
17261 +#include <asm/errno.h>
17262 +#include <asm/mman.h>
17264 +static struct acl_role_db acl_role_set;
17265 +static struct name_db name_set;
17266 +static struct inodev_db inodev_set;
17268 +/* for keeping track of userspace pointers used for subjects, so we
17269 + can share references in the kernel as well
17272 +static struct dentry *real_root;
17273 +static struct vfsmount *real_root_mnt;
17275 +static struct acl_subj_map_db subj_map_set;
17277 +static struct acl_role_label *default_role;
17279 +static u16 acl_sp_role_value;
17281 +extern char *gr_shared_page[4];
17282 +static DECLARE_MUTEX(gr_dev_sem);
17283 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
17285 +struct gr_arg *gr_usermode;
17287 +static unsigned int gr_status = GR_STATUS_INIT;
17289 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
17290 +extern void gr_clear_learn_entries(void);
17292 +#ifdef CONFIG_GRKERNSEC_RESLOG
17293 +extern void gr_log_resource(const struct task_struct *task,
17294 + const int res, const unsigned long wanted, const int gt);
17297 +unsigned char *gr_system_salt;
17298 +unsigned char *gr_system_sum;
17300 +static struct sprole_pw **acl_special_roles = NULL;
17301 +static __u16 num_sprole_pws = 0;
17303 +static struct acl_role_label *kernel_role = NULL;
17305 +static unsigned int gr_auth_attempts = 0;
17306 +static unsigned long gr_auth_expires = 0UL;
17308 +extern struct vfsmount *sock_mnt;
17309 +extern struct vfsmount *pipe_mnt;
17310 +extern struct vfsmount *shm_mnt;
17311 +static struct acl_object_label *fakefs_obj;
17313 +extern int gr_init_uidset(void);
17314 +extern void gr_free_uidset(void);
17315 +extern void gr_remove_uid(uid_t uid);
17316 +extern int gr_find_uid(uid_t uid);
17319 +gr_acl_is_enabled(void)
17321 + return (gr_status & GR_READY);
17324 +char gr_roletype_to_char(void)
17326 + switch (current->role->roletype &
17327 + (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
17328 + GR_ROLE_SPECIAL)) {
17329 + case GR_ROLE_DEFAULT:
17331 + case GR_ROLE_USER:
17333 + case GR_ROLE_GROUP:
17335 + case GR_ROLE_SPECIAL:
17343 +gr_acl_tpe_check(void)
17345 + if (unlikely(!(gr_status & GR_READY)))
17347 + if (current->role->roletype & GR_ROLE_TPE)
17354 +gr_handle_rawio(const struct inode *inode)
17356 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17357 + if (inode && S_ISBLK(inode->i_mode) &&
17358 + grsec_enable_chroot_caps && proc_is_chrooted(current) &&
17359 + !capable(CAP_SYS_RAWIO))
17366 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
17369 + unsigned long *l1;
17370 + unsigned long *l2;
17371 + unsigned char *c1;
17372 + unsigned char *c2;
17375 + if (likely(lena != lenb))
17378 + l1 = (unsigned long *)a;
17379 + l2 = (unsigned long *)b;
17381 + num_longs = lena / sizeof(unsigned long);
17383 + for (i = num_longs; i--; l1++, l2++) {
17384 + if (unlikely(*l1 != *l2))
17388 + c1 = (unsigned char *) l1;
17389 + c2 = (unsigned char *) l2;
17391 + i = lena - (num_longs * sizeof(unsigned long));
17393 + for (; i--; c1++, c2++) {
17394 + if (unlikely(*c1 != *c2))
17401 +static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17402 + struct dentry *root, struct vfsmount *rootmnt,
17403 + char *buffer, int buflen)
17405 + char * end = buffer+buflen;
17414 + /* Get '/' right */
17419 + struct dentry * parent;
17421 + if (dentry == root && vfsmnt == rootmnt)
17423 + if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
17424 + /* Global root? */
17425 + spin_lock(&vfsmount_lock);
17426 + if (vfsmnt->mnt_parent == vfsmnt) {
17427 + spin_unlock(&vfsmount_lock);
17428 + goto global_root;
17430 + dentry = vfsmnt->mnt_mountpoint;
17431 + vfsmnt = vfsmnt->mnt_parent;
17432 + spin_unlock(&vfsmount_lock);
17435 + parent = dentry->d_parent;
17436 + prefetch(parent);
17437 + namelen = dentry->d_name.len;
17438 + buflen -= namelen + 1;
17442 + memcpy(end, dentry->d_name.name, namelen);
17451 + namelen = dentry->d_name.len;
17452 + buflen -= namelen;
17455 + retval -= namelen-1; /* hit the slash */
17456 + memcpy(retval, dentry->d_name.name, namelen);
17459 + return ERR_PTR(-ENAMETOOLONG);
17463 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17464 + struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
17468 + retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
17469 + if (unlikely(IS_ERR(retval)))
17470 + retval = strcpy(buf, "<path too long>");
17471 + else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
17472 + retval[1] = '\0';
17478 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17479 + char *buf, int buflen)
17483 + /* we can use real_root, real_root_mnt, because this is only called
17484 + by the RBAC system */
17485 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
17491 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17492 + char *buf, int buflen)
17495 + struct dentry *root;
17496 + struct vfsmount *rootmnt;
17497 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
17499 + /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
17500 + read_lock(&reaper->fs->lock);
17501 + root = dget(reaper->fs->root.dentry);
17502 + rootmnt = mntget(reaper->fs->root.mnt);
17503 + read_unlock(&reaper->fs->lock);
17505 + spin_lock(&dcache_lock);
17506 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
17507 + spin_unlock(&dcache_lock);
17515 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
17518 + spin_lock(&dcache_lock);
17519 + ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17521 + spin_unlock(&dcache_lock);
17526 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
17528 + return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17533 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
17535 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
17540 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
17542 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
17547 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
17549 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
17554 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
17556 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
17561 +to_gr_audit(const __u32 reqmode)
17563 + /* masks off auditable permission flags, then shifts them to create
17564 + auditing flags, and adds the special case of append auditing if
17565 + we're requesting write */
17566 + return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
17569 +struct acl_subject_label *
17570 +lookup_subject_map(const struct acl_subject_label *userp)
17572 + unsigned int index = shash(userp, subj_map_set.s_size);
17573 + struct subject_map *match;
17575 + match = subj_map_set.s_hash[index];
17577 + while (match && match->user != userp)
17578 + match = match->next;
17580 + if (match != NULL)
17581 + return match->kernel;
17587 +insert_subj_map_entry(struct subject_map *subjmap)
17589 + unsigned int index = shash(subjmap->user, subj_map_set.s_size);
17590 + struct subject_map **curr;
17592 + subjmap->prev = NULL;
17594 + curr = &subj_map_set.s_hash[index];
17595 + if (*curr != NULL)
17596 + (*curr)->prev = subjmap;
17598 + subjmap->next = *curr;
17604 +static struct acl_role_label *
17605 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
17608 + unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
17609 + struct acl_role_label *match;
17610 + struct role_allowed_ip *ipp;
17613 + match = acl_role_set.r_hash[index];
17616 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
17617 + for (x = 0; x < match->domain_child_num; x++) {
17618 + if (match->domain_children[x] == uid)
17621 + } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
17623 + match = match->next;
17626 + if (match == NULL) {
17628 + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
17629 + match = acl_role_set.r_hash[index];
17632 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
17633 + for (x = 0; x < match->domain_child_num; x++) {
17634 + if (match->domain_children[x] == gid)
17637 + } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
17639 + match = match->next;
17642 + if (match == NULL)
17643 + match = default_role;
17644 + if (match->allowed_ips == NULL)
17647 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
17649 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
17650 + (ntohl(ipp->addr) & ipp->netmask)))
17653 + match = default_role;
17655 + } else if (match->allowed_ips == NULL) {
17658 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
17660 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
17661 + (ntohl(ipp->addr) & ipp->netmask)))
17670 +struct acl_subject_label *
17671 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
17672 + const struct acl_role_label *role)
17674 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
17675 + struct acl_subject_label *match;
17677 + match = role->subj_hash[index];
17679 + while (match && (match->inode != ino || match->device != dev ||
17680 + (match->mode & GR_DELETED))) {
17681 + match = match->next;
17684 + if (match && !(match->mode & GR_DELETED))
17690 +static struct acl_object_label *
17691 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
17692 + const struct acl_subject_label *subj)
17694 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
17695 + struct acl_object_label *match;
17697 + match = subj->obj_hash[index];
17699 + while (match && (match->inode != ino || match->device != dev ||
17700 + (match->mode & GR_DELETED))) {
17701 + match = match->next;
17704 + if (match && !(match->mode & GR_DELETED))
17710 +static struct acl_object_label *
17711 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
17712 + const struct acl_subject_label *subj)
17714 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
17715 + struct acl_object_label *match;
17717 + match = subj->obj_hash[index];
17719 + while (match && (match->inode != ino || match->device != dev ||
17720 + !(match->mode & GR_DELETED))) {
17721 + match = match->next;
17724 + if (match && (match->mode & GR_DELETED))
17727 + match = subj->obj_hash[index];
17729 + while (match && (match->inode != ino || match->device != dev ||
17730 + (match->mode & GR_DELETED))) {
17731 + match = match->next;
17734 + if (match && !(match->mode & GR_DELETED))
17740 +static struct name_entry *
17741 +lookup_name_entry(const char *name)
17743 + unsigned int len = strlen(name);
17744 + unsigned int key = full_name_hash(name, len);
17745 + unsigned int index = key % name_set.n_size;
17746 + struct name_entry *match;
17748 + match = name_set.n_hash[index];
17750 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
17751 + match = match->next;
17756 +static struct name_entry *
17757 +lookup_name_entry_create(const char *name)
17759 + unsigned int len = strlen(name);
17760 + unsigned int key = full_name_hash(name, len);
17761 + unsigned int index = key % name_set.n_size;
17762 + struct name_entry *match;
17764 + match = name_set.n_hash[index];
17766 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
17767 + !match->deleted))
17768 + match = match->next;
17770 + if (match && match->deleted)
17773 + match = name_set.n_hash[index];
17775 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
17777 + match = match->next;
17779 + if (match && !match->deleted)
17785 +static struct inodev_entry *
17786 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
17788 + unsigned int index = fhash(ino, dev, inodev_set.i_size);
17789 + struct inodev_entry *match;
17791 + match = inodev_set.i_hash[index];
17793 + while (match && (match->nentry->inode != ino || match->nentry->device != dev))
17794 + match = match->next;
17800 +insert_inodev_entry(struct inodev_entry *entry)
17802 + unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
17803 + inodev_set.i_size);
17804 + struct inodev_entry **curr;
17806 + entry->prev = NULL;
17808 + curr = &inodev_set.i_hash[index];
17809 + if (*curr != NULL)
17810 + (*curr)->prev = entry;
17812 + entry->next = *curr;
17819 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
17821 + unsigned int index =
17822 + rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
17823 + struct acl_role_label **curr;
17825 + role->prev = NULL;
17827 + curr = &acl_role_set.r_hash[index];
17828 + if (*curr != NULL)
17829 + (*curr)->prev = role;
17831 + role->next = *curr;
17838 +insert_acl_role_label(struct acl_role_label *role)
17842 + if (role->roletype & GR_ROLE_DOMAIN) {
17843 + for (i = 0; i < role->domain_child_num; i++)
17844 + __insert_acl_role_label(role, role->domain_children[i]);
17846 + __insert_acl_role_label(role, role->uidgid);
17850 +insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
17852 + struct name_entry **curr, *nentry;
17853 + struct inodev_entry *ientry;
17854 + unsigned int len = strlen(name);
17855 + unsigned int key = full_name_hash(name, len);
17856 + unsigned int index = key % name_set.n_size;
17858 + curr = &name_set.n_hash[index];
17860 + while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
17861 + curr = &((*curr)->next);
17863 + if (*curr != NULL)
17866 + nentry = acl_alloc(sizeof (struct name_entry));
17867 + if (nentry == NULL)
17869 + ientry = acl_alloc(sizeof (struct inodev_entry));
17870 + if (ientry == NULL)
17872 + ientry->nentry = nentry;
17874 + nentry->key = key;
17875 + nentry->name = name;
17876 + nentry->inode = inode;
17877 + nentry->device = device;
17878 + nentry->len = len;
17879 + nentry->deleted = deleted;
17881 + nentry->prev = NULL;
17882 + curr = &name_set.n_hash[index];
17883 + if (*curr != NULL)
17884 + (*curr)->prev = nentry;
17885 + nentry->next = *curr;
17888 + /* insert us into the table searchable by inode/dev */
17889 + insert_inodev_entry(ientry);
17895 +insert_acl_obj_label(struct acl_object_label *obj,
17896 + struct acl_subject_label *subj)
17898 + unsigned int index =
17899 + fhash(obj->inode, obj->device, subj->obj_hash_size);
17900 + struct acl_object_label **curr;
17903 + obj->prev = NULL;
17905 + curr = &subj->obj_hash[index];
17906 + if (*curr != NULL)
17907 + (*curr)->prev = obj;
17909 + obj->next = *curr;
17916 +insert_acl_subj_label(struct acl_subject_label *obj,
17917 + struct acl_role_label *role)
17919 + unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
17920 + struct acl_subject_label **curr;
17922 + obj->prev = NULL;
17924 + curr = &role->subj_hash[index];
17925 + if (*curr != NULL)
17926 + (*curr)->prev = obj;
17928 + obj->next = *curr;
17934 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
17937 +create_table(__u32 * len, int elementsize)
17939 + unsigned int table_sizes[] = {
17940 + 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
17941 + 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
17942 + 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
17943 + 268435399, 536870909, 1073741789, 2147483647
17945 + void *newtable = NULL;
17946 + unsigned int pwr = 0;
17948 + while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
17949 + table_sizes[pwr] <= *len)
17952 + if (table_sizes[pwr] <= *len)
17955 + if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
17957 + kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
17959 + newtable = vmalloc(table_sizes[pwr] * elementsize);
17961 + *len = table_sizes[pwr];
17967 +init_variables(const struct gr_arg *arg)
17969 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
17970 + unsigned int stacksize;
17972 + subj_map_set.s_size = arg->role_db.num_subjects;
17973 + acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
17974 + name_set.n_size = arg->role_db.num_objects;
17975 + inodev_set.i_size = arg->role_db.num_objects;
17977 + if (!subj_map_set.s_size || !acl_role_set.r_size ||
17978 + !name_set.n_size || !inodev_set.i_size)
17981 + if (!gr_init_uidset())
17984 + /* set up the stack that holds allocation info */
17986 + stacksize = arg->role_db.num_pointers + 5;
17988 + if (!acl_alloc_stack_init(stacksize))
17991 + /* grab reference for the real root dentry and vfsmount */
17992 + read_lock(&reaper->fs->lock);
17993 + real_root_mnt = mntget(reaper->fs->root.mnt);
17994 + real_root = dget(reaper->fs->root.dentry);
17995 + read_unlock(&reaper->fs->lock);
17997 + fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
17998 + if (fakefs_obj == NULL)
18000 + fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
18002 + subj_map_set.s_hash =
18003 + (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
18004 + acl_role_set.r_hash =
18005 + (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
18006 + name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
18007 + inodev_set.i_hash =
18008 + (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
18010 + if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
18011 + !name_set.n_hash || !inodev_set.i_hash)
18014 + memset(subj_map_set.s_hash, 0,
18015 + sizeof(struct subject_map *) * subj_map_set.s_size);
18016 + memset(acl_role_set.r_hash, 0,
18017 + sizeof (struct acl_role_label *) * acl_role_set.r_size);
18018 + memset(name_set.n_hash, 0,
18019 + sizeof (struct name_entry *) * name_set.n_size);
18020 + memset(inodev_set.i_hash, 0,
18021 + sizeof (struct inodev_entry *) * inodev_set.i_size);
18026 +/* free information not needed after startup
18027 + currently contains user->kernel pointer mappings for subjects
18031 +free_init_variables(void)
18035 + if (subj_map_set.s_hash) {
18036 + for (i = 0; i < subj_map_set.s_size; i++) {
18037 + if (subj_map_set.s_hash[i]) {
18038 + kfree(subj_map_set.s_hash[i]);
18039 + subj_map_set.s_hash[i] = NULL;
18043 + if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
18045 + kfree(subj_map_set.s_hash);
18047 + vfree(subj_map_set.s_hash);
18054 +free_variables(void)
18056 + struct acl_subject_label *s;
18057 + struct acl_role_label *r;
18058 + struct task_struct *task, *task2;
18059 + unsigned int i, x;
18061 + gr_clear_learn_entries();
18063 + read_lock(&tasklist_lock);
18064 + do_each_thread(task2, task) {
18065 + task->acl_sp_role = 0;
18066 + task->acl_role_id = 0;
18067 + task->acl = NULL;
18068 + task->role = NULL;
18069 + } while_each_thread(task2, task);
18070 + read_unlock(&tasklist_lock);
18072 + /* release the reference to the real root dentry and vfsmount */
18075 + real_root = NULL;
18076 + if (real_root_mnt)
18077 + mntput(real_root_mnt);
18078 + real_root_mnt = NULL;
18080 + /* free all object hash tables */
18082 + FOR_EACH_ROLE_START(r, i)
18083 + if (r->subj_hash == NULL)
18085 + FOR_EACH_SUBJECT_START(r, s, x)
18086 + if (s->obj_hash == NULL)
18088 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
18089 + kfree(s->obj_hash);
18091 + vfree(s->obj_hash);
18092 + FOR_EACH_SUBJECT_END(s, x)
18093 + FOR_EACH_NESTED_SUBJECT_START(r, s)
18094 + if (s->obj_hash == NULL)
18096 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
18097 + kfree(s->obj_hash);
18099 + vfree(s->obj_hash);
18100 + FOR_EACH_NESTED_SUBJECT_END(s)
18101 + if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
18102 + kfree(r->subj_hash);
18104 + vfree(r->subj_hash);
18105 + r->subj_hash = NULL;
18106 + FOR_EACH_ROLE_END(r,i)
18110 + if (acl_role_set.r_hash) {
18111 + if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
18113 + kfree(acl_role_set.r_hash);
18115 + vfree(acl_role_set.r_hash);
18117 + if (name_set.n_hash) {
18118 + if ((name_set.n_size * sizeof (struct name_entry *)) <=
18120 + kfree(name_set.n_hash);
18122 + vfree(name_set.n_hash);
18125 + if (inodev_set.i_hash) {
18126 + if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
18128 + kfree(inodev_set.i_hash);
18130 + vfree(inodev_set.i_hash);
18133 + gr_free_uidset();
18135 + memset(&name_set, 0, sizeof (struct name_db));
18136 + memset(&inodev_set, 0, sizeof (struct inodev_db));
18137 + memset(&acl_role_set, 0, sizeof (struct acl_role_db));
18138 + memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
18140 + default_role = NULL;
18146 +count_user_objs(struct acl_object_label *userp)
18148 + struct acl_object_label o_tmp;
18152 + if (copy_from_user(&o_tmp, userp,
18153 + sizeof (struct acl_object_label)))
18156 + userp = o_tmp.prev;
18163 +static struct acl_subject_label *
18164 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
18167 +copy_user_glob(struct acl_object_label *obj)
18169 + struct acl_object_label *g_tmp, **guser;
18170 + unsigned int len;
18173 + if (obj->globbed == NULL)
18176 + guser = &obj->globbed;
18178 + g_tmp = (struct acl_object_label *)
18179 + acl_alloc(sizeof (struct acl_object_label));
18180 + if (g_tmp == NULL)
18183 + if (copy_from_user(g_tmp, *guser,
18184 + sizeof (struct acl_object_label)))
18187 + len = strnlen_user(g_tmp->filename, PATH_MAX);
18189 + if (!len || len >= PATH_MAX)
18192 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18195 + if (copy_from_user(tmp, g_tmp->filename, len))
18198 + g_tmp->filename = tmp;
18201 + guser = &(g_tmp->next);
18208 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
18209 + struct acl_role_label *role)
18211 + struct acl_object_label *o_tmp;
18212 + unsigned int len;
18217 + if ((o_tmp = (struct acl_object_label *)
18218 + acl_alloc(sizeof (struct acl_object_label))) == NULL)
18221 + if (copy_from_user(o_tmp, userp,
18222 + sizeof (struct acl_object_label)))
18225 + userp = o_tmp->prev;
18227 + len = strnlen_user(o_tmp->filename, PATH_MAX);
18229 + if (!len || len >= PATH_MAX)
18232 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18235 + if (copy_from_user(tmp, o_tmp->filename, len))
18238 + o_tmp->filename = tmp;
18240 + insert_acl_obj_label(o_tmp, subj);
18241 + if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
18242 + o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
18245 + ret = copy_user_glob(o_tmp);
18249 + if (o_tmp->nested) {
18250 + o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
18251 + if (IS_ERR(o_tmp->nested))
18252 + return PTR_ERR(o_tmp->nested);
18254 + /* insert into nested subject list */
18255 + o_tmp->nested->next = role->hash->first;
18256 + role->hash->first = o_tmp->nested;
18264 +count_user_subjs(struct acl_subject_label *userp)
18266 + struct acl_subject_label s_tmp;
18270 + if (copy_from_user(&s_tmp, userp,
18271 + sizeof (struct acl_subject_label)))
18274 + userp = s_tmp.prev;
18275 + /* do not count nested subjects against this count, since
18276 + they are not included in the hash table, but are
18277 + attached to objects. We have already counted
18278 + the subjects in userspace for the allocation
18281 + if (!(s_tmp.mode & GR_NESTED))
18289 +copy_user_allowedips(struct acl_role_label *rolep)
18291 + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
18293 + ruserip = rolep->allowed_ips;
18295 + while (ruserip) {
18298 + if ((rtmp = (struct role_allowed_ip *)
18299 + acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
18302 + if (copy_from_user(rtmp, ruserip,
18303 + sizeof (struct role_allowed_ip)))
18306 + ruserip = rtmp->prev;
18309 + rtmp->prev = NULL;
18310 + rolep->allowed_ips = rtmp;
18312 + rlast->next = rtmp;
18313 + rtmp->prev = rlast;
18317 + rtmp->next = NULL;
18324 +copy_user_transitions(struct acl_role_label *rolep)
18326 + struct role_transition *rusertp, *rtmp = NULL, *rlast;
18328 + unsigned int len;
18331 + rusertp = rolep->transitions;
18333 + while (rusertp) {
18336 + if ((rtmp = (struct role_transition *)
18337 + acl_alloc(sizeof (struct role_transition))) == NULL)
18340 + if (copy_from_user(rtmp, rusertp,
18341 + sizeof (struct role_transition)))
18344 + rusertp = rtmp->prev;
18346 + len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
18348 + if (!len || len >= GR_SPROLE_LEN)
18351 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18354 + if (copy_from_user(tmp, rtmp->rolename, len))
18357 + rtmp->rolename = tmp;
18360 + rtmp->prev = NULL;
18361 + rolep->transitions = rtmp;
18363 + rlast->next = rtmp;
18364 + rtmp->prev = rlast;
18368 + rtmp->next = NULL;
18374 +static struct acl_subject_label *
18375 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
18377 + struct acl_subject_label *s_tmp = NULL, *s_tmp2;
18378 + unsigned int len;
18381 + struct acl_ip_label **i_tmp, *i_utmp2;
18382 + struct gr_hash_struct ghash;
18383 + struct subject_map *subjmap;
18384 + unsigned int i_num;
18387 + s_tmp = lookup_subject_map(userp);
18389 + /* we've already copied this subject into the kernel, just return
18390 + the reference to it, and don't copy it over again
18395 + if ((s_tmp = (struct acl_subject_label *)
18396 + acl_alloc(sizeof (struct acl_subject_label))) == NULL)
18397 + return ERR_PTR(-ENOMEM);
18399 + subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
18400 + if (subjmap == NULL)
18401 + return ERR_PTR(-ENOMEM);
18403 + subjmap->user = userp;
18404 + subjmap->kernel = s_tmp;
18405 + insert_subj_map_entry(subjmap);
18407 + if (copy_from_user(s_tmp, userp,
18408 + sizeof (struct acl_subject_label)))
18409 + return ERR_PTR(-EFAULT);
18411 + len = strnlen_user(s_tmp->filename, PATH_MAX);
18413 + if (!len || len >= PATH_MAX)
18414 + return ERR_PTR(-EINVAL);
18416 + if ((tmp = (char *) acl_alloc(len)) == NULL)
18417 + return ERR_PTR(-ENOMEM);
18419 + if (copy_from_user(tmp, s_tmp->filename, len))
18420 + return ERR_PTR(-EFAULT);
18422 + s_tmp->filename = tmp;
18424 + if (!strcmp(s_tmp->filename, "/"))
18425 + role->root_label = s_tmp;
18427 + if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
18428 + return ERR_PTR(-EFAULT);
18430 + /* copy user and group transition tables */
18432 + if (s_tmp->user_trans_num) {
18435 + uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
18436 + if (uidlist == NULL)
18437 + return ERR_PTR(-ENOMEM);
18438 + if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
18439 + return ERR_PTR(-EFAULT);
18441 + s_tmp->user_transitions = uidlist;
18444 + if (s_tmp->group_trans_num) {
18447 + gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
18448 + if (gidlist == NULL)
18449 + return ERR_PTR(-ENOMEM);
18450 + if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
18451 + return ERR_PTR(-EFAULT);
18453 + s_tmp->group_transitions = gidlist;
18456 + /* set up object hash table */
18457 + num_objs = count_user_objs(ghash.first);
18459 + s_tmp->obj_hash_size = num_objs;
18460 + s_tmp->obj_hash =
18461 + (struct acl_object_label **)
18462 + create_table(&(s_tmp->obj_hash_size), sizeof(void *));
18464 + if (!s_tmp->obj_hash)
18465 + return ERR_PTR(-ENOMEM);
18467 + memset(s_tmp->obj_hash, 0,
18468 + s_tmp->obj_hash_size *
18469 + sizeof (struct acl_object_label *));
18471 + /* add in objects */
18472 + err = copy_user_objs(ghash.first, s_tmp, role);
18475 + return ERR_PTR(err);
18477 + /* set pointer for parent subject */
18478 + if (s_tmp->parent_subject) {
18479 + s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
18481 + if (IS_ERR(s_tmp2))
18484 + s_tmp->parent_subject = s_tmp2;
18487 + /* add in ip acls */
18489 + if (!s_tmp->ip_num) {
18490 + s_tmp->ips = NULL;
18495 + (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
18497 + acl_ip_label *));
18500 + return ERR_PTR(-ENOMEM);
18502 + for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
18503 + *(i_tmp + i_num) =
18504 + (struct acl_ip_label *)
18505 + acl_alloc(sizeof (struct acl_ip_label));
18506 + if (!*(i_tmp + i_num))
18507 + return ERR_PTR(-ENOMEM);
18509 + if (copy_from_user
18510 + (&i_utmp2, s_tmp->ips + i_num,
18511 + sizeof (struct acl_ip_label *)))
18512 + return ERR_PTR(-EFAULT);
18514 + if (copy_from_user
18515 + (*(i_tmp + i_num), i_utmp2,
18516 + sizeof (struct acl_ip_label)))
18517 + return ERR_PTR(-EFAULT);
18519 + if ((*(i_tmp + i_num))->iface == NULL)
18522 + len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
18523 + if (!len || len >= IFNAMSIZ)
18524 + return ERR_PTR(-EINVAL);
18525 + tmp = acl_alloc(len);
18527 + return ERR_PTR(-ENOMEM);
18528 + if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
18529 + return ERR_PTR(-EFAULT);
18530 + (*(i_tmp + i_num))->iface = tmp;
18533 + s_tmp->ips = i_tmp;
18536 + if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
18537 + s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
18538 + return ERR_PTR(-ENOMEM);
18544 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
18546 + struct acl_subject_label s_pre;
18547 + struct acl_subject_label * ret;
18551 + if (copy_from_user(&s_pre, userp,
18552 + sizeof (struct acl_subject_label)))
18555 + /* do not add nested subjects here, add
18556 + while parsing objects
18559 + if (s_pre.mode & GR_NESTED) {
18560 + userp = s_pre.prev;
18564 + ret = do_copy_user_subj(userp, role);
18566 + err = PTR_ERR(ret);
18570 + insert_acl_subj_label(ret, role);
18572 + userp = s_pre.prev;
18579 +copy_user_acl(struct gr_arg *arg)
18581 + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
18582 + struct sprole_pw *sptmp;
18583 + struct gr_hash_struct *ghash;
18584 + uid_t *domainlist;
18585 + unsigned int r_num;
18586 + unsigned int len;
18592 + /* we need a default and kernel role */
18593 + if (arg->role_db.num_roles < 2)
18596 + /* copy special role authentication info from userspace */
18598 + num_sprole_pws = arg->num_sprole_pws;
18599 + acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
18601 + if (!acl_special_roles) {
18606 + for (i = 0; i < num_sprole_pws; i++) {
18607 + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
18612 + if (copy_from_user(sptmp, arg->sprole_pws + i,
18613 + sizeof (struct sprole_pw))) {
18619 + strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
18621 + if (!len || len >= GR_SPROLE_LEN) {
18626 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
18631 + if (copy_from_user(tmp, sptmp->rolename, len)) {
18636 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
18637 + printk(KERN_ALERT "Copying special role %s\n", tmp);
18639 + sptmp->rolename = tmp;
18640 + acl_special_roles[i] = sptmp;
18643 + r_utmp = (struct acl_role_label **) arg->role_db.r_table;
18645 + for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
18646 + r_tmp = acl_alloc(sizeof (struct acl_role_label));
18653 + if (copy_from_user(&r_utmp2, r_utmp + r_num,
18654 + sizeof (struct acl_role_label *))) {
18659 + if (copy_from_user(r_tmp, r_utmp2,
18660 + sizeof (struct acl_role_label))) {
18665 + len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
18667 + if (!len || len >= PATH_MAX) {
18672 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
18676 + if (copy_from_user(tmp, r_tmp->rolename, len)) {
18680 + r_tmp->rolename = tmp;
18682 + if (!strcmp(r_tmp->rolename, "default")
18683 + && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
18684 + default_role = r_tmp;
18685 + } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
18686 + kernel_role = r_tmp;
18689 + if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
18693 + if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
18698 + r_tmp->hash = ghash;
18700 + num_subjs = count_user_subjs(r_tmp->hash->first);
18702 + r_tmp->subj_hash_size = num_subjs;
18703 + r_tmp->subj_hash =
18704 + (struct acl_subject_label **)
18705 + create_table(&(r_tmp->subj_hash_size), sizeof(void *));
18707 + if (!r_tmp->subj_hash) {
18712 + err = copy_user_allowedips(r_tmp);
18716 + /* copy domain info */
18717 + if (r_tmp->domain_children != NULL) {
18718 + domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
18719 + if (domainlist == NULL) {
18723 + if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
18727 + r_tmp->domain_children = domainlist;
18730 + err = copy_user_transitions(r_tmp);
18734 + memset(r_tmp->subj_hash, 0,
18735 + r_tmp->subj_hash_size *
18736 + sizeof (struct acl_subject_label *));
18738 + err = copy_user_subjs(r_tmp->hash->first, r_tmp);
18743 + /* set nested subject list to null */
18744 + r_tmp->hash->first = NULL;
18746 + insert_acl_role_label(r_tmp);
18751 + free_variables();
18758 +gracl_init(struct gr_arg *args)
18762 + memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
18763 + memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
18765 + if (init_variables(args)) {
18766 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
18768 + free_variables();
18772 + error = copy_user_acl(args);
18773 + free_init_variables();
18775 + free_variables();
18779 + if ((error = gr_set_acls(0))) {
18780 + free_variables();
18784 + gr_status |= GR_READY;
18789 +/* derived from glibc fnmatch() 0: match, 1: no match*/
18792 +glob_match(const char *p, const char *n)
18796 + while ((c = *p++) != '\0') {
18801 + else if (*n == '/')
18809 + for (c = *p++; c == '?' || c == '*'; c = *p++) {
18812 + else if (c == '?') {
18822 + const char *endp;
18824 + if ((endp = strchr(n, '/')) == NULL)
18825 + endp = n + strlen(n);
18828 + for (--p; n < endp; ++n)
18829 + if (!glob_match(p, n))
18831 + } else if (c == '/') {
18832 + while (*n != '\0' && *n != '/')
18834 + if (*n == '/' && !glob_match(p, n + 1))
18837 + for (--p; n < endp; ++n)
18838 + if (*n == c && !glob_match(p, n))
18849 + if (*n == '\0' || *n == '/')
18852 + not = (*p == '!' || *p == '^');
18858 + unsigned char fn = (unsigned char)*n;
18868 + if (c == '-' && *p != ']') {
18869 + unsigned char cend = *p++;
18871 + if (cend == '\0')
18874 + if (cold <= fn && fn <= cend)
18888 + while (c != ']') {
18915 +static struct acl_object_label *
18916 +chk_glob_label(struct acl_object_label *globbed,
18917 + struct dentry *dentry, struct vfsmount *mnt, char **path)
18919 + struct acl_object_label *tmp;
18921 + if (*path == NULL)
18922 + *path = gr_to_filename_nolock(dentry, mnt);
18927 + if (!glob_match(tmp->filename, *path))
18935 +static struct acl_object_label *
18936 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
18937 + const ino_t curr_ino, const dev_t curr_dev,
18938 + const struct acl_subject_label *subj, char **path)
18940 + struct acl_subject_label *tmpsubj;
18941 + struct acl_object_label *retval;
18942 + struct acl_object_label *retval2;
18944 + tmpsubj = (struct acl_subject_label *) subj;
18945 + read_lock(&gr_inode_lock);
18947 + retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
18949 + if (retval->globbed) {
18950 + retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
18951 + (struct vfsmount *)orig_mnt, path);
18953 + retval = retval2;
18957 + } while ((tmpsubj = tmpsubj->parent_subject));
18958 + read_unlock(&gr_inode_lock);
18963 +static __inline__ struct acl_object_label *
18964 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
18965 + const struct dentry *curr_dentry,
18966 + const struct acl_subject_label *subj, char **path)
18968 + return __full_lookup(orig_dentry, orig_mnt,
18969 + curr_dentry->d_inode->i_ino,
18970 + curr_dentry->d_inode->i_sb->s_dev, subj, path);
18973 +static struct acl_object_label *
18974 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
18975 + const struct acl_subject_label *subj, char *path)
18977 + struct dentry *dentry = (struct dentry *) l_dentry;
18978 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
18979 + struct acl_object_label *retval;
18981 + spin_lock(&dcache_lock);
18983 + if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
18984 + /* ignore Eric Biederman */
18985 + IS_PRIVATE(l_dentry->d_inode))) {
18986 + retval = fakefs_obj;
18991 + if (dentry == real_root && mnt == real_root_mnt)
18994 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
18995 + if (mnt->mnt_parent == mnt)
18998 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
18999 + if (retval != NULL)
19002 + dentry = mnt->mnt_mountpoint;
19003 + mnt = mnt->mnt_parent;
19007 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19008 + if (retval != NULL)
19011 + dentry = dentry->d_parent;
19014 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19016 + if (retval == NULL)
19017 + retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
19019 + spin_unlock(&dcache_lock);
19023 +static __inline__ struct acl_object_label *
19024 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19025 + const struct acl_subject_label *subj)
19027 + char *path = NULL;
19028 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
19031 +static __inline__ struct acl_object_label *
19032 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19033 + const struct acl_subject_label *subj, char *path)
19035 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
19038 +static struct acl_subject_label *
19039 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19040 + const struct acl_role_label *role)
19042 + struct dentry *dentry = (struct dentry *) l_dentry;
19043 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
19044 + struct acl_subject_label *retval;
19046 + spin_lock(&dcache_lock);
19049 + if (dentry == real_root && mnt == real_root_mnt)
19051 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
19052 + if (mnt->mnt_parent == mnt)
19055 + read_lock(&gr_inode_lock);
19057 + lookup_acl_subj_label(dentry->d_inode->i_ino,
19058 + dentry->d_inode->i_sb->s_dev, role);
19059 + read_unlock(&gr_inode_lock);
19060 + if (retval != NULL)
19063 + dentry = mnt->mnt_mountpoint;
19064 + mnt = mnt->mnt_parent;
19068 + read_lock(&gr_inode_lock);
19069 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
19070 + dentry->d_inode->i_sb->s_dev, role);
19071 + read_unlock(&gr_inode_lock);
19072 + if (retval != NULL)
19075 + dentry = dentry->d_parent;
19078 + read_lock(&gr_inode_lock);
19079 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
19080 + dentry->d_inode->i_sb->s_dev, role);
19081 + read_unlock(&gr_inode_lock);
19083 + if (unlikely(retval == NULL)) {
19084 + read_lock(&gr_inode_lock);
19085 + retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
19086 + real_root->d_inode->i_sb->s_dev, role);
19087 + read_unlock(&gr_inode_lock);
19090 + spin_unlock(&dcache_lock);
19096 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
19098 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
19099 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19100 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19101 + 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
19107 +gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
19109 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
19110 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19111 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19112 + 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
19118 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
19119 + const unsigned int effective, const unsigned int fs)
19121 + security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
19122 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19123 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19124 + type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
19130 +gr_check_link(const struct dentry * new_dentry,
19131 + const struct dentry * parent_dentry,
19132 + const struct vfsmount * parent_mnt,
19133 + const struct dentry * old_dentry, const struct vfsmount * old_mnt)
19135 + struct acl_object_label *obj;
19136 + __u32 oldmode, newmode;
19139 + if (unlikely(!(gr_status & GR_READY)))
19140 + return (GR_CREATE | GR_LINK);
19142 + obj = chk_obj_label(old_dentry, old_mnt, current->acl);
19143 + oldmode = obj->mode;
19145 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19146 + oldmode |= (GR_CREATE | GR_LINK);
19148 + needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
19149 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
19150 + needmode |= GR_SETID | GR_AUDIT_SETID;
19153 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
19154 + oldmode | needmode);
19156 + needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
19157 + GR_SETID | GR_READ | GR_FIND | GR_DELETE |
19158 + GR_INHERIT | GR_AUDIT_INHERIT);
19160 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
19163 + if ((oldmode & needmode) != needmode)
19166 + needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
19167 + if ((newmode & needmode) != needmode)
19170 + if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
19173 + needmode = oldmode;
19174 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
19175 + needmode |= GR_SETID;
19177 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
19178 + gr_log_learn(current, old_dentry, old_mnt, needmode);
19179 + return (GR_CREATE | GR_LINK);
19180 + } else if (newmode & GR_SUPPRESS)
19181 + return GR_SUPPRESS;
19187 +gr_search_file(const struct dentry * dentry, const __u32 mode,
19188 + const struct vfsmount * mnt)
19190 + __u32 retval = mode;
19191 + struct acl_subject_label *curracl;
19192 + struct acl_object_label *currobj;
19194 + if (unlikely(!(gr_status & GR_READY)))
19195 + return (mode & ~GR_AUDITS);
19197 + curracl = current->acl;
19199 + currobj = chk_obj_label(dentry, mnt, curracl);
19200 + retval = currobj->mode & mode;
19203 + ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
19204 + && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
19205 + __u32 new_mode = mode;
19207 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19209 + retval = new_mode;
19211 + if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
19212 + new_mode |= GR_INHERIT;
19214 + if (!(mode & GR_NOLEARN))
19215 + gr_log_learn(current, dentry, mnt, new_mode);
19222 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
19223 + const struct vfsmount * mnt, const __u32 mode)
19225 + struct name_entry *match;
19226 + struct acl_object_label *matchpo;
19227 + struct acl_subject_label *curracl;
19231 + if (unlikely(!(gr_status & GR_READY)))
19232 + return (mode & ~GR_AUDITS);
19234 + preempt_disable();
19235 + path = gr_to_filename_rbac(new_dentry, mnt);
19236 + match = lookup_name_entry_create(path);
19239 + goto check_parent;
19241 + curracl = current->acl;
19243 + read_lock(&gr_inode_lock);
19244 + matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
19245 + read_unlock(&gr_inode_lock);
19248 + if ((matchpo->mode & mode) !=
19249 + (mode & ~(GR_AUDITS | GR_SUPPRESS))
19250 + && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
19251 + __u32 new_mode = mode;
19253 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19255 + gr_log_learn(current, new_dentry, mnt, new_mode);
19257 + preempt_enable();
19260 + preempt_enable();
19261 + return (matchpo->mode & mode);
19265 + curracl = current->acl;
19267 + matchpo = chk_obj_create_label(parent, mnt, curracl, path);
19268 + retval = matchpo->mode & mode;
19270 + if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
19271 + && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
19272 + __u32 new_mode = mode;
19274 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19276 + gr_log_learn(current, new_dentry, mnt, new_mode);
19277 + preempt_enable();
19281 + preempt_enable();
19286 +gr_check_hidden_task(const struct task_struct *task)
19288 + if (unlikely(!(gr_status & GR_READY)))
19291 + if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
19298 +gr_check_protected_task(const struct task_struct *task)
19300 + if (unlikely(!(gr_status & GR_READY) || !task))
19303 + if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
19304 + task->acl != current->acl)
19311 +gr_copy_label(struct task_struct *tsk)
19313 + tsk->signal->used_accept = 0;
19314 + tsk->acl_sp_role = 0;
19315 + tsk->acl_role_id = current->acl_role_id;
19316 + tsk->acl = current->acl;
19317 + tsk->role = current->role;
19318 + tsk->signal->curr_ip = current->signal->curr_ip;
19319 + if (current->exec_file)
19320 + get_file(current->exec_file);
19321 + tsk->exec_file = current->exec_file;
19322 + tsk->is_writable = current->is_writable;
19323 + if (unlikely(current->signal->used_accept))
19324 + current->signal->curr_ip = 0;
19330 +gr_set_proc_res(struct task_struct *task)
19332 + struct acl_subject_label *proc;
19333 + unsigned short i;
19335 + proc = task->acl;
19337 + if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
19340 + for (i = 0; i < (GR_NLIMITS - 1); i++) {
19341 + if (!(proc->resmask & (1 << i)))
19344 + task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
19345 + task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
19352 +gr_check_user_change(int real, int effective, int fs)
19359 + int effectiveok = 0;
19362 + if (unlikely(!(gr_status & GR_READY)))
19365 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19366 + gr_log_learn_id_change(current, 'u', real, effective, fs);
19368 + num = current->acl->user_trans_num;
19369 + uidlist = current->acl->user_transitions;
19371 + if (uidlist == NULL)
19376 + if (effective == -1)
19381 + if (current->acl->user_trans_type & GR_ID_ALLOW) {
19382 + for (i = 0; i < num; i++) {
19383 + curuid = (int)uidlist[i];
19384 + if (real == curuid)
19386 + if (effective == curuid)
19388 + if (fs == curuid)
19391 + } else if (current->acl->user_trans_type & GR_ID_DENY) {
19392 + for (i = 0; i < num; i++) {
19393 + curuid = (int)uidlist[i];
19394 + if (real == curuid)
19396 + if (effective == curuid)
19398 + if (fs == curuid)
19401 + /* not in deny list */
19409 + if (realok && effectiveok && fsok)
19412 + gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19418 +gr_check_group_change(int real, int effective, int fs)
19425 + int effectiveok = 0;
19428 + if (unlikely(!(gr_status & GR_READY)))
19431 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19432 + gr_log_learn_id_change(current, 'g', real, effective, fs);
19434 + num = current->acl->group_trans_num;
19435 + gidlist = current->acl->group_transitions;
19437 + if (gidlist == NULL)
19442 + if (effective == -1)
19447 + if (current->acl->group_trans_type & GR_ID_ALLOW) {
19448 + for (i = 0; i < num; i++) {
19449 + curgid = (int)gidlist[i];
19450 + if (real == curgid)
19452 + if (effective == curgid)
19454 + if (fs == curgid)
19457 + } else if (current->acl->group_trans_type & GR_ID_DENY) {
19458 + for (i = 0; i < num; i++) {
19459 + curgid = (int)gidlist[i];
19460 + if (real == curgid)
19462 + if (effective == curgid)
19464 + if (fs == curgid)
19467 + /* not in deny list */
19475 + if (realok && effectiveok && fsok)
19478 + gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19484 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
19486 + struct acl_role_label *role = task->role;
19487 + struct acl_subject_label *subj = NULL;
19488 + struct acl_object_label *obj;
19489 + struct file *filp;
19491 + if (unlikely(!(gr_status & GR_READY)))
19494 + filp = task->exec_file;
19496 + /* kernel process, we'll give them the kernel role */
19497 + if (unlikely(!filp)) {
19498 + task->role = kernel_role;
19499 + task->acl = kernel_role->root_label;
19501 + } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
19502 + role = lookup_acl_role_label(task, uid, gid);
19504 + /* perform subject lookup in possibly new role
19505 + we can use this result below in the case where role == task->role
19507 + subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
19509 + /* if we changed uid/gid, but result in the same role
19510 + and are using inheritance, don't lose the inherited subject
19511 + if current subject is other than what normal lookup
19512 + would result in, we arrived via inheritance, don't
19515 + if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
19516 + (subj == task->acl)))
19517 + task->acl = subj;
19519 + task->role = role;
19521 + task->is_writable = 0;
19523 + /* ignore additional mmap checks for processes that are writable
19524 + by the default ACL */
19525 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
19526 + if (unlikely(obj->mode & GR_WRITE))
19527 + task->is_writable = 1;
19528 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
19529 + if (unlikely(obj->mode & GR_WRITE))
19530 + task->is_writable = 1;
19532 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19533 + printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19536 + gr_set_proc_res(task);
19542 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
19544 + struct task_struct *task = current;
19545 + struct acl_subject_label *newacl;
19546 + struct acl_object_label *obj;
19549 + if (unlikely(!(gr_status & GR_READY)))
19552 + newacl = chk_subj_label(dentry, mnt, task->role);
19555 + if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
19556 + GR_POVERRIDE) && (task->acl != newacl) &&
19557 + !(task->role->roletype & GR_ROLE_GOD) &&
19558 + !gr_search_file(dentry, GR_PTRACERD, mnt) &&
19559 + !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
19560 + (atomic_read(&task->fs->count) > 1 ||
19561 + atomic_read(&task->files->count) > 1 ||
19562 + atomic_read(&task->sighand->count) > 1)) {
19563 + task_unlock(task);
19564 + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
19567 + task_unlock(task);
19569 + obj = chk_obj_label(dentry, mnt, task->acl);
19570 + retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
19572 + if (!(task->acl->mode & GR_INHERITLEARN) &&
19573 + ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
19575 + task->acl = obj->nested;
19577 + task->acl = newacl;
19578 + } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
19579 + gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
19581 + task->is_writable = 0;
19583 + /* ignore additional mmap checks for processes that are writable
19584 + by the default ACL */
19585 + obj = chk_obj_label(dentry, mnt, default_role->root_label);
19586 + if (unlikely(obj->mode & GR_WRITE))
19587 + task->is_writable = 1;
19588 + obj = chk_obj_label(dentry, mnt, task->role->root_label);
19589 + if (unlikely(obj->mode & GR_WRITE))
19590 + task->is_writable = 1;
19592 + gr_set_proc_res(task);
19594 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19595 + printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19600 +/* always called with valid inodev ptr */
19602 +do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
19604 + struct acl_object_label *matchpo;
19605 + struct acl_subject_label *matchps;
19606 + struct acl_subject_label *subj;
19607 + struct acl_role_label *role;
19608 + unsigned int i, x;
19610 + FOR_EACH_ROLE_START(role, i)
19611 + FOR_EACH_SUBJECT_START(role, subj, x)
19612 + if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
19613 + matchpo->mode |= GR_DELETED;
19614 + FOR_EACH_SUBJECT_END(subj,x)
19615 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
19616 + if (subj->inode == ino && subj->device == dev)
19617 + subj->mode |= GR_DELETED;
19618 + FOR_EACH_NESTED_SUBJECT_END(subj)
19619 + if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
19620 + matchps->mode |= GR_DELETED;
19621 + FOR_EACH_ROLE_END(role,i)
19623 + inodev->nentry->deleted = 1;
19629 +gr_handle_delete(const ino_t ino, const dev_t dev)
19631 + struct inodev_entry *inodev;
19633 + if (unlikely(!(gr_status & GR_READY)))
19636 + write_lock(&gr_inode_lock);
19637 + inodev = lookup_inodev_entry(ino, dev);
19638 + if (inodev != NULL)
19639 + do_handle_delete(inodev, ino, dev);
19640 + write_unlock(&gr_inode_lock);
19646 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
19647 + const ino_t newinode, const dev_t newdevice,
19648 + struct acl_subject_label *subj)
19650 + unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
19651 + struct acl_object_label *match;
19653 + match = subj->obj_hash[index];
19655 + while (match && (match->inode != oldinode ||
19656 + match->device != olddevice ||
19657 + !(match->mode & GR_DELETED)))
19658 + match = match->next;
19660 + if (match && (match->inode == oldinode)
19661 + && (match->device == olddevice)
19662 + && (match->mode & GR_DELETED)) {
19663 + if (match->prev == NULL) {
19664 + subj->obj_hash[index] = match->next;
19665 + if (match->next != NULL)
19666 + match->next->prev = NULL;
19668 + match->prev->next = match->next;
19669 + if (match->next != NULL)
19670 + match->next->prev = match->prev;
19672 + match->prev = NULL;
19673 + match->next = NULL;
19674 + match->inode = newinode;
19675 + match->device = newdevice;
19676 + match->mode &= ~GR_DELETED;
19678 + insert_acl_obj_label(match, subj);
19685 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
19686 + const ino_t newinode, const dev_t newdevice,
19687 + struct acl_role_label *role)
19689 + unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
19690 + struct acl_subject_label *match;
19692 + match = role->subj_hash[index];
19694 + while (match && (match->inode != oldinode ||
19695 + match->device != olddevice ||
19696 + !(match->mode & GR_DELETED)))
19697 + match = match->next;
19699 + if (match && (match->inode == oldinode)
19700 + && (match->device == olddevice)
19701 + && (match->mode & GR_DELETED)) {
19702 + if (match->prev == NULL) {
19703 + role->subj_hash[index] = match->next;
19704 + if (match->next != NULL)
19705 + match->next->prev = NULL;
19707 + match->prev->next = match->next;
19708 + if (match->next != NULL)
19709 + match->next->prev = match->prev;
19711 + match->prev = NULL;
19712 + match->next = NULL;
19713 + match->inode = newinode;
19714 + match->device = newdevice;
19715 + match->mode &= ~GR_DELETED;
19717 + insert_acl_subj_label(match, role);
19724 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
19725 + const ino_t newinode, const dev_t newdevice)
19727 + unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
19728 + struct inodev_entry *match;
19730 + match = inodev_set.i_hash[index];
19732 + while (match && (match->nentry->inode != oldinode ||
19733 + match->nentry->device != olddevice || !match->nentry->deleted))
19734 + match = match->next;
19736 + if (match && (match->nentry->inode == oldinode)
19737 + && (match->nentry->device == olddevice) &&
19738 + match->nentry->deleted) {
19739 + if (match->prev == NULL) {
19740 + inodev_set.i_hash[index] = match->next;
19741 + if (match->next != NULL)
19742 + match->next->prev = NULL;
19744 + match->prev->next = match->next;
19745 + if (match->next != NULL)
19746 + match->next->prev = match->prev;
19748 + match->prev = NULL;
19749 + match->next = NULL;
19750 + match->nentry->inode = newinode;
19751 + match->nentry->device = newdevice;
19752 + match->nentry->deleted = 0;
19754 + insert_inodev_entry(match);
19761 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
19762 + const struct vfsmount *mnt)
19764 + struct acl_subject_label *subj;
19765 + struct acl_role_label *role;
19766 + unsigned int i, x;
19768 + FOR_EACH_ROLE_START(role, i)
19769 + update_acl_subj_label(matchn->inode, matchn->device,
19770 + dentry->d_inode->i_ino,
19771 + dentry->d_inode->i_sb->s_dev, role);
19773 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
19774 + if ((subj->inode == dentry->d_inode->i_ino) &&
19775 + (subj->device == dentry->d_inode->i_sb->s_dev)) {
19776 + subj->inode = dentry->d_inode->i_ino;
19777 + subj->device = dentry->d_inode->i_sb->s_dev;
19779 + FOR_EACH_NESTED_SUBJECT_END(subj)
19780 + FOR_EACH_SUBJECT_START(role, subj, x)
19781 + update_acl_obj_label(matchn->inode, matchn->device,
19782 + dentry->d_inode->i_ino,
19783 + dentry->d_inode->i_sb->s_dev, subj);
19784 + FOR_EACH_SUBJECT_END(subj,x)
19785 + FOR_EACH_ROLE_END(role,i)
19787 + update_inodev_entry(matchn->inode, matchn->device,
19788 + dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
19794 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
19796 + struct name_entry *matchn;
19798 + if (unlikely(!(gr_status & GR_READY)))
19801 + preempt_disable();
19802 + matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
19804 + if (unlikely((unsigned long)matchn)) {
19805 + write_lock(&gr_inode_lock);
19806 + do_handle_create(matchn, dentry, mnt);
19807 + write_unlock(&gr_inode_lock);
19809 + preempt_enable();
19815 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
19816 + struct dentry *old_dentry,
19817 + struct dentry *new_dentry,
19818 + struct vfsmount *mnt, const __u8 replace)
19820 + struct name_entry *matchn;
19821 + struct inodev_entry *inodev;
19823 + /* vfs_rename swaps the name and parent link for old_dentry and
19825 + at this point, old_dentry has the new name, parent link, and inode
19826 + for the renamed file
19827 + if a file is being replaced by a rename, new_dentry has the inode
19828 + and name for the replaced file
19831 + if (unlikely(!(gr_status & GR_READY)))
19834 + preempt_disable();
19835 + matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
19837 + /* we wouldn't have to check d_inode if it weren't for
19838 + NFS silly-renaming
19841 + write_lock(&gr_inode_lock);
19842 + if (unlikely(replace && new_dentry->d_inode)) {
19843 + inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
19844 + new_dentry->d_inode->i_sb->s_dev);
19845 + if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
19846 + do_handle_delete(inodev, new_dentry->d_inode->i_ino,
19847 + new_dentry->d_inode->i_sb->s_dev);
19850 + inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
19851 + old_dentry->d_inode->i_sb->s_dev);
19852 + if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
19853 + do_handle_delete(inodev, old_dentry->d_inode->i_ino,
19854 + old_dentry->d_inode->i_sb->s_dev);
19856 + if (unlikely((unsigned long)matchn))
19857 + do_handle_create(matchn, old_dentry, mnt);
19859 + write_unlock(&gr_inode_lock);
19860 + preempt_enable();
19866 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
19867 + unsigned char **sum)
19869 + struct acl_role_label *r;
19870 + struct role_allowed_ip *ipp;
19871 + struct role_transition *trans;
19875 + /* check transition table */
19877 + for (trans = current->role->transitions; trans; trans = trans->next) {
19878 + if (!strcmp(rolename, trans->rolename)) {
19887 + /* handle special roles that do not require authentication
19890 + FOR_EACH_ROLE_START(r, i)
19891 + if (!strcmp(rolename, r->rolename) &&
19892 + (r->roletype & GR_ROLE_SPECIAL)) {
19894 + if (r->allowed_ips != NULL) {
19895 + for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
19896 + if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
19897 + (ntohl(ipp->addr) & ipp->netmask))
19905 + if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
19906 + ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
19912 + FOR_EACH_ROLE_END(r,i)
19914 + for (i = 0; i < num_sprole_pws; i++) {
19915 + if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
19916 + *salt = acl_special_roles[i]->salt;
19917 + *sum = acl_special_roles[i]->sum;
19926 +assign_special_role(char *rolename)
19928 + struct acl_object_label *obj;
19929 + struct acl_role_label *r;
19930 + struct acl_role_label *assigned = NULL;
19931 + struct task_struct *tsk;
19932 + struct file *filp;
19935 + FOR_EACH_ROLE_START(r, i)
19936 + if (!strcmp(rolename, r->rolename) &&
19937 + (r->roletype & GR_ROLE_SPECIAL))
19939 + FOR_EACH_ROLE_END(r,i)
19944 + read_lock(&tasklist_lock);
19945 + read_lock(&grsec_exec_file_lock);
19947 + tsk = current->parent;
19951 + filp = tsk->exec_file;
19952 + if (filp == NULL)
19955 + tsk->is_writable = 0;
19957 + tsk->acl_sp_role = 1;
19958 + tsk->acl_role_id = ++acl_sp_role_value;
19959 + tsk->role = assigned;
19960 + tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
19962 + /* ignore additional mmap checks for processes that are writable
19963 + by the default ACL */
19964 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
19965 + if (unlikely(obj->mode & GR_WRITE))
19966 + tsk->is_writable = 1;
19967 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
19968 + if (unlikely(obj->mode & GR_WRITE))
19969 + tsk->is_writable = 1;
19971 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19972 + printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
19976 + read_unlock(&grsec_exec_file_lock);
19977 + read_unlock(&tasklist_lock);
19981 +int gr_check_secure_terminal(struct task_struct *task)
19983 + struct task_struct *p, *p2, *p3;
19984 + struct files_struct *files;
19985 + struct fdtable *fdt;
19986 + struct file *our_file = NULL, *file;
19989 + if (task->signal->tty == NULL)
19992 + files = get_files_struct(task);
19993 + if (files != NULL) {
19995 + fdt = files_fdtable(files);
19996 + for (i=0; i < fdt->max_fds; i++) {
19997 + file = fcheck_files(files, i);
19998 + if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
20003 + rcu_read_unlock();
20004 + put_files_struct(files);
20007 + if (our_file == NULL)
20010 + read_lock(&tasklist_lock);
20011 + do_each_thread(p2, p) {
20012 + files = get_files_struct(p);
20013 + if (files == NULL ||
20014 + (p->signal && p->signal->tty == task->signal->tty)) {
20015 + if (files != NULL)
20016 + put_files_struct(files);
20020 + fdt = files_fdtable(files);
20021 + for (i=0; i < fdt->max_fds; i++) {
20022 + file = fcheck_files(files, i);
20023 + if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
20024 + file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
20026 + while (p3->pid > 0) {
20033 + gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
20034 + gr_handle_alertkill(p);
20035 + rcu_read_unlock();
20036 + put_files_struct(files);
20037 + read_unlock(&tasklist_lock);
20042 + rcu_read_unlock();
20043 + put_files_struct(files);
20044 + } while_each_thread(p2, p);
20045 + read_unlock(&tasklist_lock);
20052 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
20054 + struct gr_arg_wrapper uwrap;
20055 + unsigned char *sprole_salt;
20056 + unsigned char *sprole_sum;
20057 + int error = sizeof (struct gr_arg_wrapper);
20060 + down(&gr_dev_sem);
20062 + if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
20067 + if (count != sizeof (struct gr_arg_wrapper)) {
20068 + gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
20074 + if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
20075 + gr_auth_expires = 0;
20076 + gr_auth_attempts = 0;
20079 + if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
20084 + if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
20089 + if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
20094 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
20095 + gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
20096 + time_after(gr_auth_expires, get_seconds())) {
20101 + /* if non-root trying to do anything other than use a special role,
20102 + do not attempt authentication, do not count towards authentication
20106 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
20107 + gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
20113 + /* ensure pw and special role name are null terminated */
20115 + gr_usermode->pw[GR_PW_LEN - 1] = '\0';
20116 + gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
20119 + * We have our enough of the argument structure..(we have yet
20120 + * to copy_from_user the tables themselves) . Copy the tables
20121 + * only if we need them, i.e. for loading operations. */
20123 + switch (gr_usermode->mode) {
20125 + if (gr_status & GR_READY) {
20127 + if (!gr_check_secure_terminal(current))
20133 + if ((gr_status & GR_READY)
20134 + && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20135 + gr_status &= ~GR_READY;
20136 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
20137 + free_variables();
20138 + memset(gr_usermode, 0, sizeof (struct gr_arg));
20139 + memset(gr_system_salt, 0, GR_SALT_LEN);
20140 + memset(gr_system_sum, 0, GR_SHA_LEN);
20141 + } else if (gr_status & GR_READY) {
20142 + gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
20145 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
20150 + if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
20151 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
20153 + if (gr_status & GR_READY)
20157 + gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
20161 + if (!(gr_status & GR_READY)) {
20162 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
20164 + } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20166 + gr_status &= ~GR_READY;
20167 + free_variables();
20168 + if (!(error2 = gracl_init(gr_usermode))) {
20170 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
20174 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
20177 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
20182 + if (unlikely(!(gr_status & GR_READY))) {
20183 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
20188 + if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20189 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
20190 + if (gr_usermode->segv_device && gr_usermode->segv_inode) {
20191 + struct acl_subject_label *segvacl;
20193 + lookup_acl_subj_label(gr_usermode->segv_inode,
20194 + gr_usermode->segv_device,
20197 + segvacl->crashes = 0;
20198 + segvacl->expires = 0;
20200 + } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
20201 + gr_remove_uid(gr_usermode->segv_uid);
20204 + gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
20210 + if (unlikely(!(gr_status & GR_READY))) {
20211 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
20216 + if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
20217 + current->role->expires = 0;
20218 + current->role->auth_attempts = 0;
20221 + if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
20222 + time_after(current->role->expires, get_seconds())) {
20227 + if (lookup_special_role_auth
20228 + (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
20229 + && ((!sprole_salt && !sprole_sum)
20230 + || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
20232 + assign_special_role(gr_usermode->sp_role);
20233 + read_lock(&tasklist_lock);
20234 + if (current->parent)
20235 + p = current->parent->role->rolename;
20236 + read_unlock(&tasklist_lock);
20237 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
20238 + p, acl_sp_role_value);
20240 + gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
20242 + if(!(current->role->auth_attempts++))
20243 + current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20249 + if (unlikely(!(gr_status & GR_READY))) {
20250 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
20255 + if (current->role->roletype & GR_ROLE_SPECIAL) {
20259 + read_lock(&tasklist_lock);
20260 + if (current->parent) {
20261 + p = current->parent->role->rolename;
20262 + i = current->parent->acl_role_id;
20264 + read_unlock(&tasklist_lock);
20266 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
20269 + gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
20275 + gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
20280 + if (error != -EPERM)
20283 + if(!(gr_auth_attempts++))
20284 + gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20292 +gr_set_acls(const int type)
20294 + struct acl_object_label *obj;
20295 + struct task_struct *task, *task2;
20296 + struct file *filp;
20297 + struct acl_role_label *role = current->role;
20298 + __u16 acl_role_id = current->acl_role_id;
20300 + read_lock(&tasklist_lock);
20301 + read_lock(&grsec_exec_file_lock);
20302 + do_each_thread(task2, task) {
20303 + /* check to see if we're called from the exit handler,
20304 + if so, only replace ACLs that have inherited the admin
20307 + if (type && (task->role != role ||
20308 + task->acl_role_id != acl_role_id))
20311 + task->acl_role_id = 0;
20312 + task->acl_sp_role = 0;
20314 + if ((filp = task->exec_file)) {
20315 + task->role = lookup_acl_role_label(task, task->uid, task->gid);
20318 + chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
20321 + struct acl_subject_label *curr;
20322 + curr = task->acl;
20324 + task->is_writable = 0;
20325 + /* ignore additional mmap checks for processes that are writable
20326 + by the default ACL */
20327 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20328 + if (unlikely(obj->mode & GR_WRITE))
20329 + task->is_writable = 1;
20330 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
20331 + if (unlikely(obj->mode & GR_WRITE))
20332 + task->is_writable = 1;
20334 + gr_set_proc_res(task);
20336 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20337 + printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
20340 + read_unlock(&grsec_exec_file_lock);
20341 + read_unlock(&tasklist_lock);
20342 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
20346 + // it's a kernel process
20347 + task->role = kernel_role;
20348 + task->acl = kernel_role->root_label;
20349 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
20350 + task->acl->mode &= ~GR_PROCFIND;
20353 + } while_each_thread(task2, task);
20354 + read_unlock(&grsec_exec_file_lock);
20355 + read_unlock(&tasklist_lock);
20360 +gr_learn_resource(const struct task_struct *task,
20361 + const int res, const unsigned long wanted, const int gt)
20363 + struct acl_subject_label *acl;
20365 + if (unlikely((gr_status & GR_READY) &&
20366 + task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
20367 + goto skip_reslog;
20369 +#ifdef CONFIG_GRKERNSEC_RESLOG
20370 + gr_log_resource(task, res, wanted, gt);
20374 + if (unlikely(!(gr_status & GR_READY) || !wanted))
20379 + if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
20380 + !(acl->resmask & (1 << (unsigned short) res))))
20383 + if (wanted >= acl->res[res].rlim_cur) {
20384 + unsigned long res_add;
20386 + res_add = wanted;
20389 + res_add += GR_RLIM_CPU_BUMP;
20391 + case RLIMIT_FSIZE:
20392 + res_add += GR_RLIM_FSIZE_BUMP;
20394 + case RLIMIT_DATA:
20395 + res_add += GR_RLIM_DATA_BUMP;
20397 + case RLIMIT_STACK:
20398 + res_add += GR_RLIM_STACK_BUMP;
20400 + case RLIMIT_CORE:
20401 + res_add += GR_RLIM_CORE_BUMP;
20404 + res_add += GR_RLIM_RSS_BUMP;
20406 + case RLIMIT_NPROC:
20407 + res_add += GR_RLIM_NPROC_BUMP;
20409 + case RLIMIT_NOFILE:
20410 + res_add += GR_RLIM_NOFILE_BUMP;
20412 + case RLIMIT_MEMLOCK:
20413 + res_add += GR_RLIM_MEMLOCK_BUMP;
20416 + res_add += GR_RLIM_AS_BUMP;
20418 + case RLIMIT_LOCKS:
20419 + res_add += GR_RLIM_LOCKS_BUMP;
20423 + acl->res[res].rlim_cur = res_add;
20425 + if (wanted > acl->res[res].rlim_max)
20426 + acl->res[res].rlim_max = res_add;
20428 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
20429 + task->role->roletype, acl->filename,
20430 + acl->res[res].rlim_cur, acl->res[res].rlim_max,
20431 + "", (unsigned long) res);
20437 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
20439 +pax_set_initial_flags(struct linux_binprm *bprm)
20441 + struct task_struct *task = current;
20442 + struct acl_subject_label *proc;
20443 + unsigned long flags;
20445 + if (unlikely(!(gr_status & GR_READY)))
20448 + flags = pax_get_flags(task);
20450 + proc = task->acl;
20452 + if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
20453 + flags &= ~MF_PAX_PAGEEXEC;
20454 + if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
20455 + flags &= ~MF_PAX_SEGMEXEC;
20456 + if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
20457 + flags &= ~MF_PAX_RANDMMAP;
20458 + if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
20459 + flags &= ~MF_PAX_EMUTRAMP;
20460 + if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
20461 + flags &= ~MF_PAX_MPROTECT;
20463 + if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
20464 + flags |= MF_PAX_PAGEEXEC;
20465 + if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
20466 + flags |= MF_PAX_SEGMEXEC;
20467 + if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
20468 + flags |= MF_PAX_RANDMMAP;
20469 + if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
20470 + flags |= MF_PAX_EMUTRAMP;
20471 + if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
20472 + flags |= MF_PAX_MPROTECT;
20474 + pax_set_flags(task, flags);
20480 +#ifdef CONFIG_SYSCTL
20481 +/* Eric Biederman likes breaking userland ABI and every inode-based security
20482 + system to save 35kb of memory */
20484 +/* we modify the passed in filename, but adjust it back before returning */
20485 +static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
20487 + struct name_entry *nmatch;
20488 + char *p, *lastp = NULL;
20489 + struct acl_object_label *obj = NULL, *tmp;
20490 + struct acl_subject_label *tmpsubj;
20493 + read_lock(&gr_inode_lock);
20495 + p = name + len - 1;
20497 + nmatch = lookup_name_entry(name);
20498 + if (lastp != NULL)
20501 + if (nmatch == NULL)
20502 + goto next_component;
20503 + tmpsubj = current->acl;
20505 + obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
20506 + if (obj != NULL) {
20507 + tmp = obj->globbed;
20509 + if (!glob_match(tmp->filename, name)) {
20517 + } while ((tmpsubj = tmpsubj->parent_subject));
20523 + while (*p != '/')
20535 + read_unlock(&gr_inode_lock);
20536 + /* obj returned will always be non-null */
20540 +/* returns 0 when allowing, non-zero on error
20541 + op of 0 is used for readdir, so we don't log the names of hidden files
20544 +gr_handle_sysctl(const struct ctl_table *table, const int op)
20547 + const char *proc_sys = "/proc/sys";
20549 + struct acl_object_label *obj;
20550 + unsigned short len = 0, pos = 0, depth = 0, i;
20554 + if (unlikely(!(gr_status & GR_READY)))
20557 + /* for now, ignore operations on non-sysctl entries if it's not a
20559 + if (table->child != NULL && op != 0)
20563 + /* it's only a read if it's an entry, read on dirs is for readdir */
20567 + mode |= GR_WRITE;
20569 + preempt_disable();
20571 + path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
20573 + /* it's only a read/write if it's an actual entry, not a dir
20574 + (which are opened for readdir)
20577 + /* convert the requested sysctl entry into a pathname */
20579 + for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20580 + len += strlen(tmp->procname);
20585 + if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
20590 + memset(path, 0, PAGE_SIZE);
20592 + memcpy(path, proc_sys, strlen(proc_sys));
20594 + pos += strlen(proc_sys);
20596 + for (; depth > 0; depth--) {
20599 + for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20600 + if (depth == i) {
20601 + memcpy(path + pos, tmp->procname,
20602 + strlen(tmp->procname));
20603 + pos += strlen(tmp->procname);
20609 + obj = gr_lookup_by_name(path, pos);
20610 + err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
20612 + if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
20613 + ((err & mode) != mode))) {
20614 + __u32 new_mode = mode;
20616 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
20619 + gr_log_learn_sysctl(current, path, new_mode);
20620 + } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
20621 + gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
20623 + } else if (!(err & GR_FIND)) {
20625 + } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
20626 + gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
20627 + path, (mode & GR_READ) ? " reading" : "",
20628 + (mode & GR_WRITE) ? " writing" : "");
20630 + } else if ((err & mode) != mode) {
20632 + } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
20633 + gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
20634 + path, (mode & GR_READ) ? " reading" : "",
20635 + (mode & GR_WRITE) ? " writing" : "");
20641 + preempt_enable();
20648 +gr_handle_proc_ptrace(struct task_struct *task)
20650 + struct file *filp;
20651 + struct task_struct *tmp = task;
20652 + struct task_struct *curtemp = current;
20655 + if (unlikely(!(gr_status & GR_READY)))
20658 + read_lock(&tasklist_lock);
20659 + read_lock(&grsec_exec_file_lock);
20660 + filp = task->exec_file;
20662 + while (tmp->pid > 0) {
20663 + if (tmp == curtemp)
20665 + tmp = tmp->parent;
20668 + if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
20669 + read_unlock(&grsec_exec_file_lock);
20670 + read_unlock(&tasklist_lock);
20674 + retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
20675 + read_unlock(&grsec_exec_file_lock);
20676 + read_unlock(&tasklist_lock);
20678 + if (retmode & GR_NOPTRACE)
20681 + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
20682 + && (current->acl != task->acl || (current->acl != current->role->root_label
20683 + && current->pid != task->pid)))
20690 +gr_handle_ptrace(struct task_struct *task, const long request)
20692 + struct task_struct *tmp = task;
20693 + struct task_struct *curtemp = current;
20696 + if (unlikely(!(gr_status & GR_READY)))
20699 + read_lock(&tasklist_lock);
20700 + while (tmp->pid > 0) {
20701 + if (tmp == curtemp)
20703 + tmp = tmp->parent;
20706 + if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
20707 + read_unlock(&tasklist_lock);
20708 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
20711 + read_unlock(&tasklist_lock);
20713 + read_lock(&grsec_exec_file_lock);
20714 + if (unlikely(!task->exec_file)) {
20715 + read_unlock(&grsec_exec_file_lock);
20719 + retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
20720 + read_unlock(&grsec_exec_file_lock);
20722 + if (retmode & GR_NOPTRACE) {
20723 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
20727 + if (retmode & GR_PTRACERD) {
20728 + switch (request) {
20729 + case PTRACE_POKETEXT:
20730 + case PTRACE_POKEDATA:
20731 + case PTRACE_POKEUSR:
20732 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
20733 + case PTRACE_SETREGS:
20734 + case PTRACE_SETFPREGS:
20737 + case PTRACE_SETFPXREGS:
20739 +#ifdef CONFIG_ALTIVEC
20740 + case PTRACE_SETVRREGS:
20746 + } else if (!(current->acl->mode & GR_POVERRIDE) &&
20747 + !(current->role->roletype & GR_ROLE_GOD) &&
20748 + (current->acl != task->acl)) {
20749 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
20756 +static int is_writable_mmap(const struct file *filp)
20758 + struct task_struct *task = current;
20759 + struct acl_object_label *obj, *obj2;
20761 + if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
20762 + !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
20763 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20764 + obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
20765 + task->role->root_label);
20766 + if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
20767 + gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
20775 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
20779 + if (unlikely(!file || !(prot & PROT_EXEC)))
20782 + if (is_writable_mmap(file))
20786 + gr_search_file(file->f_path.dentry,
20787 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
20788 + file->f_path.mnt);
20790 + if (!gr_tpe_allow(file))
20793 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
20794 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
20796 + } else if (unlikely(!(mode & GR_EXEC))) {
20798 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
20799 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
20807 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
20811 + if (unlikely(!file || !(prot & PROT_EXEC)))
20814 + if (is_writable_mmap(file))
20818 + gr_search_file(file->f_path.dentry,
20819 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
20820 + file->f_path.mnt);
20822 + if (!gr_tpe_allow(file))
20825 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
20826 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
20828 + } else if (unlikely(!(mode & GR_EXEC))) {
20830 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
20831 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
20839 +gr_acl_handle_psacct(struct task_struct *task, const long code)
20841 + unsigned long runtime;
20842 + unsigned long cputime;
20843 + unsigned int wday, cday;
20847 + struct timespec timeval;
20849 + if (unlikely(!(gr_status & GR_READY) || !task->acl ||
20850 + !(task->acl->mode & GR_PROCACCT)))
20853 + do_posix_clock_monotonic_gettime(&timeval);
20854 + runtime = timeval.tv_sec - task->start_time.tv_sec;
20855 + wday = runtime / (3600 * 24);
20856 + runtime -= wday * (3600 * 24);
20857 + whr = runtime / 3600;
20858 + runtime -= whr * 3600;
20859 + wmin = runtime / 60;
20860 + runtime -= wmin * 60;
20863 + cputime = (task->utime + task->stime) / HZ;
20864 + cday = cputime / (3600 * 24);
20865 + cputime -= cday * (3600 * 24);
20866 + chr = cputime / 3600;
20867 + cputime -= chr * 3600;
20868 + cmin = cputime / 60;
20869 + cputime -= cmin * 60;
20872 + gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
20877 +void gr_set_kernel_label(struct task_struct *task)
20879 + if (gr_status & GR_READY) {
20880 + task->role = kernel_role;
20881 + task->acl = kernel_role->root_label;
20886 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
20888 + struct task_struct *task = current;
20889 + struct dentry *dentry = file->f_path.dentry;
20890 + struct vfsmount *mnt = file->f_path.mnt;
20891 + struct acl_object_label *obj, *tmp;
20892 + struct acl_subject_label *subj;
20893 + unsigned int bufsize;
20897 + if (unlikely(!(gr_status & GR_READY)))
20900 + if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
20903 + /* ignore Eric Biederman */
20904 + if (IS_PRIVATE(dentry->d_inode))
20907 + subj = task->acl;
20909 + obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
20911 + return (obj->mode & GR_FIND) ? 1 : 0;
20912 + } while ((subj = subj->parent_subject));
20914 + obj = chk_obj_label(dentry, mnt, task->acl);
20915 + if (obj->globbed == NULL)
20916 + return (obj->mode & GR_FIND) ? 1 : 0;
20918 + is_not_root = ((obj->filename[0] == '/') &&
20919 + (obj->filename[1] == '\0')) ? 0 : 1;
20920 + bufsize = PAGE_SIZE - namelen - is_not_root;
20922 + /* check bufsize > PAGE_SIZE || bufsize == 0 */
20923 + if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
20926 + preempt_disable();
20927 + path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
20930 + bufsize = strlen(path);
20932 + /* if base is "/", don't append an additional slash */
20934 + *(path + bufsize) = '/';
20935 + memcpy(path + bufsize + is_not_root, name, namelen);
20936 + *(path + bufsize + namelen + is_not_root) = '\0';
20938 + tmp = obj->globbed;
20940 + if (!glob_match(tmp->filename, path)) {
20941 + preempt_enable();
20942 + return (tmp->mode & GR_FIND) ? 1 : 0;
20946 + preempt_enable();
20947 + return (obj->mode & GR_FIND) ? 1 : 0;
20950 +EXPORT_SYMBOL(gr_learn_resource);
20951 +EXPORT_SYMBOL(gr_set_kernel_label);
20952 +#ifdef CONFIG_SECURITY
20953 +EXPORT_SYMBOL(gr_check_user_change);
20954 +EXPORT_SYMBOL(gr_check_group_change);
20957 diff -urNp linux-2.6.25.10/grsecurity/gracl_cap.c linux-2.6.25.10/grsecurity/gracl_cap.c
20958 --- linux-2.6.25.10/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
20959 +++ linux-2.6.25.10/grsecurity/gracl_cap.c 2008-07-03 16:53:26.000000000 -0400
20961 +#include <linux/kernel.h>
20962 +#include <linux/module.h>
20963 +#include <linux/sched.h>
20964 +#include <linux/gracl.h>
20965 +#include <linux/grsecurity.h>
20966 +#include <linux/grinternal.h>
20968 +static const char *captab_log[] = {
20970 + "CAP_DAC_OVERRIDE",
20971 + "CAP_DAC_READ_SEARCH",
20978 + "CAP_LINUX_IMMUTABLE",
20979 + "CAP_NET_BIND_SERVICE",
20980 + "CAP_NET_BROADCAST",
20985 + "CAP_SYS_MODULE",
20987 + "CAP_SYS_CHROOT",
20988 + "CAP_SYS_PTRACE",
20993 + "CAP_SYS_RESOURCE",
20995 + "CAP_SYS_TTY_CONFIG",
20998 + "CAP_AUDIT_WRITE",
20999 + "CAP_AUDIT_CONTROL",
21001 + "CAP_MAC_OVERRIDE",
21005 +EXPORT_SYMBOL(gr_task_is_capable);
21006 +EXPORT_SYMBOL(gr_is_capable_nolog);
21009 +gr_task_is_capable(struct task_struct *task, const int cap)
21011 + struct acl_subject_label *curracl;
21012 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
21014 + if (!gr_acl_is_enabled())
21017 + curracl = task->acl;
21019 + cap_drop = curracl->cap_lower;
21020 + cap_mask = curracl->cap_mask;
21022 + while ((curracl = curracl->parent_subject)) {
21023 + /* if the cap isn't specified in the current computed mask but is specified in the
21024 + current level subject, and is lowered in the current level subject, then add
21025 + it to the set of dropped capabilities
21026 + otherwise, add the current level subject's mask to the current computed mask
21028 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
21029 + cap_raise(cap_mask, cap);
21030 + if (cap_raised(curracl->cap_lower, cap))
21031 + cap_raise(cap_drop, cap);
21035 + if (!cap_raised(cap_drop, cap))
21038 + curracl = task->acl;
21040 + if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
21041 + && cap_raised(task->cap_effective, cap)) {
21042 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
21043 + task->role->roletype, task->uid,
21044 + task->gid, task->exec_file ?
21045 + gr_to_filename(task->exec_file->f_path.dentry,
21046 + task->exec_file->f_path.mnt) : curracl->filename,
21047 + curracl->filename, 0UL,
21048 + 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
21052 + if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
21053 + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
21058 +gr_is_capable_nolog(const int cap)
21060 + struct acl_subject_label *curracl;
21061 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
21063 + if (!gr_acl_is_enabled())
21066 + curracl = current->acl;
21068 + cap_drop = curracl->cap_lower;
21069 + cap_mask = curracl->cap_mask;
21071 + while ((curracl = curracl->parent_subject)) {
21072 + /* if the cap isn't specified in the current computed mask but is specified in the
21073 + current level subject, and is lowered in the current level subject, then add
21074 + it to the set of dropped capabilities
21075 + otherwise, add the current level subject's mask to the current computed mask
21077 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
21078 + cap_raise(cap_mask, cap);
21079 + if (cap_raised(curracl->cap_lower, cap))
21080 + cap_raise(cap_drop, cap);
21084 + if (!cap_raised(cap_drop, cap))
21090 diff -urNp linux-2.6.25.10/grsecurity/gracl_fs.c linux-2.6.25.10/grsecurity/gracl_fs.c
21091 --- linux-2.6.25.10/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
21092 +++ linux-2.6.25.10/grsecurity/gracl_fs.c 2008-07-03 16:53:26.000000000 -0400
21094 +#include <linux/kernel.h>
21095 +#include <linux/sched.h>
21096 +#include <linux/types.h>
21097 +#include <linux/fs.h>
21098 +#include <linux/file.h>
21099 +#include <linux/stat.h>
21100 +#include <linux/grsecurity.h>
21101 +#include <linux/grinternal.h>
21102 +#include <linux/gracl.h>
21105 +gr_acl_handle_hidden_file(const struct dentry * dentry,
21106 + const struct vfsmount * mnt)
21110 + if (unlikely(!dentry->d_inode))
21114 + gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
21116 + if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
21117 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
21119 + } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
21120 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
21122 + } else if (unlikely(!(mode & GR_FIND)))
21129 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
21132 + __u32 reqmode = GR_FIND;
21135 + if (unlikely(!dentry->d_inode))
21138 + if (unlikely(fmode & O_APPEND))
21139 + reqmode |= GR_APPEND;
21140 + else if (unlikely(fmode & FMODE_WRITE))
21141 + reqmode |= GR_WRITE;
21142 + if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
21143 + reqmode |= GR_READ;
21146 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
21149 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21150 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
21151 + reqmode & GR_READ ? " reading" : "",
21152 + reqmode & GR_WRITE ? " writing" : reqmode &
21153 + GR_APPEND ? " appending" : "");
21156 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21158 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
21159 + reqmode & GR_READ ? " reading" : "",
21160 + reqmode & GR_WRITE ? " writing" : reqmode &
21161 + GR_APPEND ? " appending" : "");
21163 + } else if (unlikely((mode & reqmode) != reqmode))
21170 +gr_acl_handle_creat(const struct dentry * dentry,
21171 + const struct dentry * p_dentry,
21172 + const struct vfsmount * p_mnt, const int fmode,
21175 + __u32 reqmode = GR_WRITE | GR_CREATE;
21178 + if (unlikely(fmode & O_APPEND))
21179 + reqmode |= GR_APPEND;
21180 + if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
21181 + reqmode |= GR_READ;
21182 + if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
21183 + reqmode |= GR_SETID;
21186 + gr_check_create(dentry, p_dentry, p_mnt,
21187 + reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
21189 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21190 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
21191 + reqmode & GR_READ ? " reading" : "",
21192 + reqmode & GR_WRITE ? " writing" : reqmode &
21193 + GR_APPEND ? " appending" : "");
21196 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21198 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
21199 + reqmode & GR_READ ? " reading" : "",
21200 + reqmode & GR_WRITE ? " writing" : reqmode &
21201 + GR_APPEND ? " appending" : "");
21203 + } else if (unlikely((mode & reqmode) != reqmode))
21210 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
21213 + __u32 mode, reqmode = GR_FIND;
21215 + if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
21216 + reqmode |= GR_EXEC;
21217 + if (fmode & S_IWOTH)
21218 + reqmode |= GR_WRITE;
21219 + if (fmode & S_IROTH)
21220 + reqmode |= GR_READ;
21223 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
21226 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21227 + gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
21228 + reqmode & GR_READ ? " reading" : "",
21229 + reqmode & GR_WRITE ? " writing" : "",
21230 + reqmode & GR_EXEC ? " executing" : "");
21233 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21235 + gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
21236 + reqmode & GR_READ ? " reading" : "",
21237 + reqmode & GR_WRITE ? " writing" : "",
21238 + reqmode & GR_EXEC ? " executing" : "");
21240 + } else if (unlikely((mode & reqmode) != reqmode))
21246 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
21250 + mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
21252 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21253 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
21255 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21256 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
21258 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
21261 + return (reqmode);
21265 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
21267 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
21271 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
21273 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
21277 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
21279 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
21283 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
21285 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
21289 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
21292 + if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
21295 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21296 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21297 + GR_FCHMOD_ACL_MSG);
21299 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
21304 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
21307 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21308 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21309 + GR_CHMOD_ACL_MSG);
21311 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
21316 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
21318 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
21322 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
21324 + return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
21328 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
21330 + return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
21331 + GR_UNIXCONNECT_ACL_MSG);
21334 +/* hardlinks require at minimum create permission,
21335 + any additional privilege required is based on the
21336 + privilege of the file being linked to
21339 +gr_acl_handle_link(const struct dentry * new_dentry,
21340 + const struct dentry * parent_dentry,
21341 + const struct vfsmount * parent_mnt,
21342 + const struct dentry * old_dentry,
21343 + const struct vfsmount * old_mnt, const char *to)
21346 + __u32 needmode = GR_CREATE | GR_LINK;
21347 + __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
21350 + gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
21353 + if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
21354 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21356 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21357 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21359 + } else if (unlikely((mode & needmode) != needmode))
21366 +gr_acl_handle_symlink(const struct dentry * new_dentry,
21367 + const struct dentry * parent_dentry,
21368 + const struct vfsmount * parent_mnt, const char *from)
21370 + __u32 needmode = GR_WRITE | GR_CREATE;
21374 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
21375 + GR_CREATE | GR_AUDIT_CREATE |
21376 + GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
21378 + if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
21379 + gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21381 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21382 + gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21384 + } else if (unlikely((mode & needmode) != needmode))
21387 + return (GR_WRITE | GR_CREATE);
21390 +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)
21394 + mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
21396 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21397 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
21399 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21400 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
21402 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
21405 + return (reqmode);
21409 +gr_acl_handle_mknod(const struct dentry * new_dentry,
21410 + const struct dentry * parent_dentry,
21411 + const struct vfsmount * parent_mnt,
21414 + __u32 reqmode = GR_WRITE | GR_CREATE;
21415 + if (unlikely(mode & (S_ISUID | S_ISGID)))
21416 + reqmode |= GR_SETID;
21418 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21419 + reqmode, GR_MKNOD_ACL_MSG);
21423 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
21424 + const struct dentry *parent_dentry,
21425 + const struct vfsmount *parent_mnt)
21427 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21428 + GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
21431 +#define RENAME_CHECK_SUCCESS(old, new) \
21432 + (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
21433 + ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
21436 +gr_acl_handle_rename(struct dentry *new_dentry,
21437 + struct dentry *parent_dentry,
21438 + const struct vfsmount *parent_mnt,
21439 + struct dentry *old_dentry,
21440 + struct inode *old_parent_inode,
21441 + struct vfsmount *old_mnt, const char *newname)
21443 + __u32 comp1, comp2;
21446 + if (unlikely(!gr_acl_is_enabled()))
21449 + if (!new_dentry->d_inode) {
21450 + comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
21451 + GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
21452 + GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
21453 + comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
21454 + GR_DELETE | GR_AUDIT_DELETE |
21455 + GR_AUDIT_READ | GR_AUDIT_WRITE |
21456 + GR_SUPPRESS, old_mnt);
21458 + comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
21459 + GR_CREATE | GR_DELETE |
21460 + GR_AUDIT_CREATE | GR_AUDIT_DELETE |
21461 + GR_AUDIT_READ | GR_AUDIT_WRITE |
21462 + GR_SUPPRESS, parent_mnt);
21464 + gr_search_file(old_dentry,
21465 + GR_READ | GR_WRITE | GR_AUDIT_READ |
21466 + GR_DELETE | GR_AUDIT_DELETE |
21467 + GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
21470 + if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
21471 + ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
21472 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21473 + else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
21474 + && !(comp2 & GR_SUPPRESS)) {
21475 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21477 + } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
21484 +gr_acl_handle_exit(void)
21488 + struct file *exec_file;
21490 + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
21491 + id = current->acl_role_id;
21492 + rolename = current->role->rolename;
21494 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
21497 + write_lock(&grsec_exec_file_lock);
21498 + exec_file = current->exec_file;
21499 + current->exec_file = NULL;
21500 + write_unlock(&grsec_exec_file_lock);
21507 +gr_acl_handle_procpidmem(const struct task_struct *task)
21509 + if (unlikely(!gr_acl_is_enabled()))
21512 + if (task != current && task->acl->mode & GR_PROTPROCFD)
21517 diff -urNp linux-2.6.25.10/grsecurity/gracl_ip.c linux-2.6.25.10/grsecurity/gracl_ip.c
21518 --- linux-2.6.25.10/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
21519 +++ linux-2.6.25.10/grsecurity/gracl_ip.c 2008-07-03 16:53:26.000000000 -0400
21521 +#include <linux/kernel.h>
21522 +#include <asm/uaccess.h>
21523 +#include <asm/errno.h>
21524 +#include <net/sock.h>
21525 +#include <linux/file.h>
21526 +#include <linux/fs.h>
21527 +#include <linux/net.h>
21528 +#include <linux/in.h>
21529 +#include <linux/skbuff.h>
21530 +#include <linux/ip.h>
21531 +#include <linux/udp.h>
21532 +#include <linux/smp_lock.h>
21533 +#include <linux/types.h>
21534 +#include <linux/sched.h>
21535 +#include <linux/netdevice.h>
21536 +#include <linux/inetdevice.h>
21537 +#include <linux/gracl.h>
21538 +#include <linux/grsecurity.h>
21539 +#include <linux/grinternal.h>
21541 +#define GR_BIND 0x01
21542 +#define GR_CONNECT 0x02
21543 +#define GR_INVERT 0x04
21545 +static const char * gr_protocols[256] = {
21546 + "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
21547 + "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
21548 + "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
21549 + "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
21550 + "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
21551 + "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
21552 + "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
21553 + "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
21554 + "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
21555 + "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
21556 + "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
21557 + "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
21558 + "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
21559 + "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
21560 + "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
21561 + "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
21562 + "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
21563 + "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
21564 + "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
21565 + "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
21566 + "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
21567 + "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
21568 + "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
21569 + "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
21570 + "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
21571 + "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
21572 + "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
21573 + "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
21574 + "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
21575 + "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
21576 + "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
21577 + "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
21580 +static const char * gr_socktypes[11] = {
21581 + "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
21582 + "unknown:7", "unknown:8", "unknown:9", "packet"
21586 +gr_proto_to_name(unsigned char proto)
21588 + return gr_protocols[proto];
21592 +gr_socktype_to_name(unsigned char type)
21594 + return gr_socktypes[type];
21598 +gr_search_socket(const int domain, const int type, const int protocol)
21600 + struct acl_subject_label *curr;
21602 + if (unlikely(!gr_acl_is_enabled()))
21605 + if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
21606 + || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
21607 + goto exit; // let the kernel handle it
21609 + curr = current->acl;
21614 + if ((curr->ip_type & (1 << type)) &&
21615 + (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
21618 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
21619 + /* we don't place acls on raw sockets , and sometimes
21620 + dgram/ip sockets are opened for ioctl and not
21621 + bind/connect, so we'll fake a bind learn log */
21622 + if (type == SOCK_RAW || type == SOCK_PACKET) {
21623 + __u32 fakeip = 0;
21624 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
21625 + current->role->roletype, current->uid,
21626 + current->gid, current->exec_file ?
21627 + gr_to_filename(current->exec_file->f_path.dentry,
21628 + current->exec_file->f_path.mnt) :
21629 + curr->filename, curr->filename,
21630 + NIPQUAD(fakeip), 0, type,
21631 + protocol, GR_CONNECT,
21632 +NIPQUAD(current->signal->curr_ip));
21633 + } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
21634 + __u32 fakeip = 0;
21635 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
21636 + current->role->roletype, current->uid,
21637 + current->gid, current->exec_file ?
21638 + gr_to_filename(current->exec_file->f_path.dentry,
21639 + current->exec_file->f_path.mnt) :
21640 + curr->filename, curr->filename,
21641 + NIPQUAD(fakeip), 0, type,
21642 + protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
21644 + /* we'll log when they use connect or bind */
21648 + gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
21649 + gr_socktype_to_name(type), gr_proto_to_name(protocol));
21656 +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)
21658 + if ((ip->mode & mode) &&
21659 + (ip_port >= ip->low) &&
21660 + (ip_port <= ip->high) &&
21661 + ((ntohl(ip_addr) & our_netmask) ==
21662 + (ntohl(our_addr) & our_netmask))
21663 + && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
21664 + && (ip->type & (1 << type))) {
21665 + if (ip->mode & GR_INVERT)
21666 + return 2; // specifically denied
21668 + return 1; // allowed
21671 + return 0; // not specifically allowed, may continue parsing
21675 +gr_search_connectbind(const int mode, const struct sock *sk,
21676 + const struct sockaddr_in *addr, const int type)
21678 + char iface[IFNAMSIZ] = {0};
21679 + struct acl_subject_label *curr;
21680 + struct acl_ip_label *ip;
21681 + struct net_device *dev;
21682 + struct in_device *idev;
21685 + __u32 ip_addr = 0;
21687 + __u32 our_netmask;
21689 + __u16 ip_port = 0;
21691 + if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
21694 + curr = current->acl;
21699 + ip_addr = addr->sin_addr.s_addr;
21700 + ip_port = ntohs(addr->sin_port);
21702 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
21703 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
21704 + current->role->roletype, current->uid,
21705 + current->gid, current->exec_file ?
21706 + gr_to_filename(current->exec_file->f_path.dentry,
21707 + current->exec_file->f_path.mnt) :
21708 + curr->filename, curr->filename,
21709 + NIPQUAD(ip_addr), ip_port, type,
21710 + sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
21714 + for (i = 0; i < curr->ip_num; i++) {
21715 + ip = *(curr->ips + i);
21716 + if (ip->iface != NULL) {
21717 + strncpy(iface, ip->iface, IFNAMSIZ - 1);
21718 + p = strchr(iface, ':');
21721 + dev = dev_get_by_name(sk->sk_net, iface);
21724 + idev = in_dev_get(dev);
21725 + if (idev == NULL) {
21731 + if (!strcmp(ip->iface, ifa->ifa_label)) {
21732 + our_addr = ifa->ifa_address;
21733 + our_netmask = 0xffffffff;
21734 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
21736 + rcu_read_unlock();
21737 + in_dev_put(idev);
21740 + } else if (ret == 2) {
21741 + rcu_read_unlock();
21742 + in_dev_put(idev);
21747 + } endfor_ifa(idev);
21748 + rcu_read_unlock();
21749 + in_dev_put(idev);
21752 + our_addr = ip->addr;
21753 + our_netmask = ip->netmask;
21754 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
21757 + else if (ret == 2)
21763 + if (mode == GR_BIND)
21764 + 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));
21765 + else if (mode == GR_CONNECT)
21766 + 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));
21772 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
21774 + return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
21778 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
21780 + return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
21783 +int gr_search_listen(const struct socket *sock)
21785 + struct sock *sk = sock->sk;
21786 + struct sockaddr_in addr;
21788 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
21789 + addr.sin_port = inet_sk(sk)->sport;
21791 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
21794 +int gr_search_accept(const struct socket *sock)
21796 + struct sock *sk = sock->sk;
21797 + struct sockaddr_in addr;
21799 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
21800 + addr.sin_port = inet_sk(sk)->sport;
21802 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
21806 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
21809 + return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
21811 + struct sockaddr_in sin;
21812 + const struct inet_sock *inet = inet_sk(sk);
21814 + sin.sin_addr.s_addr = inet->daddr;
21815 + sin.sin_port = inet->dport;
21817 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
21822 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
21824 + struct sockaddr_in sin;
21826 + if (unlikely(skb->len < sizeof (struct udphdr)))
21827 + return 1; // skip this packet
21829 + sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
21830 + sin.sin_port = udp_hdr(skb)->source;
21832 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
21834 diff -urNp linux-2.6.25.10/grsecurity/gracl_learn.c linux-2.6.25.10/grsecurity/gracl_learn.c
21835 --- linux-2.6.25.10/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
21836 +++ linux-2.6.25.10/grsecurity/gracl_learn.c 2008-07-03 16:53:26.000000000 -0400
21838 +#include <linux/kernel.h>
21839 +#include <linux/mm.h>
21840 +#include <linux/sched.h>
21841 +#include <linux/poll.h>
21842 +#include <linux/smp_lock.h>
21843 +#include <linux/string.h>
21844 +#include <linux/file.h>
21845 +#include <linux/types.h>
21846 +#include <linux/vmalloc.h>
21847 +#include <linux/grinternal.h>
21849 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
21850 + size_t count, loff_t *ppos);
21851 +extern int gr_acl_is_enabled(void);
21853 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
21854 +static int gr_learn_attached;
21856 +/* use a 512k buffer */
21857 +#define LEARN_BUFFER_SIZE (512 * 1024)
21859 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
21860 +static DECLARE_MUTEX(gr_learn_user_sem);
21862 +/* we need to maintain two buffers, so that the kernel context of grlearn
21863 + uses a semaphore around the userspace copying, and the other kernel contexts
21864 + use a spinlock when copying into the buffer, since they cannot sleep
21866 +static char *learn_buffer;
21867 +static char *learn_buffer_user;
21868 +static int learn_buffer_len;
21869 +static int learn_buffer_user_len;
21872 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
21874 + DECLARE_WAITQUEUE(wait, current);
21875 + ssize_t retval = 0;
21877 + add_wait_queue(&learn_wait, &wait);
21878 + set_current_state(TASK_INTERRUPTIBLE);
21880 + down(&gr_learn_user_sem);
21881 + spin_lock(&gr_learn_lock);
21882 + if (learn_buffer_len)
21884 + spin_unlock(&gr_learn_lock);
21885 + up(&gr_learn_user_sem);
21886 + if (file->f_flags & O_NONBLOCK) {
21887 + retval = -EAGAIN;
21890 + if (signal_pending(current)) {
21891 + retval = -ERESTARTSYS;
21898 + memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
21899 + learn_buffer_user_len = learn_buffer_len;
21900 + retval = learn_buffer_len;
21901 + learn_buffer_len = 0;
21903 + spin_unlock(&gr_learn_lock);
21905 + if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
21906 + retval = -EFAULT;
21908 + up(&gr_learn_user_sem);
21910 + set_current_state(TASK_RUNNING);
21911 + remove_wait_queue(&learn_wait, &wait);
21915 +static unsigned int
21916 +poll_learn(struct file * file, poll_table * wait)
21918 + poll_wait(file, &learn_wait, wait);
21920 + if (learn_buffer_len)
21921 + return (POLLIN | POLLRDNORM);
21927 +gr_clear_learn_entries(void)
21931 + down(&gr_learn_user_sem);
21932 + if (learn_buffer != NULL) {
21933 + spin_lock(&gr_learn_lock);
21934 + tmp = learn_buffer;
21935 + learn_buffer = NULL;
21936 + spin_unlock(&gr_learn_lock);
21937 + vfree(learn_buffer);
21939 + if (learn_buffer_user != NULL) {
21940 + vfree(learn_buffer_user);
21941 + learn_buffer_user = NULL;
21943 + learn_buffer_len = 0;
21944 + up(&gr_learn_user_sem);
21950 +gr_add_learn_entry(const char *fmt, ...)
21953 + unsigned int len;
21955 + if (!gr_learn_attached)
21958 + spin_lock(&gr_learn_lock);
21960 + /* leave a gap at the end so we know when it's "full" but don't have to
21961 + compute the exact length of the string we're trying to append
21963 + if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
21964 + spin_unlock(&gr_learn_lock);
21965 + wake_up_interruptible(&learn_wait);
21968 + if (learn_buffer == NULL) {
21969 + spin_unlock(&gr_learn_lock);
21973 + va_start(args, fmt);
21974 + len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
21977 + learn_buffer_len += len + 1;
21979 + spin_unlock(&gr_learn_lock);
21980 + wake_up_interruptible(&learn_wait);
21986 +open_learn(struct inode *inode, struct file *file)
21988 + if (file->f_mode & FMODE_READ && gr_learn_attached)
21990 + if (file->f_mode & FMODE_READ) {
21992 + down(&gr_learn_user_sem);
21993 + if (learn_buffer == NULL)
21994 + learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
21995 + if (learn_buffer_user == NULL)
21996 + learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
21997 + if (learn_buffer == NULL) {
21998 + retval = -ENOMEM;
22001 + if (learn_buffer_user == NULL) {
22002 + retval = -ENOMEM;
22005 + learn_buffer_len = 0;
22006 + learn_buffer_user_len = 0;
22007 + gr_learn_attached = 1;
22009 + up(&gr_learn_user_sem);
22016 +close_learn(struct inode *inode, struct file *file)
22020 + if (file->f_mode & FMODE_READ) {
22021 + down(&gr_learn_user_sem);
22022 + if (learn_buffer != NULL) {
22023 + spin_lock(&gr_learn_lock);
22024 + tmp = learn_buffer;
22025 + learn_buffer = NULL;
22026 + spin_unlock(&gr_learn_lock);
22029 + if (learn_buffer_user != NULL) {
22030 + vfree(learn_buffer_user);
22031 + learn_buffer_user = NULL;
22033 + learn_buffer_len = 0;
22034 + learn_buffer_user_len = 0;
22035 + gr_learn_attached = 0;
22036 + up(&gr_learn_user_sem);
22042 +struct file_operations grsec_fops = {
22043 + .read = read_learn,
22044 + .write = write_grsec_handler,
22045 + .open = open_learn,
22046 + .release = close_learn,
22047 + .poll = poll_learn,
22049 diff -urNp linux-2.6.25.10/grsecurity/gracl_res.c linux-2.6.25.10/grsecurity/gracl_res.c
22050 --- linux-2.6.25.10/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
22051 +++ linux-2.6.25.10/grsecurity/gracl_res.c 2008-07-03 16:53:26.000000000 -0400
22053 +#include <linux/kernel.h>
22054 +#include <linux/sched.h>
22055 +#include <linux/gracl.h>
22056 +#include <linux/grinternal.h>
22058 +static const char *restab_log[] = {
22059 + [RLIMIT_CPU] = "RLIMIT_CPU",
22060 + [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
22061 + [RLIMIT_DATA] = "RLIMIT_DATA",
22062 + [RLIMIT_STACK] = "RLIMIT_STACK",
22063 + [RLIMIT_CORE] = "RLIMIT_CORE",
22064 + [RLIMIT_RSS] = "RLIMIT_RSS",
22065 + [RLIMIT_NPROC] = "RLIMIT_NPROC",
22066 + [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
22067 + [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
22068 + [RLIMIT_AS] = "RLIMIT_AS",
22069 + [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
22070 + [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
22074 +gr_log_resource(const struct task_struct *task,
22075 + const int res, const unsigned long wanted, const int gt)
22077 + if (res == RLIMIT_NPROC &&
22078 + (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
22079 + cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
22081 + else if (res == RLIMIT_MEMLOCK &&
22082 + cap_raised(task->cap_effective, CAP_IPC_LOCK))
22085 + if (!gr_acl_is_enabled() && !grsec_resource_logging)
22088 + preempt_disable();
22090 + if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
22091 + (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
22092 + task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
22093 + gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
22094 + preempt_enable_no_resched();
22098 diff -urNp linux-2.6.25.10/grsecurity/gracl_segv.c linux-2.6.25.10/grsecurity/gracl_segv.c
22099 --- linux-2.6.25.10/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
22100 +++ linux-2.6.25.10/grsecurity/gracl_segv.c 2008-07-03 16:53:26.000000000 -0400
22102 +#include <linux/kernel.h>
22103 +#include <linux/mm.h>
22104 +#include <asm/uaccess.h>
22105 +#include <asm/errno.h>
22106 +#include <asm/mman.h>
22107 +#include <net/sock.h>
22108 +#include <linux/file.h>
22109 +#include <linux/fs.h>
22110 +#include <linux/net.h>
22111 +#include <linux/in.h>
22112 +#include <linux/smp_lock.h>
22113 +#include <linux/slab.h>
22114 +#include <linux/types.h>
22115 +#include <linux/sched.h>
22116 +#include <linux/timer.h>
22117 +#include <linux/gracl.h>
22118 +#include <linux/grsecurity.h>
22119 +#include <linux/grinternal.h>
22121 +static struct crash_uid *uid_set;
22122 +static unsigned short uid_used;
22123 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
22124 +extern rwlock_t gr_inode_lock;
22125 +extern struct acl_subject_label *
22126 + lookup_acl_subj_label(const ino_t inode, const dev_t dev,
22127 + struct acl_role_label *role);
22128 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
22131 +gr_init_uidset(void)
22134 + kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
22137 + return uid_set ? 1 : 0;
22141 +gr_free_uidset(void)
22150 +gr_find_uid(const uid_t uid)
22152 + struct crash_uid *tmp = uid_set;
22154 + int low = 0, high = uid_used - 1, mid;
22156 + while (high >= low) {
22157 + mid = (low + high) >> 1;
22158 + buid = tmp[mid].uid;
22170 +static __inline__ void
22171 +gr_insertsort(void)
22173 + unsigned short i, j;
22174 + struct crash_uid index;
22176 + for (i = 1; i < uid_used; i++) {
22177 + index = uid_set[i];
22179 + while ((j > 0) && uid_set[j - 1].uid > index.uid) {
22180 + uid_set[j] = uid_set[j - 1];
22183 + uid_set[j] = index;
22189 +static __inline__ void
22190 +gr_insert_uid(const uid_t uid, const unsigned long expires)
22194 + if (uid_used == GR_UIDTABLE_MAX)
22197 + loc = gr_find_uid(uid);
22200 + uid_set[loc].expires = expires;
22204 + uid_set[uid_used].uid = uid;
22205 + uid_set[uid_used].expires = expires;
22214 +gr_remove_uid(const unsigned short loc)
22216 + unsigned short i;
22218 + for (i = loc + 1; i < uid_used; i++)
22219 + uid_set[i - 1] = uid_set[i];
22227 +gr_check_crash_uid(const uid_t uid)
22232 + if (unlikely(!gr_acl_is_enabled()))
22235 + spin_lock(&gr_uid_lock);
22236 + loc = gr_find_uid(uid);
22241 + if (time_before_eq(uid_set[loc].expires, get_seconds()))
22242 + gr_remove_uid(loc);
22247 + spin_unlock(&gr_uid_lock);
22251 +static __inline__ int
22252 +proc_is_setxid(const struct task_struct *task)
22254 + if (task->uid != task->euid || task->uid != task->suid ||
22255 + task->uid != task->fsuid)
22257 + if (task->gid != task->egid || task->gid != task->sgid ||
22258 + task->gid != task->fsgid)
22263 +static __inline__ int
22264 +gr_fake_force_sig(int sig, struct task_struct *t)
22266 + unsigned long int flags;
22267 + int ret, blocked, ignored;
22268 + struct k_sigaction *action;
22270 + spin_lock_irqsave(&t->sighand->siglock, flags);
22271 + action = &t->sighand->action[sig-1];
22272 + ignored = action->sa.sa_handler == SIG_IGN;
22273 + blocked = sigismember(&t->blocked, sig);
22274 + if (blocked || ignored) {
22275 + action->sa.sa_handler = SIG_DFL;
22277 + sigdelset(&t->blocked, sig);
22278 + recalc_sigpending_and_wake(t);
22281 + ret = specific_send_sig_info(sig, (void*)1L, t);
22282 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
22288 +gr_handle_crash(struct task_struct *task, const int sig)
22290 + struct acl_subject_label *curr;
22291 + struct acl_subject_label *curr2;
22292 + struct task_struct *tsk, *tsk2;
22294 + if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
22297 + if (unlikely(!gr_acl_is_enabled()))
22300 + curr = task->acl;
22302 + if (!(curr->resmask & (1 << GR_CRASH_RES)))
22305 + if (time_before_eq(curr->expires, get_seconds())) {
22306 + curr->expires = 0;
22307 + curr->crashes = 0;
22312 + if (!curr->expires)
22313 + curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
22315 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22316 + time_after(curr->expires, get_seconds())) {
22317 + if (task->uid && proc_is_setxid(task)) {
22318 + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22319 + spin_lock(&gr_uid_lock);
22320 + gr_insert_uid(task->uid, curr->expires);
22321 + spin_unlock(&gr_uid_lock);
22322 + curr->expires = 0;
22323 + curr->crashes = 0;
22324 + read_lock(&tasklist_lock);
22325 + do_each_thread(tsk2, tsk) {
22326 + if (tsk != task && tsk->uid == task->uid)
22327 + gr_fake_force_sig(SIGKILL, tsk);
22328 + } while_each_thread(tsk2, tsk);
22329 + read_unlock(&tasklist_lock);
22331 + gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22332 + read_lock(&tasklist_lock);
22333 + do_each_thread(tsk2, tsk) {
22334 + if (likely(tsk != task)) {
22335 + curr2 = tsk->acl;
22337 + if (curr2->device == curr->device &&
22338 + curr2->inode == curr->inode)
22339 + gr_fake_force_sig(SIGKILL, tsk);
22341 + } while_each_thread(tsk2, tsk);
22342 + read_unlock(&tasklist_lock);
22350 +gr_check_crash_exec(const struct file *filp)
22352 + struct acl_subject_label *curr;
22354 + if (unlikely(!gr_acl_is_enabled()))
22357 + read_lock(&gr_inode_lock);
22358 + curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
22359 + filp->f_path.dentry->d_inode->i_sb->s_dev,
22361 + read_unlock(&gr_inode_lock);
22363 + if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
22364 + (!curr->crashes && !curr->expires))
22367 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22368 + time_after(curr->expires, get_seconds()))
22370 + else if (time_before_eq(curr->expires, get_seconds())) {
22371 + curr->crashes = 0;
22372 + curr->expires = 0;
22379 +gr_handle_alertkill(struct task_struct *task)
22381 + struct acl_subject_label *curracl;
22383 + struct task_struct *p, *p2;
22385 + if (unlikely(!gr_acl_is_enabled()))
22388 + curracl = task->acl;
22389 + curr_ip = task->signal->curr_ip;
22391 + if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
22392 + read_lock(&tasklist_lock);
22393 + do_each_thread(p2, p) {
22394 + if (p->signal->curr_ip == curr_ip)
22395 + gr_fake_force_sig(SIGKILL, p);
22396 + } while_each_thread(p2, p);
22397 + read_unlock(&tasklist_lock);
22398 + } else if (curracl->mode & GR_KILLPROC)
22399 + gr_fake_force_sig(SIGKILL, task);
22403 diff -urNp linux-2.6.25.10/grsecurity/gracl_shm.c linux-2.6.25.10/grsecurity/gracl_shm.c
22404 --- linux-2.6.25.10/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
22405 +++ linux-2.6.25.10/grsecurity/gracl_shm.c 2008-07-03 16:53:26.000000000 -0400
22407 +#include <linux/kernel.h>
22408 +#include <linux/mm.h>
22409 +#include <linux/sched.h>
22410 +#include <linux/file.h>
22411 +#include <linux/ipc.h>
22412 +#include <linux/gracl.h>
22413 +#include <linux/grsecurity.h>
22414 +#include <linux/grinternal.h>
22417 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22418 + const time_t shm_createtime, const uid_t cuid, const int shmid)
22420 + struct task_struct *task;
22422 + if (!gr_acl_is_enabled())
22425 + task = find_task_by_pid(shm_cprid);
22427 + if (unlikely(!task))
22428 + task = find_task_by_pid(shm_lapid);
22430 + if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
22431 + (task->pid == shm_lapid)) &&
22432 + (task->acl->mode & GR_PROTSHM) &&
22433 + (task->acl != current->acl))) {
22434 + gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
22440 diff -urNp linux-2.6.25.10/grsecurity/grsec_chdir.c linux-2.6.25.10/grsecurity/grsec_chdir.c
22441 --- linux-2.6.25.10/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
22442 +++ linux-2.6.25.10/grsecurity/grsec_chdir.c 2008-07-03 16:53:26.000000000 -0400
22444 +#include <linux/kernel.h>
22445 +#include <linux/sched.h>
22446 +#include <linux/fs.h>
22447 +#include <linux/file.h>
22448 +#include <linux/grsecurity.h>
22449 +#include <linux/grinternal.h>
22452 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
22454 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
22455 + if ((grsec_enable_chdir && grsec_enable_group &&
22456 + in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
22457 + !grsec_enable_group)) {
22458 + gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
22463 diff -urNp linux-2.6.25.10/grsecurity/grsec_chroot.c linux-2.6.25.10/grsecurity/grsec_chroot.c
22464 --- linux-2.6.25.10/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
22465 +++ linux-2.6.25.10/grsecurity/grsec_chroot.c 2008-07-03 16:53:26.000000000 -0400
22467 +#include <linux/kernel.h>
22468 +#include <linux/module.h>
22469 +#include <linux/sched.h>
22470 +#include <linux/file.h>
22471 +#include <linux/fs.h>
22472 +#include <linux/mount.h>
22473 +#include <linux/types.h>
22474 +#include <linux/pid_namespace.h>
22475 +#include <linux/grsecurity.h>
22476 +#include <linux/grinternal.h>
22479 +gr_handle_chroot_unix(const pid_t pid)
22481 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
22482 + struct pid *spid = NULL;
22484 + if (unlikely(!grsec_enable_chroot_unix))
22487 + if (likely(!proc_is_chrooted(current)))
22490 + read_lock(&tasklist_lock);
22492 + spid = find_pid(pid);
22494 + struct task_struct *p;
22495 + p = pid_task(spid, PIDTYPE_PID);
22497 + if (unlikely(!have_same_root(current, p))) {
22499 + read_unlock(&tasklist_lock);
22500 + gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
22505 + read_unlock(&tasklist_lock);
22511 +gr_handle_chroot_nice(void)
22513 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22514 + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
22515 + gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
22523 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
22525 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22526 + if (grsec_enable_chroot_nice && (niceval < task_nice(p))
22527 + && proc_is_chrooted(current)) {
22528 + gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
22536 +gr_handle_chroot_rawio(const struct inode *inode)
22538 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
22539 + if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
22540 + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
22547 +gr_pid_is_chrooted(struct task_struct *p)
22549 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
22550 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
22554 + if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
22555 + !have_same_root(current, p)) {
22564 +EXPORT_SYMBOL(gr_pid_is_chrooted);
22566 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
22567 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
22569 + struct dentry *dentry = (struct dentry *)u_dentry;
22570 + struct vfsmount *mnt = (struct vfsmount *)u_mnt;
22571 + struct dentry *realroot;
22572 + struct vfsmount *realrootmnt;
22573 + struct dentry *currentroot;
22574 + struct vfsmount *currentmnt;
22575 + struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
22578 + read_lock(&reaper->fs->lock);
22579 + realrootmnt = mntget(reaper->fs->root.mnt);
22580 + realroot = dget(reaper->fs->root.dentry);
22581 + read_unlock(&reaper->fs->lock);
22583 + read_lock(¤t->fs->lock);
22584 + currentmnt = mntget(current->fs->root.mnt);
22585 + currentroot = dget(current->fs->root.dentry);
22586 + read_unlock(¤t->fs->lock);
22588 + spin_lock(&dcache_lock);
22590 + if (unlikely((dentry == realroot && mnt == realrootmnt)
22591 + || (dentry == currentroot && mnt == currentmnt)))
22593 + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
22594 + if (mnt->mnt_parent == mnt)
22596 + dentry = mnt->mnt_mountpoint;
22597 + mnt = mnt->mnt_parent;
22600 + dentry = dentry->d_parent;
22602 + spin_unlock(&dcache_lock);
22604 + dput(currentroot);
22605 + mntput(currentmnt);
22607 + /* access is outside of chroot */
22608 + if (dentry == realroot && mnt == realrootmnt)
22612 + mntput(realrootmnt);
22618 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
22620 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
22621 + if (!grsec_enable_chroot_fchdir)
22624 + if (!proc_is_chrooted(current))
22626 + else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
22627 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
22635 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22636 + const time_t shm_createtime)
22638 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
22639 + struct pid *pid = NULL;
22640 + time_t starttime;
22642 + if (unlikely(!grsec_enable_chroot_shmat))
22645 + if (likely(!proc_is_chrooted(current)))
22648 + read_lock(&tasklist_lock);
22650 + pid = find_pid(shm_cprid);
22652 + struct task_struct *p;
22653 + p = pid_task(pid, PIDTYPE_PID);
22655 + starttime = p->start_time.tv_sec;
22656 + if (unlikely(!have_same_root(current, p) &&
22657 + time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
22659 + read_unlock(&tasklist_lock);
22660 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
22665 + pid = find_pid(shm_lapid);
22667 + struct task_struct *p;
22668 + p = pid_task(pid, PIDTYPE_PID);
22670 + if (unlikely(!have_same_root(current, p))) {
22672 + read_unlock(&tasklist_lock);
22673 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
22680 + read_unlock(&tasklist_lock);
22686 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
22688 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
22689 + if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
22690 + gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
22696 +gr_handle_chroot_mknod(const struct dentry *dentry,
22697 + const struct vfsmount *mnt, const int mode)
22699 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
22700 + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
22701 + proc_is_chrooted(current)) {
22702 + gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
22710 +gr_handle_chroot_mount(const struct dentry *dentry,
22711 + const struct vfsmount *mnt, const char *dev_name)
22713 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
22714 + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
22715 + gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
22723 +gr_handle_chroot_pivot(void)
22725 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
22726 + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
22727 + gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
22735 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
22737 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
22738 + if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
22739 + !gr_is_outside_chroot(dentry, mnt)) {
22740 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
22748 +gr_handle_chroot_caps(struct task_struct *task)
22750 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
22751 + if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
22752 + kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
22753 + task->cap_permitted =
22754 + cap_drop(task->cap_permitted, chroot_caps);
22755 + task->cap_inheritable =
22756 + cap_drop(task->cap_inheritable, chroot_caps);
22757 + task->cap_effective =
22758 + cap_drop(task->cap_effective, chroot_caps);
22765 +gr_handle_chroot_sysctl(const int op)
22767 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
22768 + if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
22776 +gr_handle_chroot_chdir(struct path *path)
22778 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
22779 + if (grsec_enable_chroot_chdir)
22780 + set_fs_pwd(current->fs, path);
22786 +gr_handle_chroot_chmod(const struct dentry *dentry,
22787 + const struct vfsmount *mnt, const int mode)
22789 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
22790 + if (grsec_enable_chroot_chmod &&
22791 + ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
22792 + proc_is_chrooted(current)) {
22793 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
22800 +#ifdef CONFIG_SECURITY
22801 +EXPORT_SYMBOL(gr_handle_chroot_caps);
22803 diff -urNp linux-2.6.25.10/grsecurity/grsec_disabled.c linux-2.6.25.10/grsecurity/grsec_disabled.c
22804 --- linux-2.6.25.10/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
22805 +++ linux-2.6.25.10/grsecurity/grsec_disabled.c 2008-07-03 16:53:26.000000000 -0400
22807 +#include <linux/kernel.h>
22808 +#include <linux/module.h>
22809 +#include <linux/sched.h>
22810 +#include <linux/file.h>
22811 +#include <linux/fs.h>
22812 +#include <linux/kdev_t.h>
22813 +#include <linux/net.h>
22814 +#include <linux/in.h>
22815 +#include <linux/ip.h>
22816 +#include <linux/skbuff.h>
22817 +#include <linux/sysctl.h>
22819 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
22821 +pax_set_initial_flags(struct linux_binprm *bprm)
22827 +#ifdef CONFIG_SYSCTL
22829 +gr_handle_sysctl(const struct ctl_table * table, const int op)
22836 +gr_acl_is_enabled(void)
22842 +gr_handle_rawio(const struct inode *inode)
22848 +gr_acl_handle_psacct(struct task_struct *task, const long code)
22854 +gr_handle_ptrace(struct task_struct *task, const long request)
22860 +gr_handle_proc_ptrace(struct task_struct *task)
22866 +gr_learn_resource(const struct task_struct *task,
22867 + const int res, const unsigned long wanted, const int gt)
22873 +gr_set_acls(const int type)
22879 +gr_check_hidden_task(const struct task_struct *tsk)
22885 +gr_check_protected_task(const struct task_struct *task)
22891 +gr_copy_label(struct task_struct *tsk)
22897 +gr_set_pax_flags(struct task_struct *task)
22903 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
22909 +gr_handle_delete(const ino_t ino, const dev_t dev)
22915 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
22921 +gr_handle_crash(struct task_struct *task, const int sig)
22927 +gr_check_crash_exec(const struct file *filp)
22933 +gr_check_crash_uid(const uid_t uid)
22939 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
22940 + struct dentry *old_dentry,
22941 + struct dentry *new_dentry,
22942 + struct vfsmount *mnt, const __u8 replace)
22948 +gr_search_socket(const int family, const int type, const int protocol)
22954 +gr_search_connectbind(const int mode, const struct socket *sock,
22955 + const struct sockaddr_in *addr)
22961 +gr_task_is_capable(struct task_struct *task, const int cap)
22967 +gr_is_capable_nolog(const int cap)
22973 +gr_handle_alertkill(struct task_struct *task)
22979 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
22985 +gr_acl_handle_hidden_file(const struct dentry * dentry,
22986 + const struct vfsmount * mnt)
22992 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
22999 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
23005 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
23011 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
23012 + unsigned int *vm_flags)
23018 +gr_acl_handle_truncate(const struct dentry * dentry,
23019 + const struct vfsmount * mnt)
23025 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
23031 +gr_acl_handle_access(const struct dentry * dentry,
23032 + const struct vfsmount * mnt, const int fmode)
23038 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
23045 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
23052 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
23058 +grsecurity_init(void)
23064 +gr_acl_handle_mknod(const struct dentry * new_dentry,
23065 + const struct dentry * parent_dentry,
23066 + const struct vfsmount * parent_mnt,
23073 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
23074 + const struct dentry * parent_dentry,
23075 + const struct vfsmount * parent_mnt)
23081 +gr_acl_handle_symlink(const struct dentry * new_dentry,
23082 + const struct dentry * parent_dentry,
23083 + const struct vfsmount * parent_mnt, const char *from)
23089 +gr_acl_handle_link(const struct dentry * new_dentry,
23090 + const struct dentry * parent_dentry,
23091 + const struct vfsmount * parent_mnt,
23092 + const struct dentry * old_dentry,
23093 + const struct vfsmount * old_mnt, const char *to)
23099 +gr_acl_handle_rename(const struct dentry *new_dentry,
23100 + const struct dentry *parent_dentry,
23101 + const struct vfsmount *parent_mnt,
23102 + const struct dentry *old_dentry,
23103 + const struct inode *old_parent_inode,
23104 + const struct vfsmount *old_mnt, const char *newname)
23110 +gr_acl_handle_filldir(const struct file *file, const char *name,
23111 + const int namelen, const ino_t ino)
23117 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23118 + const time_t shm_createtime, const uid_t cuid, const int shmid)
23124 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
23130 +gr_search_accept(const struct socket *sock)
23136 +gr_search_listen(const struct socket *sock)
23142 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
23148 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
23154 +gr_acl_handle_creat(const struct dentry * dentry,
23155 + const struct dentry * p_dentry,
23156 + const struct vfsmount * p_mnt, const int fmode,
23163 +gr_acl_handle_exit(void)
23169 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
23175 +gr_set_role_label(const uid_t uid, const gid_t gid)
23181 +gr_acl_handle_procpidmem(const struct task_struct *task)
23187 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
23193 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
23199 +gr_set_kernel_label(struct task_struct *task)
23205 +gr_check_user_change(int real, int effective, int fs)
23211 +gr_check_group_change(int real, int effective, int fs)
23217 +EXPORT_SYMBOL(gr_task_is_capable);
23218 +EXPORT_SYMBOL(gr_is_capable_nolog);
23219 +EXPORT_SYMBOL(gr_learn_resource);
23220 +EXPORT_SYMBOL(gr_set_kernel_label);
23221 +#ifdef CONFIG_SECURITY
23222 +EXPORT_SYMBOL(gr_check_user_change);
23223 +EXPORT_SYMBOL(gr_check_group_change);
23225 diff -urNp linux-2.6.25.10/grsecurity/grsec_exec.c linux-2.6.25.10/grsecurity/grsec_exec.c
23226 --- linux-2.6.25.10/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
23227 +++ linux-2.6.25.10/grsecurity/grsec_exec.c 2008-07-03 16:53:26.000000000 -0400
23229 +#include <linux/kernel.h>
23230 +#include <linux/sched.h>
23231 +#include <linux/file.h>
23232 +#include <linux/binfmts.h>
23233 +#include <linux/smp_lock.h>
23234 +#include <linux/fs.h>
23235 +#include <linux/types.h>
23236 +#include <linux/grdefs.h>
23237 +#include <linux/grinternal.h>
23238 +#include <linux/capability.h>
23240 +#include <asm/uaccess.h>
23242 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23243 +static char gr_exec_arg_buf[132];
23244 +static DECLARE_MUTEX(gr_exec_arg_sem);
23248 +gr_handle_nproc(void)
23250 +#ifdef CONFIG_GRKERNSEC_EXECVE
23251 + if (grsec_enable_execve && current->user &&
23252 + (atomic_read(¤t->user->processes) >
23253 + current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
23254 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
23255 + gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
23263 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
23265 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23266 + char *grarg = gr_exec_arg_buf;
23267 + unsigned int i, x, execlen = 0;
23270 + if (!((grsec_enable_execlog && grsec_enable_group &&
23271 + in_group_p(grsec_audit_gid))
23272 + || (grsec_enable_execlog && !grsec_enable_group)))
23275 + down(&gr_exec_arg_sem);
23276 + memset(grarg, 0, sizeof(gr_exec_arg_buf));
23278 + if (unlikely(argv == NULL))
23281 + for (i = 0; i < bprm->argc && execlen < 128; i++) {
23282 + const char __user *p;
23283 + unsigned int len;
23285 + if (copy_from_user(&p, argv + i, sizeof(p)))
23289 + len = strnlen_user(p, 128 - execlen);
23290 + if (len > 128 - execlen)
23291 + len = 128 - execlen;
23292 + else if (len > 0)
23294 + if (copy_from_user(grarg + execlen, p, len))
23297 + /* rewrite unprintable characters */
23298 + for (x = 0; x < len; x++) {
23299 + c = *(grarg + execlen + x);
23300 + if (c < 32 || c > 126)
23301 + *(grarg + execlen + x) = ' ';
23305 + *(grarg + execlen) = ' ';
23306 + *(grarg + execlen + 1) = '\0';
23311 + gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
23312 + bprm->file->f_path.mnt, grarg);
23313 + up(&gr_exec_arg_sem);
23317 diff -urNp linux-2.6.25.10/grsecurity/grsec_fifo.c linux-2.6.25.10/grsecurity/grsec_fifo.c
23318 --- linux-2.6.25.10/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
23319 +++ linux-2.6.25.10/grsecurity/grsec_fifo.c 2008-07-03 16:53:26.000000000 -0400
23321 +#include <linux/kernel.h>
23322 +#include <linux/sched.h>
23323 +#include <linux/fs.h>
23324 +#include <linux/file.h>
23325 +#include <linux/grinternal.h>
23328 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
23329 + const struct dentry *dir, const int flag, const int acc_mode)
23331 +#ifdef CONFIG_GRKERNSEC_FIFO
23332 + if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
23333 + !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
23334 + (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
23335 + (current->fsuid != dentry->d_inode->i_uid)) {
23336 + if (!generic_permission(dentry->d_inode, acc_mode, NULL))
23337 + gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
23343 diff -urNp linux-2.6.25.10/grsecurity/grsec_fork.c linux-2.6.25.10/grsecurity/grsec_fork.c
23344 --- linux-2.6.25.10/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
23345 +++ linux-2.6.25.10/grsecurity/grsec_fork.c 2008-07-03 16:53:26.000000000 -0400
23347 +#include <linux/kernel.h>
23348 +#include <linux/sched.h>
23349 +#include <linux/grsecurity.h>
23350 +#include <linux/grinternal.h>
23351 +#include <linux/errno.h>
23354 +gr_log_forkfail(const int retval)
23356 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
23357 + if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
23358 + gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
23362 diff -urNp linux-2.6.25.10/grsecurity/grsec_init.c linux-2.6.25.10/grsecurity/grsec_init.c
23363 --- linux-2.6.25.10/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
23364 +++ linux-2.6.25.10/grsecurity/grsec_init.c 2008-07-03 16:53:26.000000000 -0400
23366 +#include <linux/kernel.h>
23367 +#include <linux/sched.h>
23368 +#include <linux/mm.h>
23369 +#include <linux/smp_lock.h>
23370 +#include <linux/gracl.h>
23371 +#include <linux/slab.h>
23372 +#include <linux/vmalloc.h>
23373 +#include <linux/percpu.h>
23375 +int grsec_enable_link;
23376 +int grsec_enable_dmesg;
23377 +int grsec_enable_fifo;
23378 +int grsec_enable_execve;
23379 +int grsec_enable_execlog;
23380 +int grsec_enable_signal;
23381 +int grsec_enable_forkfail;
23382 +int grsec_enable_time;
23383 +int grsec_enable_audit_textrel;
23384 +int grsec_enable_group;
23385 +int grsec_audit_gid;
23386 +int grsec_enable_chdir;
23387 +int grsec_enable_audit_ipc;
23388 +int grsec_enable_mount;
23389 +int grsec_enable_chroot_findtask;
23390 +int grsec_enable_chroot_mount;
23391 +int grsec_enable_chroot_shmat;
23392 +int grsec_enable_chroot_fchdir;
23393 +int grsec_enable_chroot_double;
23394 +int grsec_enable_chroot_pivot;
23395 +int grsec_enable_chroot_chdir;
23396 +int grsec_enable_chroot_chmod;
23397 +int grsec_enable_chroot_mknod;
23398 +int grsec_enable_chroot_nice;
23399 +int grsec_enable_chroot_execlog;
23400 +int grsec_enable_chroot_caps;
23401 +int grsec_enable_chroot_sysctl;
23402 +int grsec_enable_chroot_unix;
23403 +int grsec_enable_tpe;
23404 +int grsec_tpe_gid;
23405 +int grsec_enable_tpe_all;
23406 +int grsec_enable_socket_all;
23407 +int grsec_socket_all_gid;
23408 +int grsec_enable_socket_client;
23409 +int grsec_socket_client_gid;
23410 +int grsec_enable_socket_server;
23411 +int grsec_socket_server_gid;
23412 +int grsec_resource_logging;
23415 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
23416 +unsigned long grsec_alert_wtime = 0;
23417 +unsigned long grsec_alert_fyet = 0;
23419 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
23421 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
23423 +char *gr_shared_page[4];
23425 +char *gr_alert_log_fmt;
23426 +char *gr_audit_log_fmt;
23427 +char *gr_alert_log_buf;
23428 +char *gr_audit_log_buf;
23430 +extern struct gr_arg *gr_usermode;
23431 +extern unsigned char *gr_system_salt;
23432 +extern unsigned char *gr_system_sum;
23435 +grsecurity_init(void)
23438 + /* create the per-cpu shared pages */
23440 + for (j = 0; j < 4; j++) {
23441 + gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
23442 + if (gr_shared_page[j] == NULL) {
23443 + panic("Unable to allocate grsecurity shared page");
23448 + /* allocate log buffers */
23449 + gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
23450 + if (!gr_alert_log_fmt) {
23451 + panic("Unable to allocate grsecurity alert log format buffer");
23454 + gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
23455 + if (!gr_audit_log_fmt) {
23456 + panic("Unable to allocate grsecurity audit log format buffer");
23459 + gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23460 + if (!gr_alert_log_buf) {
23461 + panic("Unable to allocate grsecurity alert log buffer");
23464 + gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23465 + if (!gr_audit_log_buf) {
23466 + panic("Unable to allocate grsecurity audit log buffer");
23470 + /* allocate memory for authentication structure */
23471 + gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
23472 + gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
23473 + gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
23475 + if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
23476 + panic("Unable to allocate grsecurity authentication structure");
23480 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
23481 +#ifndef CONFIG_GRKERNSEC_SYSCTL
23484 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
23485 + grsec_enable_audit_textrel = 1;
23487 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
23488 + grsec_enable_group = 1;
23489 + grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
23491 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
23492 + grsec_enable_chdir = 1;
23494 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23495 + grsec_enable_audit_ipc = 1;
23497 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
23498 + grsec_enable_mount = 1;
23500 +#ifdef CONFIG_GRKERNSEC_LINK
23501 + grsec_enable_link = 1;
23503 +#ifdef CONFIG_GRKERNSEC_DMESG
23504 + grsec_enable_dmesg = 1;
23506 +#ifdef CONFIG_GRKERNSEC_FIFO
23507 + grsec_enable_fifo = 1;
23509 +#ifdef CONFIG_GRKERNSEC_EXECVE
23510 + grsec_enable_execve = 1;
23512 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23513 + grsec_enable_execlog = 1;
23515 +#ifdef CONFIG_GRKERNSEC_SIGNAL
23516 + grsec_enable_signal = 1;
23518 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
23519 + grsec_enable_forkfail = 1;
23521 +#ifdef CONFIG_GRKERNSEC_TIME
23522 + grsec_enable_time = 1;
23524 +#ifdef CONFIG_GRKERNSEC_RESLOG
23525 + grsec_resource_logging = 1;
23527 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
23528 + grsec_enable_chroot_findtask = 1;
23530 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23531 + grsec_enable_chroot_unix = 1;
23533 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23534 + grsec_enable_chroot_mount = 1;
23536 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23537 + grsec_enable_chroot_fchdir = 1;
23539 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23540 + grsec_enable_chroot_shmat = 1;
23542 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23543 + grsec_enable_chroot_double = 1;
23545 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23546 + grsec_enable_chroot_pivot = 1;
23548 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23549 + grsec_enable_chroot_chdir = 1;
23551 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23552 + grsec_enable_chroot_chmod = 1;
23554 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23555 + grsec_enable_chroot_mknod = 1;
23557 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23558 + grsec_enable_chroot_nice = 1;
23560 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23561 + grsec_enable_chroot_execlog = 1;
23563 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23564 + grsec_enable_chroot_caps = 1;
23566 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23567 + grsec_enable_chroot_sysctl = 1;
23569 +#ifdef CONFIG_GRKERNSEC_TPE
23570 + grsec_enable_tpe = 1;
23571 + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
23572 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
23573 + grsec_enable_tpe_all = 1;
23576 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
23577 + grsec_enable_socket_all = 1;
23578 + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
23580 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
23581 + grsec_enable_socket_client = 1;
23582 + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
23584 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
23585 + grsec_enable_socket_server = 1;
23586 + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
23592 diff -urNp linux-2.6.25.10/grsecurity/grsec_ipc.c linux-2.6.25.10/grsecurity/grsec_ipc.c
23593 --- linux-2.6.25.10/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
23594 +++ linux-2.6.25.10/grsecurity/grsec_ipc.c 2008-07-03 16:53:26.000000000 -0400
23596 +#include <linux/kernel.h>
23597 +#include <linux/sched.h>
23598 +#include <linux/types.h>
23599 +#include <linux/ipc.h>
23600 +#include <linux/grsecurity.h>
23601 +#include <linux/grinternal.h>
23604 +gr_log_msgget(const int ret, const int msgflg)
23606 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23607 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23608 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
23609 + !grsec_enable_group)) && (ret >= 0)
23610 + && (msgflg & IPC_CREAT))
23611 + gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
23617 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
23619 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23620 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23621 + grsec_enable_audit_ipc) ||
23622 + (grsec_enable_audit_ipc && !grsec_enable_group))
23623 + gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
23629 +gr_log_semget(const int err, const int semflg)
23631 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23632 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23633 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
23634 + !grsec_enable_group)) && (err >= 0)
23635 + && (semflg & IPC_CREAT))
23636 + gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
23642 +gr_log_semrm(const uid_t uid, const uid_t cuid)
23644 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23645 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23646 + grsec_enable_audit_ipc) ||
23647 + (grsec_enable_audit_ipc && !grsec_enable_group))
23648 + gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
23654 +gr_log_shmget(const int err, const int shmflg, const size_t size)
23656 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23657 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23658 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
23659 + !grsec_enable_group)) && (err >= 0)
23660 + && (shmflg & IPC_CREAT))
23661 + gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
23667 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
23669 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23670 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23671 + grsec_enable_audit_ipc) ||
23672 + (grsec_enable_audit_ipc && !grsec_enable_group))
23673 + gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
23677 diff -urNp linux-2.6.25.10/grsecurity/grsec_link.c linux-2.6.25.10/grsecurity/grsec_link.c
23678 --- linux-2.6.25.10/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
23679 +++ linux-2.6.25.10/grsecurity/grsec_link.c 2008-07-03 16:53:26.000000000 -0400
23681 +#include <linux/kernel.h>
23682 +#include <linux/sched.h>
23683 +#include <linux/fs.h>
23684 +#include <linux/file.h>
23685 +#include <linux/grinternal.h>
23688 +gr_handle_follow_link(const struct inode *parent,
23689 + const struct inode *inode,
23690 + const struct dentry *dentry, const struct vfsmount *mnt)
23692 +#ifdef CONFIG_GRKERNSEC_LINK
23693 + if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
23694 + (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
23695 + (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
23696 + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
23704 +gr_handle_hardlink(const struct dentry *dentry,
23705 + const struct vfsmount *mnt,
23706 + struct inode *inode, const int mode, const char *to)
23708 +#ifdef CONFIG_GRKERNSEC_LINK
23709 + if (grsec_enable_link && current->fsuid != inode->i_uid &&
23710 + (!S_ISREG(mode) || (mode & S_ISUID) ||
23711 + ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
23712 + (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
23713 + !capable(CAP_FOWNER) && current->uid) {
23714 + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
23720 diff -urNp linux-2.6.25.10/grsecurity/grsec_log.c linux-2.6.25.10/grsecurity/grsec_log.c
23721 --- linux-2.6.25.10/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
23722 +++ linux-2.6.25.10/grsecurity/grsec_log.c 2008-07-03 16:53:26.000000000 -0400
23724 +#include <linux/kernel.h>
23725 +#include <linux/sched.h>
23726 +#include <linux/file.h>
23727 +#include <linux/tty.h>
23728 +#include <linux/fs.h>
23729 +#include <linux/grinternal.h>
23731 +#define BEGIN_LOCKS(x) \
23732 + read_lock(&tasklist_lock); \
23733 + read_lock(&grsec_exec_file_lock); \
23734 + if (x != GR_DO_AUDIT) \
23735 + spin_lock(&grsec_alert_lock); \
23737 + spin_lock(&grsec_audit_lock)
23739 +#define END_LOCKS(x) \
23740 + if (x != GR_DO_AUDIT) \
23741 + spin_unlock(&grsec_alert_lock); \
23743 + spin_unlock(&grsec_audit_lock); \
23744 + read_unlock(&grsec_exec_file_lock); \
23745 + read_unlock(&tasklist_lock); \
23746 + if (x == GR_DONT_AUDIT) \
23747 + gr_handle_alertkill(current)
23754 +extern char *gr_alert_log_fmt;
23755 +extern char *gr_audit_log_fmt;
23756 +extern char *gr_alert_log_buf;
23757 +extern char *gr_audit_log_buf;
23759 +static int gr_log_start(int audit)
23761 + char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
23762 + char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
23763 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
23765 + if (audit == GR_DO_AUDIT)
23768 + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
23769 + grsec_alert_wtime = jiffies;
23770 + grsec_alert_fyet = 0;
23771 + } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
23772 + grsec_alert_fyet++;
23773 + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
23774 + grsec_alert_wtime = jiffies;
23775 + grsec_alert_fyet++;
23776 + printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
23778 + } else return FLOODING;
23781 + memset(buf, 0, PAGE_SIZE);
23782 + if (current->signal->curr_ip && gr_acl_is_enabled()) {
23783 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
23784 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
23785 + } else if (current->signal->curr_ip) {
23786 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
23787 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
23788 + } else if (gr_acl_is_enabled()) {
23789 + sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
23790 + snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
23792 + sprintf(fmt, "%s%s", loglevel, "grsec: ");
23793 + strcpy(buf, fmt);
23796 + return NO_FLOODING;
23799 +static void gr_log_middle(int audit, const char *msg, va_list ap)
23801 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
23802 + unsigned int len = strlen(buf);
23804 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
23809 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
23811 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
23812 + unsigned int len = strlen(buf);
23815 + va_start(ap, msg);
23816 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
23822 +static void gr_log_end(int audit)
23824 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
23825 + unsigned int len = strlen(buf);
23827 + snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
23828 + printk("%s\n", buf);
23833 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
23836 + char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
23837 + char *str1, *str2, *str3;
23839 + unsigned long ulong1, ulong2;
23840 + struct dentry *dentry;
23841 + struct vfsmount *mnt;
23842 + struct file *file;
23843 + struct task_struct *task;
23846 + BEGIN_LOCKS(audit);
23847 + logtype = gr_log_start(audit);
23848 + if (logtype == FLOODING) {
23849 + END_LOCKS(audit);
23852 + va_start(ap, argtypes);
23853 + switch (argtypes) {
23854 + case GR_TTYSNIFF:
23855 + task = va_arg(ap, struct task_struct *);
23856 + 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);
23858 + case GR_SYSCTL_HIDDEN:
23859 + str1 = va_arg(ap, char *);
23860 + gr_log_middle_varargs(audit, msg, result, str1);
23863 + dentry = va_arg(ap, struct dentry *);
23864 + mnt = va_arg(ap, struct vfsmount *);
23865 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
23867 + case GR_RBAC_STR:
23868 + dentry = va_arg(ap, struct dentry *);
23869 + mnt = va_arg(ap, struct vfsmount *);
23870 + str1 = va_arg(ap, char *);
23871 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
23873 + case GR_STR_RBAC:
23874 + str1 = va_arg(ap, char *);
23875 + dentry = va_arg(ap, struct dentry *);
23876 + mnt = va_arg(ap, struct vfsmount *);
23877 + gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
23879 + case GR_RBAC_MODE2:
23880 + dentry = va_arg(ap, struct dentry *);
23881 + mnt = va_arg(ap, struct vfsmount *);
23882 + str1 = va_arg(ap, char *);
23883 + str2 = va_arg(ap, char *);
23884 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
23886 + case GR_RBAC_MODE3:
23887 + dentry = va_arg(ap, struct dentry *);
23888 + mnt = va_arg(ap, struct vfsmount *);
23889 + str1 = va_arg(ap, char *);
23890 + str2 = va_arg(ap, char *);
23891 + str3 = va_arg(ap, char *);
23892 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
23894 + case GR_FILENAME:
23895 + dentry = va_arg(ap, struct dentry *);
23896 + mnt = va_arg(ap, struct vfsmount *);
23897 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
23899 + case GR_STR_FILENAME:
23900 + str1 = va_arg(ap, char *);
23901 + dentry = va_arg(ap, struct dentry *);
23902 + mnt = va_arg(ap, struct vfsmount *);
23903 + gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
23905 + case GR_FILENAME_STR:
23906 + dentry = va_arg(ap, struct dentry *);
23907 + mnt = va_arg(ap, struct vfsmount *);
23908 + str1 = va_arg(ap, char *);
23909 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
23911 + case GR_FILENAME_TWO_INT:
23912 + dentry = va_arg(ap, struct dentry *);
23913 + mnt = va_arg(ap, struct vfsmount *);
23914 + num1 = va_arg(ap, int);
23915 + num2 = va_arg(ap, int);
23916 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
23918 + case GR_FILENAME_TWO_INT_STR:
23919 + dentry = va_arg(ap, struct dentry *);
23920 + mnt = va_arg(ap, struct vfsmount *);
23921 + num1 = va_arg(ap, int);
23922 + num2 = va_arg(ap, int);
23923 + str1 = va_arg(ap, char *);
23924 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
23927 + file = va_arg(ap, struct file *);
23928 + ulong1 = va_arg(ap, unsigned long);
23929 + ulong2 = va_arg(ap, unsigned long);
23930 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
23933 + task = va_arg(ap, struct task_struct *);
23934 + 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);
23936 + case GR_RESOURCE:
23937 + task = va_arg(ap, struct task_struct *);
23938 + ulong1 = va_arg(ap, unsigned long);
23939 + str1 = va_arg(ap, char *);
23940 + ulong2 = va_arg(ap, unsigned long);
23941 + 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);
23944 + task = va_arg(ap, struct task_struct *);
23945 + str1 = va_arg(ap, char *);
23946 + 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);
23949 + task = va_arg(ap, struct task_struct *);
23950 + num1 = va_arg(ap, int);
23951 + 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);
23954 + task = va_arg(ap, struct task_struct *);
23955 + ulong1 = va_arg(ap, unsigned long);
23956 + 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);
23959 + task = va_arg(ap, struct task_struct *);
23960 + ulong1 = va_arg(ap, unsigned long);
23961 + 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);
23965 + unsigned int wday, cday;
23969 + char cur_tty[64] = { 0 };
23970 + char parent_tty[64] = { 0 };
23972 + task = va_arg(ap, struct task_struct *);
23973 + wday = va_arg(ap, unsigned int);
23974 + cday = va_arg(ap, unsigned int);
23975 + whr = va_arg(ap, int);
23976 + chr = va_arg(ap, int);
23977 + wmin = va_arg(ap, int);
23978 + cmin = va_arg(ap, int);
23979 + wsec = va_arg(ap, int);
23980 + csec = va_arg(ap, int);
23981 + ulong1 = va_arg(ap, unsigned long);
23983 + 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);
23987 + gr_log_middle(audit, msg, ap);
23990 + gr_log_end(audit);
23991 + END_LOCKS(audit);
23993 diff -urNp linux-2.6.25.10/grsecurity/grsec_mem.c linux-2.6.25.10/grsecurity/grsec_mem.c
23994 --- linux-2.6.25.10/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
23995 +++ linux-2.6.25.10/grsecurity/grsec_mem.c 2008-07-03 16:53:26.000000000 -0400
23997 +#include <linux/kernel.h>
23998 +#include <linux/sched.h>
23999 +#include <linux/mm.h>
24000 +#include <linux/mman.h>
24001 +#include <linux/grinternal.h>
24004 +gr_handle_ioperm(void)
24006 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
24011 +gr_handle_iopl(void)
24013 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
24018 +gr_handle_mem_write(void)
24020 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
24025 +gr_handle_kmem_write(void)
24027 + gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
24032 +gr_handle_open_port(void)
24034 + gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
24039 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
24041 + unsigned long start, end;
24044 + end = start + vma->vm_end - vma->vm_start;
24046 + if (start > end) {
24047 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
24051 + /* allowed ranges : ISA I/O BIOS */
24052 + if ((start >= __pa(high_memory))
24054 + || (start >= 0x000a0000 && end <= 0x00100000)
24055 + || (start >= 0x00000000 && end <= 0x00001000)
24060 + if (vma->vm_flags & VM_WRITE) {
24061 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
24064 + vma->vm_flags &= ~VM_MAYWRITE;
24068 diff -urNp linux-2.6.25.10/grsecurity/grsec_mount.c linux-2.6.25.10/grsecurity/grsec_mount.c
24069 --- linux-2.6.25.10/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
24070 +++ linux-2.6.25.10/grsecurity/grsec_mount.c 2008-07-03 16:53:26.000000000 -0400
24072 +#include <linux/kernel.h>
24073 +#include <linux/sched.h>
24074 +#include <linux/grsecurity.h>
24075 +#include <linux/grinternal.h>
24078 +gr_log_remount(const char *devname, const int retval)
24080 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24081 + if (grsec_enable_mount && (retval >= 0))
24082 + gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
24088 +gr_log_unmount(const char *devname, const int retval)
24090 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24091 + if (grsec_enable_mount && (retval >= 0))
24092 + gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
24098 +gr_log_mount(const char *from, const char *to, const int retval)
24100 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24101 + if (grsec_enable_mount && (retval >= 0))
24102 + gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
24106 diff -urNp linux-2.6.25.10/grsecurity/grsec_sig.c linux-2.6.25.10/grsecurity/grsec_sig.c
24107 --- linux-2.6.25.10/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
24108 +++ linux-2.6.25.10/grsecurity/grsec_sig.c 2008-07-03 16:53:26.000000000 -0400
24110 +#include <linux/kernel.h>
24111 +#include <linux/sched.h>
24112 +#include <linux/delay.h>
24113 +#include <linux/grsecurity.h>
24114 +#include <linux/grinternal.h>
24117 +gr_log_signal(const int sig, const struct task_struct *t)
24119 +#ifdef CONFIG_GRKERNSEC_SIGNAL
24120 + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
24121 + (sig == SIGABRT) || (sig == SIGBUS))) {
24122 + if (t->pid == current->pid) {
24123 + gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
24125 + gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
24133 +gr_handle_signal(const struct task_struct *p, const int sig)
24135 +#ifdef CONFIG_GRKERNSEC
24136 + if (current->pid > 1 && gr_check_protected_task(p)) {
24137 + gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
24139 + } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
24146 +void gr_handle_brute_attach(struct task_struct *p)
24148 +#ifdef CONFIG_GRKERNSEC_BRUTE
24149 + read_lock(&tasklist_lock);
24150 + read_lock(&grsec_exec_file_lock);
24151 + if (p->parent && p->parent->exec_file == p->exec_file)
24152 + p->parent->brute = 1;
24153 + read_unlock(&grsec_exec_file_lock);
24154 + read_unlock(&tasklist_lock);
24159 +void gr_handle_brute_check(void)
24161 +#ifdef CONFIG_GRKERNSEC_BRUTE
24162 + if (current->brute)
24163 + msleep(30 * 1000);
24168 diff -urNp linux-2.6.25.10/grsecurity/grsec_sock.c linux-2.6.25.10/grsecurity/grsec_sock.c
24169 --- linux-2.6.25.10/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
24170 +++ linux-2.6.25.10/grsecurity/grsec_sock.c 2008-07-03 16:53:26.000000000 -0400
24172 +#include <linux/kernel.h>
24173 +#include <linux/module.h>
24174 +#include <linux/sched.h>
24175 +#include <linux/file.h>
24176 +#include <linux/net.h>
24177 +#include <linux/in.h>
24178 +#include <linux/ip.h>
24179 +#include <net/sock.h>
24180 +#include <net/inet_sock.h>
24181 +#include <linux/grsecurity.h>
24182 +#include <linux/grinternal.h>
24183 +#include <linux/gracl.h>
24185 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
24186 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
24187 +EXPORT_SYMBOL(udp_v4_lookup);
24190 +kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
24191 +EXPORT_SYMBOL(gr_cap_rtnetlink);
24193 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
24194 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
24196 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
24197 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
24199 +#ifdef CONFIG_UNIX_MODULE
24200 +EXPORT_SYMBOL(gr_acl_handle_unix);
24201 +EXPORT_SYMBOL(gr_acl_handle_mknod);
24202 +EXPORT_SYMBOL(gr_handle_chroot_unix);
24203 +EXPORT_SYMBOL(gr_handle_create);
24206 +#ifdef CONFIG_GRKERNSEC
24207 +#define gr_conn_table_size 32749
24208 +struct conn_table_entry {
24209 + struct conn_table_entry *next;
24210 + struct signal_struct *sig;
24213 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
24214 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
24216 +extern const char * gr_socktype_to_name(unsigned char type);
24217 +extern const char * gr_proto_to_name(unsigned char proto);
24219 +static __inline__ int
24220 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
24222 + return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
24225 +static __inline__ int
24226 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
24227 + __u16 sport, __u16 dport)
24229 + if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
24230 + sig->gr_sport == sport && sig->gr_dport == dport))
24236 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
24238 + struct conn_table_entry **match;
24239 + unsigned int index;
24241 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
24242 + sig->gr_sport, sig->gr_dport,
24243 + gr_conn_table_size);
24245 + newent->sig = sig;
24247 + match = &gr_conn_table[index];
24248 + newent->next = *match;
24254 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
24256 + struct conn_table_entry *match, *last = NULL;
24257 + unsigned int index;
24259 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
24260 + sig->gr_sport, sig->gr_dport,
24261 + gr_conn_table_size);
24263 + match = gr_conn_table[index];
24264 + while (match && !conn_match(match->sig,
24265 + sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
24266 + sig->gr_dport)) {
24268 + match = match->next;
24273 + last->next = match->next;
24275 + gr_conn_table[index] = NULL;
24282 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
24283 + __u16 sport, __u16 dport)
24285 + struct conn_table_entry *match;
24286 + unsigned int index;
24288 + index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
24290 + match = gr_conn_table[index];
24291 + while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
24292 + match = match->next;
24295 + return match->sig;
24302 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
24304 +#ifdef CONFIG_GRKERNSEC
24305 + struct signal_struct *sig = task->signal;
24306 + struct conn_table_entry *newent;
24308 + newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
24309 + if (newent == NULL)
24311 + /* no bh lock needed since we are called with bh disabled */
24312 + spin_lock(&gr_conn_table_lock);
24313 + gr_del_task_from_ip_table_nolock(sig);
24314 + sig->gr_saddr = inet->rcv_saddr;
24315 + sig->gr_daddr = inet->daddr;
24316 + sig->gr_sport = inet->sport;
24317 + sig->gr_dport = inet->dport;
24318 + gr_add_to_task_ip_table_nolock(sig, newent);
24319 + spin_unlock(&gr_conn_table_lock);
24324 +void gr_del_task_from_ip_table(struct task_struct *task)
24326 +#ifdef CONFIG_GRKERNSEC
24327 + spin_lock(&gr_conn_table_lock);
24328 + gr_del_task_from_ip_table_nolock(task->signal);
24329 + spin_unlock(&gr_conn_table_lock);
24335 +gr_attach_curr_ip(const struct sock *sk)
24337 +#ifdef CONFIG_GRKERNSEC
24338 + struct signal_struct *p, *set;
24339 + const struct inet_sock *inet = inet_sk(sk);
24341 + if (unlikely(sk->sk_protocol != IPPROTO_TCP))
24344 + set = current->signal;
24346 + spin_lock_bh(&gr_conn_table_lock);
24347 + p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
24348 + inet->dport, inet->sport);
24349 + if (unlikely(p != NULL)) {
24350 + set->curr_ip = p->curr_ip;
24351 + set->used_accept = 1;
24352 + gr_del_task_from_ip_table_nolock(p);
24353 + spin_unlock_bh(&gr_conn_table_lock);
24356 + spin_unlock_bh(&gr_conn_table_lock);
24358 + set->curr_ip = inet->daddr;
24359 + set->used_accept = 1;
24365 +gr_handle_sock_all(const int family, const int type, const int protocol)
24367 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24368 + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
24369 + (family != AF_UNIX) && (family != AF_LOCAL)) {
24370 + gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
24378 +gr_handle_sock_server(const struct sockaddr *sck)
24380 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24381 + if (grsec_enable_socket_server &&
24382 + in_group_p(grsec_socket_server_gid) &&
24383 + sck && (sck->sa_family != AF_UNIX) &&
24384 + (sck->sa_family != AF_LOCAL)) {
24385 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24393 +gr_handle_sock_server_other(const struct sock *sck)
24395 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24396 + if (grsec_enable_socket_server &&
24397 + in_group_p(grsec_socket_server_gid) &&
24398 + sck && (sck->sk_family != AF_UNIX) &&
24399 + (sck->sk_family != AF_LOCAL)) {
24400 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24408 +gr_handle_sock_client(const struct sockaddr *sck)
24410 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24411 + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
24412 + sck && (sck->sa_family != AF_UNIX) &&
24413 + (sck->sa_family != AF_LOCAL)) {
24414 + gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
24422 +gr_cap_rtnetlink(struct sock *sock)
24424 +#ifdef CONFIG_GRKERNSEC
24425 + if (!gr_acl_is_enabled())
24426 + return current->cap_effective;
24427 + else if (sock->sk_protocol == NETLINK_ISCSI &&
24428 + cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
24429 + gr_task_is_capable(current, CAP_SYS_ADMIN))
24430 + return current->cap_effective;
24431 + else if (sock->sk_protocol == NETLINK_AUDIT &&
24432 + cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
24433 + gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
24434 + cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
24435 + gr_task_is_capable(current, CAP_AUDIT_CONTROL))
24436 + return current->cap_effective;
24437 + else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
24438 + gr_task_is_capable(current, CAP_NET_ADMIN))
24439 + return current->cap_effective;
24441 + return __cap_empty_set;
24443 + return current->cap_effective;
24446 diff -urNp linux-2.6.25.10/grsecurity/grsec_sysctl.c linux-2.6.25.10/grsecurity/grsec_sysctl.c
24447 --- linux-2.6.25.10/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
24448 +++ linux-2.6.25.10/grsecurity/grsec_sysctl.c 2008-07-03 16:53:26.000000000 -0400
24450 +#include <linux/kernel.h>
24451 +#include <linux/sched.h>
24452 +#include <linux/sysctl.h>
24453 +#include <linux/grsecurity.h>
24454 +#include <linux/grinternal.h>
24456 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24457 +int grsec_modstop;
24461 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
24463 +#ifdef CONFIG_GRKERNSEC_SYSCTL
24464 + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
24465 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24469 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24470 + if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
24471 + grsec_modstop && (op & 002)) {
24472 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24479 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
24480 +ctl_table grsecurity_table[] = {
24481 +#ifdef CONFIG_GRKERNSEC_SYSCTL
24482 +#ifdef CONFIG_GRKERNSEC_LINK
24484 + .ctl_name = CTL_UNNUMBERED,
24485 + .procname = "linking_restrictions",
24486 + .data = &grsec_enable_link,
24487 + .maxlen = sizeof(int),
24489 + .proc_handler = &proc_dointvec,
24492 +#ifdef CONFIG_GRKERNSEC_FIFO
24494 + .ctl_name = CTL_UNNUMBERED,
24495 + .procname = "fifo_restrictions",
24496 + .data = &grsec_enable_fifo,
24497 + .maxlen = sizeof(int),
24499 + .proc_handler = &proc_dointvec,
24502 +#ifdef CONFIG_GRKERNSEC_EXECVE
24504 + .ctl_name = CTL_UNNUMBERED,
24505 + .procname = "execve_limiting",
24506 + .data = &grsec_enable_execve,
24507 + .maxlen = sizeof(int),
24509 + .proc_handler = &proc_dointvec,
24512 +#ifdef CONFIG_GRKERNSEC_EXECLOG
24514 + .ctl_name = CTL_UNNUMBERED,
24515 + .procname = "exec_logging",
24516 + .data = &grsec_enable_execlog,
24517 + .maxlen = sizeof(int),
24519 + .proc_handler = &proc_dointvec,
24522 +#ifdef CONFIG_GRKERNSEC_SIGNAL
24524 + .ctl_name = CTL_UNNUMBERED,
24525 + .procname = "signal_logging",
24526 + .data = &grsec_enable_signal,
24527 + .maxlen = sizeof(int),
24529 + .proc_handler = &proc_dointvec,
24532 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
24534 + .ctl_name = CTL_UNNUMBERED,
24535 + .procname = "forkfail_logging",
24536 + .data = &grsec_enable_forkfail,
24537 + .maxlen = sizeof(int),
24539 + .proc_handler = &proc_dointvec,
24542 +#ifdef CONFIG_GRKERNSEC_TIME
24544 + .ctl_name = CTL_UNNUMBERED,
24545 + .procname = "timechange_logging",
24546 + .data = &grsec_enable_time,
24547 + .maxlen = sizeof(int),
24549 + .proc_handler = &proc_dointvec,
24552 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
24554 + .ctl_name = CTL_UNNUMBERED,
24555 + .procname = "chroot_deny_shmat",
24556 + .data = &grsec_enable_chroot_shmat,
24557 + .maxlen = sizeof(int),
24559 + .proc_handler = &proc_dointvec,
24562 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
24564 + .ctl_name = CTL_UNNUMBERED,
24565 + .procname = "chroot_deny_unix",
24566 + .data = &grsec_enable_chroot_unix,
24567 + .maxlen = sizeof(int),
24569 + .proc_handler = &proc_dointvec,
24572 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
24574 + .ctl_name = CTL_UNNUMBERED,
24575 + .procname = "chroot_deny_mount",
24576 + .data = &grsec_enable_chroot_mount,
24577 + .maxlen = sizeof(int),
24579 + .proc_handler = &proc_dointvec,
24582 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
24584 + .ctl_name = CTL_UNNUMBERED,
24585 + .procname = "chroot_deny_fchdir",
24586 + .data = &grsec_enable_chroot_fchdir,
24587 + .maxlen = sizeof(int),
24589 + .proc_handler = &proc_dointvec,
24592 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
24594 + .ctl_name = CTL_UNNUMBERED,
24595 + .procname = "chroot_deny_chroot",
24596 + .data = &grsec_enable_chroot_double,
24597 + .maxlen = sizeof(int),
24599 + .proc_handler = &proc_dointvec,
24602 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
24604 + .ctl_name = CTL_UNNUMBERED,
24605 + .procname = "chroot_deny_pivot",
24606 + .data = &grsec_enable_chroot_pivot,
24607 + .maxlen = sizeof(int),
24609 + .proc_handler = &proc_dointvec,
24612 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
24614 + .ctl_name = CTL_UNNUMBERED,
24615 + .procname = "chroot_enforce_chdir",
24616 + .data = &grsec_enable_chroot_chdir,
24617 + .maxlen = sizeof(int),
24619 + .proc_handler = &proc_dointvec,
24622 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
24624 + .ctl_name = CTL_UNNUMBERED,
24625 + .procname = "chroot_deny_chmod",
24626 + .data = &grsec_enable_chroot_chmod,
24627 + .maxlen = sizeof(int),
24629 + .proc_handler = &proc_dointvec,
24632 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
24634 + .ctl_name = CTL_UNNUMBERED,
24635 + .procname = "chroot_deny_mknod",
24636 + .data = &grsec_enable_chroot_mknod,
24637 + .maxlen = sizeof(int),
24639 + .proc_handler = &proc_dointvec,
24642 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
24644 + .ctl_name = CTL_UNNUMBERED,
24645 + .procname = "chroot_restrict_nice",
24646 + .data = &grsec_enable_chroot_nice,
24647 + .maxlen = sizeof(int),
24649 + .proc_handler = &proc_dointvec,
24652 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
24654 + .ctl_name = CTL_UNNUMBERED,
24655 + .procname = "chroot_execlog",
24656 + .data = &grsec_enable_chroot_execlog,
24657 + .maxlen = sizeof(int),
24659 + .proc_handler = &proc_dointvec,
24662 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
24664 + .ctl_name = CTL_UNNUMBERED,
24665 + .procname = "chroot_caps",
24666 + .data = &grsec_enable_chroot_caps,
24667 + .maxlen = sizeof(int),
24669 + .proc_handler = &proc_dointvec,
24672 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
24674 + .ctl_name = CTL_UNNUMBERED,
24675 + .procname = "chroot_deny_sysctl",
24676 + .data = &grsec_enable_chroot_sysctl,
24677 + .maxlen = sizeof(int),
24679 + .proc_handler = &proc_dointvec,
24682 +#ifdef CONFIG_GRKERNSEC_TPE
24684 + .ctl_name = CTL_UNNUMBERED,
24685 + .procname = "tpe",
24686 + .data = &grsec_enable_tpe,
24687 + .maxlen = sizeof(int),
24689 + .proc_handler = &proc_dointvec,
24692 + .ctl_name = CTL_UNNUMBERED,
24693 + .procname = "tpe_gid",
24694 + .data = &grsec_tpe_gid,
24695 + .maxlen = sizeof(int),
24697 + .proc_handler = &proc_dointvec,
24700 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
24702 + .ctl_name = CTL_UNNUMBERED,
24703 + .procname = "tpe_restrict_all",
24704 + .data = &grsec_enable_tpe_all,
24705 + .maxlen = sizeof(int),
24707 + .proc_handler = &proc_dointvec,
24710 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24712 + .ctl_name = CTL_UNNUMBERED,
24713 + .procname = "socket_all",
24714 + .data = &grsec_enable_socket_all,
24715 + .maxlen = sizeof(int),
24717 + .proc_handler = &proc_dointvec,
24720 + .ctl_name = CTL_UNNUMBERED,
24721 + .procname = "socket_all_gid",
24722 + .data = &grsec_socket_all_gid,
24723 + .maxlen = sizeof(int),
24725 + .proc_handler = &proc_dointvec,
24728 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24730 + .ctl_name = CTL_UNNUMBERED,
24731 + .procname = "socket_client",
24732 + .data = &grsec_enable_socket_client,
24733 + .maxlen = sizeof(int),
24735 + .proc_handler = &proc_dointvec,
24738 + .ctl_name = CTL_UNNUMBERED,
24739 + .procname = "socket_client_gid",
24740 + .data = &grsec_socket_client_gid,
24741 + .maxlen = sizeof(int),
24743 + .proc_handler = &proc_dointvec,
24746 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24748 + .ctl_name = CTL_UNNUMBERED,
24749 + .procname = "socket_server",
24750 + .data = &grsec_enable_socket_server,
24751 + .maxlen = sizeof(int),
24753 + .proc_handler = &proc_dointvec,
24756 + .ctl_name = CTL_UNNUMBERED,
24757 + .procname = "socket_server_gid",
24758 + .data = &grsec_socket_server_gid,
24759 + .maxlen = sizeof(int),
24761 + .proc_handler = &proc_dointvec,
24764 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
24766 + .ctl_name = CTL_UNNUMBERED,
24767 + .procname = "audit_group",
24768 + .data = &grsec_enable_group,
24769 + .maxlen = sizeof(int),
24771 + .proc_handler = &proc_dointvec,
24774 + .ctl_name = CTL_UNNUMBERED,
24775 + .procname = "audit_gid",
24776 + .data = &grsec_audit_gid,
24777 + .maxlen = sizeof(int),
24779 + .proc_handler = &proc_dointvec,
24782 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
24784 + .ctl_name = CTL_UNNUMBERED,
24785 + .procname = "audit_chdir",
24786 + .data = &grsec_enable_chdir,
24787 + .maxlen = sizeof(int),
24789 + .proc_handler = &proc_dointvec,
24792 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24794 + .ctl_name = CTL_UNNUMBERED,
24795 + .procname = "audit_mount",
24796 + .data = &grsec_enable_mount,
24797 + .maxlen = sizeof(int),
24799 + .proc_handler = &proc_dointvec,
24802 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24804 + .ctl_name = CTL_UNNUMBERED,
24805 + .procname = "audit_ipc",
24806 + .data = &grsec_enable_audit_ipc,
24807 + .maxlen = sizeof(int),
24809 + .proc_handler = &proc_dointvec,
24812 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
24814 + .ctl_name = CTL_UNNUMBERED,
24815 + .procname = "audit_textrel",
24816 + .data = &grsec_enable_audit_textrel,
24817 + .maxlen = sizeof(int),
24819 + .proc_handler = &proc_dointvec,
24822 +#ifdef CONFIG_GRKERNSEC_DMESG
24824 + .ctl_name = CTL_UNNUMBERED,
24825 + .procname = "dmesg",
24826 + .data = &grsec_enable_dmesg,
24827 + .maxlen = sizeof(int),
24829 + .proc_handler = &proc_dointvec,
24832 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
24834 + .ctl_name = CTL_UNNUMBERED,
24835 + .procname = "chroot_findtask",
24836 + .data = &grsec_enable_chroot_findtask,
24837 + .maxlen = sizeof(int),
24839 + .proc_handler = &proc_dointvec,
24842 +#ifdef CONFIG_GRKERNSEC_RESLOG
24844 + .ctl_name = CTL_UNNUMBERED,
24845 + .procname = "resource_logging",
24846 + .data = &grsec_resource_logging,
24847 + .maxlen = sizeof(int),
24849 + .proc_handler = &proc_dointvec,
24853 + .ctl_name = CTL_UNNUMBERED,
24854 + .procname = "grsec_lock",
24855 + .data = &grsec_lock,
24856 + .maxlen = sizeof(int),
24858 + .proc_handler = &proc_dointvec,
24861 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24863 + .ctl_name = CTL_UNNUMBERED,
24864 + .procname = "disable_modules",
24865 + .data = &grsec_modstop,
24866 + .maxlen = sizeof(int),
24868 + .proc_handler = &proc_dointvec,
24871 + { .ctl_name = 0 }
24875 +int gr_check_modstop(void)
24877 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24878 + if (grsec_modstop == 1) {
24879 + gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
24885 diff -urNp linux-2.6.25.10/grsecurity/grsec_textrel.c linux-2.6.25.10/grsecurity/grsec_textrel.c
24886 --- linux-2.6.25.10/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
24887 +++ linux-2.6.25.10/grsecurity/grsec_textrel.c 2008-07-03 16:53:26.000000000 -0400
24889 +#include <linux/kernel.h>
24890 +#include <linux/sched.h>
24891 +#include <linux/mm.h>
24892 +#include <linux/file.h>
24893 +#include <linux/grinternal.h>
24894 +#include <linux/grsecurity.h>
24897 +gr_log_textrel(struct vm_area_struct * vma)
24899 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
24900 + if (grsec_enable_audit_textrel)
24901 + gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
24905 diff -urNp linux-2.6.25.10/grsecurity/grsec_time.c linux-2.6.25.10/grsecurity/grsec_time.c
24906 --- linux-2.6.25.10/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
24907 +++ linux-2.6.25.10/grsecurity/grsec_time.c 2008-07-03 16:53:26.000000000 -0400
24909 +#include <linux/kernel.h>
24910 +#include <linux/sched.h>
24911 +#include <linux/grinternal.h>
24914 +gr_log_timechange(void)
24916 +#ifdef CONFIG_GRKERNSEC_TIME
24917 + if (grsec_enable_time)
24918 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
24922 diff -urNp linux-2.6.25.10/grsecurity/grsec_tpe.c linux-2.6.25.10/grsecurity/grsec_tpe.c
24923 --- linux-2.6.25.10/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
24924 +++ linux-2.6.25.10/grsecurity/grsec_tpe.c 2008-07-03 16:53:26.000000000 -0400
24926 +#include <linux/kernel.h>
24927 +#include <linux/sched.h>
24928 +#include <linux/file.h>
24929 +#include <linux/fs.h>
24930 +#include <linux/grinternal.h>
24932 +extern int gr_acl_tpe_check(void);
24935 +gr_tpe_allow(const struct file *file)
24937 +#ifdef CONFIG_GRKERNSEC
24938 + struct inode *inode = file->f_path.dentry->d_parent->d_inode;
24940 + if (current->uid && ((grsec_enable_tpe &&
24941 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
24942 + !in_group_p(grsec_tpe_gid)
24944 + in_group_p(grsec_tpe_gid)
24946 + ) || gr_acl_tpe_check()) &&
24947 + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
24948 + (inode->i_mode & S_IWOTH))))) {
24949 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
24952 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
24953 + if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
24954 + ((inode->i_uid && (inode->i_uid != current->uid)) ||
24955 + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
24956 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
24963 diff -urNp linux-2.6.25.10/grsecurity/grsum.c linux-2.6.25.10/grsecurity/grsum.c
24964 --- linux-2.6.25.10/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
24965 +++ linux-2.6.25.10/grsecurity/grsum.c 2008-07-03 16:53:26.000000000 -0400
24967 +#include <linux/err.h>
24968 +#include <linux/kernel.h>
24969 +#include <linux/sched.h>
24970 +#include <linux/mm.h>
24971 +#include <linux/scatterlist.h>
24972 +#include <linux/crypto.h>
24973 +#include <linux/gracl.h>
24976 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
24977 +#error "crypto and sha256 must be built into the kernel"
24981 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
24984 + struct crypto_hash *tfm;
24985 + struct hash_desc desc;
24986 + struct scatterlist sg;
24987 + unsigned char temp_sum[GR_SHA_LEN];
24988 + volatile int retval = 0;
24989 + volatile int dummy = 0;
24992 + tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
24993 + if (IS_ERR(tfm)) {
24994 + /* should never happen, since sha256 should be built in */
25001 + crypto_hash_init(&desc);
25004 + sg_set_buf(&sg, p, GR_SALT_LEN);
25005 + crypto_hash_update(&desc, &sg, sg.length);
25008 + sg_set_buf(&sg, p, strlen(p));
25010 + crypto_hash_update(&desc, &sg, sg.length);
25012 + crypto_hash_final(&desc, temp_sum);
25014 + memset(entry->pw, 0, GR_PW_LEN);
25016 + for (i = 0; i < GR_SHA_LEN; i++)
25017 + if (sum[i] != temp_sum[i])
25020 + dummy = 1; // waste a cycle
25022 + crypto_free_hash(tfm);
25026 diff -urNp linux-2.6.25.10/grsecurity/Kconfig linux-2.6.25.10/grsecurity/Kconfig
25027 --- linux-2.6.25.10/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
25028 +++ linux-2.6.25.10/grsecurity/Kconfig 2008-07-03 16:53:26.000000000 -0400
25031 +# grecurity configuration
25037 + bool "Grsecurity"
25039 + select CRYPTO_SHA256
25041 + select SECURITY_CAPABILITIES
25043 + If you say Y here, you will be able to configure many features
25044 + that will enhance the security of your system. It is highly
25045 + recommended that you say Y here and read through the help
25046 + for each option so that you fully understand the features and
25047 + can evaluate their usefulness for your machine.
25050 + prompt "Security Level"
25051 + depends on GRKERNSEC
25052 + default GRKERNSEC_CUSTOM
25054 +config GRKERNSEC_LOW
25056 + select GRKERNSEC_LINK
25057 + select GRKERNSEC_FIFO
25058 + select GRKERNSEC_EXECVE
25059 + select GRKERNSEC_RANDNET
25060 + select GRKERNSEC_DMESG
25061 + select GRKERNSEC_CHROOT_CHDIR
25062 + select GRKERNSEC_MODSTOP if (MODULES)
25065 + If you choose this option, several of the grsecurity options will
25066 + be enabled that will give you greater protection against a number
25067 + of attacks, while assuring that none of your software will have any
25068 + conflicts with the additional security measures. If you run a lot
25069 + of unusual software, or you are having problems with the higher
25070 + security levels, you should say Y here. With this option, the
25071 + following features are enabled:
25073 + - Linking restrictions
25074 + - FIFO restrictions
25075 + - Enforcing RLIMIT_NPROC on execve
25076 + - Restricted dmesg
25077 + - Enforced chdir("/") on chroot
25078 + - Runtime module disabling
25080 +config GRKERNSEC_MEDIUM
25083 + select PAX_EI_PAX
25084 + select PAX_PT_PAX_FLAGS
25085 + select PAX_HAVE_ACL_FLAGS
25086 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
25087 + select GRKERNSEC_CHROOT_SYSCTL
25088 + select GRKERNSEC_LINK
25089 + select GRKERNSEC_FIFO
25090 + select GRKERNSEC_EXECVE
25091 + select GRKERNSEC_DMESG
25092 + select GRKERNSEC_RANDNET
25093 + select GRKERNSEC_FORKFAIL
25094 + select GRKERNSEC_TIME
25095 + select GRKERNSEC_SIGNAL
25096 + select GRKERNSEC_CHROOT
25097 + select GRKERNSEC_CHROOT_UNIX
25098 + select GRKERNSEC_CHROOT_MOUNT
25099 + select GRKERNSEC_CHROOT_PIVOT
25100 + select GRKERNSEC_CHROOT_DOUBLE
25101 + select GRKERNSEC_CHROOT_CHDIR
25102 + select GRKERNSEC_CHROOT_MKNOD
25103 + select GRKERNSEC_PROC
25104 + select GRKERNSEC_PROC_USERGROUP
25105 + select GRKERNSEC_MODSTOP if (MODULES)
25106 + select PAX_RANDUSTACK
25108 + select PAX_RANDMMAP
25111 + If you say Y here, several features in addition to those included
25112 + in the low additional security level will be enabled. These
25113 + features provide even more security to your system, though in rare
25114 + cases they may be incompatible with very old or poorly written
25115 + software. If you enable this option, make sure that your auth
25116 + service (identd) is running as gid 1001. With this option,
25117 + the following features (in addition to those provided in the
25118 + low additional security level) will be enabled:
25120 + - Failed fork logging
25121 + - Time change logging
25123 + - Deny mounts in chroot
25124 + - Deny double chrooting
25125 + - Deny sysctl writes in chroot
25126 + - Deny mknod in chroot
25127 + - Deny access to abstract AF_UNIX sockets out of chroot
25128 + - Deny pivot_root in chroot
25129 + - Denied writes of /dev/kmem, /dev/mem, and /dev/port
25130 + - /proc restrictions with special GID set to 10 (usually wheel)
25131 + - Address Space Layout Randomization (ASLR)
25133 +config GRKERNSEC_HIGH
25135 + select GRKERNSEC_LINK
25136 + select GRKERNSEC_FIFO
25137 + select GRKERNSEC_EXECVE
25138 + select GRKERNSEC_DMESG
25139 + select GRKERNSEC_FORKFAIL
25140 + select GRKERNSEC_TIME
25141 + select GRKERNSEC_SIGNAL
25142 + select GRKERNSEC_CHROOT_SHMAT
25143 + select GRKERNSEC_CHROOT_UNIX
25144 + select GRKERNSEC_CHROOT_MOUNT
25145 + select GRKERNSEC_CHROOT_FCHDIR
25146 + select GRKERNSEC_CHROOT_PIVOT
25147 + select GRKERNSEC_CHROOT_DOUBLE
25148 + select GRKERNSEC_CHROOT_CHDIR
25149 + select GRKERNSEC_CHROOT_MKNOD
25150 + select GRKERNSEC_CHROOT_CAPS
25151 + select GRKERNSEC_CHROOT_SYSCTL
25152 + select GRKERNSEC_CHROOT_FINDTASK
25153 + select GRKERNSEC_PROC
25154 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
25155 + select GRKERNSEC_HIDESYM
25156 + select GRKERNSEC_BRUTE
25157 + select GRKERNSEC_PROC_USERGROUP
25158 + select GRKERNSEC_KMEM
25159 + select GRKERNSEC_RESLOG
25160 + select GRKERNSEC_RANDNET
25161 + select GRKERNSEC_PROC_ADD
25162 + select GRKERNSEC_CHROOT_CHMOD
25163 + select GRKERNSEC_CHROOT_NICE
25164 + select GRKERNSEC_AUDIT_MOUNT
25165 + select GRKERNSEC_MODSTOP if (MODULES)
25167 + select PAX_RANDUSTACK
25169 + select PAX_RANDMMAP
25170 + select PAX_NOEXEC
25171 + select PAX_MPROTECT
25172 + select PAX_EI_PAX
25173 + select PAX_PT_PAX_FLAGS
25174 + select PAX_HAVE_ACL_FLAGS
25175 + select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
25176 + select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
25177 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
25178 + select PAX_SEGMEXEC if (X86 && !X86_64)
25179 + select PAX_PAGEEXEC if (!X86)
25180 + select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
25181 + select PAX_DLRESOLVE if (SPARC32 || SPARC64)
25182 + select PAX_SYSCALL if (PPC32)
25183 + select PAX_EMUTRAMP if (PARISC)
25184 + select PAX_EMUSIGRT if (PARISC)
25185 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
25187 + If you say Y here, many of the features of grsecurity will be
25188 + enabled, which will protect you against many kinds of attacks
25189 + against your system. The heightened security comes at a cost
25190 + of an increased chance of incompatibilities with rare software
25191 + on your machine. Since this security level enables PaX, you should
25192 + view <http://pax.grsecurity.net> and read about the PaX
25193 + project. While you are there, download chpax and run it on
25194 + binaries that cause problems with PaX. Also remember that
25195 + since the /proc restrictions are enabled, you must run your
25196 + identd as gid 1001. This security level enables the following
25197 + features in addition to those listed in the low and medium
25200 + - Additional /proc restrictions
25201 + - Chmod restrictions in chroot
25202 + - No signals, ptrace, or viewing of processes outside of chroot
25203 + - Capability restrictions in chroot
25204 + - Deny fchdir out of chroot
25205 + - Priority restrictions in chroot
25206 + - Segmentation-based implementation of PaX
25207 + - Mprotect restrictions
25208 + - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
25209 + - Kernel stack randomization
25210 + - Mount/unmount/remount logging
25211 + - Kernel symbol hiding
25212 + - Prevention of memory exhaustion-based exploits
25213 +config GRKERNSEC_CUSTOM
25216 + If you say Y here, you will be able to configure every grsecurity
25217 + option, which allows you to enable many more features that aren't
25218 + covered in the basic security levels. These additional features
25219 + include TPE, socket restrictions, and the sysctl system for
25220 + grsecurity. It is advised that you read through the help for
25221 + each option to determine its usefulness in your situation.
25225 +menu "Address Space Protection"
25226 +depends on GRKERNSEC
25228 +config GRKERNSEC_KMEM
25229 + bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
25231 + If you say Y here, /dev/kmem and /dev/mem won't be allowed to
25232 + be written to via mmap or otherwise to modify the running kernel.
25233 + /dev/port will also not be allowed to be opened. If you have module
25234 + support disabled, enabling this will close up four ways that are
25235 + currently used to insert malicious code into the running kernel.
25236 + Even with all these features enabled, we still highly recommend that
25237 + you use the RBAC system, as it is still possible for an attacker to
25238 + modify the running kernel through privileged I/O granted by ioperm/iopl.
25239 + If you are not using XFree86, you may be able to stop this additional
25240 + case by enabling the 'Disable privileged I/O' option. Though nothing
25241 + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
25242 + but only to video memory, which is the only writing we allow in this
25243 + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
25244 + not be allowed to mprotect it with PROT_WRITE later.
25245 + It is highly recommended that you say Y here if you meet all the
25246 + conditions above.
25248 +config GRKERNSEC_IO
25249 + bool "Disable privileged I/O"
25253 + If you say Y here, all ioperm and iopl calls will return an error.
25254 + Ioperm and iopl can be used to modify the running kernel.
25255 + Unfortunately, some programs need this access to operate properly,
25256 + the most notable of which are XFree86 and hwclock. hwclock can be
25257 + remedied by having RTC support in the kernel, so CONFIG_RTC is
25258 + enabled if this option is enabled, to ensure that hwclock operates
25259 + correctly. XFree86 still will not operate correctly with this option
25260 + enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
25261 + and you still want to protect your kernel against modification,
25262 + use the RBAC system.
25264 +config GRKERNSEC_PROC_MEMMAP
25265 + bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
25266 + depends on PAX_NOEXEC || PAX_ASLR
25268 + If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
25269 + give no information about the addresses of its mappings if
25270 + PaX features that rely on random addresses are enabled on the task.
25271 + If you use PaX it is greatly recommended that you say Y here as it
25272 + closes up a hole that makes the full ASLR useless for suid
25275 +config GRKERNSEC_BRUTE
25276 + bool "Deter exploit bruteforcing"
25278 + If you say Y here, attempts to bruteforce exploits against forking
25279 + daemons such as apache or sshd will be deterred. When a child of a
25280 + forking daemon is killed by PaX or crashes due to an illegal
25281 + instruction, the parent process will be delayed 30 seconds upon every
25282 + subsequent fork until the administrator is able to assess the
25283 + situation and restart the daemon. It is recommended that you also
25284 + enable signal logging in the auditing section so that logs are
25285 + generated when a process performs an illegal instruction.
25287 +config GRKERNSEC_MODSTOP
25288 + bool "Runtime module disabling"
25289 + depends on MODULES
25291 + If you say Y here, you will be able to disable the ability to (un)load
25292 + modules at runtime. This feature is useful if you need the ability
25293 + to load kernel modules at boot time, but do not want to allow an
25294 + attacker to load a rootkit kernel module into the system, or to remove
25295 + a loaded kernel module important to system functioning. You should
25296 + enable the /dev/mem protection feature as well, since rootkits can be
25297 + inserted into the kernel via other methods than kernel modules. Since
25298 + an untrusted module could still be loaded by modifying init scripts and
25299 + rebooting the system, it is also recommended that you enable the RBAC
25300 + system. If you enable this option, a sysctl option with name
25301 + "disable_modules" will be created. Setting this option to "1" disables
25302 + module loading. After this option is set, no further writes to it are
25303 + allowed until the system is rebooted.
25305 +config GRKERNSEC_HIDESYM
25306 + bool "Hide kernel symbols"
25308 + If you say Y here, getting information on loaded modules, and
25309 + displaying all kernel symbols through a syscall will be restricted
25310 + to users with CAP_SYS_MODULE. This option is only effective
25311 + provided the following conditions are met:
25312 + 1) The kernel using grsecurity is not precompiled by some distribution
25313 + 2) You are using the RBAC system and hiding other files such as your
25314 + kernel image and System.map
25315 + 3) You have the additional /proc restrictions enabled, which removes
25317 + If the above conditions are met, this option will aid to provide a
25318 + useful protection against local and remote kernel exploitation of
25319 + overflows and arbitrary read/write vulnerabilities.
25322 +menu "Role Based Access Control Options"
25323 +depends on GRKERNSEC
25325 +config GRKERNSEC_ACL_HIDEKERN
25326 + bool "Hide kernel processes"
25328 + If you say Y here, all kernel threads will be hidden to all
25329 + processes but those whose subject has the "view hidden processes"
25332 +config GRKERNSEC_ACL_MAXTRIES
25333 + int "Maximum tries before password lockout"
25336 + This option enforces the maximum number of times a user can attempt
25337 + to authorize themselves with the grsecurity RBAC system before being
25338 + denied the ability to attempt authorization again for a specified time.
25339 + The lower the number, the harder it will be to brute-force a password.
25341 +config GRKERNSEC_ACL_TIMEOUT
25342 + int "Time to wait after max password tries, in seconds"
25345 + This option specifies the time the user must wait after attempting to
25346 + authorize to the RBAC system with the maximum number of invalid
25347 + passwords. The higher the number, the harder it will be to brute-force
25351 +menu "Filesystem Protections"
25352 +depends on GRKERNSEC
25354 +config GRKERNSEC_PROC
25355 + bool "Proc restrictions"
25357 + If you say Y here, the permissions of the /proc filesystem
25358 + will be altered to enhance system security and privacy. You MUST
25359 + choose either a user only restriction or a user and group restriction.
25360 + Depending upon the option you choose, you can either restrict users to
25361 + see only the processes they themselves run, or choose a group that can
25362 + view all processes and files normally restricted to root if you choose
25363 + the "restrict to user only" option. NOTE: If you're running identd as
25364 + a non-root user, you will have to run it as the group you specify here.
25366 +config GRKERNSEC_PROC_USER
25367 + bool "Restrict /proc to user only"
25368 + depends on GRKERNSEC_PROC
25370 + If you say Y here, non-root users will only be able to view their own
25371 + processes, and restricts them from viewing network-related information,
25372 + and viewing kernel symbol and module information.
25374 +config GRKERNSEC_PROC_USERGROUP
25375 + bool "Allow special group"
25376 + depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
25378 + If you say Y here, you will be able to select a group that will be
25379 + able to view all processes, network-related information, and
25380 + kernel and symbol information. This option is useful if you want
25381 + to run identd as a non-root user.
25383 +config GRKERNSEC_PROC_GID
25384 + int "GID for special group"
25385 + depends on GRKERNSEC_PROC_USERGROUP
25388 +config GRKERNSEC_PROC_ADD
25389 + bool "Additional restrictions"
25390 + depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
25392 + If you say Y here, additional restrictions will be placed on
25393 + /proc that keep normal users from viewing device information and
25394 + slabinfo information that could be useful for exploits.
25396 +config GRKERNSEC_LINK
25397 + bool "Linking restrictions"
25399 + If you say Y here, /tmp race exploits will be prevented, since users
25400 + will no longer be able to follow symlinks owned by other users in
25401 + world-writable +t directories (i.e. /tmp), unless the owner of the
25402 + symlink is the owner of the directory. users will also not be
25403 + able to hardlink to files they do not own. If the sysctl option is
25404 + enabled, a sysctl option with name "linking_restrictions" is created.
25406 +config GRKERNSEC_FIFO
25407 + bool "FIFO restrictions"
25409 + If you say Y here, users will not be able to write to FIFOs they don't
25410 + own in world-writable +t directories (i.e. /tmp), unless the owner of
25411 + the FIFO is the same owner of the directory it's held in. If the sysctl
25412 + option is enabled, a sysctl option with name "fifo_restrictions" is
25415 +config GRKERNSEC_CHROOT
25416 + bool "Chroot jail restrictions"
25418 + If you say Y here, you will be able to choose several options that will
25419 + make breaking out of a chrooted jail much more difficult. If you
25420 + encounter no software incompatibilities with the following options, it
25421 + is recommended that you enable each one.
25423 +config GRKERNSEC_CHROOT_MOUNT
25424 + bool "Deny mounts"
25425 + depends on GRKERNSEC_CHROOT
25427 + If you say Y here, processes inside a chroot will not be able to
25428 + mount or remount filesystems. If the sysctl option is enabled, a
25429 + sysctl option with name "chroot_deny_mount" is created.
25431 +config GRKERNSEC_CHROOT_DOUBLE
25432 + bool "Deny double-chroots"
25433 + depends on GRKERNSEC_CHROOT
25435 + If you say Y here, processes inside a chroot will not be able to chroot
25436 + again outside the chroot. This is a widely used method of breaking
25437 + out of a chroot jail and should not be allowed. If the sysctl
25438 + option is enabled, a sysctl option with name
25439 + "chroot_deny_chroot" is created.
25441 +config GRKERNSEC_CHROOT_PIVOT
25442 + bool "Deny pivot_root in chroot"
25443 + depends on GRKERNSEC_CHROOT
25445 + If you say Y here, processes inside a chroot will not be able to use
25446 + a function called pivot_root() that was introduced in Linux 2.3.41. It
25447 + works similar to chroot in that it changes the root filesystem. This
25448 + function could be misused in a chrooted process to attempt to break out
25449 + of the chroot, and therefore should not be allowed. If the sysctl
25450 + option is enabled, a sysctl option with name "chroot_deny_pivot" is
25453 +config GRKERNSEC_CHROOT_CHDIR
25454 + bool "Enforce chdir(\"/\") on all chroots"
25455 + depends on GRKERNSEC_CHROOT
25457 + If you say Y here, the current working directory of all newly-chrooted
25458 + applications will be set to the the root directory of the chroot.
25459 + The man page on chroot(2) states:
25460 + Note that this call does not change the current working
25461 + directory, so that `.' can be outside the tree rooted at
25462 + `/'. In particular, the super-user can escape from a
25463 + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
25465 + It is recommended that you say Y here, since it's not known to break
25466 + any software. If the sysctl option is enabled, a sysctl option with
25467 + name "chroot_enforce_chdir" is created.
25469 +config GRKERNSEC_CHROOT_CHMOD
25470 + bool "Deny (f)chmod +s"
25471 + depends on GRKERNSEC_CHROOT
25473 + If you say Y here, processes inside a chroot will not be able to chmod
25474 + or fchmod files to make them have suid or sgid bits. This protects
25475 + against another published method of breaking a chroot. If the sysctl
25476 + option is enabled, a sysctl option with name "chroot_deny_chmod" is
25479 +config GRKERNSEC_CHROOT_FCHDIR
25480 + bool "Deny fchdir out of chroot"
25481 + depends on GRKERNSEC_CHROOT
25483 + If you say Y here, a well-known method of breaking chroots by fchdir'ing
25484 + to a file descriptor of the chrooting process that points to a directory
25485 + outside the filesystem will be stopped. If the sysctl option
25486 + is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
25488 +config GRKERNSEC_CHROOT_MKNOD
25489 + bool "Deny mknod"
25490 + depends on GRKERNSEC_CHROOT
25492 + If you say Y here, processes inside a chroot will not be allowed to
25493 + mknod. The problem with using mknod inside a chroot is that it
25494 + would allow an attacker to create a device entry that is the same
25495 + as one on the physical root of your system, which could range from
25496 + anything from the console device to a device for your harddrive (which
25497 + they could then use to wipe the drive or steal data). It is recommended
25498 + that you say Y here, unless you run into software incompatibilities.
25499 + If the sysctl option is enabled, a sysctl option with name
25500 + "chroot_deny_mknod" is created.
25502 +config GRKERNSEC_CHROOT_SHMAT
25503 + bool "Deny shmat() out of chroot"
25504 + depends on GRKERNSEC_CHROOT
25506 + If you say Y here, processes inside a chroot will not be able to attach
25507 + to shared memory segments that were created outside of the chroot jail.
25508 + It is recommended that you say Y here. If the sysctl option is enabled,
25509 + a sysctl option with name "chroot_deny_shmat" is created.
25511 +config GRKERNSEC_CHROOT_UNIX
25512 + bool "Deny access to abstract AF_UNIX sockets out of chroot"
25513 + depends on GRKERNSEC_CHROOT
25515 + If you say Y here, processes inside a chroot will not be able to
25516 + connect to abstract (meaning not belonging to a filesystem) Unix
25517 + domain sockets that were bound outside of a chroot. It is recommended
25518 + that you say Y here. If the sysctl option is enabled, a sysctl option
25519 + with name "chroot_deny_unix" is created.
25521 +config GRKERNSEC_CHROOT_FINDTASK
25522 + bool "Protect outside processes"
25523 + depends on GRKERNSEC_CHROOT
25525 + If you say Y here, processes inside a chroot will not be able to
25526 + kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
25527 + or view any process outside of the chroot. If the sysctl
25528 + option is enabled, a sysctl option with name "chroot_findtask" is
25531 +config GRKERNSEC_CHROOT_NICE
25532 + bool "Restrict priority changes"
25533 + depends on GRKERNSEC_CHROOT
25535 + If you say Y here, processes inside a chroot will not be able to raise
25536 + the priority of processes in the chroot, or alter the priority of
25537 + processes outside the chroot. This provides more security than simply
25538 + removing CAP_SYS_NICE from the process' capability set. If the
25539 + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
25542 +config GRKERNSEC_CHROOT_SYSCTL
25543 + bool "Deny sysctl writes"
25544 + depends on GRKERNSEC_CHROOT
25546 + If you say Y here, an attacker in a chroot will not be able to
25547 + write to sysctl entries, either by sysctl(2) or through a /proc
25548 + interface. It is strongly recommended that you say Y here. If the
25549 + sysctl option is enabled, a sysctl option with name
25550 + "chroot_deny_sysctl" is created.
25552 +config GRKERNSEC_CHROOT_CAPS
25553 + bool "Capability restrictions"
25554 + depends on GRKERNSEC_CHROOT
25556 + If you say Y here, the capabilities on all root processes within a
25557 + chroot jail will be lowered to stop module insertion, raw i/o,
25558 + system and net admin tasks, rebooting the system, modifying immutable
25559 + files, modifying IPC owned by another, and changing the system time.
25560 + This is left an option because it can break some apps. Disable this
25561 + if your chrooted apps are having problems performing those kinds of
25562 + tasks. If the sysctl option is enabled, a sysctl option with
25563 + name "chroot_caps" is created.
25566 +menu "Kernel Auditing"
25567 +depends on GRKERNSEC
25569 +config GRKERNSEC_AUDIT_GROUP
25570 + bool "Single group for auditing"
25572 + If you say Y here, the exec, chdir, (un)mount, and ipc logging features
25573 + will only operate on a group you specify. This option is recommended
25574 + if you only want to watch certain users instead of having a large
25575 + amount of logs from the entire system. If the sysctl option is enabled,
25576 + a sysctl option with name "audit_group" is created.
25578 +config GRKERNSEC_AUDIT_GID
25579 + int "GID for auditing"
25580 + depends on GRKERNSEC_AUDIT_GROUP
25583 +config GRKERNSEC_EXECLOG
25584 + bool "Exec logging"
25586 + If you say Y here, all execve() calls will be logged (since the
25587 + other exec*() calls are frontends to execve(), all execution
25588 + will be logged). Useful for shell-servers that like to keep track
25589 + of their users. If the sysctl option is enabled, a sysctl option with
25590 + name "exec_logging" is created.
25591 + WARNING: This option when enabled will produce a LOT of logs, especially
25592 + on an active system.
25594 +config GRKERNSEC_RESLOG
25595 + bool "Resource logging"
25597 + If you say Y here, all attempts to overstep resource limits will
25598 + be logged with the resource name, the requested size, and the current
25599 + limit. It is highly recommended that you say Y here. If the sysctl
25600 + option is enabled, a sysctl option with name "resource_logging" is
25601 + created. If the RBAC system is enabled, the sysctl value is ignored.
25603 +config GRKERNSEC_CHROOT_EXECLOG
25604 + bool "Log execs within chroot"
25606 + If you say Y here, all executions inside a chroot jail will be logged
25607 + to syslog. This can cause a large amount of logs if certain
25608 + applications (eg. djb's daemontools) are installed on the system, and
25609 + is therefore left as an option. If the sysctl option is enabled, a
25610 + sysctl option with name "chroot_execlog" is created.
25612 +config GRKERNSEC_AUDIT_CHDIR
25613 + bool "Chdir logging"
25615 + If you say Y here, all chdir() calls will be logged. If the sysctl
25616 + option is enabled, a sysctl option with name "audit_chdir" is created.
25618 +config GRKERNSEC_AUDIT_MOUNT
25619 + bool "(Un)Mount logging"
25621 + If you say Y here, all mounts and unmounts will be logged. If the
25622 + sysctl option is enabled, a sysctl option with name "audit_mount" is
25625 +config GRKERNSEC_AUDIT_IPC
25626 + bool "IPC logging"
25628 + If you say Y here, creation and removal of message queues, semaphores,
25629 + and shared memory will be logged. If the sysctl option is enabled, a
25630 + sysctl option with name "audit_ipc" is created.
25632 +config GRKERNSEC_SIGNAL
25633 + bool "Signal logging"
25635 + If you say Y here, certain important signals will be logged, such as
25636 + SIGSEGV, which will as a result inform you of when a error in a program
25637 + occurred, which in some cases could mean a possible exploit attempt.
25638 + If the sysctl option is enabled, a sysctl option with name
25639 + "signal_logging" is created.
25641 +config GRKERNSEC_FORKFAIL
25642 + bool "Fork failure logging"
25644 + If you say Y here, all failed fork() attempts will be logged.
25645 + This could suggest a fork bomb, or someone attempting to overstep
25646 + their process limit. If the sysctl option is enabled, a sysctl option
25647 + with name "forkfail_logging" is created.
25649 +config GRKERNSEC_TIME
25650 + bool "Time change logging"
25652 + If you say Y here, any changes of the system clock will be logged.
25653 + If the sysctl option is enabled, a sysctl option with name
25654 + "timechange_logging" is created.
25656 +config GRKERNSEC_PROC_IPADDR
25657 + bool "/proc/<pid>/ipaddr support"
25659 + If you say Y here, a new entry will be added to each /proc/<pid>
25660 + directory that contains the IP address of the person using the task.
25661 + The IP is carried across local TCP and AF_UNIX stream sockets.
25662 + This information can be useful for IDS/IPSes to perform remote response
25663 + to a local attack. The entry is readable by only the owner of the
25664 + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
25665 + the RBAC system), and thus does not create privacy concerns.
25667 +config GRKERNSEC_AUDIT_TEXTREL
25668 + bool 'ELF text relocations logging (READ HELP)'
25669 + depends on PAX_MPROTECT
25671 + If you say Y here, text relocations will be logged with the filename
25672 + of the offending library or binary. The purpose of the feature is
25673 + to help Linux distribution developers get rid of libraries and
25674 + binaries that need text relocations which hinder the future progress
25675 + of PaX. Only Linux distribution developers should say Y here, and
25676 + never on a production machine, as this option creates an information
25677 + leak that could aid an attacker in defeating the randomization of
25678 + a single memory region. If the sysctl option is enabled, a sysctl
25679 + option with name "audit_textrel" is created.
25683 +menu "Executable Protections"
25684 +depends on GRKERNSEC
25686 +config GRKERNSEC_EXECVE
25687 + bool "Enforce RLIMIT_NPROC on execs"
25689 + If you say Y here, users with a resource limit on processes will
25690 + have the value checked during execve() calls. The current system
25691 + only checks the system limit during fork() calls. If the sysctl option
25692 + is enabled, a sysctl option with name "execve_limiting" is created.
25694 +config GRKERNSEC_DMESG
25695 + bool "Dmesg(8) restriction"
25697 + If you say Y here, non-root users will not be able to use dmesg(8)
25698 + to view up to the last 4kb of messages in the kernel's log buffer.
25699 + If the sysctl option is enabled, a sysctl option with name "dmesg" is
25702 +config GRKERNSEC_TPE
25703 + bool "Trusted Path Execution (TPE)"
25705 + If you say Y here, you will be able to choose a gid to add to the
25706 + supplementary groups of users you want to mark as "untrusted."
25707 + These users will not be able to execute any files that are not in
25708 + root-owned directories writable only by root. If the sysctl option
25709 + is enabled, a sysctl option with name "tpe" is created.
25711 +config GRKERNSEC_TPE_ALL
25712 + bool "Partially restrict non-root users"
25713 + depends on GRKERNSEC_TPE
25715 + If you say Y here, All non-root users other than the ones in the
25716 + group specified in the main TPE option will only be allowed to
25717 + execute files in directories they own that are not group or
25718 + world-writable, or in directories owned by root and writable only by
25719 + root. If the sysctl option is enabled, a sysctl option with name
25720 + "tpe_restrict_all" is created.
25722 +config GRKERNSEC_TPE_INVERT
25723 + bool "Invert GID option"
25724 + depends on GRKERNSEC_TPE
25726 + If you say Y here, the group you specify in the TPE configuration will
25727 + decide what group TPE restrictions will be *disabled* for. This
25728 + option is useful if you want TPE restrictions to be applied to most
25729 + users on the system.
25731 +config GRKERNSEC_TPE_GID
25732 + int "GID for untrusted users"
25733 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
25736 + If you have selected the "Invert GID option" above, setting this
25737 + GID determines what group TPE restrictions will be *disabled* for.
25738 + If you have not selected the "Invert GID option" above, setting this
25739 + GID determines what group TPE restrictions will be *enabled* for.
25740 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
25743 +config GRKERNSEC_TPE_GID
25744 + int "GID for trusted users"
25745 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
25748 + If you have selected the "Invert GID option" above, setting this
25749 + GID determines what group TPE restrictions will be *disabled* for.
25750 + If you have not selected the "Invert GID option" above, setting this
25751 + GID determines what group TPE restrictions will be *enabled* for.
25752 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
25756 +menu "Network Protections"
25757 +depends on GRKERNSEC
25759 +config GRKERNSEC_RANDNET
25760 + bool "Larger entropy pools"
25762 + If you say Y here, the entropy pools used for many features of Linux
25763 + and grsecurity will be doubled in size. Since several grsecurity
25764 + features use additional randomness, it is recommended that you say Y
25765 + here. Saying Y here has a similar effect as modifying
25766 + /proc/sys/kernel/random/poolsize.
25768 +config GRKERNSEC_SOCKET
25769 + bool "Socket restrictions"
25771 + If you say Y here, you will be able to choose from several options.
25772 + If you assign a GID on your system and add it to the supplementary
25773 + groups of users you want to restrict socket access to, this patch
25774 + will perform up to three things, based on the option(s) you choose.
25776 +config GRKERNSEC_SOCKET_ALL
25777 + bool "Deny any sockets to group"
25778 + depends on GRKERNSEC_SOCKET
25780 + If you say Y here, you will be able to choose a GID of whose users will
25781 + be unable to connect to other hosts from your machine or run server
25782 + applications from your machine. If the sysctl option is enabled, a
25783 + sysctl option with name "socket_all" is created.
25785 +config GRKERNSEC_SOCKET_ALL_GID
25786 + int "GID to deny all sockets for"
25787 + depends on GRKERNSEC_SOCKET_ALL
25790 + Here you can choose the GID to disable socket access for. Remember to
25791 + add the users you want socket access disabled for to the GID
25792 + specified here. If the sysctl option is enabled, a sysctl option
25793 + with name "socket_all_gid" is created.
25795 +config GRKERNSEC_SOCKET_CLIENT
25796 + bool "Deny client sockets to group"
25797 + depends on GRKERNSEC_SOCKET
25799 + If you say Y here, you will be able to choose a GID of whose users will
25800 + be unable to connect to other hosts from your machine, but will be
25801 + able to run servers. If this option is enabled, all users in the group
25802 + you specify will have to use passive mode when initiating ftp transfers
25803 + from the shell on your machine. If the sysctl option is enabled, a
25804 + sysctl option with name "socket_client" is created.
25806 +config GRKERNSEC_SOCKET_CLIENT_GID
25807 + int "GID to deny client sockets for"
25808 + depends on GRKERNSEC_SOCKET_CLIENT
25811 + Here you can choose the GID to disable client socket access for.
25812 + Remember to add the users you want client socket access disabled for to
25813 + the GID specified here. If the sysctl option is enabled, a sysctl
25814 + option with name "socket_client_gid" is created.
25816 +config GRKERNSEC_SOCKET_SERVER
25817 + bool "Deny server sockets to group"
25818 + depends on GRKERNSEC_SOCKET
25820 + If you say Y here, you will be able to choose a GID of whose users will
25821 + be unable to run server applications from your machine. If the sysctl
25822 + option is enabled, a sysctl option with name "socket_server" is created.
25824 +config GRKERNSEC_SOCKET_SERVER_GID
25825 + int "GID to deny server sockets for"
25826 + depends on GRKERNSEC_SOCKET_SERVER
25829 + Here you can choose the GID to disable server socket access for.
25830 + Remember to add the users you want server socket access disabled for to
25831 + the GID specified here. If the sysctl option is enabled, a sysctl
25832 + option with name "socket_server_gid" is created.
25835 +menu "Sysctl support"
25836 +depends on GRKERNSEC && SYSCTL
25838 +config GRKERNSEC_SYSCTL
25839 + bool "Sysctl support"
25841 + If you say Y here, you will be able to change the options that
25842 + grsecurity runs with at bootup, without having to recompile your
25843 + kernel. You can echo values to files in /proc/sys/kernel/grsecurity
25844 + to enable (1) or disable (0) various features. All the sysctl entries
25845 + are mutable until the "grsec_lock" entry is set to a non-zero value.
25846 + All features enabled in the kernel configuration are disabled at boot
25847 + if you do not say Y to the "Turn on features by default" option.
25848 + All options should be set at startup, and the grsec_lock entry should
25849 + be set to a non-zero value after all the options are set.
25850 + *THIS IS EXTREMELY IMPORTANT*
25852 +config GRKERNSEC_SYSCTL_ON
25853 + bool "Turn on features by default"
25854 + depends on GRKERNSEC_SYSCTL
25856 + If you say Y here, instead of having all features enabled in the
25857 + kernel configuration disabled at boot time, the features will be
25858 + enabled at boot time. It is recommended you say Y here unless
25859 + there is some reason you would want all sysctl-tunable features to
25860 + be disabled by default. As mentioned elsewhere, it is important
25861 + to enable the grsec_lock entry once you have finished modifying
25862 + the sysctl entries.
25865 +menu "Logging Options"
25866 +depends on GRKERNSEC
25868 +config GRKERNSEC_FLOODTIME
25869 + int "Seconds in between log messages (minimum)"
25872 + This option allows you to enforce the number of seconds between
25873 + grsecurity log messages. The default should be suitable for most
25874 + people, however, if you choose to change it, choose a value small enough
25875 + to allow informative logs to be produced, but large enough to
25876 + prevent flooding.
25878 +config GRKERNSEC_FLOODBURST
25879 + int "Number of messages in a burst (maximum)"
25882 + This option allows you to choose the maximum number of messages allowed
25883 + within the flood time interval you chose in a separate option. The
25884 + default should be suitable for most people, however if you find that
25885 + many of your logs are being interpreted as flooding, you may want to
25886 + raise this value.
25891 diff -urNp linux-2.6.25.10/grsecurity/Makefile linux-2.6.25.10/grsecurity/Makefile
25892 --- linux-2.6.25.10/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
25893 +++ linux-2.6.25.10/grsecurity/Makefile 2008-07-03 16:53:26.000000000 -0400
25895 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
25896 +# during 2001-2005 it has been completely redesigned by Brad Spengler
25897 +# into an RBAC system
25899 +# All code in this directory and various hooks inserted throughout the kernel
25900 +# are copyright Brad Spengler, and released under the GPL v2 or higher
25902 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
25903 + grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
25904 + grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
25906 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
25907 + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
25908 + gracl_learn.o grsec_log.o
25909 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
25911 +ifndef CONFIG_GRKERNSEC
25912 +obj-y += grsec_disabled.o
25915 diff -urNp linux-2.6.25.10/include/asm-alpha/elf.h linux-2.6.25.10/include/asm-alpha/elf.h
25916 --- linux-2.6.25.10/include/asm-alpha/elf.h 2008-07-02 23:46:47.000000000 -0400
25917 +++ linux-2.6.25.10/include/asm-alpha/elf.h 2008-07-03 16:53:26.000000000 -0400
25918 @@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
25920 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
25922 +#ifdef CONFIG_PAX_ASLR
25923 +#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
25925 +#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
25926 +#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
25929 /* $0 is set by ld.so to a pointer to a function which might be
25930 registered using atexit. This provides a mean for the dynamic
25931 linker to call DT_FINI functions for shared libraries that have
25932 diff -urNp linux-2.6.25.10/include/asm-alpha/kmap_types.h linux-2.6.25.10/include/asm-alpha/kmap_types.h
25933 --- linux-2.6.25.10/include/asm-alpha/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
25934 +++ linux-2.6.25.10/include/asm-alpha/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
25935 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
25940 +D(13) KM_CLEARPAGE,
25945 diff -urNp linux-2.6.25.10/include/asm-alpha/pgtable.h linux-2.6.25.10/include/asm-alpha/pgtable.h
25946 --- linux-2.6.25.10/include/asm-alpha/pgtable.h 2008-07-02 23:46:47.000000000 -0400
25947 +++ linux-2.6.25.10/include/asm-alpha/pgtable.h 2008-07-03 16:53:26.000000000 -0400
25948 @@ -101,6 +101,17 @@ struct vm_area_struct;
25949 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
25950 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
25951 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
25953 +#ifdef CONFIG_PAX_PAGEEXEC
25954 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
25955 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
25956 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
25958 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
25959 +# define PAGE_COPY_NOEXEC PAGE_COPY
25960 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
25963 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
25965 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
25966 diff -urNp linux-2.6.25.10/include/asm-arm/elf.h linux-2.6.25.10/include/asm-arm/elf.h
25967 --- linux-2.6.25.10/include/asm-arm/elf.h 2008-07-02 23:46:47.000000000 -0400
25968 +++ linux-2.6.25.10/include/asm-arm/elf.h 2008-07-03 16:53:26.000000000 -0400
25969 @@ -87,7 +87,14 @@ extern char elf_platform[];
25970 the loader. We need to make sure that it is out of the way of the program
25971 that it will "exec", and that there is sufficient room for the brk. */
25973 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
25974 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
25976 +#ifdef CONFIG_PAX_ASLR
25977 +#define PAX_ELF_ET_DYN_BASE 0x00008000UL
25979 +#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
25980 +#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
25983 /* When the program starts, a1 contains a pointer to a function to be
25984 registered with atexit, as per the SVR4 ABI. A value of 0 means we
25985 diff -urNp linux-2.6.25.10/include/asm-arm/kmap_types.h linux-2.6.25.10/include/asm-arm/kmap_types.h
25986 --- linux-2.6.25.10/include/asm-arm/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
25987 +++ linux-2.6.25.10/include/asm-arm/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
25988 @@ -18,6 +18,7 @@ enum km_type {
25996 diff -urNp linux-2.6.25.10/include/asm-avr32/elf.h linux-2.6.25.10/include/asm-avr32/elf.h
25997 --- linux-2.6.25.10/include/asm-avr32/elf.h 2008-07-02 23:46:47.000000000 -0400
25998 +++ linux-2.6.25.10/include/asm-avr32/elf.h 2008-07-03 16:53:26.000000000 -0400
25999 @@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
26000 the loader. We need to make sure that it is out of the way of the program
26001 that it will "exec", and that there is sufficient room for the brk. */
26003 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
26004 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
26006 +#ifdef CONFIG_PAX_ASLR
26007 +#define PAX_ELF_ET_DYN_BASE 0x00001000UL
26009 +#define PAX_DELTA_MMAP_LEN 15
26010 +#define PAX_DELTA_STACK_LEN 15
26013 /* This yields a mask that user programs can use to figure out what
26014 instruction set this CPU supports. This could be done in user space,
26015 diff -urNp linux-2.6.25.10/include/asm-avr32/kmap_types.h linux-2.6.25.10/include/asm-avr32/kmap_types.h
26016 --- linux-2.6.25.10/include/asm-avr32/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26017 +++ linux-2.6.25.10/include/asm-avr32/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26018 @@ -22,7 +22,8 @@ D(10) KM_IRQ0,
26023 +D(14) KM_CLEARPAGE,
26028 diff -urNp linux-2.6.25.10/include/asm-blackfin/kmap_types.h linux-2.6.25.10/include/asm-blackfin/kmap_types.h
26029 --- linux-2.6.25.10/include/asm-blackfin/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26030 +++ linux-2.6.25.10/include/asm-blackfin/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26031 @@ -15,6 +15,7 @@ enum km_type {
26039 diff -urNp linux-2.6.25.10/include/asm-cris/kmap_types.h linux-2.6.25.10/include/asm-cris/kmap_types.h
26040 --- linux-2.6.25.10/include/asm-cris/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26041 +++ linux-2.6.25.10/include/asm-cris/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26042 @@ -19,6 +19,7 @@ enum km_type {
26050 diff -urNp linux-2.6.25.10/include/asm-frv/kmap_types.h linux-2.6.25.10/include/asm-frv/kmap_types.h
26051 --- linux-2.6.25.10/include/asm-frv/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26052 +++ linux-2.6.25.10/include/asm-frv/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26053 @@ -23,6 +23,7 @@ enum km_type {
26061 diff -urNp linux-2.6.25.10/include/asm-generic/futex.h linux-2.6.25.10/include/asm-generic/futex.h
26062 --- linux-2.6.25.10/include/asm-generic/futex.h 2008-07-02 23:46:47.000000000 -0400
26063 +++ linux-2.6.25.10/include/asm-generic/futex.h 2008-07-03 16:53:26.000000000 -0400
26065 #include <asm/uaccess.h>
26068 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
26069 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
26071 int op = (encoded_op >> 28) & 7;
26072 int cmp = (encoded_op >> 24) & 15;
26073 @@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op,
26077 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
26078 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
26082 diff -urNp linux-2.6.25.10/include/asm-generic/vmlinux.lds.h linux-2.6.25.10/include/asm-generic/vmlinux.lds.h
26083 --- linux-2.6.25.10/include/asm-generic/vmlinux.lds.h 2008-07-02 23:46:47.000000000 -0400
26084 +++ linux-2.6.25.10/include/asm-generic/vmlinux.lds.h 2008-07-03 16:53:26.000000000 -0400
26086 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
26087 VMLINUX_SYMBOL(__start_rodata) = .; \
26088 *(.rodata) *(.rodata.*) \
26089 + *(.data.read_only) \
26090 *(__vermagic) /* Kernel version magic */ \
26091 *(__markers_strings) /* Markers: strings */ \
26093 diff -urNp linux-2.6.25.10/include/asm-h8300/kmap_types.h linux-2.6.25.10/include/asm-h8300/kmap_types.h
26094 --- linux-2.6.25.10/include/asm-h8300/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26095 +++ linux-2.6.25.10/include/asm-h8300/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26096 @@ -15,6 +15,7 @@ enum km_type {
26104 diff -urNp linux-2.6.25.10/include/asm-ia64/elf.h linux-2.6.25.10/include/asm-ia64/elf.h
26105 --- linux-2.6.25.10/include/asm-ia64/elf.h 2008-07-02 23:46:47.000000000 -0400
26106 +++ linux-2.6.25.10/include/asm-ia64/elf.h 2008-07-03 16:53:26.000000000 -0400
26107 @@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
26108 typedef struct ia64_fpreg elf_fpreg_t;
26109 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
26111 +#ifdef CONFIG_PAX_ASLR
26112 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
26114 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
26115 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
26118 struct pt_regs; /* forward declaration... */
26119 extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
26120 diff -urNp linux-2.6.25.10/include/asm-ia64/kmap_types.h linux-2.6.25.10/include/asm-ia64/kmap_types.h
26121 --- linux-2.6.25.10/include/asm-ia64/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26122 +++ linux-2.6.25.10/include/asm-ia64/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26123 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26128 +D(13) KM_CLEARPAGE,
26133 diff -urNp linux-2.6.25.10/include/asm-ia64/pgtable.h linux-2.6.25.10/include/asm-ia64/pgtable.h
26134 --- linux-2.6.25.10/include/asm-ia64/pgtable.h 2008-07-02 23:46:47.000000000 -0400
26135 +++ linux-2.6.25.10/include/asm-ia64/pgtable.h 2008-07-03 16:53:26.000000000 -0400
26136 @@ -143,6 +143,17 @@
26137 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
26138 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
26139 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
26141 +#ifdef CONFIG_PAX_PAGEEXEC
26142 +# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
26143 +# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
26144 +# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
26146 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
26147 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
26148 +# define PAGE_COPY_NOEXEC PAGE_COPY
26151 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
26152 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
26153 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
26154 diff -urNp linux-2.6.25.10/include/asm-m32r/kmap_types.h linux-2.6.25.10/include/asm-m32r/kmap_types.h
26155 --- linux-2.6.25.10/include/asm-m32r/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26156 +++ linux-2.6.25.10/include/asm-m32r/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26157 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
26162 +D(13) KM_CLEARPAGE,
26167 diff -urNp linux-2.6.25.10/include/asm-m68k/kmap_types.h linux-2.6.25.10/include/asm-m68k/kmap_types.h
26168 --- linux-2.6.25.10/include/asm-m68k/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26169 +++ linux-2.6.25.10/include/asm-m68k/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26170 @@ -15,6 +15,7 @@ enum km_type {
26178 diff -urNp linux-2.6.25.10/include/asm-m68knommu/kmap_types.h linux-2.6.25.10/include/asm-m68knommu/kmap_types.h
26179 --- linux-2.6.25.10/include/asm-m68knommu/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26180 +++ linux-2.6.25.10/include/asm-m68knommu/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26181 @@ -15,6 +15,7 @@ enum km_type {
26189 diff -urNp linux-2.6.25.10/include/asm-mips/elf.h linux-2.6.25.10/include/asm-mips/elf.h
26190 --- linux-2.6.25.10/include/asm-mips/elf.h 2008-07-02 23:46:47.000000000 -0400
26191 +++ linux-2.6.25.10/include/asm-mips/elf.h 2008-07-03 16:53:26.000000000 -0400
26192 @@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
26193 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
26196 +#ifdef CONFIG_PAX_ASLR
26197 +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
26199 +#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26200 +#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26203 #endif /* _ASM_ELF_H */
26204 diff -urNp linux-2.6.25.10/include/asm-mips/kmap_types.h linux-2.6.25.10/include/asm-mips/kmap_types.h
26205 --- linux-2.6.25.10/include/asm-mips/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26206 +++ linux-2.6.25.10/include/asm-mips/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26207 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26212 +D(13) KM_CLEARPAGE,
26217 diff -urNp linux-2.6.25.10/include/asm-mips/page.h linux-2.6.25.10/include/asm-mips/page.h
26218 --- linux-2.6.25.10/include/asm-mips/page.h 2008-07-02 23:46:47.000000000 -0400
26219 +++ linux-2.6.25.10/include/asm-mips/page.h 2008-07-03 16:53:26.000000000 -0400
26220 @@ -79,7 +79,7 @@ extern void copy_user_highpage(struct pa
26221 #ifdef CONFIG_CPU_MIPS32
26222 typedef struct { unsigned long pte_low, pte_high; } pte_t;
26223 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
26224 - #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
26225 + #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
26227 typedef struct { unsigned long long pte; } pte_t;
26228 #define pte_val(x) ((x).pte)
26229 diff -urNp linux-2.6.25.10/include/asm-mips/system.h linux-2.6.25.10/include/asm-mips/system.h
26230 --- linux-2.6.25.10/include/asm-mips/system.h 2008-07-02 23:46:47.000000000 -0400
26231 +++ linux-2.6.25.10/include/asm-mips/system.h 2008-07-03 16:53:26.000000000 -0400
26232 @@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
26234 #define __ARCH_WANT_UNLOCKED_CTXSW
26236 -extern unsigned long arch_align_stack(unsigned long sp);
26237 +#define arch_align_stack(x) (x)
26239 #endif /* _ASM_SYSTEM_H */
26240 diff -urNp linux-2.6.25.10/include/asm-parisc/elf.h linux-2.6.25.10/include/asm-parisc/elf.h
26241 --- linux-2.6.25.10/include/asm-parisc/elf.h 2008-07-02 23:46:47.000000000 -0400
26242 +++ linux-2.6.25.10/include/asm-parisc/elf.h 2008-07-03 16:53:26.000000000 -0400
26243 @@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
26245 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
26247 +#ifdef CONFIG_PAX_ASLR
26248 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
26250 +#define PAX_DELTA_MMAP_LEN 16
26251 +#define PAX_DELTA_STACK_LEN 16
26254 /* This yields a mask that user programs can use to figure out what
26255 instruction set this CPU supports. This could be done in user space,
26256 but it's not easy, and we've already done it here. */
26257 diff -urNp linux-2.6.25.10/include/asm-parisc/kmap_types.h linux-2.6.25.10/include/asm-parisc/kmap_types.h
26258 --- linux-2.6.25.10/include/asm-parisc/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26259 +++ linux-2.6.25.10/include/asm-parisc/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26260 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26265 +D(13) KM_CLEARPAGE,
26270 diff -urNp linux-2.6.25.10/include/asm-parisc/pgtable.h linux-2.6.25.10/include/asm-parisc/pgtable.h
26271 --- linux-2.6.25.10/include/asm-parisc/pgtable.h 2008-07-02 23:46:47.000000000 -0400
26272 +++ linux-2.6.25.10/include/asm-parisc/pgtable.h 2008-07-03 16:53:26.000000000 -0400
26273 @@ -202,6 +202,17 @@
26274 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
26275 #define PAGE_COPY PAGE_EXECREAD
26276 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
26278 +#ifdef CONFIG_PAX_PAGEEXEC
26279 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
26280 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26281 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26283 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
26284 +# define PAGE_COPY_NOEXEC PAGE_COPY
26285 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
26288 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
26289 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
26290 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
26291 diff -urNp linux-2.6.25.10/include/asm-powerpc/elf.h linux-2.6.25.10/include/asm-powerpc/elf.h
26292 --- linux-2.6.25.10/include/asm-powerpc/elf.h 2008-07-02 23:46:47.000000000 -0400
26293 +++ linux-2.6.25.10/include/asm-powerpc/elf.h 2008-07-03 16:53:26.000000000 -0400
26294 @@ -160,6 +160,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
26295 typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
26298 +#ifdef CONFIG_PAX_ASLR
26299 +#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
26301 +#ifdef __powerpc64__
26302 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
26303 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
26305 +#define PAX_DELTA_MMAP_LEN 15
26306 +#define PAX_DELTA_STACK_LEN 15
26312 * This is used to ensure we don't load something for the wrong architecture.
26313 diff -urNp linux-2.6.25.10/include/asm-powerpc/kmap_types.h linux-2.6.25.10/include/asm-powerpc/kmap_types.h
26314 --- linux-2.6.25.10/include/asm-powerpc/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26315 +++ linux-2.6.25.10/include/asm-powerpc/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26316 @@ -26,6 +26,7 @@ enum km_type {
26319 KM_PPC_SYNC_ICACHE,
26324 diff -urNp linux-2.6.25.10/include/asm-powerpc/page_64.h linux-2.6.25.10/include/asm-powerpc/page_64.h
26325 --- linux-2.6.25.10/include/asm-powerpc/page_64.h 2008-07-02 23:46:47.000000000 -0400
26326 +++ linux-2.6.25.10/include/asm-powerpc/page_64.h 2008-07-03 16:53:26.000000000 -0400
26327 @@ -170,15 +170,18 @@ do { \
26328 * stack by default, so in the absense of a PT_GNU_STACK program header
26329 * we turn execute permission off.
26331 -#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
26332 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26333 +#define VM_STACK_DEFAULT_FLAGS32 \
26334 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
26335 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26337 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
26338 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26340 +#ifndef CONFIG_PAX_PAGEEXEC
26341 #define VM_STACK_DEFAULT_FLAGS \
26342 (test_thread_flag(TIF_32BIT) ? \
26343 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
26346 #include <asm-generic/page.h>
26348 diff -urNp linux-2.6.25.10/include/asm-powerpc/page.h linux-2.6.25.10/include/asm-powerpc/page.h
26349 --- linux-2.6.25.10/include/asm-powerpc/page.h 2008-07-02 23:46:47.000000000 -0400
26350 +++ linux-2.6.25.10/include/asm-powerpc/page.h 2008-07-03 16:53:26.000000000 -0400
26352 * and needs to be executable. This means the whole heap ends
26353 * up being executable.
26355 -#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
26356 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26357 +#define VM_DATA_DEFAULT_FLAGS32 \
26358 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
26359 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26361 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
26362 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26363 diff -urNp linux-2.6.25.10/include/asm-ppc/mmu_context.h linux-2.6.25.10/include/asm-ppc/mmu_context.h
26364 --- linux-2.6.25.10/include/asm-ppc/mmu_context.h 2008-07-02 23:46:47.000000000 -0400
26365 +++ linux-2.6.25.10/include/asm-ppc/mmu_context.h 2008-07-03 16:53:26.000000000 -0400
26366 @@ -141,7 +141,8 @@ static inline void get_mmu_context(struc
26367 static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
26369 mm->context.id = NO_CONTEXT;
26370 - mm->context.vdso_base = 0;
26371 + if (t == current)
26372 + mm->context.vdso_base = ~0UL;
26376 diff -urNp linux-2.6.25.10/include/asm-ppc/pgtable.h linux-2.6.25.10/include/asm-ppc/pgtable.h
26377 --- linux-2.6.25.10/include/asm-ppc/pgtable.h 2008-07-02 23:46:47.000000000 -0400
26378 +++ linux-2.6.25.10/include/asm-ppc/pgtable.h 2008-07-03 16:53:26.000000000 -0400
26379 @@ -390,11 +390,21 @@ extern unsigned long ioremap_bot, iorema
26381 #define PAGE_NONE __pgprot(_PAGE_BASE)
26382 #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
26383 -#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
26384 +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
26385 #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
26386 -#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
26387 +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
26388 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
26389 -#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
26390 +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
26392 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
26393 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
26394 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
26395 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
26397 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
26398 +# define PAGE_COPY_NOEXEC PAGE_COPY
26399 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
26402 #define PAGE_KERNEL __pgprot(_PAGE_RAM)
26403 #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
26404 @@ -406,21 +416,21 @@ extern unsigned long ioremap_bot, iorema
26405 * This is the closest we can get..
26407 #define __P000 PAGE_NONE
26408 -#define __P001 PAGE_READONLY_X
26409 -#define __P010 PAGE_COPY
26410 -#define __P011 PAGE_COPY_X
26411 -#define __P100 PAGE_READONLY
26412 +#define __P001 PAGE_READONLY_NOEXEC
26413 +#define __P010 PAGE_COPY_NOEXEC
26414 +#define __P011 PAGE_COPY_NOEXEC
26415 +#define __P100 PAGE_READONLY_X
26416 #define __P101 PAGE_READONLY_X
26417 -#define __P110 PAGE_COPY
26418 +#define __P110 PAGE_COPY_X
26419 #define __P111 PAGE_COPY_X
26421 #define __S000 PAGE_NONE
26422 -#define __S001 PAGE_READONLY_X
26423 -#define __S010 PAGE_SHARED
26424 -#define __S011 PAGE_SHARED_X
26425 -#define __S100 PAGE_READONLY
26426 +#define __S001 PAGE_READONLY_NOEXEC
26427 +#define __S010 PAGE_SHARED_NOEXEC
26428 +#define __S011 PAGE_SHARED_NOEXEC
26429 +#define __S100 PAGE_READONLY_X
26430 #define __S101 PAGE_READONLY_X
26431 -#define __S110 PAGE_SHARED
26432 +#define __S110 PAGE_SHARED_X
26433 #define __S111 PAGE_SHARED_X
26435 #ifndef __ASSEMBLY__
26436 diff -urNp linux-2.6.25.10/include/asm-s390/kmap_types.h linux-2.6.25.10/include/asm-s390/kmap_types.h
26437 --- linux-2.6.25.10/include/asm-s390/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26438 +++ linux-2.6.25.10/include/asm-s390/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26439 @@ -16,6 +16,7 @@ enum km_type {
26447 diff -urNp linux-2.6.25.10/include/asm-sh/kmap_types.h linux-2.6.25.10/include/asm-sh/kmap_types.h
26448 --- linux-2.6.25.10/include/asm-sh/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26449 +++ linux-2.6.25.10/include/asm-sh/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26450 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
26455 +D(13) KM_CLEARPAGE,
26460 diff -urNp linux-2.6.25.10/include/asm-sparc/elf.h linux-2.6.25.10/include/asm-sparc/elf.h
26461 --- linux-2.6.25.10/include/asm-sparc/elf.h 2008-07-02 23:46:47.000000000 -0400
26462 +++ linux-2.6.25.10/include/asm-sparc/elf.h 2008-07-03 16:53:26.000000000 -0400
26463 @@ -120,6 +120,13 @@ typedef struct {
26465 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
26467 +#ifdef CONFIG_PAX_ASLR
26468 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
26470 +#define PAX_DELTA_MMAP_LEN 16
26471 +#define PAX_DELTA_STACK_LEN 16
26474 /* This yields a mask that user programs can use to figure out what
26475 instruction set this cpu supports. This can NOT be done in userspace
26477 diff -urNp linux-2.6.25.10/include/asm-sparc/kmap_types.h linux-2.6.25.10/include/asm-sparc/kmap_types.h
26478 --- linux-2.6.25.10/include/asm-sparc/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26479 +++ linux-2.6.25.10/include/asm-sparc/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26480 @@ -15,6 +15,7 @@ enum km_type {
26488 diff -urNp linux-2.6.25.10/include/asm-sparc/pgtable.h linux-2.6.25.10/include/asm-sparc/pgtable.h
26489 --- linux-2.6.25.10/include/asm-sparc/pgtable.h 2008-07-02 23:46:47.000000000 -0400
26490 +++ linux-2.6.25.10/include/asm-sparc/pgtable.h 2008-07-03 16:53:26.000000000 -0400
26491 @@ -48,6 +48,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
26492 BTFIXUPDEF_INT(page_none)
26493 BTFIXUPDEF_INT(page_copy)
26494 BTFIXUPDEF_INT(page_readonly)
26496 +#ifdef CONFIG_PAX_PAGEEXEC
26497 +BTFIXUPDEF_INT(page_shared_noexec)
26498 +BTFIXUPDEF_INT(page_copy_noexec)
26499 +BTFIXUPDEF_INT(page_readonly_noexec)
26502 BTFIXUPDEF_INT(page_kernel)
26504 #define PMD_SHIFT SUN4C_PMD_SHIFT
26505 @@ -69,6 +76,16 @@ extern pgprot_t PAGE_SHARED;
26506 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
26507 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
26509 +#ifdef CONFIG_PAX_PAGEEXEC
26510 +extern pgprot_t PAGE_SHARED_NOEXEC;
26511 +# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
26512 +# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
26514 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
26515 +# define PAGE_COPY_NOEXEC PAGE_COPY
26516 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
26519 extern unsigned long page_kernel;
26522 diff -urNp linux-2.6.25.10/include/asm-sparc/pgtsrmmu.h linux-2.6.25.10/include/asm-sparc/pgtsrmmu.h
26523 --- linux-2.6.25.10/include/asm-sparc/pgtsrmmu.h 2008-07-02 23:46:47.000000000 -0400
26524 +++ linux-2.6.25.10/include/asm-sparc/pgtsrmmu.h 2008-07-03 16:53:26.000000000 -0400
26525 @@ -115,6 +115,16 @@
26526 SRMMU_EXEC | SRMMU_REF)
26527 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
26528 SRMMU_EXEC | SRMMU_REF)
26530 +#ifdef CONFIG_PAX_PAGEEXEC
26531 +#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
26532 + SRMMU_WRITE | SRMMU_REF)
26533 +#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
26535 +#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
26539 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
26540 SRMMU_DIRTY | SRMMU_REF)
26542 diff -urNp linux-2.6.25.10/include/asm-sparc64/elf.h linux-2.6.25.10/include/asm-sparc64/elf.h
26543 --- linux-2.6.25.10/include/asm-sparc64/elf.h 2008-07-02 23:46:47.000000000 -0400
26544 +++ linux-2.6.25.10/include/asm-sparc64/elf.h 2008-07-03 16:53:26.000000000 -0400
26545 @@ -164,6 +164,12 @@ typedef struct {
26546 #define ELF_ET_DYN_BASE 0x0000010000000000UL
26547 #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
26549 +#ifdef CONFIG_PAX_ASLR
26550 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
26552 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
26553 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
26556 /* This yields a mask that user programs can use to figure out what
26557 instruction set this cpu supports. */
26558 diff -urNp linux-2.6.25.10/include/asm-sparc64/kmap_types.h linux-2.6.25.10/include/asm-sparc64/kmap_types.h
26559 --- linux-2.6.25.10/include/asm-sparc64/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26560 +++ linux-2.6.25.10/include/asm-sparc64/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26561 @@ -19,6 +19,7 @@ enum km_type {
26569 diff -urNp linux-2.6.25.10/include/asm-um/kmap_types.h linux-2.6.25.10/include/asm-um/kmap_types.h
26570 --- linux-2.6.25.10/include/asm-um/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26571 +++ linux-2.6.25.10/include/asm-um/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26572 @@ -23,6 +23,7 @@ enum km_type {
26580 diff -urNp linux-2.6.25.10/include/asm-v850/kmap_types.h linux-2.6.25.10/include/asm-v850/kmap_types.h
26581 --- linux-2.6.25.10/include/asm-v850/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
26582 +++ linux-2.6.25.10/include/asm-v850/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
26583 @@ -13,6 +13,7 @@ enum km_type {
26591 diff -urNp linux-2.6.25.10/include/asm-x86/alternative.h linux-2.6.25.10/include/asm-x86/alternative.h
26592 --- linux-2.6.25.10/include/asm-x86/alternative.h 2008-07-02 23:46:47.000000000 -0400
26593 +++ linux-2.6.25.10/include/asm-x86/alternative.h 2008-07-03 16:53:26.000000000 -0400
26594 @@ -94,7 +94,7 @@ static inline void alternatives_smp_swit
26595 " .byte 662b-661b\n" /* sourcelen */ \
26596 " .byte 664f-663f\n" /* replacementlen */ \
26598 - ".section .altinstr_replacement,\"ax\"\n" \
26599 + ".section .altinstr_replacement,\"a\"\n" \
26600 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26601 ".previous" :: "i" (feature) : "memory")
26603 @@ -118,7 +118,7 @@ static inline void alternatives_smp_swit
26604 " .byte 662b-661b\n" /* sourcelen */ \
26605 " .byte 664f-663f\n" /* replacementlen */ \
26607 - ".section .altinstr_replacement,\"ax\"\n" \
26608 + ".section .altinstr_replacement,\"a\"\n" \
26609 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26610 ".previous" :: "i" (feature), ##input)
26612 @@ -133,7 +133,7 @@ static inline void alternatives_smp_swit
26613 " .byte 662b-661b\n" /* sourcelen */ \
26614 " .byte 664f-663f\n" /* replacementlen */ \
26616 - ".section .altinstr_replacement,\"ax\"\n" \
26617 + ".section .altinstr_replacement,\"a\"\n" \
26618 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26619 ".previous" : output : [feat] "i" (feature), ##input)
26621 diff -urNp linux-2.6.25.10/include/asm-x86/apic.h linux-2.6.25.10/include/asm-x86/apic.h
26622 --- linux-2.6.25.10/include/asm-x86/apic.h 2008-07-02 23:46:47.000000000 -0400
26623 +++ linux-2.6.25.10/include/asm-x86/apic.h 2008-07-03 16:53:26.000000000 -0400
26626 #define ARCH_APICTIMER_STOPS_ON_C3 1
26628 -#define Dprintk(x...)
26629 +#define Dprintk(x...) do {} while (0)
26633 diff -urNp linux-2.6.25.10/include/asm-x86/boot.h linux-2.6.25.10/include/asm-x86/boot.h
26634 --- linux-2.6.25.10/include/asm-x86/boot.h 2008-07-02 23:46:47.000000000 -0400
26635 +++ linux-2.6.25.10/include/asm-x86/boot.h 2008-07-03 16:53:26.000000000 -0400
26637 #define ASK_VGA 0xfffd /* ask for it at bootup */
26639 /* Physical address where kernel should be loaded. */
26640 -#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
26641 +#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
26642 + (CONFIG_PHYSICAL_ALIGN - 1)) \
26643 & ~(CONFIG_PHYSICAL_ALIGN - 1))
26645 +#ifndef __ASSEMBLY__
26646 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
26647 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
26650 #endif /* _ASM_BOOT_H */
26651 diff -urNp linux-2.6.25.10/include/asm-x86/cache.h linux-2.6.25.10/include/asm-x86/cache.h
26652 --- linux-2.6.25.10/include/asm-x86/cache.h 2008-07-02 23:46:47.000000000 -0400
26653 +++ linux-2.6.25.10/include/asm-x86/cache.h 2008-07-03 16:53:26.000000000 -0400
26655 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
26657 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
26658 +#define __read_only __attribute__((__section__(".data.read_only")))
26660 #ifdef CONFIG_X86_VSMP
26661 /* vSMP Internode cacheline shift */
26662 diff -urNp linux-2.6.25.10/include/asm-x86/checksum_32.h linux-2.6.25.10/include/asm-x86/checksum_32.h
26663 --- linux-2.6.25.10/include/asm-x86/checksum_32.h 2008-07-02 23:46:47.000000000 -0400
26664 +++ linux-2.6.25.10/include/asm-x86/checksum_32.h 2008-07-03 16:53:26.000000000 -0400
26665 @@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
26666 asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
26667 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
26669 +asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
26670 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
26672 +asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
26673 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
26676 * Note: when you get a NULL pointer exception here this means someone
26677 * passed in an incorrect kernel address to one of these functions.
26678 @@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
26679 int len, __wsum sum, int *err_ptr)
26682 - return csum_partial_copy_generic((__force void *)src, dst,
26683 + return csum_partial_copy_generic_from_user((__force void *)src, dst,
26684 len, sum, err_ptr, NULL);
26687 @@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
26690 if (access_ok(VERIFY_WRITE, dst, len))
26691 - return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
26692 + return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
26695 *err_ptr = -EFAULT;
26696 diff -urNp linux-2.6.25.10/include/asm-x86/desc.h linux-2.6.25.10/include/asm-x86/desc.h
26697 --- linux-2.6.25.10/include/asm-x86/desc.h 2008-07-02 23:46:47.000000000 -0400
26698 +++ linux-2.6.25.10/include/asm-x86/desc.h 2008-07-03 16:53:26.000000000 -0400
26699 @@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
26700 desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
26701 desc->type = (info->read_exec_only ^ 1) << 1;
26702 desc->type |= info->contents << 2;
26703 + desc->type |= info->seg_not_present ^ 1;
26706 desc->p = info->seg_not_present ^ 1;
26707 @@ -27,14 +28,15 @@ static inline void fill_ldt(struct desc_
26710 extern struct desc_ptr idt_descr;
26711 -extern gate_desc idt_table[];
26712 +extern gate_desc idt_table[256];
26714 -#ifdef CONFIG_X86_64
26715 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
26716 -extern struct desc_ptr cpu_gdt_descr[];
26717 -/* the cpu gdt accessor */
26718 -#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address)
26719 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
26720 +static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
26722 + return cpu_gdt_table[cpu];
26725 +#ifdef CONFIG_X86_64
26726 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
26727 unsigned dpl, unsigned ist, unsigned seg)
26729 @@ -51,16 +53,6 @@ static inline void pack_gate(gate_desc *
26734 - struct desc_struct gdt[GDT_ENTRIES];
26735 -} __attribute__((aligned(PAGE_SIZE)));
26736 -DECLARE_PER_CPU(struct gdt_page, gdt_page);
26738 -static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
26740 - return per_cpu(gdt_page, cpu).gdt;
26743 static inline void pack_gate(gate_desc *gate, unsigned char type,
26744 unsigned long base, unsigned dpl, unsigned flags, unsigned short seg)
26746 @@ -69,7 +61,6 @@ static inline void pack_gate(gate_desc *
26747 gate->b = (base & 0xffff0000) |
26748 (((0x80 | type | (dpl << 5)) & 0xff) << 8);
26753 static inline int desc_empty(const void *ptr)
26754 @@ -105,19 +96,48 @@ static inline int desc_empty(const void
26755 static inline void native_write_idt_entry(gate_desc *idt, int entry,
26756 const gate_desc *gate)
26759 +#ifdef CONFIG_PAX_KERNEXEC
26760 + unsigned long cr0;
26762 + pax_open_kernel(cr0);
26765 memcpy(&idt[entry], gate, sizeof(*gate));
26767 +#ifdef CONFIG_PAX_KERNEXEC
26768 + pax_close_kernel(cr0);
26773 static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
26777 +#ifdef CONFIG_PAX_KERNEXEC
26778 + unsigned long cr0;
26780 + pax_open_kernel(cr0);
26783 memcpy(&ldt[entry], desc, 8);
26785 +#ifdef CONFIG_PAX_KERNEXEC
26786 + pax_close_kernel(cr0);
26791 static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
26792 const void *desc, int type)
26796 +#ifdef CONFIG_PAX_KERNEXEC
26797 + unsigned long cr0;
26802 size = sizeof(tss_desc);
26803 @@ -129,7 +149,17 @@ static inline void native_write_gdt_entr
26804 size = sizeof(struct desc_struct);
26808 +#ifdef CONFIG_PAX_KERNEXEC
26809 + pax_open_kernel(cr0);
26812 memcpy(&gdt[entry], desc, size);
26814 +#ifdef CONFIG_PAX_KERNEXEC
26815 + pax_close_kernel(cr0);
26820 static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
26821 @@ -236,8 +266,19 @@ static inline void native_load_tls(struc
26823 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
26825 +#ifdef CONFIG_PAX_KERNEXEC
26826 + unsigned long cr0;
26828 + pax_open_kernel(cr0);
26831 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
26832 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
26834 +#ifdef CONFIG_PAX_KERNEXEC
26835 + pax_close_kernel(cr0);
26840 #define _LDT_empty(info) (\
26841 @@ -353,6 +394,18 @@ static inline void set_system_gate_ist(i
26842 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
26845 +#ifdef CONFIG_X86_32
26846 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
26848 + struct desc_struct d;
26850 + if (likely(limit))
26851 + limit = (limit - 1UL) >> PAGE_SHIFT;
26852 + pack_descriptor(&d, base, limit, 0xFB, 0xC);
26853 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
26859 * GET_DESC_BASE reads the descriptor base of the specified segment.
26860 diff -urNp linux-2.6.25.10/include/asm-x86/elf.h linux-2.6.25.10/include/asm-x86/elf.h
26861 --- linux-2.6.25.10/include/asm-x86/elf.h 2008-07-02 23:46:47.000000000 -0400
26862 +++ linux-2.6.25.10/include/asm-x86/elf.h 2008-07-03 16:53:26.000000000 -0400
26863 @@ -243,7 +243,25 @@ extern int force_personality32;
26864 the loader. We need to make sure that it is out of the way of the program
26865 that it will "exec", and that there is sufficient room for the brk. */
26867 +#ifdef CONFIG_PAX_SEGMEXEC
26868 +#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
26870 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
26873 +#ifdef CONFIG_PAX_ASLR
26874 +#ifdef CONFIG_X86_32
26875 +#define PAX_ELF_ET_DYN_BASE 0x10000000UL
26877 +#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
26878 +#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
26880 +#define PAX_ELF_ET_DYN_BASE 0x400000UL
26882 +#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
26883 +#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
26887 /* This yields a mask that user programs can use to figure out what
26888 instruction set this CPU supports. This could be done in user space,
26889 @@ -292,7 +310,7 @@ do if (vdso_enabled) { \
26891 #define ARCH_DLINFO \
26892 do if (vdso_enabled) { \
26893 - NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
26894 + NEW_AUX_ENT(AT_SYSINFO_EHDR,current->mm->context.vdso);\
26897 #define AT_SYSINFO 32
26898 @@ -303,7 +321,7 @@ do if (vdso_enabled) { \
26900 #endif /* !CONFIG_X86_32 */
26902 -#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
26903 +#define VDSO_CURRENT_BASE (current->mm->context.vdso)
26905 #define VDSO_ENTRY \
26906 ((unsigned long) VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
26907 @@ -317,7 +335,4 @@ extern int arch_setup_additional_pages(s
26908 extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
26909 #define compat_arch_setup_additional_pages syscall32_setup_pages
26911 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
26912 -#define arch_randomize_brk arch_randomize_brk
26915 diff -urNp linux-2.6.25.10/include/asm-x86/futex.h linux-2.6.25.10/include/asm-x86/futex.h
26916 --- linux-2.6.25.10/include/asm-x86/futex.h 2008-07-02 23:46:47.000000000 -0400
26917 +++ linux-2.6.25.10/include/asm-x86/futex.h 2008-07-03 16:53:26.000000000 -0400
26919 #include <asm/system.h>
26920 #include <asm/uaccess.h>
26922 +#ifdef CONFIG_X86_32
26923 +#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
26924 + __asm__ __volatile( \
26925 + "movw %w6, %%ds\n" \
26927 +"2: pushl %%ss\n \
26929 + .section .fixup,\"ax\"\n \
26933 + _ASM_EXTABLE(1b,3b) \
26934 + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
26935 + : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
26937 +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
26938 + __asm__ __volatile( \
26939 +" movw %w7, %%es\n \
26940 +1: movl %%es:%2, %0\n \
26943 +"2: lock; cmpxchgl %3, %%es:%2\n \
26947 + .section .fixup,\"ax\"\n \
26951 + _ASM_EXTABLE(1b,4b) \
26952 + _ASM_EXTABLE(2b,4b) \
26953 + : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
26955 + : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
26957 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
26958 __asm__ __volatile( \
26961 : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
26963 : "r" (oparg), "i" (-EFAULT), "1" (0))
26967 futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
26968 @@ -64,11 +100,20 @@ futex_atomic_op_inuser(int encoded_op, i
26972 +#ifdef CONFIG_X86_32
26973 + __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
26975 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
26979 +#ifdef CONFIG_X86_32
26980 + __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
26983 __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
26988 __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
26989 @@ -113,14 +158,26 @@ futex_atomic_cmpxchg_inatomic(int __user
26992 __asm__ __volatile__(
26993 +#ifdef CONFIG_X86_32
26994 + " movw %w5, %%ds \n"
26995 + "1: lock; cmpxchgl %3, %%ds:%1 \n"
26996 + "2: pushl %%ss \n"
26998 + " .section .fixup, \"ax\" \n"
27000 "1: lock; cmpxchgl %3, %1 \n"
27001 "2: .section .fixup, \"ax\" \n"
27006 _ASM_EXTABLE(1b,3b)
27007 : "=a" (oldval), "+m" (*uaddr)
27008 +#ifdef CONFIG_X86_32
27009 + : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
27011 : "i" (-EFAULT), "r" (newval), "0" (oldval)
27016 diff -urNp linux-2.6.25.10/include/asm-x86/i387.h linux-2.6.25.10/include/asm-x86/i387.h
27017 --- linux-2.6.25.10/include/asm-x86/i387.h 2008-07-02 23:46:47.000000000 -0400
27018 +++ linux-2.6.25.10/include/asm-x86/i387.h 2008-07-03 16:53:26.000000000 -0400
27019 @@ -202,13 +202,8 @@ static inline void restore_fpu(struct ta
27022 /* We need a safe address that is cheap to find and that is already
27023 - in L1 during context switch. The best choices are unfortunately
27024 - different for UP and SMP */
27026 -#define safe_address (__per_cpu_offset[0])
27028 -#define safe_address (kstat_cpu(0).cpustat.user)
27030 + in L1 during context switch. */
27031 +#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
27034 * These must be called with preempt disabled
27035 diff -urNp linux-2.6.25.10/include/asm-x86/io_64.h linux-2.6.25.10/include/asm-x86/io_64.h
27036 --- linux-2.6.25.10/include/asm-x86/io_64.h 2008-07-02 23:46:47.000000000 -0400
27037 +++ linux-2.6.25.10/include/asm-x86/io_64.h 2008-07-03 16:53:26.000000000 -0400
27038 @@ -143,6 +143,17 @@ static inline void * phys_to_virt(unsign
27042 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
27043 +static inline int valid_phys_addr_range (unsigned long addr, size_t count)
27045 + return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
27048 +static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
27050 + return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
27054 * Change "struct page" to physical address.
27056 diff -urNp linux-2.6.25.10/include/asm-x86/irqflags.h linux-2.6.25.10/include/asm-x86/irqflags.h
27057 --- linux-2.6.25.10/include/asm-x86/irqflags.h 2008-07-02 23:46:47.000000000 -0400
27058 +++ linux-2.6.25.10/include/asm-x86/irqflags.h 2008-07-03 16:53:26.000000000 -0400
27059 @@ -146,6 +146,8 @@ static inline unsigned long __raw_local_
27060 #define INTERRUPT_RETURN iret
27061 #define ENABLE_INTERRUPTS_SYSCALL_RET sti; sysexit
27062 #define GET_CR0_INTO_EAX movl %cr0, %eax
27063 +#define GET_CR0_INTO_EDX movl %cr0, %edx
27064 +#define SET_CR0_FROM_EDX movl %edx, %cr0
27068 diff -urNp linux-2.6.25.10/include/asm-x86/kmap_types.h linux-2.6.25.10/include/asm-x86/kmap_types.h
27069 --- linux-2.6.25.10/include/asm-x86/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
27070 +++ linux-2.6.25.10/include/asm-x86/kmap_types.h 2008-07-03 16:53:26.000000000 -0400
27071 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
27076 +D(13) KM_CLEARPAGE,
27081 diff -urNp linux-2.6.25.10/include/asm-x86/linkage.h linux-2.6.25.10/include/asm-x86/linkage.h
27082 --- linux-2.6.25.10/include/asm-x86/linkage.h 2008-07-02 23:46:47.000000000 -0400
27083 +++ linux-2.6.25.10/include/asm-x86/linkage.h 2008-07-03 16:53:26.000000000 -0400
27085 #ifdef CONFIG_X86_64
27086 #define __ALIGN .p2align 4,,15
27087 #define __ALIGN_STR ".p2align 4,,15"
27089 +#ifdef CONFIG_X86_ALIGNMENT_16
27090 +#define __ALIGN .align 16,0x90
27091 +#define __ALIGN_STR ".align 16,0x90"
27095 #ifdef CONFIG_X86_32
27100 -#ifdef CONFIG_X86_ALIGNMENT_16
27101 -#define __ALIGN .align 16,0x90
27102 -#define __ALIGN_STR ".align 16,0x90"
27107 diff -urNp linux-2.6.25.10/include/asm-x86/mach-default/apm.h linux-2.6.25.10/include/asm-x86/mach-default/apm.h
27108 --- linux-2.6.25.10/include/asm-x86/mach-default/apm.h 2008-07-02 23:46:47.000000000 -0400
27109 +++ linux-2.6.25.10/include/asm-x86/mach-default/apm.h 2008-07-03 16:53:26.000000000 -0400
27110 @@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
27111 __asm__ __volatile__(APM_DO_ZERO_SEGS
27114 - "lcall *%%cs:apm_bios_entry\n\t"
27115 + "lcall *%%ss:apm_bios_entry\n\t"
27119 @@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
27120 __asm__ __volatile__(APM_DO_ZERO_SEGS
27123 - "lcall *%%cs:apm_bios_entry\n\t"
27124 + "lcall *%%ss:apm_bios_entry\n\t"
27128 diff -urNp linux-2.6.25.10/include/asm-x86/mman.h linux-2.6.25.10/include/asm-x86/mman.h
27129 --- linux-2.6.25.10/include/asm-x86/mman.h 2008-07-02 23:46:47.000000000 -0400
27130 +++ linux-2.6.25.10/include/asm-x86/mman.h 2008-07-03 16:53:26.000000000 -0400
27132 #define MCL_CURRENT 1 /* lock all current mappings */
27133 #define MCL_FUTURE 2 /* lock all future mappings */
27136 +#ifndef __ASSEMBLY__
27137 +#ifdef CONFIG_X86_32
27138 +#define arch_mmap_check i386_mmap_check
27139 +int i386_mmap_check(unsigned long addr, unsigned long len,
27140 + unsigned long flags);
27145 #endif /* _ASM_X86_MMAN_H */
27146 diff -urNp linux-2.6.25.10/include/asm-x86/mmu_context_32.h linux-2.6.25.10/include/asm-x86/mmu_context_32.h
27147 --- linux-2.6.25.10/include/asm-x86/mmu_context_32.h 2008-07-02 23:46:47.000000000 -0400
27148 +++ linux-2.6.25.10/include/asm-x86/mmu_context_32.h 2008-07-03 16:53:26.000000000 -0400
27149 @@ -55,6 +55,22 @@ static inline void switch_mm(struct mm_s
27151 if (unlikely(prev->context.ldt != next->context.ldt))
27152 load_LDT_nolock(&next->context);
27154 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27155 + if (!nx_enabled) {
27156 + smp_mb__before_clear_bit();
27157 + cpu_clear(cpu, prev->context.cpu_user_cs_mask);
27158 + smp_mb__after_clear_bit();
27159 + cpu_set(cpu, next->context.cpu_user_cs_mask);
27163 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27164 + if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
27165 + prev->context.user_cs_limit != next->context.user_cs_limit))
27166 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27172 @@ -67,6 +83,19 @@ static inline void switch_mm(struct mm_s
27174 load_cr3(next->pgd);
27175 load_LDT_nolock(&next->context);
27177 +#ifdef CONFIG_PAX_PAGEEXEC
27179 + cpu_set(cpu, next->context.cpu_user_cs_mask);
27182 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27183 +#ifdef CONFIG_PAX_PAGEEXEC
27184 + if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
27186 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27192 diff -urNp linux-2.6.25.10/include/asm-x86/mmu.h linux-2.6.25.10/include/asm-x86/mmu.h
27193 --- linux-2.6.25.10/include/asm-x86/mmu.h 2008-07-02 23:46:47.000000000 -0400
27194 +++ linux-2.6.25.10/include/asm-x86/mmu.h 2008-07-03 16:53:26.000000000 -0400
27195 @@ -11,13 +11,26 @@
27196 * cpu_vm_mask is used to optimize ldt flushing.
27200 + struct desc_struct *ldt;
27201 #ifdef CONFIG_X86_64
27207 + unsigned long vdso;
27209 +#ifdef CONFIG_X86_32
27210 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27211 + unsigned long user_cs_base;
27212 + unsigned long user_cs_limit;
27214 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27215 + cpumask_t cpu_user_cs_mask;
27224 diff -urNp linux-2.6.25.10/include/asm-x86/module.h linux-2.6.25.10/include/asm-x86/module.h
27225 --- linux-2.6.25.10/include/asm-x86/module.h 2008-07-02 23:46:47.000000000 -0400
27226 +++ linux-2.6.25.10/include/asm-x86/module.h 2008-07-03 16:53:26.000000000 -0400
27227 @@ -76,7 +76,12 @@ struct mod_arch_specific {};
27229 # define MODULE_STACKSIZE ""
27231 -# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
27232 +# ifdef CONFIG_GRKERNSEC
27233 +# define MODULE_GRSEC "GRSECURITY "
27235 +# define MODULE_GRSEC ""
27237 +# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
27240 #endif /* _ASM_MODULE_H */
27241 diff -urNp linux-2.6.25.10/include/asm-x86/page_32.h linux-2.6.25.10/include/asm-x86/page_32.h
27242 --- linux-2.6.25.10/include/asm-x86/page_32.h 2008-07-02 23:46:47.000000000 -0400
27243 +++ linux-2.6.25.10/include/asm-x86/page_32.h 2008-07-03 16:53:26.000000000 -0400
27246 #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
27248 +#ifdef CONFIG_PAX_KERNEXEC
27249 +#ifndef __ASSEMBLY__
27250 +extern unsigned char MODULES_VADDR[];
27251 +extern unsigned char MODULES_END[];
27252 +extern unsigned char KERNEL_TEXT_OFFSET[];
27253 +#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
27254 +#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
27257 +#define ktla_ktva(addr) (addr)
27258 +#define ktva_ktla(addr) (addr)
27261 +#ifdef CONFIG_PAX_PAGEEXEC
27262 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
27265 #ifdef CONFIG_X86_PAE
27266 /* 44=32+12, the limit we can fit into an unsigned long pfn */
27267 #define __PHYSICAL_MASK_SHIFT 44
27268 diff -urNp linux-2.6.25.10/include/asm-x86/page_64.h linux-2.6.25.10/include/asm-x86/page_64.h
27269 --- linux-2.6.25.10/include/asm-x86/page_64.h 2008-07-02 23:46:47.000000000 -0400
27270 +++ linux-2.6.25.10/include/asm-x86/page_64.h 2008-07-03 16:53:26.000000000 -0400
27272 #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
27273 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
27275 +#define ktla_ktva(addr) (addr)
27276 +#define ktva_ktla(addr) (addr)
27278 /* See Documentation/x86_64/mm.txt for a description of the memory map. */
27279 #define __PHYSICAL_MASK_SHIFT 46
27280 #define __VIRTUAL_MASK_SHIFT 48
27281 @@ -87,5 +90,6 @@ typedef struct { pteval_t pte; } pte_t;
27282 #define pfn_valid(pfn) ((pfn) < end_pfn)
27285 +#define nx_enabled (1)
27287 #endif /* _X86_64_PAGE_H */
27288 diff -urNp linux-2.6.25.10/include/asm-x86/paravirt.h linux-2.6.25.10/include/asm-x86/paravirt.h
27289 --- linux-2.6.25.10/include/asm-x86/paravirt.h 2008-07-02 23:46:47.000000000 -0400
27290 +++ linux-2.6.25.10/include/asm-x86/paravirt.h 2008-07-03 16:53:26.000000000 -0400
27291 @@ -1356,24 +1356,24 @@ static inline unsigned long __raw_local_
27293 #define INTERRUPT_RETURN \
27294 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \
27295 - jmp *%cs:pv_cpu_ops+PV_CPU_iret)
27296 + jmp *%ss:pv_cpu_ops+PV_CPU_iret)
27298 #define DISABLE_INTERRUPTS(clobbers) \
27299 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
27301 - call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \
27302 + call *%ss:pv_irq_ops+PV_IRQ_irq_disable; \
27303 PV_RESTORE_REGS;) \
27305 #define ENABLE_INTERRUPTS(clobbers) \
27306 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
27308 - call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
27309 + call *%ss:pv_irq_ops+PV_IRQ_irq_enable; \
27312 #define ENABLE_INTERRUPTS_SYSCALL_RET \
27313 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\
27315 - jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
27316 + jmp *%ss:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
27319 #ifdef CONFIG_X86_32
27320 diff -urNp linux-2.6.25.10/include/asm-x86/pda.h linux-2.6.25.10/include/asm-x86/pda.h
27321 --- linux-2.6.25.10/include/asm-x86/pda.h 2008-07-02 23:46:47.000000000 -0400
27322 +++ linux-2.6.25.10/include/asm-x86/pda.h 2008-07-03 16:53:26.000000000 -0400
27323 @@ -16,11 +16,9 @@ struct x8664_pda {
27324 unsigned long oldrsp; /* 24 user rsp for system call */
27325 int irqcount; /* 32 Irq nesting counter. Starts -1 */
27326 unsigned int cpunumber; /* 36 Logical CPU number */
27327 -#ifdef CONFIG_CC_STACKPROTECTOR
27328 unsigned long stack_canary; /* 40 stack canary value */
27329 /* gcc-ABI: this canary MUST be at
27333 unsigned int nodenumber; /* number of current node */
27334 unsigned int __softirq_pending;
27335 diff -urNp linux-2.6.25.10/include/asm-x86/percpu.h linux-2.6.25.10/include/asm-x86/percpu.h
27336 --- linux-2.6.25.10/include/asm-x86/percpu.h 2008-07-02 23:46:47.000000000 -0400
27337 +++ linux-2.6.25.10/include/asm-x86/percpu.h 2008-07-03 16:53:26.000000000 -0400
27338 @@ -67,6 +67,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
27340 #define __my_cpu_offset x86_read_percpu(this_cpu_off)
27342 +#include <asm-generic/sections.h>
27343 +#include <linux/threads.h>
27344 +#define __per_cpu_offset __per_cpu_offset
27345 +extern unsigned long __per_cpu_offset[NR_CPUS];
27346 +#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
27348 /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
27349 #define __percpu_seg "%%fs:"
27351 diff -urNp linux-2.6.25.10/include/asm-x86/pgalloc_32.h linux-2.6.25.10/include/asm-x86/pgalloc_32.h
27352 --- linux-2.6.25.10/include/asm-x86/pgalloc_32.h 2008-07-02 23:46:47.000000000 -0400
27353 +++ linux-2.6.25.10/include/asm-x86/pgalloc_32.h 2008-07-03 16:53:26.000000000 -0400
27354 @@ -21,7 +21,11 @@ static inline void pmd_populate_kernel(s
27355 pmd_t *pmd, pte_t *pte)
27357 paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);
27358 +#ifdef CONFIG_COMPAT_VDSO
27359 set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
27361 + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
27365 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
27366 diff -urNp linux-2.6.25.10/include/asm-x86/pgalloc_64.h linux-2.6.25.10/include/asm-x86/pgalloc_64.h
27367 --- linux-2.6.25.10/include/asm-x86/pgalloc_64.h 2008-07-02 23:46:47.000000000 -0400
27368 +++ linux-2.6.25.10/include/asm-x86/pgalloc_64.h 2008-07-03 16:53:26.000000000 -0400
27370 #include <linux/mm.h>
27372 #define pmd_populate_kernel(mm, pmd, pte) \
27373 - set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
27374 + set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
27375 #define pud_populate(mm, pud, pmd) \
27376 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
27377 #define pgd_populate(mm, pgd, pud) \
27378 diff -urNp linux-2.6.25.10/include/asm-x86/pgtable-2level.h linux-2.6.25.10/include/asm-x86/pgtable-2level.h
27379 --- linux-2.6.25.10/include/asm-x86/pgtable-2level.h 2008-07-02 23:46:47.000000000 -0400
27380 +++ linux-2.6.25.10/include/asm-x86/pgtable-2level.h 2008-07-03 16:53:26.000000000 -0400
27381 @@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
27383 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
27386 +#ifdef CONFIG_PAX_KERNEXEC
27387 + unsigned long cr0;
27389 + pax_open_kernel(cr0);
27394 +#ifdef CONFIG_PAX_KERNEXEC
27395 + pax_close_kernel(cr0);
27400 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
27401 diff -urNp linux-2.6.25.10/include/asm-x86/pgtable_32.h linux-2.6.25.10/include/asm-x86/pgtable_32.h
27402 --- linux-2.6.25.10/include/asm-x86/pgtable_32.h 2008-07-02 23:46:47.000000000 -0400
27403 +++ linux-2.6.25.10/include/asm-x86/pgtable_32.h 2008-07-03 16:53:26.000000000 -0400
27406 struct vm_area_struct;
27408 -extern pgd_t swapper_pg_dir[1024];
27410 static inline void pgtable_cache_init(void) { }
27411 static inline void check_pgt_cache(void) { }
27412 void paging_init(void);
27413 @@ -45,6 +43,11 @@ void paging_init(void);
27414 # include <asm/pgtable-2level-defs.h>
27417 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
27418 +#ifdef CONFIG_X86_PAE
27419 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
27422 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
27423 #define PGDIR_MASK (~(PGDIR_SIZE-1))
27425 @@ -83,7 +86,7 @@ void paging_init(void);
27426 #undef TEST_ACCESS_OK
27428 /* The boot page tables (all created as a single array) */
27429 -extern unsigned long pg0[];
27430 +extern pte_t pg0[];
27432 #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
27434 @@ -113,7 +116,19 @@ extern unsigned long pg0[];
27436 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
27438 - memcpy(dst, src, count * sizeof(pgd_t));
27440 +#ifdef CONFIG_PAX_KERNEXEC
27441 + unsigned long cr0;
27443 + pax_open_kernel(cr0);
27446 + memcpy(dst, src, count * sizeof(pgd_t));
27448 +#ifdef CONFIG_PAX_KERNEXEC
27449 + pax_close_kernel(cr0);
27455 @@ -223,6 +238,9 @@ static inline void paravirt_pagetable_se
27457 #endif /* !__ASSEMBLY__ */
27459 +#define HAVE_ARCH_UNMAPPED_AREA
27460 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
27463 * kern_addr_valid() is (1) for FLATMEM and (0) for
27464 * SPARSEMEM and DISCONTIGMEM
27465 diff -urNp linux-2.6.25.10/include/asm-x86/pgtable-3level.h linux-2.6.25.10/include/asm-x86/pgtable-3level.h
27466 --- linux-2.6.25.10/include/asm-x86/pgtable-3level.h 2008-07-02 23:46:47.000000000 -0400
27467 +++ linux-2.6.25.10/include/asm-x86/pgtable-3level.h 2008-07-03 16:53:26.000000000 -0400
27468 @@ -64,11 +64,35 @@ static inline void native_set_pte_atomic
27470 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
27473 +#ifdef CONFIG_PAX_KERNEXEC
27474 + unsigned long cr0;
27476 + pax_open_kernel(cr0);
27479 set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
27481 +#ifdef CONFIG_PAX_KERNEXEC
27482 + pax_close_kernel(cr0);
27486 static inline void native_set_pud(pud_t *pudp, pud_t pud)
27489 +#ifdef CONFIG_PAX_KERNEXEC
27490 + unsigned long cr0;
27492 + pax_open_kernel(cr0);
27495 set_64bit((unsigned long long *)(pudp),native_pud_val(pud));
27497 +#ifdef CONFIG_PAX_KERNEXEC
27498 + pax_close_kernel(cr0);
27504 diff -urNp linux-2.6.25.10/include/asm-x86/pgtable_64.h linux-2.6.25.10/include/asm-x86/pgtable_64.h
27505 --- linux-2.6.25.10/include/asm-x86/pgtable_64.h 2008-07-02 23:46:47.000000000 -0400
27506 +++ linux-2.6.25.10/include/asm-x86/pgtable_64.h 2008-07-03 16:53:26.000000000 -0400
27507 @@ -96,7 +96,19 @@ static inline pte_t native_ptep_get_and_
27509 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
27512 +#ifdef CONFIG_PAX_KERNEXEC
27513 + unsigned long cr0;
27515 + pax_open_kernel(cr0);
27520 +#ifdef CONFIG_PAX_KERNEXEC
27521 + pax_close_kernel(cr0);
27526 static inline void native_pmd_clear(pmd_t *pmd)
27527 @@ -148,17 +160,17 @@ static inline void native_pgd_clear(pgd_
27529 static inline unsigned long pgd_bad(pgd_t pgd)
27531 - return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
27532 + return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
27535 static inline unsigned long pud_bad(pud_t pud)
27537 - return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
27538 + return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
27541 static inline unsigned long pmd_bad(pmd_t pmd)
27543 - return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
27544 + return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
27547 #define pte_none(x) (!pte_val(x))
27548 diff -urNp linux-2.6.25.10/include/asm-x86/pgtable.h linux-2.6.25.10/include/asm-x86/pgtable.h
27549 --- linux-2.6.25.10/include/asm-x86/pgtable.h 2008-07-02 23:46:47.000000000 -0400
27550 +++ linux-2.6.25.10/include/asm-x86/pgtable.h 2008-07-03 16:53:26.000000000 -0400
27552 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
27553 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
27555 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
27556 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
27558 #ifdef CONFIG_X86_32
27559 #define _PAGE_KERNEL_EXEC \
27560 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
27561 @@ -87,7 +90,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KE
27562 #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
27563 #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
27564 #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
27565 -#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
27566 +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
27567 #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
27568 #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
27570 @@ -140,10 +143,13 @@ extern unsigned long empty_zero_page[PAG
27571 extern spinlock_t pgd_lock;
27572 extern struct list_head pgd_list;
27574 +extern pteval_t __supported_pte_mask;
27577 * The following only work if pte_present() is true.
27578 * Undefined behaviour if not..
27580 +static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
27581 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
27582 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
27583 static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
27584 @@ -157,10 +163,31 @@ static inline int pmd_large(pmd_t pte) {
27585 (_PAGE_PSE|_PAGE_PRESENT);
27588 +static inline pte_t pte_exprotect(pte_t pte)
27590 +#ifdef CONFIG_X86_PAE
27591 + if (__supported_pte_mask & _PAGE_NX)
27592 + return __pte(pte_val(pte) | _PAGE_NX);
27595 + return __pte(pte_val(pte) & ~_PAGE_USER);
27598 static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_DIRTY); }
27599 static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED); }
27600 static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW); }
27601 -static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX); }
27602 +static inline pte_t pte_mkread(pte_t pte) { return __pte(pte_val(pte) | _PAGE_USER); }
27604 +static inline pte_t pte_mkexec(pte_t pte)
27606 +#ifdef CONFIG_X86_PAE
27607 + if (__supported_pte_mask & _PAGE_NX)
27608 + return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
27611 + return __pte(pte_val(pte) | _PAGE_USER);
27614 static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); }
27615 static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); }
27616 static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); }
27617 @@ -169,8 +196,6 @@ static inline pte_t pte_clrhuge(pte_t pt
27618 static inline pte_t pte_mkglobal(pte_t pte) { return __pte(pte_val(pte) | _PAGE_GLOBAL); }
27619 static inline pte_t pte_clrglobal(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL); }
27621 -extern pteval_t __supported_pte_mask;
27623 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
27625 return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
27626 diff -urNp linux-2.6.25.10/include/asm-x86/processor.h linux-2.6.25.10/include/asm-x86/processor.h
27627 --- linux-2.6.25.10/include/asm-x86/processor.h 2008-07-02 23:46:47.000000000 -0400
27628 +++ linux-2.6.25.10/include/asm-x86/processor.h 2008-07-03 16:53:26.000000000 -0400
27629 @@ -236,7 +236,7 @@ struct tss_struct {
27630 unsigned long stack[64];
27631 } __attribute__((packed));
27633 -DECLARE_PER_CPU(struct tss_struct, init_tss);
27634 +extern struct tss_struct init_tss[NR_CPUS];
27636 /* Save the original ist values for checking stack pointers during debugging */
27638 @@ -714,11 +714,20 @@ static inline void prefetchw(const void
27639 * User space process size: 3GB (default).
27641 #define TASK_SIZE (PAGE_OFFSET)
27643 +#ifdef CONFIG_PAX_SEGMEXEC
27644 +#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
27647 +#ifdef CONFIG_PAX_SEGMEXEC
27648 +#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
27650 #define STACK_TOP TASK_SIZE
27651 -#define STACK_TOP_MAX STACK_TOP
27653 +#define STACK_TOP_MAX TASK_SIZE
27655 #define INIT_THREAD { \
27656 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
27657 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
27658 .vm86_info = NULL, \
27659 .sysenter_cs = __KERNEL_CS, \
27660 .io_bitmap_ptr = NULL, \
27661 @@ -733,7 +742,7 @@ static inline void prefetchw(const void
27663 #define INIT_TSS { \
27665 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
27666 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
27667 .ss0 = __KERNEL_DS, \
27668 .ss1 = __KERNEL_CS, \
27669 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
27670 @@ -757,11 +766,7 @@ static inline void prefetchw(const void
27671 extern unsigned long thread_saved_pc(struct task_struct *tsk);
27673 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
27674 -#define KSTK_TOP(info) \
27676 - unsigned long *__ptr = (unsigned long *)(info); \
27677 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
27679 +#define KSTK_TOP(info) ((info)->task.thread.sp0)
27682 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
27683 @@ -776,7 +781,7 @@ extern unsigned long thread_saved_pc(str
27684 #define task_pt_regs(task) \
27686 struct pt_regs *__regs__; \
27687 - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
27688 + __regs__ = (struct pt_regs *)((task)->thread.sp0); \
27692 @@ -792,7 +797,7 @@ extern unsigned long thread_saved_pc(str
27693 * space during mmap's.
27695 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
27696 - 0xc0000000 : 0xFFFFe000)
27697 + 0xc0000000 : 0xFFFFf000)
27699 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
27700 IA32_PAGE_OFFSET : TASK_SIZE64)
27701 @@ -837,6 +842,10 @@ extern unsigned long thread_saved_pc(str
27703 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
27705 +#ifdef CONFIG_PAX_SEGMEXEC
27706 +#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
27709 #define KSTK_EIP(task) (task_pt_regs(task)->ip)
27712 diff -urNp linux-2.6.25.10/include/asm-x86/ptrace.h linux-2.6.25.10/include/asm-x86/ptrace.h
27713 --- linux-2.6.25.10/include/asm-x86/ptrace.h 2008-07-02 23:46:47.000000000 -0400
27714 +++ linux-2.6.25.10/include/asm-x86/ptrace.h 2008-07-03 16:53:26.000000000 -0400
27715 @@ -56,7 +56,6 @@ struct pt_regs {
27718 #include <asm/vm86.h>
27719 -#include <asm/segment.h>
27721 #endif /* __KERNEL__ */
27723 @@ -129,6 +128,7 @@ struct pt_regs {
27725 /* the DS BTS struct is used for ptrace as well */
27726 #include <asm/ds.h>
27727 +#include <asm/segment.h>
27729 struct task_struct;
27731 @@ -148,28 +148,29 @@ void signal_fault(struct pt_regs *regs,
27732 #define regs_return_value(regs) ((regs)->ax)
27735 - * user_mode_vm(regs) determines whether a register set came from user mode.
27736 + * user_mode(regs) determines whether a register set came from user mode.
27737 * This is true if V8086 mode was enabled OR if the register set was from
27738 * protected mode with RPL-3 CS value. This tricky test checks that with
27739 * one comparison. Many places in the kernel can bypass this full check
27740 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
27741 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
27744 -static inline int user_mode(struct pt_regs *regs)
27745 +static inline int user_mode_novm(struct pt_regs *regs)
27747 #ifdef CONFIG_X86_32
27748 return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
27750 - return !!(regs->cs & 3);
27751 + return !!(regs->cs & SEGMENT_RPL_MASK);
27755 -static inline int user_mode_vm(struct pt_regs *regs)
27756 +static inline int user_mode(struct pt_regs *regs)
27758 #ifdef CONFIG_X86_32
27759 return ((regs->cs & SEGMENT_RPL_MASK) |
27760 (regs->flags & VM_MASK)) >= USER_RPL;
27762 - return user_mode(regs);
27763 + return user_mode_novm(regs);
27767 diff -urNp linux-2.6.25.10/include/asm-x86/reboot.h linux-2.6.25.10/include/asm-x86/reboot.h
27768 --- linux-2.6.25.10/include/asm-x86/reboot.h 2008-07-02 23:46:47.000000000 -0400
27769 +++ linux-2.6.25.10/include/asm-x86/reboot.h 2008-07-03 16:53:26.000000000 -0400
27770 @@ -15,6 +15,6 @@ struct machine_ops
27772 extern struct machine_ops machine_ops;
27774 -void machine_real_restart(unsigned char *code, int length);
27775 +void machine_real_restart(const unsigned char *code, unsigned int length);
27777 #endif /* _ASM_REBOOT_H */
27778 diff -urNp linux-2.6.25.10/include/asm-x86/segment.h linux-2.6.25.10/include/asm-x86/segment.h
27779 --- linux-2.6.25.10/include/asm-x86/segment.h 2008-07-02 23:46:47.000000000 -0400
27780 +++ linux-2.6.25.10/include/asm-x86/segment.h 2008-07-03 16:53:26.000000000 -0400
27781 @@ -83,13 +83,19 @@
27782 #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
27783 #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
27785 -#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
27786 +#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
27788 #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
27790 #define __KERNEL_PERCPU 0
27793 +#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
27794 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
27796 +#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
27797 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
27799 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
27802 @@ -130,10 +136,10 @@
27803 #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
27805 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
27806 -#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
27807 +#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
27809 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
27810 -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
27811 +#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
27815 diff -urNp linux-2.6.25.10/include/asm-x86/system.h linux-2.6.25.10/include/asm-x86/system.h
27816 --- linux-2.6.25.10/include/asm-x86/system.h 2008-07-02 23:46:47.000000000 -0400
27817 +++ linux-2.6.25.10/include/asm-x86/system.h 2008-07-03 16:53:26.000000000 -0400
27818 @@ -70,6 +70,8 @@ struct task_struct *__switch_to(struct t
27819 ".globl thread_return\n" \
27820 "thread_return:\n\t" \
27821 "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
27822 + "movq %P[task_canary](%%rsi),%%r8\n\t" \
27823 + "movq %%r8,%%gs:%P[pda_canary]\n\t" \
27824 "movq %P[thread_info](%%rsi),%%r8\n\t" \
27825 LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
27826 "movq %%rax,%%rdi\n\t" \
27827 @@ -81,7 +83,9 @@ struct task_struct *__switch_to(struct t
27828 [ti_flags] "i" (offsetof(struct thread_info, flags)), \
27829 [tif_fork] "i" (TIF_FORK), \
27830 [thread_info] "i" (offsetof(struct task_struct, stack)), \
27831 - [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
27832 + [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
27833 + [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
27834 + [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
27835 : "memory", "cc" __EXTRA_CLOBBER)
27838 @@ -145,7 +149,7 @@ static inline unsigned long get_limit(un
27839 unsigned long __limit;
27840 __asm__("lsll %1,%0"
27841 :"=r" (__limit):"r" (segment));
27842 - return __limit+1;
27846 static inline void native_clts(void)
27847 @@ -269,6 +273,21 @@ static inline void native_wbinvd(void)
27849 #define stts() write_cr0(8 | read_cr0())
27851 +#define pax_open_kernel(cr0) \
27853 + typecheck(unsigned long, cr0); \
27854 + preempt_disable(); \
27855 + cr0 = read_cr0(); \
27856 + write_cr0(cr0 & ~X86_CR0_WP); \
27859 +#define pax_close_kernel(cr0) \
27861 + typecheck(unsigned long, cr0); \
27862 + write_cr0(cr0); \
27863 + preempt_enable_no_resched(); \
27866 #endif /* __KERNEL__ */
27868 static inline void clflush(volatile void *__p)
27869 @@ -284,7 +303,7 @@ void enable_hlt(void);
27870 extern int es7000_plat;
27871 void cpu_idle_wait(void);
27873 -extern unsigned long arch_align_stack(unsigned long sp);
27874 +#define arch_align_stack(x) (x)
27875 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
27877 void default_idle(void);
27878 diff -urNp linux-2.6.25.10/include/asm-x86/uaccess_32.h linux-2.6.25.10/include/asm-x86/uaccess_32.h
27879 --- linux-2.6.25.10/include/asm-x86/uaccess_32.h 2008-07-02 23:46:47.000000000 -0400
27880 +++ linux-2.6.25.10/include/asm-x86/uaccess_32.h 2008-07-03 16:53:26.000000000 -0400
27882 #include <linux/string.h>
27883 #include <asm/asm.h>
27884 #include <asm/page.h>
27885 +#include <asm/segment.h>
27887 #define VERIFY_READ 0
27888 #define VERIFY_WRITE 1
27891 #define get_ds() (KERNEL_DS)
27892 #define get_fs() (current_thread_info()->addr_limit)
27893 -#define set_fs(x) (current_thread_info()->addr_limit = (x))
27894 +void __set_fs(mm_segment_t x, int cpu);
27895 +void set_fs(mm_segment_t x);
27897 #define segment_eq(a,b) ((a).seg == (b).seg)
27899 @@ -102,6 +104,7 @@ struct exception_table_entry
27902 extern int fixup_exception(struct pt_regs *regs);
27903 +#define ARCH_HAS_SORT_EXTABLE
27906 * These are the main single-value transfer routines. They automatically
27907 @@ -281,9 +284,12 @@ extern void __put_user_8(void);
27909 #define __put_user_u64(x, addr, err) \
27910 __asm__ __volatile__( \
27911 - "1: movl %%eax,0(%2)\n" \
27912 - "2: movl %%edx,4(%2)\n" \
27913 + " movw %w5,%%ds\n" \
27914 + "1: movl %%eax,%%ds:0(%2)\n" \
27915 + "2: movl %%edx,%%ds:4(%2)\n" \
27917 + " pushl %%ss\n" \
27919 ".section .fixup,\"ax\"\n" \
27920 "4: movl %3,%0\n" \
27922 @@ -291,7 +297,8 @@ extern void __put_user_8(void);
27923 _ASM_EXTABLE(1b,4b) \
27924 _ASM_EXTABLE(2b,4b) \
27926 - : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
27927 + : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
27930 #ifdef CONFIG_X86_WP_WORKS_OK
27932 @@ -330,15 +337,19 @@ struct __large_struct { unsigned long bu
27934 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
27935 __asm__ __volatile__( \
27936 - "1: mov"itype" %"rtype"1,%2\n" \
27937 + " movw %w5,%%ds\n" \
27938 + "1: mov"itype" %"rtype"1,%%ds:%2\n" \
27940 + " pushl %%ss\n" \
27942 ".section .fixup,\"ax\"\n" \
27943 "3: movl %3,%0\n" \
27946 _ASM_EXTABLE(1b,3b) \
27948 - : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
27949 + : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
27953 #define __get_user_nocheck(x,ptr,size) \
27954 @@ -366,8 +377,11 @@ do { \
27956 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
27957 __asm__ __volatile__( \
27958 - "1: mov"itype" %2,%"rtype"1\n" \
27959 + " movw %w5,%%ds\n" \
27960 + "1: mov"itype" %%ds:%2,%"rtype"1\n" \
27962 + " pushl %%ss\n" \
27964 ".section .fixup,\"ax\"\n" \
27965 "3: movl %3,%0\n" \
27966 " xor"itype" %"rtype"1,%"rtype"1\n" \
27967 @@ -375,7 +389,7 @@ do { \
27969 _ASM_EXTABLE(1b,3b) \
27970 : "=r"(err), ltype (x) \
27971 - : "m"(__m(addr)), "i"(errret), "0"(err))
27972 + : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
27975 unsigned long __must_check __copy_to_user_ll(void __user *to,
27976 diff -urNp linux-2.6.25.10/include/asm-x86/uaccess_64.h linux-2.6.25.10/include/asm-x86/uaccess_64.h
27977 --- linux-2.6.25.10/include/asm-x86/uaccess_64.h 2008-07-02 23:46:47.000000000 -0400
27978 +++ linux-2.6.25.10/include/asm-x86/uaccess_64.h 2008-07-03 16:53:27.000000000 -0400
27979 @@ -68,6 +68,7 @@ struct exception_table_entry
27980 extern int fixup_exception(struct pt_regs *regs);
27982 #define ARCH_HAS_SEARCH_EXTABLE
27983 +#define ARCH_HAS_SORT_EXTABLE
27986 * These are the main single-value transfer routines. They automatically
27987 diff -urNp linux-2.6.25.10/include/asm-xtensa/kmap_types.h linux-2.6.25.10/include/asm-xtensa/kmap_types.h
27988 --- linux-2.6.25.10/include/asm-xtensa/kmap_types.h 2008-07-02 23:46:47.000000000 -0400
27989 +++ linux-2.6.25.10/include/asm-xtensa/kmap_types.h 2008-07-03 16:53:27.000000000 -0400
27990 @@ -25,6 +25,7 @@ enum km_type {
27998 diff -urNp linux-2.6.25.10/include/linux/a.out.h linux-2.6.25.10/include/linux/a.out.h
27999 --- linux-2.6.25.10/include/linux/a.out.h 2008-07-02 23:46:47.000000000 -0400
28000 +++ linux-2.6.25.10/include/linux/a.out.h 2008-07-03 16:53:27.000000000 -0400
28001 @@ -41,6 +41,14 @@ enum machine_type {
28002 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
28005 +/* Constants for the N_FLAGS field */
28006 +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
28007 +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
28008 +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
28009 +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
28010 +/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
28011 +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
28013 #if !defined (N_MAGIC)
28014 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
28016 diff -urNp linux-2.6.25.10/include/linux/binfmts.h linux-2.6.25.10/include/linux/binfmts.h
28017 --- linux-2.6.25.10/include/linux/binfmts.h 2008-07-02 23:46:47.000000000 -0400
28018 +++ linux-2.6.25.10/include/linux/binfmts.h 2008-07-03 16:53:27.000000000 -0400
28019 @@ -49,6 +49,7 @@ struct linux_binprm{
28020 unsigned interp_data;
28021 unsigned long loader, exec;
28022 unsigned long argv_len;
28026 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
28027 @@ -100,5 +101,8 @@ extern void compute_creds(struct linux_b
28028 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
28029 extern int set_binfmt(struct linux_binfmt *new);
28031 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
28032 +void pax_report_insns(void *pc, void *sp);
28034 #endif /* __KERNEL__ */
28035 #endif /* _LINUX_BINFMTS_H */
28036 diff -urNp linux-2.6.25.10/include/linux/cache.h linux-2.6.25.10/include/linux/cache.h
28037 --- linux-2.6.25.10/include/linux/cache.h 2008-07-02 23:46:47.000000000 -0400
28038 +++ linux-2.6.25.10/include/linux/cache.h 2008-07-03 16:53:27.000000000 -0400
28040 #define __read_mostly
28043 +#ifndef __read_only
28044 +#define __read_only __read_mostly
28047 #ifndef ____cacheline_aligned
28048 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
28050 diff -urNp linux-2.6.25.10/include/linux/capability.h linux-2.6.25.10/include/linux/capability.h
28051 --- linux-2.6.25.10/include/linux/capability.h 2008-07-02 23:46:47.000000000 -0400
28052 +++ linux-2.6.25.10/include/linux/capability.h 2008-07-03 16:53:27.000000000 -0400
28053 @@ -501,6 +501,7 @@ extern const kernel_cap_t __cap_full_set
28054 extern const kernel_cap_t __cap_init_eff_set;
28056 int capable(int cap);
28057 +int capable_nolog(int cap);
28058 int __capable(struct task_struct *t, int cap);
28060 extern long cap_prctl_drop(unsigned long cap);
28061 diff -urNp linux-2.6.25.10/include/linux/elf.h linux-2.6.25.10/include/linux/elf.h
28062 --- linux-2.6.25.10/include/linux/elf.h 2008-07-02 23:46:47.000000000 -0400
28063 +++ linux-2.6.25.10/include/linux/elf.h 2008-07-03 16:53:27.000000000 -0400
28068 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
28069 +#undef elf_read_implies_exec
28072 #ifndef elf_read_implies_exec
28073 /* Executables for which elf_read_implies_exec() returns TRUE will
28074 have the READ_IMPLIES_EXEC personality flag set automatically.
28075 @@ -50,6 +54,16 @@ typedef __s64 Elf64_Sxword;
28077 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
28079 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
28081 +/* Constants for the e_flags field */
28082 +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
28083 +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
28084 +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
28085 +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
28086 +/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
28087 +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
28089 /* These constants define the different elf file types */
28092 @@ -84,6 +98,8 @@ typedef __s64 Elf64_Sxword;
28093 #define DT_DEBUG 21
28094 #define DT_TEXTREL 22
28095 #define DT_JMPREL 23
28096 +#define DT_FLAGS 30
28097 + #define DF_TEXTREL 0x00000004
28098 #define DT_ENCODING 32
28099 #define OLD_DT_LOOS 0x60000000
28100 #define DT_LOOS 0x6000000d
28101 @@ -230,6 +246,19 @@ typedef struct elf64_hdr {
28105 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
28106 +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
28107 +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
28108 +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
28109 +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
28110 +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
28111 +/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
28112 +/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
28113 +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
28114 +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
28115 +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
28116 +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
28118 typedef struct elf32_phdr{
28120 Elf32_Off p_offset;
28121 @@ -322,6 +351,8 @@ typedef struct elf64_shdr {
28127 #define ELFMAG0 0x7f /* EI_MAG */
28128 #define ELFMAG1 'E'
28129 #define ELFMAG2 'L'
28130 @@ -382,6 +413,7 @@ extern Elf32_Dyn _DYNAMIC [];
28131 #define elf_phdr elf32_phdr
28132 #define elf_note elf32_note
28133 #define elf_addr_t Elf32_Off
28134 +#define elf_dyn Elf32_Dyn
28138 @@ -390,6 +422,7 @@ extern Elf64_Dyn _DYNAMIC [];
28139 #define elf_phdr elf64_phdr
28140 #define elf_note elf64_note
28141 #define elf_addr_t Elf64_Off
28142 +#define elf_dyn Elf64_Dyn
28146 diff -urNp linux-2.6.25.10/include/linux/ext4_fs_extents.h linux-2.6.25.10/include/linux/ext4_fs_extents.h
28147 --- linux-2.6.25.10/include/linux/ext4_fs_extents.h 2008-07-02 23:46:47.000000000 -0400
28148 +++ linux-2.6.25.10/include/linux/ext4_fs_extents.h 2008-07-03 16:53:27.000000000 -0400
28151 #define ext_debug(a...) printk(a)
28153 -#define ext_debug(a...)
28154 +#define ext_debug(a...) do {} while (0)
28158 diff -urNp linux-2.6.25.10/include/linux/gracl.h linux-2.6.25.10/include/linux/gracl.h
28159 --- linux-2.6.25.10/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
28160 +++ linux-2.6.25.10/include/linux/gracl.h 2008-07-03 16:53:27.000000000 -0400
28165 +#include <linux/grdefs.h>
28166 +#include <linux/resource.h>
28167 +#include <linux/capability.h>
28168 +#include <linux/dcache.h>
28169 +#include <asm/resource.h>
28171 +/* Major status information */
28173 +#define GR_VERSION "grsecurity 2.1.12"
28174 +#define GRSECURITY_VERSION 0x2112
28189 +/* Password setup definitions
28190 + * kernel/grhash.c */
28193 + GR_SALT_LEN = 16,
28198 + GR_SPROLE_LEN = 64,
28201 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
28203 +/* Begin Data Structures */
28205 +struct sprole_pw {
28206 + unsigned char *rolename;
28207 + unsigned char salt[GR_SALT_LEN];
28208 + unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
28211 +struct name_entry {
28218 + struct name_entry *prev;
28219 + struct name_entry *next;
28222 +struct inodev_entry {
28223 + struct name_entry *nentry;
28224 + struct inodev_entry *prev;
28225 + struct inodev_entry *next;
28228 +struct acl_role_db {
28229 + struct acl_role_label **r_hash;
28233 +struct inodev_db {
28234 + struct inodev_entry **i_hash;
28239 + struct name_entry **n_hash;
28243 +struct crash_uid {
28245 + unsigned long expires;
28248 +struct gr_hash_struct {
28250 + void **nametable;
28252 + __u32 table_size;
28257 +/* Userspace Grsecurity ACL data structures */
28259 +struct acl_subject_label {
28264 + kernel_cap_t cap_mask;
28265 + kernel_cap_t cap_lower;
28267 + struct rlimit res[GR_NLIMITS];
28270 + __u8 user_trans_type;
28271 + __u8 group_trans_type;
28272 + uid_t *user_transitions;
28273 + gid_t *group_transitions;
28274 + __u16 user_trans_num;
28275 + __u16 group_trans_num;
28277 + __u32 ip_proto[8];
28279 + struct acl_ip_label **ips;
28283 + unsigned long expires;
28285 + struct acl_subject_label *parent_subject;
28286 + struct gr_hash_struct *hash;
28287 + struct acl_subject_label *prev;
28288 + struct acl_subject_label *next;
28290 + struct acl_object_label **obj_hash;
28291 + __u32 obj_hash_size;
28295 +struct role_allowed_ip {
28299 + struct role_allowed_ip *prev;
28300 + struct role_allowed_ip *next;
28303 +struct role_transition {
28306 + struct role_transition *prev;
28307 + struct role_transition *next;
28310 +struct acl_role_label {
28315 + __u16 auth_attempts;
28316 + unsigned long expires;
28318 + struct acl_subject_label *root_label;
28319 + struct gr_hash_struct *hash;
28321 + struct acl_role_label *prev;
28322 + struct acl_role_label *next;
28324 + struct role_transition *transitions;
28325 + struct role_allowed_ip *allowed_ips;
28326 + uid_t *domain_children;
28327 + __u16 domain_child_num;
28329 + struct acl_subject_label **subj_hash;
28330 + __u32 subj_hash_size;
28333 +struct user_acl_role_db {
28334 + struct acl_role_label **r_table;
28335 + __u32 num_pointers; /* Number of allocations to track */
28336 + __u32 num_roles; /* Number of roles */
28337 + __u32 num_domain_children; /* Number of domain children */
28338 + __u32 num_subjects; /* Number of subjects */
28339 + __u32 num_objects; /* Number of objects */
28342 +struct acl_object_label {
28348 + struct acl_subject_label *nested;
28349 + struct acl_object_label *globbed;
28351 + /* next two structures not used */
28353 + struct acl_object_label *prev;
28354 + struct acl_object_label *next;
28357 +struct acl_ip_label {
28366 + /* next two structures not used */
28368 + struct acl_ip_label *prev;
28369 + struct acl_ip_label *next;
28373 + struct user_acl_role_db role_db;
28374 + unsigned char pw[GR_PW_LEN];
28375 + unsigned char salt[GR_SALT_LEN];
28376 + unsigned char sum[GR_SHA_LEN];
28377 + unsigned char sp_role[GR_SPROLE_LEN];
28378 + struct sprole_pw *sprole_pws;
28379 + dev_t segv_device;
28380 + ino_t segv_inode;
28382 + __u16 num_sprole_pws;
28386 +struct gr_arg_wrapper {
28387 + struct gr_arg *arg;
28392 +struct subject_map {
28393 + struct acl_subject_label *user;
28394 + struct acl_subject_label *kernel;
28395 + struct subject_map *prev;
28396 + struct subject_map *next;
28399 +struct acl_subj_map_db {
28400 + struct subject_map **s_hash;
28404 +/* End Data Structures Section */
28406 +/* Hash functions generated by empirical testing by Brad Spengler
28407 + Makes good use of the low bits of the inode. Generally 0-1 times
28408 + in loop for successful match. 0-3 for unsuccessful match.
28409 + Shift/add algorithm with modulus of table size and an XOR*/
28411 +static __inline__ unsigned int
28412 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
28414 + return (((uid << type) + (uid ^ type)) % sz);
28417 + static __inline__ unsigned int
28418 +shash(const struct acl_subject_label *userp, const unsigned int sz)
28420 + return ((const unsigned long)userp % sz);
28423 +static __inline__ unsigned int
28424 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
28426 + return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
28429 +static __inline__ unsigned int
28430 +nhash(const char *name, const __u16 len, const unsigned int sz)
28432 + return full_name_hash(name, len) % sz;
28435 +#define FOR_EACH_ROLE_START(role,iter) \
28438 + while (iter < acl_role_set.r_size) { \
28439 + if (role == NULL) \
28440 + role = acl_role_set.r_hash[iter]; \
28441 + if (role == NULL) { \
28446 +#define FOR_EACH_ROLE_END(role,iter) \
28447 + role = role->next; \
28448 + if (role == NULL) \
28452 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
28455 + while (iter < role->subj_hash_size) { \
28456 + if (subj == NULL) \
28457 + subj = role->subj_hash[iter]; \
28458 + if (subj == NULL) { \
28463 +#define FOR_EACH_SUBJECT_END(subj,iter) \
28464 + subj = subj->next; \
28465 + if (subj == NULL) \
28470 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
28471 + subj = role->hash->first; \
28472 + while (subj != NULL) {
28474 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
28475 + subj = subj->next; \
28480 diff -urNp linux-2.6.25.10/include/linux/gralloc.h linux-2.6.25.10/include/linux/gralloc.h
28481 --- linux-2.6.25.10/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
28482 +++ linux-2.6.25.10/include/linux/gralloc.h 2008-07-03 16:53:27.000000000 -0400
28484 +#ifndef __GRALLOC_H
28485 +#define __GRALLOC_H
28487 +void acl_free_all(void);
28488 +int acl_alloc_stack_init(unsigned long size);
28489 +void *acl_alloc(unsigned long len);
28492 diff -urNp linux-2.6.25.10/include/linux/grdefs.h linux-2.6.25.10/include/linux/grdefs.h
28493 --- linux-2.6.25.10/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
28494 +++ linux-2.6.25.10/include/linux/grdefs.h 2008-07-03 16:53:27.000000000 -0400
28499 +/* Begin grsecurity status declarations */
28503 + GR_STATUS_INIT = 0x00 // disabled state
28506 +/* Begin ACL declarations */
28511 + GR_ROLE_USER = 0x0001,
28512 + GR_ROLE_GROUP = 0x0002,
28513 + GR_ROLE_DEFAULT = 0x0004,
28514 + GR_ROLE_SPECIAL = 0x0008,
28515 + GR_ROLE_AUTH = 0x0010,
28516 + GR_ROLE_NOPW = 0x0020,
28517 + GR_ROLE_GOD = 0x0040,
28518 + GR_ROLE_LEARN = 0x0080,
28519 + GR_ROLE_TPE = 0x0100,
28520 + GR_ROLE_DOMAIN = 0x0200,
28521 + GR_ROLE_PAM = 0x0400
28524 +/* ACL Subject and Object mode flags */
28526 + GR_DELETED = 0x80000000
28529 +/* ACL Object-only mode flags */
28531 + GR_READ = 0x00000001,
28532 + GR_APPEND = 0x00000002,
28533 + GR_WRITE = 0x00000004,
28534 + GR_EXEC = 0x00000008,
28535 + GR_FIND = 0x00000010,
28536 + GR_INHERIT = 0x00000020,
28537 + GR_SETID = 0x00000040,
28538 + GR_CREATE = 0x00000080,
28539 + GR_DELETE = 0x00000100,
28540 + GR_LINK = 0x00000200,
28541 + GR_AUDIT_READ = 0x00000400,
28542 + GR_AUDIT_APPEND = 0x00000800,
28543 + GR_AUDIT_WRITE = 0x00001000,
28544 + GR_AUDIT_EXEC = 0x00002000,
28545 + GR_AUDIT_FIND = 0x00004000,
28546 + GR_AUDIT_INHERIT= 0x00008000,
28547 + GR_AUDIT_SETID = 0x00010000,
28548 + GR_AUDIT_CREATE = 0x00020000,
28549 + GR_AUDIT_DELETE = 0x00040000,
28550 + GR_AUDIT_LINK = 0x00080000,
28551 + GR_PTRACERD = 0x00100000,
28552 + GR_NOPTRACE = 0x00200000,
28553 + GR_SUPPRESS = 0x00400000,
28554 + GR_NOLEARN = 0x00800000
28557 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
28558 + GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
28559 + GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
28561 +/* ACL subject-only mode flags */
28563 + GR_KILL = 0x00000001,
28564 + GR_VIEW = 0x00000002,
28565 + GR_PROTECTED = 0x00000004,
28566 + GR_LEARN = 0x00000008,
28567 + GR_OVERRIDE = 0x00000010,
28568 + /* just a placeholder, this mode is only used in userspace */
28569 + GR_DUMMY = 0x00000020,
28570 + GR_PROTSHM = 0x00000040,
28571 + GR_KILLPROC = 0x00000080,
28572 + GR_KILLIPPROC = 0x00000100,
28573 + /* just a placeholder, this mode is only used in userspace */
28574 + GR_NOTROJAN = 0x00000200,
28575 + GR_PROTPROCFD = 0x00000400,
28576 + GR_PROCACCT = 0x00000800,
28577 + GR_RELAXPTRACE = 0x00001000,
28578 + GR_NESTED = 0x00002000,
28579 + GR_INHERITLEARN = 0x00004000,
28580 + GR_PROCFIND = 0x00008000,
28581 + GR_POVERRIDE = 0x00010000,
28582 + GR_KERNELAUTH = 0x00020000,
28586 + GR_PAX_ENABLE_SEGMEXEC = 0x0001,
28587 + GR_PAX_ENABLE_PAGEEXEC = 0x0002,
28588 + GR_PAX_ENABLE_MPROTECT = 0x0004,
28589 + GR_PAX_ENABLE_RANDMMAP = 0x0008,
28590 + GR_PAX_ENABLE_EMUTRAMP = 0x0010,
28591 + GR_PAX_DISABLE_SEGMEXEC = 0x0100,
28592 + GR_PAX_DISABLE_PAGEEXEC = 0x0200,
28593 + GR_PAX_DISABLE_MPROTECT = 0x0400,
28594 + GR_PAX_DISABLE_RANDMMAP = 0x0800,
28595 + GR_PAX_DISABLE_EMUTRAMP = 0x1000,
28599 + GR_ID_USER = 0x01,
28600 + GR_ID_GROUP = 0x02,
28604 + GR_ID_ALLOW = 0x01,
28605 + GR_ID_DENY = 0x02,
28608 +#define GR_CRASH_RES 11
28609 +#define GR_UIDTABLE_MAX 500
28611 +/* begin resource learning section */
28613 + GR_RLIM_CPU_BUMP = 60,
28614 + GR_RLIM_FSIZE_BUMP = 50000,
28615 + GR_RLIM_DATA_BUMP = 10000,
28616 + GR_RLIM_STACK_BUMP = 1000,
28617 + GR_RLIM_CORE_BUMP = 10000,
28618 + GR_RLIM_RSS_BUMP = 500000,
28619 + GR_RLIM_NPROC_BUMP = 1,
28620 + GR_RLIM_NOFILE_BUMP = 5,
28621 + GR_RLIM_MEMLOCK_BUMP = 50000,
28622 + GR_RLIM_AS_BUMP = 500000,
28623 + GR_RLIM_LOCKS_BUMP = 2
28627 diff -urNp linux-2.6.25.10/include/linux/grinternal.h linux-2.6.25.10/include/linux/grinternal.h
28628 --- linux-2.6.25.10/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
28629 +++ linux-2.6.25.10/include/linux/grinternal.h 2008-07-03 16:53:27.000000000 -0400
28631 +#ifndef __GRINTERNAL_H
28632 +#define __GRINTERNAL_H
28634 +#ifdef CONFIG_GRKERNSEC
28636 +#include <linux/fs.h>
28637 +#include <linux/gracl.h>
28638 +#include <linux/grdefs.h>
28639 +#include <linux/grmsg.h>
28641 +void gr_add_learn_entry(const char *fmt, ...);
28642 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
28643 + const struct vfsmount *mnt);
28644 +__u32 gr_check_create(const struct dentry *new_dentry,
28645 + const struct dentry *parent,
28646 + const struct vfsmount *mnt, const __u32 mode);
28647 +int gr_check_protected_task(const struct task_struct *task);
28648 +__u32 to_gr_audit(const __u32 reqmode);
28649 +int gr_set_acls(const int type);
28651 +int gr_acl_is_enabled(void);
28652 +char gr_roletype_to_char(void);
28654 +void gr_handle_alertkill(struct task_struct *task);
28655 +char *gr_to_filename(const struct dentry *dentry,
28656 + const struct vfsmount *mnt);
28657 +char *gr_to_filename1(const struct dentry *dentry,
28658 + const struct vfsmount *mnt);
28659 +char *gr_to_filename2(const struct dentry *dentry,
28660 + const struct vfsmount *mnt);
28661 +char *gr_to_filename3(const struct dentry *dentry,
28662 + const struct vfsmount *mnt);
28664 +extern int grsec_enable_link;
28665 +extern int grsec_enable_fifo;
28666 +extern int grsec_enable_execve;
28667 +extern int grsec_enable_shm;
28668 +extern int grsec_enable_execlog;
28669 +extern int grsec_enable_signal;
28670 +extern int grsec_enable_forkfail;
28671 +extern int grsec_enable_time;
28672 +extern int grsec_enable_chroot_shmat;
28673 +extern int grsec_enable_chroot_findtask;
28674 +extern int grsec_enable_chroot_mount;
28675 +extern int grsec_enable_chroot_double;
28676 +extern int grsec_enable_chroot_pivot;
28677 +extern int grsec_enable_chroot_chdir;
28678 +extern int grsec_enable_chroot_chmod;
28679 +extern int grsec_enable_chroot_mknod;
28680 +extern int grsec_enable_chroot_fchdir;
28681 +extern int grsec_enable_chroot_nice;
28682 +extern int grsec_enable_chroot_execlog;
28683 +extern int grsec_enable_chroot_caps;
28684 +extern int grsec_enable_chroot_sysctl;
28685 +extern int grsec_enable_chroot_unix;
28686 +extern int grsec_enable_tpe;
28687 +extern int grsec_tpe_gid;
28688 +extern int grsec_enable_tpe_all;
28689 +extern int grsec_enable_sidcaps;
28690 +extern int grsec_enable_socket_all;
28691 +extern int grsec_socket_all_gid;
28692 +extern int grsec_enable_socket_client;
28693 +extern int grsec_socket_client_gid;
28694 +extern int grsec_enable_socket_server;
28695 +extern int grsec_socket_server_gid;
28696 +extern int grsec_audit_gid;
28697 +extern int grsec_enable_group;
28698 +extern int grsec_enable_audit_ipc;
28699 +extern int grsec_enable_audit_textrel;
28700 +extern int grsec_enable_mount;
28701 +extern int grsec_enable_chdir;
28702 +extern int grsec_resource_logging;
28703 +extern int grsec_lock;
28705 +extern spinlock_t grsec_alert_lock;
28706 +extern unsigned long grsec_alert_wtime;
28707 +extern unsigned long grsec_alert_fyet;
28709 +extern spinlock_t grsec_audit_lock;
28711 +extern rwlock_t grsec_exec_file_lock;
28713 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
28714 + gr_to_filename2(tsk->exec_file->f_path.dentry, \
28715 + tsk->exec_file->f_vfsmnt) : "/")
28717 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
28718 + gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
28719 + tsk->parent->exec_file->f_vfsmnt) : "/")
28721 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
28722 + gr_to_filename(tsk->exec_file->f_path.dentry, \
28723 + tsk->exec_file->f_vfsmnt) : "/")
28725 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
28726 + gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
28727 + tsk->parent->exec_file->f_vfsmnt) : "/")
28729 +#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
28730 + ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
28731 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
28732 + (tsk_a->fs->root.dentry->d_inode->i_ino != \
28733 + tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
28735 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
28736 + (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
28737 + tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
28738 + (tsk_a->fs->root.dentry->d_inode->i_ino == \
28739 + tsk_b->fs->root.dentry->d_inode->i_ino))
28741 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
28742 + task->pid, task->uid, \
28743 + task->euid, task->gid, task->egid, \
28744 + gr_parent_task_fullpath(task), \
28745 + task->parent->comm, task->parent->pid, \
28746 + task->parent->uid, task->parent->euid, \
28747 + task->parent->gid, task->parent->egid
28749 +#define GR_CHROOT_CAPS {{ \
28750 + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
28751 + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
28752 + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
28753 + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
28754 + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
28755 + CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
28757 +#define security_learn(normal_msg,args...) \
28759 + read_lock(&grsec_exec_file_lock); \
28760 + gr_add_learn_entry(normal_msg "\n", ## args); \
28761 + read_unlock(&grsec_exec_file_lock); \
28767 + GR_DONT_AUDIT_GOOD
28778 + GR_SYSCTL_HIDDEN,
28781 + GR_ONE_INT_TWO_STR,
28786 + GR_FIVE_INT_TWO_STR,
28792 + GR_FILENAME_TWO_INT,
28793 + GR_FILENAME_TWO_INT_STR,
28804 +#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
28805 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
28806 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
28807 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
28808 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
28809 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
28810 +#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)
28811 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
28812 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
28813 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
28814 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
28815 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
28816 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
28817 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
28818 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
28819 +#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)
28820 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
28821 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
28822 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
28823 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
28824 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
28825 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
28826 +#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)
28827 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
28828 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
28829 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
28830 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
28831 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
28832 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
28833 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
28834 +#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)
28836 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
28841 diff -urNp linux-2.6.25.10/include/linux/grmsg.h linux-2.6.25.10/include/linux/grmsg.h
28842 --- linux-2.6.25.10/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
28843 +++ linux-2.6.25.10/include/linux/grmsg.h 2008-07-03 16:53:27.000000000 -0400
28845 +#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"
28846 +#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"
28847 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
28848 +#define GR_STOPMOD_MSG "denied modification of module state by "
28849 +#define GR_IOPERM_MSG "denied use of ioperm() by "
28850 +#define GR_IOPL_MSG "denied use of iopl() by "
28851 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
28852 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
28853 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
28854 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
28855 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
28856 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
28857 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
28858 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
28859 +#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"
28860 +#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"
28861 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
28862 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
28863 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
28864 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
28865 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
28866 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
28867 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
28868 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
28869 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
28870 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
28871 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
28872 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
28873 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
28874 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
28875 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
28876 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
28877 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
28878 +#define GR_NPROC_MSG "denied overstep of process limit by "
28879 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
28880 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
28881 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
28882 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
28883 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
28884 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
28885 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
28886 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
28887 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
28888 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
28889 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
28890 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
28891 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
28892 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
28893 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
28894 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
28895 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
28896 +#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"
28897 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
28898 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
28899 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
28900 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
28901 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
28902 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
28903 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
28904 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
28905 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
28906 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
28907 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
28908 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
28909 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
28910 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
28911 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
28912 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
28913 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
28914 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
28915 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
28916 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
28917 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
28918 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
28919 +#define GR_NICE_CHROOT_MSG "denied priority change by "
28920 +#define GR_UNISIGLOG_MSG "signal %d sent to "
28921 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
28922 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
28923 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
28924 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
28925 +#define GR_TIME_MSG "time set by "
28926 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
28927 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
28928 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
28929 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
28930 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
28931 +#define GR_BIND_MSG "denied bind() by "
28932 +#define GR_CONNECT_MSG "denied connect() by "
28933 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
28934 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
28935 +#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"
28936 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
28937 +#define GR_CAP_ACL_MSG "use of %s denied for "
28938 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
28939 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
28940 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
28941 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
28942 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
28943 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
28944 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
28945 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
28946 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
28947 +#define GR_SEM_AUDIT_MSG "semaphore created by "
28948 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
28949 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
28950 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
28951 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
28952 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
28953 diff -urNp linux-2.6.25.10/include/linux/grsecurity.h linux-2.6.25.10/include/linux/grsecurity.h
28954 --- linux-2.6.25.10/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
28955 +++ linux-2.6.25.10/include/linux/grsecurity.h 2008-07-03 16:53:27.000000000 -0400
28957 +#ifndef GR_SECURITY_H
28958 +#define GR_SECURITY_H
28959 +#include <linux/fs.h>
28960 +#include <linux/binfmts.h>
28961 +#include <linux/gracl.h>
28963 +/* notify of brain-dead configs */
28964 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
28965 +#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
28967 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
28968 +#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
28970 +#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
28971 +#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
28973 +#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
28974 +#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
28976 +#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
28977 +#error "CONFIG_PAX enabled, but no PaX options are enabled."
28980 +void gr_handle_brute_attach(struct task_struct *p);
28981 +void gr_handle_brute_check(void);
28983 +char gr_roletype_to_char(void);
28985 +int gr_check_user_change(int real, int effective, int fs);
28986 +int gr_check_group_change(int real, int effective, int fs);
28988 +void gr_del_task_from_ip_table(struct task_struct *p);
28990 +int gr_pid_is_chrooted(struct task_struct *p);
28991 +int gr_handle_chroot_nice(void);
28992 +int gr_handle_chroot_sysctl(const int op);
28993 +int gr_handle_chroot_setpriority(struct task_struct *p,
28994 + const int niceval);
28995 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
28996 +int gr_handle_chroot_chroot(const struct dentry *dentry,
28997 + const struct vfsmount *mnt);
28998 +void gr_handle_chroot_caps(struct task_struct *task);
28999 +void gr_handle_chroot_chdir(struct path *path);
29000 +int gr_handle_chroot_chmod(const struct dentry *dentry,
29001 + const struct vfsmount *mnt, const int mode);
29002 +int gr_handle_chroot_mknod(const struct dentry *dentry,
29003 + const struct vfsmount *mnt, const int mode);
29004 +int gr_handle_chroot_mount(const struct dentry *dentry,
29005 + const struct vfsmount *mnt,
29006 + const char *dev_name);
29007 +int gr_handle_chroot_pivot(void);
29008 +int gr_handle_chroot_unix(const pid_t pid);
29010 +int gr_handle_rawio(const struct inode *inode);
29011 +int gr_handle_nproc(void);
29013 +void gr_handle_ioperm(void);
29014 +void gr_handle_iopl(void);
29016 +int gr_tpe_allow(const struct file *file);
29018 +int gr_random_pid(void);
29020 +void gr_log_forkfail(const int retval);
29021 +void gr_log_timechange(void);
29022 +void gr_log_signal(const int sig, const struct task_struct *t);
29023 +void gr_log_chdir(const struct dentry *dentry,
29024 + const struct vfsmount *mnt);
29025 +void gr_log_chroot_exec(const struct dentry *dentry,
29026 + const struct vfsmount *mnt);
29027 +void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
29028 +void gr_log_remount(const char *devname, const int retval);
29029 +void gr_log_unmount(const char *devname, const int retval);
29030 +void gr_log_mount(const char *from, const char *to, const int retval);
29031 +void gr_log_msgget(const int ret, const int msgflg);
29032 +void gr_log_msgrm(const uid_t uid, const uid_t cuid);
29033 +void gr_log_semget(const int err, const int semflg);
29034 +void gr_log_semrm(const uid_t uid, const uid_t cuid);
29035 +void gr_log_shmget(const int err, const int shmflg, const size_t size);
29036 +void gr_log_shmrm(const uid_t uid, const uid_t cuid);
29037 +void gr_log_textrel(struct vm_area_struct *vma);
29039 +int gr_handle_follow_link(const struct inode *parent,
29040 + const struct inode *inode,
29041 + const struct dentry *dentry,
29042 + const struct vfsmount *mnt);
29043 +int gr_handle_fifo(const struct dentry *dentry,
29044 + const struct vfsmount *mnt,
29045 + const struct dentry *dir, const int flag,
29046 + const int acc_mode);
29047 +int gr_handle_hardlink(const struct dentry *dentry,
29048 + const struct vfsmount *mnt,
29049 + struct inode *inode,
29050 + const int mode, const char *to);
29052 +int gr_task_is_capable(struct task_struct *task, const int cap);
29053 +int gr_is_capable_nolog(const int cap);
29054 +void gr_learn_resource(const struct task_struct *task, const int limit,
29055 + const unsigned long wanted, const int gt);
29056 +void gr_copy_label(struct task_struct *tsk);
29057 +void gr_handle_crash(struct task_struct *task, const int sig);
29058 +int gr_handle_signal(const struct task_struct *p, const int sig);
29059 +int gr_check_crash_uid(const uid_t uid);
29060 +int gr_check_protected_task(const struct task_struct *task);
29061 +int gr_acl_handle_mmap(const struct file *file,
29062 + const unsigned long prot);
29063 +int gr_acl_handle_mprotect(const struct file *file,
29064 + const unsigned long prot);
29065 +int gr_check_hidden_task(const struct task_struct *tsk);
29066 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
29067 + const struct vfsmount *mnt);
29068 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
29069 + const struct vfsmount *mnt);
29070 +__u32 gr_acl_handle_access(const struct dentry *dentry,
29071 + const struct vfsmount *mnt, const int fmode);
29072 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
29073 + const struct vfsmount *mnt, mode_t mode);
29074 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
29075 + const struct vfsmount *mnt, mode_t mode);
29076 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
29077 + const struct vfsmount *mnt);
29078 +int gr_handle_ptrace(struct task_struct *task, const long request);
29079 +int gr_handle_proc_ptrace(struct task_struct *task);
29080 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
29081 + const struct vfsmount *mnt);
29082 +int gr_check_crash_exec(const struct file *filp);
29083 +int gr_acl_is_enabled(void);
29084 +void gr_set_kernel_label(struct task_struct *task);
29085 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
29086 + const gid_t gid);
29087 +int gr_set_proc_label(const struct dentry *dentry,
29088 + const struct vfsmount *mnt);
29089 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
29090 + const struct vfsmount *mnt);
29091 +__u32 gr_acl_handle_open(const struct dentry *dentry,
29092 + const struct vfsmount *mnt, const int fmode);
29093 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
29094 + const struct dentry *p_dentry,
29095 + const struct vfsmount *p_mnt, const int fmode,
29096 + const int imode);
29097 +void gr_handle_create(const struct dentry *dentry,
29098 + const struct vfsmount *mnt);
29099 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
29100 + const struct dentry *parent_dentry,
29101 + const struct vfsmount *parent_mnt,
29103 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
29104 + const struct dentry *parent_dentry,
29105 + const struct vfsmount *parent_mnt);
29106 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
29107 + const struct vfsmount *mnt);
29108 +void gr_handle_delete(const ino_t ino, const dev_t dev);
29109 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
29110 + const struct vfsmount *mnt);
29111 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
29112 + const struct dentry *parent_dentry,
29113 + const struct vfsmount *parent_mnt,
29114 + const char *from);
29115 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
29116 + const struct dentry *parent_dentry,
29117 + const struct vfsmount *parent_mnt,
29118 + const struct dentry *old_dentry,
29119 + const struct vfsmount *old_mnt, const char *to);
29120 +int gr_acl_handle_rename(struct dentry *new_dentry,
29121 + struct dentry *parent_dentry,
29122 + const struct vfsmount *parent_mnt,
29123 + struct dentry *old_dentry,
29124 + struct inode *old_parent_inode,
29125 + struct vfsmount *old_mnt, const char *newname);
29126 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
29127 + struct dentry *old_dentry,
29128 + struct dentry *new_dentry,
29129 + struct vfsmount *mnt, const __u8 replace);
29130 +__u32 gr_check_link(const struct dentry *new_dentry,
29131 + const struct dentry *parent_dentry,
29132 + const struct vfsmount *parent_mnt,
29133 + const struct dentry *old_dentry,
29134 + const struct vfsmount *old_mnt);
29135 +int gr_acl_handle_filldir(const struct file *file, const char *name,
29136 + const unsigned int namelen, const ino_t ino);
29138 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
29139 + const struct vfsmount *mnt);
29140 +void gr_acl_handle_exit(void);
29141 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
29142 +int gr_acl_handle_procpidmem(const struct task_struct *task);
29144 +#ifdef CONFIG_GRKERNSEC
29145 +void gr_handle_mem_write(void);
29146 +void gr_handle_kmem_write(void);
29147 +void gr_handle_open_port(void);
29148 +int gr_handle_mem_mmap(const unsigned long offset,
29149 + struct vm_area_struct *vma);
29151 +extern int grsec_enable_dmesg;
29152 +extern int grsec_enable_randsrc;
29153 +extern int grsec_enable_shm;
29157 diff -urNp linux-2.6.25.10/include/linux/highmem.h linux-2.6.25.10/include/linux/highmem.h
29158 --- linux-2.6.25.10/include/linux/highmem.h 2008-07-02 23:46:47.000000000 -0400
29159 +++ linux-2.6.25.10/include/linux/highmem.h 2008-07-03 16:53:27.000000000 -0400
29160 @@ -122,6 +122,13 @@ static inline void clear_highpage(struct
29161 kunmap_atomic(kaddr, KM_USER0);
29164 +static inline void sanitize_highpage(struct page *page)
29166 + void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
29167 + clear_page(kaddr);
29168 + kunmap_atomic(kaddr, KM_CLEARPAGE);
29171 static inline void zero_user_segments(struct page *page,
29172 unsigned start1, unsigned end1,
29173 unsigned start2, unsigned end2)
29174 diff -urNp linux-2.6.25.10/include/linux/irqflags.h linux-2.6.25.10/include/linux/irqflags.h
29175 --- linux-2.6.25.10/include/linux/irqflags.h 2008-07-02 23:46:47.000000000 -0400
29176 +++ linux-2.6.25.10/include/linux/irqflags.h 2008-07-03 16:53:27.000000000 -0400
29177 @@ -84,10 +84,10 @@
29179 #define irqs_disabled() \
29181 - unsigned long flags; \
29182 + unsigned long __flags; \
29184 - raw_local_save_flags(flags); \
29185 - raw_irqs_disabled_flags(flags); \
29186 + raw_local_save_flags(__flags); \
29187 + raw_irqs_disabled_flags(__flags); \
29190 #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
29191 diff -urNp linux-2.6.25.10/include/linux/jbd2.h linux-2.6.25.10/include/linux/jbd2.h
29192 --- linux-2.6.25.10/include/linux/jbd2.h 2008-07-02 23:46:47.000000000 -0400
29193 +++ linux-2.6.25.10/include/linux/jbd2.h 2008-07-03 16:53:27.000000000 -0400
29194 @@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug;
29198 -#define jbd_debug(f, a...) /**/
29199 +#define jbd_debug(f, a...) do {} while (0)
29202 static inline void *jbd2_alloc(size_t size, gfp_t flags)
29203 diff -urNp linux-2.6.25.10/include/linux/jbd.h linux-2.6.25.10/include/linux/jbd.h
29204 --- linux-2.6.25.10/include/linux/jbd.h 2008-07-02 23:46:47.000000000 -0400
29205 +++ linux-2.6.25.10/include/linux/jbd.h 2008-07-03 16:53:27.000000000 -0400
29206 @@ -68,7 +68,7 @@ extern u8 journal_enable_debug;
29210 -#define jbd_debug(f, a...) /**/
29211 +#define jbd_debug(f, a...) do {} while (0)
29214 static inline void *jbd_alloc(size_t size, gfp_t flags)
29215 diff -urNp linux-2.6.25.10/include/linux/libata.h linux-2.6.25.10/include/linux/libata.h
29216 --- linux-2.6.25.10/include/linux/libata.h 2008-07-02 23:46:47.000000000 -0400
29217 +++ linux-2.6.25.10/include/linux/libata.h 2008-07-03 16:53:27.000000000 -0400
29218 @@ -63,11 +63,11 @@
29219 #ifdef ATA_VERBOSE_DEBUG
29220 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
29222 -#define VPRINTK(fmt, args...)
29223 +#define VPRINTK(fmt, args...) do {} while (0)
29224 #endif /* ATA_VERBOSE_DEBUG */
29226 -#define DPRINTK(fmt, args...)
29227 -#define VPRINTK(fmt, args...)
29228 +#define DPRINTK(fmt, args...) do {} while (0)
29229 +#define VPRINTK(fmt, args...) do {} while (0)
29230 #endif /* ATA_DEBUG */
29232 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
29233 diff -urNp linux-2.6.25.10/include/linux/mm.h linux-2.6.25.10/include/linux/mm.h
29234 --- linux-2.6.25.10/include/linux/mm.h 2008-07-02 23:46:47.000000000 -0400
29235 +++ linux-2.6.25.10/include/linux/mm.h 2008-07-03 16:53:27.000000000 -0400
29236 @@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
29237 #include <asm/page.h>
29238 #include <asm/pgtable.h>
29239 #include <asm/processor.h>
29240 +#include <asm/mman.h>
29242 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
29244 @@ -108,6 +109,14 @@ extern unsigned int kobjsize(const void
29246 #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
29248 +#ifdef CONFIG_PAX_PAGEEXEC
29249 +#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */
29252 +#ifdef CONFIG_PAX_MPROTECT
29253 +#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */
29256 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
29257 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
29259 @@ -836,6 +845,8 @@ struct shrinker {
29260 extern void register_shrinker(struct shrinker *);
29261 extern void unregister_shrinker(struct shrinker *);
29263 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
29265 int vma_wants_writenotify(struct vm_area_struct *vma);
29267 extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
29268 @@ -1074,6 +1085,7 @@ out:
29271 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
29272 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
29274 extern unsigned long do_brk(unsigned long, unsigned long);
29276 @@ -1126,6 +1138,10 @@ extern struct vm_area_struct * find_vma(
29277 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
29278 struct vm_area_struct **pprev);
29280 +extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
29281 +extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
29282 +extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
29284 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
29285 NULL if none. Assume start_addr < end_addr. */
29286 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
29287 @@ -1142,7 +1158,6 @@ static inline unsigned long vma_pages(st
29288 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
29291 -pgprot_t vm_get_page_prot(unsigned long vm_flags);
29292 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
29293 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
29294 unsigned long pfn, unsigned long size, pgprot_t);
29295 @@ -1230,5 +1245,11 @@ int vmemmap_populate_basepages(struct pa
29296 unsigned long pages, int node);
29297 int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
29299 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
29300 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
29302 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
29305 #endif /* __KERNEL__ */
29306 #endif /* _LINUX_MM_H */
29307 diff -urNp linux-2.6.25.10/include/linux/mm_types.h linux-2.6.25.10/include/linux/mm_types.h
29308 --- linux-2.6.25.10/include/linux/mm_types.h 2008-07-02 23:46:47.000000000 -0400
29309 +++ linux-2.6.25.10/include/linux/mm_types.h 2008-07-03 16:53:27.000000000 -0400
29310 @@ -154,6 +154,8 @@ struct vm_area_struct {
29312 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
29315 + struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
29319 @@ -225,6 +227,24 @@ struct mm_struct {
29320 #ifdef CONFIG_CGROUP_MEM_RES_CTLR
29321 struct mem_cgroup *mem_cgroup;
29324 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
29325 + unsigned long pax_flags;
29328 +#ifdef CONFIG_PAX_DLRESOLVE
29329 + unsigned long call_dl_resolve;
29332 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
29333 + unsigned long call_syscall;
29336 +#ifdef CONFIG_PAX_ASLR
29337 + unsigned long delta_mmap; /* randomized offset */
29338 + unsigned long delta_stack; /* randomized offset */
29343 #endif /* _LINUX_MM_TYPES_H */
29344 diff -urNp linux-2.6.25.10/include/linux/module.h linux-2.6.25.10/include/linux/module.h
29345 --- linux-2.6.25.10/include/linux/module.h 2008-07-02 23:46:47.000000000 -0400
29346 +++ linux-2.6.25.10/include/linux/module.h 2008-07-03 16:53:27.000000000 -0400
29347 @@ -296,16 +296,16 @@ struct module
29350 /* If this is non-NULL, vfree after init() returns */
29351 - void *module_init;
29352 + void *module_init_rx, *module_init_rw;
29354 /* Here is the actual code + data, vfree'd on unload. */
29355 - void *module_core;
29356 + void *module_core_rx, *module_core_rw;
29358 /* Here are the sizes of the init and core sections */
29359 - unsigned long init_size, core_size;
29360 + unsigned long init_size_rw, core_size_rw;
29362 /* The size of the executable code in each section. */
29363 - unsigned long init_text_size, core_text_size;
29364 + unsigned long init_size_rx, core_size_rx;
29366 /* The handle returned from unwind_add_table. */
29368 diff -urNp linux-2.6.25.10/include/linux/moduleloader.h linux-2.6.25.10/include/linux/moduleloader.h
29369 --- linux-2.6.25.10/include/linux/moduleloader.h 2008-07-02 23:46:47.000000000 -0400
29370 +++ linux-2.6.25.10/include/linux/moduleloader.h 2008-07-03 16:53:27.000000000 -0400
29371 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
29372 sections. Returns NULL on failure. */
29373 void *module_alloc(unsigned long size);
29375 +#ifdef CONFIG_PAX_KERNEXEC
29376 +void *module_alloc_exec(unsigned long size);
29378 +#define module_alloc_exec(x) module_alloc(x)
29381 /* Free memory returned from module_alloc. */
29382 void module_free(struct module *mod, void *module_region);
29384 +#ifdef CONFIG_PAX_KERNEXEC
29385 +void module_free_exec(struct module *mod, void *module_region);
29387 +#define module_free_exec(x, y) module_free(x, y)
29390 /* Apply the given relocation to the (simplified) ELF. Return -error
29392 int apply_relocate(Elf_Shdr *sechdrs,
29393 diff -urNp linux-2.6.25.10/include/linux/namei.h linux-2.6.25.10/include/linux/namei.h
29394 --- linux-2.6.25.10/include/linux/namei.h 2008-07-02 23:46:47.000000000 -0400
29395 +++ linux-2.6.25.10/include/linux/namei.h 2008-07-03 16:53:27.000000000 -0400
29396 @@ -21,7 +21,7 @@ struct nameidata {
29397 unsigned int flags;
29400 - char *saved_names[MAX_NESTED_LINKS + 1];
29401 + const char *saved_names[MAX_NESTED_LINKS + 1];
29405 @@ -83,12 +83,12 @@ extern int follow_up(struct vfsmount **,
29406 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
29407 extern void unlock_rename(struct dentry *, struct dentry *);
29409 -static inline void nd_set_link(struct nameidata *nd, char *path)
29410 +static inline void nd_set_link(struct nameidata *nd, const char *path)
29412 nd->saved_names[nd->depth] = path;
29415 -static inline char *nd_get_link(struct nameidata *nd)
29416 +static inline const char *nd_get_link(struct nameidata *nd)
29418 return nd->saved_names[nd->depth];
29420 diff -urNp linux-2.6.25.10/include/linux/percpu.h linux-2.6.25.10/include/linux/percpu.h
29421 --- linux-2.6.25.10/include/linux/percpu.h 2008-07-02 23:46:47.000000000 -0400
29422 +++ linux-2.6.25.10/include/linux/percpu.h 2008-07-03 16:53:27.000000000 -0400
29426 #define PERCPU_ENOUGH_ROOM \
29427 - (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
29428 + ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
29429 #endif /* PERCPU_ENOUGH_ROOM */
29432 diff -urNp linux-2.6.25.10/include/linux/poison.h linux-2.6.25.10/include/linux/poison.h
29433 --- linux-2.6.25.10/include/linux/poison.h 2008-07-02 23:46:47.000000000 -0400
29434 +++ linux-2.6.25.10/include/linux/poison.h 2008-07-03 16:53:27.000000000 -0400
29436 * under normal circumstances, used to verify that nobody uses
29437 * non-initialized list entries.
29439 -#define LIST_POISON1 ((void *) 0x00100100)
29440 -#define LIST_POISON2 ((void *) 0x00200200)
29441 +#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
29442 +#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
29444 /********** mm/slab.c **********/
29446 diff -urNp linux-2.6.25.10/include/linux/random.h linux-2.6.25.10/include/linux/random.h
29447 --- linux-2.6.25.10/include/linux/random.h 2008-07-02 23:46:47.000000000 -0400
29448 +++ linux-2.6.25.10/include/linux/random.h 2008-07-03 16:53:27.000000000 -0400
29449 @@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
29450 u32 random32(void);
29451 void srandom32(u32 seed);
29453 +static inline unsigned long pax_get_random_long(void)
29455 + return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
29458 #endif /* __KERNEL___ */
29460 #endif /* _LINUX_RANDOM_H */
29461 diff -urNp linux-2.6.25.10/include/linux/sched.h linux-2.6.25.10/include/linux/sched.h
29462 --- linux-2.6.25.10/include/linux/sched.h 2008-07-02 23:46:47.000000000 -0400
29463 +++ linux-2.6.25.10/include/linux/sched.h 2008-07-03 16:53:27.000000000 -0400
29464 @@ -97,6 +97,7 @@ struct exec_domain;
29465 struct futex_pi_state;
29466 struct robust_list_head;
29468 +struct linux_binprm;
29471 * List of flags we want to share for kernel threads,
29472 @@ -542,6 +543,15 @@ struct signal_struct {
29473 unsigned audit_tty;
29474 struct tty_audit_buf *tty_audit_buf;
29477 +#ifdef CONFIG_GRKERNSEC
29483 + u8 used_accept:1;
29487 /* Context switch must be unlocked if interrupts are to be enabled */
29488 @@ -993,7 +1003,7 @@ struct sched_rt_entity {
29490 struct task_struct {
29491 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
29493 + struct thread_info *stack;
29495 unsigned int flags; /* per process flags, defined below */
29496 unsigned int ptrace;
29497 @@ -1063,10 +1073,9 @@ struct task_struct {
29501 -#ifdef CONFIG_CC_STACKPROTECTOR
29502 /* Canary value for the -fstack-protector gcc feature */
29503 unsigned long stack_canary;
29507 * pointers to (original) parent process, youngest child, younger sibling,
29508 * older sibling, respectively. (p->father can be replaced with
29509 @@ -1087,8 +1096,8 @@ struct task_struct {
29510 struct list_head thread_group;
29512 struct completion *vfork_done; /* for vfork() */
29513 - int __user *set_child_tid; /* CLONE_CHILD_SETTID */
29514 - int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
29515 + pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
29516 + pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
29518 unsigned int rt_priority;
29519 cputime_t utime, stime, utimescaled, stimescaled;
29520 @@ -1271,8 +1280,60 @@ struct task_struct {
29521 int latency_record_count;
29522 struct latency_record latency_record[LT_SAVECOUNT];
29525 +#ifdef CONFIG_GRKERNSEC
29527 + struct acl_subject_label *acl;
29528 + struct acl_role_label *role;
29529 + struct file *exec_file;
29538 +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
29539 +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
29540 +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
29541 +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
29542 +/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
29543 +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
29545 +#ifdef CONFIG_PAX_SOFTMODE
29546 +extern unsigned int pax_softmode;
29549 +extern int pax_check_flags(unsigned long *);
29551 +/* if tsk != current then task_lock must be held on it */
29552 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
29553 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
29555 + if (likely(tsk->mm))
29556 + return tsk->mm->pax_flags;
29561 +/* if tsk != current then task_lock must be held on it */
29562 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
29564 + if (likely(tsk->mm)) {
29565 + tsk->mm->pax_flags = flags;
29572 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
29573 +extern void pax_set_initial_flags(struct linux_binprm *bprm);
29574 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
29575 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
29579 * Priority of a process goes from 0..MAX_PRIO-1, valid RT
29580 * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
29581 @@ -1775,7 +1836,7 @@ extern void __cleanup_signal(struct sign
29582 extern void __cleanup_sighand(struct sighand_struct *);
29583 extern void exit_itimers(struct signal_struct *);
29585 -extern NORET_TYPE void do_group_exit(int);
29586 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
29588 extern void daemonize(const char *, ...);
29589 extern int allow_signal(int);
29590 @@ -1877,8 +1938,8 @@ static inline void unlock_task_sighand(s
29592 #ifndef __HAVE_THREAD_FUNCTIONS
29594 -#define task_thread_info(task) ((struct thread_info *)(task)->stack)
29595 -#define task_stack_page(task) ((task)->stack)
29596 +#define task_thread_info(task) ((task)->stack)
29597 +#define task_stack_page(task) ((void *)(task)->stack)
29599 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
29601 @@ -2026,6 +2087,12 @@ extern void arch_pick_mmap_layout(struct
29602 static inline void arch_pick_mmap_layout(struct mm_struct *mm)
29604 mm->mmap_base = TASK_UNMAPPED_BASE;
29606 +#ifdef CONFIG_PAX_RANDMMAP
29607 + if (mm->pax_flags & MF_PAX_RANDMMAP)
29608 + mm->mmap_base += mm->delta_mmap;
29611 mm->get_unmapped_area = arch_get_unmapped_area;
29612 mm->unmap_area = arch_unmap_area;
29614 diff -urNp linux-2.6.25.10/include/linux/screen_info.h linux-2.6.25.10/include/linux/screen_info.h
29615 --- linux-2.6.25.10/include/linux/screen_info.h 2008-07-02 23:46:47.000000000 -0400
29616 +++ linux-2.6.25.10/include/linux/screen_info.h 2008-07-03 16:53:27.000000000 -0400
29617 @@ -42,7 +42,8 @@ struct screen_info {
29618 __u16 pages; /* 0x32 */
29619 __u16 vesa_attributes; /* 0x34 */
29620 __u32 capabilities; /* 0x36 */
29621 - __u8 _reserved[6]; /* 0x3a */
29622 + __u16 vesapm_size; /* 0x3a */
29623 + __u8 _reserved[4]; /* 0x3c */
29624 } __attribute__((packed));
29626 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
29627 diff -urNp linux-2.6.25.10/include/linux/shm.h linux-2.6.25.10/include/linux/shm.h
29628 --- linux-2.6.25.10/include/linux/shm.h 2008-07-02 23:46:47.000000000 -0400
29629 +++ linux-2.6.25.10/include/linux/shm.h 2008-07-03 16:53:27.000000000 -0400
29630 @@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
29633 struct user_struct *mlock_user;
29634 +#ifdef CONFIG_GRKERNSEC
29635 + time_t shm_createtime;
29640 /* shm_mode upper byte flags */
29641 diff -urNp linux-2.6.25.10/include/linux/sysctl.h linux-2.6.25.10/include/linux/sysctl.h
29642 --- linux-2.6.25.10/include/linux/sysctl.h 2008-07-02 23:46:47.000000000 -0400
29643 +++ linux-2.6.25.10/include/linux/sysctl.h 2008-07-03 16:53:27.000000000 -0400
29644 @@ -163,9 +163,21 @@ enum
29645 KERN_MAX_LOCK_DEPTH=74,
29646 KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
29647 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
29649 +#ifdef CONFIG_GRKERNSEC
29650 + KERN_GRSECURITY=98, /* grsecurity */
29653 +#ifdef CONFIG_PAX_SOFTMODE
29654 + KERN_PAX=99, /* PaX control */
29659 +#ifdef CONFIG_PAX_SOFTMODE
29661 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
29665 /* CTL_VM names: */
29667 diff -urNp linux-2.6.25.10/include/linux/uaccess.h linux-2.6.25.10/include/linux/uaccess.h
29668 --- linux-2.6.25.10/include/linux/uaccess.h 2008-07-02 23:46:47.000000000 -0400
29669 +++ linux-2.6.25.10/include/linux/uaccess.h 2008-07-03 16:53:27.000000000 -0400
29670 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
29672 mm_segment_t old_fs = get_fs(); \
29674 - set_fs(KERNEL_DS); \
29675 pagefault_disable(); \
29676 + set_fs(KERNEL_DS); \
29677 ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
29678 - pagefault_enable(); \
29680 + pagefault_enable(); \
29684 diff -urNp linux-2.6.25.10/include/linux/udf_fs.h linux-2.6.25.10/include/linux/udf_fs.h
29685 --- linux-2.6.25.10/include/linux/udf_fs.h 2008-07-02 23:46:47.000000000 -0400
29686 +++ linux-2.6.25.10/include/linux/udf_fs.h 2008-07-03 16:53:27.000000000 -0400
29691 -#define udf_debug(f, a...) /**/
29692 +#define udf_debug(f, a...) do {} while (0)
29695 #define udf_info(f, a...) \
29696 diff -urNp linux-2.6.25.10/include/net/sctp/sctp.h linux-2.6.25.10/include/net/sctp/sctp.h
29697 --- linux-2.6.25.10/include/net/sctp/sctp.h 2008-07-02 23:46:47.000000000 -0400
29698 +++ linux-2.6.25.10/include/net/sctp/sctp.h 2008-07-03 16:53:27.000000000 -0400
29699 @@ -309,8 +309,8 @@ extern int sctp_debug_flag;
29701 #else /* SCTP_DEBUG */
29703 -#define SCTP_DEBUG_PRINTK(whatever...)
29704 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
29705 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
29706 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
29707 #define SCTP_ENABLE_DEBUG
29708 #define SCTP_DISABLE_DEBUG
29709 #define SCTP_ASSERT(expr, str, func)
29710 diff -urNp linux-2.6.25.10/include/sound/core.h linux-2.6.25.10/include/sound/core.h
29711 --- linux-2.6.25.10/include/sound/core.h 2008-07-02 23:46:47.000000000 -0400
29712 +++ linux-2.6.25.10/include/sound/core.h 2008-07-03 16:53:27.000000000 -0400
29713 @@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
29715 #else /* !CONFIG_SND_DEBUG */
29717 -#define snd_printd(fmt, args...) /* nothing */
29718 +#define snd_printd(fmt, args...) do {} while (0)
29719 #define snd_assert(expr, args...) (void)(expr)
29720 -#define snd_BUG() /* nothing */
29721 +#define snd_BUG() do {} while (0)
29723 #endif /* CONFIG_SND_DEBUG */
29725 @@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
29727 #define snd_printdd(format, args...) snd_printk(format, ##args)
29729 -#define snd_printdd(format, args...) /* nothing */
29730 +#define snd_printdd(format, args...) do {} while (0)
29734 diff -urNp linux-2.6.25.10/init/do_mounts.c linux-2.6.25.10/init/do_mounts.c
29735 --- linux-2.6.25.10/init/do_mounts.c 2008-07-02 23:46:47.000000000 -0400
29736 +++ linux-2.6.25.10/init/do_mounts.c 2008-07-03 16:53:27.000000000 -0400
29737 @@ -188,11 +188,11 @@ static void __init get_fs_names(char *pa
29739 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
29741 - int err = sys_mount(name, "/root", fs, flags, data);
29742 + int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
29746 - sys_chdir("/root");
29747 + sys_chdir((char __user *)"/root");
29748 ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
29749 printk("VFS: Mounted root (%s filesystem)%s.\n",
29750 current->fs->pwd.mnt->mnt_sb->s_type->name,
29751 @@ -278,18 +278,18 @@ void __init change_floppy(char *fmt, ...
29752 va_start(args, fmt);
29753 vsprintf(buf, fmt, args);
29755 - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
29756 + fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
29758 sys_ioctl(fd, FDEJECT, 0);
29761 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
29762 - fd = sys_open("/dev/console", O_RDWR, 0);
29763 + fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
29765 sys_ioctl(fd, TCGETS, (long)&termios);
29766 termios.c_lflag &= ~ICANON;
29767 sys_ioctl(fd, TCSETSF, (long)&termios);
29768 - sys_read(fd, &c, 1);
29769 + sys_read(fd, (char __user *)&c, 1);
29770 termios.c_lflag |= ICANON;
29771 sys_ioctl(fd, TCSETSF, (long)&termios);
29773 @@ -375,7 +375,7 @@ void __init prepare_namespace(void)
29777 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
29779 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
29780 + sys_chroot((char __user *)".");
29783 diff -urNp linux-2.6.25.10/init/do_mounts.h linux-2.6.25.10/init/do_mounts.h
29784 --- linux-2.6.25.10/init/do_mounts.h 2008-07-02 23:46:47.000000000 -0400
29785 +++ linux-2.6.25.10/init/do_mounts.h 2008-07-03 16:53:27.000000000 -0400
29786 @@ -15,15 +15,15 @@ extern char *root_device_name;
29788 static inline int create_dev(char *name, dev_t dev)
29790 - sys_unlink(name);
29791 - return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
29792 + sys_unlink((char __user *)name);
29793 + return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
29796 #if BITS_PER_LONG == 32
29797 static inline u32 bstat(char *name)
29799 struct stat64 stat;
29800 - if (sys_stat64(name, &stat) != 0)
29801 + if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
29803 if (!S_ISBLK(stat.st_mode))
29805 diff -urNp linux-2.6.25.10/init/do_mounts_md.c linux-2.6.25.10/init/do_mounts_md.c
29806 --- linux-2.6.25.10/init/do_mounts_md.c 2008-07-02 23:46:47.000000000 -0400
29807 +++ linux-2.6.25.10/init/do_mounts_md.c 2008-07-03 16:53:27.000000000 -0400
29808 @@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
29809 partitioned ? "_d" : "", minor,
29810 md_setup_args[ent].device_names);
29812 - fd = sys_open(name, 0, 0);
29813 + fd = sys_open((char __user *)name, 0, 0);
29815 printk(KERN_ERR "md: open failed - cannot start "
29816 "array %s\n", name);
29817 @@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
29821 - fd = sys_open(name, 0, 0);
29822 + fd = sys_open((char __user *)name, 0, 0);
29823 sys_ioctl(fd, BLKRRPART, 0);
29826 @@ -271,7 +271,7 @@ void __init md_run_setup(void)
29827 if (raid_noautodetect)
29828 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
29830 - int fd = sys_open("/dev/md0", 0, 0);
29831 + int fd = sys_open((char __user *)"/dev/md0", 0, 0);
29833 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
29835 diff -urNp linux-2.6.25.10/init/initramfs.c linux-2.6.25.10/init/initramfs.c
29836 --- linux-2.6.25.10/init/initramfs.c 2008-07-02 23:46:47.000000000 -0400
29837 +++ linux-2.6.25.10/init/initramfs.c 2008-07-03 16:53:27.000000000 -0400
29838 @@ -240,7 +240,7 @@ static int __init maybe_link(void)
29840 char *old = find_link(major, minor, ino, mode, collected);
29842 - return (sys_link(old, collected) < 0) ? -1 : 1;
29843 + return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
29847 @@ -249,11 +249,11 @@ static void __init clean_path(char *path
29851 - if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
29852 + if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
29853 if (S_ISDIR(st.st_mode))
29855 + sys_rmdir((char __user *)path);
29857 - sys_unlink(path);
29858 + sys_unlink((char __user *)path);
29862 @@ -276,7 +276,7 @@ static int __init do_name(void)
29863 int openflags = O_WRONLY|O_CREAT;
29865 openflags |= O_TRUNC;
29866 - wfd = sys_open(collected, openflags, mode);
29867 + wfd = sys_open((char __user *)collected, openflags, mode);
29870 sys_fchown(wfd, uid, gid);
29871 @@ -285,15 +285,15 @@ static int __init do_name(void)
29874 } else if (S_ISDIR(mode)) {
29875 - sys_mkdir(collected, mode);
29876 - sys_chown(collected, uid, gid);
29877 - sys_chmod(collected, mode);
29878 + sys_mkdir((char __user *)collected, mode);
29879 + sys_chown((char __user *)collected, uid, gid);
29880 + sys_chmod((char __user *)collected, mode);
29881 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
29882 S_ISFIFO(mode) || S_ISSOCK(mode)) {
29883 if (maybe_link() == 0) {
29884 - sys_mknod(collected, mode, rdev);
29885 - sys_chown(collected, uid, gid);
29886 - sys_chmod(collected, mode);
29887 + sys_mknod((char __user *)collected, mode, rdev);
29888 + sys_chown((char __user *)collected, uid, gid);
29889 + sys_chmod((char __user *)collected, mode);
29893 @@ -302,13 +302,13 @@ static int __init do_name(void)
29894 static int __init do_copy(void)
29896 if (count >= body_len) {
29897 - sys_write(wfd, victim, body_len);
29898 + sys_write(wfd, (char __user *)victim, body_len);
29904 - sys_write(wfd, victim, count);
29905 + sys_write(wfd, (char __user *)victim, count);
29909 @@ -319,8 +319,8 @@ static int __init do_symlink(void)
29911 collected[N_ALIGN(name_len) + body_len] = '\0';
29912 clean_path(collected, 0);
29913 - sys_symlink(collected + N_ALIGN(name_len), collected);
29914 - sys_lchown(collected, uid, gid);
29915 + sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
29916 + sys_lchown((char __user *)collected, uid, gid);
29918 next_state = Reset;
29920 diff -urNp linux-2.6.25.10/init/Kconfig linux-2.6.25.10/init/Kconfig
29921 --- linux-2.6.25.10/init/Kconfig 2008-07-02 23:46:47.000000000 -0400
29922 +++ linux-2.6.25.10/init/Kconfig 2008-07-03 16:53:27.000000000 -0400
29923 @@ -539,6 +539,7 @@ config SYSCTL_SYSCALL
29925 bool "Load all symbols for debugging/ksymoops" if EMBEDDED
29927 + depends on !GRKERNSEC_HIDESYM
29929 Say Y here to let the kernel print out symbolic crash information and
29930 symbolic stack backtraces. This increases the size of the kernel
29931 diff -urNp linux-2.6.25.10/init/main.c linux-2.6.25.10/init/main.c
29932 --- linux-2.6.25.10/init/main.c 2008-07-02 23:46:47.000000000 -0400
29933 +++ linux-2.6.25.10/init/main.c 2008-07-03 16:53:27.000000000 -0400
29934 @@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void)
29936 extern void tc_init(void);
29938 +extern void grsecurity_init(void);
29940 enum system_states system_state;
29941 EXPORT_SYMBOL(system_state);
29942 @@ -187,6 +188,40 @@ static int __init set_reset_devices(char
29944 __setup("reset_devices", set_reset_devices);
29946 +#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
29947 +static int __init setup_pax_nouderef(char *str)
29949 + unsigned int cpu;
29951 +#ifdef CONFIG_PAX_KERNEXEC
29952 + unsigned long cr0;
29954 + pax_open_kernel(cr0);
29957 + for (cpu = 0; cpu < NR_CPUS; cpu++)
29958 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
29960 +#ifdef CONFIG_PAX_KERNEXEC
29961 + pax_close_kernel(cr0);
29966 +__setup("pax_nouderef", setup_pax_nouderef);
29969 +#ifdef CONFIG_PAX_SOFTMODE
29970 +unsigned int pax_softmode;
29972 +static int __init setup_pax_softmode(char *str)
29974 + get_option(&str, &pax_softmode);
29977 +__setup("pax_softmode=", setup_pax_softmode);
29980 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
29981 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
29982 static const char *panic_later, *panic_param;
29983 @@ -364,7 +399,7 @@ static inline void smp_prepare_cpus(unsi
29986 #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
29987 -unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
29988 +unsigned long __per_cpu_offset[NR_CPUS] __read_only;
29990 EXPORT_SYMBOL(__per_cpu_offset);
29992 @@ -668,7 +703,7 @@ static void __init do_initcalls(void)
29994 for (call = __initcall_start; call < __initcall_end; call++) {
29995 ktime_t t0, t1, delta;
29996 - char *msg = NULL;
29997 + const char *msg1 = "", *msg2 = "";
30001 @@ -697,23 +732,22 @@ static void __init do_initcalls(void)
30002 (unsigned long) *call);
30005 - if (result && result != -ENODEV && initcall_debug) {
30006 - sprintf(msgbuf, "error code %d", result);
30010 + if (result && result != -ENODEV && initcall_debug)
30011 + sprintf(msgbuf, " error code %d", result);
30012 if (preempt_count() != count) {
30013 - msg = "preemption imbalance";
30014 + msg1 = " preemption imbalance";
30015 preempt_count() = count;
30017 if (irqs_disabled()) {
30018 - msg = "disabled interrupts";
30019 + msg2 = " disabled interrupts";
30020 local_irq_enable();
30023 + if (msgbuf[0] || *msg1 || *msg2) {
30024 printk(KERN_WARNING "initcall at 0x%p", *call);
30025 print_fn_descriptor_symbol(": %s()",
30026 (unsigned long) *call);
30027 - printk(": returned with %s\n", msg);
30028 + printk(": returned with%s%s%s\n", msgbuf, msg1, msg2);
30032 @@ -848,6 +882,8 @@ static int __init kernel_init(void * unu
30033 prepare_namespace();
30036 + grsecurity_init();
30039 * Ok, we have completed the initial bootup, and
30040 * we're essentially up and running. Get rid of the
30041 diff -urNp linux-2.6.25.10/init/noinitramfs.c linux-2.6.25.10/init/noinitramfs.c
30042 --- linux-2.6.25.10/init/noinitramfs.c 2008-07-02 23:46:47.000000000 -0400
30043 +++ linux-2.6.25.10/init/noinitramfs.c 2008-07-03 16:53:27.000000000 -0400
30044 @@ -29,7 +29,7 @@ static int __init default_rootfs(void)
30048 - err = sys_mkdir("/dev", 0755);
30049 + err = sys_mkdir((const char __user *)"/dev", 0755);
30053 @@ -39,7 +39,7 @@ static int __init default_rootfs(void)
30057 - err = sys_mkdir("/root", 0700);
30058 + err = sys_mkdir((const char __user *)"/root", 0700);
30062 diff -urNp linux-2.6.25.10/ipc/ipc_sysctl.c linux-2.6.25.10/ipc/ipc_sysctl.c
30063 --- linux-2.6.25.10/ipc/ipc_sysctl.c 2008-07-02 23:46:47.000000000 -0400
30064 +++ linux-2.6.25.10/ipc/ipc_sysctl.c 2008-07-03 16:53:27.000000000 -0400
30065 @@ -158,7 +158,7 @@ static struct ctl_table ipc_kern_table[]
30066 .proc_handler = proc_ipc_dointvec,
30067 .strategy = sysctl_ipc_data,
30070 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
30073 static struct ctl_table ipc_root_table[] = {
30074 @@ -168,7 +168,7 @@ static struct ctl_table ipc_root_table[]
30076 .child = ipc_kern_table,
30079 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
30082 static int __init ipc_sysctl_init(void)
30083 diff -urNp linux-2.6.25.10/ipc/msg.c linux-2.6.25.10/ipc/msg.c
30084 --- linux-2.6.25.10/ipc/msg.c 2008-07-02 23:46:47.000000000 -0400
30085 +++ linux-2.6.25.10/ipc/msg.c 2008-07-03 16:53:27.000000000 -0400
30087 #include <linux/nsproxy.h>
30088 #include <linux/ipc_namespace.h>
30089 #include <linux/vs_base.h>
30090 +#include <linux/grsecurity.h>
30092 #include <asm/current.h>
30093 #include <asm/uaccess.h>
30094 @@ -293,6 +294,7 @@ asmlinkage long sys_msgget(key_t key, in
30095 struct ipc_namespace *ns;
30096 struct ipc_ops msg_ops;
30097 struct ipc_params msg_params;
30100 ns = current->nsproxy->ipc_ns;
30102 @@ -303,7 +305,11 @@ asmlinkage long sys_msgget(key_t key, in
30103 msg_params.key = key;
30104 msg_params.flg = msgflg;
30106 - return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
30107 + err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
30109 + gr_log_msgget(err, msgflg);
30114 static inline unsigned long
30115 @@ -564,6 +570,7 @@ asmlinkage long sys_msgctl(int msqid, in
30119 + gr_log_msgrm(ipcp->uid, ipcp->cuid);
30120 freeque(ns, &msq->q_perm);
30123 diff -urNp linux-2.6.25.10/ipc/sem.c linux-2.6.25.10/ipc/sem.c
30124 --- linux-2.6.25.10/ipc/sem.c 2008-07-02 23:46:47.000000000 -0400
30125 +++ linux-2.6.25.10/ipc/sem.c 2008-07-03 16:53:27.000000000 -0400
30127 #include <linux/ipc_namespace.h>
30128 #include <linux/vs_base.h>
30129 #include <linux/vs_limit.h>
30130 +#include <linux/grsecurity.h>
30132 #include <asm/uaccess.h>
30134 @@ -312,6 +313,7 @@ asmlinkage long sys_semget(key_t key, in
30135 struct ipc_namespace *ns;
30136 struct ipc_ops sem_ops;
30137 struct ipc_params sem_params;
30140 ns = current->nsproxy->ipc_ns;
30142 @@ -326,7 +328,11 @@ asmlinkage long sys_semget(key_t key, in
30143 sem_params.flg = semflg;
30144 sem_params.u.nsems = nsems;
30146 - return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
30147 + err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
30149 + gr_log_semget(err, semflg);
30154 /* Manage the doubly linked list sma->sem_pending as a FIFO:
30155 @@ -909,6 +915,7 @@ static int semctl_down(struct ipc_namesp
30159 + gr_log_semrm(ipcp->uid, ipcp->cuid);
30163 diff -urNp linux-2.6.25.10/ipc/shm.c linux-2.6.25.10/ipc/shm.c
30164 --- linux-2.6.25.10/ipc/shm.c 2008-07-02 23:46:47.000000000 -0400
30165 +++ linux-2.6.25.10/ipc/shm.c 2008-07-03 16:53:27.000000000 -0400
30167 #include <linux/ipc_namespace.h>
30168 #include <linux/vs_context.h>
30169 #include <linux/vs_limit.h>
30170 +#include <linux/grsecurity.h>
30172 #include <asm/uaccess.h>
30174 @@ -70,6 +71,14 @@ static void shm_destroy (struct ipc_name
30175 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
30178 +#ifdef CONFIG_GRKERNSEC
30179 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
30180 + const time_t shm_createtime, const uid_t cuid,
30181 + const int shmid);
30182 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
30183 + const time_t shm_createtime);
30186 void shm_init_ns(struct ipc_namespace *ns)
30188 ns->shm_ctlmax = SHMMAX;
30189 @@ -88,6 +97,8 @@ static void do_shm_rmid(struct ipc_names
30190 struct shmid_kernel *shp;
30191 shp = container_of(ipcp, struct shmid_kernel, shm_perm);
30193 + gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
30195 if (shp->shm_nattch){
30196 shp->shm_perm.mode |= SHM_DEST;
30197 /* Do not find it any more */
30198 @@ -428,6 +439,14 @@ static int newseg(struct ipc_namespace *
30199 shp->shm_lprid = 0;
30200 shp->shm_atim = shp->shm_dtim = 0;
30201 shp->shm_ctim = get_seconds();
30202 +#ifdef CONFIG_GRKERNSEC
30204 + struct timespec timeval;
30205 + do_posix_clock_monotonic_gettime(&timeval);
30207 + shp->shm_createtime = timeval.tv_sec;
30210 shp->shm_segsz = size;
30211 shp->shm_nattch = 0;
30212 shp->shm_perm.id = shm_buildid(id, shp->shm_perm.seq);
30213 @@ -482,6 +501,7 @@ asmlinkage long sys_shmget (key_t key, s
30214 struct ipc_namespace *ns;
30215 struct ipc_ops shm_ops;
30216 struct ipc_params shm_params;
30219 ns = current->nsproxy->ipc_ns;
30221 @@ -493,7 +513,11 @@ asmlinkage long sys_shmget (key_t key, s
30222 shm_params.flg = shmflg;
30223 shm_params.u.size = size;
30225 - return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
30226 + err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
30228 + gr_log_shmget(err, shmflg, size);
30233 static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
30234 @@ -959,9 +983,21 @@ long do_shmat(int shmid, char __user *sh
30238 +#ifdef CONFIG_GRKERNSEC
30239 + if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
30240 + shp->shm_perm.cuid, shmid) ||
30241 + !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
30247 path.dentry = dget(shp->shm_file->f_path.dentry);
30248 path.mnt = shp->shm_file->f_path.mnt;
30250 +#ifdef CONFIG_GRKERNSEC
30251 + shp->shm_lapid = current->pid;
30253 size = i_size_read(path.dentry->d_inode);
30256 diff -urNp linux-2.6.25.10/kernel/acct.c linux-2.6.25.10/kernel/acct.c
30257 --- linux-2.6.25.10/kernel/acct.c 2008-07-02 23:46:47.000000000 -0400
30258 +++ linux-2.6.25.10/kernel/acct.c 2008-07-03 16:53:27.000000000 -0400
30259 @@ -519,7 +519,7 @@ static void do_acct_process(struct pid_n
30261 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
30262 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
30263 - file->f_op->write(file, (char *)&ac,
30264 + file->f_op->write(file, (char __user *)&ac,
30265 sizeof(acct_t), &file->f_pos);
30266 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
30268 diff -urNp linux-2.6.25.10/kernel/capability.c linux-2.6.25.10/kernel/capability.c
30269 --- linux-2.6.25.10/kernel/capability.c 2008-07-02 23:46:47.000000000 -0400
30270 +++ linux-2.6.25.10/kernel/capability.c 2008-07-03 16:53:27.000000000 -0400
30272 #include <linux/syscalls.h>
30273 #include <linux/pid_namespace.h>
30274 #include <linux/vs_context.h>
30275 +#include <linux/grsecurity.h>
30276 #include <asm/uaccess.h>
30279 @@ -363,13 +364,22 @@ out:
30281 int __capable(struct task_struct *t, int cap)
30283 - if (security_capable(t, cap) == 0) {
30284 + if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
30285 t->flags |= PF_SUPERPRIV;
30291 +int capable_nolog(int cap)
30293 + if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
30294 + current->flags |= PF_SUPERPRIV;
30300 #include <linux/vserver/base.h>
30301 int capable(int cap)
30303 @@ -347,3 +357,4 @@ int capable(int cap)
30304 return __capable(current, cap);
30306 EXPORT_SYMBOL(capable);
30307 +EXPORT_SYMBOL(capable_nolog);
30308 diff -urNp linux-2.6.25.10/kernel/configs.c linux-2.6.25.10/kernel/configs.c
30309 --- linux-2.6.25.10/kernel/configs.c 2008-07-02 23:46:47.000000000 -0400
30310 +++ linux-2.6.25.10/kernel/configs.c 2008-07-03 16:53:27.000000000 -0400
30311 @@ -79,8 +79,16 @@ static int __init ikconfig_init(void)
30312 struct proc_dir_entry *entry;
30314 /* create the current config file */
30315 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
30316 +#ifdef CONFIG_GRKERNSEC_PROC_USER
30317 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
30318 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
30319 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
30322 entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
30328 diff -urNp linux-2.6.25.10/kernel/cpu.c linux-2.6.25.10/kernel/cpu.c
30329 --- linux-2.6.25.10/kernel/cpu.c 2008-07-02 23:46:47.000000000 -0400
30330 +++ linux-2.6.25.10/kernel/cpu.c 2008-07-03 16:53:27.000000000 -0400
30332 /* Serializes the updates to cpu_online_map, cpu_present_map */
30333 static DEFINE_MUTEX(cpu_add_remove_lock);
30335 -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
30336 +static RAW_NOTIFIER_HEAD(cpu_chain);
30338 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
30339 * Should always be manipulated under cpu_add_remove_lock
30340 @@ -136,7 +136,7 @@ static void cpu_hotplug_done(void)
30341 mutex_unlock(&cpu_hotplug.lock);
30343 /* Need to know about CPUs going up/down? */
30344 -int __cpuinit register_cpu_notifier(struct notifier_block *nb)
30345 +int register_cpu_notifier(struct notifier_block *nb)
30348 cpu_maps_update_begin();
30349 diff -urNp linux-2.6.25.10/kernel/exit.c linux-2.6.25.10/kernel/exit.c
30350 --- linux-2.6.25.10/kernel/exit.c 2008-07-02 23:46:47.000000000 -0400
30351 +++ linux-2.6.25.10/kernel/exit.c 2008-07-03 16:53:27.000000000 -0400
30353 #include <linux/vs_network.h>
30354 #include <linux/vs_pid.h>
30355 #include <linux/vserver/global.h>
30356 +#include <linux/grsecurity.h>
30358 +#ifdef CONFIG_GRKERNSEC
30359 +extern rwlock_t grsec_exec_file_lock;
30362 #include <asm/uaccess.h>
30363 #include <asm/unistd.h>
30364 @@ -120,6 +125,7 @@ static void __exit_signal(struct task_st
30366 __unhash_process(tsk);
30368 + gr_del_task_from_ip_table(tsk);
30369 tsk->signal = NULL;
30370 tsk->sighand = NULL;
30371 spin_unlock(&sighand->siglock);
30372 @@ -301,12 +307,23 @@ static void reparent_to_kthreadd(void)
30374 write_lock_irq(&tasklist_lock);
30376 +#ifdef CONFIG_GRKERNSEC
30377 + write_lock(&grsec_exec_file_lock);
30378 + if (current->exec_file) {
30379 + fput(current->exec_file);
30380 + current->exec_file = NULL;
30382 + write_unlock(&grsec_exec_file_lock);
30385 ptrace_unlink(current);
30386 /* Reparent to init */
30387 remove_parent(current);
30388 current->real_parent = current->parent = kthreadd_task;
30389 add_parent(current);
30391 + gr_set_kernel_label(current);
30393 /* Set the exit signal to SIGCHLD so we signal init on exit */
30394 current->exit_signal = SIGCHLD;
30396 @@ -402,6 +419,17 @@ void daemonize(const char *name, ...)
30397 vsnprintf(current->comm, sizeof(current->comm), name, args);
30400 +#ifdef CONFIG_GRKERNSEC
30401 + write_lock(&grsec_exec_file_lock);
30402 + if (current->exec_file) {
30403 + fput(current->exec_file);
30404 + current->exec_file = NULL;
30406 + write_unlock(&grsec_exec_file_lock);
30409 + gr_set_kernel_label(current);
30412 * If we were started as result of loading a module, close all of the
30413 * user space pages. We don't need them, and if we didn't close them
30414 @@ -962,6 +990,9 @@ NORET_TYPE void do_exit(long code)
30415 tsk->exit_code = code;
30416 taskstats_exit(tsk, group_dead);
30418 + gr_acl_handle_psacct(tsk, code);
30419 + gr_acl_handle_exit();
30424 @@ -1171,7 +1202,7 @@ static int wait_task_zombie(struct task_
30425 if (unlikely(noreap)) {
30426 uid_t uid = p->uid;
30427 int exit_code = p->exit_code;
30431 get_task_struct(p);
30432 read_unlock(&tasklist_lock);
30433 diff -urNp linux-2.6.25.10/kernel/fork.c linux-2.6.25.10/kernel/fork.c
30434 --- linux-2.6.25.10/kernel/fork.c 2008-07-02 23:46:47.000000000 -0400
30435 +++ linux-2.6.25.10/kernel/fork.c 2008-07-03 16:53:27.000000000 -0400
30437 #include <linux/vs_limit.h>
30438 #include <linux/vs_memory.h>
30439 #include <linux/vserver/global.h>
30440 +#include <linux/grsecurity.h>
30442 #include <asm/pgtable.h>
30443 #include <asm/pgalloc.h>
30444 @@ -194,7 +195,7 @@ static struct task_struct *dup_task_stru
30445 setup_thread_stack(tsk, orig);
30447 #ifdef CONFIG_CC_STACKPROTECTOR
30448 - tsk->stack_canary = get_random_int();
30449 + tsk->stack_canary = pax_get_random_long();
30452 /* One for us, one for whoever does the "release_task()" (usually parent) */
30453 @@ -226,8 +227,8 @@ static int dup_mmap(struct mm_struct *mm
30456 mm->mmap_cache = NULL;
30457 - mm->free_area_cache = oldmm->mmap_base;
30458 - mm->cached_hole_size = ~0UL;
30459 + mm->free_area_cache = oldmm->free_area_cache;
30460 + mm->cached_hole_size = oldmm->cached_hole_size;
30462 __set_mm_counter(mm, file_rss, 0);
30463 __set_mm_counter(mm, anon_rss, 0);
30464 @@ -264,6 +265,7 @@ static int dup_mmap(struct mm_struct *mm
30465 tmp->vm_flags &= ~VM_LOCKED;
30467 tmp->vm_next = NULL;
30468 + tmp->vm_mirror = NULL;
30469 anon_vma_link(tmp);
30470 file = tmp->vm_file;
30472 @@ -300,6 +302,31 @@ static int dup_mmap(struct mm_struct *mm
30477 +#ifdef CONFIG_PAX_SEGMEXEC
30478 + if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
30479 + struct vm_area_struct *mpnt_m;
30481 + for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
30482 + BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
30484 + if (!mpnt->vm_mirror)
30487 + if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
30488 + BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
30489 + mpnt->vm_mirror = mpnt_m;
30491 + BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
30492 + mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
30493 + mpnt_m->vm_mirror->vm_mirror = mpnt_m;
30494 + mpnt->vm_mirror->vm_mirror = mpnt;
30501 /* a new mm has just been created */
30502 arch_dup_mmap(oldmm, mm);
30504 @@ -482,7 +509,7 @@ void mm_release(struct task_struct *tsk,
30505 if (tsk->clear_child_tid
30506 && !(tsk->flags & PF_SIGNALED)
30507 && atomic_read(&mm->mm_users) > 1) {
30508 - u32 __user * tidptr = tsk->clear_child_tid;
30509 + pid_t __user * tidptr = tsk->clear_child_tid;
30510 tsk->clear_child_tid = NULL;
30513 @@ -490,7 +517,7 @@ void mm_release(struct task_struct *tsk,
30514 * not set up a proper pointer then tough luck.
30516 put_user(0, tidptr);
30517 - sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
30518 + sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
30522 @@ -1046,6 +1073,9 @@ static struct task_struct *copy_process(
30523 DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
30524 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
30527 + gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
30529 init_vx_info(&p->vx_info, current->vx_info);
30530 init_nx_info(&p->nx_info, current->nx_info);
30532 @@ -1212,6 +1242,8 @@ static struct task_struct *copy_process(
30533 if (clone_flags & CLONE_THREAD)
30534 p->tgid = current->tgid;
30536 + gr_copy_label(p);
30538 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
30540 * Clear TID on mm_release()?
30541 @@ -1401,6 +1433,8 @@ bad_fork_cleanup_count:
30545 + gr_log_forkfail(retval);
30547 return ERR_PTR(retval);
30550 @@ -1493,6 +1527,8 @@ long do_fork(unsigned long clone_flags,
30551 if (clone_flags & CLONE_PARENT_SETTID)
30552 put_user(nr, parent_tidptr);
30554 + gr_handle_brute_check();
30556 if (clone_flags & CLONE_VFORK) {
30557 p->vfork_done = &vfork;
30558 init_completion(&vfork);
30559 diff -urNp linux-2.6.25.10/kernel/futex.c linux-2.6.25.10/kernel/futex.c
30560 --- linux-2.6.25.10/kernel/futex.c 2008-07-02 23:46:47.000000000 -0400
30561 +++ linux-2.6.25.10/kernel/futex.c 2008-07-03 16:53:27.000000000 -0400
30562 @@ -195,6 +195,11 @@ static int get_futex_key(u32 __user *uad
30566 +#ifdef CONFIG_PAX_SEGMEXEC
30567 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
30572 * The futex address must be "naturally" aligned.
30574 @@ -221,8 +226,8 @@ static int get_futex_key(u32 __user *uad
30575 * The futex is hashed differently depending on whether
30576 * it's in a shared or private mapping. So check vma first.
30578 - vma = find_extend_vma(mm, address);
30579 - if (unlikely(!vma))
30580 + vma = find_vma(mm, address);
30581 + if (unlikely(!vma || address < vma->vm_start))
30585 @@ -2032,7 +2037,7 @@ retry:
30587 static inline int fetch_robust_entry(struct robust_list __user **entry,
30588 struct robust_list __user * __user *head,
30590 + unsigned int *pi)
30592 unsigned long uentry;
30594 diff -urNp linux-2.6.25.10/kernel/irq/handle.c linux-2.6.25.10/kernel/irq/handle.c
30595 --- linux-2.6.25.10/kernel/irq/handle.c 2008-07-02 23:46:47.000000000 -0400
30596 +++ linux-2.6.25.10/kernel/irq/handle.c 2008-07-03 16:53:27.000000000 -0400
30597 @@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
30599 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
30601 - .affinity = CPU_MASK_ALL
30602 + .affinity = CPU_MASK_ALL,
30607 diff -urNp linux-2.6.25.10/kernel/kallsyms.c linux-2.6.25.10/kernel/kallsyms.c
30608 --- linux-2.6.25.10/kernel/kallsyms.c 2008-07-02 23:46:47.000000000 -0400
30609 +++ linux-2.6.25.10/kernel/kallsyms.c 2008-07-03 16:53:27.000000000 -0400
30610 @@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
30612 static inline int is_kernel(unsigned long addr)
30615 +#ifdef CONFIG_PAX_KERNEXEC
30617 +#ifdef CONFIG_MODULES
30618 + if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
30619 + ktla_ktva(addr) < (unsigned long)MODULES_END)
30623 + if (is_kernel_inittext(addr))
30627 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
30629 return in_gate_area_no_task(addr);
30630 @@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
30632 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
30634 - iter->name[0] = '\0';
30635 iter->nameoff = get_symbol_offset(new_pos);
30636 iter->pos = new_pos;
30638 @@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
30639 struct kallsym_iter *iter;
30642 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
30643 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
30646 reset_iter(iter, 0);
30647 @@ -474,7 +486,15 @@ static int __init kallsyms_init(void)
30649 struct proc_dir_entry *entry;
30651 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
30652 +#ifdef CONFIG_GRKERNSEC_PROC_USER
30653 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
30654 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
30655 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
30658 entry = create_proc_entry("kallsyms", 0444, NULL);
30661 entry->proc_fops = &kallsyms_operations;
30663 diff -urNp linux-2.6.25.10/kernel/kmod.c linux-2.6.25.10/kernel/kmod.c
30664 --- linux-2.6.25.10/kernel/kmod.c 2008-07-02 23:46:47.000000000 -0400
30665 +++ linux-2.6.25.10/kernel/kmod.c 2008-07-03 16:53:27.000000000 -0400
30666 @@ -107,7 +107,7 @@ int request_module(const char *fmt, ...)
30670 - ret = call_usermodehelper(modprobe_path, argv, envp, 1);
30671 + ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
30672 atomic_dec(&kmod_concurrent);
30675 diff -urNp linux-2.6.25.10/kernel/kprobes.c linux-2.6.25.10/kernel/kprobes.c
30676 --- linux-2.6.25.10/kernel/kprobes.c 2008-07-02 23:46:47.000000000 -0400
30677 +++ linux-2.6.25.10/kernel/kprobes.c 2008-07-03 16:53:27.000000000 -0400
30678 @@ -162,7 +162,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
30679 * kernel image and loaded module images reside. This is required
30680 * so x86_64 can correctly handle the %rip-relative fixups.
30682 - kip->insns = module_alloc(PAGE_SIZE);
30683 + kip->insns = module_alloc_exec(PAGE_SIZE);
30687 @@ -194,7 +194,7 @@ static int __kprobes collect_one_slot(st
30688 hlist_add_head(&kip->hlist,
30689 &kprobe_insn_pages);
30691 - module_free(NULL, kip->insns);
30692 + module_free_exec(NULL, kip->insns);
30696 diff -urNp linux-2.6.25.10/kernel/lockdep.c linux-2.6.25.10/kernel/lockdep.c
30697 --- linux-2.6.25.10/kernel/lockdep.c 2008-07-02 23:46:47.000000000 -0400
30698 +++ linux-2.6.25.10/kernel/lockdep.c 2008-07-03 16:53:27.000000000 -0400
30699 @@ -598,6 +598,10 @@ static int static_obj(void *obj)
30703 +#ifdef CONFIG_PAX_KERNEXEC
30704 + start = (unsigned long )&_data;
30710 @@ -609,9 +613,12 @@ static int static_obj(void *obj)
30713 for_each_possible_cpu(i) {
30714 +#ifdef CONFIG_X86_32
30715 + start = per_cpu_offset(i);
30717 start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
30718 - end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
30719 - + per_cpu_offset(i);
30721 + end = start + PERCPU_ENOUGH_ROOM;
30723 if ((addr >= start) && (addr < end))
30725 diff -urNp linux-2.6.25.10/kernel/module.c linux-2.6.25.10/kernel/module.c
30726 --- linux-2.6.25.10/kernel/module.c 2008-07-02 23:46:47.000000000 -0400
30727 +++ linux-2.6.25.10/kernel/module.c 2008-07-03 16:53:27.000000000 -0400
30729 #include <asm/uaccess.h>
30730 #include <asm/semaphore.h>
30731 #include <asm/cacheflush.h>
30733 +#ifdef CONFIG_PAX_KERNEXEC
30734 +#include <asm/desc.h>
30737 #include <linux/license.h>
30738 #include <asm/sections.h>
30740 @@ -71,6 +76,8 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
30742 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
30744 +extern int gr_check_modstop(void);
30746 int register_module_notifier(struct notifier_block * nb)
30748 return blocking_notifier_chain_register(&module_notify_list, nb);
30749 @@ -344,6 +351,8 @@ static inline unsigned int block_size(in
30753 +EXPORT_SYMBOL(__per_cpu_start);
30755 static void *percpu_modalloc(unsigned long size, unsigned long align,
30758 @@ -351,7 +360,7 @@ static void *percpu_modalloc(unsigned lo
30762 - if (align > PAGE_SIZE) {
30763 + if (align-1 >= PAGE_SIZE) {
30764 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
30765 name, align, PAGE_SIZE);
30767 @@ -433,7 +442,11 @@ static void percpu_modcopy(void *pcpudes
30770 for_each_possible_cpu(cpu)
30771 +#ifdef CONFIG_X86_32
30772 + memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
30774 memcpy(pcpudest + per_cpu_offset(cpu), from, size);
30778 static int percpu_modinit(void)
30779 @@ -684,6 +697,9 @@ sys_delete_module(const char __user *nam
30780 char name[MODULE_NAME_LEN];
30781 int ret, forced = 0;
30783 + if (gr_check_modstop())
30786 if (!capable(CAP_SYS_MODULE))
30789 @@ -1347,16 +1363,19 @@ static void free_module(struct module *m
30790 module_unload_free(mod);
30792 /* This may be NULL, but that's OK */
30793 - module_free(mod, mod->module_init);
30794 + module_free(mod, mod->module_init_rw);
30795 + module_free_exec(mod, mod->module_init_rx);
30798 percpu_modfree(mod->percpu);
30800 /* Free lock-classes: */
30801 - lockdep_free_key_range(mod->module_core, mod->core_size);
30802 + lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
30803 + lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
30805 /* Finally, free the core (containing the module structure) */
30806 - module_free(mod, mod->module_core);
30807 + module_free_exec(mod, mod->module_core_rx);
30808 + module_free(mod, mod->module_core_rw);
30811 void *__symbol_get(const char *symbol)
30812 @@ -1421,10 +1440,14 @@ static int simplify_symbols(Elf_Shdr *se
30813 struct module *mod)
30815 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
30816 - unsigned long secbase;
30817 + unsigned long secbase, symbol;
30818 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
30821 +#ifdef CONFIG_PAX_KERNEXEC
30822 + unsigned long cr0;
30825 for (i = 1; i < n; i++) {
30826 switch (sym[i].st_shndx) {
30828 @@ -1443,10 +1466,19 @@ static int simplify_symbols(Elf_Shdr *se
30833 - = resolve_symbol(sechdrs, versindex,
30834 + symbol = resolve_symbol(sechdrs, versindex,
30835 strtab + sym[i].st_name, mod);
30837 +#ifdef CONFIG_PAX_KERNEXEC
30838 + pax_open_kernel(cr0);
30841 + sym[i].st_value = symbol;
30843 +#ifdef CONFIG_PAX_KERNEXEC
30844 + pax_close_kernel(cr0);
30847 /* Ok if resolved. */
30848 if (!IS_ERR_VALUE(sym[i].st_value))
30850 @@ -1461,11 +1493,27 @@ static int simplify_symbols(Elf_Shdr *se
30853 /* Divert to percpu allocation if a percpu var. */
30854 - if (sym[i].st_shndx == pcpuindex)
30855 + if (sym[i].st_shndx == pcpuindex) {
30857 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
30858 + secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
30860 secbase = (unsigned long)mod->percpu;
30865 secbase = sechdrs[sym[i].st_shndx].sh_addr;
30867 +#ifdef CONFIG_PAX_KERNEXEC
30868 + pax_open_kernel(cr0);
30871 sym[i].st_value += secbase;
30873 +#ifdef CONFIG_PAX_KERNEXEC
30874 + pax_close_kernel(cr0);
30880 @@ -1517,11 +1565,14 @@ static void layout_sections(struct modul
30881 || strncmp(secstrings + s->sh_name,
30884 - s->sh_entsize = get_offset(&mod->core_size, s);
30885 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
30886 + s->sh_entsize = get_offset(&mod->core_size_rw, s);
30888 + s->sh_entsize = get_offset(&mod->core_size_rx, s);
30889 DEBUGP("\t%s\n", secstrings + s->sh_name);
30892 - mod->core_text_size = mod->core_size;
30893 + mod->core_size_rx = mod->core_size_rx;
30896 DEBUGP("Init section allocation order:\n");
30897 @@ -1535,12 +1586,15 @@ static void layout_sections(struct modul
30898 || strncmp(secstrings + s->sh_name,
30901 - s->sh_entsize = (get_offset(&mod->init_size, s)
30902 - | INIT_OFFSET_MASK);
30903 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
30904 + s->sh_entsize = get_offset(&mod->init_size_rw, s);
30906 + s->sh_entsize = get_offset(&mod->init_size_rx, s);
30907 + s->sh_entsize |= INIT_OFFSET_MASK;
30908 DEBUGP("\t%s\n", secstrings + s->sh_name);
30911 - mod->init_text_size = mod->init_size;
30912 + mod->init_size_rx = mod->init_size_rx;
30916 @@ -1667,14 +1721,31 @@ static void add_kallsyms(struct module *
30920 +#ifdef CONFIG_PAX_KERNEXEC
30921 + unsigned long cr0;
30924 mod->symtab = (void *)sechdrs[symindex].sh_addr;
30925 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
30926 mod->strtab = (void *)sechdrs[strindex].sh_addr;
30928 /* Set types up while we still have access to sections. */
30929 - for (i = 0; i < mod->num_symtab; i++)
30930 - mod->symtab[i].st_info
30931 - = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
30933 + for (i = 0; i < mod->num_symtab; i++) {
30934 + char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
30936 +#ifdef CONFIG_PAX_KERNEXEC
30937 + pax_open_kernel(cr0);
30940 + mod->symtab[i].st_info = type;
30942 +#ifdef CONFIG_PAX_KERNEXEC
30943 + pax_close_kernel(cr0);
30950 static inline void add_kallsyms(struct module *mod,
30951 @@ -1724,6 +1795,10 @@ static struct module *load_module(void _
30952 struct exception_table_entry *extable;
30953 mm_segment_t old_fs;
30955 +#ifdef CONFIG_PAX_KERNEXEC
30956 + unsigned long cr0;
30959 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
30961 if (len < sizeof(*hdr))
30962 @@ -1882,21 +1957,57 @@ static struct module *load_module(void _
30963 layout_sections(mod, hdr, sechdrs, secstrings);
30965 /* Do the allocs. */
30966 - ptr = module_alloc(mod->core_size);
30967 + ptr = module_alloc(mod->core_size_rw);
30972 - memset(ptr, 0, mod->core_size);
30973 - mod->module_core = ptr;
30974 + memset(ptr, 0, mod->core_size_rw);
30975 + mod->module_core_rw = ptr;
30977 + ptr = module_alloc(mod->init_size_rw);
30978 + if (!ptr && mod->init_size_rw) {
30980 + goto free_core_rw;
30982 + memset(ptr, 0, mod->init_size_rw);
30983 + mod->module_init_rw = ptr;
30985 + ptr = module_alloc_exec(mod->core_size_rx);
30988 + goto free_init_rw;
30991 - ptr = module_alloc(mod->init_size);
30992 - if (!ptr && mod->init_size) {
30993 +#ifdef CONFIG_PAX_KERNEXEC
30994 + pax_open_kernel(cr0);
30997 + memset(ptr, 0, mod->core_size_rx);
30999 +#ifdef CONFIG_PAX_KERNEXEC
31000 + pax_close_kernel(cr0);
31003 + mod->module_core_rx = ptr;
31005 + ptr = module_alloc_exec(mod->init_size_rx);
31006 + if (!ptr && mod->init_size_rx) {
31009 + goto free_core_rx;
31011 - memset(ptr, 0, mod->init_size);
31012 - mod->module_init = ptr;
31014 +#ifdef CONFIG_PAX_KERNEXEC
31015 + pax_open_kernel(cr0);
31018 + memset(ptr, 0, mod->init_size_rx);
31020 +#ifdef CONFIG_PAX_KERNEXEC
31021 + pax_close_kernel(cr0);
31024 + mod->module_init_rx = ptr;
31026 /* Transfer each section which specifies SHF_ALLOC */
31027 DEBUGP("final section addresses:\n");
31028 @@ -1906,17 +2017,41 @@ static struct module *load_module(void _
31029 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
31032 - if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
31033 - dest = mod->module_init
31034 - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
31036 - dest = mod->module_core + sechdrs[i].sh_entsize;
31037 + if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
31038 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
31039 + dest = mod->module_init_rw
31040 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
31042 + dest = mod->module_init_rx
31043 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
31045 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
31046 + dest = mod->module_core_rw + sechdrs[i].sh_entsize;
31048 + dest = mod->module_core_rx + sechdrs[i].sh_entsize;
31051 + if (sechdrs[i].sh_type != SHT_NOBITS) {
31053 - if (sechdrs[i].sh_type != SHT_NOBITS)
31054 - memcpy(dest, (void *)sechdrs[i].sh_addr,
31055 - sechdrs[i].sh_size);
31056 +#ifdef CONFIG_PAX_KERNEXEC
31057 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
31058 + pax_open_kernel(cr0);
31059 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
31060 + pax_close_kernel(cr0);
31064 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
31066 /* Update sh_addr to point to copy in image. */
31067 - sechdrs[i].sh_addr = (unsigned long)dest;
31069 +#ifdef CONFIG_PAX_KERNEXEC
31070 + if (sechdrs[i].sh_flags & SHF_EXECINSTR)
31071 + sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
31075 + sechdrs[i].sh_addr = (unsigned long)dest;
31076 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
31078 /* Module has been moved. */
31079 @@ -2057,12 +2192,12 @@ static struct module *load_module(void _
31080 * Do it before processing of module parameters, so the module
31081 * can provide parameter accessor functions of its own.
31083 - if (mod->module_init)
31084 - flush_icache_range((unsigned long)mod->module_init,
31085 - (unsigned long)mod->module_init
31086 - + mod->init_size);
31087 - flush_icache_range((unsigned long)mod->module_core,
31088 - (unsigned long)mod->module_core + mod->core_size);
31089 + if (mod->module_init_rx)
31090 + flush_icache_range((unsigned long)mod->module_init_rx,
31091 + (unsigned long)mod->module_init_rx
31092 + + mod->init_size_rx);
31093 + flush_icache_range((unsigned long)mod->module_core_rx,
31094 + (unsigned long)mod->module_core_rx + mod->core_size_rx);
31098 @@ -2115,9 +2250,13 @@ static struct module *load_module(void _
31099 kobject_put(&mod->mkobj.kobj);
31101 module_unload_free(mod);
31102 - module_free(mod, mod->module_init);
31104 - module_free(mod, mod->module_core);
31105 + module_free_exec(mod, mod->module_init_rx);
31107 + module_free_exec(mod, mod->module_core_rx);
31109 + module_free(mod, mod->module_init_rw);
31111 + module_free(mod, mod->module_core_rw);
31114 percpu_modfree(percpu);
31115 @@ -2142,6 +2281,9 @@ sys_init_module(void __user *umod,
31116 struct module *mod;
31119 + if (gr_check_modstop())
31122 /* Must have permission */
31123 if (!capable(CAP_SYS_MODULE))
31125 @@ -2195,10 +2337,12 @@ sys_init_module(void __user *umod,
31126 /* Drop initial reference. */
31128 unwind_remove_table(mod->unwind_info, 1);
31129 - module_free(mod, mod->module_init);
31130 - mod->module_init = NULL;
31131 - mod->init_size = 0;
31132 - mod->init_text_size = 0;
31133 + module_free(mod, mod->module_init_rw);
31134 + module_free_exec(mod, mod->module_init_rx);
31135 + mod->module_init_rw = NULL;
31136 + mod->module_init_rx = NULL;
31137 + mod->init_size_rw = 0;
31138 + mod->init_size_rx = 0;
31139 mutex_unlock(&module_mutex);
31142 @@ -2206,6 +2350,13 @@ sys_init_module(void __user *umod,
31144 static inline int within(unsigned long addr, void *start, unsigned long size)
31147 +#ifdef CONFIG_PAX_KERNEXEC
31148 + if (ktla_ktva(addr) >= (unsigned long)start &&
31149 + ktla_ktva(addr) < (unsigned long)start + size)
31153 return ((void *)addr >= start && (void *)addr < start + size);
31156 @@ -2229,10 +2380,14 @@ static const char *get_ksymbol(struct mo
31157 unsigned long nextval;
31159 /* At worse, next value is at end of module */
31160 - if (within(addr, mod->module_init, mod->init_size))
31161 - nextval = (unsigned long)mod->module_init+mod->init_text_size;
31162 + if (within(addr, mod->module_init_rx, mod->init_size_rx))
31163 + nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
31164 + else if (within(addr, mod->module_init_rw, mod->init_size_rw))
31165 + nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
31166 + else if (within(addr, mod->module_core_rx, mod->core_size_rx))
31167 + nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
31169 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
31170 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
31172 /* Scan for closest preceeding symbol, and next symbol. (ELF
31173 starts real symbols at 1). */
31174 @@ -2277,8 +2432,10 @@ const char *module_address_lookup(unsign
31177 list_for_each_entry(mod, &modules, list) {
31178 - if (within(addr, mod->module_init, mod->init_size)
31179 - || within(addr, mod->module_core, mod->core_size)) {
31180 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
31181 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
31182 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
31183 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
31185 *modname = mod->name;
31186 ret = get_ksymbol(mod, addr, size, offset);
31187 @@ -2300,8 +2457,10 @@ int lookup_module_symbol_name(unsigned l
31190 list_for_each_entry(mod, &modules, list) {
31191 - if (within(addr, mod->module_init, mod->init_size) ||
31192 - within(addr, mod->module_core, mod->core_size)) {
31193 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
31194 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
31195 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
31196 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
31199 sym = get_ksymbol(mod, addr, NULL, NULL);
31200 @@ -2324,8 +2483,10 @@ int lookup_module_symbol_attrs(unsigned
31203 list_for_each_entry(mod, &modules, list) {
31204 - if (within(addr, mod->module_init, mod->init_size) ||
31205 - within(addr, mod->module_core, mod->core_size)) {
31206 + if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
31207 + within(addr, mod->module_init_rw, mod->init_size_rw) ||
31208 + within(addr, mod->module_core_rx, mod->core_size_rx) ||
31209 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
31212 sym = get_ksymbol(mod, addr, size, offset);
31213 @@ -2456,7 +2617,7 @@ static int m_show(struct seq_file *m, vo
31216 seq_printf(m, "%s %lu",
31217 - mod->name, mod->init_size + mod->core_size);
31218 + mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
31219 print_unload_info(m, mod);
31221 /* Informative for users. */
31222 @@ -2465,7 +2626,7 @@ static int m_show(struct seq_file *m, vo
31223 mod->state == MODULE_STATE_COMING ? "Loading":
31225 /* Used by oprofile and other similar tools. */
31226 - seq_printf(m, " 0x%p", mod->module_core);
31227 + seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
31231 @@ -2521,7 +2682,8 @@ int is_module_address(unsigned long addr
31234 list_for_each_entry(mod, &modules, list) {
31235 - if (within(addr, mod->module_core, mod->core_size)) {
31236 + if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
31237 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
31241 @@ -2539,8 +2701,8 @@ struct module *__module_text_address(uns
31242 struct module *mod;
31244 list_for_each_entry(mod, &modules, list)
31245 - if (within(addr, mod->module_init, mod->init_text_size)
31246 - || within(addr, mod->module_core, mod->core_text_size))
31247 + if (within(addr, mod->module_init_rx, mod->init_size_rx)
31248 + || within(addr, mod->module_core_rx, mod->core_size_rx))
31252 diff -urNp linux-2.6.25.10/kernel/mutex.c linux-2.6.25.10/kernel/mutex.c
31253 --- linux-2.6.25.10/kernel/mutex.c 2008-07-02 23:46:47.000000000 -0400
31254 +++ linux-2.6.25.10/kernel/mutex.c 2008-07-03 16:53:27.000000000 -0400
31255 @@ -82,7 +82,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
31257 * This function is similar to (but not equivalent to) down().
31259 -void inline __sched mutex_lock(struct mutex *lock)
31260 +inline void __sched mutex_lock(struct mutex *lock)
31264 diff -urNp linux-2.6.25.10/kernel/panic.c linux-2.6.25.10/kernel/panic.c
31265 --- linux-2.6.25.10/kernel/panic.c 2008-07-02 23:46:47.000000000 -0400
31266 +++ linux-2.6.25.10/kernel/panic.c 2008-07-03 16:53:27.000000000 -0400
31267 @@ -323,6 +323,8 @@ EXPORT_SYMBOL(warn_on_slowpath);
31269 void __stack_chk_fail(void)
31271 + print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
31273 panic("stack-protector: Kernel stack is corrupted");
31275 EXPORT_SYMBOL(__stack_chk_fail);
31276 diff -urNp linux-2.6.25.10/kernel/pid.c linux-2.6.25.10/kernel/pid.c
31277 --- linux-2.6.25.10/kernel/pid.c 2008-07-02 23:46:47.000000000 -0400
31278 +++ linux-2.6.25.10/kernel/pid.c 2008-07-03 16:53:27.000000000 -0400
31280 #include <linux/syscalls.h>
31281 #include <linux/vs_pid.h>
31282 #include <linux/vserver/global.h>
31283 +#include <linux/grsecurity.h>
31285 #define pid_hashfn(nr, ns) \
31286 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
31287 @@ -44,7 +45,7 @@ struct pid init_struct_pid = INIT_STRUCT
31289 int pid_max = PID_MAX_DEFAULT;
31291 -#define RESERVED_PIDS 300
31292 +#define RESERVED_PIDS 500
31294 int pid_max_min = RESERVED_PIDS + 1;
31295 int pid_max_max = PID_MAX_LIMIT;
31296 @@ -375,7 +376,14 @@ EXPORT_SYMBOL(pid_task);
31297 struct task_struct *find_task_by_pid_type_ns(int type, int nr,
31298 struct pid_namespace *ns)
31300 - return pid_task(find_pid_ns(nr, ns), type);
31301 + struct task_struct *task;
31303 + task = pid_task(find_pid_ns(nr, ns), type);
31305 + if (gr_pid_is_chrooted(task))
31311 EXPORT_SYMBOL(find_task_by_pid_type_ns);
31312 diff -urNp linux-2.6.25.10/kernel/posix-cpu-timers.c linux-2.6.25.10/kernel/posix-cpu-timers.c
31313 --- linux-2.6.25.10/kernel/posix-cpu-timers.c 2008-07-02 23:46:47.000000000 -0400
31314 +++ linux-2.6.25.10/kernel/posix-cpu-timers.c 2008-07-03 16:53:27.000000000 -0400
31316 #include <linux/posix-timers.h>
31317 #include <asm/uaccess.h>
31318 #include <linux/errno.h>
31319 +#include <linux/grsecurity.h>
31321 static int check_clock(const clockid_t which_clock)
31323 @@ -1174,6 +1175,7 @@ static void check_process_timers(struct
31324 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
31327 + gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
31328 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
31330 * At the soft limit, send a SIGXCPU every second.
31331 diff -urNp linux-2.6.25.10/kernel/power/poweroff.c linux-2.6.25.10/kernel/power/poweroff.c
31332 --- linux-2.6.25.10/kernel/power/poweroff.c 2008-07-02 23:46:47.000000000 -0400
31333 +++ linux-2.6.25.10/kernel/power/poweroff.c 2008-07-03 16:53:27.000000000 -0400
31334 @@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
31335 .enable_mask = SYSRQ_ENABLE_BOOT,
31338 -static int pm_sysrq_init(void)
31339 +static int __init pm_sysrq_init(void)
31341 register_sysrq_key('o', &sysrq_poweroff_op);
31343 diff -urNp linux-2.6.25.10/kernel/printk.c linux-2.6.25.10/kernel/printk.c
31344 --- linux-2.6.25.10/kernel/printk.c 2008-07-02 23:46:47.000000000 -0400
31345 +++ linux-2.6.25.10/kernel/printk.c 2008-07-03 16:53:27.000000000 -0400
31347 #include <linux/bootmem.h>
31348 #include <linux/syscalls.h>
31349 #include <linux/vs_cvirt.h>
31350 +#include <linux/grsecurity.h>
31352 #include <asm/uaccess.h>
31354 @@ -299,6 +300,11 @@ int do_syslog(int type, char __user *buf
31358 +#ifdef CONFIG_GRKERNSEC_DMESG
31359 + if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
31363 error = security_syslog(type);
31366 diff -urNp linux-2.6.25.10/kernel/ptrace.c linux-2.6.25.10/kernel/ptrace.c
31367 --- linux-2.6.25.10/kernel/ptrace.c 2008-07-02 23:46:47.000000000 -0400
31368 +++ linux-2.6.25.10/kernel/ptrace.c 2008-07-03 16:53:27.000000000 -0400
31370 #include <linux/pid_namespace.h>
31371 #include <linux/syscalls.h>
31372 #include <linux/vs_context.h>
31373 +#include <linux/grsecurity.h>
31375 #include <asm/pgtable.h>
31376 #include <asm/uaccess.h>
31377 @@ -140,12 +141,12 @@ int __ptrace_may_attach(struct task_stru
31378 (current->uid != task->uid) ||
31379 (current->gid != task->egid) ||
31380 (current->gid != task->sgid) ||
31381 - (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
31382 + (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
31386 dumpable = get_dumpable(task->mm);
31387 - if (!dumpable && !capable(CAP_SYS_PTRACE))
31388 + if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
31390 if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT))
31392 @@ -203,7 +204,7 @@ repeat:
31395 task->ptrace |= PT_PTRACED;
31396 - if (capable(CAP_SYS_PTRACE))
31397 + if (capable_nolog(CAP_SYS_PTRACE))
31398 task->ptrace |= PT_PTRACE_CAP;
31400 __ptrace_link(task, current);
31401 @@ -577,6 +578,11 @@ asmlinkage long sys_ptrace(long request,
31403 goto out_put_task_struct;
31405 + if (gr_handle_ptrace(child, request)) {
31407 + goto out_put_task_struct;
31410 ret = arch_ptrace(child, request, addr, data);
31412 goto out_put_task_struct;
31413 diff -urNp linux-2.6.25.10/kernel/relay.c linux-2.6.25.10/kernel/relay.c
31414 --- linux-2.6.25.10/kernel/relay.c 2008-07-02 23:46:47.000000000 -0400
31415 +++ linux-2.6.25.10/kernel/relay.c 2008-07-03 16:53:27.000000000 -0400
31416 @@ -1140,7 +1140,7 @@ static int subbuf_splice_actor(struct fi
31419 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
31420 - if (ret < 0 || ret < total_len)
31421 + if ((int)ret < 0 || ret < total_len)
31424 if (read_start + ret == nonpad_end)
31425 diff -urNp linux-2.6.25.10/kernel/resource.c linux-2.6.25.10/kernel/resource.c
31426 --- linux-2.6.25.10/kernel/resource.c 2008-07-02 23:46:47.000000000 -0400
31427 +++ linux-2.6.25.10/kernel/resource.c 2008-07-03 16:53:27.000000000 -0400
31428 @@ -133,10 +133,27 @@ static int __init ioresources_init(void)
31430 struct proc_dir_entry *entry;
31432 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
31433 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31434 + entry = create_proc_entry("ioports", S_IRUSR, NULL);
31435 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31436 + entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
31439 entry = create_proc_entry("ioports", 0, NULL);
31442 entry->proc_fops = &proc_ioports_operations;
31444 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
31445 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31446 + entry = create_proc_entry("iomem", S_IRUSR, NULL);
31447 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31448 + entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
31451 entry = create_proc_entry("iomem", 0, NULL);
31454 entry->proc_fops = &proc_iomem_operations;
31456 diff -urNp linux-2.6.25.10/kernel/sched.c linux-2.6.25.10/kernel/sched.c
31457 --- linux-2.6.25.10/kernel/sched.c 2008-07-02 23:46:47.000000000 -0400
31458 +++ linux-2.6.25.10/kernel/sched.c 2008-07-03 16:53:27.000000000 -0400
31460 #include <linux/hrtimer.h>
31461 #include <linux/vs_sched.h>
31462 #include <linux/vs_cvirt.h>
31463 +#include <linux/grsecurity.h>
31465 #include <asm/tlb.h>
31466 #include <asm/irq_regs.h>
31467 @@ -4499,7 +4500,8 @@ asmlinkage long sys_nice(int increment)
31471 - if (increment < 0 && !can_nice(current, nice))
31472 + if (increment < 0 && (!can_nice(current, nice) ||
31473 + gr_handle_chroot_nice()))
31474 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
31476 retval = security_task_setnice(current, nice);
31477 @@ -5742,7 +5744,7 @@ static struct ctl_table sd_ctl_dir[] = {
31478 .procname = "sched_domain",
31482 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31485 static struct ctl_table sd_ctl_root[] = {
31486 @@ -5752,7 +5754,7 @@ static struct ctl_table sd_ctl_root[] =
31488 .child = sd_ctl_dir,
31491 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31494 static struct ctl_table *sd_alloc_ctl_entry(int n)
31495 diff -urNp linux-2.6.25.10/kernel/signal.c linux-2.6.25.10/kernel/signal.c
31496 --- linux-2.6.25.10/kernel/signal.c 2008-07-02 23:46:47.000000000 -0400
31497 +++ linux-2.6.25.10/kernel/signal.c 2008-07-03 19:42:44.000000000 -0400
31499 #include <linux/capability.h>
31500 #include <linux/freezer.h>
31501 #include <linux/pid_namespace.h>
31502 +#include <linux/grsecurity.h>
31503 #include <linux/nsproxy.h>
31504 #include <linux/vs_context.h>
31505 #include <linux/vs_pid.h>
31506 @@ -540,7 +541,9 @@ static int check_kill_permission(int sig
31507 && (current->euid ^ t->suid) && (current->euid ^ t->uid)
31508 && (current->uid ^ t->suid) && (current->uid ^ t->uid)
31509 && !capable(CAP_KILL))
31512 + if (gr_handle_signal(t, sig))
31517 @@ -757,7 +760,7 @@ static int __init setup_print_fatal_sign
31519 __setup("print-fatal-signals=", setup_print_fatal_signals);
31523 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
31526 @@ -811,8 +814,12 @@ force_sig_info(int sig, struct siginfo *
31529 ret = specific_send_sig_info(sig, info, t);
31531 spin_unlock_irqrestore(&t->sighand->siglock, flags);
31533 + gr_log_signal(sig, t);
31534 + gr_handle_crash(t, sig);
31539 @@ -1012,6 +1019,8 @@ int group_send_sig_info(int sig, struct
31540 ret = __group_send_sig_info(sig, info, p);
31541 unlock_task_sighand(p, &flags);
31544 + gr_log_signal(sig, p);
31548 diff -urNp linux-2.6.25.10/kernel/softirq.c linux-2.6.25.10/kernel/softirq.c
31549 --- linux-2.6.25.10/kernel/softirq.c 2008-07-02 23:46:47.000000000 -0400
31550 +++ linux-2.6.25.10/kernel/softirq.c 2008-07-03 16:53:27.000000000 -0400
31551 @@ -475,9 +475,9 @@ void tasklet_kill(struct tasklet_struct
31552 printk("Attempt to kill tasklet from interrupt\n");
31554 while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
31558 - while (test_bit(TASKLET_STATE_SCHED, &t->state));
31559 + } while (test_bit(TASKLET_STATE_SCHED, &t->state));
31561 tasklet_unlock_wait(t);
31562 clear_bit(TASKLET_STATE_SCHED, &t->state);
31563 diff -urNp linux-2.6.25.10/kernel/sys.c linux-2.6.25.10/kernel/sys.c
31564 --- linux-2.6.25.10/kernel/sys.c 2008-07-02 23:46:47.000000000 -0400
31565 +++ linux-2.6.25.10/kernel/sys.c 2008-07-03 16:53:27.000000000 -0400
31567 #include <linux/task_io_accounting_ops.h>
31568 #include <linux/seccomp.h>
31569 #include <linux/cpu.h>
31570 +#include <linux/grsecurity.h>
31572 #include <linux/compat.h>
31573 #include <linux/syscalls.h>
31574 @@ -119,6 +120,12 @@ static int set_one_prio(struct task_stru
31579 + if (gr_handle_chroot_setpriority(p, niceval)) {
31584 no_nice = security_task_setnice(p, niceval);
31587 @@ -175,10 +182,10 @@ asmlinkage long sys_setpriority(int whic
31588 if ((who != current->uid) && !(user = find_user(who)))
31589 goto out_unlock; /* No processes for this user */
31591 - do_each_thread(g, p)
31592 + do_each_thread(g, p) {
31594 error = set_one_prio(p, niceval, error);
31595 - while_each_thread(g, p);
31596 + } while_each_thread(g, p);
31597 if (who != current->uid)
31598 free_uid(user); /* For find_user() */
31600 @@ -237,13 +244,13 @@ asmlinkage long sys_getpriority(int whic
31601 if ((who != current->uid) && !(user = find_user(who)))
31602 goto out_unlock; /* No processes for this user */
31604 - do_each_thread(g, p)
31605 + do_each_thread(g, p) {
31606 if (p->uid == who) {
31607 niceval = 20 - task_nice(p);
31608 if (niceval > retval)
31611 - while_each_thread(g, p);
31612 + } while_each_thread(g, p);
31613 if (who != current->uid)
31614 free_uid(user); /* for find_user() */
31616 @@ -508,6 +515,10 @@ asmlinkage long sys_setregid(gid_t rgid,
31621 + if (gr_check_group_change(new_rgid, new_egid, -1))
31624 if (new_egid != old_egid) {
31625 set_dumpable(current->mm, suid_dumpable);
31627 @@ -515,6 +526,9 @@ asmlinkage long sys_setregid(gid_t rgid,
31628 if (rgid != (gid_t) -1 ||
31629 (egid != (gid_t) -1 && egid != old_rgid))
31630 current->sgid = new_egid;
31632 + gr_set_role_label(current, current->uid, new_rgid);
31634 current->fsgid = new_egid;
31635 current->egid = new_egid;
31636 current->gid = new_rgid;
31637 @@ -537,11 +551,17 @@ asmlinkage long sys_setgid(gid_t gid)
31641 + if (gr_check_group_change(gid, gid, gid))
31644 if (capable(CAP_SETGID)) {
31645 if (old_egid != gid) {
31646 set_dumpable(current->mm, suid_dumpable);
31650 + gr_set_role_label(current, current->uid, gid);
31652 current->gid = current->egid = current->sgid = current->fsgid = gid;
31653 } else if ((gid == current->gid) || (gid == current->sgid)) {
31654 if (old_egid != gid) {
31655 @@ -579,6 +599,9 @@ static int set_user(uid_t new_ruid, int
31656 set_dumpable(current->mm, suid_dumpable);
31660 + gr_set_role_label(current, new_ruid, current->gid);
31662 current->uid = new_ruid;
31665 @@ -628,6 +651,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
31669 + if (gr_check_user_change(new_ruid, new_euid, -1))
31672 if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
31675 @@ -674,6 +700,12 @@ asmlinkage long sys_setuid(uid_t uid)
31676 old_suid = current->suid;
31677 new_suid = old_suid;
31679 + if (gr_check_crash_uid(uid))
31682 + if (gr_check_user_change(uid, uid, uid))
31685 if (capable(CAP_SETUID)) {
31686 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
31688 @@ -721,6 +753,10 @@ asmlinkage long sys_setresuid(uid_t ruid
31689 (suid != current->euid) && (suid != current->suid))
31693 + if (gr_check_user_change(ruid, euid, -1))
31696 if (ruid != (uid_t) -1) {
31697 if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
31699 @@ -775,6 +811,10 @@ asmlinkage long sys_setresgid(gid_t rgid
31700 (sgid != current->egid) && (sgid != current->sgid))
31704 + if (gr_check_group_change(rgid, egid, -1))
31707 if (egid != (gid_t) -1) {
31708 if (egid != current->egid) {
31709 set_dumpable(current->mm, suid_dumpable);
31710 @@ -783,8 +823,10 @@ asmlinkage long sys_setresgid(gid_t rgid
31711 current->egid = egid;
31713 current->fsgid = current->egid;
31714 - if (rgid != (gid_t) -1)
31715 + if (rgid != (gid_t) -1) {
31716 + gr_set_role_label(current, current->uid, rgid);
31717 current->gid = rgid;
31719 if (sgid != (gid_t) -1)
31720 current->sgid = sgid;
31722 @@ -819,6 +861,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
31723 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
31726 + if (gr_check_user_change(-1, -1, uid))
31727 + return old_fsuid;
31729 if (uid == current->uid || uid == current->euid ||
31730 uid == current->suid || uid == current->fsuid ||
31731 capable(CAP_SETUID)) {
31732 @@ -851,6 +896,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
31733 if (gid == current->gid || gid == current->egid ||
31734 gid == current->sgid || gid == current->fsgid ||
31735 capable(CAP_SETGID)) {
31736 + if (gr_check_group_change(-1, -1, gid))
31737 + return old_fsgid;
31739 if (gid != old_fsgid) {
31740 set_dumpable(current->mm, suid_dumpable);
31742 @@ -932,7 +980,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
31743 write_lock_irq(&tasklist_lock);
31746 - p = find_task_by_vpid(pid);
31747 + /* grsec: replaced find_task_by_vpid with equivalent call which
31748 + lacks the chroot restriction
31750 + p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
31754 @@ -1647,7 +1698,7 @@ asmlinkage long sys_prctl(int option, un
31755 error = get_dumpable(current->mm);
31757 case PR_SET_DUMPABLE:
31758 - if (arg2 < 0 || arg2 > 1) {
31763 diff -urNp linux-2.6.25.10/kernel/sysctl.c linux-2.6.25.10/kernel/sysctl.c
31764 --- linux-2.6.25.10/kernel/sysctl.c 2008-07-02 23:46:47.000000000 -0400
31765 +++ linux-2.6.25.10/kernel/sysctl.c 2008-07-03 16:53:27.000000000 -0400
31767 static int deprecated_sysctl_warning(struct __sysctl_args *args);
31769 #if defined(CONFIG_SYSCTL)
31770 +#include <linux/grsecurity.h>
31771 +#include <linux/grinternal.h>
31773 +extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
31774 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
31776 +extern int gr_handle_chroot_sysctl(const int op);
31778 /* External variables not in a header file. */
31780 @@ -156,6 +163,7 @@ static int proc_do_cad_pid(struct ctl_ta
31781 static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
31782 void __user *buffer, size_t *lenp, loff_t *ppos);
31784 +extern ctl_table grsecurity_table[];
31786 static struct ctl_table root_table[];
31787 static struct ctl_table_root sysctl_table_root;
31788 @@ -183,6 +191,21 @@ extern struct ctl_table inotify_table[];
31789 int sysctl_legacy_va_layout;
31792 +#ifdef CONFIG_PAX_SOFTMODE
31793 +static ctl_table pax_table[] = {
31795 + .ctl_name = CTL_UNNUMBERED,
31796 + .procname = "softmode",
31797 + .data = &pax_softmode,
31798 + .maxlen = sizeof(unsigned int),
31800 + .proc_handler = &proc_dointvec,
31803 + { .ctl_name = 0 }
31807 extern int prove_locking;
31808 extern int lock_stat;
31810 @@ -219,6 +242,7 @@ static struct ctl_table root_table[] = {
31812 .child = dev_table,
31816 * NOTE: do not add new entries to this table unless you have read
31817 * Documentation/sysctl/ctl_unnumbered.txt
31818 @@ -820,6 +844,24 @@ static struct ctl_table kern_table[] = {
31819 .proc_handler = &proc_dostring,
31820 .strategy = &sysctl_string,
31822 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
31824 + .ctl_name = CTL_UNNUMBERED,
31825 + .procname = "grsecurity",
31827 + .child = grsecurity_table,
31831 +#ifdef CONFIG_PAX_SOFTMODE
31833 + .ctl_name = CTL_UNNUMBERED,
31834 + .procname = "pax",
31836 + .child = pax_table,
31841 * NOTE: do not add new entries to this table unless you have read
31842 * Documentation/sysctl/ctl_unnumbered.txt
31843 @@ -1507,6 +1549,25 @@ static int test_perm(int mode, int op)
31844 int sysctl_perm(struct ctl_table *table, int op)
31847 + if (table->parent != NULL && table->parent->procname != NULL &&
31848 + table->procname != NULL &&
31849 + gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
31851 + if (gr_handle_chroot_sysctl(op))
31853 + error = gr_handle_sysctl(table, op);
31856 + error = security_sysctl(table, op);
31859 + return test_perm(table->mode, op);
31862 +int sysctl_perm_nochk(ctl_table *table, int op)
31866 error = security_sysctl(table, op);
31869 @@ -1531,13 +1592,14 @@ repeat:
31870 if (n == table->ctl_name) {
31872 if (table->child) {
31873 - if (sysctl_perm(table, 001))
31874 + if (sysctl_perm_nochk(table, 001))
31878 table = table->child;
31882 error = do_sysctl_strategy(table, name, nlen,
31885 diff -urNp linux-2.6.25.10/kernel/time.c linux-2.6.25.10/kernel/time.c
31886 --- linux-2.6.25.10/kernel/time.c 2008-07-02 23:46:47.000000000 -0400
31887 +++ linux-2.6.25.10/kernel/time.c 2008-07-03 16:53:27.000000000 -0400
31889 #include <linux/syscalls.h>
31890 #include <linux/security.h>
31891 #include <linux/fs.h>
31892 +#include <linux/grsecurity.h>
31894 #include <asm/uaccess.h>
31895 #include <asm/unistd.h>
31896 @@ -90,6 +91,9 @@ asmlinkage long sys_stime(time_t __user
31899 vx_settimeofday(&tv);
31901 + gr_log_timechange();
31906 @@ -198,6 +202,8 @@ asmlinkage long sys_settimeofday(struct
31910 + gr_log_timechange();
31912 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
31915 @@ -236,7 +242,7 @@ EXPORT_SYMBOL(current_fs_time);
31916 * Avoid unnecessary multiplications/divisions in the
31917 * two most common HZ cases:
31919 -unsigned int inline jiffies_to_msecs(const unsigned long j)
31920 +inline unsigned int jiffies_to_msecs(const unsigned long j)
31922 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
31923 return (MSEC_PER_SEC / HZ) * j;
31924 @@ -252,7 +258,7 @@ unsigned int inline jiffies_to_msecs(con
31926 EXPORT_SYMBOL(jiffies_to_msecs);
31928 -unsigned int inline jiffies_to_usecs(const unsigned long j)
31929 +inline unsigned int jiffies_to_usecs(const unsigned long j)
31931 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
31932 return (USEC_PER_SEC / HZ) * j;
31933 diff -urNp linux-2.6.25.10/kernel/utsname_sysctl.c linux-2.6.25.10/kernel/utsname_sysctl.c
31934 --- linux-2.6.25.10/kernel/utsname_sysctl.c 2008-07-02 23:46:47.000000000 -0400
31935 +++ linux-2.6.25.10/kernel/utsname_sysctl.c 2008-07-03 16:53:27.000000000 -0400
31936 @@ -125,7 +125,7 @@ static struct ctl_table uts_kern_table[]
31937 .proc_handler = proc_do_uts_string,
31938 .strategy = sysctl_uts_string,
31941 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31944 static struct ctl_table uts_root_table[] = {
31945 @@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[]
31947 .child = uts_kern_table,
31950 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31953 static int __init utsname_sysctl_init(void)
31954 diff -urNp linux-2.6.25.10/lib/radix-tree.c linux-2.6.25.10/lib/radix-tree.c
31955 --- linux-2.6.25.10/lib/radix-tree.c 2008-07-02 23:46:47.000000000 -0400
31956 +++ linux-2.6.25.10/lib/radix-tree.c 2008-07-03 16:53:27.000000000 -0400
31957 @@ -81,7 +81,7 @@ struct radix_tree_preload {
31959 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
31961 -DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
31962 +DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
31964 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
31966 diff -urNp linux-2.6.25.10/localversion-grsec linux-2.6.25.10/localversion-grsec
31967 --- linux-2.6.25.10/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
31968 +++ linux-2.6.25.10/localversion-grsec 2008-07-03 16:53:27.000000000 -0400
31971 diff -urNp linux-2.6.25.10/Makefile linux-2.6.25.10/Makefile
31972 --- linux-2.6.25.10/Makefile 2008-07-02 23:46:47.000000000 -0400
31973 +++ linux-2.6.25.10/Makefile 2008-07-03 16:53:24.000000000 -0400
31974 @@ -214,7 +214,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
31978 -HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
31979 +HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
31982 # Decide whether to build built-in, modular, or both.
31983 @@ -603,7 +603,7 @@ export mod_strip_cmd
31986 ifeq ($(KBUILD_EXTMOD),)
31987 -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
31988 +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
31990 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
31991 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
31992 diff -urNp linux-2.6.25.10/mm/filemap.c linux-2.6.25.10/mm/filemap.c
31993 --- linux-2.6.25.10/mm/filemap.c 2008-07-02 23:46:47.000000000 -0400
31994 +++ linux-2.6.25.10/mm/filemap.c 2008-07-03 16:53:27.000000000 -0400
31996 #include <linux/cpuset.h>
31997 #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
31998 #include <linux/memcontrol.h>
31999 +#include <linux/grsecurity.h>
32000 #include "internal.h"
32003 @@ -1481,7 +1482,7 @@ int generic_file_mmap(struct file * file
32004 struct address_space *mapping = file->f_mapping;
32006 if (!mapping->a_ops->readpage)
32009 file_accessed(file);
32010 vma->vm_ops = &generic_file_vm_ops;
32011 vma->vm_flags |= VM_CAN_NONLINEAR;
32012 @@ -1841,6 +1842,7 @@ inline int generic_write_checks(struct f
32013 *pos = i_size_read(inode);
32015 if (limit != RLIM_INFINITY) {
32016 + gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
32017 if (*pos >= limit) {
32018 send_sig(SIGXFSZ, current, 0);
32020 diff -urNp linux-2.6.25.10/mm/fremap.c linux-2.6.25.10/mm/fremap.c
32021 --- linux-2.6.25.10/mm/fremap.c 2008-07-02 23:46:47.000000000 -0400
32022 +++ linux-2.6.25.10/mm/fremap.c 2008-07-03 16:53:27.000000000 -0400
32023 @@ -150,6 +150,13 @@ asmlinkage long sys_remap_file_pages(uns
32025 vma = find_vma(mm, start);
32027 +#ifdef CONFIG_PAX_SEGMEXEC
32028 + if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
32029 + up_read(&mm->mmap_sem);
32035 * Make sure the vma is shared, that it supports prefaulting,
32036 * and that the remapped range is valid and fully within
32037 diff -urNp linux-2.6.25.10/mm/hugetlb.c linux-2.6.25.10/mm/hugetlb.c
32038 --- linux-2.6.25.10/mm/hugetlb.c 2008-07-02 23:46:47.000000000 -0400
32039 +++ linux-2.6.25.10/mm/hugetlb.c 2008-07-03 16:53:27.000000000 -0400
32040 @@ -843,6 +843,26 @@ void unmap_hugepage_range(struct vm_area
32044 +#ifdef CONFIG_PAX_SEGMEXEC
32045 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
32047 + struct mm_struct *mm = vma->vm_mm;
32048 + struct vm_area_struct *vma_m;
32049 + unsigned long address_m;
32052 + vma_m = pax_find_mirror_vma(vma);
32056 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
32057 + address_m = address + SEGMEXEC_TASK_SIZE;
32058 + ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
32059 + get_page(page_m);
32060 + set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
32064 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
32065 unsigned long address, pte_t *ptep, pte_t pte)
32067 @@ -877,6 +897,11 @@ static int hugetlb_cow(struct mm_struct
32069 set_huge_pte_at(mm, address, ptep,
32070 make_huge_pte(vma, new_page, 1));
32072 +#ifdef CONFIG_PAX_SEGMEXEC
32073 + pax_mirror_huge_pte(vma, address, new_page);
32076 /* Make the old page be freed below */
32077 new_page = old_page;
32079 @@ -949,6 +974,10 @@ retry:
32080 && (vma->vm_flags & VM_SHARED)));
32081 set_huge_pte_at(mm, address, ptep, new_pte);
32083 +#ifdef CONFIG_PAX_SEGMEXEC
32084 + pax_mirror_huge_pte(vma, address, page);
32087 if (write_access && !(vma->vm_flags & VM_SHARED)) {
32088 /* Optimization, do the COW without a second fault */
32089 ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
32090 @@ -974,6 +1003,27 @@ int hugetlb_fault(struct mm_struct *mm,
32092 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
32094 +#ifdef CONFIG_PAX_SEGMEXEC
32095 + struct vm_area_struct *vma_m;
32097 + vma_m = pax_find_mirror_vma(vma);
32099 + unsigned long address_m;
32101 + if (vma->vm_start > vma_m->vm_start) {
32102 + address_m = address;
32103 + address -= SEGMEXEC_TASK_SIZE;
32106 + address_m = address + SEGMEXEC_TASK_SIZE;
32108 + if (!huge_pte_alloc(mm, address_m))
32109 + return VM_FAULT_OOM;
32110 + address_m &= HPAGE_MASK;
32111 + unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
32115 ptep = huge_pte_alloc(mm, address);
32117 return VM_FAULT_OOM;
32118 diff -urNp linux-2.6.25.10/mm/madvise.c linux-2.6.25.10/mm/madvise.c
32119 --- linux-2.6.25.10/mm/madvise.c 2008-07-02 23:46:47.000000000 -0400
32120 +++ linux-2.6.25.10/mm/madvise.c 2008-07-03 16:53:27.000000000 -0400
32121 @@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
32123 int new_flags = vma->vm_flags;
32125 +#ifdef CONFIG_PAX_SEGMEXEC
32126 + struct vm_area_struct *vma_m;
32129 switch (behavior) {
32131 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
32132 @@ -92,6 +96,13 @@ success:
32134 * vm_flags is protected by the mmap_sem held in write mode.
32137 +#ifdef CONFIG_PAX_SEGMEXEC
32138 + vma_m = pax_find_mirror_vma(vma);
32140 + vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
32143 vma->vm_flags = new_flags;
32146 @@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
32148 case MADV_DONTNEED:
32149 error = madvise_dontneed(vma, prev, start, end);
32151 +#ifdef CONFIG_PAX_SEGMEXEC
32153 + struct vm_area_struct *vma_m, *prev_m;
32155 + vma_m = pax_find_mirror_vma(vma);
32157 + error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
32164 @@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
32168 +#ifdef CONFIG_PAX_SEGMEXEC
32169 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
32170 + if (end > SEGMEXEC_TASK_SIZE)
32175 + if (end > TASK_SIZE)
32181 diff -urNp linux-2.6.25.10/mm/memory.c linux-2.6.25.10/mm/memory.c
32182 --- linux-2.6.25.10/mm/memory.c 2008-07-02 23:46:47.000000000 -0400
32183 +++ linux-2.6.25.10/mm/memory.c 2008-07-03 16:53:27.000000000 -0400
32185 #include <linux/init.h>
32186 #include <linux/writeback.h>
32187 #include <linux/memcontrol.h>
32188 +#include <linux/grsecurity.h>
32190 #include <asm/pgalloc.h>
32191 #include <asm/uaccess.h>
32192 @@ -1026,11 +1027,11 @@ int get_user_pages(struct task_struct *t
32193 vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
32198 struct vm_area_struct *vma;
32199 unsigned int foll_flags;
32201 - vma = find_extend_vma(mm, start);
32202 + vma = find_vma(mm, start);
32203 if (!vma && in_gate_area(tsk, start)) {
32204 unsigned long pg = start & PAGE_MASK;
32205 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
32206 @@ -1070,7 +1071,7 @@ int get_user_pages(struct task_struct *t
32210 - if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
32211 + if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
32212 || !(vm_flags & vma->vm_flags))
32213 return i ? : -EFAULT;
32215 @@ -1143,7 +1144,7 @@ int get_user_pages(struct task_struct *t
32216 start += PAGE_SIZE;
32218 } while (len && start < vma->vm_end);
32223 EXPORT_SYMBOL(get_user_pages);
32224 @@ -1569,6 +1570,186 @@ static inline void cow_user_page(struct
32225 copy_user_highpage(dst, src, va, vma);
32228 +#ifdef CONFIG_PAX_SEGMEXEC
32229 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
32231 + struct mm_struct *mm = vma->vm_mm;
32233 + pte_t *pte, entry;
32235 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
32237 + if (!pte_present(entry)) {
32238 + if (!pte_none(entry)) {
32239 + BUG_ON(pte_file(entry));
32240 + free_swap_and_cache(pte_to_swp_entry(entry));
32241 + pte_clear_not_present_full(mm, address, pte, 0);
32244 + struct page *page;
32246 + flush_cache_page(vma, address, pte_pfn(entry));
32247 + entry = ptep_clear_flush(vma, address, pte);
32248 + BUG_ON(pte_dirty(entry));
32249 + page = vm_normal_page(vma, address, entry);
32251 + update_hiwater_rss(mm);
32252 + if (PageAnon(page))
32253 + dec_mm_counter(mm, anon_rss);
32255 + dec_mm_counter(mm, file_rss);
32256 + page_remove_rmap(page, vma);
32257 + page_cache_release(page);
32260 + pte_unmap_unlock(pte, ptl);
32263 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
32265 + * the ptl of the lower mapped page is held on entry and is not released on exit
32266 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
32268 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
32270 + struct mm_struct *mm = vma->vm_mm;
32271 + unsigned long address_m;
32272 + spinlock_t *ptl_m;
32273 + struct vm_area_struct *vma_m;
32275 + pte_t *pte_m, entry_m;
32277 + BUG_ON(!page_m || !PageAnon(page_m));
32279 + vma_m = pax_find_mirror_vma(vma);
32283 + BUG_ON(!PageLocked(page_m));
32284 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
32285 + address_m = address + SEGMEXEC_TASK_SIZE;
32286 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
32287 + pte_m = pte_offset_map_nested(pmd_m, address_m);
32288 + ptl_m = pte_lockptr(mm, pmd_m);
32289 + if (ptl != ptl_m) {
32290 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
32291 + if (!pte_none(*pte_m))
32295 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
32296 + page_cache_get(page_m);
32297 + page_add_anon_rmap(page_m, vma_m, address_m);
32298 + inc_mm_counter(mm, anon_rss);
32299 + set_pte_at(mm, address_m, pte_m, entry_m);
32300 + update_mmu_cache(vma_m, address_m, entry_m);
32302 + if (ptl != ptl_m)
32303 + spin_unlock(ptl_m);
32304 + pte_unmap_nested(pte_m);
32305 + unlock_page(page_m);
32308 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
32310 + struct mm_struct *mm = vma->vm_mm;
32311 + unsigned long address_m;
32312 + spinlock_t *ptl_m;
32313 + struct vm_area_struct *vma_m;
32315 + pte_t *pte_m, entry_m;
32317 + BUG_ON(!page_m || PageAnon(page_m));
32319 + vma_m = pax_find_mirror_vma(vma);
32323 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
32324 + address_m = address + SEGMEXEC_TASK_SIZE;
32325 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
32326 + pte_m = pte_offset_map_nested(pmd_m, address_m);
32327 + ptl_m = pte_lockptr(mm, pmd_m);
32328 + if (ptl != ptl_m) {
32329 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
32330 + if (!pte_none(*pte_m))
32334 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
32335 + page_cache_get(page_m);
32336 + page_add_file_rmap(page_m);
32337 + inc_mm_counter(mm, file_rss);
32338 + set_pte_at(mm, address_m, pte_m, entry_m);
32339 + update_mmu_cache(vma_m, address_m, entry_m);
32341 + if (ptl != ptl_m)
32342 + spin_unlock(ptl_m);
32343 + pte_unmap_nested(pte_m);
32346 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
32348 + struct mm_struct *mm = vma->vm_mm;
32349 + unsigned long address_m;
32350 + spinlock_t *ptl_m;
32351 + struct vm_area_struct *vma_m;
32353 + pte_t *pte_m, entry_m;
32355 + vma_m = pax_find_mirror_vma(vma);
32359 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
32360 + address_m = address + SEGMEXEC_TASK_SIZE;
32361 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
32362 + pte_m = pte_offset_map_nested(pmd_m, address_m);
32363 + ptl_m = pte_lockptr(mm, pmd_m);
32364 + if (ptl != ptl_m) {
32365 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
32366 + if (!pte_none(*pte_m))
32370 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
32371 + set_pte_at(mm, address_m, pte_m, entry_m);
32373 + if (ptl != ptl_m)
32374 + spin_unlock(ptl_m);
32375 + pte_unmap_nested(pte_m);
32378 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
32380 + struct page *page_m;
32383 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
32387 + page_m = vm_normal_page(vma, address, entry);
32389 + pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
32390 + else if (PageAnon(page_m)) {
32391 + if (pax_find_mirror_vma(vma)) {
32392 + pte_unmap_unlock(pte, ptl);
32393 + lock_page(page_m);
32394 + pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
32395 + if (pte_same(entry, *pte))
32396 + pax_mirror_anon_pte(vma, address, page_m, ptl);
32398 + unlock_page(page_m);
32401 + pax_mirror_file_pte(vma, address, page_m, ptl);
32404 + pte_unmap_unlock(pte, ptl);
32409 * This routine handles present pages, when users try to write
32410 * to a shared page. It is done by copying the page to a new address
32411 @@ -1685,6 +1866,12 @@ gotten:
32413 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
32414 if (likely(pte_same(*page_table, orig_pte))) {
32416 +#ifdef CONFIG_PAX_SEGMEXEC
32417 + if (pax_find_mirror_vma(vma))
32418 + BUG_ON(TestSetPageLocked(new_page));
32422 page_remove_rmap(old_page, vma);
32423 if (!PageAnon(old_page)) {
32424 @@ -1708,6 +1895,10 @@ gotten:
32425 lru_cache_add_active(new_page);
32426 page_add_new_anon_rmap(new_page, vma, address);
32428 +#ifdef CONFIG_PAX_SEGMEXEC
32429 + pax_mirror_anon_pte(vma, address, new_page, ptl);
32432 /* Free the old page.. */
32433 new_page = old_page;
32434 ret |= VM_FAULT_WRITE;
32435 @@ -1967,6 +2158,7 @@ int vmtruncate(struct inode * inode, lof
32436 unsigned long limit;
32438 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
32439 + gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
32440 if (limit != RLIM_INFINITY && offset > limit)
32442 if (offset > inode->i_sb->s_maxbytes)
32443 @@ -2117,6 +2309,11 @@ static int do_swap_page(struct mm_struct
32445 if (vm_swap_full())
32446 remove_exclusive_swap_page(page);
32448 +#ifdef CONFIG_PAX_SEGMEXEC
32449 + if (write_access || !pax_find_mirror_vma(vma))
32454 if (write_access) {
32455 @@ -2128,6 +2325,11 @@ static int do_swap_page(struct mm_struct
32457 /* No need to invalidate - it was non-present before */
32458 update_mmu_cache(vma, address, pte);
32460 +#ifdef CONFIG_PAX_SEGMEXEC
32461 + pax_mirror_anon_pte(vma, address, page, ptl);
32465 pte_unmap_unlock(page_table, ptl);
32467 @@ -2172,6 +2374,12 @@ static int do_anonymous_page(struct mm_s
32468 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
32469 if (!pte_none(*page_table))
32472 +#ifdef CONFIG_PAX_SEGMEXEC
32473 + if (pax_find_mirror_vma(vma))
32474 + BUG_ON(TestSetPageLocked(page));
32477 inc_mm_counter(mm, anon_rss);
32478 lru_cache_add_active(page);
32479 page_add_new_anon_rmap(page, vma, address);
32480 @@ -2179,6 +2387,11 @@ static int do_anonymous_page(struct mm_s
32482 /* No need to invalidate - it was non-present before */
32483 update_mmu_cache(vma, address, entry);
32485 +#ifdef CONFIG_PAX_SEGMEXEC
32486 + pax_mirror_anon_pte(vma, address, page, ptl);
32490 pte_unmap_unlock(page_table, ptl);
32492 @@ -2320,6 +2533,12 @@ static int __do_fault(struct mm_struct *
32494 /* Only go through if we didn't race with anybody else... */
32495 if (likely(pte_same(*page_table, orig_pte))) {
32497 +#ifdef CONFIG_PAX_SEGMEXEC
32498 + if (anon && pax_find_mirror_vma(vma))
32499 + BUG_ON(TestSetPageLocked(page));
32502 flush_icache_page(vma, page);
32503 entry = mk_pte(page, vma->vm_page_prot);
32504 if (flags & FAULT_FLAG_WRITE)
32505 @@ -2340,6 +2559,14 @@ static int __do_fault(struct mm_struct *
32507 /* no need to invalidate: a not-present page won't be cached */
32508 update_mmu_cache(vma, address, entry);
32510 +#ifdef CONFIG_PAX_SEGMEXEC
32512 + pax_mirror_anon_pte(vma, address, page, ptl);
32514 + pax_mirror_file_pte(vma, address, page, ptl);
32518 mem_cgroup_uncharge_page(page);
32520 @@ -2423,6 +2650,11 @@ static noinline int do_no_pfn(struct mm_
32522 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
32523 set_pte_at(mm, address, page_table, entry);
32525 +#ifdef CONFIG_PAX_SEGMEXEC
32526 + pax_mirror_pfn_pte(vma, address, pfn, ptl);
32530 pte_unmap_unlock(page_table, ptl);
32532 @@ -2525,6 +2757,12 @@ static inline int handle_pte_fault(struc
32534 flush_tlb_page(vma, address);
32537 +#ifdef CONFIG_PAX_SEGMEXEC
32538 + pax_mirror_pte(vma, address, pte, pmd, ptl);
32543 pte_unmap_unlock(pte, ptl);
32545 @@ -2541,6 +2779,10 @@ int handle_mm_fault(struct mm_struct *mm
32549 +#ifdef CONFIG_PAX_SEGMEXEC
32550 + struct vm_area_struct *vma_m;
32553 __set_current_state(TASK_RUNNING);
32555 count_vm_event(PGFAULT);
32556 @@ -2548,6 +2790,34 @@ int handle_mm_fault(struct mm_struct *mm
32557 if (unlikely(is_vm_hugetlb_page(vma)))
32558 return hugetlb_fault(mm, vma, address, write_access);
32560 +#ifdef CONFIG_PAX_SEGMEXEC
32561 + vma_m = pax_find_mirror_vma(vma);
32563 + unsigned long address_m;
32568 + if (vma->vm_start > vma_m->vm_start) {
32569 + address_m = address;
32570 + address -= SEGMEXEC_TASK_SIZE;
32573 + address_m = address + SEGMEXEC_TASK_SIZE;
32575 + pgd_m = pgd_offset(mm, address_m);
32576 + pud_m = pud_alloc(mm, pgd_m, address_m);
32578 + return VM_FAULT_OOM;
32579 + pmd_m = pmd_alloc(mm, pud_m, address_m);
32581 + return VM_FAULT_OOM;
32582 + if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
32583 + return VM_FAULT_OOM;
32584 + pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
32588 pgd = pgd_offset(mm, address);
32589 pud = pud_alloc(mm, pgd, address);
32591 @@ -2641,7 +2911,7 @@ static int __init gate_vma_init(void)
32592 gate_vma.vm_start = FIXADDR_USER_START;
32593 gate_vma.vm_end = FIXADDR_USER_END;
32594 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
32595 - gate_vma.vm_page_prot = __P101;
32596 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
32598 * Make sure the vDSO gets into every core dump.
32599 * Dumping its contents makes post-mortem fully interpretable later
32600 diff -urNp linux-2.6.25.10/mm/mempolicy.c linux-2.6.25.10/mm/mempolicy.c
32601 --- linux-2.6.25.10/mm/mempolicy.c 2008-07-02 23:46:47.000000000 -0400
32602 +++ linux-2.6.25.10/mm/mempolicy.c 2008-07-03 16:53:27.000000000 -0400
32603 @@ -433,6 +433,10 @@ static int mbind_range(struct vm_area_st
32604 struct vm_area_struct *next;
32607 +#ifdef CONFIG_PAX_SEGMEXEC
32608 + struct vm_area_struct *vma_m;
32612 for (; vma && vma->vm_start < end; vma = next) {
32613 next = vma->vm_next;
32614 @@ -444,6 +448,16 @@ static int mbind_range(struct vm_area_st
32615 err = policy_vma(vma, new);
32619 +#ifdef CONFIG_PAX_SEGMEXEC
32620 + vma_m = pax_find_mirror_vma(vma);
32622 + err = policy_vma(vma_m, new);
32631 @@ -809,6 +823,17 @@ static long do_mbind(unsigned long start
32636 +#ifdef CONFIG_PAX_SEGMEXEC
32637 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
32638 + if (end > SEGMEXEC_TASK_SIZE)
32643 + if (end > TASK_SIZE)
32649 diff -urNp linux-2.6.25.10/mm/mlock.c linux-2.6.25.10/mm/mlock.c
32650 --- linux-2.6.25.10/mm/mlock.c 2008-07-02 23:46:47.000000000 -0400
32651 +++ linux-2.6.25.10/mm/mlock.c 2008-07-03 16:53:27.000000000 -0400
32653 #include <linux/sched.h>
32654 #include <linux/module.h>
32655 #include <linux/vs_memory.h>
32656 +#include <linux/grsecurity.h>
32658 int can_do_mlock(void)
32660 @@ -95,6 +96,17 @@ static int do_mlock(unsigned long start,
32665 +#ifdef CONFIG_PAX_SEGMEXEC
32666 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
32667 + if (end > SEGMEXEC_TASK_SIZE)
32672 + if (end > TASK_SIZE)
32675 vma = find_vma_prev(current->mm, start, &prev);
32676 if (!vma || vma->vm_start > start)
32678 @@ -152,6 +164,7 @@ asmlinkage long sys_mlock(unsigned long
32679 lock_limit >>= PAGE_SHIFT;
32681 /* check against resource limits */
32682 + gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
32683 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
32684 error = do_mlock(start, len, 1);
32686 @@ -173,10 +186,10 @@ asmlinkage long sys_munlock(unsigned lon
32687 static int do_mlockall(int flags)
32689 struct vm_area_struct * vma, * prev = NULL;
32690 - unsigned int def_flags = 0;
32691 + unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
32693 if (flags & MCL_FUTURE)
32694 - def_flags = VM_LOCKED;
32695 + def_flags |= VM_LOCKED;
32696 current->mm->def_flags = def_flags;
32697 if (flags == MCL_FUTURE)
32699 @@ -184,6 +197,12 @@ static int do_mlockall(int flags)
32700 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
32701 unsigned int newflags;
32703 +#ifdef CONFIG_PAX_SEGMEXEC
32704 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
32708 + BUG_ON(vma->vm_end > TASK_SIZE);
32709 newflags = vma->vm_flags | VM_LOCKED;
32710 if (!(flags & MCL_CURRENT))
32711 newflags &= ~VM_LOCKED;
32712 @@ -213,6 +232,7 @@ asmlinkage long sys_mlockall(int flags)
32713 lock_limit >>= PAGE_SHIFT;
32716 + gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
32717 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
32719 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
32720 diff -urNp linux-2.6.25.10/mm/mmap.c linux-2.6.25.10/mm/mmap.c
32721 --- linux-2.6.25.10/mm/mmap.c 2008-07-02 23:46:47.000000000 -0400
32722 +++ linux-2.6.25.10/mm/mmap.c 2008-07-03 16:53:27.000000000 -0400
32724 #include <linux/mount.h>
32725 #include <linux/mempolicy.h>
32726 #include <linux/rmap.h>
32727 +#include <linux/grsecurity.h>
32729 #include <asm/uaccess.h>
32730 #include <asm/cacheflush.h>
32732 #define arch_rebalance_pgtables(addr, len) (addr)
32735 +static inline void verify_mm_writelocked(struct mm_struct *mm)
32737 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
32738 + if (unlikely(down_read_trylock(&mm->mmap_sem))) {
32739 + up_read(&mm->mmap_sem);
32745 static void unmap_region(struct mm_struct *mm,
32746 struct vm_area_struct *vma, struct vm_area_struct *prev,
32747 unsigned long start, unsigned long end);
32748 @@ -65,15 +76,23 @@ static void unmap_region(struct mm_struc
32749 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
32752 -pgprot_t protection_map[16] = {
32753 +pgprot_t protection_map[16] __read_only = {
32754 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
32755 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
32758 pgprot_t vm_get_page_prot(unsigned long vm_flags)
32760 - return protection_map[vm_flags &
32761 - (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
32762 + pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
32764 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
32765 + if (!nx_enabled &&
32766 + (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
32767 + (vm_flags & (VM_READ | VM_WRITE)))
32768 + prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
32773 EXPORT_SYMBOL(vm_get_page_prot);
32775 @@ -228,6 +247,7 @@ static struct vm_area_struct *remove_vma
32776 struct vm_area_struct *next = vma->vm_next;
32779 + BUG_ON(vma->vm_mirror);
32780 if (vma->vm_ops && vma->vm_ops->close)
32781 vma->vm_ops->close(vma);
32783 @@ -261,6 +281,7 @@ asmlinkage unsigned long sys_brk(unsigne
32784 * not page aligned -Ram Gupta
32786 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
32787 + gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
32788 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
32789 (mm->end_data - mm->start_data) > rlim)
32791 @@ -362,8 +383,12 @@ find_vma_prepare(struct mm_struct *mm, u
32793 if (vma_tmp->vm_end > addr) {
32795 - if (vma_tmp->vm_start <= addr)
32797 + if (vma_tmp->vm_start <= addr) {
32798 +//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
32799 +//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
32800 +//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
32803 __rb_link = &__rb_parent->rb_left;
32805 rb_prev = __rb_parent;
32806 @@ -687,6 +712,12 @@ static int
32807 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
32808 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
32811 +#ifdef CONFIG_PAX_SEGMEXEC
32812 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
32816 if (is_mergeable_vma(vma, file, vm_flags) &&
32817 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
32818 if (vma->vm_pgoff == vm_pgoff)
32819 @@ -706,6 +737,12 @@ static int
32820 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
32821 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
32824 +#ifdef CONFIG_PAX_SEGMEXEC
32825 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
32829 if (is_mergeable_vma(vma, file, vm_flags) &&
32830 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
32832 @@ -748,12 +785,19 @@ can_vma_merge_after(struct vm_area_struc
32833 struct vm_area_struct *vma_merge(struct mm_struct *mm,
32834 struct vm_area_struct *prev, unsigned long addr,
32835 unsigned long end, unsigned long vm_flags,
32836 - struct anon_vma *anon_vma, struct file *file,
32837 + struct anon_vma *anon_vma, struct file *file,
32838 pgoff_t pgoff, struct mempolicy *policy)
32840 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
32841 struct vm_area_struct *area, *next;
32843 +#ifdef CONFIG_PAX_SEGMEXEC
32844 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
32845 + struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
32847 + BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
32851 * We later require that vma->vm_flags == vm_flags,
32852 * so this tests vma->vm_flags & VM_SPECIAL, too.
32853 @@ -769,6 +813,15 @@ struct vm_area_struct *vma_merge(struct
32854 if (next && next->vm_end == end) /* cases 6, 7, 8 */
32855 next = next->vm_next;
32857 +#ifdef CONFIG_PAX_SEGMEXEC
32859 + prev_m = pax_find_mirror_vma(prev);
32861 + area_m = pax_find_mirror_vma(area);
32863 + next_m = pax_find_mirror_vma(next);
32867 * Can it merge with the predecessor?
32869 @@ -788,9 +841,24 @@ struct vm_area_struct *vma_merge(struct
32871 vma_adjust(prev, prev->vm_start,
32872 next->vm_end, prev->vm_pgoff, NULL);
32873 - } else /* cases 2, 5, 7 */
32875 +#ifdef CONFIG_PAX_SEGMEXEC
32877 + vma_adjust(prev_m, prev_m->vm_start,
32878 + next_m->vm_end, prev_m->vm_pgoff, NULL);
32881 + } else { /* cases 2, 5, 7 */
32882 vma_adjust(prev, prev->vm_start,
32883 end, prev->vm_pgoff, NULL);
32885 +#ifdef CONFIG_PAX_SEGMEXEC
32887 + vma_adjust(prev_m, prev_m->vm_start,
32888 + end_m, prev_m->vm_pgoff, NULL);
32895 @@ -801,12 +869,27 @@ struct vm_area_struct *vma_merge(struct
32896 mpol_equal(policy, vma_policy(next)) &&
32897 can_vma_merge_before(next, vm_flags,
32898 anon_vma, file, pgoff+pglen)) {
32899 - if (prev && addr < prev->vm_end) /* case 4 */
32900 + if (prev && addr < prev->vm_end) { /* case 4 */
32901 vma_adjust(prev, prev->vm_start,
32902 addr, prev->vm_pgoff, NULL);
32903 - else /* cases 3, 8 */
32905 +#ifdef CONFIG_PAX_SEGMEXEC
32907 + vma_adjust(prev_m, prev_m->vm_start,
32908 + addr_m, prev_m->vm_pgoff, NULL);
32911 + } else { /* cases 3, 8 */
32912 vma_adjust(area, addr, next->vm_end,
32913 next->vm_pgoff - pglen, NULL);
32915 +#ifdef CONFIG_PAX_SEGMEXEC
32917 + vma_adjust(area_m, addr_m, next_m->vm_end,
32918 + next_m->vm_pgoff - pglen, NULL);
32925 @@ -881,14 +964,11 @@ none:
32926 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
32927 struct file *file, long pages)
32929 - const unsigned long stack_flags
32930 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
32933 mm->shared_vm += pages;
32934 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
32935 mm->exec_vm += pages;
32936 - } else if (flags & stack_flags)
32937 + } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
32938 mm->stack_vm += pages;
32939 if (flags & (VM_RESERVED|VM_IO))
32940 mm->reserved_vm += pages;
32941 @@ -916,7 +996,7 @@ unsigned long do_mmap_pgoff(struct file
32942 * (the exception is when the underlying filesystem is noexec
32943 * mounted, in which case we dont add PROT_EXEC.)
32945 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
32946 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
32947 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
32950 @@ -926,15 +1006,15 @@ unsigned long do_mmap_pgoff(struct file
32951 if (!(flags & MAP_FIXED))
32952 addr = round_hint_to_min(addr);
32954 - error = arch_mmap_check(addr, len, flags);
32958 /* Careful about overflows.. */
32959 len = PAGE_ALIGN(len);
32960 if (!len || len > TASK_SIZE)
32963 + error = arch_mmap_check(addr, len, flags);
32967 /* offset overflow? */
32968 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
32970 @@ -946,7 +1026,7 @@ unsigned long do_mmap_pgoff(struct file
32971 /* Obtain the address to map to. we verify (or select) it and ensure
32972 * that it represents a valid section of the address space.
32974 - addr = get_unmapped_area(file, addr, len, pgoff, flags);
32975 + addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
32976 if (addr & ~PAGE_MASK)
32979 @@ -957,6 +1037,26 @@ unsigned long do_mmap_pgoff(struct file
32980 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
32981 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
32983 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32984 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
32986 +#ifdef CONFIG_PAX_MPROTECT
32987 + if (mm->pax_flags & MF_PAX_MPROTECT) {
32988 + if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
32989 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
32991 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
32998 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
32999 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
33000 + vm_flags &= ~VM_PAGEEXEC;
33003 if (flags & MAP_LOCKED) {
33004 if (!can_do_mlock())
33006 @@ -969,6 +1069,7 @@ unsigned long do_mmap_pgoff(struct file
33007 locked += mm->locked_vm;
33008 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
33009 lock_limit >>= PAGE_SHIFT;
33010 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
33011 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
33014 @@ -1037,6 +1138,9 @@ unsigned long do_mmap_pgoff(struct file
33018 + if (!gr_acl_handle_mmap(file, prot))
33021 return mmap_region(file, addr, len, flags, vm_flags, pgoff,
33024 @@ -1050,10 +1154,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
33026 int vma_wants_writenotify(struct vm_area_struct *vma)
33028 - unsigned int vm_flags = vma->vm_flags;
33029 + unsigned long vm_flags = vma->vm_flags;
33031 /* If it was private or non-writable, the write bit is already clear */
33032 - if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
33033 + if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
33036 /* The backer wishes to know when pages are first written to? */
33037 @@ -1088,14 +1192,24 @@ unsigned long mmap_region(struct file *f
33038 unsigned long charged = 0;
33039 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
33041 +#ifdef CONFIG_PAX_SEGMEXEC
33042 + struct vm_area_struct *vma_m = NULL;
33046 + * mm->mmap_sem is required to protect against another thread
33047 + * changing the mappings in case we sleep.
33049 + verify_mm_writelocked(mm);
33051 /* Clear old maps */
33054 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33055 if (vma && vma->vm_start < addr + len) {
33056 if (do_munmap(mm, addr, len))
33058 - goto munmap_back;
33059 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33060 + BUG_ON(vma && vma->vm_start < addr + len);
33063 /* Check against address space limit. */
33064 @@ -1139,6 +1253,16 @@ munmap_back:
33068 +#ifdef CONFIG_PAX_SEGMEXEC
33069 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
33070 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
33079 vma->vm_start = addr;
33080 vma->vm_end = addr + len;
33081 @@ -1161,6 +1285,14 @@ munmap_back:
33082 error = file->f_op->mmap(file, vma);
33084 goto unmap_and_free_vma;
33086 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
33087 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
33088 + vma->vm_flags |= VM_PAGEEXEC;
33089 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
33093 } else if (vm_flags & VM_SHARED) {
33094 error = shmem_zero_setup(vma);
33096 @@ -1191,6 +1323,12 @@ munmap_back:
33097 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
33098 file = vma->vm_file;
33099 vma_link(mm, vma, prev, rb_link, rb_parent);
33101 +#ifdef CONFIG_PAX_SEGMEXEC
33103 + pax_mirror_vma(vma_m, vma);
33106 if (correct_wcount)
33107 atomic_inc(&inode->i_writecount);
33109 @@ -1201,10 +1339,18 @@ munmap_back:
33111 mpol_free(vma_policy(vma));
33112 kmem_cache_free(vm_area_cachep, vma);
33115 +#ifdef CONFIG_PAX_SEGMEXEC
33117 + kmem_cache_free(vm_area_cachep, vma_m);
33122 vx_vmpages_add(mm, len >> PAGE_SHIFT);
33123 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
33124 + track_exec_limit(mm, addr, addr + len, vm_flags);
33125 if (vm_flags & VM_LOCKED) {
33126 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
33127 make_pages_present(addr, addr + len);
33128 @@ -1223,6 +1369,12 @@ unmap_and_free_vma:
33129 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
33133 +#ifdef CONFIG_PAX_SEGMEXEC
33135 + kmem_cache_free(vm_area_cachep, vma_m);
33138 kmem_cache_free(vm_area_cachep, vma);
33141 @@ -1256,6 +1408,10 @@ arch_get_unmapped_area(struct file *filp
33142 if (flags & MAP_FIXED)
33145 +#ifdef CONFIG_PAX_RANDMMAP
33146 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
33150 addr = PAGE_ALIGN(addr);
33151 vma = find_vma(mm, addr);
33152 @@ -1264,10 +1420,10 @@ arch_get_unmapped_area(struct file *filp
33155 if (len > mm->cached_hole_size) {
33156 - start_addr = addr = mm->free_area_cache;
33157 + start_addr = addr = mm->free_area_cache;
33159 - start_addr = addr = TASK_UNMAPPED_BASE;
33160 - mm->cached_hole_size = 0;
33161 + start_addr = addr = mm->mmap_base;
33162 + mm->cached_hole_size = 0;
33166 @@ -1278,9 +1434,8 @@ full_search:
33167 * Start a new search - just in case we missed
33170 - if (start_addr != TASK_UNMAPPED_BASE) {
33171 - addr = TASK_UNMAPPED_BASE;
33172 - start_addr = addr;
33173 + if (start_addr != mm->mmap_base) {
33174 + start_addr = addr = mm->mmap_base;
33175 mm->cached_hole_size = 0;
33178 @@ -1302,10 +1457,16 @@ full_search:
33180 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
33183 +#ifdef CONFIG_PAX_SEGMEXEC
33184 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
33189 * Is this a new hole at the lowest possible address?
33191 - if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
33192 + if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
33193 mm->free_area_cache = addr;
33194 mm->cached_hole_size = ~0UL;
33196 @@ -1323,7 +1484,7 @@ arch_get_unmapped_area_topdown(struct fi
33198 struct vm_area_struct *vma;
33199 struct mm_struct *mm = current->mm;
33200 - unsigned long addr = addr0;
33201 + unsigned long base = mm->mmap_base, addr = addr0;
33203 /* requested length too big for entire address space */
33204 if (len > TASK_SIZE)
33205 @@ -1332,6 +1493,10 @@ arch_get_unmapped_area_topdown(struct fi
33206 if (flags & MAP_FIXED)
33209 +#ifdef CONFIG_PAX_RANDMMAP
33210 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
33213 /* requesting a specific address */
33215 addr = PAGE_ALIGN(addr);
33216 @@ -1389,13 +1554,21 @@ bottomup:
33217 * can happen with large stack limits and large mmap()
33220 + mm->mmap_base = TASK_UNMAPPED_BASE;
33222 +#ifdef CONFIG_PAX_RANDMMAP
33223 + if (mm->pax_flags & MF_PAX_RANDMMAP)
33224 + mm->mmap_base += mm->delta_mmap;
33227 + mm->free_area_cache = mm->mmap_base;
33228 mm->cached_hole_size = ~0UL;
33229 - mm->free_area_cache = TASK_UNMAPPED_BASE;
33230 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
33232 * Restore the topdown base:
33234 - mm->free_area_cache = mm->mmap_base;
33235 + mm->mmap_base = base;
33236 + mm->free_area_cache = base;
33237 mm->cached_hole_size = ~0UL;
33240 @@ -1404,6 +1577,12 @@ bottomup:
33242 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
33245 +#ifdef CONFIG_PAX_SEGMEXEC
33246 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
33251 * Is this a new hole at the highest possible address?
33253 @@ -1411,8 +1590,10 @@ void arch_unmap_area_topdown(struct mm_s
33254 mm->free_area_cache = addr;
33256 /* dont allow allocations above current base */
33257 - if (mm->free_area_cache > mm->mmap_base)
33258 + if (mm->free_area_cache > mm->mmap_base) {
33259 mm->free_area_cache = mm->mmap_base;
33260 + mm->cached_hole_size = ~0UL;
33265 @@ -1512,6 +1693,33 @@ out:
33266 return prev ? prev->vm_next : vma;
33269 +#ifdef CONFIG_PAX_SEGMEXEC
33270 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
33272 + struct vm_area_struct *vma_m;
33274 + BUG_ON(!vma || vma->vm_start >= vma->vm_end);
33275 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
33276 + BUG_ON(vma->vm_mirror);
33279 + BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
33280 + vma_m = vma->vm_mirror;
33281 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
33282 + BUG_ON(vma->vm_file != vma_m->vm_file);
33283 + BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
33284 + BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
33286 +#ifdef CONFIG_PAX_MPROTECT
33287 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
33289 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
33297 * Verify that the stack growth is acceptable and
33298 * update accounting. This is shared with both the
33299 @@ -1528,6 +1736,7 @@ static int acct_stack_growth(struct vm_a
33302 /* Stack limit test */
33303 + gr_learn_resource(current, RLIMIT_STACK, size, 1);
33304 if (size > rlim[RLIMIT_STACK].rlim_cur)
33307 @@ -1537,6 +1746,7 @@ static int acct_stack_growth(struct vm_a
33308 unsigned long limit;
33309 locked = mm->locked_vm + grow;
33310 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
33311 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
33312 if (locked > limit && !capable(CAP_IPC_LOCK))
33315 @@ -1551,7 +1761,7 @@ static int acct_stack_growth(struct vm_a
33316 * Overcommit.. This must be the final test, as it will
33317 * update security statistics.
33319 - if (security_vm_enough_memory(grow))
33320 + if (security_vm_enough_memory_mm(mm, grow))
33323 /* Ok, everything looks good - let it rip */
33324 @@ -1572,35 +1782,40 @@ static inline
33326 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
33329 + int error, locknext;
33331 if (!(vma->vm_flags & VM_GROWSUP))
33334 + /* Also guard against wrapping around to address 0. */
33335 + if (address < PAGE_ALIGN(address+1))
33336 + address = PAGE_ALIGN(address+1);
33341 * We must make sure the anon_vma is allocated
33342 * so that the anon_vma locking is not a noop.
33344 if (unlikely(anon_vma_prepare(vma)))
33346 + locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
33347 + if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
33349 anon_vma_lock(vma);
33351 + anon_vma_lock(vma->vm_next);
33354 * vma->vm_start/vm_end cannot change under us because the caller
33355 * is required to hold the mmap_sem in read mode. We need the
33356 - * anon_vma lock to serialize against concurrent expand_stacks.
33357 - * Also guard against wrapping around to address 0.
33358 + * anon_vma locks to serialize against concurrent expand_stacks
33359 + * and expand_upwards.
33361 - if (address < PAGE_ALIGN(address+4))
33362 - address = PAGE_ALIGN(address+4);
33364 - anon_vma_unlock(vma);
33369 /* Somebody else might have raced and expanded it already */
33370 - if (address > vma->vm_end) {
33371 + if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
33372 unsigned long size, grow;
33374 size = address - vma->vm_start;
33375 @@ -1610,6 +1825,8 @@ int expand_upwards(struct vm_area_struct
33377 vma->vm_end = address;
33380 + anon_vma_unlock(vma->vm_next);
33381 anon_vma_unlock(vma);
33384 @@ -1621,7 +1838,8 @@ int expand_upwards(struct vm_area_struct
33385 static inline int expand_downwards(struct vm_area_struct *vma,
33386 unsigned long address)
33389 + int error, lockprev = 0;
33390 + struct vm_area_struct *prev = NULL;
33393 * We must make sure the anon_vma is allocated
33394 @@ -1635,6 +1853,15 @@ static inline int expand_downwards(struc
33398 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
33399 + find_vma_prev(vma->vm_mm, address, &prev);
33400 + lockprev = prev && (prev->vm_flags & VM_GROWSUP);
33402 + if (lockprev && unlikely(anon_vma_prepare(prev)))
33405 + anon_vma_lock(prev);
33407 anon_vma_lock(vma);
33410 @@ -1644,9 +1871,15 @@ static inline int expand_downwards(struc
33413 /* Somebody else might have raced and expanded it already */
33414 - if (address < vma->vm_start) {
33415 + if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
33416 unsigned long size, grow;
33418 +#ifdef CONFIG_PAX_SEGMEXEC
33419 + struct vm_area_struct *vma_m;
33421 + vma_m = pax_find_mirror_vma(vma);
33424 size = vma->vm_end - address;
33425 grow = (vma->vm_start - address) >> PAGE_SHIFT;
33427 @@ -1654,9 +1887,20 @@ static inline int expand_downwards(struc
33429 vma->vm_start = address;
33430 vma->vm_pgoff -= grow;
33431 + track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
33433 +#ifdef CONFIG_PAX_SEGMEXEC
33435 + vma_m->vm_start -= grow << PAGE_SHIFT;
33436 + vma_m->vm_pgoff -= grow;
33442 anon_vma_unlock(vma);
33444 + anon_vma_unlock(prev);
33448 @@ -1728,6 +1972,13 @@ static void remove_vma_list(struct mm_st
33450 long nrpages = vma_pages(vma);
33452 +#ifdef CONFIG_PAX_SEGMEXEC
33453 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
33454 + vma = remove_vma(vma);
33459 vx_vmpages_sub(mm, nrpages);
33460 if (vma->vm_flags & VM_LOCKED)
33461 vx_vmlocked_sub(mm, nrpages);
33462 @@ -1774,6 +2025,16 @@ detach_vmas_to_be_unmapped(struct mm_str
33464 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
33467 +#ifdef CONFIG_PAX_SEGMEXEC
33468 + if (vma->vm_mirror) {
33469 + BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
33470 + vma->vm_mirror->vm_mirror = NULL;
33471 + vma->vm_mirror->vm_flags &= ~VM_EXEC;
33472 + vma->vm_mirror = NULL;
33476 rb_erase(&vma->vm_rb, &mm->mm_rb);
33479 @@ -1793,6 +2054,102 @@ detach_vmas_to_be_unmapped(struct mm_str
33480 * Split a vma into two pieces at address 'addr', a new vma is allocated
33481 * either for the first part or the tail.
33484 +#ifdef CONFIG_PAX_SEGMEXEC
33485 +int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
33486 + unsigned long addr, int new_below)
33488 + struct mempolicy *pol;
33489 + struct vm_area_struct *new, *vma_m, *new_m = NULL;
33490 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
33492 + if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
33495 + vma_m = pax_find_mirror_vma(vma);
33497 + BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
33498 + if (mm->map_count >= sysctl_max_map_count-1)
33500 + } else if (mm->map_count >= sysctl_max_map_count)
33503 + new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
33508 + new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
33510 + kmem_cache_free(vm_area_cachep, new);
33515 + /* most fields are the same, copy all, and then fixup */
33519 + new->vm_end = addr;
33521 + new->vm_start = addr;
33522 + new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
33527 + new_m->vm_mirror = new;
33528 + new->vm_mirror = new_m;
33531 + new_m->vm_end = addr_m;
33533 + new_m->vm_start = addr_m;
33534 + new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
33538 + pol = mpol_copy(vma_policy(vma));
33539 + if (IS_ERR(pol)) {
33541 + kmem_cache_free(vm_area_cachep, new_m);
33542 + kmem_cache_free(vm_area_cachep, new);
33543 + return PTR_ERR(pol);
33545 + vma_set_policy(new, pol);
33547 + if (new->vm_file)
33548 + get_file(new->vm_file);
33550 + if (new->vm_ops && new->vm_ops->open)
33551 + new->vm_ops->open(new);
33554 + vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
33555 + ((addr - new->vm_start) >> PAGE_SHIFT), new);
33557 + vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
33561 + vma_set_policy(new_m, pol);
33563 + if (new_m->vm_file)
33564 + get_file(new_m->vm_file);
33566 + if (new_m->vm_ops && new_m->vm_ops->open)
33567 + new_m->vm_ops->open(new_m);
33570 + vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
33571 + ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
33573 + vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
33579 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
33580 unsigned long addr, int new_below)
33582 @@ -1840,17 +2197,37 @@ int split_vma(struct mm_struct * mm, str
33588 /* Munmap is split into 2 main parts -- this part which finds
33589 * what needs doing, and the areas themselves, which do the
33590 * work. This now handles partial unmappings.
33591 * Jeremy Fitzhardinge <jeremy@goop.org>
33593 +#ifdef CONFIG_PAX_SEGMEXEC
33594 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
33596 + int ret = __do_munmap(mm, start, len);
33597 + if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
33600 + return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
33603 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
33605 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
33609 struct vm_area_struct *vma, *prev, *last;
33612 + * mm->mmap_sem is required to protect against another thread
33613 + * changing the mappings in case we sleep.
33615 + verify_mm_writelocked(mm);
33617 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
33620 @@ -1900,6 +2277,8 @@ int do_munmap(struct mm_struct *mm, unsi
33621 /* Fix up all other VM information */
33622 remove_vma_list(mm, vma);
33624 + track_exec_limit(mm, start, end, 0UL);
33629 @@ -1912,22 +2291,18 @@ asmlinkage long sys_munmap(unsigned long
33631 profile_munmap(addr);
33633 +#ifdef CONFIG_PAX_SEGMEXEC
33634 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
33635 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
33639 down_write(&mm->mmap_sem);
33640 ret = do_munmap(mm, addr, len);
33641 up_write(&mm->mmap_sem);
33645 -static inline void verify_mm_writelocked(struct mm_struct *mm)
33647 -#ifdef CONFIG_DEBUG_VM
33648 - if (unlikely(down_read_trylock(&mm->mmap_sem))) {
33650 - up_read(&mm->mmap_sem);
33656 * this is really a simplified "do_mmap". it only handles
33657 * anonymous maps. eventually we may be able to do some
33658 @@ -1941,6 +2316,11 @@ unsigned long do_brk(unsigned long addr,
33659 struct rb_node ** rb_link, * rb_parent;
33660 pgoff_t pgoff = addr >> PAGE_SHIFT;
33662 + unsigned long charged;
33664 +#ifdef CONFIG_PAX_SEGMEXEC
33665 + struct vm_area_struct *vma_m = NULL;
33668 len = PAGE_ALIGN(len);
33670 @@ -1958,19 +2338,34 @@ unsigned long do_brk(unsigned long addr,
33672 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
33674 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
33675 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
33676 + flags &= ~VM_EXEC;
33678 +#ifdef CONFIG_PAX_MPROTECT
33679 + if (mm->pax_flags & MF_PAX_MPROTECT)
33680 + flags &= ~VM_MAYEXEC;
33686 error = arch_mmap_check(addr, len, flags);
33690 + charged = len >> PAGE_SHIFT;
33693 * mlock MCL_FUTURE?
33695 if (mm->def_flags & VM_LOCKED) {
33696 unsigned long locked, lock_limit;
33697 - locked = len >> PAGE_SHIFT;
33698 + locked = charged;
33699 locked += mm->locked_vm;
33700 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
33701 lock_limit >>= PAGE_SHIFT;
33702 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
33703 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
33706 @@ -1984,23 +2379,23 @@ unsigned long do_brk(unsigned long addr,
33708 * Clear old maps. this also does some error checking for us
33711 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33712 if (vma && vma->vm_start < addr + len) {
33713 if (do_munmap(mm, addr, len))
33715 - goto munmap_back;
33716 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33717 + BUG_ON(vma && vma->vm_start < addr + len);
33720 /* Check against address space limits *after* clearing old maps... */
33721 - if (!may_expand_vm(mm, len >> PAGE_SHIFT))
33722 + if (!may_expand_vm(mm, charged))
33725 if (mm->map_count > sysctl_max_map_count)
33728 - if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
33729 - !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
33730 + if (security_vm_enough_memory(charged) ||
33731 + !vx_vmpages_avail(mm, charged))
33734 /* Can we just expand an old private anonymous mapping? */
33735 @@ -2012,10 +2407,21 @@ unsigned long do_brk(unsigned long addr,
33737 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
33739 - vm_unacct_memory(len >> PAGE_SHIFT);
33740 + vm_unacct_memory(charged);
33744 +#ifdef CONFIG_PAX_SEGMEXEC
33745 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
33746 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
33748 + kmem_cache_free(vm_area_cachep, vma);
33749 + vm_unacct_memory(charged);
33756 vma->vm_start = addr;
33757 vma->vm_end = addr + len;
33758 @@ -2023,12 +2429,19 @@ unsigned long do_brk(unsigned long addr,
33759 vma->vm_flags = flags;
33760 vma->vm_page_prot = vm_get_page_prot(flags);
33761 vma_link(mm, vma, prev, rb_link, rb_parent);
33763 +#ifdef CONFIG_PAX_SEGMEXEC
33765 + pax_mirror_vma(vma_m, vma);
33769 - vx_vmpages_add(mm, len >> PAGE_SHIFT);
33770 + vx_vmpages_add(mm, charged);
33771 if (flags & VM_LOCKED) {
33772 - vx_vmlocked_add(mm, len >> PAGE_SHIFT);
33773 + vx_vmlocked_add(mm, charged);
33774 make_pages_present(addr, addr + len);
33776 + track_exec_limit(mm, addr, addr + len, flags);
33780 @@ -2059,8 +2472,10 @@ void exit_mmap(struct mm_struct *mm)
33781 * Walk the list again, actually closing and freeing it,
33782 * with preemption enabled, without holding any MM locks.
33786 + vma->vm_mirror = NULL;
33787 vma = remove_vma(vma);
33790 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
33792 @@ -2074,6 +2489,10 @@ int insert_vm_struct(struct mm_struct *
33793 struct vm_area_struct * __vma, * prev;
33794 struct rb_node ** rb_link, * rb_parent;
33796 +#ifdef CONFIG_PAX_SEGMEXEC
33797 + struct vm_area_struct *vma_m = NULL;
33801 * The vm_pgoff of a purely anonymous vma should be irrelevant
33802 * until its first write fault, when page's anon_vma and index
33803 @@ -2096,7 +2515,22 @@ int insert_vm_struct(struct mm_struct *
33804 if ((vma->vm_flags & VM_ACCOUNT) &&
33805 security_vm_enough_memory_mm(mm, vma_pages(vma)))
33808 +#ifdef CONFIG_PAX_SEGMEXEC
33809 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
33810 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
33816 vma_link(mm, vma, prev, rb_link, rb_parent);
33818 +#ifdef CONFIG_PAX_SEGMEXEC
33820 + pax_mirror_vma(vma_m, vma);
33826 @@ -2114,6 +2548,8 @@ struct vm_area_struct *copy_vma(struct v
33827 struct rb_node **rb_link, *rb_parent;
33828 struct mempolicy *pol;
33830 + BUG_ON(vma->vm_mirror);
33833 * If anonymous vma has not yet been faulted, update new pgoff
33834 * to match new location, to increase its chance of merging.
33835 @@ -2154,6 +2590,35 @@ struct vm_area_struct *copy_vma(struct v
33839 +#ifdef CONFIG_PAX_SEGMEXEC
33840 +void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
33842 + struct vm_area_struct *prev_m;
33843 + struct rb_node **rb_link_m, *rb_parent_m;
33844 + struct mempolicy *pol_m;
33846 + BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
33847 + BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
33848 + BUG_ON(!vma_mpol_equal(vma, vma_m));
33850 + pol_m = vma_policy(vma);
33852 + vma_set_policy(vma_m, pol_m);
33853 + vma_m->vm_start += SEGMEXEC_TASK_SIZE;
33854 + vma_m->vm_end += SEGMEXEC_TASK_SIZE;
33855 + vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
33856 + vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
33857 + if (vma_m->vm_file)
33858 + get_file(vma_m->vm_file);
33859 + if (vma_m->vm_ops && vma_m->vm_ops->open)
33860 + vma_m->vm_ops->open(vma_m);
33861 + find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
33862 + vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
33863 + vma_m->vm_mirror = vma;
33864 + vma->vm_mirror = vma_m;
33869 * Return true if the calling process may expand its vm space by the passed
33871 @@ -2164,7 +2629,7 @@ int may_expand_vm(struct mm_struct *mm,
33874 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
33876 + gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
33877 if (cur + npages > lim)
33880 @@ -2233,6 +2698,15 @@ int install_special_mapping(struct mm_st
33881 vma->vm_start = addr;
33882 vma->vm_end = addr + len;
33884 +#ifdef CONFIG_PAX_MPROTECT
33885 + if (mm->pax_flags & MF_PAX_MPROTECT) {
33886 + if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
33887 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
33889 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
33893 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
33894 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
33896 diff -urNp linux-2.6.25.10/mm/mprotect.c linux-2.6.25.10/mm/mprotect.c
33897 --- linux-2.6.25.10/mm/mprotect.c 2008-07-02 23:46:47.000000000 -0400
33898 +++ linux-2.6.25.10/mm/mprotect.c 2008-07-03 16:53:27.000000000 -0400
33899 @@ -21,10 +21,17 @@
33900 #include <linux/syscalls.h>
33901 #include <linux/swap.h>
33902 #include <linux/swapops.h>
33903 +#include <linux/grsecurity.h>
33905 +#ifdef CONFIG_PAX_MPROTECT
33906 +#include <linux/elf.h>
33909 #include <asm/uaccess.h>
33910 #include <asm/pgtable.h>
33911 #include <asm/cacheflush.h>
33912 #include <asm/tlbflush.h>
33913 +#include <asm/mmu_context.h>
33915 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
33916 unsigned long addr, unsigned long end, pgprot_t newprot,
33917 @@ -127,6 +134,48 @@ static void change_protection(struct vm_
33918 flush_tlb_range(vma, start, end);
33921 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
33922 +/* called while holding the mmap semaphor for writing except stack expansion */
33923 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
33925 + unsigned long oldlimit, newlimit = 0UL;
33927 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
33930 + spin_lock(&mm->page_table_lock);
33931 + oldlimit = mm->context.user_cs_limit;
33932 + if ((prot & VM_EXEC) && oldlimit < end)
33933 + /* USER_CS limit moved up */
33935 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
33936 + /* USER_CS limit moved down */
33937 + newlimit = start;
33940 + mm->context.user_cs_limit = newlimit;
33944 + cpus_clear(mm->context.cpu_user_cs_mask);
33945 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
33948 + set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
33950 + spin_unlock(&mm->page_table_lock);
33951 + if (newlimit == end) {
33952 + struct vm_area_struct *vma = find_vma(mm, oldlimit);
33954 + for (; vma && vma->vm_start < end; vma = vma->vm_next)
33955 + if (is_vm_hugetlb_page(vma))
33956 + hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
33958 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
33964 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
33965 unsigned long start, unsigned long end, unsigned long newflags)
33966 @@ -139,6 +188,14 @@ mprotect_fixup(struct vm_area_struct *vm
33968 int dirty_accountable = 0;
33970 +#ifdef CONFIG_PAX_SEGMEXEC
33971 + struct vm_area_struct *vma_m = NULL;
33972 + unsigned long start_m, end_m;
33974 + start_m = start + SEGMEXEC_TASK_SIZE;
33975 + end_m = end + SEGMEXEC_TASK_SIZE;
33978 if (newflags == oldflags) {
33981 @@ -161,6 +218,38 @@ mprotect_fixup(struct vm_area_struct *vm
33985 +#ifdef CONFIG_PAX_SEGMEXEC
33986 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
33987 + if (start != vma->vm_start) {
33988 + error = split_vma(mm, vma, start, 1);
33991 + BUG_ON(!*pprev || (*pprev)->vm_next == vma);
33992 + *pprev = (*pprev)->vm_next;
33995 + if (end != vma->vm_end) {
33996 + error = split_vma(mm, vma, end, 0);
34001 + if (pax_find_mirror_vma(vma)) {
34002 + error = __do_munmap(mm, start_m, end_m - start_m);
34006 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34011 + vma->vm_flags = newflags;
34012 + pax_mirror_vma(vma_m, vma);
34018 * First try to merge with previous and/or next vma.
34020 @@ -211,6 +300,70 @@ fail:
34024 +#ifdef CONFIG_PAX_MPROTECT
34025 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
34026 + * therefore we'll grant them VM_MAYWRITE once during their life.
34028 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
34029 + * basis because we want to allow the common case and not the special ones.
34031 +static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
34033 + struct elfhdr elf_h;
34034 + struct elf_phdr elf_p;
34035 + elf_addr_t dyn_offset = 0UL;
34037 + unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
34039 +#ifndef CONFIG_PAX_NOELFRELOCS
34040 + if ((vma->vm_start != start) ||
34042 + !(vma->vm_flags & VM_MAYEXEC) ||
34043 + (vma->vm_flags & VM_MAYNOTWRITE))
34048 + if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
34049 + memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
34051 +#ifdef CONFIG_PAX_ETEXECRELOCS
34052 + (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
34054 + elf_h.e_type != ET_DYN ||
34057 + !elf_check_arch(&elf_h) ||
34058 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
34059 + elf_h.e_phnum > j)
34062 + for (i = 0UL; i < elf_h.e_phnum; i++) {
34063 + if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
34065 + if (elf_p.p_type == PT_DYNAMIC) {
34066 + dyn_offset = elf_p.p_offset;
34070 + if (elf_h.e_phnum <= j)
34075 + if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
34077 + if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
34078 + vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
34079 + gr_log_textrel(vma);
34083 + } while (dyn.d_tag != DT_NULL);
34089 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
34091 @@ -230,6 +383,17 @@ sys_mprotect(unsigned long start, size_t
34096 +#ifdef CONFIG_PAX_SEGMEXEC
34097 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
34098 + if (end > SEGMEXEC_TASK_SIZE)
34103 + if (end > TASK_SIZE)
34106 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
34109 @@ -237,7 +401,7 @@ sys_mprotect(unsigned long start, size_t
34111 * Does the application expect PROT_READ to imply PROT_EXEC:
34113 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
34114 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
34117 vm_flags = calc_vm_prot_bits(prot);
34118 @@ -269,6 +433,16 @@ sys_mprotect(unsigned long start, size_t
34119 if (start > vma->vm_start)
34122 + if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
34127 +#ifdef CONFIG_PAX_MPROTECT
34128 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
34129 + pax_handle_maywrite(vma, start);
34132 for (nstart = start ; ; ) {
34133 unsigned long newflags;
34135 @@ -282,6 +456,12 @@ sys_mprotect(unsigned long start, size_t
34139 +#ifdef CONFIG_PAX_MPROTECT
34140 + /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
34141 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
34142 + newflags &= ~VM_MAYWRITE;
34145 error = security_file_mprotect(vma, reqprot, prot);
34148 @@ -292,6 +472,9 @@ sys_mprotect(unsigned long start, size_t
34149 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
34153 + track_exec_limit(current->mm, nstart, tmp, vm_flags);
34157 if (nstart < prev->vm_end)
34158 diff -urNp linux-2.6.25.10/mm/mremap.c linux-2.6.25.10/mm/mremap.c
34159 --- linux-2.6.25.10/mm/mremap.c 2008-07-02 23:46:47.000000000 -0400
34160 +++ linux-2.6.25.10/mm/mremap.c 2008-07-03 16:53:27.000000000 -0400
34161 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
34163 pte = ptep_clear_flush(vma, old_addr, old_pte);
34164 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
34166 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
34167 + if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
34168 + pte = pte_exprotect(pte);
34171 set_pte_at(mm, new_addr, new_pte, pte);
34174 @@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
34175 struct vm_area_struct *vma;
34176 unsigned long ret = -EINVAL;
34177 unsigned long charged = 0;
34178 + unsigned long pax_task_size = TASK_SIZE;
34180 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
34182 @@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
34186 +#ifdef CONFIG_PAX_SEGMEXEC
34187 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
34188 + pax_task_size = SEGMEXEC_TASK_SIZE;
34191 + if (new_len > pax_task_size || addr > pax_task_size-new_len ||
34192 + old_len > pax_task_size || addr > pax_task_size-old_len)
34195 /* new_addr is only valid if MREMAP_FIXED is specified */
34196 if (flags & MREMAP_FIXED) {
34197 if (new_addr & ~PAGE_MASK)
34198 @@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
34199 if (!(flags & MREMAP_MAYMOVE))
34202 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
34203 + if (new_addr > pax_task_size - new_len)
34206 /* Check if the location we're moving into overlaps the
34207 * old location at all, and fail if it does.
34209 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
34212 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
34213 + if (addr + old_len > new_addr && new_addr + new_len > addr)
34216 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
34217 @@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
34222 +#ifdef CONFIG_PAX_SEGMEXEC
34223 + if (pax_find_mirror_vma(vma)) {
34229 /* We can't remap across vm area boundaries */
34230 if (old_len > vma->vm_end - addr)
34232 @@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
34233 if (old_len == vma->vm_end - addr &&
34234 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
34235 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
34236 - unsigned long max_addr = TASK_SIZE;
34237 + unsigned long max_addr = pax_task_size;
34239 max_addr = vma->vm_next->vm_start;
34240 /* can we just expand the current mapping? */
34241 @@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
34245 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
34249 @@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
34252 if (flags & MREMAP_MAYMOVE) {
34253 + unsigned long map_flags = 0;
34254 if (!(flags & MREMAP_FIXED)) {
34255 - unsigned long map_flags = 0;
34256 if (vma->vm_flags & VM_MAYSHARE)
34257 map_flags |= MAP_SHARED;
34259 @@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
34263 + map_flags = vma->vm_flags;
34264 ret = move_vma(vma, addr, old_len, new_len, new_addr);
34265 + if (!(ret & ~PAGE_MASK)) {
34266 + track_exec_limit(current->mm, addr, addr + old_len, 0UL);
34267 + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
34271 if (ret & ~PAGE_MASK)
34272 diff -urNp linux-2.6.25.10/mm/nommu.c linux-2.6.25.10/mm/nommu.c
34273 --- linux-2.6.25.10/mm/nommu.c 2008-07-02 23:46:47.000000000 -0400
34274 +++ linux-2.6.25.10/mm/nommu.c 2008-07-03 16:53:27.000000000 -0400
34275 @@ -405,15 +405,6 @@ struct vm_area_struct *find_vma(struct m
34277 EXPORT_SYMBOL(find_vma);
34281 - * - we don't extend stack VMAs under NOMMU conditions
34283 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
34285 - return find_vma(mm, addr);
34288 int expand_stack(struct vm_area_struct *vma, unsigned long address)
34291 diff -urNp linux-2.6.25.10/mm/page_alloc.c linux-2.6.25.10/mm/page_alloc.c
34292 --- linux-2.6.25.10/mm/page_alloc.c 2008-07-02 23:46:47.000000000 -0400
34293 +++ linux-2.6.25.10/mm/page_alloc.c 2008-07-03 16:53:27.000000000 -0400
34294 @@ -514,9 +514,20 @@ static void free_pages_bulk(struct zone
34296 static void free_one_page(struct zone *zone, struct page *page, int order)
34299 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
34300 + unsigned long index = 1UL << order;
34303 spin_lock(&zone->lock);
34304 zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
34305 zone->pages_scanned = 0;
34307 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
34308 + for (; index; --index)
34309 + sanitize_highpage(page + index - 1);
34312 __free_one_page(page, zone, order);
34313 spin_unlock(&zone->lock);
34315 @@ -641,8 +652,10 @@ static int prep_new_page(struct page *pa
34316 arch_alloc_page(page, order);
34317 kernel_map_pages(page, 1 << order, 1);
34319 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
34320 if (gfp_flags & __GFP_ZERO)
34321 prep_zero_page(page, order, gfp_flags);
34324 if (order && (gfp_flags & __GFP_COMP))
34325 prep_compound_page(page, order);
34326 @@ -1009,6 +1022,11 @@ static void free_hot_cold_page(struct pa
34327 list_add(&page->lru, &pcp->list);
34328 set_page_private(page, get_pageblock_migratetype(page));
34331 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
34332 + sanitize_highpage(page);
34335 if (pcp->count >= pcp->high) {
34336 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
34337 pcp->count -= pcp->batch;
34338 diff -urNp linux-2.6.25.10/mm/rmap.c linux-2.6.25.10/mm/rmap.c
34339 --- linux-2.6.25.10/mm/rmap.c 2008-07-02 23:46:47.000000000 -0400
34340 +++ linux-2.6.25.10/mm/rmap.c 2008-07-03 16:53:27.000000000 -0400
34341 @@ -64,6 +64,10 @@ int anon_vma_prepare(struct vm_area_stru
34342 struct mm_struct *mm = vma->vm_mm;
34343 struct anon_vma *allocated, *locked;
34345 +#ifdef CONFIG_PAX_SEGMEXEC
34346 + struct vm_area_struct *vma_m;
34349 anon_vma = find_mergeable_anon_vma(vma);
34352 @@ -80,6 +84,15 @@ int anon_vma_prepare(struct vm_area_stru
34353 /* page_table_lock to protect against threads */
34354 spin_lock(&mm->page_table_lock);
34355 if (likely(!vma->anon_vma)) {
34357 +#ifdef CONFIG_PAX_SEGMEXEC
34358 + vma_m = pax_find_mirror_vma(vma);
34360 + vma_m->anon_vma = anon_vma;
34361 + __anon_vma_link(vma_m);
34365 vma->anon_vma = anon_vma;
34366 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
34368 diff -urNp linux-2.6.25.10/mm/shmem.c linux-2.6.25.10/mm/shmem.c
34369 --- linux-2.6.25.10/mm/shmem.c 2008-07-02 23:46:47.000000000 -0400
34370 +++ linux-2.6.25.10/mm/shmem.c 2008-07-03 16:53:27.000000000 -0400
34371 @@ -2517,7 +2517,7 @@ static struct file_system_type tmpfs_fs_
34372 .get_sb = shmem_get_sb,
34373 .kill_sb = kill_litter_super,
34375 -static struct vfsmount *shm_mnt;
34376 +struct vfsmount *shm_mnt;
34378 static int __init init_tmpfs(void)
34380 diff -urNp linux-2.6.25.10/mm/slab.c linux-2.6.25.10/mm/slab.c
34381 --- linux-2.6.25.10/mm/slab.c 2008-07-02 23:46:47.000000000 -0400
34382 +++ linux-2.6.25.10/mm/slab.c 2008-07-03 16:53:27.000000000 -0400
34383 @@ -305,7 +305,7 @@ struct kmem_list3 {
34384 * Need this for bootstrapping a per node allocator.
34386 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
34387 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
34388 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
34389 #define CACHE_CACHE 0
34390 #define SIZE_AC MAX_NUMNODES
34391 #define SIZE_L3 (2 * MAX_NUMNODES)
34392 @@ -654,14 +654,14 @@ struct cache_names {
34393 static struct cache_names __initdata cache_names[] = {
34394 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
34395 #include <linux/kmalloc_sizes.h>
34401 static struct arraycache_init initarray_cache __initdata =
34402 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
34403 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
34404 static struct arraycache_init initarray_generic =
34405 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
34406 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
34408 /* internal cache of cache description objs */
34409 static struct kmem_cache cache_cache = {
34410 @@ -3007,7 +3007,7 @@ retry:
34411 * there must be at least one object available for
34414 - BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
34415 + BUG_ON(slabp->inuse >= cachep->num);
34417 while (slabp->inuse < cachep->num && batchcount--) {
34418 STATS_INC_ALLOCED(cachep);
34419 diff -urNp linux-2.6.25.10/mm/swap.c linux-2.6.25.10/mm/swap.c
34420 --- linux-2.6.25.10/mm/swap.c 2008-07-02 23:46:47.000000000 -0400
34421 +++ linux-2.6.25.10/mm/swap.c 2008-07-03 16:53:27.000000000 -0400
34423 /* How many pages do we try to swap or page in/out together? */
34426 -static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
34427 -static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
34428 -static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
34429 +static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs);
34430 +static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs);
34431 +static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
34434 * This path almost never happens for VM activity - pages are normally
34435 diff -urNp linux-2.6.25.10/mm/tiny-shmem.c linux-2.6.25.10/mm/tiny-shmem.c
34436 --- linux-2.6.25.10/mm/tiny-shmem.c 2008-07-02 23:46:47.000000000 -0400
34437 +++ linux-2.6.25.10/mm/tiny-shmem.c 2008-07-03 16:53:27.000000000 -0400
34438 @@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
34439 .kill_sb = kill_litter_super,
34442 -static struct vfsmount *shm_mnt;
34443 +struct vfsmount *shm_mnt;
34445 static int __init init_tmpfs(void)
34447 diff -urNp linux-2.6.25.10/mm/vmalloc.c linux-2.6.25.10/mm/vmalloc.c
34448 --- linux-2.6.25.10/mm/vmalloc.c 2008-07-02 23:46:47.000000000 -0400
34449 +++ linux-2.6.25.10/mm/vmalloc.c 2008-07-03 16:53:27.000000000 -0400
34450 @@ -246,20 +246,15 @@ static struct vm_struct *__get_vm_area_n
34451 (unsigned long)tmp->addr, align);
34454 - if ((size + addr) < addr)
34456 if (size + addr <= (unsigned long)tmp->addr)
34459 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
34460 - if (addr > end - size)
34463 if ((size + addr) < addr)
34465 if (addr > end - size)
34472 diff -urNp linux-2.6.25.10/net/bridge/br_stp_if.c linux-2.6.25.10/net/bridge/br_stp_if.c
34473 --- linux-2.6.25.10/net/bridge/br_stp_if.c 2008-07-02 23:46:47.000000000 -0400
34474 +++ linux-2.6.25.10/net/bridge/br_stp_if.c 2008-07-03 16:53:27.000000000 -0400
34475 @@ -148,7 +148,7 @@ static void br_stp_stop(struct net_bridg
34476 char *envp[] = { NULL };
34478 if (br->stp_enabled == BR_USER_STP) {
34479 - r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
34480 + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
34481 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
34484 diff -urNp linux-2.6.25.10/net/core/flow.c linux-2.6.25.10/net/core/flow.c
34485 --- linux-2.6.25.10/net/core/flow.c 2008-07-02 23:46:47.000000000 -0400
34486 +++ linux-2.6.25.10/net/core/flow.c 2008-07-03 16:53:27.000000000 -0400
34487 @@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
34489 static u32 flow_hash_shift;
34490 #define flow_hash_size (1 << flow_hash_shift)
34491 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
34492 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
34494 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
34496 @@ -53,7 +53,7 @@ struct flow_percpu_info {
34500 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
34501 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
34503 #define flow_hash_rnd_recalc(cpu) \
34504 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
34505 @@ -70,7 +70,7 @@ struct flow_flush_info {
34507 struct completion completion;
34509 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
34510 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
34512 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
34514 diff -urNp linux-2.6.25.10/net/dccp/ccids/ccid3.c linux-2.6.25.10/net/dccp/ccids/ccid3.c
34515 --- linux-2.6.25.10/net/dccp/ccids/ccid3.c 2008-07-02 23:46:47.000000000 -0400
34516 +++ linux-2.6.25.10/net/dccp/ccids/ccid3.c 2008-07-03 16:53:27.000000000 -0400
34518 static int ccid3_debug;
34519 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
34521 -#define ccid3_pr_debug(format, a...)
34522 +#define ccid3_pr_debug(format, a...) do {} while (0)
34526 diff -urNp linux-2.6.25.10/net/dccp/dccp.h linux-2.6.25.10/net/dccp/dccp.h
34527 --- linux-2.6.25.10/net/dccp/dccp.h 2008-07-02 23:46:47.000000000 -0400
34528 +++ linux-2.6.25.10/net/dccp/dccp.h 2008-07-03 16:53:27.000000000 -0400
34529 @@ -43,8 +43,8 @@ extern int dccp_debug;
34530 #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
34531 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
34533 -#define dccp_pr_debug(format, a...)
34534 -#define dccp_pr_debug_cat(format, a...)
34535 +#define dccp_pr_debug(format, a...) do {} while (0)
34536 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
34539 extern struct inet_hashinfo dccp_hashinfo;
34540 diff -urNp linux-2.6.25.10/net/ipv4/inet_connection_sock.c linux-2.6.25.10/net/ipv4/inet_connection_sock.c
34541 --- linux-2.6.25.10/net/ipv4/inet_connection_sock.c 2008-07-02 23:46:47.000000000 -0400
34542 +++ linux-2.6.25.10/net/ipv4/inet_connection_sock.c 2008-07-03 16:53:27.000000000 -0400
34545 #include <linux/module.h>
34546 #include <linux/jhash.h>
34547 +#include <linux/grsecurity.h>
34549 #include <net/inet_connection_sock.h>
34550 #include <net/inet_hashtables.h>
34551 diff -urNp linux-2.6.25.10/net/ipv4/inet_hashtables.c linux-2.6.25.10/net/ipv4/inet_hashtables.c
34552 --- linux-2.6.25.10/net/ipv4/inet_hashtables.c 2008-07-02 23:46:47.000000000 -0400
34553 +++ linux-2.6.25.10/net/ipv4/inet_hashtables.c 2008-07-03 16:53:27.000000000 -0400
34554 @@ -18,12 +18,15 @@
34555 #include <linux/sched.h>
34556 #include <linux/slab.h>
34557 #include <linux/wait.h>
34558 +#include <linux/grsecurity.h>
34560 #include <net/inet_connection_sock.h>
34561 #include <net/inet_hashtables.h>
34562 #include <net/route.h>
34563 #include <net/ip.h>
34565 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
34568 * Allocate and initialize a new local port bind bucket.
34569 * The bindhash mutex for snum's hash chain must be held here.
34570 @@ -467,6 +470,8 @@ ok:
34572 spin_unlock(&head->lock);
34574 + gr_update_task_in_ip_table(current, inet_sk(sk));
34577 inet_twsk_deschedule(tw, death_row);
34579 diff -urNp linux-2.6.25.10/net/ipv4/netfilter/ipt_stealth.c linux-2.6.25.10/net/ipv4/netfilter/ipt_stealth.c
34580 --- linux-2.6.25.10/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
34581 +++ linux-2.6.25.10/net/ipv4/netfilter/ipt_stealth.c 2008-07-03 16:53:27.000000000 -0400
34583 +/* Kernel module to add stealth support.
34585 + * Copyright (C) 2002-2006 Brad Spengler <spender@grsecurity.net>
34589 +#include <linux/kernel.h>
34590 +#include <linux/module.h>
34591 +#include <linux/skbuff.h>
34592 +#include <linux/net.h>
34593 +#include <linux/sched.h>
34594 +#include <linux/inet.h>
34595 +#include <linux/stddef.h>
34597 +#include <net/ip.h>
34598 +#include <net/sock.h>
34599 +#include <net/tcp.h>
34600 +#include <net/udp.h>
34601 +#include <net/route.h>
34602 +#include <net/inet_common.h>
34604 +#include <linux/netfilter_ipv4/ip_tables.h>
34606 +MODULE_LICENSE("GPL");
34608 +extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
34611 +match(const struct sk_buff *skb,
34612 + const struct net_device *in,
34613 + const struct net_device *out,
34614 + const struct xt_match *match,
34615 + const void *matchinfo,
34617 + unsigned int protoff,
34620 + struct iphdr *ip = ip_hdr(skb);
34621 + struct tcphdr th;
34622 + struct udphdr uh;
34623 + struct sock *sk = NULL;
34625 + if (!ip || offset) return false;
34627 + switch(ip->protocol) {
34628 + case IPPROTO_TCP:
34629 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
34633 + if (!(th.syn && !th.ack)) return false;
34634 + sk = inet_lookup_listener(skb->dev->nd_net, &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
34636 + case IPPROTO_UDP:
34637 + if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
34641 + sk = udp_v4_lookup(skb->dev->nd_net, ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
34647 + if(!sk) // port is being listened on, match this
34655 +/* Called when user tries to insert an entry of this type. */
34657 +checkentry(const char *tablename,
34659 + const struct xt_match *match,
34661 + unsigned int hook_mask)
34663 + const struct ipt_ip *ip = (const struct ipt_ip *)nip;
34665 + if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
34666 + ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
34667 + && (hook_mask & (1 << NF_INET_LOCAL_IN)))
34670 + printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
34676 +static struct xt_match stealth_match __read_mostly = {
34677 + .name = "stealth",
34678 + .family = AF_INET,
34680 + .checkentry = checkentry,
34682 + .me = THIS_MODULE
34685 +static int __init init(void)
34687 + return xt_register_match(&stealth_match);
34690 +static void __exit fini(void)
34692 + xt_unregister_match(&stealth_match);
34695 +module_init(init);
34696 +module_exit(fini);
34697 diff -urNp linux-2.6.25.10/net/ipv4/netfilter/Kconfig linux-2.6.25.10/net/ipv4/netfilter/Kconfig
34698 --- linux-2.6.25.10/net/ipv4/netfilter/Kconfig 2008-07-02 23:46:47.000000000 -0400
34699 +++ linux-2.6.25.10/net/ipv4/netfilter/Kconfig 2008-07-03 16:53:27.000000000 -0400
34700 @@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
34701 If you want to compile it as a module, say M here and read
34702 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
34704 +config IP_NF_MATCH_STEALTH
34705 + tristate "stealth match support"
34706 + depends on IP_NF_IPTABLES
34708 + Enabling this option will drop all syn packets coming to unserved tcp
34709 + ports as well as all packets coming to unserved udp ports. If you
34710 + are using your system to route any type of packets (ie. via NAT)
34711 + you should put this module at the end of your ruleset, since it will
34712 + drop packets that aren't going to ports that are listening on your
34713 + machine itself, it doesn't take into account that the packet might be
34714 + destined for someone on your internal network if you're using NAT for
34717 + To compile it as a module, choose M here. If unsure, say N.
34719 # `filter', generic and specific targets
34720 config IP_NF_FILTER
34721 tristate "Packet filtering"
34722 @@ -380,4 +395,3 @@ config IP_NF_ARP_MANGLE
34723 hardware and network addresses.
34727 diff -urNp linux-2.6.25.10/net/ipv4/netfilter/Makefile linux-2.6.25.10/net/ipv4/netfilter/Makefile
34728 --- linux-2.6.25.10/net/ipv4/netfilter/Makefile 2008-07-02 23:46:47.000000000 -0400
34729 +++ linux-2.6.25.10/net/ipv4/netfilter/Makefile 2008-07-03 16:53:27.000000000 -0400
34730 @@ -55,6 +55,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
34731 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
34732 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
34733 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
34734 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
34735 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
34736 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
34738 diff -urNp linux-2.6.25.10/net/ipv4/tcp.c linux-2.6.25.10/net/ipv4/tcp.c
34739 --- linux-2.6.25.10/net/ipv4/tcp.c 2008-07-02 23:46:47.000000000 -0400
34740 +++ linux-2.6.25.10/net/ipv4/tcp.c 2008-07-03 16:53:27.000000000 -0400
34741 @@ -1206,7 +1206,8 @@ int tcp_read_sock(struct sock *sk, read_
34743 while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
34744 if (offset < skb->len) {
34745 - size_t used, len;
34749 len = skb->len - offset;
34750 /* Stop reading if we hit a patch of urgent data */
34751 diff -urNp linux-2.6.25.10/net/ipv4/tcp_ipv4.c linux-2.6.25.10/net/ipv4/tcp_ipv4.c
34752 --- linux-2.6.25.10/net/ipv4/tcp_ipv4.c 2008-07-02 23:46:47.000000000 -0400
34753 +++ linux-2.6.25.10/net/ipv4/tcp_ipv4.c 2008-07-03 16:53:27.000000000 -0400
34755 #include <linux/jhash.h>
34756 #include <linux/init.h>
34757 #include <linux/times.h>
34758 +#include <linux/grsecurity.h>
34760 #include <net/net_namespace.h>
34761 #include <net/icmp.h>
34762 diff -urNp linux-2.6.25.10/net/ipv4/udp.c linux-2.6.25.10/net/ipv4/udp.c
34763 --- linux-2.6.25.10/net/ipv4/udp.c 2008-07-02 23:46:47.000000000 -0400
34764 +++ linux-2.6.25.10/net/ipv4/udp.c 2008-07-03 16:53:27.000000000 -0400
34766 #include <linux/skbuff.h>
34767 #include <linux/proc_fs.h>
34768 #include <linux/seq_file.h>
34769 +#include <linux/grsecurity.h>
34770 #include <net/net_namespace.h>
34771 #include <net/icmp.h>
34772 #include <net/route.h>
34773 @@ -106,6 +107,11 @@
34774 #include <net/xfrm.h>
34775 #include "udp_impl.h"
34777 +extern int gr_search_udp_recvmsg(const struct sock *sk,
34778 + const struct sk_buff *skb);
34779 +extern int gr_search_udp_sendmsg(const struct sock *sk,
34780 + const struct sockaddr_in *addr);
34783 * Snmp MIB for the UDP layer
34785 @@ -314,6 +320,13 @@ static struct sock *__udp4_lib_lookup(st
34789 +struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
34790 + __be32 daddr, __be16 dport, int dif)
34792 + return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
34796 static inline struct sock *udp_v4_mcast_next(struct sock *sk,
34797 __be16 loc_port, __be32 loc_addr,
34798 __be16 rmt_port, __be32 rmt_addr,
34799 @@ -600,9 +613,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
34800 dport = usin->sin_port;
34804 + if (!gr_search_udp_sendmsg(sk, usin))
34807 if (sk->sk_state != TCP_ESTABLISHED)
34808 return -EDESTADDRREQ;
34810 + if (!gr_search_udp_sendmsg(sk, NULL))
34813 daddr = inet->daddr;
34814 dport = inet->dport;
34815 /* Open fast path for connected socket.
34816 @@ -864,6 +884,11 @@ try_again:
34820 + if (!gr_search_udp_recvmsg(sk, skb)) {
34825 ulen = skb->len - sizeof(struct udphdr);
34828 diff -urNp linux-2.6.25.10/net/ipv6/exthdrs.c linux-2.6.25.10/net/ipv6/exthdrs.c
34829 --- linux-2.6.25.10/net/ipv6/exthdrs.c 2008-07-02 23:46:47.000000000 -0400
34830 +++ linux-2.6.25.10/net/ipv6/exthdrs.c 2008-07-03 16:53:27.000000000 -0400
34831 @@ -626,7 +626,7 @@ static struct tlvtype_proc tlvprochopopt
34832 .type = IPV6_TLV_JUMBO,
34833 .func = ipv6_hop_jumbo,
34839 int ipv6_parse_hopopts(struct sk_buff *skb)
34840 diff -urNp linux-2.6.25.10/net/ipv6/raw.c linux-2.6.25.10/net/ipv6/raw.c
34841 --- linux-2.6.25.10/net/ipv6/raw.c 2008-07-02 23:46:47.000000000 -0400
34842 +++ linux-2.6.25.10/net/ipv6/raw.c 2008-07-03 16:53:27.000000000 -0400
34843 @@ -617,7 +617,7 @@ out:
34847 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
34848 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
34849 struct flowi *fl, struct rt6_info *rt,
34850 unsigned int flags)
34852 diff -urNp linux-2.6.25.10/net/irda/ircomm/ircomm_tty.c linux-2.6.25.10/net/irda/ircomm/ircomm_tty.c
34853 --- linux-2.6.25.10/net/irda/ircomm/ircomm_tty.c 2008-07-02 23:46:47.000000000 -0400
34854 +++ linux-2.6.25.10/net/irda/ircomm/ircomm_tty.c 2008-07-03 16:53:27.000000000 -0400
34855 @@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
34856 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
34859 - if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
34860 + if (line >= IRCOMM_TTY_PORTS) {
34864 diff -urNp linux-2.6.25.10/net/mac80211/regdomain.c linux-2.6.25.10/net/mac80211/regdomain.c
34865 --- linux-2.6.25.10/net/mac80211/regdomain.c 2008-07-02 23:46:47.000000000 -0400
34866 +++ linux-2.6.25.10/net/mac80211/regdomain.c 2008-07-03 16:53:27.000000000 -0400
34867 @@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra
34868 { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */,
34869 { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */,
34870 { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */,
34875 static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
34876 { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
34877 { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
34878 { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
34884 diff -urNp linux-2.6.25.10/net/sctp/socket.c linux-2.6.25.10/net/sctp/socket.c
34885 --- linux-2.6.25.10/net/sctp/socket.c 2008-07-02 23:46:47.000000000 -0400
34886 +++ linux-2.6.25.10/net/sctp/socket.c 2008-07-03 16:53:27.000000000 -0400
34887 @@ -1391,7 +1391,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
34888 struct sctp_sndrcvinfo *sinfo;
34889 struct sctp_initmsg *sinit;
34890 sctp_assoc_t associd = 0;
34891 - sctp_cmsgs_t cmsgs = { NULL };
34892 + sctp_cmsgs_t cmsgs = { NULL, NULL };
34894 sctp_scope_t scope;
34896 diff -urNp linux-2.6.25.10/net/socket.c linux-2.6.25.10/net/socket.c
34897 --- linux-2.6.25.10/net/socket.c 2008-07-02 23:46:47.000000000 -0400
34898 +++ linux-2.6.25.10/net/socket.c 2008-07-03 16:53:27.000000000 -0400
34900 #include <linux/audit.h>
34901 #include <linux/wireless.h>
34902 #include <linux/nsproxy.h>
34903 +#include <linux/in.h>
34905 #include <asm/uaccess.h>
34906 #include <asm/unistd.h>
34908 #include <net/sock.h>
34909 #include <linux/netfilter.h>
34911 +extern void gr_attach_curr_ip(const struct sock *sk);
34912 +extern int gr_handle_sock_all(const int family, const int type,
34913 + const int protocol);
34914 +extern int gr_handle_sock_server(const struct sockaddr *sck);
34915 +extern int gr_handle_sock_server_other(const struct socket *sck);
34916 +extern int gr_handle_sock_client(const struct sockaddr *sck);
34917 +extern int gr_search_connect(const struct socket * sock,
34918 + const struct sockaddr_in * addr);
34919 +extern int gr_search_bind(const struct socket * sock,
34920 + const struct sockaddr_in * addr);
34921 +extern int gr_search_listen(const struct socket * sock);
34922 +extern int gr_search_accept(const struct socket * sock);
34923 +extern int gr_search_socket(const int domain, const int type,
34924 + const int protocol);
34926 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
34927 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
34928 unsigned long nr_segs, loff_t pos);
34929 @@ -297,7 +313,7 @@ static int sockfs_get_sb(struct file_sys
34933 -static struct vfsmount *sock_mnt __read_mostly;
34934 +struct vfsmount *sock_mnt __read_mostly;
34936 static struct file_system_type sock_fs_type = {
34938 @@ -1218,6 +1234,16 @@ asmlinkage long sys_socket(int family, i
34940 struct socket *sock;
34942 + if(!gr_search_socket(family, type, protocol)) {
34943 + retval = -EACCES;
34947 + if (gr_handle_sock_all(family, type, protocol)) {
34948 + retval = -EACCES;
34952 retval = sock_create(family, type, protocol, &sock);
34955 @@ -1348,6 +1374,12 @@ asmlinkage long sys_bind(int fd, struct
34957 err = move_addr_to_kernel(umyaddr, addrlen, address);
34959 + if (!gr_search_bind(sock, (struct sockaddr_in *)address) ||
34960 + gr_handle_sock_server((struct sockaddr *)address)) {
34965 err = security_socket_bind(sock,
34966 (struct sockaddr *)address,
34968 @@ -1356,6 +1388,7 @@ asmlinkage long sys_bind(int fd, struct
34969 (struct sockaddr *)
34973 fput_light(sock->file, fput_needed);
34976 @@ -1379,10 +1412,17 @@ asmlinkage long sys_listen(int fd, int b
34977 if ((unsigned)backlog > somaxconn)
34978 backlog = somaxconn;
34980 + if (gr_handle_sock_server_other(sock) ||
34981 + !gr_search_listen(sock)) {
34986 err = security_socket_listen(sock, backlog);
34988 err = sock->ops->listen(sock, backlog);
34991 fput_light(sock->file, fput_needed);
34994 @@ -1419,6 +1459,13 @@ asmlinkage long sys_accept(int fd, struc
34995 newsock->type = sock->type;
34996 newsock->ops = sock->ops;
34998 + if (gr_handle_sock_server_other(sock) ||
34999 + !gr_search_accept(sock)) {
35001 + sock_release(newsock);
35006 * We don't need try_module_get here, as the listening socket (sock)
35007 * has the protocol module (sock->ops->owner) held.
35008 @@ -1462,6 +1509,7 @@ asmlinkage long sys_accept(int fd, struc
35011 security_socket_post_accept(sock, newsock);
35012 + gr_attach_curr_ip(newsock->sk);
35015 fput_light(sock->file, fput_needed);
35016 @@ -1495,6 +1543,7 @@ asmlinkage long sys_connect(int fd, stru
35018 struct socket *sock;
35019 char address[MAX_SOCK_ADDR];
35020 + struct sockaddr *sck;
35021 int err, fput_needed;
35023 sock = sockfd_lookup_light(fd, &err, &fput_needed);
35024 @@ -1504,6 +1553,13 @@ asmlinkage long sys_connect(int fd, stru
35028 + sck = (struct sockaddr *)address;
35029 + if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
35030 + gr_handle_sock_client(sck)) {
35036 security_socket_connect(sock, (struct sockaddr *)address, addrlen);
35038 @@ -1770,6 +1826,7 @@ asmlinkage long sys_shutdown(int fd, int
35039 err = sock->ops->shutdown(sock, how);
35040 fput_light(sock->file, fput_needed);
35046 diff -urNp linux-2.6.25.10/net/unix/af_unix.c linux-2.6.25.10/net/unix/af_unix.c
35047 --- linux-2.6.25.10/net/unix/af_unix.c 2008-07-02 23:46:47.000000000 -0400
35048 +++ linux-2.6.25.10/net/unix/af_unix.c 2008-07-03 16:53:27.000000000 -0400
35049 @@ -116,6 +116,7 @@
35050 #include <linux/security.h>
35051 #include <linux/vs_context.h>
35052 #include <linux/vs_limit.h>
35053 +#include <linux/grsecurity.h>
35055 static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
35056 static DEFINE_SPINLOCK(unix_table_lock);
35057 @@ -720,6 +721,12 @@ static struct sock *unix_find_other(stru
35058 err = -ECONNREFUSED;
35059 if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
35062 + if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
35067 u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
35070 @@ -740,6 +747,13 @@ static struct sock *unix_find_other(stru
35072 struct dentry *dentry;
35073 dentry = unix_sk(u)->dentry;
35075 + if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
35082 touch_atime(unix_sk(u)->mnt, dentry);
35084 @@ -819,9 +833,18 @@ static int unix_bind(struct socket *sock
35087 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
35089 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
35091 + goto out_mknod_dput;
35094 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0, NULL);
35096 goto out_mknod_dput;
35098 + gr_handle_create(dentry, nd.path.mnt);
35100 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
35101 dput(nd.path.dentry);
35102 nd.path.dentry = dentry;
35103 @@ -839,6 +862,10 @@ static int unix_bind(struct socket *sock
35107 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
35108 + sk->sk_peercred.pid = current->pid;
35111 list = &unix_socket_table[addr->hash];
35113 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
35114 diff -urNp linux-2.6.25.10/scripts/pnmtologo.c linux-2.6.25.10/scripts/pnmtologo.c
35115 --- linux-2.6.25.10/scripts/pnmtologo.c 2008-07-02 23:46:47.000000000 -0400
35116 +++ linux-2.6.25.10/scripts/pnmtologo.c 2008-07-03 16:53:27.000000000 -0400
35117 @@ -237,14 +237,14 @@ static void write_header(void)
35118 fprintf(out, " * Linux logo %s\n", logoname);
35119 fputs(" */\n\n", out);
35120 fputs("#include <linux/linux_logo.h>\n\n", out);
35121 - fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
35122 + fprintf(out, "static unsigned char %s_data[] = {\n",
35126 static void write_footer(void)
35128 fputs("\n};\n\n", out);
35129 - fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
35130 + fprintf(out, "struct linux_logo %s = {\n", logoname);
35131 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
35132 fprintf(out, " .width\t= %d,\n", logo_width);
35133 fprintf(out, " .height\t= %d,\n", logo_height);
35134 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
35135 fputs("\n};\n\n", out);
35137 /* write logo clut */
35138 - fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
35139 + fprintf(out, "static unsigned char %s_clut[] = {\n",
35142 for (i = 0; i < logo_clutsize; i++) {
35143 diff -urNp linux-2.6.25.10/security/commoncap.c linux-2.6.25.10/security/commoncap.c
35144 --- linux-2.6.25.10/security/commoncap.c 2008-07-02 23:46:47.000000000 -0400
35145 +++ linux-2.6.25.10/security/commoncap.c 2008-07-03 16:53:27.000000000 -0400
35146 @@ -24,15 +24,18 @@
35147 #include <linux/mount.h>
35148 #include <linux/sched.h>
35149 #include <linux/vs_context.h>
35150 +#include <linux/grsecurity.h>
35152 /* Global security state */
35154 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
35155 EXPORT_SYMBOL(securebits);
35157 +extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
35159 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
35161 - NETLINK_CB(skb).eff_cap = vx_mbcaps(current->cap_effective);
35162 + NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
35166 @@ -54,7 +57,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
35167 int cap_capable (struct task_struct *tsk, int cap)
35169 /* Derived from include/linux/sched.h:capable. */
35170 - if (vx_cap_raised(vxi, tsk->cap_effective, cap))
35171 + if (vx_cap_raised (vxi, tsk->cap_effective, cap))
35176 +int cap_capable_nolog (struct task_struct *tsk, int cap)
35178 + /* tsk = current for all callers */
35179 + if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
35183 @@ -352,8 +363,11 @@ void cap_bprm_apply_creds (struct linux_
35187 - current->suid = current->euid = current->fsuid = bprm->e_uid;
35188 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
35189 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
35190 + current->suid = current->euid = current->fsuid = bprm->e_uid;
35192 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
35193 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
35195 /* For init, we want to retain the capabilities set
35196 * in the init_task struct. Thus we skip the usual
35197 @@ -366,6 +380,8 @@ void cap_bprm_apply_creds (struct linux_
35198 cap_clear(current->cap_effective);
35201 + gr_handle_chroot_caps(current);
35203 /* AUD: Audit candidate if current->cap_effective is set */
35205 current->keep_capabilities = 0;
35206 @@ -592,7 +608,7 @@ int cap_vm_enough_memory(struct mm_struc
35208 int cap_sys_admin = 0;
35210 - if (cap_capable(current, CAP_SYS_ADMIN) == 0)
35211 + if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
35213 return __vm_enough_memory(mm, pages, cap_sys_admin);
35215 diff -urNp linux-2.6.25.10/security/dummy.c linux-2.6.25.10/security/dummy.c
35216 --- linux-2.6.25.10/security/dummy.c 2008-07-02 23:46:47.000000000 -0400
35217 +++ linux-2.6.25.10/security/dummy.c 2008-07-03 16:53:27.000000000 -0400
35219 #include <linux/ptrace.h>
35220 #include <linux/file.h>
35221 #include <linux/vs_context.h>
35222 +#include <linux/grsecurity.h>
35224 static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
35226 @@ -140,8 +141,11 @@ static void dummy_bprm_apply_creds (stru
35230 - current->suid = current->euid = current->fsuid = bprm->e_uid;
35231 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
35232 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
35233 + current->suid = current->euid = current->fsuid = bprm->e_uid;
35235 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
35236 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
35238 dummy_capget(current, ¤t->cap_effective, ¤t->cap_inheritable, ¤t->cap_permitted);
35240 diff -urNp linux-2.6.25.10/security/Kconfig linux-2.6.25.10/security/Kconfig
35241 --- linux-2.6.25.10/security/Kconfig 2008-07-02 23:46:47.000000000 -0400
35242 +++ linux-2.6.25.10/security/Kconfig 2008-07-03 16:53:27.000000000 -0400
35245 menu "Security options"
35247 +source grsecurity/Kconfig
35252 + bool "Enable various PaX features"
35253 + depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
35255 + This allows you to enable various PaX features. PaX adds
35256 + intrusion prevention mechanisms to the kernel that reduce
35257 + the risks posed by exploitable memory corruption bugs.
35259 +menu "PaX Control"
35262 +config PAX_SOFTMODE
35263 + bool 'Support soft mode'
35265 + Enabling this option will allow you to run PaX in soft mode, that
35266 + is, PaX features will not be enforced by default, only on executables
35267 + marked explicitly. You must also enable PT_PAX_FLAGS support as it
35268 + is the only way to mark executables for soft mode use.
35270 + Soft mode can be activated by using the "pax_softmode=1" kernel command
35271 + line option on boot. Furthermore you can control various PaX features
35272 + at runtime via the entries in /proc/sys/kernel/pax.
35275 + bool 'Use legacy ELF header marking'
35277 + Enabling this option will allow you to control PaX features on
35278 + a per executable basis via the 'chpax' utility available at
35279 + http://pax.grsecurity.net/. The control flags will be read from
35280 + an otherwise reserved part of the ELF header. This marking has
35281 + numerous drawbacks (no support for soft-mode, toolchain does not
35282 + know about the non-standard use of the ELF header) therefore it
35283 + has been deprecated in favour of PT_PAX_FLAGS support.
35285 + If you have applications not marked by the PT_PAX_FLAGS ELF
35286 + program header then you MUST enable this option otherwise they
35287 + will not get any protection.
35289 + Note that if you enable PT_PAX_FLAGS marking support as well,
35290 + the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
35292 +config PAX_PT_PAX_FLAGS
35293 + bool 'Use ELF program header marking'
35295 + Enabling this option will allow you to control PaX features on
35296 + a per executable basis via the 'paxctl' utility available at
35297 + http://pax.grsecurity.net/. The control flags will be read from
35298 + a PaX specific ELF program header (PT_PAX_FLAGS). This marking
35299 + has the benefits of supporting both soft mode and being fully
35300 + integrated into the toolchain (the binutils patch is available
35301 + from http://pax.grsecurity.net).
35303 + If you have applications not marked by the PT_PAX_FLAGS ELF
35304 + program header then you MUST enable the EI_PAX marking support
35305 + otherwise they will not get any protection.
35307 + Note that if you enable the legacy EI_PAX marking support as well,
35308 + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
35311 + prompt 'MAC system integration'
35312 + default PAX_HAVE_ACL_FLAGS
35314 + Mandatory Access Control systems have the option of controlling
35315 + PaX flags on a per executable basis, choose the method supported
35316 + by your particular system.
35318 + - "none": if your MAC system does not interact with PaX,
35319 + - "direct": if your MAC system defines pax_set_initial_flags() itself,
35320 + - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
35322 + NOTE: this option is for developers/integrators only.
35324 + config PAX_NO_ACL_FLAGS
35327 + config PAX_HAVE_ACL_FLAGS
35330 + config PAX_HOOK_ACL_FLAGS
35336 +menu "Non-executable pages"
35340 + bool "Enforce non-executable pages"
35341 + depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
35343 + By design some architectures do not allow for protecting memory
35344 + pages against execution or even if they do, Linux does not make
35345 + use of this feature. In practice this means that if a page is
35346 + readable (such as the stack or heap) it is also executable.
35348 + There is a well known exploit technique that makes use of this
35349 + fact and a common programming mistake where an attacker can
35350 + introduce code of his choice somewhere in the attacked program's
35351 + memory (typically the stack or the heap) and then execute it.
35353 + If the attacked program was running with different (typically
35354 + higher) privileges than that of the attacker, then he can elevate
35355 + his own privilege level (e.g. get a root shell, write to files for
35356 + which he does not have write access to, etc).
35358 + Enabling this option will let you choose from various features
35359 + that prevent the injection and execution of 'foreign' code in
35362 + This will also break programs that rely on the old behaviour and
35363 + expect that dynamically allocated memory via the malloc() family
35364 + of functions is executable (which it is not). Notable examples
35365 + are the XFree86 4.x server, the java runtime and wine.
35367 +config PAX_PAGEEXEC
35368 + bool "Paging based non-executable pages"
35369 + 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)
35371 + This implementation is based on the paging feature of the CPU.
35372 + On i386 without hardware non-executable bit support there is a
35373 + variable but usually low performance impact, however on Intel's
35374 + P4 core based CPUs it is very high so you should not enable this
35375 + for kernels meant to be used on such CPUs.
35377 + On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
35378 + with hardware non-executable bit support there is no performance
35379 + impact, on ppc the impact is negligible.
35381 + Note that several architectures require various emulations due to
35382 + badly designed userland ABIs, this will cause a performance impact
35383 + but will disappear as soon as userland is fixed (e.g., ppc users
35384 + can make use of the secure-plt feature found in binutils).
35386 +config PAX_SEGMEXEC
35387 + bool "Segmentation based non-executable pages"
35388 + depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
35390 + This implementation is based on the segmentation feature of the
35391 + CPU and has a very small performance impact, however applications
35392 + will be limited to a 1.5 GB address space instead of the normal
35395 +config PAX_EMUTRAMP
35396 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
35397 + default y if PARISC || PPC32
35399 + There are some programs and libraries that for one reason or
35400 + another attempt to execute special small code snippets from
35401 + non-executable memory pages. Most notable examples are the
35402 + signal handler return code generated by the kernel itself and
35403 + the GCC trampolines.
35405 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
35406 + such programs will no longer work under your kernel.
35408 + As a remedy you can say Y here and use the 'chpax' or 'paxctl'
35409 + utilities to enable trampoline emulation for the affected programs
35410 + yet still have the protection provided by the non-executable pages.
35412 + On parisc and ppc you MUST enable this option and EMUSIGRT as
35413 + well, otherwise your system will not even boot.
35415 + Alternatively you can say N here and use the 'chpax' or 'paxctl'
35416 + utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
35417 + for the affected files.
35419 + NOTE: enabling this feature *may* open up a loophole in the
35420 + protection provided by non-executable pages that an attacker
35421 + could abuse. Therefore the best solution is to not have any
35422 + files on your system that would require this option. This can
35423 + be achieved by not using libc5 (which relies on the kernel
35424 + signal handler return code) and not using or rewriting programs
35425 + that make use of the nested function implementation of GCC.
35426 + Skilled users can just fix GCC itself so that it implements
35427 + nested function calls in a way that does not interfere with PaX.
35429 +config PAX_EMUSIGRT
35430 + bool "Automatically emulate sigreturn trampolines"
35431 + depends on PAX_EMUTRAMP && (PARISC || PPC32)
35434 + Enabling this option will have the kernel automatically detect
35435 + and emulate signal return trampolines executing on the stack
35436 + that would otherwise lead to task termination.
35438 + This solution is intended as a temporary one for users with
35439 + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
35440 + Modula-3 runtime, etc) or executables linked to such, basically
35441 + everything that does not specify its own SA_RESTORER function in
35442 + normal executable memory like glibc 2.1+ does.
35444 + On parisc and ppc you MUST enable this option, otherwise your
35445 + system will not even boot.
35447 + NOTE: this feature cannot be disabled on a per executable basis
35448 + and since it *does* open up a loophole in the protection provided
35449 + by non-executable pages, the best solution is to not have any
35450 + files on your system that would require this option.
35452 +config PAX_MPROTECT
35453 + bool "Restrict mprotect()"
35454 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
35456 + Enabling this option will prevent programs from
35457 + - changing the executable status of memory pages that were
35458 + not originally created as executable,
35459 + - making read-only executable pages writable again,
35460 + - creating executable pages from anonymous memory.
35462 + You should say Y here to complete the protection provided by
35463 + the enforcement of non-executable pages.
35465 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
35466 + this feature on a per file basis.
35468 +config PAX_NOELFRELOCS
35469 + bool "Disallow ELF text relocations"
35470 + depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
35472 + Non-executable pages and mprotect() restrictions are effective
35473 + in preventing the introduction of new executable code into an
35474 + attacked task's address space. There remain only two venues
35475 + for this kind of attack: if the attacker can execute already
35476 + existing code in the attacked task then he can either have it
35477 + create and mmap() a file containing his code or have it mmap()
35478 + an already existing ELF library that does not have position
35479 + independent code in it and use mprotect() on it to make it
35480 + writable and copy his code there. While protecting against
35481 + the former approach is beyond PaX, the latter can be prevented
35482 + by having only PIC ELF libraries on one's system (which do not
35483 + need to relocate their code). If you are sure this is your case,
35484 + then enable this option otherwise be careful as you may not even
35485 + be able to boot or log on your system (for example, some PAM
35486 + modules are erroneously compiled as non-PIC by default).
35488 + NOTE: if you are using dynamic ELF executables (as suggested
35489 + when using ASLR) then you must have made sure that you linked
35490 + your files using the PIC version of crt1 (the et_dyn.tar.gz package
35491 + referenced there has already been updated to support this).
35493 +config PAX_ETEXECRELOCS
35494 + bool "Allow ELF ET_EXEC text relocations"
35495 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
35498 + On some architectures there are incorrectly created applications
35499 + that require text relocations and would not work without enabling
35500 + this option. If you are an alpha, ia64 or parisc user, you should
35501 + enable this option and disable it once you have made sure that
35502 + none of your applications need it.
35505 + bool "Automatically emulate ELF PLT"
35506 + depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
35509 + Enabling this option will have the kernel automatically detect
35510 + and emulate the Procedure Linkage Table entries in ELF files.
35511 + On some architectures such entries are in writable memory, and
35512 + become non-executable leading to task termination. Therefore
35513 + it is mandatory that you enable this option on alpha, parisc,
35514 + ppc (if secure-plt is not used throughout in userland), sparc
35515 + and sparc64, otherwise your system would not even boot.
35517 + NOTE: this feature *does* open up a loophole in the protection
35518 + provided by the non-executable pages, therefore the proper
35519 + solution is to modify the toolchain to produce a PLT that does
35520 + not need to be writable.
35522 +config PAX_DLRESOLVE
35524 + depends on PAX_EMUPLT && (SPARC32 || SPARC64)
35527 +config PAX_SYSCALL
35529 + depends on PAX_PAGEEXEC && PPC32
35532 +config PAX_KERNEXEC
35533 + bool "Enforce non-executable kernel pages"
35534 + depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
35536 + This is the kernel land equivalent of PAGEEXEC and MPROTECT,
35537 + that is, enabling this option will make it harder to inject
35538 + and execute 'foreign' code in kernel memory itself.
35542 +menu "Address Space Layout Randomization"
35546 + bool "Address Space Layout Randomization"
35547 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
35549 + Many if not most exploit techniques rely on the knowledge of
35550 + certain addresses in the attacked program. The following options
35551 + will allow the kernel to apply a certain amount of randomization
35552 + to specific parts of the program thereby forcing an attacker to
35553 + guess them in most cases. Any failed guess will most likely crash
35554 + the attacked program which allows the kernel to detect such attempts
35555 + and react on them. PaX itself provides no reaction mechanisms,
35556 + instead it is strongly encouraged that you make use of Nergal's
35557 + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
35558 + (http://www.grsecurity.net/) built-in crash detection features or
35559 + develop one yourself.
35561 + By saying Y here you can choose to randomize the following areas:
35562 + - top of the task's kernel stack
35563 + - top of the task's userland stack
35564 + - base address for mmap() requests that do not specify one
35565 + (this includes all libraries)
35566 + - base address of the main executable
35568 + It is strongly recommended to say Y here as address space layout
35569 + randomization has negligible impact on performance yet it provides
35570 + a very effective protection.
35572 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
35573 + this feature on a per file basis.
35575 +config PAX_RANDKSTACK
35576 + bool "Randomize kernel stack base"
35577 + depends on PAX_ASLR && X86_TSC && X86_32
35579 + By saying Y here the kernel will randomize every task's kernel
35580 + stack on every system call. This will not only force an attacker
35581 + to guess it but also prevent him from making use of possible
35582 + leaked information about it.
35584 + Since the kernel stack is a rather scarce resource, randomization
35585 + may cause unexpected stack overflows, therefore you should very
35586 + carefully test your system. Note that once enabled in the kernel
35587 + configuration, this feature cannot be disabled on a per file basis.
35589 +config PAX_RANDUSTACK
35590 + bool "Randomize user stack base"
35591 + depends on PAX_ASLR
35593 + By saying Y here the kernel will randomize every task's userland
35594 + stack. The randomization is done in two steps where the second
35595 + one may apply a big amount of shift to the top of the stack and
35596 + cause problems for programs that want to use lots of memory (more
35597 + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
35598 + For this reason the second step can be controlled by 'chpax' or
35599 + 'paxctl' on a per file basis.
35601 +config PAX_RANDMMAP
35602 + bool "Randomize mmap() base"
35603 + depends on PAX_ASLR
35605 + By saying Y here the kernel will use a randomized base address for
35606 + mmap() requests that do not specify one themselves. As a result
35607 + all dynamically loaded libraries will appear at random addresses
35608 + and therefore be harder to exploit by a technique where an attacker
35609 + attempts to execute library code for his purposes (e.g. spawn a
35610 + shell from an exploited program that is running at an elevated
35611 + privilege level).
35613 + Furthermore, if a program is relinked as a dynamic ELF file, its
35614 + base address will be randomized as well, completing the full
35615 + randomization of the address space layout. Attacking such programs
35616 + becomes a guess game. You can find an example of doing this at
35617 + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
35618 + http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
35620 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
35621 + feature on a per file basis.
35625 +menu "Miscellaneous hardening features"
35627 +config PAX_MEMORY_SANITIZE
35628 + bool "Sanitize all freed memory"
35630 + By saying Y here the kernel will erase memory pages as soon as they
35631 + are freed. This in turn reduces the lifetime of data stored in the
35632 + pages, making it less likely that sensitive information such as
35633 + passwords, cryptographic secrets, etc stay in memory for too long.
35635 + This is especially useful for programs whose runtime is short, long
35636 + lived processes and the kernel itself benefit from this as long as
35637 + they operate on whole memory pages and ensure timely freeing of pages
35638 + that may hold sensitive information.
35640 + The tradeoff is performance impact, on a single CPU system kernel
35641 + compilation sees a 3% slowdown, other systems and workloads may vary
35642 + and you are advised to test this feature on your expected workload
35643 + before deploying it.
35645 + Note that this feature does not protect data stored in live pages,
35646 + e.g., process memory swapped to disk may stay there for a long time.
35648 +config PAX_MEMORY_UDEREF
35649 + bool "Prevent invalid userland pointer dereference"
35650 + depends on X86_32 && !COMPAT_VDSO
35652 + By saying Y here the kernel will be prevented from dereferencing
35653 + userland pointers in contexts where the kernel expects only kernel
35654 + pointers. This is both a useful runtime debugging feature and a
35655 + security measure that prevents exploiting a class of kernel bugs.
35657 + The tradeoff is that some virtualization solutions may experience
35658 + a huge slowdown and therefore you should not enable this feature
35659 + for kernels meant to run in such environments. Whether a given VM
35660 + solution is affected or not is best determined by simply trying it
35661 + out, the performance impact will be obvious right on boot as this
35662 + mechanism engages from very early on. A good rule of thumb is that
35663 + VMs running on CPUs without hardware virtualization support (i.e.,
35664 + the majority of IA-32 CPUs) will likely experience the slowdown.
35671 bool "Enable access key retention support"
35673 diff -urNp linux-2.6.25.10/sound/core/oss/pcm_oss.c linux-2.6.25.10/sound/core/oss/pcm_oss.c
35674 --- linux-2.6.25.10/sound/core/oss/pcm_oss.c 2008-07-02 23:46:47.000000000 -0400
35675 +++ linux-2.6.25.10/sound/core/oss/pcm_oss.c 2008-07-03 16:53:27.000000000 -0400
35676 @@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
35679 #else /* !CONFIG_SND_VERBOSE_PROCFS */
35680 -#define snd_pcm_oss_proc_init(pcm)
35681 -#define snd_pcm_oss_proc_done(pcm)
35682 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
35683 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
35684 #endif /* CONFIG_SND_VERBOSE_PROCFS */
35687 diff -urNp linux-2.6.25.10/sound/core/seq/seq_lock.h linux-2.6.25.10/sound/core/seq/seq_lock.h
35688 --- linux-2.6.25.10/sound/core/seq/seq_lock.h 2008-07-02 23:46:47.000000000 -0400
35689 +++ linux-2.6.25.10/sound/core/seq/seq_lock.h 2008-07-03 16:53:27.000000000 -0400
35690 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
35691 #else /* SMP || CONFIG_SND_DEBUG */
35693 typedef spinlock_t snd_use_lock_t; /* dummy */
35694 -#define snd_use_lock_init(lockp) /**/
35695 -#define snd_use_lock_use(lockp) /**/
35696 -#define snd_use_lock_free(lockp) /**/
35697 -#define snd_use_lock_sync(lockp) /**/
35698 +#define snd_use_lock_init(lockp) do {} while (0)
35699 +#define snd_use_lock_use(lockp) do {} while (0)
35700 +#define snd_use_lock_free(lockp) do {} while (0)
35701 +#define snd_use_lock_sync(lockp) do {} while (0)
35703 #endif /* SMP || CONFIG_SND_DEBUG */
35705 diff -urNp linux-2.6.25.10/sound/pci/ac97/ac97_patch.c linux-2.6.25.10/sound/pci/ac97/ac97_patch.c
35706 --- linux-2.6.25.10/sound/pci/ac97/ac97_patch.c 2008-07-02 23:46:47.000000000 -0400
35707 +++ linux-2.6.25.10/sound/pci/ac97/ac97_patch.c 2008-07-03 16:53:27.000000000 -0400
35708 @@ -1486,7 +1486,7 @@ static const struct snd_ac97_res_table a
35709 { AC97_VIDEO, 0x9f1f },
35710 { AC97_AUX, 0x9f1f },
35711 { AC97_PCM, 0x9f1f },
35712 - { } /* terminator */
35713 + { 0, 0 } /* terminator */
35716 static int patch_ad1819(struct snd_ac97 * ac97)
35717 @@ -3544,7 +3544,7 @@ static struct snd_ac97_res_table lm4550_
35718 { AC97_AUX, 0x1f1f },
35719 { AC97_PCM, 0x1f1f },
35720 { AC97_REC_GAIN, 0x0f0f },
35721 - { } /* terminator */
35722 + { 0, 0 } /* terminator */
35725 static int patch_lm4550(struct snd_ac97 *ac97)
35726 diff -urNp linux-2.6.25.10/sound/pci/ens1370.c linux-2.6.25.10/sound/pci/ens1370.c
35727 --- linux-2.6.25.10/sound/pci/ens1370.c 2008-07-02 23:46:47.000000000 -0400
35728 +++ linux-2.6.25.10/sound/pci/ens1370.c 2008-07-03 16:53:27.000000000 -0400
35729 @@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
35730 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
35731 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
35734 + { 0, 0, 0, 0, 0, 0, 0 }
35737 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
35738 diff -urNp linux-2.6.25.10/sound/pci/intel8x0.c linux-2.6.25.10/sound/pci/intel8x0.c
35739 --- linux-2.6.25.10/sound/pci/intel8x0.c 2008-07-02 23:46:47.000000000 -0400
35740 +++ linux-2.6.25.10/sound/pci/intel8x0.c 2008-07-03 16:53:27.000000000 -0400
35741 @@ -435,7 +435,7 @@ static struct pci_device_id snd_intel8x0
35742 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
35743 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
35744 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
35746 + { 0, 0, 0, 0, 0, 0, 0 }
35749 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
35750 @@ -2057,7 +2057,7 @@ static struct ac97_quirk ac97_quirks[] _
35751 .type = AC97_TUNE_HP_ONLY
35754 - { } /* terminator */
35755 + { 0, 0, 0, 0, NULL, 0 } /* terminator */
35758 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
35759 diff -urNp linux-2.6.25.10/sound/pci/intel8x0m.c linux-2.6.25.10/sound/pci/intel8x0m.c
35760 --- linux-2.6.25.10/sound/pci/intel8x0m.c 2008-07-02 23:46:47.000000000 -0400
35761 +++ linux-2.6.25.10/sound/pci/intel8x0m.c 2008-07-03 16:53:27.000000000 -0400
35762 @@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
35763 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
35764 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
35767 + { 0, 0, 0, 0, 0, 0, 0 }
35770 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
35771 @@ -1260,7 +1260,7 @@ static struct shortname_table {
35772 { 0x5455, "ALi M5455" },
35773 { 0x746d, "AMD AMD8111" },
35779 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
35780 diff -urNp linux-2.6.25.10/virt/kvm/kvm_main.c linux-2.6.25.10/virt/kvm/kvm_main.c
35781 --- linux-2.6.25.10/virt/kvm/kvm_main.c 2008-07-02 23:46:47.000000000 -0400
35782 +++ linux-2.6.25.10/virt/kvm/kvm_main.c 2008-07-03 16:53:27.000000000 -0400
35783 @@ -1077,6 +1077,9 @@ static struct miscdevice kvm_dev = {
35792 static void hardware_enable(void *junk)