1 diff -urNp linux-2.6.17.7/Makefile linux-2.6.17.7/Makefile
2 --- linux-2.6.17.7/Makefile 2006-07-24 23:36:01.000000000 -0400
3 +++ linux-2.6.17.7/Makefile 2006-08-01 20:29:48.000000000 -0400
4 @@ -518,7 +518,7 @@ export MODLIB
7 ifeq ($(KBUILD_EXTMOD),)
8 -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
9 +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
11 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
12 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
13 diff -urNp linux-2.6.17.7/arch/alpha/kernel/module.c linux-2.6.17.7/arch/alpha/kernel/module.c
14 --- linux-2.6.17.7/arch/alpha/kernel/module.c 2006-07-24 23:36:01.000000000 -0400
15 +++ linux-2.6.17.7/arch/alpha/kernel/module.c 2006-08-01 20:29:45.000000000 -0400
16 @@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
18 /* The small sections were sorted to the end of the segment.
19 The following should definitely cover them. */
20 - gp = (u64)me->module_core + me->core_size - 0x8000;
21 + gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
22 got = sechdrs[me->arch.gotsecindex].sh_addr;
24 for (i = 0; i < n; i++) {
25 diff -urNp linux-2.6.17.7/arch/alpha/kernel/osf_sys.c linux-2.6.17.7/arch/alpha/kernel/osf_sys.c
26 --- linux-2.6.17.7/arch/alpha/kernel/osf_sys.c 2006-07-24 23:36:01.000000000 -0400
27 +++ linux-2.6.17.7/arch/alpha/kernel/osf_sys.c 2006-08-01 20:29:45.000000000 -0400
28 @@ -1273,6 +1273,10 @@ arch_get_unmapped_area(struct file *filp
29 merely specific addresses, but regions of memory -- perhaps
30 this feature should be incorporated into all ports? */
32 +#ifdef CONFIG_PAX_RANDMMAP
33 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
37 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
38 if (addr != (unsigned long) -ENOMEM)
39 @@ -1280,8 +1284,8 @@ arch_get_unmapped_area(struct file *filp
42 /* Next, try allocating at TASK_UNMAPPED_BASE. */
43 - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
45 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
47 if (addr != (unsigned long) -ENOMEM)
50 diff -urNp linux-2.6.17.7/arch/alpha/kernel/ptrace.c linux-2.6.17.7/arch/alpha/kernel/ptrace.c
51 --- linux-2.6.17.7/arch/alpha/kernel/ptrace.c 2006-07-24 23:36:01.000000000 -0400
52 +++ linux-2.6.17.7/arch/alpha/kernel/ptrace.c 2006-08-01 20:29:45.000000000 -0400
54 #include <linux/security.h>
55 #include <linux/signal.h>
56 #include <linux/vs_pid.h>
57 +#include <linux/grsecurity.h>
59 #include <asm/uaccess.h>
60 #include <asm/pgtable.h>
61 @@ -283,6 +284,9 @@ do_sys_ptrace(long request, long pid, lo
65 + if (gr_handle_ptrace(child, request))
68 if (request == PTRACE_ATTACH) {
69 ret = ptrace_attach(child);
71 diff -urNp linux-2.6.17.7/arch/alpha/mm/fault.c linux-2.6.17.7/arch/alpha/mm/fault.c
72 --- linux-2.6.17.7/arch/alpha/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
73 +++ linux-2.6.17.7/arch/alpha/mm/fault.c 2006-08-01 20:29:45.000000000 -0400
75 #include <linux/smp_lock.h>
76 #include <linux/interrupt.h>
77 #include <linux/module.h>
78 +#include <linux/binfmts.h>
80 #include <asm/system.h>
81 #include <asm/uaccess.h>
82 @@ -56,6 +57,124 @@ __load_new_mm_context(struct mm_struct *
86 +#ifdef CONFIG_PAX_PAGEEXEC
88 + * PaX: decide what to do with offenders (regs->pc = fault address)
90 + * returns 1 when task should be killed
91 + * 2 when patched PLT trampoline was detected
92 + * 3 when unpatched PLT trampoline was detected
94 +static int pax_handle_fetch_fault(struct pt_regs *regs)
97 +#ifdef CONFIG_PAX_EMUPLT
100 + do { /* PaX: patched PLT emulation #1 */
101 + unsigned int ldah, ldq, jmp;
103 + err = get_user(ldah, (unsigned int *)regs->pc);
104 + err |= get_user(ldq, (unsigned int *)(regs->pc+4));
105 + err |= get_user(jmp, (unsigned int *)(regs->pc+8));
110 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
111 + (ldq & 0xFFFF0000U) == 0xA77B0000U &&
112 + jmp == 0x6BFB0000U)
114 + unsigned long r27, addr;
115 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
116 + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
118 + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
119 + err = get_user(r27, (unsigned long*)addr);
129 + do { /* PaX: patched PLT emulation #2 */
130 + unsigned int ldah, lda, br;
132 + err = get_user(ldah, (unsigned int *)regs->pc);
133 + err |= get_user(lda, (unsigned int *)(regs->pc+4));
134 + err |= get_user(br, (unsigned int *)(regs->pc+8));
139 + if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
140 + (lda & 0xFFFF0000U) == 0xA77B0000U &&
141 + (br & 0xFFE00000U) == 0xC3E00000U)
143 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
144 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
145 + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
147 + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
148 + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
153 + do { /* PaX: unpatched PLT emulation */
156 + err = get_user(br, (unsigned int *)regs->pc);
158 + if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
159 + unsigned int br2, ldq, nop, jmp;
160 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
162 + addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
163 + err = get_user(br2, (unsigned int *)addr);
164 + err |= get_user(ldq, (unsigned int *)(addr+4));
165 + err |= get_user(nop, (unsigned int *)(addr+8));
166 + err |= get_user(jmp, (unsigned int *)(addr+12));
167 + err |= get_user(resolver, (unsigned long *)(addr+16));
172 + if (br2 == 0xC3600000U &&
173 + ldq == 0xA77B000CU &&
174 + nop == 0x47FF041FU &&
175 + jmp == 0x6B7B0000U)
177 + regs->r28 = regs->pc+4;
178 + regs->r27 = addr+16;
179 + regs->pc = resolver;
189 +void pax_report_insns(void *pc, void *sp)
193 + printk(KERN_ERR "PAX: bytes at PC: ");
194 + for (i = 0; i < 5; i++) {
196 + if (get_user(c, (unsigned int*)pc+i))
197 + printk("???????? ");
199 + printk("%08x ", c);
206 * This routine handles page faults. It determines the address,
207 @@ -133,8 +252,29 @@ do_page_fault(unsigned long address, uns
209 si_code = SEGV_ACCERR;
211 - if (!(vma->vm_flags & VM_EXEC))
212 + if (!(vma->vm_flags & VM_EXEC)) {
214 +#ifdef CONFIG_PAX_PAGEEXEC
215 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
218 + up_read(&mm->mmap_sem);
219 + switch(pax_handle_fetch_fault(regs)) {
221 +#ifdef CONFIG_PAX_EMUPLT
228 + pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
236 /* Allow reads even for write-only mappings */
237 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
238 diff -urNp linux-2.6.17.7/arch/arm/mm/mmap.c linux-2.6.17.7/arch/arm/mm/mmap.c
239 --- linux-2.6.17.7/arch/arm/mm/mmap.c 2006-07-24 23:36:01.000000000 -0400
240 +++ linux-2.6.17.7/arch/arm/mm/mmap.c 2006-08-01 20:29:45.000000000 -0400
241 @@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
245 +#ifdef CONFIG_PAX_RANDMMAP
246 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
251 addr = COLOUR_ALIGN(addr, pgoff);
252 @@ -76,7 +80,7 @@ arch_get_unmapped_area(struct file *filp
253 if (len > mm->cached_hole_size) {
254 start_addr = addr = mm->free_area_cache;
256 - start_addr = addr = TASK_UNMAPPED_BASE;
257 + start_addr = addr = mm->mmap_base;
258 mm->cached_hole_size = 0;
261 @@ -93,8 +97,8 @@ full_search:
262 * Start a new search - just in case we missed
265 - if (start_addr != TASK_UNMAPPED_BASE) {
266 - start_addr = addr = TASK_UNMAPPED_BASE;
267 + if (start_addr != mm->mmap_base) {
268 + start_addr = addr = mm->mmap_base;
269 mm->cached_hole_size = 0;
272 diff -urNp linux-2.6.17.7/arch/i386/Kconfig linux-2.6.17.7/arch/i386/Kconfig
273 --- linux-2.6.17.7/arch/i386/Kconfig 2006-07-24 23:36:01.000000000 -0400
274 +++ linux-2.6.17.7/arch/i386/Kconfig 2006-08-01 20:29:45.000000000 -0400
275 @@ -980,7 +980,7 @@ endchoice
279 - depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
280 + depends on !X86_VISWS && PCI && PCI_GOBIOS
284 diff -urNp linux-2.6.17.7/arch/i386/Kconfig.cpu linux-2.6.17.7/arch/i386/Kconfig.cpu
285 --- linux-2.6.17.7/arch/i386/Kconfig.cpu 2006-07-24 23:36:01.000000000 -0400
286 +++ linux-2.6.17.7/arch/i386/Kconfig.cpu 2006-08-01 20:29:45.000000000 -0400
287 @@ -251,7 +251,7 @@ config X86_PPRO_FENCE
291 - depends on M586MMX || M586TSC || M586 || M486 || M386
292 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
295 config X86_WP_WORKS_OK
296 @@ -281,7 +281,7 @@ config X86_CMPXCHG64
298 config X86_ALIGNMENT_16
300 - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
301 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
305 diff -urNp linux-2.6.17.7/arch/i386/Kconfig.debug linux-2.6.17.7/arch/i386/Kconfig.debug
306 --- linux-2.6.17.7/arch/i386/Kconfig.debug 2006-07-24 23:36:01.000000000 -0400
307 +++ linux-2.6.17.7/arch/i386/Kconfig.debug 2006-08-01 20:29:45.000000000 -0400
308 @@ -53,7 +53,7 @@ config DEBUG_PAGEALLOC
311 bool "Write protect kernel read-only data structures"
312 - depends on DEBUG_KERNEL
313 + depends on DEBUG_KERNEL && 0
315 Mark the kernel read-only data as write-protected in the pagetables,
316 in order to catch accidental (and incorrect) writes to such const
317 diff -urNp linux-2.6.17.7/arch/i386/boot/compressed/head.S linux-2.6.17.7/arch/i386/boot/compressed/head.S
318 --- linux-2.6.17.7/arch/i386/boot/compressed/head.S 2006-07-24 23:36:01.000000000 -0400
319 +++ linux-2.6.17.7/arch/i386/boot/compressed/head.S 2006-08-01 20:29:45.000000000 -0400
320 @@ -39,11 +39,13 @@ startup_32:
326 1: incl %eax # check that A20 really IS enabled
327 movl %eax,0x000000 # loop forever if it isn't
333 * Initialize eflags. Some BIOS's leave bits like NT set. This would
334 diff -urNp linux-2.6.17.7/arch/i386/kernel/acpi/sleep.c linux-2.6.17.7/arch/i386/kernel/acpi/sleep.c
335 --- linux-2.6.17.7/arch/i386/kernel/acpi/sleep.c 2006-07-24 23:36:01.000000000 -0400
336 +++ linux-2.6.17.7/arch/i386/kernel/acpi/sleep.c 2006-08-01 20:29:45.000000000 -0400
338 #include <linux/dmi.h>
340 #include <asm/tlbflush.h>
341 +#include <asm/desc.h>
343 /* address in low memory of the wakeup routine. */
344 unsigned long acpi_wakeup_address = 0;
345 @@ -24,11 +25,22 @@ static void init_low_mapping(pgd_t * pgd
349 +#ifdef CONFIG_PAX_KERNEXEC
352 + pax_open_kernel(cr0);
355 while ((pgd_ofs < pgd_limit)
356 && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
357 set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD));
361 +#ifdef CONFIG_PAX_KERNEXEC
362 + pax_close_kernel(cr0);
368 @@ -55,7 +67,18 @@ int acpi_save_state_mem(void)
370 void acpi_restore_state_mem(void)
372 +#ifdef CONFIG_PAX_KERNEXEC
375 + pax_open_kernel(cr0);
380 +#ifdef CONFIG_PAX_KERNEXEC
381 + pax_close_kernel(cr0);
387 diff -urNp linux-2.6.17.7/arch/i386/kernel/alternative.c linux-2.6.17.7/arch/i386/kernel/alternative.c
388 --- linux-2.6.17.7/arch/i386/kernel/alternative.c 2006-07-24 23:36:01.000000000 -0400
389 +++ linux-2.6.17.7/arch/i386/kernel/alternative.c 2006-08-01 20:29:45.000000000 -0400
391 #include <linux/list.h>
392 #include <asm/alternative.h>
393 #include <asm/sections.h>
394 +#include <asm/desc.h>
398 @@ -101,71 +102,128 @@ void apply_alternatives(struct alt_instr
402 +#ifdef CONFIG_PAX_KERNEXEC
405 + pax_open_kernel(cr0);
408 DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
409 for (a = start; a < end; a++) {
410 BUG_ON(a->replacementlen > a->instrlen);
411 if (!boot_cpu_has(a->cpuid))
413 - memcpy(a->instr, a->replacement, a->replacementlen);
414 + memcpy(a->instr + __KERNEL_TEXT_OFFSET, a->replacement, a->replacementlen);
415 diff = a->instrlen - a->replacementlen;
416 /* Pad the rest with nops */
417 for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
421 - memcpy(a->instr + i, noptable[k], k);
422 + memcpy(a->instr + i + __KERNEL_TEXT_OFFSET, noptable[k], k);
426 +#ifdef CONFIG_PAX_KERNEXEC
427 + pax_close_kernel(cr0);
432 static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end)
436 +#ifdef CONFIG_PAX_KERNEXEC
439 + pax_open_kernel(cr0);
442 DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end);
443 for (a = start; a < end; a++) {
444 memcpy(a->replacement + a->replacementlen,
446 + a->instr + __KERNEL_TEXT_OFFSET,
450 +#ifdef CONFIG_PAX_KERNEXEC
451 + pax_close_kernel(cr0);
456 static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end)
460 +#ifdef CONFIG_PAX_KERNEXEC
463 + pax_open_kernel(cr0);
466 for (a = start; a < end; a++) {
468 + memcpy(a->instr + __KERNEL_TEXT_OFFSET,
469 a->replacement + a->replacementlen,
473 +#ifdef CONFIG_PAX_KERNEXEC
474 + pax_close_kernel(cr0);
479 static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
484 +#ifdef CONFIG_PAX_KERNEXEC
487 - for (ptr = start; ptr < end; ptr++) {
489 + pax_open_kernel(cr0);
492 + for (; start < end; start++) {
493 + ptr = *start + __KERNEL_TEXT_OFFSET;
496 - if (*ptr > text_end)
497 + if (ptr > text_end)
499 - **ptr = 0xf0; /* lock prefix */
500 + *ptr = 0xf0; /* lock prefix */
503 +#ifdef CONFIG_PAX_KERNEXEC
504 + pax_close_kernel(cr0);
509 static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
511 unsigned char **noptable = find_nop_table();
515 +#ifdef CONFIG_PAX_KERNEXEC
518 + pax_open_kernel(cr0);
521 - for (ptr = start; ptr < end; ptr++) {
523 + for (; start < end; start++) {
524 + ptr = *start + __KERNEL_TEXT_OFFSET;
527 - if (*ptr > text_end)
528 + if (ptr > text_end)
530 - **ptr = noptable[1][0];
531 + *ptr = noptable[1][0];
534 +#ifdef CONFIG_PAX_KERNEXEC
535 + pax_close_kernel(cr0);
540 struct smp_alt_module {
541 diff -urNp linux-2.6.17.7/arch/i386/kernel/apic.c linux-2.6.17.7/arch/i386/kernel/apic.c
542 --- linux-2.6.17.7/arch/i386/kernel/apic.c 2006-07-24 23:36:01.000000000 -0400
543 +++ linux-2.6.17.7/arch/i386/kernel/apic.c 2006-08-01 20:29:45.000000000 -0400
544 @@ -1176,7 +1176,7 @@ inline void smp_local_timer_interrupt(st
546 profile_tick(CPU_PROFILING, regs);
548 - update_process_times(user_mode_vm(regs));
549 + update_process_times(user_mode(regs));
553 diff -urNp linux-2.6.17.7/arch/i386/kernel/apm.c linux-2.6.17.7/arch/i386/kernel/apm.c
554 --- linux-2.6.17.7/arch/i386/kernel/apm.c 2006-07-24 23:36:01.000000000 -0400
555 +++ linux-2.6.17.7/arch/i386/kernel/apm.c 2006-08-01 20:29:45.000000000 -0400
556 @@ -589,9 +589,18 @@ static u8 apm_bios_call(u32 func, u32 eb
557 struct desc_struct save_desc_40;
558 struct desc_struct *gdt;
560 +#ifdef CONFIG_PAX_KERNEXEC
564 cpus = apm_save_cpus();
568 +#ifdef CONFIG_PAX_KERNEXEC
569 + pax_open_kernel(cr0);
572 gdt = get_cpu_gdt_table(cpu);
573 save_desc_40 = gdt[0x40 / 8];
574 gdt[0x40 / 8] = bad_bios_desc;
575 @@ -603,6 +612,11 @@ static u8 apm_bios_call(u32 func, u32 eb
577 local_irq_restore(flags);
578 gdt[0x40 / 8] = save_desc_40;
580 +#ifdef CONFIG_PAX_KERNEXEC
581 + pax_close_kernel(cr0);
585 apm_restore_cpus(cpus);
587 @@ -633,9 +647,18 @@ static u8 apm_bios_call_simple(u32 func,
588 struct desc_struct save_desc_40;
589 struct desc_struct *gdt;
591 +#ifdef CONFIG_PAX_KERNEXEC
595 cpus = apm_save_cpus();
599 +#ifdef CONFIG_PAX_KERNEXEC
600 + pax_open_kernel(cr0);
603 gdt = get_cpu_gdt_table(cpu);
604 save_desc_40 = gdt[0x40 / 8];
605 gdt[0x40 / 8] = bad_bios_desc;
606 @@ -647,6 +670,11 @@ static u8 apm_bios_call_simple(u32 func,
608 local_irq_restore(flags);
609 gdt[0x40 / 8] = save_desc_40;
611 +#ifdef CONFIG_PAX_KERNEXEC
612 + pax_close_kernel(cr0);
616 apm_restore_cpus(cpus);
618 diff -urNp linux-2.6.17.7/arch/i386/kernel/asm-offsets.c linux-2.6.17.7/arch/i386/kernel/asm-offsets.c
619 --- linux-2.6.17.7/arch/i386/kernel/asm-offsets.c 2006-07-24 23:36:01.000000000 -0400
620 +++ linux-2.6.17.7/arch/i386/kernel/asm-offsets.c 2006-08-01 20:29:45.000000000 -0400
621 @@ -68,5 +68,6 @@ void foo(void)
622 sizeof(struct tss_struct));
624 DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
625 + DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
626 DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
628 diff -urNp linux-2.6.17.7/arch/i386/kernel/cpu/common.c linux-2.6.17.7/arch/i386/kernel/cpu/common.c
629 --- linux-2.6.17.7/arch/i386/kernel/cpu/common.c 2006-07-24 23:36:01.000000000 -0400
630 +++ linux-2.6.17.7/arch/i386/kernel/cpu/common.c 2006-08-01 20:29:45.000000000 -0400
632 #include <linux/smp.h>
633 #include <linux/module.h>
634 #include <linux/percpu.h>
635 -#include <linux/bootmem.h>
636 #include <asm/semaphore.h>
637 #include <asm/processor.h>
638 #include <asm/i387.h>
643 -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
644 -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
646 DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
647 EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
649 @@ -401,6 +397,10 @@ void __cpuinit identify_cpu(struct cpuin
650 if (this_cpu->c_init)
653 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_NOVSYSCALL)
654 + clear_bit(X86_FEATURE_SEP, c->x86_capability);
657 /* Disable the PN if appropriate */
658 squash_the_stupid_serial_number(c);
660 @@ -590,11 +590,10 @@ void __init early_cpu_init(void)
661 void __cpuinit cpu_init(void)
663 int cpu = smp_processor_id();
664 - struct tss_struct * t = &per_cpu(init_tss, cpu);
665 + struct tss_struct * t = init_tss + cpu;
666 struct thread_struct *thread = ¤t->thread;
667 - struct desc_struct *gdt;
668 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
669 __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
670 - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
672 if (cpu_test_and_set(cpu, cpu_initialized)) {
673 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
674 @@ -612,29 +611,11 @@ void __cpuinit cpu_init(void)
678 - * This is a horrible hack to allocate the GDT. The problem
679 - * is that cpu_init() is called really early for the boot CPU
680 - * (and hence needs bootmem) but much later for the secondary
681 - * CPUs, when bootmem will have gone away
683 - if (NODE_DATA(0)->bdata->node_bootmem_map) {
684 - gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
685 - /* alloc_bootmem_pages panics on failure, so no check */
686 - memset(gdt, 0, PAGE_SIZE);
688 - gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
689 - if (unlikely(!gdt)) {
690 - printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
692 - local_irq_enable();
697 * Initialize the per-CPU GDT with the boot GDT,
698 * and set up the GDT descriptor:
700 - memcpy(gdt, cpu_gdt_table, GDT_SIZE);
702 + memcpy(gdt, cpu_gdt_table, GDT_SIZE);
704 /* Set up GDT entry for 16bit stack */
705 *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
706 @@ -642,10 +623,10 @@ void __cpuinit cpu_init(void)
707 ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
708 (CPU_16BIT_STACK_SIZE - 1);
710 - cpu_gdt_descr->size = GDT_SIZE - 1;
711 - cpu_gdt_descr->address = (unsigned long)gdt;
712 + cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
713 + cpu_gdt_descr[cpu].address = (unsigned long)gdt;
715 - load_gdt(cpu_gdt_descr);
716 + load_gdt(&cpu_gdt_descr[cpu]);
717 load_idt(&idt_descr);
720 @@ -660,7 +641,7 @@ void __cpuinit cpu_init(void)
721 load_esp0(t, thread);
724 - load_LDT(&init_mm.context);
725 + _load_LDT(&init_mm.context);
727 #ifdef CONFIG_DOUBLEFAULT
728 /* Set up doublefault TSS pointer in the GDT */
729 @@ -668,7 +649,7 @@ void __cpuinit cpu_init(void)
732 /* Clear %fs and %gs. */
733 - asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
734 + asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r"(0));
736 /* Clear all 6 debug registers: */
738 diff -urNp linux-2.6.17.7/arch/i386/kernel/crash.c linux-2.6.17.7/arch/i386/kernel/crash.c
739 --- linux-2.6.17.7/arch/i386/kernel/crash.c 2006-07-24 23:36:01.000000000 -0400
740 +++ linux-2.6.17.7/arch/i386/kernel/crash.c 2006-08-01 20:29:45.000000000 -0400
741 @@ -105,7 +105,7 @@ static int crash_nmi_callback(struct pt_
745 - if (!user_mode_vm(regs)) {
746 + if (!user_mode(regs)) {
747 crash_fixup_ss_esp(&fixed_regs, regs);
750 diff -urNp linux-2.6.17.7/arch/i386/kernel/doublefault.c linux-2.6.17.7/arch/i386/kernel/doublefault.c
751 --- linux-2.6.17.7/arch/i386/kernel/doublefault.c 2006-07-24 23:36:01.000000000 -0400
752 +++ linux-2.6.17.7/arch/i386/kernel/doublefault.c 2006-08-01 20:29:45.000000000 -0400
755 #define DOUBLEFAULT_STACKSIZE (1024)
756 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
757 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
758 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
760 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
762 @@ -56,10 +56,10 @@ struct tss_struct doublefault_tss __cach
763 .eip = (unsigned long) doublefault_fn,
764 .eflags = X86_EFLAGS_SF | 0x2, /* 0x2 bit is always set */
773 .__cr3 = __pa(swapper_pg_dir)
775 diff -urNp linux-2.6.17.7/arch/i386/kernel/efi.c linux-2.6.17.7/arch/i386/kernel/efi.c
776 --- linux-2.6.17.7/arch/i386/kernel/efi.c 2006-07-24 23:36:01.000000000 -0400
777 +++ linux-2.6.17.7/arch/i386/kernel/efi.c 2006-08-01 20:29:45.000000000 -0400
778 @@ -64,82 +64,48 @@ extern void * boot_ioremap(unsigned long
780 static unsigned long efi_rt_eflags;
781 static DEFINE_SPINLOCK(efi_rt_lock);
782 -static pgd_t efi_bak_pg_dir_pointer[2];
783 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
785 -static void efi_call_phys_prelog(void)
786 +static void __init efi_call_phys_prelog(void)
789 - unsigned long temp;
790 - struct Xgt_desc_struct *cpu_gdt_descr;
792 spin_lock(&efi_rt_lock);
793 local_irq_save(efi_rt_eflags);
795 - cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
798 - * If I don't have PSE, I should just duplicate two entries in page
799 - * directory. If I have PSE, I just need to duplicate one entry in
804 - if (cr4 & X86_CR4_PSE) {
805 - efi_bak_pg_dir_pointer[0].pgd =
806 - swapper_pg_dir[pgd_index(0)].pgd;
807 - swapper_pg_dir[0].pgd =
808 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
810 - efi_bak_pg_dir_pointer[0].pgd =
811 - swapper_pg_dir[pgd_index(0)].pgd;
812 - efi_bak_pg_dir_pointer[1].pgd =
813 - swapper_pg_dir[pgd_index(0x400000)].pgd;
814 - swapper_pg_dir[pgd_index(0)].pgd =
815 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
816 - temp = PAGE_OFFSET + 0x400000;
817 - swapper_pg_dir[pgd_index(0x400000)].pgd =
818 - swapper_pg_dir[pgd_index(temp)].pgd;
819 + clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
820 + if (USER_PTRS_PER_PGD >= KERNEL_PGD_PTRS)
821 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PTRS_PER_PGD, KERNEL_PGD_PTRS);
824 + for (i = 0; i < KERNEL_PGD_PTRS; ++i)
825 + clone_pgd_range(swapper_pg_dir + i, swapper_pg_dir + USER_PTRS_PER_PGD + i, 1);
829 * After the lock is released, the original page table is restored.
834 - cpu_gdt_descr->address = __pa(cpu_gdt_descr->address);
835 - load_gdt(cpu_gdt_descr);
836 + cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
837 + load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
840 -static void efi_call_phys_epilog(void)
841 +static void __init efi_call_phys_epilog(void)
844 - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
846 - cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address);
847 - load_gdt(cpu_gdt_descr);
848 + cpu_gdt_descr[0].address = (unsigned long) __va(cpu_gdt_descr[0].address);
849 + load_gdt(&cpu_gdt_descr[0]);
853 - if (cr4 & X86_CR4_PSE) {
854 - swapper_pg_dir[pgd_index(0)].pgd =
855 - efi_bak_pg_dir_pointer[0].pgd;
857 - swapper_pg_dir[pgd_index(0)].pgd =
858 - efi_bak_pg_dir_pointer[0].pgd;
859 - swapper_pg_dir[pgd_index(0x400000)].pgd =
860 - efi_bak_pg_dir_pointer[1].pgd;
862 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
865 * After the lock is released, the original page table is restored.
870 local_irq_restore(efi_rt_eflags);
871 spin_unlock(&efi_rt_lock);
875 +static efi_status_t __init
876 phys_efi_set_virtual_address_map(unsigned long memory_map_size,
877 unsigned long descriptor_size,
878 u32 descriptor_version,
879 @@ -155,7 +121,7 @@ phys_efi_set_virtual_address_map(unsigne
884 +static efi_status_t __init
885 phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
888 diff -urNp linux-2.6.17.7/arch/i386/kernel/efi_stub.S linux-2.6.17.7/arch/i386/kernel/efi_stub.S
889 --- linux-2.6.17.7/arch/i386/kernel/efi_stub.S 2006-07-24 23:36:01.000000000 -0400
890 +++ linux-2.6.17.7/arch/i386/kernel/efi_stub.S 2006-08-01 20:29:45.000000000 -0400
893 #include <linux/config.h>
894 #include <linux/linkage.h>
895 +#include <linux/init.h>
896 #include <asm/page.h>
897 #include <asm/pgtable.h>
900 * service functions will comply with gcc calling convention, too.
907 * 0. The function can only be called in Linux kernel. So CS has been
908 @@ -38,9 +39,7 @@ ENTRY(efi_call_phys)
909 * The mapping of lower virtual memory has been created in prelog and
913 - subl $__PAGE_OFFSET, %edx
915 + jmp 1f-__PAGE_OFFSET
919 @@ -49,14 +48,8 @@ ENTRY(efi_call_phys)
920 * parameter 2, ..., param n. To make things easy, we save the return
921 * address of efi_call_phys in a global variable.
924 - movl %edx, saved_return_addr
925 - /* get the function pointer into ECX*/
927 - movl %ecx, efi_rt_function_ptr
929 - subl $__PAGE_OFFSET, %edx
931 + popl (saved_return_addr)
932 + popl (efi_rt_function_ptr)
935 * 3. Clear PG bit in %CR0.
936 @@ -75,9 +68,8 @@ ENTRY(efi_call_phys)
938 * 5. Call the physical function.
941 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
945 * 6. After EFI runtime service returns, control will return to
946 * following instruction. We'd better readjust stack pointer first.
947 @@ -87,37 +79,29 @@ ENTRY(efi_call_phys)
952 - orl $0x80000000, %edx
957 * 8. Now restore the virtual mode from flat mode by
958 * adding EIP with PAGE_OFFSET.
963 + orl $0x80000000, %edx
965 + jmp 1f+__PAGE_OFFSET
969 * 9. Balance the stack. And because EAX contain the return value,
970 * we'd better not clobber it.
972 - leal efi_rt_function_ptr, %edx
975 + pushl (efi_rt_function_ptr)
978 - * 10. Push the saved return address onto the stack and return.
979 + * 10. Return to the saved return address.
981 - leal saved_return_addr, %edx
985 + jmpl *(saved_return_addr)
993 diff -urNp linux-2.6.17.7/arch/i386/kernel/entry.S linux-2.6.17.7/arch/i386/kernel/entry.S
994 --- linux-2.6.17.7/arch/i386/kernel/entry.S 2006-07-24 23:36:01.000000000 -0400
995 +++ linux-2.6.17.7/arch/i386/kernel/entry.S 2006-08-01 20:29:45.000000000 -0400
996 @@ -82,7 +82,7 @@ VM_MASK = 0x00020000
997 #define resume_kernel restore_nocheck
1001 +#define __SAVE_ALL(_DS) \
1005 @@ -93,10 +93,24 @@ VM_MASK = 0x00020000
1009 - movl $(__USER_DS), %edx; \
1010 + movl $(_DS), %edx; \
1014 +#ifdef CONFIG_PAX_KERNEXEC
1016 + __SAVE_ALL(__KERNEL_DS) \
1017 + movl %cr0, %edx; \
1018 + movl %edx, %esi; \
1019 + orl $0x10000, %edx; \
1020 + xorl %edx, %esi; \
1022 +#elif defined(CONFIG_PAX_NOVSYSCALL)
1023 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
1025 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
1028 #define RESTORE_INT_REGS \
1031 @@ -146,7 +160,19 @@ ret_from_intr:
1032 movl EFLAGS(%esp), %eax # mix EFLAGS and CS
1034 testl $(VM_MASK | 3), %eax
1036 +#ifdef CONFIG_PAX_KERNEXEC
1037 + jnz resume_userspace
1048 ENTRY(resume_userspace)
1049 cli # make sure we don't miss an interrupt
1050 # setting need_resched or sigpending
1051 @@ -213,13 +239,33 @@ sysenter_past_esp:
1052 movl TI_flags(%ebp), %ecx
1053 testw $_TIF_ALLWORK_MASK, %cx
1054 jne syscall_exit_work
1056 +#ifdef CONFIG_PAX_RANDKSTACK
1058 + call pax_randomize_kstack
1062 /* if something modifies registers it must also disable sysexit */
1063 movl EIP(%esp), %edx
1064 movl OLDESP(%esp), %ecx
1065 +1: mov DS(%esp), %ds
1066 +2: mov ES(%esp), %es
1071 +.section .fixup,"ax"
1072 +3: movl $0,DS(%esp)
1074 +4: movl $0,ES(%esp)
1077 +.section __ex_table,"a"
1083 # system call handler stub
1085 @@ -247,6 +293,10 @@ syscall_exit:
1086 testw $_TIF_ALLWORK_MASK, %cx # current->work
1087 jne syscall_exit_work
1089 +#ifdef CONFIG_PAX_RANDKSTACK
1090 + call pax_randomize_kstack
1094 movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
1095 # Warning: OLDSS(%esp) contains the wrong/random values if we
1096 @@ -402,7 +452,7 @@ syscall_badsys:
1097 * Build the entry stubs and pointer table with
1098 * some assembler magic.
1101 +.section .rodata,"a",@progbits
1105 @@ -412,7 +462,7 @@ ENTRY(irq_entries_start)
1107 1: pushl $vector-256
1108 jmp common_interrupt
1110 +.section .rodata,"a",@progbits
1114 @@ -459,10 +509,19 @@ error_code:
1115 movl ORIG_EAX(%esp), %edx # get the error code
1116 movl %eax, ORIG_EAX(%esp)
1118 - movl $(__USER_DS), %ecx
1119 + movl $(__KERNEL_DS), %ecx
1122 movl %esp,%eax # pt_regs pointer
1124 +#ifdef CONFIG_PAX_KERNEXEC
1127 + orl $0x10000, %ecx
1133 jmp ret_from_exception
1135 @@ -558,6 +617,13 @@ nmi_stack_correct:
1136 xorl %edx,%edx # zero error code
1137 movl %esp,%eax # pt_regs pointer
1140 +#ifdef CONFIG_PAX_KERNEXEC
1149 @@ -588,6 +654,13 @@ nmi_16bit_stack:
1150 FIXUP_ESPFIX_STACK # %eax == %esp
1151 xorl %edx,%edx # zero error code
1154 +#ifdef CONFIG_PAX_KERNEXEC
1161 lss 12+4(%esp), %esp # back to 16bit stack
1163 @@ -663,7 +736,6 @@ ENTRY(spurious_interrupt_bug)
1164 pushl $do_spurious_interrupt_bug
1167 -.section .rodata,"a"
1168 #include "syscall_table.S"
1170 syscall_table_size=(.-sys_call_table)
1171 diff -urNp linux-2.6.17.7/arch/i386/kernel/head.S linux-2.6.17.7/arch/i386/kernel/head.S
1172 --- linux-2.6.17.7/arch/i386/kernel/head.S 2006-07-24 23:36:01.000000000 -0400
1173 +++ linux-2.6.17.7/arch/i386/kernel/head.S 2006-08-01 20:29:45.000000000 -0400
1176 #define INIT_MAP_BEYOND_END (128*1024)
1178 +#ifdef CONFIG_PAX_KERNEXEC
1179 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
1184 + * Real beginning of normal "text" segment
1190 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
1191 @@ -67,6 +77,26 @@ ENTRY(startup_32)
1195 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1196 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
1197 + movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
1198 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c0f300),%eax
1199 + movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_DEFAULT_USER_DS * 8 + 4)
1202 +#ifdef CONFIG_PAX_KERNEXEC
1203 + movl $ __KERNEL_TEXT_OFFSET,%eax
1204 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
1206 + movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
1207 + movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1209 + movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
1210 + movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
1212 + movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
1216 * Clear BSS first so that there are no surprises...
1217 * No need to cld as DF is already clear from cld above...
1218 @@ -114,24 +144,42 @@ ENTRY(startup_32)
1219 * Warning: don't use %esi or the stack in this code. However, %esp
1220 * can be used as a GPR if you really need it...
1222 -page_pde_offset = (__PAGE_OFFSET >> 20);
1224 +#ifdef CONFIG_X86_PAE
1225 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE_asm));
1227 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE_asm));
1229 movl $(pg0 - __PAGE_OFFSET), %edi
1230 +#ifdef CONFIG_X86_PAE
1231 + movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1233 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1234 - movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
1236 + movl $0x063, %eax /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1238 - leal 0x007(%edi),%ecx /* Create PDE entry */
1239 + leal 0x063(%edi),%ecx /* Create PDE entry */
1240 movl %ecx,(%edx) /* Store identity PDE entry */
1241 movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
1242 +#ifdef CONFIG_X86_PAE
1244 + movl $0,page_pde_offset+4(%edx)
1253 +#ifdef CONFIG_X86_PAE
1259 /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1260 - /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1261 - leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1262 + /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1263 + leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1266 movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1267 @@ -154,6 +202,11 @@ ENTRY(startup_32_smp)
1271 + /* This is a secondary processor (AP) */
1274 +#endif /* CONFIG_SMP */
1277 * New page tables may be in 4Mbyte page mode and may
1278 * be using the global pages.
1279 @@ -169,26 +222,27 @@ ENTRY(startup_32_smp)
1280 * not yet offset PAGE_OFFSET..
1282 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1288 movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
1292 - btl $5, %eax # check if PAE is enabled
1294 +#ifdef CONFIG_X86_PAE
1297 /* Check if extended functions are implemented */
1298 movl $0x80000000, %eax
1300 cmpl $0x80000000, %eax
1303 mov $0x80000001, %eax
1305 /* Execute Disable bit supported? */
1310 /* Setup EFER (Extended Feature Enable Register) */
1311 movl $0xc0000080, %ecx
1312 @@ -197,14 +251,12 @@ ENTRY(startup_32_smp)
1314 /* Make changes effective */
1316 + btsl $63,__supported_pte_mask-__PAGE_OFFSET
1319 - /* This is a secondary processor (AP) */
1324 -#endif /* CONFIG_SMP */
1332 @@ -229,9 +281,7 @@ ENTRY(startup_32_smp)
1336 - jz 1f /* Initial CPU cleans BSS */
1339 + jnz checkCPUtype /* Initial CPU cleans BSS */
1340 #endif /* CONFIG_SMP */
1343 @@ -308,8 +358,6 @@ is386: movl $2,%ecx # set MP
1344 ljmp $(__KERNEL_CS),$1f
1345 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
1346 movl %eax,%ss # after changing gdt.
1348 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
1352 @@ -412,32 +460,50 @@ ignore_int:
1357 - * Real beginning of normal "text" segment
1365 -.section ".bss.page_aligned","w"
1366 +.section .swapper_pg_dir,"a",@progbits
1367 ENTRY(swapper_pg_dir)
1368 +#ifdef CONFIG_X86_PAE
1369 + .long swapper_pm_dir-__PAGE_OFFSET+1
1371 + .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1373 + .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
1375 + .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
1381 +#ifdef CONFIG_X86_PAE
1382 +.section .swapper_pm_dir,"a",@progbits
1383 +ENTRY(swapper_pm_dir)
1390 +.section .empty_zero_page,"a",@progbits
1391 ENTRY(empty_zero_page)
1395 - * This starts the data section.
1398 + * The IDT has to be page-aligned to simplify the Pentium
1399 + * F0 0F bug workaround.. We have a special link segment
1402 +.section .idt,"a",@progbits
1406 +.section .rodata,"a",@progbits
1410 - .long init_thread_union+THREAD_SIZE
1411 + .long init_thread_union+THREAD_SIZE-8
1417 .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
1419 @@ -465,7 +531,7 @@ idt_descr:
1421 # boot GDT descriptor (later on used by CPU#0):
1422 .word 0 # 32 bit align gdt_desc.address
1424 +ENTRY(cpu_gdt_descr)
1425 .word GDT_ENTRIES*8-1
1428 @@ -476,13 +542,13 @@ cpu_gdt_descr:
1429 .align L1_CACHE_BYTES
1430 ENTRY(boot_gdt_table)
1431 .fill GDT_ENTRY_BOOT_CS,8,0
1432 - .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
1433 - .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
1434 + .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
1435 + .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
1438 * The Global Descriptor Table contains 28 quadwords, per-CPU.
1440 - .align L1_CACHE_BYTES
1442 ENTRY(cpu_gdt_table)
1443 .quad 0x0000000000000000 /* NULL descriptor */
1444 .quad 0x0000000000000000 /* 0x0b reserved */
1445 @@ -497,10 +563,10 @@ ENTRY(cpu_gdt_table)
1446 .quad 0x0000000000000000 /* 0x53 reserved */
1447 .quad 0x0000000000000000 /* 0x5b reserved */
1449 - .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
1450 - .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
1451 - .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */
1452 - .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */
1453 + .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
1454 + .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
1455 + .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
1456 + .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
1458 .quad 0x0000000000000000 /* 0x80 TSS descriptor */
1459 .quad 0x0000000000000000 /* 0x88 LDT descriptor */
1460 @@ -510,24 +576,30 @@ ENTRY(cpu_gdt_table)
1461 * They code segments and data segments have fixed 64k limits,
1462 * the transfer segment sizes are set at run time.
1464 - .quad 0x00409a000000ffff /* 0x90 32-bit code */
1465 - .quad 0x00009a000000ffff /* 0x98 16-bit code */
1466 - .quad 0x000092000000ffff /* 0xa0 16-bit data */
1467 - .quad 0x0000920000000000 /* 0xa8 16-bit data */
1468 - .quad 0x0000920000000000 /* 0xb0 16-bit data */
1469 + .quad 0x00409b000000ffff /* 0x90 32-bit code */
1470 + .quad 0x00009b000000ffff /* 0x98 16-bit code */
1471 + .quad 0x000093000000ffff /* 0xa0 16-bit data */
1472 + .quad 0x0000930000000000 /* 0xa8 16-bit data */
1473 + .quad 0x0000930000000000 /* 0xb0 16-bit data */
1476 * The APM segments have byte granularity and their bases
1477 * are set at run time. All have 64k limits.
1479 - .quad 0x00409a000000ffff /* 0xb8 APM CS code */
1480 - .quad 0x00009a000000ffff /* 0xc0 APM CS 16 code (16 bit) */
1481 - .quad 0x004092000000ffff /* 0xc8 APM DS data */
1482 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
1483 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
1484 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
1486 - .quad 0x0000920000000000 /* 0xd0 - ESPFIX 16-bit SS */
1487 + .quad 0x0000930000000000 /* 0xd0 - ESPFIX 16-bit SS */
1488 .quad 0x0000000000000000 /* 0xd8 - unused */
1489 .quad 0x0000000000000000 /* 0xe0 - unused */
1490 .quad 0x0000000000000000 /* 0xe8 - unused */
1491 .quad 0x0000000000000000 /* 0xf0 - unused */
1492 .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
1494 + /* Be sure this is zeroed to avoid false validations in Xen */
1495 + .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
1498 + .fill (NR_CPUS-1) * (PAGE_SIZE_asm / 8),8,0 /* other CPU's GDT */
1500 diff -urNp linux-2.6.17.7/arch/i386/kernel/i386_ksyms.c linux-2.6.17.7/arch/i386/kernel/i386_ksyms.c
1501 --- linux-2.6.17.7/arch/i386/kernel/i386_ksyms.c 2006-07-24 23:36:01.000000000 -0400
1502 +++ linux-2.6.17.7/arch/i386/kernel/i386_ksyms.c 2006-08-01 20:52:30.000000000 -0400
1504 #include <asm/checksum.h>
1505 #include <asm/desc.h>
1507 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
1509 EXPORT_SYMBOL(__down_failed);
1510 EXPORT_SYMBOL(__down_failed_interruptible);
1511 EXPORT_SYMBOL(__down_failed_trylock);
1512 EXPORT_SYMBOL(__up_wakeup);
1513 /* Networking helper routines. */
1514 EXPORT_SYMBOL(csum_partial_copy_generic);
1515 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
1516 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
1518 EXPORT_SYMBOL(__get_user_1);
1519 EXPORT_SYMBOL(__get_user_2);
1520 diff -urNp linux-2.6.17.7/arch/i386/kernel/init_task.c linux-2.6.17.7/arch/i386/kernel/init_task.c
1521 --- linux-2.6.17.7/arch/i386/kernel/init_task.c 2006-07-24 23:36:01.000000000 -0400
1522 +++ linux-2.6.17.7/arch/i386/kernel/init_task.c 2006-08-01 20:29:45.000000000 -0400
1523 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
1524 * per-CPU TSS segments. Threads are completely 'soft' on Linux,
1525 * no more per-task TSS's.
1527 -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
1528 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
1530 diff -urNp linux-2.6.17.7/arch/i386/kernel/ioport.c linux-2.6.17.7/arch/i386/kernel/ioport.c
1531 --- linux-2.6.17.7/arch/i386/kernel/ioport.c 2006-07-24 23:36:01.000000000 -0400
1532 +++ linux-2.6.17.7/arch/i386/kernel/ioport.c 2006-08-01 20:29:45.000000000 -0400
1534 #include <linux/stddef.h>
1535 #include <linux/slab.h>
1536 #include <linux/thread_info.h>
1537 +#include <linux/grsecurity.h>
1539 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
1540 static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
1541 @@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
1543 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
1545 +#ifdef CONFIG_GRKERNSEC_IO
1547 + gr_handle_ioperm();
1549 if (turn_on && !capable(CAP_SYS_RAWIO))
1553 +#ifdef CONFIG_GRKERNSEC_IO
1557 * If it's the first ioperm() call in this thread's lifetime, set the
1558 * IO bitmap up. ioperm() is much less timing critical than clone(),
1559 @@ -88,7 +96,7 @@ asmlinkage long sys_ioperm(unsigned long
1560 * because the ->io_bitmap_max value must match the bitmap
1563 - tss = &per_cpu(init_tss, get_cpu());
1564 + tss = init_tss + get_cpu();
1566 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
1568 @@ -142,8 +150,13 @@ asmlinkage long sys_iopl(unsigned long u
1570 /* Trying to gain more privileges? */
1572 +#ifdef CONFIG_GRKERNSEC_IO
1576 if (!capable(CAP_SYS_RAWIO))
1580 t->iopl = level << 12;
1581 regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
1582 diff -urNp linux-2.6.17.7/arch/i386/kernel/irq.c linux-2.6.17.7/arch/i386/kernel/irq.c
1583 --- linux-2.6.17.7/arch/i386/kernel/irq.c 2006-07-24 23:36:01.000000000 -0400
1584 +++ linux-2.6.17.7/arch/i386/kernel/irq.c 2006-08-01 20:29:45.000000000 -0400
1585 @@ -91,7 +91,7 @@ fastcall unsigned int do_IRQ(struct pt_r
1586 int arg1, arg2, ebx;
1588 /* build the stack frame on the IRQ stack */
1589 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1590 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1591 irqctx->tinfo.task = curctx->tinfo.task;
1592 irqctx->tinfo.previous_esp = current_stack_pointer;
1594 @@ -119,10 +119,10 @@ fastcall unsigned int do_IRQ(struct pt_r
1595 * gcc's 3.0 and earlier don't handle that correctly.
1597 static char softirq_stack[NR_CPUS * THREAD_SIZE]
1598 - __attribute__((__aligned__(THREAD_SIZE)));
1599 + __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1601 static char hardirq_stack[NR_CPUS * THREAD_SIZE]
1602 - __attribute__((__aligned__(THREAD_SIZE)));
1603 + __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1606 * allocate per-cpu stacks for hardirq and for softirq processing
1607 @@ -182,7 +182,7 @@ asmlinkage void do_softirq(void)
1608 irqctx->tinfo.previous_esp = current_stack_pointer;
1610 /* build the stack frame on the softirq stack */
1611 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1612 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1615 " xchgl %%ebx,%%esp \n"
1616 diff -urNp linux-2.6.17.7/arch/i386/kernel/ldt.c linux-2.6.17.7/arch/i386/kernel/ldt.c
1617 --- linux-2.6.17.7/arch/i386/kernel/ldt.c 2006-07-24 23:36:01.000000000 -0400
1618 +++ linux-2.6.17.7/arch/i386/kernel/ldt.c 2006-08-01 20:29:45.000000000 -0400
1619 @@ -103,6 +103,19 @@ int init_new_context(struct task_struct
1620 retval = copy_ldt(&mm->context, &old_mm->context);
1621 up(&old_mm->context.sem);
1624 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1625 + if (!mm->context.user_cs_limit) {
1626 + mm->context.user_cs_base = 0UL;
1627 + mm->context.user_cs_limit = ~0UL;
1629 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
1630 + cpus_clear(mm->context.cpu_user_cs_mask);
1639 @@ -160,7 +173,7 @@ static int read_default_ldt(void __user
1644 + const void *address;
1647 address = &default_ldt[0];
1648 @@ -215,6 +228,13 @@ static int write_ldt(void __user * ptr,
1652 +#ifdef CONFIG_PAX_SEGMEXEC
1653 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
1659 entry_1 = LDT_entry_a(&ldt_info);
1660 entry_2 = LDT_entry_b(&ldt_info);
1662 diff -urNp linux-2.6.17.7/arch/i386/kernel/module.c linux-2.6.17.7/arch/i386/kernel/module.c
1663 --- linux-2.6.17.7/arch/i386/kernel/module.c 2006-07-24 23:36:01.000000000 -0400
1664 +++ linux-2.6.17.7/arch/i386/kernel/module.c 2006-08-01 20:29:45.000000000 -0400
1666 #include <linux/fs.h>
1667 #include <linux/string.h>
1668 #include <linux/kernel.h>
1669 +#include <asm/desc.h>
1672 #define DEBUGP printk
1673 @@ -32,9 +33,30 @@ void *module_alloc(unsigned long size)
1678 +#ifdef CONFIG_PAX_KERNEXEC
1679 + return vmalloc(size);
1681 return vmalloc_exec(size);
1686 +#ifdef CONFIG_PAX_KERNEXEC
1687 +void *module_alloc_exec(unsigned long size)
1689 + struct vm_struct *area;
1694 + area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
1696 + return area->addr;
1702 /* Free memory returned from module_alloc */
1703 void module_free(struct module *mod, void *module_region)
1704 @@ -44,6 +66,45 @@ void module_free(struct module *mod, voi
1708 +#ifdef CONFIG_PAX_KERNEXEC
1709 +void module_free_exec(struct module *mod, void *module_region)
1711 + struct vm_struct **p, *tmp;
1713 + if (!module_region)
1716 + if ((PAGE_SIZE-1) & (unsigned long)module_region) {
1717 + printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
1722 + write_lock(&vmlist_lock);
1723 + for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next)
1724 + if (tmp->addr == module_region)
1728 + unsigned long cr0;
1730 + pax_open_kernel(cr0);
1731 + memset(tmp->addr, 0xCC, tmp->size);
1732 + pax_close_kernel(cr0);
1737 + write_unlock(&vmlist_lock);
1740 + printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
1747 /* We don't need anything special. */
1748 int module_frob_arch_sections(Elf_Ehdr *hdr,
1750 @@ -62,14 +123,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1752 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
1754 - uint32_t *location;
1755 + uint32_t *plocation, location;
1757 DEBUGP("Applying relocate section %u to %u\n", relsec,
1758 sechdrs[relsec].sh_info);
1759 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
1760 /* This is where to make the change */
1761 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
1762 - + rel[i].r_offset;
1763 + plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
1764 + location = (uint32_t)plocation;
1765 + if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
1766 + plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
1767 /* This is the symbol it is referring to. Note that all
1768 undefined symbols have been resolved. */
1769 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
1770 @@ -78,11 +141,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1771 switch (ELF32_R_TYPE(rel[i].r_info)) {
1773 /* We add the value into the location given */
1774 - *location += sym->st_value;
1775 + *plocation += sym->st_value;
1778 /* Add the value, subtract its postition */
1779 - *location += sym->st_value - (uint32_t)location;
1780 + *plocation += sym->st_value - location;
1783 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
1784 diff -urNp linux-2.6.17.7/arch/i386/kernel/process.c linux-2.6.17.7/arch/i386/kernel/process.c
1785 --- linux-2.6.17.7/arch/i386/kernel/process.c 2006-07-24 23:36:01.000000000 -0400
1786 +++ linux-2.6.17.7/arch/i386/kernel/process.c 2006-08-01 20:29:45.000000000 -0400
1787 @@ -69,7 +69,7 @@ EXPORT_SYMBOL(boot_option_idle_override)
1789 unsigned long thread_saved_pc(struct task_struct *tsk)
1791 - return ((unsigned long *)tsk->thread.esp)[3];
1792 + return tsk->thread.eip;
1796 @@ -294,7 +294,7 @@ void show_regs(struct pt_regs * regs)
1797 printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
1798 print_symbol("EIP is at %s\n", regs->eip);
1800 - if (user_mode_vm(regs))
1801 + if (user_mode(regs))
1802 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
1803 printk(" EFLAGS: %08lx %s (%s %.*s)\n",
1804 regs->eflags, print_tainted(), system_utsname.release,
1805 @@ -343,8 +343,8 @@ int kernel_thread(int (*fn)(void *), voi
1806 regs.ebx = (unsigned long) fn;
1807 regs.edx = (unsigned long) arg;
1809 - regs.xds = __USER_DS;
1810 - regs.xes = __USER_DS;
1811 + regs.xds = __KERNEL_DS;
1812 + regs.xes = __KERNEL_DS;
1814 regs.eip = (unsigned long) kernel_thread_helper;
1815 regs.xcs = __KERNEL_CS;
1816 @@ -366,7 +366,7 @@ void exit_thread(void)
1817 /* The process may have allocated an io port bitmap... nuke it. */
1818 if (unlikely(NULL != t->io_bitmap_ptr)) {
1819 int cpu = get_cpu();
1820 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
1821 + struct tss_struct *tss = init_tss + cpu;
1823 kfree(t->io_bitmap_ptr);
1824 t->io_bitmap_ptr = NULL;
1825 @@ -386,6 +386,9 @@ void flush_thread(void)
1827 struct task_struct *tsk = current;
1829 + __asm__("mov %0,%%fs\n"
1831 + : : "r" (0) : "memory");
1832 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
1833 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
1835 @@ -418,7 +421,7 @@ int copy_thread(int nr, unsigned long cl
1836 struct task_struct *tsk;
1839 - childregs = task_pt_regs(p);
1840 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
1843 childregs->esp = esp;
1844 @@ -461,6 +464,11 @@ int copy_thread(int nr, unsigned long cl
1845 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1848 +#ifdef CONFIG_PAX_SEGMEXEC
1849 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1853 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
1854 desc->a = LDT_entry_a(&info);
1855 desc->b = LDT_entry_b(&info);
1856 @@ -625,7 +633,11 @@ struct task_struct fastcall * __switch_t
1857 struct thread_struct *prev = &prev_p->thread,
1858 *next = &next_p->thread;
1859 int cpu = smp_processor_id();
1860 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
1861 + struct tss_struct *tss = init_tss + cpu;
1863 +#ifdef CONFIG_PAX_KERNEXEC
1864 + unsigned long cr0;
1867 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
1869 @@ -648,11 +660,23 @@ struct task_struct fastcall * __switch_t
1870 savesegment(fs, prev->fs);
1871 savesegment(gs, prev->gs);
1873 +#ifdef CONFIG_PAX_KERNEXEC
1874 + pax_open_kernel(cr0);
1877 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1878 + __set_fs(get_fs(), cpu);
1882 * Load the per-thread Thread-Local Storage descriptor.
1884 load_TLS(next, cpu);
1886 +#ifdef CONFIG_PAX_KERNEXEC
1887 + pax_close_kernel(cr0);
1891 * Restore %fs and %gs if needed.
1893 @@ -806,8 +830,18 @@ asmlinkage int sys_set_thread_area(struc
1894 struct desc_struct *desc;
1897 +#ifdef CONFIG_PAX_KERNEXEC
1898 + unsigned long cr0;
1901 if (copy_from_user(&info, u_info, sizeof(info)))
1904 +#ifdef CONFIG_PAX_SEGMEXEC
1905 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1909 idx = info.entry_number;
1912 @@ -839,8 +873,17 @@ asmlinkage int sys_set_thread_area(struc
1913 desc->a = LDT_entry_a(&info);
1914 desc->b = LDT_entry_b(&info);
1917 +#ifdef CONFIG_PAX_KERNEXEC
1918 + pax_open_kernel(cr0);
1923 +#ifdef CONFIG_PAX_KERNEXEC
1924 + pax_close_kernel(cr0);
1930 @@ -896,9 +939,27 @@ asmlinkage int sys_get_thread_area(struc
1934 -unsigned long arch_align_stack(unsigned long sp)
1935 +#ifdef CONFIG_PAX_RANDKSTACK
1936 +asmlinkage void pax_randomize_kstack(void)
1938 - if (randomize_va_space)
1939 - sp -= get_random_int() % 8192;
1941 + struct tss_struct *tss = init_tss + smp_processor_id();
1942 + unsigned long time;
1944 + if (!randomize_va_space)
1949 + /* P4 seems to return a 0 LSB, ignore it */
1950 +#ifdef CONFIG_MPENTIUM4
1958 + tss->esp0 ^= time;
1959 + current->thread.esp0 = tss->esp0;
1962 diff -urNp linux-2.6.17.7/arch/i386/kernel/ptrace.c linux-2.6.17.7/arch/i386/kernel/ptrace.c
1963 --- linux-2.6.17.7/arch/i386/kernel/ptrace.c 2006-07-24 23:36:01.000000000 -0400
1964 +++ linux-2.6.17.7/arch/i386/kernel/ptrace.c 2006-08-01 20:29:45.000000000 -0400
1966 #include <linux/audit.h>
1967 #include <linux/seccomp.h>
1968 #include <linux/signal.h>
1969 +#include <linux/grsecurity.h>
1971 #include <asm/uaccess.h>
1972 #include <asm/pgtable.h>
1973 @@ -342,6 +343,11 @@ ptrace_set_thread_area(struct task_struc
1974 if (copy_from_user(&info, user_desc, sizeof(info)))
1977 +#ifdef CONFIG_PAX_SEGMEXEC
1978 + if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1982 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1985 @@ -432,6 +438,17 @@ long arch_ptrace(struct task_struct *chi
1986 if(addr == (long) &dummy->u_debugreg[5]) break;
1987 if(addr < (long) &dummy->u_debugreg[4] &&
1988 ((unsigned long) data) >= TASK_SIZE-3) break;
1990 +#ifdef CONFIG_GRKERNSEC
1991 + if(addr >= (long) &dummy->u_debugreg[0] &&
1992 + addr <= (long) &dummy->u_debugreg[3]){
1993 + long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
1994 + long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
1995 + long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
1996 + if((type & 1) && (data & align))
2001 /* Sanity-check data. Take one half-byte at once with
2002 * check = (val >> (16 + 4*i)) & 0xf. It contains the
2003 @@ -645,7 +662,7 @@ void send_sigtrap(struct task_struct *ts
2004 info.si_code = TRAP_BRKPT;
2006 /* User-mode eip? */
2007 - info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
2008 + info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
2010 /* Send us the fakey SIGTRAP */
2011 force_sig_info(SIGTRAP, &info, tsk);
2012 diff -urNp linux-2.6.17.7/arch/i386/kernel/reboot.c linux-2.6.17.7/arch/i386/kernel/reboot.c
2013 --- linux-2.6.17.7/arch/i386/kernel/reboot.c 2006-07-24 23:36:01.000000000 -0400
2014 +++ linux-2.6.17.7/arch/i386/kernel/reboot.c 2006-08-01 20:29:45.000000000 -0400
2015 @@ -138,18 +138,18 @@ core_initcall(reboot_init);
2016 doesn't work with at least one type of 486 motherboard. It is easy
2017 to stop this code working; hence the copious comments. */
2019 -static unsigned long long
2020 +static const unsigned long long
2021 real_mode_gdt_entries [3] =
2023 0x0000000000000000ULL, /* Null descriptor */
2024 - 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
2025 - 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
2026 + 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
2027 + 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
2032 unsigned short size __attribute__ ((packed));
2033 - unsigned long long * base __attribute__ ((packed));
2034 + const unsigned long long * base __attribute__ ((packed));
2036 real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
2037 real_mode_idt = { 0x3ff, NULL },
2038 @@ -203,6 +203,10 @@ void machine_real_restart(unsigned char
2040 unsigned long flags;
2042 +#ifdef CONFIG_PAX_KERNEXEC
2043 + unsigned long cr0;
2046 local_irq_disable();
2048 /* Write zero to CMOS register number 0x0f, which the BIOS POST
2049 @@ -223,9 +227,17 @@ void machine_real_restart(unsigned char
2050 from the kernel segment. This assumes the kernel segment starts at
2051 virtual address PAGE_OFFSET. */
2053 +#ifdef CONFIG_PAX_KERNEXEC
2054 + pax_open_kernel(cr0);
2057 memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2058 sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
2060 +#ifdef CONFIG_PAX_KERNEXEC
2061 + pax_close_kernel(cr0);
2065 * Use `swapper_pg_dir' as our page directory.
2067 diff -urNp linux-2.6.17.7/arch/i386/kernel/setup.c linux-2.6.17.7/arch/i386/kernel/setup.c
2068 --- linux-2.6.17.7/arch/i386/kernel/setup.c 2006-07-24 23:36:01.000000000 -0400
2069 +++ linux-2.6.17.7/arch/i386/kernel/setup.c 2006-08-01 20:29:45.000000000 -0400
2070 @@ -88,7 +88,11 @@ struct cpuinfo_x86 new_cpu_data __initda
2071 struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
2072 EXPORT_SYMBOL(boot_cpu_data);
2074 +#ifdef CONFIG_X86_PAE
2075 +unsigned long mmu_cr4_features = X86_CR4_PAE;
2077 unsigned long mmu_cr4_features;
2081 int acpi_disabled = 0;
2082 @@ -1493,14 +1497,14 @@ void __init setup_arch(char **cmdline_p)
2084 if (!MOUNT_ROOT_RDONLY)
2085 root_mountflags &= ~MS_RDONLY;
2086 - init_mm.start_code = (unsigned long) _text;
2087 - init_mm.end_code = (unsigned long) _etext;
2088 + init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
2089 + init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
2090 init_mm.end_data = (unsigned long) _edata;
2091 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
2093 - code_resource.start = virt_to_phys(_text);
2094 - code_resource.end = virt_to_phys(_etext)-1;
2095 - data_resource.start = virt_to_phys(_etext);
2096 + code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
2097 + code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
2098 + data_resource.start = virt_to_phys(_data);
2099 data_resource.end = virt_to_phys(_edata)-1;
2101 parse_cmdline_early(cmdline_p);
2102 diff -urNp linux-2.6.17.7/arch/i386/kernel/signal.c linux-2.6.17.7/arch/i386/kernel/signal.c
2103 --- linux-2.6.17.7/arch/i386/kernel/signal.c 2006-07-24 23:36:01.000000000 -0400
2104 +++ linux-2.6.17.7/arch/i386/kernel/signal.c 2006-08-01 20:29:45.000000000 -0400
2105 @@ -351,7 +351,17 @@ static int setup_frame(int sig, struct k
2109 +#ifdef CONFIG_PAX_NOVSYSCALL
2110 + restorer = frame->retcode;
2112 restorer = &__kernel_sigreturn;
2114 +#ifdef CONFIG_PAX_SEGMEXEC
2115 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2116 + restorer -= SEGMEXEC_TASK_SIZE;
2120 if (ka->sa.sa_flags & SA_RESTORER)
2121 restorer = ka->sa.sa_restorer;
2123 @@ -447,7 +457,18 @@ static int setup_rt_frame(int sig, struc
2126 /* Set up to return from userspace. */
2128 +#ifdef CONFIG_PAX_NOVSYSCALL
2129 + restorer = frame->retcode;
2131 restorer = &__kernel_rt_sigreturn;
2133 +#ifdef CONFIG_PAX_SEGMEXEC
2134 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2135 + restorer -= SEGMEXEC_TASK_SIZE;
2139 if (ka->sa.sa_flags & SA_RESTORER)
2140 restorer = ka->sa.sa_restorer;
2141 err |= __put_user(restorer, &frame->pretcode);
2142 @@ -580,7 +601,7 @@ static void fastcall do_signal(struct pt
2143 * before reaching here, so testing against kernel
2146 - if (!user_mode(regs))
2147 + if (!user_mode_novm(regs))
2150 if (test_thread_flag(TIF_RESTORE_SIGMASK))
2151 diff -urNp linux-2.6.17.7/arch/i386/kernel/sys_i386.c linux-2.6.17.7/arch/i386/kernel/sys_i386.c
2152 --- linux-2.6.17.7/arch/i386/kernel/sys_i386.c 2006-07-24 23:36:01.000000000 -0400
2153 +++ linux-2.6.17.7/arch/i386/kernel/sys_i386.c 2006-08-01 20:29:45.000000000 -0400
2154 @@ -99,6 +99,191 @@ out:
2159 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
2160 + unsigned long len, unsigned long pgoff, unsigned long flags)
2162 + struct mm_struct *mm = current->mm;
2163 + struct vm_area_struct *vma;
2164 + unsigned long start_addr, task_size = TASK_SIZE;
2166 +#ifdef CONFIG_PAX_SEGMEXEC
2167 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
2168 + task_size = SEGMEXEC_TASK_SIZE;
2171 + if (len > task_size)
2174 +#ifdef CONFIG_PAX_RANDMMAP
2175 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2179 + addr = PAGE_ALIGN(addr);
2180 + vma = find_vma(mm, addr);
2181 + if (task_size - len >= addr &&
2182 + (!vma || addr + len <= vma->vm_start))
2185 + if (len > mm->cached_hole_size) {
2186 + start_addr = addr = mm->free_area_cache;
2188 + start_addr = addr = mm->mmap_base;
2189 + mm->cached_hole_size = 0;
2192 +#ifdef CONFIG_PAX_PAGEEXEC
2193 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
2194 + start_addr = 0x00110000UL;
2196 +#ifdef CONFIG_PAX_RANDMMAP
2197 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2198 + start_addr += mm->delta_mmap & 0x03FFF000UL;
2201 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
2202 + start_addr = addr = mm->mmap_base;
2204 + addr = start_addr;
2209 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
2210 + /* At this point: (!vma || addr < vma->vm_end). */
2211 + if (task_size - len < addr) {
2213 + * Start a new search - just in case we missed
2216 + if (start_addr != mm->mmap_base) {
2217 + start_addr = addr = mm->mmap_base;
2218 + mm->cached_hole_size = 0;
2223 + if (!vma || addr + len <= vma->vm_start) {
2225 + * Remember the place where we stopped the search:
2227 + mm->free_area_cache = addr + len;
2230 + if (addr + mm->cached_hole_size < vma->vm_start)
2231 + mm->cached_hole_size = vma->vm_start - addr;
2232 + addr = vma->vm_end;
2233 + if (mm->start_brk <= addr && addr < mm->mmap_base) {
2234 + start_addr = addr = mm->mmap_base;
2241 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
2242 + const unsigned long len, const unsigned long pgoff,
2243 + const unsigned long flags)
2245 + struct vm_area_struct *vma;
2246 + struct mm_struct *mm = current->mm;
2247 + unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
2249 +#ifdef CONFIG_PAX_SEGMEXEC
2250 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
2251 + task_size = SEGMEXEC_TASK_SIZE;
2254 + /* requested length too big for entire address space */
2255 + if (len > task_size)
2258 +#ifdef CONFIG_PAX_PAGEEXEC
2259 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
2263 +#ifdef CONFIG_PAX_RANDMMAP
2264 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2267 + /* requesting a specific address */
2269 + addr = PAGE_ALIGN(addr);
2270 + vma = find_vma(mm, addr);
2271 + if (task_size - len >= addr &&
2272 + (!vma || addr + len <= vma->vm_start))
2276 + /* check if free_area_cache is useful for us */
2277 + if (len <= mm->cached_hole_size) {
2278 + mm->cached_hole_size = 0;
2279 + mm->free_area_cache = mm->mmap_base;
2282 + /* either no address requested or can't fit in requested address hole */
2283 + addr = mm->free_area_cache;
2285 + /* make sure it can fit in the remaining address space */
2287 + vma = find_vma(mm, addr-len);
2288 + if (!vma || addr <= vma->vm_start)
2289 + /* remember the address as a hint for next time */
2290 + return (mm->free_area_cache = addr-len);
2293 + if (mm->mmap_base < len)
2296 + addr = mm->mmap_base-len;
2300 + * Lookup failure means no vma is above this address,
2301 + * else if new region fits below vma->vm_start,
2302 + * return with success:
2304 + vma = find_vma(mm, addr);
2305 + if (!vma || addr+len <= vma->vm_start)
2306 + /* remember the address as a hint for next time */
2307 + return (mm->free_area_cache = addr);
2309 + /* remember the largest hole we saw so far */
2310 + if (addr + mm->cached_hole_size < vma->vm_start)
2311 + mm->cached_hole_size = vma->vm_start - addr;
2313 + /* try just below the current vma->vm_start */
2314 + addr = vma->vm_start-len;
2315 + } while (len < vma->vm_start);
2319 + * A failed mmap() very likely causes application failure,
2320 + * so fall back to the bottom-up function here. This scenario
2321 + * can happen with large stack limits and large mmap()
2324 + mm->mmap_base = TASK_UNMAPPED_BASE;
2326 +#ifdef CONFIG_PAX_RANDMMAP
2327 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2328 + mm->mmap_base += mm->delta_mmap;
2331 + mm->free_area_cache = mm->mmap_base;
2332 + mm->cached_hole_size = ~0UL;
2333 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
2335 + * Restore the topdown base:
2337 + mm->mmap_base = base;
2338 + mm->free_area_cache = base;
2339 + mm->cached_hole_size = ~0UL;
2344 struct sel_arg_struct {
2346 diff -urNp linux-2.6.17.7/arch/i386/kernel/syscall_table.S linux-2.6.17.7/arch/i386/kernel/syscall_table.S
2347 --- linux-2.6.17.7/arch/i386/kernel/syscall_table.S 2006-07-24 23:36:01.000000000 -0400
2348 +++ linux-2.6.17.7/arch/i386/kernel/syscall_table.S 2006-08-01 20:29:45.000000000 -0400
2350 +.section .rodata,"a",@progbits
2351 ENTRY(sys_call_table)
2352 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
2354 diff -urNp linux-2.6.17.7/arch/i386/kernel/sysenter.c linux-2.6.17.7/arch/i386/kernel/sysenter.c
2355 --- linux-2.6.17.7/arch/i386/kernel/sysenter.c 2006-07-24 23:36:01.000000000 -0400
2356 +++ linux-2.6.17.7/arch/i386/kernel/sysenter.c 2006-08-01 20:29:45.000000000 -0400
2357 @@ -24,7 +24,7 @@ extern asmlinkage void sysenter_entry(vo
2358 void enable_sep_cpu(void)
2360 int cpu = get_cpu();
2361 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
2362 + struct tss_struct *tss = init_tss + cpu;
2364 if (!boot_cpu_has(X86_FEATURE_SEP)) {
2366 @@ -48,6 +48,7 @@ extern const char vsyscall_sysenter_star
2368 int __init sysenter_setup(void)
2370 +#ifndef CONFIG_PAX_NOVSYSCALL
2371 void *page = (void *)get_zeroed_page(GFP_ATOMIC);
2373 __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
2374 @@ -62,6 +63,7 @@ int __init sysenter_setup(void)
2376 &vsyscall_sysenter_start,
2377 &vsyscall_sysenter_end - &vsyscall_sysenter_start);
2382 diff -urNp linux-2.6.17.7/arch/i386/kernel/traps.c linux-2.6.17.7/arch/i386/kernel/traps.c
2383 --- linux-2.6.17.7/arch/i386/kernel/traps.c 2006-07-24 23:36:01.000000000 -0400
2384 +++ linux-2.6.17.7/arch/i386/kernel/traps.c 2006-08-01 20:29:45.000000000 -0400
2386 #include <linux/utsname.h>
2387 #include <linux/kprobes.h>
2388 #include <linux/kexec.h>
2389 +#include <linux/binfmts.h>
2392 #include <linux/ioport.h>
2395 asmlinkage int system_call(void);
2397 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2398 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2399 { 0, 0 }, { 0, 0 } };
2401 /* Do we ignore FPU interrupts ? */
2402 char ignore_fpu_irq = 0;
2405 - * The IDT has to be page-aligned to simplify the Pentium
2406 - * F0 0F bug workaround.. We have a special link segment
2409 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
2410 +extern struct desc_struct idt_table[256];
2412 asmlinkage void divide_error(void);
2413 asmlinkage void debug(void);
2414 @@ -144,18 +140,22 @@ static inline unsigned long print_contex
2417 int printed = 0; /* nr of entries already printed on current line */
2418 + int i = kstack_depth_to_print;
2420 #ifdef CONFIG_FRAME_POINTER
2421 while (valid_stack_ptr(tinfo, (void *)ebp)) {
2422 addr = *(unsigned long *)(ebp + 4);
2423 printed = print_addr_and_symbol(addr, log_lvl, printed);
2424 ebp = *(unsigned long *)ebp;
2428 while (valid_stack_ptr(tinfo, stack)) {
2430 - if (__kernel_text_address(addr))
2431 + if (__kernel_text_address(addr)) {
2432 printed = print_addr_and_symbol(addr, log_lvl, printed);
2438 @@ -249,7 +249,7 @@ void show_registers(struct pt_regs *regs
2440 esp = (unsigned long) (®s->esp);
2441 savesegment(ss, ss);
2442 - if (user_mode_vm(regs)) {
2443 + if (user_mode(regs)) {
2446 ss = regs->xss & 0xffff;
2447 @@ -276,13 +276,15 @@ void show_registers(struct pt_regs *regs
2451 + mm_segment_t old_fs = get_fs();
2453 printk("\n" KERN_EMERG "Stack: ");
2454 show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG);
2456 printk(KERN_EMERG "Code: ");
2458 - eip = (u8 __user *)regs->eip - 43;
2459 + set_fs(KERNEL_DS);
2460 + eip = (u8 __user *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
2461 for (i = 0; i < 64; i++, eip++) {
2464 @@ -290,11 +292,12 @@ void show_registers(struct pt_regs *regs
2465 printk(" Bad EIP value.");
2468 - if (eip == (u8 __user *)regs->eip)
2469 + if (eip == (u8 __user *)regs->eip + __KERNEL_TEXT_OFFSET)
2470 printk("<%02x> ", c);
2478 @@ -306,9 +309,11 @@ static void handle_BUG(struct pt_regs *r
2482 + mm_segment_t old_fs = get_fs();
2485 + eip = regs->eip + __KERNEL_TEXT_OFFSET;
2487 + set_fs(KERNEL_DS);
2488 if (eip < PAGE_OFFSET)
2490 if (__get_user(ud2, (unsigned short __user *)eip))
2491 @@ -325,10 +330,12 @@ static void handle_BUG(struct pt_regs *r
2492 printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
2498 /* Here we know it was a BUG but file-n-line is unavailable */
2501 printk(KERN_EMERG "Kernel BUG\n");
2504 @@ -430,7 +437,7 @@ void die(const char * str, struct pt_reg
2506 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
2508 - if (!user_mode_vm(regs))
2509 + if (!user_mode(regs))
2510 die(str, regs, err);
2513 @@ -448,7 +455,7 @@ static void __kprobes do_trap(int trapnr
2517 - if (!user_mode(regs))
2518 + if (!user_mode_novm(regs))
2522 @@ -536,7 +543,7 @@ fastcall void __kprobes do_general_prote
2525 int cpu = get_cpu();
2526 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
2527 + struct tss_struct *tss = &init_tss[cpu];
2528 struct thread_struct *thread = ¤t->thread;
2531 @@ -572,9 +579,25 @@ fastcall void __kprobes do_general_prote
2532 if (regs->eflags & VM_MASK)
2535 - if (!user_mode(regs))
2536 + if (!user_mode_novm(regs))
2539 +#ifdef CONFIG_PAX_PAGEEXEC
2540 + if (current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
2541 + struct mm_struct *mm = current->mm;
2542 + unsigned long limit;
2544 + down_write(&mm->mmap_sem);
2545 + limit = mm->context.user_cs_limit;
2546 + if (limit < TASK_SIZE) {
2547 + track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
2548 + up_write(&mm->mmap_sem);
2551 + up_write(&mm->mmap_sem);
2555 current->thread.error_code = error_code;
2556 current->thread.trap_no = 13;
2557 force_sig(SIGSEGV, current);
2558 @@ -590,6 +613,13 @@ gp_in_kernel:
2559 if (notify_die(DIE_GPF, "general protection fault", regs,
2560 error_code, 13, SIGSEGV) == NOTIFY_STOP)
2563 +#ifdef CONFIG_PAX_KERNEXEC
2564 + if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
2565 + die("PAX: suspicious general protection fault", regs, error_code);
2569 die("general protection fault", regs, error_code);
2572 @@ -663,7 +693,7 @@ void die_nmi (struct pt_regs *regs, cons
2573 /* If we are in kernel we are probably nested up pretty bad
2574 * and might aswell get out now while we still can.
2576 - if (!user_mode_vm(regs)) {
2577 + if (!user_mode(regs)) {
2578 current->thread.trap_no = 2;
2581 @@ -816,7 +846,7 @@ fastcall void __kprobes do_debug(struct
2582 * check for kernel mode by just checking the CPL
2585 - if (!user_mode(regs))
2586 + if (!user_mode_novm(regs))
2587 goto clear_TF_reenable;
2590 @@ -1106,7 +1136,19 @@ do { \
2592 void set_intr_gate(unsigned int n, void *addr)
2595 +#ifdef CONFIG_PAX_KERNEXEC
2596 + unsigned long cr0;
2598 + pax_open_kernel(cr0);
2601 _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
2603 +#ifdef CONFIG_PAX_KERNEXEC
2604 + pax_close_kernel(cr0);
2610 diff -urNp linux-2.6.17.7/arch/i386/kernel/vm86.c linux-2.6.17.7/arch/i386/kernel/vm86.c
2611 --- linux-2.6.17.7/arch/i386/kernel/vm86.c 2006-07-24 23:36:01.000000000 -0400
2612 +++ linux-2.6.17.7/arch/i386/kernel/vm86.c 2006-08-01 20:29:45.000000000 -0400
2613 @@ -123,7 +123,7 @@ struct pt_regs * fastcall save_v86_state
2617 - tss = &per_cpu(init_tss, get_cpu());
2618 + tss = init_tss + get_cpu();
2619 current->thread.esp0 = current->thread.saved_esp0;
2620 current->thread.sysenter_cs = __KERNEL_CS;
2621 load_esp0(tss, ¤t->thread);
2622 @@ -297,7 +297,7 @@ static void do_sys_vm86(struct kernel_vm
2623 savesegment(fs, tsk->thread.saved_fs);
2624 savesegment(gs, tsk->thread.saved_gs);
2626 - tss = &per_cpu(init_tss, get_cpu());
2627 + tss = init_tss + get_cpu();
2628 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
2630 tsk->thread.sysenter_cs = 0;
2631 diff -urNp linux-2.6.17.7/arch/i386/kernel/vmlinux.lds.S linux-2.6.17.7/arch/i386/kernel/vmlinux.lds.S
2632 --- linux-2.6.17.7/arch/i386/kernel/vmlinux.lds.S 2006-07-24 23:36:01.000000000 -0400
2633 +++ linux-2.6.17.7/arch/i386/kernel/vmlinux.lds.S 2006-08-01 20:29:45.000000000 -0400
2636 #define LOAD_OFFSET __PAGE_OFFSET
2638 +#include <linux/config.h>
2640 #include <asm-generic/vmlinux.lds.h>
2641 #include <asm/thread_info.h>
2642 #include <asm/page.h>
2643 #include <asm/cache.h>
2644 +#include <asm/segment.h>
2646 +#ifdef CONFIG_X86_PAE
2647 +#define PMD_SHIFT 21
2649 +#define PMD_SHIFT 22
2652 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
2654 @@ -16,59 +25,14 @@ jiffies = jiffies_64;
2658 - phys_startup_32 = startup_32 - LOAD_OFFSET;
2660 - _text = .; /* Text and read-only data */
2661 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
2670 - _etext = .; /* End of text section */
2672 - . = ALIGN(16); /* Exception table */
2673 - __start___ex_table = .;
2674 - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2675 - __stop___ex_table = .;
2678 + phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
2681 - .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
2684 + .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
2685 + BYTE(0xEA) /* jmp far */
2686 + LONG(phys_startup_32)
2691 - __nosave_begin = .;
2692 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2697 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
2702 - .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2703 - *(.data.cacheline_aligned)
2706 - /* rarely changed data like cpu maps */
2708 - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2709 - _edata = .; /* End of data section */
2711 - . = ALIGN(THREAD_SIZE); /* init_task */
2712 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
2713 - *(.data.init_task)
2716 /* might get freed after init */
2718 __smp_alt_begin = .;
2719 @@ -92,11 +56,6 @@ SECTIONS
2720 /* will be freed after init */
2721 . = ALIGN(4096); /* Init code and data */
2723 - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
2728 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
2731 @@ -128,9 +87,7 @@ SECTIONS
2732 .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
2733 *(.altinstr_replacement)
2735 - /* .exit.text is discard at runtime, not link time, to deal with references
2736 - from .altinstructions and .eh_frame */
2737 - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
2739 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
2741 __initramfs_start = .;
2742 @@ -140,10 +97,108 @@ SECTIONS
2743 __per_cpu_start = .;
2744 .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
2751 + .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2757 + /* .exit.text is discard at runtime, not link time, to deal with references
2758 + from .altinstructions and .eh_frame */
2759 + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
2761 +#ifdef CONFIG_PAX_KERNEXEC
2762 + .text.align : AT(ADDR(.text.align) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2763 + . = ALIGN(__KERNEL_TEXT_OFFSET - LOAD_OFFSET) - 1;
2770 + __init_end = . + __KERNEL_TEXT_OFFSET;
2771 /* freed after init ends here */
2774 + _text = .; /* Text and read-only data */
2775 + .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2784 + _etext = .; /* End of text section */
2785 + . += __KERNEL_TEXT_OFFSET;
2786 + . = ALIGN(16); /* Exception table */
2787 + __start___ex_table = .;
2788 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2789 + __stop___ex_table = .;
2792 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
2793 + *(.empty_zero_page)
2795 +#ifdef CONFIG_X86_PAE
2796 + *(.swapper_pm_dir)
2799 + *(.swapper_pg_dir)
2805 +#ifdef CONFIG_PAX_KERNEXEC
2807 + MODULES_VADDR = .;
2809 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
2810 + . += (4 * 1024 * 1024);
2811 + . = ALIGN(1 << PMD_SHIFT) - 1;
2821 + .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
2828 + __nosave_begin = .;
2829 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2834 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2835 + *(.data.cacheline_aligned)
2838 + /* rarely changed data like cpu maps */
2840 + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2842 + . = ALIGN(THREAD_SIZE); /* init_task */
2843 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
2844 + *(.data.init_task)
2847 + _edata = .; /* End of data section */
2850 __bss_start = .; /* BSS */
2851 .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
2852 *(.bss.page_aligned)
2853 diff -urNp linux-2.6.17.7/arch/i386/lib/checksum.S linux-2.6.17.7/arch/i386/lib/checksum.S
2854 --- linux-2.6.17.7/arch/i386/lib/checksum.S 2006-07-24 23:36:01.000000000 -0400
2855 +++ linux-2.6.17.7/arch/i386/lib/checksum.S 2006-08-01 20:29:45.000000000 -0400
2858 #include <linux/config.h>
2859 #include <asm/errno.h>
2861 +#include <asm/segment.h>
2864 * computes a partial checksum, e.g. for TCP/UDP fragments
2866 @@ -281,12 +282,23 @@ unsigned int csum_partial_copy_generic (
2869 .globl csum_partial_copy_generic
2871 +.globl csum_partial_copy_generic_to_user
2872 +.globl csum_partial_copy_generic_from_user
2874 #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
2880 +csum_partial_copy_generic_to_user:
2881 + pushl $(__USER_DS)
2883 + jmp csum_partial_copy_generic
2885 +csum_partial_copy_generic_from_user:
2886 + pushl $(__USER_DS)
2889 csum_partial_copy_generic:
2892 @@ -305,7 +317,7 @@ csum_partial_copy_generic:
2894 SRC(1: movw (%esi), %bx )
2896 -DST( movw %bx, (%edi) )
2897 +DST( movw %bx, %es:(%edi) )
2901 @@ -317,30 +329,30 @@ DST( movw %bx, (%edi) )
2902 SRC(1: movl (%esi), %ebx )
2903 SRC( movl 4(%esi), %edx )
2905 -DST( movl %ebx, (%edi) )
2906 +DST( movl %ebx, %es:(%edi) )
2908 -DST( movl %edx, 4(%edi) )
2909 +DST( movl %edx, %es:4(%edi) )
2911 SRC( movl 8(%esi), %ebx )
2912 SRC( movl 12(%esi), %edx )
2914 -DST( movl %ebx, 8(%edi) )
2915 +DST( movl %ebx, %es:8(%edi) )
2917 -DST( movl %edx, 12(%edi) )
2918 +DST( movl %edx, %es:12(%edi) )
2920 SRC( movl 16(%esi), %ebx )
2921 SRC( movl 20(%esi), %edx )
2923 -DST( movl %ebx, 16(%edi) )
2924 +DST( movl %ebx, %es:16(%edi) )
2926 -DST( movl %edx, 20(%edi) )
2927 +DST( movl %edx, %es:20(%edi) )
2929 SRC( movl 24(%esi), %ebx )
2930 SRC( movl 28(%esi), %edx )
2932 -DST( movl %ebx, 24(%edi) )
2933 +DST( movl %ebx, %es:24(%edi) )
2935 -DST( movl %edx, 28(%edi) )
2936 +DST( movl %edx, %es:28(%edi) )
2940 @@ -354,7 +366,7 @@ DST( movl %edx, 28(%edi) )
2941 shrl $2, %edx # This clears CF
2942 SRC(3: movl (%esi), %ebx )
2944 -DST( movl %ebx, (%edi) )
2945 +DST( movl %ebx, %es:(%edi) )
2949 @@ -366,12 +378,12 @@ DST( movl %ebx, (%edi) )
2951 SRC( movw (%esi), %cx )
2953 -DST( movw %cx, (%edi) )
2954 +DST( movw %cx, %es:(%edi) )
2958 SRC(5: movb (%esi), %cl )
2959 -DST( movb %cl, (%edi) )
2960 +DST( movb %cl, %es:(%edi) )
2964 @@ -382,7 +394,7 @@ DST( movb %cl, (%edi) )
2967 movl ARGBASE+20(%esp), %ebx # src_err_ptr
2968 - movl $-EFAULT, (%ebx)
2969 + movl $-EFAULT, %ss:(%ebx)
2971 # zero the complete destination - computing the rest
2973 @@ -395,11 +407,15 @@ DST( movb %cl, (%edi) )
2976 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
2977 - movl $-EFAULT,(%ebx)
2978 + movl $-EFAULT,%ss:(%ebx)
2990 @@ -411,17 +427,28 @@ DST( movb %cl, (%edi) )
2991 /* Version for PentiumII/PPro */
2995 SRC(movl x(%esi), %ebx ) ; \
2997 - DST(movl %ebx, x(%edi) ) ;
2998 + DST(movl %ebx, %es:x(%edi));
3002 SRC(movl x(%esi), %ebx ) ; \
3004 - DST(movl %ebx, x(%edi) ) ;
3005 + DST(movl %ebx, %es:x(%edi));
3010 +csum_partial_copy_generic_to_user:
3011 + pushl $(__USER_DS)
3013 + jmp csum_partial_copy_generic
3015 +csum_partial_copy_generic_from_user:
3016 + pushl $(__USER_DS)
3019 csum_partial_copy_generic:
3022 @@ -440,7 +467,7 @@ csum_partial_copy_generic:
3026 - lea 3f(%ebx,%ebx), %ebx
3027 + lea 3f(%ebx,%ebx,2), %ebx
3031 @@ -461,19 +488,19 @@ csum_partial_copy_generic:
3033 SRC( movw (%esi), %dx )
3035 -DST( movw %dx, (%edi) )
3036 +DST( movw %dx, %es:(%edi) )
3041 SRC( movb (%esi), %dl )
3042 -DST( movb %dl, (%edi) )
3043 +DST( movb %dl, %es:(%edi) )
3047 .section .fixup, "ax"
3048 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
3049 - movl $-EFAULT, (%ebx)
3050 + movl $-EFAULT, %ss:(%ebx)
3051 # zero the complete destination (computing the rest is too much work)
3052 movl ARGBASE+8(%esp),%edi # dst
3053 movl ARGBASE+12(%esp),%ecx # len
3054 @@ -481,10 +508,14 @@ DST( movb %dl, (%edi) )
3057 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
3058 - movl $-EFAULT, (%ebx)
3059 + movl $-EFAULT, %ss:(%ebx)
3070 diff -urNp linux-2.6.17.7/arch/i386/lib/getuser.S linux-2.6.17.7/arch/i386/lib/getuser.S
3071 --- linux-2.6.17.7/arch/i386/lib/getuser.S 2006-07-24 23:36:01.000000000 -0400
3072 +++ linux-2.6.17.7/arch/i386/lib/getuser.S 2006-08-01 20:29:45.000000000 -0400
3076 #include <asm/thread_info.h>
3077 +#include <asm/segment.h>
3081 @@ -30,8 +31,12 @@ __get_user_1:
3082 GET_THREAD_INFO(%edx)
3083 cmpl TI_addr_limit(%edx),%eax
3085 + pushl $(__USER_DS)
3087 1: movzbl (%eax),%edx
3094 @@ -42,7 +47,11 @@ __get_user_2:
3095 GET_THREAD_INFO(%edx)
3096 cmpl TI_addr_limit(%edx),%eax
3098 + pushl $(__USER_DS)
3100 2: movzwl -1(%eax),%edx
3106 @@ -54,11 +63,17 @@ __get_user_4:
3107 GET_THREAD_INFO(%edx)
3108 cmpl TI_addr_limit(%edx),%eax
3110 + pushl $(__USER_DS)
3112 3: movl -3(%eax),%edx
3124 diff -urNp linux-2.6.17.7/arch/i386/lib/mmx.c linux-2.6.17.7/arch/i386/lib/mmx.c
3125 --- linux-2.6.17.7/arch/i386/lib/mmx.c 2006-07-24 23:36:01.000000000 -0400
3126 +++ linux-2.6.17.7/arch/i386/lib/mmx.c 2006-08-01 20:29:45.000000000 -0400
3127 @@ -48,14 +48,30 @@ void *_mmx_memcpy(void *to, const void *
3128 " prefetch 256(%0)\n"
3130 ".section .fixup, \"ax\"\n"
3131 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3134 +#ifdef CONFIG_PAX_KERNEXEC
3136 + " movl %%cr0, %%eax\n"
3137 + " andl $0xFFFEFFFF, %%eax\n"
3138 + " movl %%eax, %%cr0\n"
3141 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3143 +#ifdef CONFIG_PAX_KERNEXEC
3144 + " orl $0x00010000, %%eax\n"
3145 + " movl %%eax, %%cr0\n"
3151 ".section __ex_table,\"a\"\n"
3156 + : : "r" (from) : "ax");
3160 @@ -79,14 +95,30 @@ void *_mmx_memcpy(void *to, const void *
3161 " movq %%mm2, 48(%1)\n"
3162 " movq %%mm3, 56(%1)\n"
3163 ".section .fixup, \"ax\"\n"
3164 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3167 +#ifdef CONFIG_PAX_KERNEXEC
3169 + " movl %%cr0, %%eax\n"
3170 + " andl $0xFFFEFFFF, %%eax\n"
3171 + " movl %%eax, %%cr0\n"
3174 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3176 +#ifdef CONFIG_PAX_KERNEXEC
3177 + " orl $0x00010000, %%eax\n"
3178 + " movl %%eax, %%cr0\n"
3184 ".section __ex_table,\"a\"\n"
3188 - : : "r" (from), "r" (to) : "memory");
3189 + : : "r" (from), "r" (to) : "memory", "ax");
3193 @@ -179,14 +211,30 @@ static void fast_copy_page(void *to, voi
3194 " prefetch 256(%0)\n"
3196 ".section .fixup, \"ax\"\n"
3197 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3200 +#ifdef CONFIG_PAX_KERNEXEC
3202 + " movl %%cr0, %%eax\n"
3203 + " andl $0xFFFEFFFF, %%eax\n"
3204 + " movl %%eax, %%cr0\n"
3207 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3209 +#ifdef CONFIG_PAX_KERNEXEC
3210 + " orl $0x00010000, %%eax\n"
3211 + " movl %%eax, %%cr0\n"
3217 ".section __ex_table,\"a\"\n"
3222 + : : "r" (from) : "ax");
3224 for(i=0; i<(4096-320)/64; i++)
3226 @@ -209,14 +257,30 @@ static void fast_copy_page(void *to, voi
3227 " movq 56(%0), %%mm7\n"
3228 " movntq %%mm7, 56(%1)\n"
3229 ".section .fixup, \"ax\"\n"
3230 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3233 +#ifdef CONFIG_PAX_KERNEXEC
3235 + " movl %%cr0, %%eax\n"
3236 + " andl $0xFFFEFFFF, %%eax\n"
3237 + " movl %%eax, %%cr0\n"
3240 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3242 +#ifdef CONFIG_PAX_KERNEXEC
3243 + " orl $0x00010000, %%eax\n"
3244 + " movl %%eax, %%cr0\n"
3250 ".section __ex_table,\"a\"\n"
3254 - : : "r" (from), "r" (to) : "memory");
3255 + : : "r" (from), "r" (to) : "memory", "ax");
3259 @@ -309,14 +373,30 @@ static void fast_copy_page(void *to, voi
3260 " prefetch 256(%0)\n"
3262 ".section .fixup, \"ax\"\n"
3263 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3266 +#ifdef CONFIG_PAX_KERNEXEC
3268 + " movl %%cr0, %%eax\n"
3269 + " andl $0xFFFEFFFF, %%eax\n"
3270 + " movl %%eax, %%cr0\n"
3273 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3275 +#ifdef CONFIG_PAX_KERNEXEC
3276 + " orl $0x00010000, %%eax\n"
3277 + " movl %%eax, %%cr0\n"
3283 ".section __ex_table,\"a\"\n"
3288 + : : "r" (from) : "ax");
3290 for(i=0; i<4096/64; i++)
3292 @@ -339,14 +419,30 @@ static void fast_copy_page(void *to, voi
3293 " movq %%mm2, 48(%1)\n"
3294 " movq %%mm3, 56(%1)\n"
3295 ".section .fixup, \"ax\"\n"
3296 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3299 +#ifdef CONFIG_PAX_KERNEXEC
3301 + " movl %%cr0, %%eax\n"
3302 + " andl $0xFFFEFFFF, %%eax\n"
3303 + " movl %%eax, %%cr0\n"
3306 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3308 +#ifdef CONFIG_PAX_KERNEXEC
3309 + " orl $0x00010000, %%eax\n"
3310 + " movl %%eax, %%cr0\n"
3316 ".section __ex_table,\"a\"\n"
3320 - : : "r" (from), "r" (to) : "memory");
3321 + : : "r" (from), "r" (to) : "memory", "ax");
3325 diff -urNp linux-2.6.17.7/arch/i386/lib/putuser.S linux-2.6.17.7/arch/i386/lib/putuser.S
3326 --- linux-2.6.17.7/arch/i386/lib/putuser.S 2006-07-24 23:36:01.000000000 -0400
3327 +++ linux-2.6.17.7/arch/i386/lib/putuser.S 2006-08-01 20:29:45.000000000 -0400
3331 #include <asm/thread_info.h>
3332 +#include <asm/segment.h>
3336 @@ -33,7 +34,11 @@ __put_user_1:
3338 cmpl TI_addr_limit(%ebx),%ecx
3340 + pushl $(__USER_DS)
3348 @@ -45,7 +50,11 @@ __put_user_2:
3352 + pushl $(__USER_DS)
3360 @@ -57,7 +66,11 @@ __put_user_4:
3364 + pushl $(__USER_DS)
3372 @@ -69,12 +82,18 @@ __put_user_8:
3376 + pushl $(__USER_DS)
3379 5: movl %edx,4(%ecx)
3391 diff -urNp linux-2.6.17.7/arch/i386/lib/usercopy.c linux-2.6.17.7/arch/i386/lib/usercopy.c
3392 --- linux-2.6.17.7/arch/i386/lib/usercopy.c 2006-07-24 23:36:01.000000000 -0400
3393 +++ linux-2.6.17.7/arch/i386/lib/usercopy.c 2006-08-01 20:29:45.000000000 -0400
3394 @@ -33,6 +33,7 @@ do { \
3395 int __d0, __d1, __d2; \
3397 __asm__ __volatile__( \
3398 + " movw %w10,%%ds\n" \
3402 @@ -43,6 +44,8 @@ do { \
3408 ".section .fixup,\"ax\"\n" \
3411 @@ -53,7 +56,8 @@ do { \
3413 : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
3415 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
3416 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),\
3421 @@ -123,10 +127,13 @@ do { \
3424 __asm__ __volatile__( \
3425 + " movw %w6,%%es\n" \
3432 ".section .fixup,\"ax\"\n" \
3433 "3: lea 0(%2,%0,4),%0\n" \
3435 @@ -137,7 +144,8 @@ do { \
3438 : "=&c"(size), "=&D" (__d0) \
3439 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
3440 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0), \
3441 + "r"(__USER_DS)); \
3445 @@ -198,14 +206,17 @@ long strnlen_user(const char __user *s,
3448 __asm__ __volatile__(
3449 + " movw %w8,%%es\n"
3452 - " andl %0,%%ecx\n"
3453 + " movl %0,%%ecx\n"
3461 ".section .fixup,\"ax\"\n"
3462 "2: xorl %%eax,%%eax\n"
3464 @@ -217,7 +228,7 @@ long strnlen_user(const char __user *s,
3467 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
3468 - :"0" (n), "1" (s), "2" (0), "3" (mask)
3469 + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
3473 @@ -229,6 +240,7 @@ __copy_user_intel(void __user *to, const
3476 __asm__ __volatile__(
3477 + " movw %w6, %%es\n"
3479 "1: movl 32(%4), %%eax\n"
3481 @@ -237,36 +249,36 @@ __copy_user_intel(void __user *to, const
3483 "3: movl 0(%4), %%eax\n"
3484 "4: movl 4(%4), %%edx\n"
3485 - "5: movl %%eax, 0(%3)\n"
3486 - "6: movl %%edx, 4(%3)\n"
3487 + "5: movl %%eax, %%es:0(%3)\n"
3488 + "6: movl %%edx, %%es:4(%3)\n"
3489 "7: movl 8(%4), %%eax\n"
3490 "8: movl 12(%4),%%edx\n"
3491 - "9: movl %%eax, 8(%3)\n"
3492 - "10: movl %%edx, 12(%3)\n"
3493 + "9: movl %%eax, %%es:8(%3)\n"
3494 + "10: movl %%edx, %%es:12(%3)\n"
3495 "11: movl 16(%4), %%eax\n"
3496 "12: movl 20(%4), %%edx\n"
3497 - "13: movl %%eax, 16(%3)\n"
3498 - "14: movl %%edx, 20(%3)\n"
3499 + "13: movl %%eax, %%es:16(%3)\n"
3500 + "14: movl %%edx, %%es:20(%3)\n"
3501 "15: movl 24(%4), %%eax\n"
3502 "16: movl 28(%4), %%edx\n"
3503 - "17: movl %%eax, 24(%3)\n"
3504 - "18: movl %%edx, 28(%3)\n"
3505 + "17: movl %%eax, %%es:24(%3)\n"
3506 + "18: movl %%edx, %%es:28(%3)\n"
3507 "19: movl 32(%4), %%eax\n"
3508 "20: movl 36(%4), %%edx\n"
3509 - "21: movl %%eax, 32(%3)\n"
3510 - "22: movl %%edx, 36(%3)\n"
3511 + "21: movl %%eax, %%es:32(%3)\n"
3512 + "22: movl %%edx, %%es:36(%3)\n"
3513 "23: movl 40(%4), %%eax\n"
3514 "24: movl 44(%4), %%edx\n"
3515 - "25: movl %%eax, 40(%3)\n"
3516 - "26: movl %%edx, 44(%3)\n"
3517 + "25: movl %%eax, %%es:40(%3)\n"
3518 + "26: movl %%edx, %%es:44(%3)\n"
3519 "27: movl 48(%4), %%eax\n"
3520 "28: movl 52(%4), %%edx\n"
3521 - "29: movl %%eax, 48(%3)\n"
3522 - "30: movl %%edx, 52(%3)\n"
3523 + "29: movl %%eax, %%es:48(%3)\n"
3524 + "30: movl %%edx, %%es:52(%3)\n"
3525 "31: movl 56(%4), %%eax\n"
3526 "32: movl 60(%4), %%edx\n"
3527 - "33: movl %%eax, 56(%3)\n"
3528 - "34: movl %%edx, 60(%3)\n"
3529 + "33: movl %%eax, %%es:56(%3)\n"
3530 + "34: movl %%edx, %%es:60(%3)\n"
3534 @@ -280,6 +292,8 @@ __copy_user_intel(void __user *to, const
3535 "36: movl %%eax, %0\n"
3540 ".section .fixup,\"ax\"\n"
3541 "101: lea 0(%%eax,%0,4),%0\n"
3543 @@ -326,7 +340,7 @@ __copy_user_intel(void __user *to, const
3546 : "=&c"(size), "=&D" (d0), "=&S" (d1)
3547 - : "1"(to), "2"(from), "0"(size)
3548 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
3549 : "eax", "edx", "memory");
3552 @@ -336,6 +350,7 @@ __copy_user_zeroing_intel(void *to, cons
3555 __asm__ __volatile__(
3556 + " movw %w6, %%ds\n"
3558 "0: movl 32(%4), %%eax\n"
3560 @@ -344,36 +359,36 @@ __copy_user_zeroing_intel(void *to, cons
3562 "2: movl 0(%4), %%eax\n"
3563 "21: movl 4(%4), %%edx\n"
3564 - " movl %%eax, 0(%3)\n"
3565 - " movl %%edx, 4(%3)\n"
3566 + " movl %%eax, %%es:0(%3)\n"
3567 + " movl %%edx, %%es:4(%3)\n"
3568 "3: movl 8(%4), %%eax\n"
3569 "31: movl 12(%4),%%edx\n"
3570 - " movl %%eax, 8(%3)\n"
3571 - " movl %%edx, 12(%3)\n"
3572 + " movl %%eax, %%es:8(%3)\n"
3573 + " movl %%edx, %%es:12(%3)\n"
3574 "4: movl 16(%4), %%eax\n"
3575 "41: movl 20(%4), %%edx\n"
3576 - " movl %%eax, 16(%3)\n"
3577 - " movl %%edx, 20(%3)\n"
3578 + " movl %%eax, %%es:16(%3)\n"
3579 + " movl %%edx, %%es:20(%3)\n"
3580 "10: movl 24(%4), %%eax\n"
3581 "51: movl 28(%4), %%edx\n"
3582 - " movl %%eax, 24(%3)\n"
3583 - " movl %%edx, 28(%3)\n"
3584 + " movl %%eax, %%es:24(%3)\n"
3585 + " movl %%edx, %%es:28(%3)\n"
3586 "11: movl 32(%4), %%eax\n"
3587 "61: movl 36(%4), %%edx\n"
3588 - " movl %%eax, 32(%3)\n"
3589 - " movl %%edx, 36(%3)\n"
3590 + " movl %%eax, %%es:32(%3)\n"
3591 + " movl %%edx, %%es:36(%3)\n"
3592 "12: movl 40(%4), %%eax\n"
3593 "71: movl 44(%4), %%edx\n"
3594 - " movl %%eax, 40(%3)\n"
3595 - " movl %%edx, 44(%3)\n"
3596 + " movl %%eax, %%es:40(%3)\n"
3597 + " movl %%edx, %%es:44(%3)\n"
3598 "13: movl 48(%4), %%eax\n"
3599 "81: movl 52(%4), %%edx\n"
3600 - " movl %%eax, 48(%3)\n"
3601 - " movl %%edx, 52(%3)\n"
3602 + " movl %%eax, %%es:48(%3)\n"
3603 + " movl %%edx, %%es:52(%3)\n"
3604 "14: movl 56(%4), %%eax\n"
3605 "91: movl 60(%4), %%edx\n"
3606 - " movl %%eax, 56(%3)\n"
3607 - " movl %%edx, 60(%3)\n"
3608 + " movl %%eax, %%es:56(%3)\n"
3609 + " movl %%edx, %%es:60(%3)\n"
3613 @@ -387,6 +402,8 @@ __copy_user_zeroing_intel(void *to, cons
3619 ".section .fixup,\"ax\"\n"
3620 "9: lea 0(%%eax,%0,4),%0\n"
3622 @@ -421,7 +438,7 @@ __copy_user_zeroing_intel(void *to, cons
3625 : "=&c"(size), "=&D" (d0), "=&S" (d1)
3626 - : "1"(to), "2"(from), "0"(size)
3627 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
3628 : "eax", "edx", "memory");
3631 @@ -441,6 +458,7 @@ __copy_user_intel(void __user *to, const
3633 int __d0, __d1, __d2; \
3634 __asm__ __volatile__( \
3635 + " movw %w8,%%es\n" \
3639 @@ -456,6 +474,8 @@ do { \
3645 ".section .fixup,\"ax\"\n" \
3648 @@ -469,7 +489,7 @@ do { \
3651 : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
3652 - : "3"(size), "0"(size), "1"(to), "2"(from) \
3653 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)\
3657 @@ -477,6 +497,7 @@ do { \
3659 int __d0, __d1, __d2; \
3660 __asm__ __volatile__( \
3661 + " movw %w8,%%ds\n" \
3665 @@ -492,6 +513,8 @@ do { \
3671 ".section .fixup,\"ax\"\n" \
3674 @@ -511,7 +534,7 @@ do { \
3677 : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
3678 - : "3"(size), "0"(size), "1"(to), "2"(from) \
3679 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)\
3683 @@ -640,3 +663,45 @@ copy_from_user(void *to, const void __us
3686 EXPORT_SYMBOL(copy_from_user);
3688 +#ifdef CONFIG_PAX_MEMORY_UDEREF
3689 +void __set_fs(mm_segment_t x, int cpu)
3691 + unsigned long limit = x.seg;
3693 + current_thread_info()->addr_limit = x;
3694 + if (likely(limit)) {
3699 + get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].a = (limit & 0xFFFFUL);
3700 + get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].b = (limit & 0xF0000UL) | 0xC0F300UL;
3703 +void set_fs(mm_segment_t x)
3705 + int cpu = get_cpu();
3707 +#ifdef CONFIG_PAX_KERNEXEC
3708 + unsigned long cr0;
3710 + pax_open_kernel(cr0);
3715 +#ifdef CONFIG_PAX_KERNEXEC
3716 + pax_close_kernel(cr0);
3719 + put_cpu_no_resched();
3722 +void set_fs(mm_segment_t x)
3724 + current_thread_info()->addr_limit = x;
3728 +EXPORT_SYMBOL(set_fs);
3729 diff -urNp linux-2.6.17.7/arch/i386/mach-voyager/voyager_smp.c linux-2.6.17.7/arch/i386/mach-voyager/voyager_smp.c
3730 --- linux-2.6.17.7/arch/i386/mach-voyager/voyager_smp.c 2006-07-24 23:36:01.000000000 -0400
3731 +++ linux-2.6.17.7/arch/i386/mach-voyager/voyager_smp.c 2006-08-01 20:29:45.000000000 -0400
3732 @@ -1295,7 +1295,7 @@ smp_local_timer_interrupt(struct pt_regs
3733 per_cpu(prof_counter, cpu);
3736 - update_process_times(user_mode_vm(regs));
3737 + update_process_times(user_mode(regs));
3740 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
3741 diff -urNp linux-2.6.17.7/arch/i386/mm/boot_ioremap.c linux-2.6.17.7/arch/i386/mm/boot_ioremap.c
3742 --- linux-2.6.17.7/arch/i386/mm/boot_ioremap.c 2006-07-24 23:36:01.000000000 -0400
3743 +++ linux-2.6.17.7/arch/i386/mm/boot_ioremap.c 2006-08-01 20:29:45.000000000 -0400
3749 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
3750 - * keeps that from happenning. If anyone has a better way, I'm listening.
3752 - * boot_pte_t is defined only if this all works correctly
3755 #include <linux/config.h>
3756 -#undef CONFIG_X86_PAE
3757 #include <asm/page.h>
3758 #include <asm/pgtable.h>
3759 #include <asm/tlbflush.h>
3760 #include <linux/init.h>
3761 #include <linux/stddef.h>
3764 - * I'm cheating here. It is known that the two boot PTE pages are
3765 - * allocated next to each other. I'm pretending that they're just
3769 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
3770 -#define boot_pte_index(address) \
3771 - (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
3773 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
3775 - boot_pte_t* boot_pg = (boot_pte_t*)pg0;
3776 - return &boot_pg[boot_pte_index((unsigned long)address)];
3780 * This is only for a caller who is clever enough to page-align
3781 * phys_addr and virtual_source, and who also has a preference
3782 * about which virtual address from which to steal ptes
3784 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
3785 - void* virtual_source)
3786 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned int nrpages,
3787 + char* virtual_source)
3791 - char *vaddr = virtual_source;
3797 + unsigned long vaddr = (unsigned long)virtual_source;
3799 + pgd = pgd_offset_k(vaddr);
3800 + pud = pud_offset(pgd, vaddr);
3801 + pmd = pmd_offset(pud, vaddr);
3802 + pte = pte_offset_kernel(pmd, vaddr);
3804 - pte = boot_vaddr_to_pte(virtual_source);
3805 for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
3806 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
3807 - __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
3808 + __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
3812 diff -urNp linux-2.6.17.7/arch/i386/mm/extable.c linux-2.6.17.7/arch/i386/mm/extable.c
3813 --- linux-2.6.17.7/arch/i386/mm/extable.c 2006-07-24 23:36:01.000000000 -0400
3814 +++ linux-2.6.17.7/arch/i386/mm/extable.c 2006-08-01 20:29:45.000000000 -0400
3815 @@ -12,7 +12,7 @@ int fixup_exception(struct pt_regs *regs
3816 const struct exception_table_entry *fixup;
3818 #ifdef CONFIG_PNPBIOS
3819 - if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3)))
3820 + if (unlikely(regs->xcs == (GDT_ENTRY_PNPBIOS_BASE << 3)))
3822 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
3823 extern u32 pnp_bios_is_utter_crap;
3824 diff -urNp linux-2.6.17.7/arch/i386/mm/fault.c linux-2.6.17.7/arch/i386/mm/fault.c
3825 --- linux-2.6.17.7/arch/i386/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
3826 +++ linux-2.6.17.7/arch/i386/mm/fault.c 2006-08-01 20:29:45.000000000 -0400
3828 #include <linux/highmem.h>
3829 #include <linux/module.h>
3830 #include <linux/kprobes.h>
3831 +#include <linux/unistd.h>
3832 +#include <linux/compiler.h>
3833 +#include <linux/binfmts.h>
3835 #include <asm/system.h>
3836 #include <asm/uaccess.h>
3837 @@ -82,11 +85,13 @@ static inline unsigned long get_segment_
3839 /* Unlikely, but must come before segment checks. */
3840 if (unlikely((regs->eflags & VM_MASK) != 0))
3841 - return eip + (seg << 4);
3842 + return (eip & 0xFFFF) + (seg << 4);
3844 /* By far the most common cases. */
3845 - if (likely(seg == __USER_CS || seg == __KERNEL_CS))
3846 + if (likely(seg == __USER_CS))
3848 + if (likely(seg == __KERNEL_CS))
3849 + return eip + __KERNEL_TEXT_OFFSET;
3851 /* Check the segment exists, is within the current LDT/GDT size,
3852 that kernel/user (ring 0..3) has the appropriate privilege,
3853 @@ -214,6 +219,30 @@ static noinline void force_sig_info_faul
3855 fastcall void do_invalid_op(struct pt_regs *, unsigned long);
3857 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
3858 +static int pax_handle_fetch_fault(struct pt_regs *regs);
3861 +#ifdef CONFIG_PAX_PAGEEXEC
3862 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
3868 + pgd = pgd_offset(mm, address);
3869 + if (!pgd_present(*pgd))
3871 + pud = pud_offset(pgd, address);
3872 + if (!pud_present(*pud))
3874 + pmd = pmd_offset(pud, address);
3875 + if (!pmd_present(*pmd))
3881 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
3883 unsigned index = pgd_index(address);
3884 @@ -295,13 +324,20 @@ fastcall void __kprobes do_page_fault(st
3885 struct mm_struct *mm;
3886 struct vm_area_struct * vma;
3887 unsigned long address;
3888 - unsigned long page;
3891 +#ifdef CONFIG_PAX_PAGEEXEC
3895 + unsigned char pte_mask;
3898 /* get the address */
3899 address = read_cr2();
3904 si_code = SEGV_MAPERR;
3906 @@ -340,14 +376,12 @@ fastcall void __kprobes do_page_fault(st
3907 if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
3913 * If we're in an interrupt, have no user context or are running in an
3914 * atomic region then we must not take the fault..
3916 if (in_atomic() || !mm)
3917 - goto bad_area_nosemaphore;
3918 + goto bad_area_nopax;
3920 /* When running in the kernel we expect faults to occur only to
3921 * addresses in user space. All other faults represent errors in the
3922 @@ -367,10 +401,101 @@ fastcall void __kprobes do_page_fault(st
3923 if (!down_read_trylock(&mm->mmap_sem)) {
3924 if ((error_code & 4) == 0 &&
3925 !search_exception_tables(regs->eip))
3926 - goto bad_area_nosemaphore;
3927 + goto bad_area_nopax;
3928 down_read(&mm->mmap_sem);
3931 +#ifdef CONFIG_PAX_PAGEEXEC
3932 + if (unlikely((error_code & 5) != 5 ||
3933 + (regs->eflags & X86_EFLAGS_VM) ||
3934 + !(mm->pax_flags & MF_PAX_PAGEEXEC)))
3935 + goto not_pax_fault;
3937 + /* PaX: it's our fault, let's handle it if we can */
3939 + /* PaX: take a look at read faults before acquiring any locks */
3940 + if (unlikely(!(error_code & 2) && (regs->eip == address))) {
3941 + /* instruction fetch attempt from a protected page in user mode */
3942 + up_read(&mm->mmap_sem);
3943 + switch (pax_handle_fetch_fault(regs)) {
3945 +#ifdef CONFIG_PAX_EMUTRAMP
3951 + pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
3955 + pmd = pax_get_pmd(mm, address);
3956 + if (unlikely(!pmd))
3957 + goto not_pax_fault;
3959 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
3960 + if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
3961 + pte_unmap_unlock(pte, ptl);
3962 + goto not_pax_fault;
3965 + if (unlikely((error_code & 2) && !pte_write(*pte))) {
3966 + /* write attempt to a protected page in user mode */
3967 + pte_unmap_unlock(pte, ptl);
3968 + goto not_pax_fault;
3972 + if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
3974 + if (likely(address > get_limit(regs->xcs)))
3977 + set_pte(pte, pte_mkread(*pte));
3978 + __flush_tlb_one(address);
3979 + pte_unmap_unlock(pte, ptl);
3980 + up_read(&mm->mmap_sem);
3984 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
3987 + * PaX: fill DTLB with user rights and retry
3989 + __asm__ __volatile__ (
3991 + "orb %2,%%ss:(%1)\n"
3992 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
3994 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
3995 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
3996 + * page fault when examined during a TLB load attempt. this is true not only
3997 + * for PTEs holding a non-present entry but also present entries that will
3998 + * raise a page fault (such as those set up by PaX, or the copy-on-write
3999 + * mechanism). in effect it means that we do *not* need to flush the TLBs
4000 + * for our target pages since their PTEs are simply not in the TLBs at all.
4002 + * the best thing in omitting it is that we gain around 15-20% speed in the
4003 + * fast path of the page fault handler and can get rid of tracing since we
4004 + * can no longer flush unintended entries.
4009 + "xorb %3,%%ss:(%1)\n"
4013 + : "q" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
4014 + : "memory", "cc");
4015 + pte_unmap_unlock(pte, ptl);
4016 + up_read(&mm->mmap_sem);
4022 vma = find_vma(mm, address);
4025 @@ -456,6 +581,37 @@ bad_area:
4026 up_read(&mm->mmap_sem);
4028 bad_area_nosemaphore:
4030 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4031 + if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
4033 +#ifdef CONFIG_PAX_PAGEEXEC
4034 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
4035 + pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4040 +#ifdef CONFIG_PAX_SEGMEXEC
4041 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
4043 + switch (pax_handle_fetch_fault(regs)) {
4045 +#ifdef CONFIG_PAX_EMUTRAMP
4051 + pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4060 /* User mode accesses just cause a SIGSEGV */
4061 if (error_code & 4) {
4063 @@ -523,6 +679,21 @@ no_context:
4064 if (address < PAGE_SIZE)
4065 printk(KERN_ALERT "BUG: unable to handle kernel NULL "
4066 "pointer dereference");
4068 +#ifdef CONFIG_PAX_KERNEXEC
4069 +#ifdef CONFIG_MODULES
4070 + else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
4072 + else if (init_mm.start_code <= address && address < init_mm.end_code)
4074 + if (tsk->signal->curr_ip)
4075 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
4076 + NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
4078 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
4079 + tsk->comm, tsk->pid, tsk->uid, tsk->euid);
4083 printk(KERN_ALERT "BUG: unable to handle kernel paging"
4085 @@ -530,24 +701,34 @@ no_context:
4086 printk(KERN_ALERT " printing eip:\n");
4087 printk("%08lx\n", regs->eip);
4089 - page = read_cr3();
4090 - page = ((unsigned long *) __va(page))[address >> 22];
4091 - if (oops_may_print())
4092 - printk(KERN_ALERT "*pde = %08lx\n", page);
4094 - * We must not directly access the pte in the highpte
4095 - * case, the page table might be allocated in highmem.
4096 - * And lets rather not kmap-atomic the pte, just in case
4097 - * it's allocated already.
4100 + if (oops_may_print()) {
4101 + unsigned long index = pgd_index(address);
4107 + pgd = index + (pgd_t *)__va(read_cr3());
4108 + printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
4109 + if (pgd_present(*pgd)) {
4110 + pud = pud_offset(pgd, address);
4111 + pmd = pmd_offset(pud, address);
4112 + printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
4114 + * We must not directly access the pte in the highpte
4115 + * case, the page table might be allocated in highmem.
4116 + * And lets rather not kmap-atomic the pte, just in case
4117 + * it's allocated already.
4119 #ifndef CONFIG_HIGHPTE
4120 - if ((page & 1) && oops_may_print()) {
4121 - page &= PAGE_MASK;
4122 - address &= 0x003ff000;
4123 - page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
4124 - printk(KERN_ALERT "*pte = %08lx\n", page);
4126 + if (pmd_present(*pmd) && !pmd_large(*pmd)) {
4127 + pte = pte_offset_kernel(pmd, address);
4128 + printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
4133 tsk->thread.cr2 = address;
4134 tsk->thread.trap_no = 14;
4135 tsk->thread.error_code = error_code;
4136 @@ -624,3 +805,105 @@ void vmalloc_sync_all(void)
4141 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4143 + * PaX: decide what to do with offenders (regs->eip = fault address)
4145 + * returns 1 when task should be killed
4146 + * 2 when gcc trampoline was detected
4148 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4151 +#ifdef CONFIG_PAX_EMUTRAMP
4152 + static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
4156 + if (regs->eflags & X86_EFLAGS_VM)
4159 +#ifdef CONFIG_PAX_EMUTRAMP
4160 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
4163 + do { /* PaX: gcc trampoline emulation #1 */
4164 + unsigned char mov1, mov2;
4165 + unsigned short jmp;
4166 + unsigned long addr1, addr2;
4168 + err = get_user(mov1, (unsigned char __user *)regs->eip);
4169 + err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
4170 + err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
4171 + err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
4172 + err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
4177 + if ((mov1 & 0xF8) == 0xB8 &&
4178 + (mov2 & 0xF8) == 0xB8 &&
4179 + (mov1 & 0x07) != (mov2 & 0x07) &&
4180 + (jmp & 0xF8FF) == 0xE0FF &&
4181 + (mov2 & 0x07) == ((jmp>>8) & 0x07))
4183 + ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
4184 + ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
4185 + regs->eip = addr2;
4190 + do { /* PaX: gcc trampoline emulation #2 */
4191 + unsigned char mov, jmp;
4192 + unsigned long addr1, addr2;
4194 + err = get_user(mov, (unsigned char __user *)regs->eip);
4195 + err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
4196 + err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
4197 + err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
4202 + if ((mov & 0xF8) == 0xB8 &&
4205 + ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
4206 + regs->eip += addr2 + 10;
4212 + return 1; /* PaX in action */
4216 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4217 +void pax_report_insns(void *pc, void *sp)
4221 + printk(KERN_ERR "PAX: bytes at PC: ");
4222 + for (i = 0; i < 20; i++) {
4224 + if (get_user(c, (unsigned char __user *)pc+i))
4227 + printk("%02x ", c);
4231 + printk(KERN_ERR "PAX: bytes at SP-4: ");
4232 + for (i = -1; i < 20; i++) {
4234 + if (get_user(c, (unsigned long __user *)sp+i))
4235 + printk("???????? ");
4237 + printk("%08lx ", c);
4242 diff -urNp linux-2.6.17.7/arch/i386/mm/hugetlbpage.c linux-2.6.17.7/arch/i386/mm/hugetlbpage.c
4243 --- linux-2.6.17.7/arch/i386/mm/hugetlbpage.c 2006-07-24 23:36:01.000000000 -0400
4244 +++ linux-2.6.17.7/arch/i386/mm/hugetlbpage.c 2006-08-01 20:29:45.000000000 -0400
4245 @@ -121,7 +121,12 @@ static unsigned long hugetlb_get_unmappe
4247 struct mm_struct *mm = current->mm;
4248 struct vm_area_struct *vma;
4249 - unsigned long start_addr;
4250 + unsigned long start_addr, task_size = TASK_SIZE;
4252 +#ifdef CONFIG_PAX_SEGMEXEC
4253 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
4254 + task_size = SEGMEXEC_TASK_SIZE;
4257 if (len > mm->cached_hole_size) {
4258 start_addr = mm->free_area_cache;
4259 @@ -135,7 +140,7 @@ full_search:
4261 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
4262 /* At this point: (!vma || addr < vma->vm_end). */
4263 - if (TASK_SIZE - len < addr) {
4264 + if (task_size - len < addr) {
4266 * Start a new search - just in case we missed
4268 @@ -163,9 +168,8 @@ static unsigned long hugetlb_get_unmappe
4270 struct mm_struct *mm = current->mm;
4271 struct vm_area_struct *vma, *prev_vma;
4272 - unsigned long base = mm->mmap_base, addr = addr0;
4273 + unsigned long base = mm->mmap_base, addr;
4274 unsigned long largest_hole = mm->cached_hole_size;
4275 - int first_time = 1;
4277 /* don't allow allocations above current base */
4278 if (mm->free_area_cache > base)
4279 @@ -175,7 +179,7 @@ static unsigned long hugetlb_get_unmappe
4281 mm->free_area_cache = base;
4285 /* make sure it can fit in the remaining address space */
4286 if (mm->free_area_cache < len)
4288 @@ -217,16 +221,6 @@ try_again:
4292 - * if hint left us with no space for the requested
4293 - * mapping then try again:
4296 - mm->free_area_cache = base;
4302 * A failed mmap() very likely causes application failure,
4303 * so fall back to the bottom-up function here. This scenario
4304 * can happen with large stack limits and large mmap()
4305 @@ -252,16 +246,23 @@ hugetlb_get_unmapped_area(struct file *f
4307 struct mm_struct *mm = current->mm;
4308 struct vm_area_struct *vma;
4309 + unsigned long task_size = TASK_SIZE;
4311 if (len & ~HPAGE_MASK)
4313 - if (len > TASK_SIZE)
4315 +#ifdef CONFIG_PAX_SEGMEXEC
4316 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
4317 + task_size = SEGMEXEC_TASK_SIZE;
4320 + if (len > task_size || addr > task_size - len)
4324 addr = ALIGN(addr, HPAGE_SIZE);
4325 vma = find_vma(mm, addr);
4326 - if (TASK_SIZE - len >= addr &&
4327 + if (task_size - len >= addr &&
4328 (!vma || addr + len <= vma->vm_start))
4331 diff -urNp linux-2.6.17.7/arch/i386/mm/init.c linux-2.6.17.7/arch/i386/mm/init.c
4332 --- linux-2.6.17.7/arch/i386/mm/init.c 2006-07-24 23:36:01.000000000 -0400
4333 +++ linux-2.6.17.7/arch/i386/mm/init.c 2006-08-01 20:29:45.000000000 -0400
4335 #include <asm/tlb.h>
4336 #include <asm/tlbflush.h>
4337 #include <asm/sections.h>
4338 +#include <asm/desc.h>
4340 unsigned int __VMALLOC_RESERVE = 128 << 20;
4342 @@ -50,30 +51,6 @@ unsigned long highstart_pfn, highend_pfn
4343 static int noinline do_test_wp_bit(void);
4346 - * Creates a middle page table and puts a pointer to it in the
4347 - * given global directory entry. This only returns the gd entry
4348 - * in non-PAE compilation mode, since the middle layer is folded.
4350 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
4355 -#ifdef CONFIG_X86_PAE
4356 - pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
4357 - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
4358 - pud = pud_offset(pgd, 0);
4359 - if (pmd_table != pmd_offset(pud, 0))
4362 - pud = pud_offset(pgd, 0);
4363 - pmd_table = pmd_offset(pud, 0);
4370 * Create a page table and place a pointer to it in a middle page
4373 @@ -81,7 +58,11 @@ static pte_t * __init one_page_table_ini
4375 if (pmd_none(*pmd)) {
4376 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
4377 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4378 + set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
4380 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
4382 if (page_table != pte_offset_kernel(pmd, 0))
4385 @@ -116,8 +97,6 @@ static void __init page_table_range_init
4386 pgd = pgd_base + pgd_idx;
4388 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
4389 - if (pgd_none(*pgd))
4390 - one_md_table_init(pgd);
4391 pud = pud_offset(pgd, vaddr);
4392 pmd = pmd_offset(pud, vaddr);
4393 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
4394 @@ -130,11 +109,22 @@ static void __init page_table_range_init
4398 -static inline int is_kernel_text(unsigned long addr)
4399 +static inline int is_kernel_text(unsigned long start, unsigned long end)
4401 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
4404 + unsigned long etext;
4406 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
4407 + etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
4409 + etext = (unsigned long)&_etext;
4412 + if ((start > etext + __KERNEL_TEXT_OFFSET ||
4413 + end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
4414 + (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
4415 + end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
4421 @@ -146,26 +136,24 @@ static void __init kernel_physical_mappi
4428 - int pgd_idx, pmd_idx, pte_ofs;
4429 + unsigned int pgd_idx, pmd_idx, pte_ofs;
4431 pgd_idx = pgd_index(PAGE_OFFSET);
4432 pgd = pgd_base + pgd_idx;
4435 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
4436 - pmd = one_md_table_init(pgd);
4437 - if (pfn >= max_low_pfn)
4439 + for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
4440 + pud = pud_offset(pgd, 0);
4441 + pmd = pmd_offset(pud, 0);
4442 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
4443 - unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
4444 + unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
4446 /* Map with big pages if possible, otherwise create normal page tables. */
4448 - unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
4450 - if (is_kernel_text(address) || is_kernel_text(address2))
4451 + if (is_kernel_text(address, address + PMD_SIZE))
4452 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
4454 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
4455 @@ -174,7 +162,7 @@ static void __init kernel_physical_mappi
4456 pte = one_page_table_init(pmd);
4458 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
4459 - if (is_kernel_text(address))
4460 + if (is_kernel_text(address, address + PAGE_SIZE))
4461 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
4463 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
4464 @@ -341,13 +329,6 @@ static void __init pagetable_init (void)
4465 unsigned long vaddr;
4466 pgd_t *pgd_base = swapper_pg_dir;
4468 -#ifdef CONFIG_X86_PAE
4470 - /* Init entries of the first-level page table to the zero page */
4471 - for (i = 0; i < PTRS_PER_PGD; i++)
4472 - set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
4475 /* Enable PSE if available */
4477 set_in_cr4(X86_CR4_PSE);
4478 @@ -371,17 +352,6 @@ static void __init pagetable_init (void)
4479 page_table_range_init(vaddr, 0, pgd_base);
4481 permanent_kmaps_init(pgd_base);
4483 -#ifdef CONFIG_X86_PAE
4485 - * Add low memory identity-mappings - SMP needs it when
4486 - * starting up on an AP from real-mode. In the non-PAE
4487 - * case we already have these mappings through head.S.
4488 - * All user-space mappings are explicitly cleared after
4491 - set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
4495 #ifdef CONFIG_SOFTWARE_SUSPEND
4496 @@ -423,7 +393,6 @@ void zap_low_mappings (void)
4500 -static int disable_nx __initdata = 0;
4501 u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
4504 @@ -437,11 +406,9 @@ u64 __supported_pte_mask __read_mostly =
4505 void __init noexec_setup(const char *str)
4507 if (!strncmp(str, "on",2) && cpu_has_nx) {
4508 - __supported_pte_mask |= _PAGE_NX;
4511 } else if (!strncmp(str,"off",3)) {
4513 - __supported_pte_mask &= ~_PAGE_NX;
4518 @@ -450,17 +417,13 @@ int nx_enabled = 0;
4520 static void __init set_nx(void)
4522 - unsigned int v[4], l, h;
4523 + if (!nx_enabled && cpu_has_nx) {
4526 - if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
4527 - cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
4528 - if ((v[3] & (1 << 20)) && !disable_nx) {
4529 - rdmsr(MSR_EFER, l, h);
4531 - wrmsr(MSR_EFER, l, h);
4533 - __supported_pte_mask |= _PAGE_NX;
4535 + __supported_pte_mask &= ~_PAGE_NX;
4536 + rdmsr(MSR_EFER, l, h);
4538 + wrmsr(MSR_EFER, l, h);
4542 @@ -512,14 +475,6 @@ void __init paging_init(void)
4544 load_cr3(swapper_pg_dir);
4546 -#ifdef CONFIG_X86_PAE
4548 - * We will bail out later - printk doesn't work right now so
4549 - * the user would just see a hanging kernel.
4552 - set_in_cr4(X86_CR4_PAE);
4557 @@ -611,7 +566,7 @@ void __init mem_init(void)
4558 set_highmem_pages_init(bad_ppro);
4560 codesize = (unsigned long) &_etext - (unsigned long) &_text;
4561 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
4562 + datasize = (unsigned long) &_edata - (unsigned long) &_data;
4563 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
4565 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
4566 @@ -628,10 +583,6 @@ void __init mem_init(void)
4567 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
4570 -#ifdef CONFIG_X86_PAE
4572 - panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
4574 if (boot_cpu_data.wp_works_ok < 0)
4577 @@ -761,6 +712,37 @@ void free_init_pages(char *what, unsigne
4579 void free_initmem(void)
4582 +#ifdef CONFIG_PAX_KERNEXEC
4583 + /* PaX: limit KERNEL_CS to actual size */
4584 + unsigned long addr, limit;
4590 +#ifdef CONFIG_MODULES
4591 + limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
4593 + limit = (unsigned long)&_etext;
4595 + limit = (limit - 1UL) >> PAGE_SHIFT;
4597 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
4598 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
4599 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
4602 + /* PaX: make KERNEL_CS read-only */
4603 + for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
4604 + pgd = pgd_offset_k(addr);
4605 + pud = pud_offset(pgd, addr);
4606 + pmd = pmd_offset(pud, addr);
4607 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
4612 free_init_pages("unused kernel memory",
4613 (unsigned long)(&__init_begin),
4614 (unsigned long)(&__init_end));
4615 diff -urNp linux-2.6.17.7/arch/i386/mm/mmap.c linux-2.6.17.7/arch/i386/mm/mmap.c
4616 --- linux-2.6.17.7/arch/i386/mm/mmap.c 2006-07-24 23:36:01.000000000 -0400
4617 +++ linux-2.6.17.7/arch/i386/mm/mmap.c 2006-08-01 20:29:45.000000000 -0400
4619 * Leave an at least ~128 MB hole.
4621 #define MIN_GAP (128*1024*1024)
4622 -#define MAX_GAP (TASK_SIZE/6*5)
4623 +#define MAX_GAP (task_size/6*5)
4625 static inline unsigned long mmap_base(struct mm_struct *mm)
4627 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
4628 unsigned long random_factor = 0;
4629 + unsigned long task_size = TASK_SIZE;
4631 +#ifdef CONFIG_PAX_SEGMEXEC
4632 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
4633 + task_size = SEGMEXEC_TASK_SIZE;
4636 if (current->flags & PF_RANDOMIZE)
4637 random_factor = get_random_int() % (1024*1024);
4638 @@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
4639 else if (gap > MAX_GAP)
4642 - return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
4643 + return PAGE_ALIGN(task_size - gap - random_factor);
4647 @@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
4648 (current->personality & ADDR_COMPAT_LAYOUT) ||
4649 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
4650 mm->mmap_base = TASK_UNMAPPED_BASE;
4652 +#ifdef CONFIG_PAX_RANDMMAP
4653 + if (mm->pax_flags & MF_PAX_RANDMMAP)
4654 + mm->mmap_base += mm->delta_mmap;
4657 mm->get_unmapped_area = arch_get_unmapped_area;
4658 mm->unmap_area = arch_unmap_area;
4660 mm->mmap_base = mmap_base(mm);
4662 +#ifdef CONFIG_PAX_RANDMMAP
4663 + if (mm->pax_flags & MF_PAX_RANDMMAP)
4664 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
4667 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
4668 mm->unmap_area = arch_unmap_area_topdown;
4670 diff -urNp linux-2.6.17.7/arch/i386/mm/pageattr.c linux-2.6.17.7/arch/i386/mm/pageattr.c
4671 --- linux-2.6.17.7/arch/i386/mm/pageattr.c 2006-07-24 23:36:01.000000000 -0400
4672 +++ linux-2.6.17.7/arch/i386/mm/pageattr.c 2006-08-01 20:29:45.000000000 -0400
4674 #include <asm/tlbflush.h>
4675 #include <asm/pgalloc.h>
4676 #include <asm/sections.h>
4677 +#include <asm/desc.h>
4679 static DEFINE_SPINLOCK(cpa_lock);
4680 static struct list_head df_list = LIST_HEAD_INIT(df_list);
4681 @@ -84,7 +85,18 @@ static void set_pmd_pte(pte_t *kpte, uns
4683 unsigned long flags;
4685 +#ifdef CONFIG_PAX_KERNEXEC
4686 + unsigned long cr0;
4688 + pax_open_kernel(cr0);
4691 set_pte_atomic(kpte, pte); /* change init_mm */
4693 +#ifdef CONFIG_PAX_KERNEXEC
4694 + pax_close_kernel(cr0);
4697 if (PTRS_PER_PMD > 1)
4700 @@ -111,7 +123,7 @@ static inline void revert_page(struct pa
4704 - ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
4705 + ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
4706 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
4709 @@ -143,7 +155,7 @@ __change_page_attr(struct page *page, pg
4713 - ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
4714 + ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
4715 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
4716 split = split_large_page(address, prot, ref_prot);
4718 diff -urNp linux-2.6.17.7/arch/i386/oprofile/backtrace.c linux-2.6.17.7/arch/i386/oprofile/backtrace.c
4719 --- linux-2.6.17.7/arch/i386/oprofile/backtrace.c 2006-07-24 23:36:01.000000000 -0400
4720 +++ linux-2.6.17.7/arch/i386/oprofile/backtrace.c 2006-08-01 20:29:45.000000000 -0400
4721 @@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
4722 head = (struct frame_head *)regs->ebp;
4725 - if (!user_mode_vm(regs)) {
4726 + if (!user_mode(regs)) {
4727 while (depth-- && valid_kernel_stack(head, regs))
4728 head = dump_kernel_backtrace(head);
4730 diff -urNp linux-2.6.17.7/arch/i386/power/cpu.c linux-2.6.17.7/arch/i386/power/cpu.c
4731 --- linux-2.6.17.7/arch/i386/power/cpu.c 2006-07-24 23:36:01.000000000 -0400
4732 +++ linux-2.6.17.7/arch/i386/power/cpu.c 2006-08-01 20:29:45.000000000 -0400
4733 @@ -62,7 +62,7 @@ static void do_fpu_end(void)
4734 static void fix_processor_context(void)
4736 int cpu = smp_processor_id();
4737 - struct tss_struct * t = &per_cpu(init_tss, cpu);
4738 + struct tss_struct * t = init_tss + cpu;
4740 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. */
4742 diff -urNp linux-2.6.17.7/arch/ia64/ia32/binfmt_elf32.c linux-2.6.17.7/arch/ia64/ia32/binfmt_elf32.c
4743 --- linux-2.6.17.7/arch/ia64/ia32/binfmt_elf32.c 2006-07-24 23:36:01.000000000 -0400
4744 +++ linux-2.6.17.7/arch/ia64/ia32/binfmt_elf32.c 2006-08-01 20:29:45.000000000 -0400
4745 @@ -46,6 +46,17 @@ randomize_stack_top(unsigned long stack_
4747 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
4749 +#ifdef CONFIG_PAX_ASLR
4750 +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
4752 +#define PAX_DELTA_MMAP_LSB(tsk) IA32_PAGE_SHIFT
4753 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
4754 +#define PAX_DELTA_EXEC_LSB(tsk) IA32_PAGE_SHIFT
4755 +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
4756 +#define PAX_DELTA_STACK_LSB(tsk) IA32_PAGE_SHIFT
4757 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
4760 /* Ugly but avoids duplication */
4761 #include "../../../fs/binfmt_elf.c"
4763 diff -urNp linux-2.6.17.7/arch/ia64/ia32/ia32priv.h linux-2.6.17.7/arch/ia64/ia32/ia32priv.h
4764 --- linux-2.6.17.7/arch/ia64/ia32/ia32priv.h 2006-07-24 23:36:01.000000000 -0400
4765 +++ linux-2.6.17.7/arch/ia64/ia32/ia32priv.h 2006-08-01 20:29:45.000000000 -0400
4766 @@ -305,7 +305,14 @@ struct old_linux32_dirent {
4767 #define ELF_DATA ELFDATA2LSB
4768 #define ELF_ARCH EM_386
4770 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
4771 +#ifdef CONFIG_PAX_RANDUSTACK
4772 +#define __IA32_DELTA_STACK (current->mm->delta_stack)
4774 +#define __IA32_DELTA_STACK 0UL
4777 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
4779 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
4780 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
4782 diff -urNp linux-2.6.17.7/arch/ia64/kernel/module.c linux-2.6.17.7/arch/ia64/kernel/module.c
4783 --- linux-2.6.17.7/arch/ia64/kernel/module.c 2006-07-24 23:36:01.000000000 -0400
4784 +++ linux-2.6.17.7/arch/ia64/kernel/module.c 2006-08-01 20:29:45.000000000 -0400
4785 @@ -322,7 +322,7 @@ module_alloc (unsigned long size)
4787 module_free (struct module *mod, void *module_region)
4789 - if (mod->arch.init_unw_table && module_region == mod->module_init) {
4790 + if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
4791 unw_remove_unwind_table(mod->arch.init_unw_table);
4792 mod->arch.init_unw_table = NULL;
4794 @@ -500,15 +500,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
4798 +in_init_rx (const struct module *mod, uint64_t addr)
4800 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
4804 +in_init_rw (const struct module *mod, uint64_t addr)
4806 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
4810 in_init (const struct module *mod, uint64_t addr)
4812 - return addr - (uint64_t) mod->module_init < mod->init_size;
4813 + return in_init_rx(mod, value) || in_init_rw(mod, value);
4817 +in_core_rx (const struct module *mod, uint64_t addr)
4819 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
4823 +in_core_rw (const struct module *mod, uint64_t addr)
4825 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
4829 in_core (const struct module *mod, uint64_t addr)
4831 - return addr - (uint64_t) mod->module_core < mod->core_size;
4832 + return in_core_rx(mod, value) || in_core_rw(mod, value);
4836 @@ -692,7 +716,14 @@ do_reloc (struct module *mod, uint8_t r_
4840 - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
4841 + if (in_init_rx(mod, val))
4842 + val -= (uint64_t) mod->module_init_rx;
4843 + else if (in_init_rw(mod, val))
4844 + val -= (uint64_t) mod->module_init_rw;
4845 + else if (in_core_rx(mod, val))
4846 + val -= (uint64_t) mod->module_core_rx;
4847 + else if (in_core_rw(mod, val))
4848 + val -= (uint64_t) mod->module_core_rw;
4852 @@ -826,15 +857,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
4853 * addresses have been selected...
4856 - if (mod->core_size > MAX_LTOFF)
4857 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
4859 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
4860 * at the end of the module.
4862 - gp = mod->core_size - MAX_LTOFF / 2;
4863 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
4865 - gp = mod->core_size / 2;
4866 - gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
4867 + gp = (mod->core_size_rx + mod->core_size_rw) / 2;
4868 + gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
4870 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
4872 diff -urNp linux-2.6.17.7/arch/ia64/kernel/ptrace.c linux-2.6.17.7/arch/ia64/kernel/ptrace.c
4873 --- linux-2.6.17.7/arch/ia64/kernel/ptrace.c 2006-07-24 23:36:01.000000000 -0400
4874 +++ linux-2.6.17.7/arch/ia64/kernel/ptrace.c 2006-08-01 20:29:45.000000000 -0400
4876 #include <linux/audit.h>
4877 #include <linux/signal.h>
4878 #include <linux/vs_pid.h>
4879 +#include <linux/grsecurity.h>
4881 #include <asm/pgtable.h>
4882 #include <asm/processor.h>
4883 @@ -1447,6 +1448,9 @@ sys_ptrace (long request, pid_t pid, uns
4884 if (pid == 1) /* no messing around with init! */
4887 + if (gr_handle_ptrace(child, request))
4890 if (request == PTRACE_ATTACH) {
4891 ret = ptrace_attach(child);
4893 diff -urNp linux-2.6.17.7/arch/ia64/kernel/sys_ia64.c linux-2.6.17.7/arch/ia64/kernel/sys_ia64.c
4894 --- linux-2.6.17.7/arch/ia64/kernel/sys_ia64.c 2006-07-24 23:36:01.000000000 -0400
4895 +++ linux-2.6.17.7/arch/ia64/kernel/sys_ia64.c 2006-08-01 20:29:45.000000000 -0400
4896 @@ -38,6 +38,13 @@ arch_get_unmapped_area (struct file *fil
4897 if (REGION_NUMBER(addr) == RGN_HPAGE)
4901 +#ifdef CONFIG_PAX_RANDMMAP
4902 + if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
4903 + addr = mm->free_area_cache;
4908 addr = mm->free_area_cache;
4910 @@ -56,9 +63,9 @@ arch_get_unmapped_area (struct file *fil
4911 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
4912 /* At this point: (!vma || addr < vma->vm_end). */
4913 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
4914 - if (start_addr != TASK_UNMAPPED_BASE) {
4915 + if (start_addr != mm->mmap_base) {
4916 /* Start a new search --- just in case we missed some holes. */
4917 - addr = TASK_UNMAPPED_BASE;
4918 + addr = mm->mmap_base;
4922 diff -urNp linux-2.6.17.7/arch/ia64/mm/fault.c linux-2.6.17.7/arch/ia64/mm/fault.c
4923 --- linux-2.6.17.7/arch/ia64/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
4924 +++ linux-2.6.17.7/arch/ia64/mm/fault.c 2006-08-01 20:29:45.000000000 -0400
4926 #include <linux/interrupt.h>
4927 #include <linux/kprobes.h>
4928 #include <linux/vs_memory.h>
4929 +#include <linux/binfmts.h>
4931 #include <asm/pgtable.h>
4932 #include <asm/processor.h>
4933 @@ -51,6 +52,23 @@ mapped_kernel_page_is_present (unsigned
4934 return pte_present(pte);
4937 +#ifdef CONFIG_PAX_PAGEEXEC
4938 +void pax_report_insns(void *pc, void *sp)
4942 + printk(KERN_ERR "PAX: bytes at PC: ");
4943 + for (i = 0; i < 8; i++) {
4945 + if (get_user(c, (unsigned int*)pc+i))
4946 + printk("???????? ");
4948 + printk("%08x ", c);
4955 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
4957 @@ -116,9 +134,23 @@ ia64_do_page_fault (unsigned long addres
4958 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
4959 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
4961 - if ((vma->vm_flags & mask) != mask)
4962 + if ((vma->vm_flags & mask) != mask) {
4964 +#ifdef CONFIG_PAX_PAGEEXEC
4965 + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
4966 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
4969 + up_read(&mm->mmap_sem);
4970 + pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
4981 * If for any reason at all we couldn't handle the fault, make
4982 diff -urNp linux-2.6.17.7/arch/ia64/mm/init.c linux-2.6.17.7/arch/ia64/mm/init.c
4983 --- linux-2.6.17.7/arch/ia64/mm/init.c 2006-07-24 23:36:01.000000000 -0400
4984 +++ linux-2.6.17.7/arch/ia64/mm/init.c 2006-08-01 20:29:45.000000000 -0400
4986 #include <linux/swap.h>
4987 #include <linux/proc_fs.h>
4988 #include <linux/bitops.h>
4989 +#include <linux/a.out.h>
4991 -#include <asm/a.out.h>
4992 #include <asm/dma.h>
4993 #include <asm/ia32.h>
4995 diff -urNp linux-2.6.17.7/arch/mips/kernel/binfmt_elfn32.c linux-2.6.17.7/arch/mips/kernel/binfmt_elfn32.c
4996 --- linux-2.6.17.7/arch/mips/kernel/binfmt_elfn32.c 2006-07-24 23:36:01.000000000 -0400
4997 +++ linux-2.6.17.7/arch/mips/kernel/binfmt_elfn32.c 2006-08-01 20:29:45.000000000 -0400
4998 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
4999 #undef ELF_ET_DYN_BASE
5000 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
5002 +#ifdef CONFIG_PAX_ASLR
5003 +#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5005 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
5006 +#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5007 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
5008 +#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5009 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
5010 +#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5013 #include <asm/processor.h>
5014 #include <linux/module.h>
5015 #include <linux/elfcore.h>
5016 diff -urNp linux-2.6.17.7/arch/mips/kernel/binfmt_elfo32.c linux-2.6.17.7/arch/mips/kernel/binfmt_elfo32.c
5017 --- linux-2.6.17.7/arch/mips/kernel/binfmt_elfo32.c 2006-07-24 23:36:01.000000000 -0400
5018 +++ linux-2.6.17.7/arch/mips/kernel/binfmt_elfo32.c 2006-08-01 20:29:45.000000000 -0400
5019 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
5020 #undef ELF_ET_DYN_BASE
5021 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
5023 +#ifdef CONFIG_PAX_ASLR
5024 +#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5026 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
5027 +#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5028 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
5029 +#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5030 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
5031 +#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5034 #include <asm/processor.h>
5035 #include <linux/module.h>
5036 #include <linux/elfcore.h>
5037 diff -urNp linux-2.6.17.7/arch/mips/kernel/syscall.c linux-2.6.17.7/arch/mips/kernel/syscall.c
5038 --- linux-2.6.17.7/arch/mips/kernel/syscall.c 2006-07-24 23:36:01.000000000 -0400
5039 +++ linux-2.6.17.7/arch/mips/kernel/syscall.c 2006-08-01 20:29:45.000000000 -0400
5040 @@ -89,6 +89,11 @@ unsigned long arch_get_unmapped_area(str
5042 if (filp || (flags & MAP_SHARED))
5045 +#ifdef CONFIG_PAX_RANDMMAP
5046 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5051 addr = COLOUR_ALIGN(addr, pgoff);
5052 @@ -99,7 +104,7 @@ unsigned long arch_get_unmapped_area(str
5053 (!vmm || addr + len <= vmm->vm_start))
5056 - addr = TASK_UNMAPPED_BASE;
5057 + addr = current->mm->mmap_base;
5059 addr = COLOUR_ALIGN(addr, pgoff);
5061 diff -urNp linux-2.6.17.7/arch/mips/mm/fault.c linux-2.6.17.7/arch/mips/mm/fault.c
5062 --- linux-2.6.17.7/arch/mips/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
5063 +++ linux-2.6.17.7/arch/mips/mm/fault.c 2006-08-01 20:29:45.000000000 -0400
5065 #include <asm/ptrace.h>
5066 #include <asm/highmem.h> /* For VMALLOC_END */
5068 +#ifdef CONFIG_PAX_PAGEEXEC
5069 +void pax_report_insns(void *pc)
5073 + printk(KERN_ERR "PAX: bytes at PC: ");
5074 + for (i = 0; i < 5; i++) {
5076 + if (get_user(c, (unsigned int*)pc+i))
5077 + printk("???????? ");
5079 + printk("%08x ", c);
5086 * This routine handles page faults. It determines the address,
5087 * and the problem, and then passes it off to one of the appropriate
5088 diff -urNp linux-2.6.17.7/arch/parisc/kernel/module.c linux-2.6.17.7/arch/parisc/kernel/module.c
5089 --- linux-2.6.17.7/arch/parisc/kernel/module.c 2006-07-24 23:36:01.000000000 -0400
5090 +++ linux-2.6.17.7/arch/parisc/kernel/module.c 2006-08-01 20:29:45.000000000 -0400
5093 /* three functions to determine where in the module core
5094 * or init pieces the location is */
5095 +static inline int is_init_rx(struct module *me, void *loc)
5097 + return (loc >= me->module_init_rx &&
5098 + loc < (me->module_init_rx + me->init_size_rx));
5101 +static inline int is_init_rw(struct module *me, void *loc)
5103 + return (loc >= me->module_init_rw &&
5104 + loc < (me->module_init_rw + me->init_size_rw));
5107 static inline int is_init(struct module *me, void *loc)
5109 - return (loc >= me->module_init &&
5110 - loc <= (me->module_init + me->init_size));
5111 + return is_init_rx(me, loc) || is_init_rw(me, loc);
5114 +static inline int is_core_rx(struct module *me, void *loc)
5116 + return (loc >= me->module_core_rx &&
5117 + loc < (me->module_core_rx + me->core_size_rx));
5120 +static inline int is_core_rw(struct module *me, void *loc)
5122 + return (loc >= me->module_core_rw &&
5123 + loc < (me->module_core_rw + me->core_size_rw));
5126 static inline int is_core(struct module *me, void *loc)
5128 - return (loc >= me->module_core &&
5129 - loc <= (me->module_core + me->core_size));
5130 + return is_core_rx(me, loc) || is_core_rw(me, loc);
5133 static inline int is_local(struct module *me, void *loc)
5134 @@ -289,21 +311,21 @@ int module_frob_arch_sections(CONST Elf_
5137 /* align things a bit */
5138 - me->core_size = ALIGN(me->core_size, 16);
5139 - me->arch.got_offset = me->core_size;
5140 - me->core_size += gots * sizeof(struct got_entry);
5142 - me->core_size = ALIGN(me->core_size, 16);
5143 - me->arch.fdesc_offset = me->core_size;
5144 - me->core_size += fdescs * sizeof(Elf_Fdesc);
5146 - me->core_size = ALIGN(me->core_size, 16);
5147 - me->arch.stub_offset = me->core_size;
5148 - me->core_size += stubs * sizeof(struct stub_entry);
5150 - me->init_size = ALIGN(me->init_size, 16);
5151 - me->arch.init_stub_offset = me->init_size;
5152 - me->init_size += init_stubs * sizeof(struct stub_entry);
5153 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
5154 + me->arch.got_offset = me->core_size_rw;
5155 + me->core_size_rw += gots * sizeof(struct got_entry);
5157 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
5158 + me->arch.fdesc_offset = me->core_size_rw;
5159 + me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
5161 + me->core_size_rx = ALIGN(me->core_size_rx, 16);
5162 + me->arch.stub_offset = me->core_size_rx;
5163 + me->core_size_rx += stubs * sizeof(struct stub_entry);
5165 + me->init_size_rx = ALIGN(me->init_size_rx, 16);
5166 + me->arch.init_stub_offset = me->init_size_rx;
5167 + me->init_size_rx += init_stubs * sizeof(struct stub_entry);
5169 me->arch.got_max = gots;
5170 me->arch.fdesc_max = fdescs;
5171 @@ -323,7 +345,7 @@ static Elf64_Word get_got(struct module
5175 - got = me->module_core + me->arch.got_offset;
5176 + got = me->module_core_rw + me->arch.got_offset;
5177 for (i = 0; got[i].addr; i++)
5178 if (got[i].addr == value)
5180 @@ -341,7 +363,7 @@ static Elf64_Word get_got(struct module
5182 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
5184 - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
5185 + Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
5188 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
5189 @@ -359,7 +381,7 @@ static Elf_Addr get_fdesc(struct module
5191 /* Create new one */
5192 fdesc->addr = value;
5193 - fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
5194 + fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
5195 return (Elf_Addr)fdesc;
5197 #endif /* __LP64__ */
5198 @@ -373,12 +395,12 @@ static Elf_Addr get_stub(struct module *
5200 i = me->arch.init_stub_count++;
5201 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
5202 - stub = me->module_init + me->arch.init_stub_offset +
5203 + stub = me->module_init_rx + me->arch.init_stub_offset +
5204 i * sizeof(struct stub_entry);
5206 i = me->arch.stub_count++;
5207 BUG_ON(me->arch.stub_count > me->arch.stub_max);
5208 - stub = me->module_core + me->arch.stub_offset +
5209 + stub = me->module_core_rx + me->arch.stub_offset +
5210 i * sizeof(struct stub_entry);
5213 @@ -721,7 +743,7 @@ register_unwind_table(struct module *me,
5215 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
5216 end = table + sechdrs[me->arch.unwind_section].sh_size;
5217 - gp = (Elf_Addr)me->module_core + me->arch.got_offset;
5218 + gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
5220 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
5221 me->arch.unwind_section, table, end, gp);
5222 diff -urNp linux-2.6.17.7/arch/parisc/kernel/ptrace.c linux-2.6.17.7/arch/parisc/kernel/ptrace.c
5223 --- linux-2.6.17.7/arch/parisc/kernel/ptrace.c 2006-07-24 23:36:01.000000000 -0400
5224 +++ linux-2.6.17.7/arch/parisc/kernel/ptrace.c 2006-08-01 20:29:45.000000000 -0400
5226 #include <linux/security.h>
5227 #include <linux/compat.h>
5228 #include <linux/signal.h>
5229 +#include <linux/grsecurity.h>
5231 #include <asm/uaccess.h>
5232 #include <asm/pgtable.h>
5233 diff -urNp linux-2.6.17.7/arch/parisc/kernel/sys_parisc.c linux-2.6.17.7/arch/parisc/kernel/sys_parisc.c
5234 --- linux-2.6.17.7/arch/parisc/kernel/sys_parisc.c 2006-07-24 23:36:01.000000000 -0400
5235 +++ linux-2.6.17.7/arch/parisc/kernel/sys_parisc.c 2006-08-01 20:29:45.000000000 -0400
5236 @@ -105,7 +105,7 @@ unsigned long arch_get_unmapped_area(str
5237 if (len > TASK_SIZE)
5240 - addr = TASK_UNMAPPED_BASE;
5241 + addr = current->mm->mmap_base;
5244 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
5245 diff -urNp linux-2.6.17.7/arch/parisc/kernel/traps.c linux-2.6.17.7/arch/parisc/kernel/traps.c
5246 --- linux-2.6.17.7/arch/parisc/kernel/traps.c 2006-07-24 23:36:01.000000000 -0400
5247 +++ linux-2.6.17.7/arch/parisc/kernel/traps.c 2006-08-01 20:29:45.000000000 -0400
5248 @@ -711,9 +711,7 @@ void handle_interruption(int code, struc
5250 down_read(¤t->mm->mmap_sem);
5251 vma = find_vma(current->mm,regs->iaoq[0]);
5252 - if (vma && (regs->iaoq[0] >= vma->vm_start)
5253 - && (vma->vm_flags & VM_EXEC)) {
5255 + if (vma && (regs->iaoq[0] >= vma->vm_start)) {
5256 fault_address = regs->iaoq[0];
5257 fault_space = regs->iasq[0];
5259 diff -urNp linux-2.6.17.7/arch/parisc/mm/fault.c linux-2.6.17.7/arch/parisc/mm/fault.c
5260 --- linux-2.6.17.7/arch/parisc/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
5261 +++ linux-2.6.17.7/arch/parisc/mm/fault.c 2006-08-01 20:29:45.000000000 -0400
5263 #include <linux/sched.h>
5264 #include <linux/interrupt.h>
5265 #include <linux/module.h>
5266 +#include <linux/unistd.h>
5267 +#include <linux/binfmts.h>
5269 #include <asm/uaccess.h>
5270 #include <asm/traps.h>
5271 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
5272 static unsigned long
5273 parisc_acctyp(unsigned long code, unsigned int inst)
5275 - if (code == 6 || code == 16)
5276 + if (code == 6 || code == 7 || code == 16)
5279 switch (inst & 0xf0000000) {
5280 @@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
5284 +#ifdef CONFIG_PAX_PAGEEXEC
5286 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
5288 + * returns 1 when task should be killed
5289 + * 2 when rt_sigreturn trampoline was detected
5290 + * 3 when unpatched PLT trampoline was detected
5292 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5295 +#ifdef CONFIG_PAX_EMUPLT
5298 + do { /* PaX: unpatched PLT emulation */
5299 + unsigned int bl, depwi;
5301 + err = get_user(bl, (unsigned int*)instruction_pointer(regs));
5302 + err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
5307 + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
5308 + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
5310 + err = get_user(ldw, (unsigned int*)addr);
5311 + err |= get_user(bv, (unsigned int*)(addr+4));
5312 + err |= get_user(ldw2, (unsigned int*)(addr+8));
5317 + if (ldw == 0x0E801096U &&
5318 + bv == 0xEAC0C000U &&
5319 + ldw2 == 0x0E881095U)
5321 + unsigned int resolver, map;
5323 + err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
5324 + err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
5328 + regs->gr[20] = instruction_pointer(regs)+8;
5329 + regs->gr[21] = map;
5330 + regs->gr[22] = resolver;
5331 + regs->iaoq[0] = resolver | 3UL;
5332 + regs->iaoq[1] = regs->iaoq[0] + 4;
5339 +#ifdef CONFIG_PAX_EMUTRAMP
5341 +#ifndef CONFIG_PAX_EMUSIGRT
5342 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
5346 + do { /* PaX: rt_sigreturn emulation */
5347 + unsigned int ldi1, ldi2, bel, nop;
5349 + err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
5350 + err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
5351 + err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
5352 + err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
5357 + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
5358 + ldi2 == 0x3414015AU &&
5359 + bel == 0xE4008200U &&
5360 + nop == 0x08000240U)
5362 + regs->gr[25] = (ldi1 & 2) >> 1;
5363 + regs->gr[20] = __NR_rt_sigreturn;
5364 + regs->gr[31] = regs->iaoq[1] + 16;
5365 + regs->sr[0] = regs->iasq[1];
5366 + regs->iaoq[0] = 0x100UL;
5367 + regs->iaoq[1] = regs->iaoq[0] + 4;
5368 + regs->iasq[0] = regs->sr[2];
5369 + regs->iasq[1] = regs->sr[2];
5378 +void pax_report_insns(void *pc, void *sp)
5382 + printk(KERN_ERR "PAX: bytes at PC: ");
5383 + for (i = 0; i < 5; i++) {
5385 + if (get_user(c, (unsigned int*)pc+i))
5386 + printk("???????? ");
5388 + printk("%08x ", c);
5394 void do_page_fault(struct pt_regs *regs, unsigned long code,
5395 unsigned long address)
5397 @@ -168,8 +280,33 @@ good_area:
5399 acc_type = parisc_acctyp(code,regs->iir);
5401 - if ((vma->vm_flags & acc_type) != acc_type)
5402 + if ((vma->vm_flags & acc_type) != acc_type) {
5404 +#ifdef CONFIG_PAX_PAGEEXEC
5405 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
5406 + (address & ~3UL) == instruction_pointer(regs))
5408 + up_read(&mm->mmap_sem);
5409 + switch(pax_handle_fetch_fault(regs)) {
5411 +#ifdef CONFIG_PAX_EMUPLT
5416 +#ifdef CONFIG_PAX_EMUTRAMP
5422 + pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
5431 * If for any reason at all we couldn't handle the fault, make
5432 diff -urNp linux-2.6.17.7/arch/powerpc/kernel/module_32.c linux-2.6.17.7/arch/powerpc/kernel/module_32.c
5433 --- linux-2.6.17.7/arch/powerpc/kernel/module_32.c 2006-07-24 23:36:01.000000000 -0400
5434 +++ linux-2.6.17.7/arch/powerpc/kernel/module_32.c 2006-08-01 20:29:45.000000000 -0400
5435 @@ -123,7 +123,7 @@ int module_frob_arch_sections(Elf32_Ehdr
5436 me->arch.core_plt_section = i;
5438 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
5439 - printk("Module doesn't contain .plt or .init.plt sections.\n");
5440 + printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
5444 @@ -164,11 +164,16 @@ static uint32_t do_plt_call(void *locati
5446 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
5447 /* Init, or core PLT? */
5448 - if (location >= mod->module_core
5449 - && location < mod->module_core + mod->core_size)
5450 + if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
5451 + (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
5452 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
5454 + else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
5455 + (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
5456 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
5458 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
5462 /* Find this entry, or if that fails, the next avail. entry */
5463 while (entry->jump[0]) {
5464 diff -urNp linux-2.6.17.7/arch/powerpc/mm/fault.c linux-2.6.17.7/arch/powerpc/mm/fault.c
5465 --- linux-2.6.17.7/arch/powerpc/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
5466 +++ linux-2.6.17.7/arch/powerpc/mm/fault.c 2006-08-01 20:29:45.000000000 -0400
5468 #include <linux/highmem.h>
5469 #include <linux/module.h>
5470 #include <linux/kprobes.h>
5471 +#include <linux/binfmts.h>
5473 #include <asm/page.h>
5474 #include <asm/pgtable.h>
5475 @@ -103,6 +104,38 @@ static void do_dabr(struct pt_regs *regs
5477 #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
5479 +#ifdef CONFIG_PAX_PAGEEXEC
5481 + * PaX: decide what to do with offenders (regs->nip = fault address)
5483 + * returns 1 when task should be killed
5485 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5488 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
5495 +void pax_report_insns(void *pc, void *sp)
5499 + printk(KERN_ERR "PAX: bytes at PC: ");
5500 + for (i = 0; i < 5; i++) {
5502 + if (get_user(c, (unsigned int*)pc+i))
5503 + printk("???????? ");
5505 + printk("%08x ", c);
5512 * For 600- and 800-family processors, the error_code parameter is DSISR
5513 * for a data fault, SRR1 for an instruction fault. For 400-family processors
5514 @@ -335,6 +368,19 @@ bad_area:
5515 bad_area_nosemaphore:
5516 /* User mode accesses cause a SIGSEGV */
5517 if (user_mode(regs)) {
5519 +#ifdef CONFIG_PAX_PAGEEXEC
5520 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
5521 + if (is_exec && (error_code & DSISR_PROTFAULT)) {
5522 + switch (pax_handle_fetch_fault(regs)) {
5525 + pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
5531 _exception(SIGSEGV, regs, code, address);
5534 diff -urNp linux-2.6.17.7/arch/powerpc/mm/mmap.c linux-2.6.17.7/arch/powerpc/mm/mmap.c
5535 --- linux-2.6.17.7/arch/powerpc/mm/mmap.c 2006-07-24 23:36:01.000000000 -0400
5536 +++ linux-2.6.17.7/arch/powerpc/mm/mmap.c 2006-08-01 20:29:45.000000000 -0400
5537 @@ -74,10 +74,22 @@ void arch_pick_mmap_layout(struct mm_str
5539 if (mmap_is_legacy()) {
5540 mm->mmap_base = TASK_UNMAPPED_BASE;
5542 +#ifdef CONFIG_PAX_RANDMMAP
5543 + if (mm->pax_flags & MF_PAX_RANDMMAP)
5544 + mm->mmap_base += mm->delta_mmap;
5547 mm->get_unmapped_area = arch_get_unmapped_area;
5548 mm->unmap_area = arch_unmap_area;
5550 mm->mmap_base = mmap_base();
5552 +#ifdef CONFIG_PAX_RANDMMAP
5553 + if (mm->pax_flags & MF_PAX_RANDMMAP)
5554 + mm->mmap_base -= mm->delta_mmap;
5557 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
5558 mm->unmap_area = arch_unmap_area_topdown;
5560 diff -urNp linux-2.6.17.7/arch/ppc/mm/fault.c linux-2.6.17.7/arch/ppc/mm/fault.c
5561 --- linux-2.6.17.7/arch/ppc/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
5562 +++ linux-2.6.17.7/arch/ppc/mm/fault.c 2006-08-01 20:29:46.000000000 -0400
5564 #include <linux/interrupt.h>
5565 #include <linux/highmem.h>
5566 #include <linux/module.h>
5567 +#include <linux/slab.h>
5568 +#include <linux/pagemap.h>
5569 +#include <linux/compiler.h>
5570 +#include <linux/binfmts.h>
5571 +#include <linux/unistd.h>
5573 #include <asm/page.h>
5574 #include <asm/pgtable.h>
5575 @@ -49,6 +54,364 @@ unsigned long pte_misses; /* updated by
5576 unsigned long pte_errors; /* updated by do_page_fault() */
5577 unsigned int probingmem;
5579 +#ifdef CONFIG_PAX_EMUSIGRT
5580 +void pax_syscall_close(struct vm_area_struct * vma)
5582 + vma->vm_mm->call_syscall = 0UL;
5585 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
5587 + struct page* page;
5588 + unsigned int *kaddr;
5590 + page = alloc_page(GFP_HIGHUSER);
5592 + return NOPAGE_OOM;
5594 + kaddr = kmap(page);
5595 + memset(kaddr, 0, PAGE_SIZE);
5596 + kaddr[0] = 0x44000002U; /* sc */
5597 + __flush_dcache_icache(kaddr);
5600 + *type = VM_FAULT_MAJOR;
5604 +static struct vm_operations_struct pax_vm_ops = {
5605 + .close = pax_syscall_close,
5606 + .nopage = pax_syscall_nopage,
5609 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
5613 + memset(vma, 0, sizeof(*vma));
5614 + vma->vm_mm = current->mm;
5615 + vma->vm_start = addr;
5616 + vma->vm_end = addr + PAGE_SIZE;
5617 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
5618 + vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
5619 + vma->vm_ops = &pax_vm_ops;
5621 + ret = insert_vm_struct(current->mm, vma);
5625 + ++current->mm->total_vm;
5630 +#ifdef CONFIG_PAX_PAGEEXEC
5632 + * PaX: decide what to do with offenders (regs->nip = fault address)
5634 + * returns 1 when task should be killed
5635 + * 2 when patched GOT trampoline was detected
5636 + * 3 when patched PLT trampoline was detected
5637 + * 4 when unpatched PLT trampoline was detected
5638 + * 5 when sigreturn trampoline was detected
5639 + * 7 when rt_sigreturn trampoline was detected
5641 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5644 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
5648 +#ifdef CONFIG_PAX_EMUPLT
5649 + do { /* PaX: patched GOT emulation */
5650 + unsigned int blrl;
5652 + err = get_user(blrl, (unsigned int*)regs->nip);
5654 + if (!err && blrl == 0x4E800021U) {
5655 + unsigned long temp = regs->nip;
5657 + regs->nip = regs->link & 0xFFFFFFFCUL;
5658 + regs->link = temp + 4UL;
5663 + do { /* PaX: patched PLT emulation #1 */
5666 + err = get_user(b, (unsigned int *)regs->nip);
5668 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
5669 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
5674 + do { /* PaX: unpatched PLT emulation #1 */
5675 + unsigned int li, b;
5677 + err = get_user(li, (unsigned int *)regs->nip);
5678 + err |= get_user(b, (unsigned int *)(regs->nip+4));
5680 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
5681 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
5682 + unsigned long addr = b | 0xFC000000UL;
5684 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
5685 + err = get_user(rlwinm, (unsigned int*)addr);
5686 + err |= get_user(add, (unsigned int*)(addr+4));
5687 + err |= get_user(li2, (unsigned int*)(addr+8));
5688 + err |= get_user(addis2, (unsigned int*)(addr+12));
5689 + err |= get_user(mtctr, (unsigned int*)(addr+16));
5690 + err |= get_user(li3, (unsigned int*)(addr+20));
5691 + err |= get_user(addis3, (unsigned int*)(addr+24));
5692 + err |= get_user(bctr, (unsigned int*)(addr+28));
5697 + if (rlwinm == 0x556C083CU &&
5698 + add == 0x7D6C5A14U &&
5699 + (li2 & 0xFFFF0000U) == 0x39800000U &&
5700 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
5701 + mtctr == 0x7D8903A6U &&
5702 + (li3 & 0xFFFF0000U) == 0x39800000U &&
5703 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
5704 + bctr == 0x4E800420U)
5706 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5707 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5708 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
5709 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5710 + regs->ctr += (addis2 & 0xFFFFU) << 16;
5711 + regs->nip = regs->ctr;
5718 + do { /* PaX: unpatched PLT emulation #2 */
5719 + unsigned int lis, lwzu, b, bctr;
5721 + err = get_user(lis, (unsigned int *)regs->nip);
5722 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
5723 + err |= get_user(b, (unsigned int *)(regs->nip+8));
5724 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
5729 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
5730 + (lwzu & 0xU) == 0xU &&
5731 + (b & 0xFC000003U) == 0x48000000U &&
5732 + bctr == 0x4E800420U)
5734 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
5735 + unsigned long addr = b | 0xFC000000UL;
5737 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
5738 + err = get_user(addis, (unsigned int*)addr);
5739 + err |= get_user(addi, (unsigned int*)(addr+4));
5740 + err |= get_user(rlwinm, (unsigned int*)(addr+8));
5741 + err |= get_user(add, (unsigned int*)(addr+12));
5742 + err |= get_user(li2, (unsigned int*)(addr+16));
5743 + err |= get_user(addis2, (unsigned int*)(addr+20));
5744 + err |= get_user(mtctr, (unsigned int*)(addr+24));
5745 + err |= get_user(li3, (unsigned int*)(addr+28));
5746 + err |= get_user(addis3, (unsigned int*)(addr+32));
5747 + err |= get_user(bctr, (unsigned int*)(addr+36));
5752 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
5753 + (addi & 0xFFFF0000U) == 0x396B0000U &&
5754 + rlwinm == 0x556C083CU &&
5755 + add == 0x7D6C5A14U &&
5756 + (li2 & 0xFFFF0000U) == 0x39800000U &&
5757 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
5758 + mtctr == 0x7D8903A6U &&
5759 + (li3 & 0xFFFF0000U) == 0x39800000U &&
5760 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
5761 + bctr == 0x4E800420U)
5763 + regs->gpr[PT_R11] =
5764 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5765 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5766 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
5767 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5768 + regs->ctr += (addis2 & 0xFFFFU) << 16;
5769 + regs->nip = regs->ctr;
5776 + do { /* PaX: unpatched PLT emulation #3 */
5777 + unsigned int li, b;
5779 + err = get_user(li, (unsigned int *)regs->nip);
5780 + err |= get_user(b, (unsigned int *)(regs->nip+4));
5782 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
5783 + unsigned int addis, lwz, mtctr, bctr;
5784 + unsigned long addr = b | 0xFC000000UL;
5786 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
5787 + err = get_user(addis, (unsigned int*)addr);
5788 + err |= get_user(lwz, (unsigned int*)(addr+4));
5789 + err |= get_user(mtctr, (unsigned int*)(addr+8));
5790 + err |= get_user(bctr, (unsigned int*)(addr+12));
5795 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
5796 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
5797 + mtctr == 0x7D6903A6U &&
5798 + bctr == 0x4E800420U)
5802 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5803 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5805 + err = get_user(r11, (unsigned int*)addr);
5809 + regs->gpr[PT_R11] = r11;
5818 +#ifdef CONFIG_PAX_EMUSIGRT
5819 + do { /* PaX: sigreturn emulation */
5820 + unsigned int li, sc;
5822 + err = get_user(li, (unsigned int *)regs->nip);
5823 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
5825 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
5826 + struct vm_area_struct *vma;
5827 + unsigned long call_syscall;
5829 + down_read(¤t->mm->mmap_sem);
5830 + call_syscall = current->mm->call_syscall;
5831 + up_read(¤t->mm->mmap_sem);
5832 + if (likely(call_syscall))
5835 + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5837 + down_write(¤t->mm->mmap_sem);
5838 + if (current->mm->call_syscall) {
5839 + call_syscall = current->mm->call_syscall;
5840 + up_write(¤t->mm->mmap_sem);
5841 + if (vma) kmem_cache_free(vm_area_cachep, vma);
5845 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5846 + if (!vma || (call_syscall & ~PAGE_MASK)) {
5847 + up_write(¤t->mm->mmap_sem);
5848 + if (vma) kmem_cache_free(vm_area_cachep, vma);
5852 + if (pax_insert_vma(vma, call_syscall)) {
5853 + up_write(¤t->mm->mmap_sem);
5854 + kmem_cache_free(vm_area_cachep, vma);
5858 + current->mm->call_syscall = call_syscall;
5859 + up_write(¤t->mm->mmap_sem);
5862 + regs->gpr[PT_R0] = __NR_sigreturn;
5863 + regs->nip = call_syscall;
5868 + do { /* PaX: rt_sigreturn emulation */
5869 + unsigned int li, sc;
5871 + err = get_user(li, (unsigned int *)regs->nip);
5872 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
5874 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
5875 + struct vm_area_struct *vma;
5876 + unsigned int call_syscall;
5878 + down_read(¤t->mm->mmap_sem);
5879 + call_syscall = current->mm->call_syscall;
5880 + up_read(¤t->mm->mmap_sem);
5881 + if (likely(call_syscall))
5884 + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5886 + down_write(¤t->mm->mmap_sem);
5887 + if (current->mm->call_syscall) {
5888 + call_syscall = current->mm->call_syscall;
5889 + up_write(¤t->mm->mmap_sem);
5890 + if (vma) kmem_cache_free(vm_area_cachep, vma);
5894 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5895 + if (!vma || (call_syscall & ~PAGE_MASK)) {
5896 + up_write(¤t->mm->mmap_sem);
5897 + if (vma) kmem_cache_free(vm_area_cachep, vma);
5901 + if (pax_insert_vma(vma, call_syscall)) {
5902 + up_write(¤t->mm->mmap_sem);
5903 + kmem_cache_free(vm_area_cachep, vma);
5907 + current->mm->call_syscall = call_syscall;
5908 + up_write(¤t->mm->mmap_sem);
5911 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
5912 + regs->nip = call_syscall;
5921 +void pax_report_insns(void *pc, void *sp)
5925 + printk(KERN_ERR "PAX: bytes at PC: ");
5926 + for (i = 0; i < 5; i++) {
5928 + if (get_user(c, (unsigned int*)pc+i))
5929 + printk("???????? ");
5931 + printk("%08x ", c);
5938 * Check whether the instruction at regs->nip is a store using
5939 * an update addressing form which will update r1.
5940 @@ -109,7 +472,7 @@ int do_page_fault(struct pt_regs *regs,
5941 * indicate errors in DSISR but can validly be set in SRR1.
5943 if (TRAP(regs) == 0x400)
5944 - error_code &= 0x48200000;
5945 + error_code &= 0x58200000;
5947 is_write = error_code & 0x02000000;
5948 #endif /* CONFIG_4xx || CONFIG_BOOKE */
5949 @@ -204,15 +567,14 @@ good_area:
5955 /* It would be nice to actually enforce the VM execute
5956 permission on CPUs which can do so, but far too
5957 much stuff in userspace doesn't get the permissions
5958 right, so we let any page be executed for now. */
5959 if (! (vma->vm_flags & VM_EXEC))
5964 /* Since 4xx/Book-E supports per-page execute permission,
5965 * we lazily flush dcache to icache. */
5967 @@ -235,6 +597,7 @@ good_area:
5968 pte_unmap_unlock(ptep, ptl);
5974 /* protection fault */
5975 @@ -280,6 +643,33 @@ bad_area:
5977 /* User mode accesses cause a SIGSEGV */
5978 if (user_mode(regs)) {
5980 +#ifdef CONFIG_PAX_PAGEEXEC
5981 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
5982 + if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
5983 + switch (pax_handle_fetch_fault(regs)) {
5985 +#ifdef CONFIG_PAX_EMUPLT
5992 +#ifdef CONFIG_PAX_EMUSIGRT
6000 + pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
6006 _exception(SIGSEGV, regs, code, address);
6009 diff -urNp linux-2.6.17.7/arch/s390/kernel/module.c linux-2.6.17.7/arch/s390/kernel/module.c
6010 --- linux-2.6.17.7/arch/s390/kernel/module.c 2006-07-24 23:36:01.000000000 -0400
6011 +++ linux-2.6.17.7/arch/s390/kernel/module.c 2006-08-01 20:29:46.000000000 -0400
6012 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
6014 /* Increase core size by size of got & plt and set start
6015 offsets for got and plt. */
6016 - me->core_size = ALIGN(me->core_size, 4);
6017 - me->arch.got_offset = me->core_size;
6018 - me->core_size += me->arch.got_size;
6019 - me->arch.plt_offset = me->core_size;
6020 - me->core_size += me->arch.plt_size;
6021 + me->core_size_rw = ALIGN(me->core_size_rw, 4);
6022 + me->arch.got_offset = me->core_size_rw;
6023 + me->core_size_rw += me->arch.got_size;
6024 + me->arch.plt_offset = me->core_size_rx;
6025 + me->core_size_rx += me->arch.plt_size;
6029 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6030 if (info->got_initialized == 0) {
6033 - gotent = me->module_core + me->arch.got_offset +
6034 + gotent = me->module_core_rw + me->arch.got_offset +
6037 info->got_initialized = 1;
6038 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6039 else if (r_type == R_390_GOTENT ||
6040 r_type == R_390_GOTPLTENT)
6041 *(unsigned int *) loc =
6042 - (val + (Elf_Addr) me->module_core - loc) >> 1;
6043 + (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
6044 else if (r_type == R_390_GOT64 ||
6045 r_type == R_390_GOTPLT64)
6046 *(unsigned long *) loc = val;
6047 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6048 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
6049 if (info->plt_initialized == 0) {
6051 - ip = me->module_core + me->arch.plt_offset +
6052 + ip = me->module_core_rx + me->arch.plt_offset +
6054 #ifndef CONFIG_64BIT
6055 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
6056 @@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6057 val = me->arch.plt_offset - me->arch.got_offset +
6058 info->plt_offset + rela->r_addend;
6060 - val = (Elf_Addr) me->module_core +
6061 + val = (Elf_Addr) me->module_core_rx +
6062 me->arch.plt_offset + info->plt_offset +
6063 rela->r_addend - loc;
6064 if (r_type == R_390_PLT16DBL)
6065 @@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6066 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
6067 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
6068 val = val + rela->r_addend -
6069 - ((Elf_Addr) me->module_core + me->arch.got_offset);
6070 + ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
6071 if (r_type == R_390_GOTOFF16)
6072 *(unsigned short *) loc = val;
6073 else if (r_type == R_390_GOTOFF32)
6074 @@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6076 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
6077 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
6078 - val = (Elf_Addr) me->module_core + me->arch.got_offset +
6079 + val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
6080 rela->r_addend - loc;
6081 if (r_type == R_390_GOTPC)
6082 *(unsigned int *) loc = val;
6083 diff -urNp linux-2.6.17.7/arch/sparc/Makefile linux-2.6.17.7/arch/sparc/Makefile
6084 --- linux-2.6.17.7/arch/sparc/Makefile 2006-07-24 23:36:01.000000000 -0400
6085 +++ linux-2.6.17.7/arch/sparc/Makefile 2006-08-01 20:29:46.000000000 -0400
6086 @@ -34,7 +34,7 @@ libs-y += arch/sparc/prom/ arch/sparc/li
6087 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
6088 INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
6090 -CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
6091 +CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
6092 CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
6093 DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
6094 NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
6095 diff -urNp linux-2.6.17.7/arch/sparc/kernel/ptrace.c linux-2.6.17.7/arch/sparc/kernel/ptrace.c
6096 --- linux-2.6.17.7/arch/sparc/kernel/ptrace.c 2006-07-24 23:36:01.000000000 -0400
6097 +++ linux-2.6.17.7/arch/sparc/kernel/ptrace.c 2006-08-01 20:29:46.000000000 -0400
6099 #include <linux/security.h>
6100 #include <linux/signal.h>
6101 #include <linux/vs_pid.h>
6102 +#include <linux/grsecurity.h>
6104 #include <asm/pgtable.h>
6105 #include <asm/system.h>
6106 @@ -300,6 +301,11 @@ asmlinkage void do_ptrace(struct pt_regs
6110 + if (gr_handle_ptrace(child, request)) {
6111 + pt_error_return(regs, EPERM);
6115 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
6116 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
6117 if (ptrace_attach(child)) {
6118 diff -urNp linux-2.6.17.7/arch/sparc/kernel/sys_sparc.c linux-2.6.17.7/arch/sparc/kernel/sys_sparc.c
6119 --- linux-2.6.17.7/arch/sparc/kernel/sys_sparc.c 2006-07-24 23:36:01.000000000 -0400
6120 +++ linux-2.6.17.7/arch/sparc/kernel/sys_sparc.c 2006-08-01 20:29:46.000000000 -0400
6121 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
6122 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
6125 - addr = TASK_UNMAPPED_BASE;
6126 + addr = current->mm->mmap_base;
6128 if (flags & MAP_SHARED)
6129 addr = COLOUR_ALIGN(addr);
6130 diff -urNp linux-2.6.17.7/arch/sparc/mm/fault.c linux-2.6.17.7/arch/sparc/mm/fault.c
6131 --- linux-2.6.17.7/arch/sparc/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
6132 +++ linux-2.6.17.7/arch/sparc/mm/fault.c 2006-08-01 20:29:46.000000000 -0400
6134 #include <linux/smp_lock.h>
6135 #include <linux/interrupt.h>
6136 #include <linux/module.h>
6137 +#include <linux/slab.h>
6138 +#include <linux/pagemap.h>
6139 +#include <linux/compiler.h>
6140 +#include <linux/binfmts.h>
6142 #include <asm/system.h>
6143 #include <asm/page.h>
6144 @@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
6145 return safe_compute_effective_address(regs, insn);
6148 +#ifdef CONFIG_PAX_PAGEEXEC
6149 +void pax_emuplt_close(struct vm_area_struct * vma)
6151 + vma->vm_mm->call_dl_resolve = 0UL;
6154 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6156 + struct page* page;
6157 + unsigned int *kaddr;
6159 + page = alloc_page(GFP_HIGHUSER);
6161 + return NOPAGE_OOM;
6163 + kaddr = kmap(page);
6164 + memset(kaddr, 0, PAGE_SIZE);
6165 + kaddr[0] = 0x9DE3BFA8U; /* save */
6166 + flush_dcache_page(page);
6169 + *type = VM_FAULT_MAJOR;
6174 +static struct vm_operations_struct pax_vm_ops = {
6175 + .close = pax_emuplt_close,
6176 + .nopage = pax_emuplt_nopage,
6179 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6183 + memset(vma, 0, sizeof(*vma));
6184 + vma->vm_mm = current->mm;
6185 + vma->vm_start = addr;
6186 + vma->vm_end = addr + PAGE_SIZE;
6187 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6188 + vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
6189 + vma->vm_ops = &pax_vm_ops;
6191 + ret = insert_vm_struct(current->mm, vma);
6195 + ++current->mm->total_vm;
6200 + * PaX: decide what to do with offenders (regs->pc = fault address)
6202 + * returns 1 when task should be killed
6203 + * 2 when patched PLT trampoline was detected
6204 + * 3 when unpatched PLT trampoline was detected
6206 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6209 +#ifdef CONFIG_PAX_EMUPLT
6212 + do { /* PaX: patched PLT emulation #1 */
6213 + unsigned int sethi1, sethi2, jmpl;
6215 + err = get_user(sethi1, (unsigned int*)regs->pc);
6216 + err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
6217 + err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
6222 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6223 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
6224 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
6226 + unsigned int addr;
6228 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
6229 + addr = regs->u_regs[UREG_G1];
6230 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
6232 + regs->npc = addr+4;
6237 + { /* PaX: patched PLT emulation #2 */
6240 + err = get_user(ba, (unsigned int*)regs->pc);
6242 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
6243 + unsigned int addr;
6245 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
6247 + regs->npc = addr+4;
6252 + do { /* PaX: patched PLT emulation #3 */
6253 + unsigned int sethi, jmpl, nop;
6255 + err = get_user(sethi, (unsigned int*)regs->pc);
6256 + err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
6257 + err |= get_user(nop, (unsigned int*)(regs->pc+8));
6262 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
6263 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
6264 + nop == 0x01000000U)
6266 + unsigned int addr;
6268 + addr = (sethi & 0x003FFFFFU) << 10;
6269 + regs->u_regs[UREG_G1] = addr;
6270 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
6272 + regs->npc = addr+4;
6277 + do { /* PaX: unpatched PLT emulation step 1 */
6278 + unsigned int sethi, ba, nop;
6280 + err = get_user(sethi, (unsigned int*)regs->pc);
6281 + err |= get_user(ba, (unsigned int*)(regs->pc+4));
6282 + err |= get_user(nop, (unsigned int*)(regs->pc+8));
6287 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
6288 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
6289 + nop == 0x01000000U)
6291 + unsigned int addr, save, call;
6293 + if ((ba & 0xFFC00000U) == 0x30800000U)
6294 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
6296 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
6298 + err = get_user(save, (unsigned int*)addr);
6299 + err |= get_user(call, (unsigned int*)(addr+4));
6300 + err |= get_user(nop, (unsigned int*)(addr+8));
6304 + if (save == 0x9DE3BFA8U &&
6305 + (call & 0xC0000000U) == 0x40000000U &&
6306 + nop == 0x01000000U)
6308 + struct vm_area_struct *vma;
6309 + unsigned long call_dl_resolve;
6311 + down_read(¤t->mm->mmap_sem);
6312 + call_dl_resolve = current->mm->call_dl_resolve;
6313 + up_read(¤t->mm->mmap_sem);
6314 + if (likely(call_dl_resolve))
6317 + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6319 + down_write(¤t->mm->mmap_sem);
6320 + if (current->mm->call_dl_resolve) {
6321 + call_dl_resolve = current->mm->call_dl_resolve;
6322 + up_write(¤t->mm->mmap_sem);
6323 + if (vma) kmem_cache_free(vm_area_cachep, vma);
6327 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6328 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
6329 + up_write(¤t->mm->mmap_sem);
6330 + if (vma) kmem_cache_free(vm_area_cachep, vma);
6334 + if (pax_insert_vma(vma, call_dl_resolve)) {
6335 + up_write(¤t->mm->mmap_sem);
6336 + kmem_cache_free(vm_area_cachep, vma);
6340 + current->mm->call_dl_resolve = call_dl_resolve;
6341 + up_write(¤t->mm->mmap_sem);
6344 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
6345 + regs->pc = call_dl_resolve;
6346 + regs->npc = addr+4;
6352 + do { /* PaX: unpatched PLT emulation step 2 */
6353 + unsigned int save, call, nop;
6355 + err = get_user(save, (unsigned int*)(regs->pc-4));
6356 + err |= get_user(call, (unsigned int*)regs->pc);
6357 + err |= get_user(nop, (unsigned int*)(regs->pc+4));
6361 + if (save == 0x9DE3BFA8U &&
6362 + (call & 0xC0000000U) == 0x40000000U &&
6363 + nop == 0x01000000U)
6365 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
6367 + regs->u_regs[UREG_RETPC] = regs->pc;
6368 + regs->pc = dl_resolve;
6369 + regs->npc = dl_resolve+4;
6378 +void pax_report_insns(void *pc, void *sp)
6382 + printk(KERN_ERR "PAX: bytes at PC: ");
6383 + for (i = 0; i < 5; i++) {
6385 + if (get_user(c, (unsigned int*)pc+i))
6386 + printk("???????? ");
6388 + printk("%08x ", c);
6394 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
6395 unsigned long address)
6397 @@ -280,6 +530,24 @@ good_area:
6398 if(!(vma->vm_flags & VM_WRITE))
6402 +#ifdef CONFIG_PAX_PAGEEXEC
6403 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
6404 + up_read(&mm->mmap_sem);
6405 + switch (pax_handle_fetch_fault(regs)) {
6407 +#ifdef CONFIG_PAX_EMUPLT
6414 + pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
6419 /* Allow reads even for write-only mappings */
6420 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
6422 diff -urNp linux-2.6.17.7/arch/sparc/mm/init.c linux-2.6.17.7/arch/sparc/mm/init.c
6423 --- linux-2.6.17.7/arch/sparc/mm/init.c 2006-07-24 23:36:01.000000000 -0400
6424 +++ linux-2.6.17.7/arch/sparc/mm/init.c 2006-08-01 20:29:46.000000000 -0400
6425 @@ -333,17 +333,17 @@ void __init paging_init(void)
6427 /* Initialize the protection map with non-constant, MMU dependent values. */
6428 protection_map[0] = PAGE_NONE;
6429 - protection_map[1] = PAGE_READONLY;
6430 - protection_map[2] = PAGE_COPY;
6431 - protection_map[3] = PAGE_COPY;
6432 + protection_map[1] = PAGE_READONLY_NOEXEC;
6433 + protection_map[2] = PAGE_COPY_NOEXEC;
6434 + protection_map[3] = PAGE_COPY_NOEXEC;
6435 protection_map[4] = PAGE_READONLY;
6436 protection_map[5] = PAGE_READONLY;
6437 protection_map[6] = PAGE_COPY;
6438 protection_map[7] = PAGE_COPY;
6439 protection_map[8] = PAGE_NONE;
6440 - protection_map[9] = PAGE_READONLY;
6441 - protection_map[10] = PAGE_SHARED;
6442 - protection_map[11] = PAGE_SHARED;
6443 + protection_map[9] = PAGE_READONLY_NOEXEC;
6444 + protection_map[10] = PAGE_SHARED_NOEXEC;
6445 + protection_map[11] = PAGE_SHARED_NOEXEC;
6446 protection_map[12] = PAGE_READONLY;
6447 protection_map[13] = PAGE_READONLY;
6448 protection_map[14] = PAGE_SHARED;
6449 diff -urNp linux-2.6.17.7/arch/sparc/mm/srmmu.c linux-2.6.17.7/arch/sparc/mm/srmmu.c
6450 --- linux-2.6.17.7/arch/sparc/mm/srmmu.c 2006-07-24 23:36:01.000000000 -0400
6451 +++ linux-2.6.17.7/arch/sparc/mm/srmmu.c 2006-08-01 20:29:46.000000000 -0400
6452 @@ -2161,6 +2161,13 @@ void __init ld_mmu_srmmu(void)
6453 BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
6454 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
6455 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
6457 +#ifdef CONFIG_PAX_PAGEEXEC
6458 + BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
6459 + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
6460 + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
6463 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
6464 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
6466 diff -urNp linux-2.6.17.7/arch/sparc64/kernel/ptrace.c linux-2.6.17.7/arch/sparc64/kernel/ptrace.c
6467 --- linux-2.6.17.7/arch/sparc64/kernel/ptrace.c 2006-07-24 23:36:01.000000000 -0400
6468 +++ linux-2.6.17.7/arch/sparc64/kernel/ptrace.c 2006-08-01 20:29:46.000000000 -0400
6470 #include <linux/audit.h>
6471 #include <linux/signal.h>
6472 #include <linux/vs_pid.h>
6473 +#include <linux/grsecurity.h>
6475 #include <asm/asi.h>
6476 #include <asm/pgtable.h>
6477 @@ -213,6 +214,11 @@ asmlinkage void do_ptrace(struct pt_regs
6481 + if (gr_handle_ptrace(child, (long)request)) {
6482 + pt_error_return(regs, EPERM);
6486 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
6487 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
6488 if (ptrace_attach(child)) {
6489 diff -urNp linux-2.6.17.7/arch/sparc64/kernel/sys_sparc.c linux-2.6.17.7/arch/sparc64/kernel/sys_sparc.c
6490 --- linux-2.6.17.7/arch/sparc64/kernel/sys_sparc.c 2006-07-24 23:36:01.000000000 -0400
6491 +++ linux-2.6.17.7/arch/sparc64/kernel/sys_sparc.c 2006-08-01 20:29:46.000000000 -0400
6492 @@ -140,6 +140,10 @@ unsigned long arch_get_unmapped_area(str
6493 if (filp || (flags & MAP_SHARED))
6496 +#ifdef CONFIG_PAX_RANDMMAP
6497 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6502 addr = COLOUR_ALIGN(addr, pgoff);
6503 @@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str
6506 if (len > mm->cached_hole_size) {
6507 - start_addr = addr = mm->free_area_cache;
6508 + start_addr = addr = mm->free_area_cache;
6510 - start_addr = addr = TASK_UNMAPPED_BASE;
6511 + start_addr = addr = mm->mmap_base;
6512 mm->cached_hole_size = 0;
6515 @@ -175,8 +179,8 @@ full_search:
6516 vma = find_vma(mm, VA_EXCLUDE_END);
6518 if (unlikely(task_size < addr)) {
6519 - if (start_addr != TASK_UNMAPPED_BASE) {
6520 - start_addr = addr = TASK_UNMAPPED_BASE;
6521 + if (start_addr != mm->mmap_base) {
6522 + start_addr = addr = mm->mmap_base;
6523 mm->cached_hole_size = 0;
6526 diff -urNp linux-2.6.17.7/arch/sparc64/mm/fault.c linux-2.6.17.7/arch/sparc64/mm/fault.c
6527 --- linux-2.6.17.7/arch/sparc64/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
6528 +++ linux-2.6.17.7/arch/sparc64/mm/fault.c 2006-08-01 20:29:46.000000000 -0400
6530 #include <linux/init.h>
6531 #include <linux/interrupt.h>
6532 #include <linux/kprobes.h>
6533 +#include <linux/slab.h>
6534 +#include <linux/pagemap.h>
6535 +#include <linux/compiler.h>
6536 +#include <linux/binfmts.h>
6538 #include <asm/page.h>
6539 #include <asm/pgtable.h>
6540 @@ -253,6 +257,369 @@ cannot_handle:
6541 unhandled_fault (address, current, regs);
6544 +#ifdef CONFIG_PAX_PAGEEXEC
6545 +#ifdef CONFIG_PAX_EMUPLT
6546 +static void pax_emuplt_close(struct vm_area_struct * vma)
6548 + vma->vm_mm->call_dl_resolve = 0UL;
6551 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6553 + struct page* page;
6554 + unsigned int *kaddr;
6556 + page = alloc_page(GFP_HIGHUSER);
6558 + return NOPAGE_OOM;
6560 + kaddr = kmap(page);
6561 + memset(kaddr, 0, PAGE_SIZE);
6562 + kaddr[0] = 0x9DE3BFA8U; /* save */
6563 + flush_dcache_page(page);
6566 + *type = VM_FAULT_MAJOR;
6570 +static struct vm_operations_struct pax_vm_ops = {
6571 + .close = pax_emuplt_close,
6572 + .nopage = pax_emuplt_nopage,
6575 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6579 + memset(vma, 0, sizeof(*vma));
6580 + vma->vm_mm = current->mm;
6581 + vma->vm_start = addr;
6582 + vma->vm_end = addr + PAGE_SIZE;
6583 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6584 + vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
6585 + vma->vm_ops = &pax_vm_ops;
6587 + ret = insert_vm_struct(current->mm, vma);
6591 + ++current->mm->total_vm;
6597 + * PaX: decide what to do with offenders (regs->tpc = fault address)
6599 + * returns 1 when task should be killed
6600 + * 2 when patched PLT trampoline was detected
6601 + * 3 when unpatched PLT trampoline was detected
6603 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6606 +#ifdef CONFIG_PAX_EMUPLT
6609 + do { /* PaX: patched PLT emulation #1 */
6610 + unsigned int sethi1, sethi2, jmpl;
6612 + err = get_user(sethi1, (unsigned int*)regs->tpc);
6613 + err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
6614 + err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
6619 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6620 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
6621 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
6623 + unsigned long addr;
6625 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
6626 + addr = regs->u_regs[UREG_G1];
6627 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
6629 + regs->tnpc = addr+4;
6634 + { /* PaX: patched PLT emulation #2 */
6637 + err = get_user(ba, (unsigned int*)regs->tpc);
6639 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
6640 + unsigned long addr;
6642 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
6644 + regs->tnpc = addr+4;
6649 + do { /* PaX: patched PLT emulation #3 */
6650 + unsigned int sethi, jmpl, nop;
6652 + err = get_user(sethi, (unsigned int*)regs->tpc);
6653 + err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
6654 + err |= get_user(nop, (unsigned int*)(regs->tpc+8));
6659 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
6660 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
6661 + nop == 0x01000000U)
6663 + unsigned long addr;
6665 + addr = (sethi & 0x003FFFFFU) << 10;
6666 + regs->u_regs[UREG_G1] = addr;
6667 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
6669 + regs->tnpc = addr+4;
6674 + do { /* PaX: patched PLT emulation #4 */
6675 + unsigned int mov1, call, mov2;
6677 + err = get_user(mov1, (unsigned int*)regs->tpc);
6678 + err |= get_user(call, (unsigned int*)(regs->tpc+4));
6679 + err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
6684 + if (mov1 == 0x8210000FU &&
6685 + (call & 0xC0000000U) == 0x40000000U &&
6686 + mov2 == 0x9E100001U)
6688 + unsigned long addr;
6690 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
6691 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
6693 + regs->tnpc = addr+4;
6698 + do { /* PaX: patched PLT emulation #5 */
6699 + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
6701 + err = get_user(sethi1, (unsigned int*)regs->tpc);
6702 + err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
6703 + err |= get_user(or1, (unsigned int*)(regs->tpc+8));
6704 + err |= get_user(or2, (unsigned int*)(regs->tpc+12));
6705 + err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
6706 + err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
6707 + err |= get_user(nop, (unsigned int*)(regs->tpc+24));
6712 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6713 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
6714 + (or1 & 0xFFFFE000U) == 0x82106000U &&
6715 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
6716 + sllx == 0x83287020 &&
6717 + jmpl == 0x81C04005U &&
6718 + nop == 0x01000000U)
6720 + unsigned long addr;
6722 + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
6723 + regs->u_regs[UREG_G1] <<= 32;
6724 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
6725 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
6727 + regs->tnpc = addr+4;
6732 + do { /* PaX: patched PLT emulation #6 */
6733 + unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
6735 + err = get_user(sethi1, (unsigned int*)regs->tpc);
6736 + err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
6737 + err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
6738 + err |= get_user(or, (unsigned int*)(regs->tpc+12));
6739 + err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
6740 + err |= get_user(nop, (unsigned int*)(regs->tpc+20));
6745 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6746 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
6747 + sllx == 0x83287020 &&
6748 + (or & 0xFFFFE000U) == 0x8A116000U &&
6749 + jmpl == 0x81C04005U &&
6750 + nop == 0x01000000U)
6752 + unsigned long addr;
6754 + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
6755 + regs->u_regs[UREG_G1] <<= 32;
6756 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
6757 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
6759 + regs->tnpc = addr+4;
6764 + do { /* PaX: patched PLT emulation #7 */
6765 + unsigned int sethi, ba, nop;
6767 + err = get_user(sethi, (unsigned int*)regs->tpc);
6768 + err |= get_user(ba, (unsigned int*)(regs->tpc+4));
6769 + err |= get_user(nop, (unsigned int*)(regs->tpc+8));
6774 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
6775 + (ba & 0xFFF00000U) == 0x30600000U &&
6776 + nop == 0x01000000U)
6778 + unsigned long addr;
6780 + addr = (sethi & 0x003FFFFFU) << 10;
6781 + regs->u_regs[UREG_G1] = addr;
6782 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
6784 + regs->tnpc = addr+4;
6789 + do { /* PaX: unpatched PLT emulation step 1 */
6790 + unsigned int sethi, ba, nop;
6792 + err = get_user(sethi, (unsigned int*)regs->tpc);
6793 + err |= get_user(ba, (unsigned int*)(regs->tpc+4));
6794 + err |= get_user(nop, (unsigned int*)(regs->tpc+8));
6799 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
6800 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
6801 + nop == 0x01000000U)
6803 + unsigned long addr;
6804 + unsigned int save, call;
6806 + if ((ba & 0xFFC00000U) == 0x30800000U)
6807 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
6809 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
6811 + err = get_user(save, (unsigned int*)addr);
6812 + err |= get_user(call, (unsigned int*)(addr+4));
6813 + err |= get_user(nop, (unsigned int*)(addr+8));
6817 + if (save == 0x9DE3BFA8U &&
6818 + (call & 0xC0000000U) == 0x40000000U &&
6819 + nop == 0x01000000U)
6821 + struct vm_area_struct *vma;
6822 + unsigned long call_dl_resolve;
6824 + down_read(¤t->mm->mmap_sem);
6825 + call_dl_resolve = current->mm->call_dl_resolve;
6826 + up_read(¤t->mm->mmap_sem);
6827 + if (likely(call_dl_resolve))
6830 + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6832 + down_write(¤t->mm->mmap_sem);
6833 + if (current->mm->call_dl_resolve) {
6834 + call_dl_resolve = current->mm->call_dl_resolve;
6835 + up_write(¤t->mm->mmap_sem);
6836 + if (vma) kmem_cache_free(vm_area_cachep, vma);
6840 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6841 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
6842 + up_write(¤t->mm->mmap_sem);
6843 + if (vma) kmem_cache_free(vm_area_cachep, vma);
6847 + if (pax_insert_vma(vma, call_dl_resolve)) {
6848 + up_write(¤t->mm->mmap_sem);
6849 + kmem_cache_free(vm_area_cachep, vma);
6853 + current->mm->call_dl_resolve = call_dl_resolve;
6854 + up_write(¤t->mm->mmap_sem);
6857 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
6858 + regs->tpc = call_dl_resolve;
6859 + regs->tnpc = addr+4;
6865 + do { /* PaX: unpatched PLT emulation step 2 */
6866 + unsigned int save, call, nop;
6868 + err = get_user(save, (unsigned int*)(regs->tpc-4));
6869 + err |= get_user(call, (unsigned int*)regs->tpc);
6870 + err |= get_user(nop, (unsigned int*)(regs->tpc+4));
6874 + if (save == 0x9DE3BFA8U &&
6875 + (call & 0xC0000000U) == 0x40000000U &&
6876 + nop == 0x01000000U)
6878 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
6880 + regs->u_regs[UREG_RETPC] = regs->tpc;
6881 + regs->tpc = dl_resolve;
6882 + regs->tnpc = dl_resolve+4;
6891 +void pax_report_insns(void *pc, void *sp)
6895 + printk(KERN_ERR "PAX: bytes at PC: ");
6896 + for (i = 0; i < 5; i++) {
6898 + if (get_user(c, (unsigned int*)pc+i))
6899 + printk("???????? ");
6901 + printk("%08x ", c);
6907 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
6909 struct mm_struct *mm = current->mm;
6910 @@ -295,8 +662,10 @@ asmlinkage void __kprobes do_sparc64_fau
6913 if (test_thread_flag(TIF_32BIT)) {
6914 - if (!(regs->tstate & TSTATE_PRIV))
6915 + if (!(regs->tstate & TSTATE_PRIV)) {
6916 regs->tpc &= 0xffffffff;
6917 + regs->tnpc &= 0xffffffff;
6919 address &= 0xffffffff;
6922 @@ -313,6 +682,29 @@ asmlinkage void __kprobes do_sparc64_fau
6926 +#ifdef CONFIG_PAX_PAGEEXEC
6927 + /* PaX: detect ITLB misses on non-exec pages */
6928 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
6929 + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
6931 + if (address != regs->tpc)
6934 + up_read(&mm->mmap_sem);
6935 + switch (pax_handle_fetch_fault(regs)) {
6937 +#ifdef CONFIG_PAX_EMUPLT
6944 + pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
6949 /* Pure DTLB misses do not tell us whether the fault causing
6950 * load/store/atomic was a write or not, it only says that there
6951 * was no match. So in such a case we (carefully) read the
6952 diff -urNp linux-2.6.17.7/arch/v850/kernel/module.c linux-2.6.17.7/arch/v850/kernel/module.c
6953 --- linux-2.6.17.7/arch/v850/kernel/module.c 2006-07-24 23:36:01.000000000 -0400
6954 +++ linux-2.6.17.7/arch/v850/kernel/module.c 2006-08-01 20:29:46.000000000 -0400
6955 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
6956 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
6958 /* Init, or core PLT? */
6959 - if (location >= mod->module_core
6960 - && location < mod->module_core + mod->core_size)
6961 + if (location >= mod->module_core_rx
6962 + && location < mod->module_core_rx + mod->core_size_rx)
6963 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
6965 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
6966 diff -urNp linux-2.6.17.7/arch/x86_64/boot/compressed/head.S linux-2.6.17.7/arch/x86_64/boot/compressed/head.S
6967 --- linux-2.6.17.7/arch/x86_64/boot/compressed/head.S 2006-07-24 23:36:01.000000000 -0400
6968 +++ linux-2.6.17.7/arch/x86_64/boot/compressed/head.S 2006-08-01 20:29:46.000000000 -0400
6969 @@ -41,11 +41,13 @@ startup_32:
6972 lss stack_start,%esp
6973 + movl 0x000000,%ecx
6975 1: incl %eax # check that A20 really IS enabled
6976 movl %eax,0x000000 # loop forever if it isn't
6979 + movl %ecx,0x000000
6982 * Initialize eflags. Some BIOS's leave bits like NT set. This would
6983 diff -urNp linux-2.6.17.7/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.17.7/arch/x86_64/ia32/ia32_binfmt.c
6984 --- linux-2.6.17.7/arch/x86_64/ia32/ia32_binfmt.c 2006-07-24 23:36:01.000000000 -0400
6985 +++ linux-2.6.17.7/arch/x86_64/ia32/ia32_binfmt.c 2006-08-01 20:29:46.000000000 -0400
6986 @@ -186,6 +186,17 @@ struct elf_prpsinfo
6987 //#include <asm/ia32.h>
6988 #include <linux/elf.h>
6990 +#ifdef CONFIG_PAX_ASLR
6991 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x08048000UL
6993 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
6994 +#define PAX_DELTA_MMAP_LEN(tsk) 16
6995 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
6996 +#define PAX_DELTA_EXEC_LEN(tsk) 16
6997 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
6998 +#define PAX_DELTA_STACK_LEN(tsk) 16
7001 typedef struct user_i387_ia32_struct elf_fpregset_t;
7002 typedef struct user32_fxsr_struct elf_fpxregset_t;
7004 diff -urNp linux-2.6.17.7/arch/x86_64/ia32/mmap32.c linux-2.6.17.7/arch/x86_64/ia32/mmap32.c
7005 --- linux-2.6.17.7/arch/x86_64/ia32/mmap32.c 2006-07-24 23:36:01.000000000 -0400
7006 +++ linux-2.6.17.7/arch/x86_64/ia32/mmap32.c 2006-08-01 20:29:46.000000000 -0400
7007 @@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
7008 (current->personality & ADDR_COMPAT_LAYOUT) ||
7009 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
7010 mm->mmap_base = TASK_UNMAPPED_BASE;
7012 +#ifdef CONFIG_PAX_RANDMMAP
7013 + if (mm->pax_flags & MF_PAX_RANDMMAP)
7014 + mm->mmap_base += mm->delta_mmap;
7017 mm->get_unmapped_area = arch_get_unmapped_area;
7018 mm->unmap_area = arch_unmap_area;
7020 mm->mmap_base = mmap_base(mm);
7022 +#ifdef CONFIG_PAX_RANDMMAP
7023 + if (mm->pax_flags & MF_PAX_RANDMMAP)
7024 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7027 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7028 mm->unmap_area = arch_unmap_area_topdown;
7030 diff -urNp linux-2.6.17.7/arch/x86_64/kernel/process.c linux-2.6.17.7/arch/x86_64/kernel/process.c
7031 --- linux-2.6.17.7/arch/x86_64/kernel/process.c 2006-07-24 23:36:01.000000000 -0400
7032 +++ linux-2.6.17.7/arch/x86_64/kernel/process.c 2006-08-01 20:29:46.000000000 -0400
7033 @@ -830,9 +830,3 @@ int dump_task_regs(struct task_struct *t
7037 -unsigned long arch_align_stack(unsigned long sp)
7039 - if (randomize_va_space)
7040 - sp -= get_random_int() % 8192;
7043 diff -urNp linux-2.6.17.7/arch/x86_64/kernel/ptrace.c linux-2.6.17.7/arch/x86_64/kernel/ptrace.c
7044 --- linux-2.6.17.7/arch/x86_64/kernel/ptrace.c 2006-07-24 23:36:01.000000000 -0400
7045 +++ linux-2.6.17.7/arch/x86_64/kernel/ptrace.c 2006-08-01 20:29:46.000000000 -0400
7047 #include <linux/audit.h>
7048 #include <linux/seccomp.h>
7049 #include <linux/signal.h>
7050 +#include <linux/grsecurity.h>
7052 #include <asm/uaccess.h>
7053 #include <asm/pgtable.h>
7054 diff -urNp linux-2.6.17.7/arch/x86_64/kernel/setup64.c linux-2.6.17.7/arch/x86_64/kernel/setup64.c
7055 --- linux-2.6.17.7/arch/x86_64/kernel/setup64.c 2006-07-24 23:36:01.000000000 -0400
7056 +++ linux-2.6.17.7/arch/x86_64/kernel/setup64.c 2006-08-01 20:29:46.000000000 -0400
7057 @@ -38,7 +38,6 @@ struct desc_ptr idt_descr = { 256 * 16 -
7058 char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
7060 unsigned long __supported_pte_mask __read_mostly = ~0UL;
7061 -static int do_not_nx __cpuinitdata = 0;
7064 Control non executable mappings for 64bit processes.
7065 @@ -50,16 +49,14 @@ int __init nonx_setup(char *str)
7067 if (!strncmp(str, "on", 2)) {
7068 __supported_pte_mask |= _PAGE_NX;
7070 } else if (!strncmp(str, "off", 3)) {
7072 __supported_pte_mask &= ~_PAGE_NX;
7076 __setup("noexec=", nonx_setup); /* parsed early actually */
7078 -int force_personality32 = 0;
7079 +int force_personality32;
7082 Control non executable heap for 32bit processes.
7083 @@ -173,7 +170,7 @@ void __cpuinit check_efer(void)
7086 rdmsrl(MSR_EFER, efer);
7087 - if (!(efer & EFER_NX) || do_not_nx) {
7088 + if (!(efer & EFER_NX)) {
7089 __supported_pte_mask &= ~_PAGE_NX;
7092 diff -urNp linux-2.6.17.7/arch/x86_64/kernel/sys_x86_64.c linux-2.6.17.7/arch/x86_64/kernel/sys_x86_64.c
7093 --- linux-2.6.17.7/arch/x86_64/kernel/sys_x86_64.c 2006-07-24 23:36:01.000000000 -0400
7094 +++ linux-2.6.17.7/arch/x86_64/kernel/sys_x86_64.c 2006-08-01 20:29:46.000000000 -0400
7095 @@ -65,8 +65,8 @@ out:
7099 -static void find_start_end(unsigned long flags, unsigned long *begin,
7100 - unsigned long *end)
7101 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
7102 + unsigned long *begin, unsigned long *end)
7104 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
7105 /* This is usually used needed to map code in small
7106 @@ -79,7 +79,7 @@ static void find_start_end(unsigned long
7107 *begin = 0x40000000;
7110 - *begin = TASK_UNMAPPED_BASE;
7111 + *begin = mm->mmap_base;
7115 @@ -93,11 +93,15 @@ arch_get_unmapped_area(struct file *filp
7116 unsigned long start_addr;
7117 unsigned long begin, end;
7119 - find_start_end(flags, &begin, &end);
7120 + find_start_end(mm, flags, &begin, &end);
7125 +#ifdef CONFIG_PAX_RANDMMAP
7126 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7130 addr = PAGE_ALIGN(addr);
7131 vma = find_vma(mm, addr);
7132 diff -urNp linux-2.6.17.7/arch/x86_64/mm/fault.c linux-2.6.17.7/arch/x86_64/mm/fault.c
7133 --- linux-2.6.17.7/arch/x86_64/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
7134 +++ linux-2.6.17.7/arch/x86_64/mm/fault.c 2006-08-01 20:29:46.000000000 -0400
7136 #include <linux/compiler.h>
7137 #include <linux/module.h>
7138 #include <linux/kprobes.h>
7139 +#include <linux/binfmts.h>
7141 #include <asm/system.h>
7142 #include <asm/uaccess.h>
7143 @@ -294,6 +295,33 @@ static int vmalloc_fault(unsigned long a
7147 +#ifdef CONFIG_PAX_PAGEEXEC
7148 +void pax_report_insns(void *pc, void *sp)
7152 + printk(KERN_ERR "PAX: bytes at PC: ");
7153 + for (i = 0; i < 20; i++) {
7155 + if (get_user(c, (unsigned char __user *)pc+i))
7158 + printk("%02x ", c);
7162 + printk(KERN_ERR "PAX: bytes at SP-8: ");
7163 + for (i = -1; i < 10; i++) {
7165 + if (get_user(c, (unsigned long __user *)sp+i))
7166 + printk("???????????????? ");
7168 + printk("%016lx ", c);
7174 int page_fault_trace = 0;
7175 int exception_trace = 1;
7177 @@ -423,6 +451,8 @@ asmlinkage void __kprobes do_page_fault(
7179 info.si_code = SEGV_ACCERR;
7181 + if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
7183 switch (error_code & (PF_PROT|PF_WRITE)) {
7184 default: /* 3: write, present */
7186 @@ -489,7 +519,14 @@ bad_area_nosemaphore:
7187 tsk->comm, tsk->pid, address, regs->rip,
7188 regs->rsp, error_code);
7192 +#ifdef CONFIG_PAX_PAGEEXEC
7193 + if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
7194 + pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
7199 tsk->thread.cr2 = address;
7200 /* Kernel addresses are always protection faults */
7201 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
7202 diff -urNp linux-2.6.17.7/arch/x86_64/mm/mmap.c linux-2.6.17.7/arch/x86_64/mm/mmap.c
7203 --- linux-2.6.17.7/arch/x86_64/mm/mmap.c 2006-07-24 23:36:01.000000000 -0400
7204 +++ linux-2.6.17.7/arch/x86_64/mm/mmap.c 2006-08-01 20:29:46.000000000 -0400
7205 @@ -24,6 +24,12 @@ void arch_pick_mmap_layout(struct mm_str
7206 unsigned rnd = get_random_int() & 0xfffffff;
7207 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
7210 +#ifdef CONFIG_PAX_RANDMMAP
7211 + if (mm->pax_flags & MF_PAX_RANDMMAP)
7212 + mm->mmap_base += mm->delta_mmap;
7215 mm->get_unmapped_area = arch_get_unmapped_area;
7216 mm->unmap_area = arch_unmap_area;
7218 diff -urNp linux-2.6.17.7/drivers/char/agp/frontend.c linux-2.6.17.7/drivers/char/agp/frontend.c
7219 --- linux-2.6.17.7/drivers/char/agp/frontend.c 2006-07-24 23:36:01.000000000 -0400
7220 +++ linux-2.6.17.7/drivers/char/agp/frontend.c 2006-08-01 20:29:46.000000000 -0400
7221 @@ -841,7 +841,7 @@ static int agpioc_reserve_wrap(struct ag
7222 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
7225 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
7226 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
7229 client = agp_find_client_by_pid(reserve.pid);
7230 diff -urNp linux-2.6.17.7/drivers/char/keyboard.c linux-2.6.17.7/drivers/char/keyboard.c
7231 --- linux-2.6.17.7/drivers/char/keyboard.c 2006-07-24 23:36:01.000000000 -0400
7232 +++ linux-2.6.17.7/drivers/char/keyboard.c 2006-08-01 20:29:46.000000000 -0400
7233 @@ -618,6 +618,16 @@ static void k_spec(struct vc_data *vc, u
7234 kbd->kbdmode == VC_MEDIUMRAW) &&
7235 value != KVAL(K_SAK))
7236 return; /* SAK is allowed even in raw mode */
7238 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
7240 + void *func = fn_handler[value];
7241 + if (func == fn_show_state || func == fn_show_ptregs ||
7242 + func == fn_show_mem)
7247 fn_handler[value](vc, regs);
7250 diff -urNp linux-2.6.17.7/drivers/char/mem.c linux-2.6.17.7/drivers/char/mem.c
7251 --- linux-2.6.17.7/drivers/char/mem.c 2006-07-24 23:36:01.000000000 -0400
7252 +++ linux-2.6.17.7/drivers/char/mem.c 2006-08-01 20:29:46.000000000 -0400
7254 #include <linux/backing-dev.h>
7255 #include <linux/bootmem.h>
7256 #include <linux/pipe_fs_i.h>
7257 +#include <linux/grsecurity.h>
7259 #include <asm/uaccess.h>
7262 # include <linux/efi.h>
7265 +#ifdef CONFIG_GRKERNSEC
7266 +extern struct file_operations grsec_fops;
7270 * Architectures vary in how they handle caching for addresses
7271 * outside of main memory.
7272 @@ -175,6 +180,11 @@ static ssize_t write_mem(struct file * f
7273 if (!valid_phys_addr_range(p, count))
7276 +#ifdef CONFIG_GRKERNSEC_KMEM
7277 + gr_handle_mem_write();
7283 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
7284 @@ -251,6 +261,11 @@ static int mmap_mem(struct file * file,
7288 +#ifdef CONFIG_GRKERNSEC_KMEM
7289 + if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
7293 /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
7294 if (remap_pfn_range(vma,
7296 @@ -478,6 +493,11 @@ static ssize_t write_kmem(struct file *
7298 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
7300 +#ifdef CONFIG_GRKERNSEC_KMEM
7301 + gr_handle_kmem_write();
7305 if (p < (unsigned long) high_memory) {
7308 @@ -618,7 +638,23 @@ static inline size_t read_zero_pagealign
7311 zap_page_range(vma, addr, count, NULL);
7312 - zeromap_page_range(vma, addr, count, PAGE_COPY);
7313 + zeromap_page_range(vma, addr, count, vma->vm_page_prot);
7315 +#ifdef CONFIG_PAX_SEGMEXEC
7316 + if (vma->vm_flags & VM_MIRROR) {
7317 + unsigned long addr_m;
7318 + struct vm_area_struct * vma_m;
7320 + addr_m = vma->vm_start + vma->vm_mirror;
7321 + vma_m = find_vma(mm, addr_m);
7322 + if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
7323 + addr_m = addr + vma->vm_mirror;
7324 + zap_page_range(vma_m, addr_m, count, NULL);
7326 + printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
7327 + addr, vma->vm_start);
7333 @@ -767,6 +803,16 @@ static loff_t memory_lseek(struct file *
7335 static int open_port(struct inode * inode, struct file * filp)
7337 +#ifdef CONFIG_GRKERNSEC_KMEM
7338 + gr_handle_open_port();
7342 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
7345 +static int open_mem(struct inode * inode, struct file * filp)
7347 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
7350 @@ -774,7 +820,6 @@ static int open_port(struct inode * inod
7351 #define full_lseek null_lseek
7352 #define write_zero write_null
7353 #define read_full read_zero
7354 -#define open_mem open_port
7355 #define open_kmem open_mem
7356 #define open_oldmem open_mem
7358 @@ -897,6 +942,11 @@ static int memory_open(struct inode * in
7359 filp->f_op = &oldmem_fops;
7362 +#ifdef CONFIG_GRKERNSEC
7364 + filp->f_op = &grsec_fops;
7370 @@ -929,6 +979,9 @@ static const struct {
7371 #ifdef CONFIG_CRASH_DUMP
7372 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
7374 +#ifdef CONFIG_GRKERNSEC
7375 + {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
7379 static struct class *mem_class;
7380 diff -urNp linux-2.6.17.7/drivers/char/random.c linux-2.6.17.7/drivers/char/random.c
7381 --- linux-2.6.17.7/drivers/char/random.c 2006-07-24 23:36:01.000000000 -0400
7382 +++ linux-2.6.17.7/drivers/char/random.c 2006-08-01 20:29:46.000000000 -0400
7383 @@ -249,8 +249,13 @@
7385 * Configuration information
7387 +#ifdef CONFIG_GRKERNSEC_RANDNET
7388 +#define INPUT_POOL_WORDS 512
7389 +#define OUTPUT_POOL_WORDS 128
7391 #define INPUT_POOL_WORDS 128
7392 #define OUTPUT_POOL_WORDS 32
7394 #define SEC_XFER_SIZE 512
7397 @@ -287,10 +292,17 @@ static struct poolinfo {
7399 int tap1, tap2, tap3, tap4, tap5;
7400 } poolinfo_table[] = {
7401 +#ifdef CONFIG_GRKERNSEC_RANDNET
7402 + /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
7403 + { 512, 411, 308, 208, 104, 1 },
7404 + /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
7405 + { 128, 103, 76, 51, 25, 1 },
7407 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
7408 { 128, 103, 76, 51, 25, 1 },
7409 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
7410 { 32, 26, 20, 14, 7, 1 },
7413 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
7414 { 2048, 1638, 1231, 819, 411, 1 },
7415 @@ -1658,3 +1670,25 @@ randomize_range(unsigned long start, uns
7417 return PAGE_ALIGN(get_random_int() % range + start);
7420 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
7421 +unsigned long pax_get_random_long(void)
7423 + static time_t rekey_time;
7424 + static __u32 secret[12];
7428 + * Pick a random secret every REKEY_INTERVAL seconds.
7430 + t = get_seconds();
7431 + if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
7433 + get_random_bytes(secret, sizeof(secret));
7436 + secret[1] = half_md4_transform(secret+8, secret);
7437 + secret[0] = half_md4_transform(secret+8, secret);
7438 + return *(unsigned long *)secret;
7441 diff -urNp linux-2.6.17.7/drivers/char/vt_ioctl.c linux-2.6.17.7/drivers/char/vt_ioctl.c
7442 --- linux-2.6.17.7/drivers/char/vt_ioctl.c 2006-07-24 23:36:01.000000000 -0400
7443 +++ linux-2.6.17.7/drivers/char/vt_ioctl.c 2006-08-01 20:29:46.000000000 -0400
7444 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
7449 +#ifdef CONFIG_GRKERNSEC
7450 + if (!capable(CAP_SYS_TTY_CONFIG))
7454 if (!i && v == K_NOSUCHMAP) {
7455 /* disallocate map */
7456 key_map = key_maps[s];
7457 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
7461 +#ifdef CONFIG_GRKERNSEC
7462 + if (!capable(CAP_SYS_TTY_CONFIG)) {
7469 first_free = funcbufptr + (funcbufsize - funcbufleft);
7470 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
7471 diff -urNp linux-2.6.17.7/drivers/ieee1394/hosts.c linux-2.6.17.7/drivers/ieee1394/hosts.c
7472 --- linux-2.6.17.7/drivers/ieee1394/hosts.c 2006-07-24 23:36:01.000000000 -0400
7473 +++ linux-2.6.17.7/drivers/ieee1394/hosts.c 2006-08-01 20:29:46.000000000 -0400
7474 @@ -75,6 +75,7 @@ static int dummy_isoctl(struct hpsb_iso
7477 static struct hpsb_host_driver dummy_driver = {
7479 .transmit_packet = dummy_transmit_packet,
7480 .devctl = dummy_devctl,
7481 .isoctl = dummy_isoctl
7482 diff -urNp linux-2.6.17.7/drivers/ieee1394/ohci1394.c linux-2.6.17.7/drivers/ieee1394/ohci1394.c
7483 --- linux-2.6.17.7/drivers/ieee1394/ohci1394.c 2006-07-24 23:36:01.000000000 -0400
7484 +++ linux-2.6.17.7/drivers/ieee1394/ohci1394.c 2006-08-01 20:29:46.000000000 -0400
7485 @@ -162,9 +162,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
7486 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
7488 /* Module Parameters */
7489 -static int phys_dma = 1;
7490 +static int phys_dma = 0;
7491 module_param(phys_dma, int, 0644);
7492 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
7493 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
7495 static void dma_trm_tasklet(unsigned long data);
7496 static void dma_trm_reset(struct dma_trm_ctx *d);
7497 diff -urNp linux-2.6.17.7/drivers/mtd/devices/doc2001.c linux-2.6.17.7/drivers/mtd/devices/doc2001.c
7498 --- linux-2.6.17.7/drivers/mtd/devices/doc2001.c 2006-07-24 23:36:01.000000000 -0400
7499 +++ linux-2.6.17.7/drivers/mtd/devices/doc2001.c 2006-08-01 20:29:46.000000000 -0400
7500 @@ -423,6 +423,8 @@ static int doc_read_ecc (struct mtd_info
7501 /* Don't allow read past end of device */
7502 if (from >= this->totlen)
7507 /* Don't allow a single read to cross a 512-byte block boundary */
7508 if (from + len > ((from | 0x1ff) + 1))
7509 diff -urNp linux-2.6.17.7/drivers/net/pcnet32.c linux-2.6.17.7/drivers/net/pcnet32.c
7510 --- linux-2.6.17.7/drivers/net/pcnet32.c 2006-07-24 23:36:01.000000000 -0400
7511 +++ linux-2.6.17.7/drivers/net/pcnet32.c 2006-08-01 20:29:46.000000000 -0400
7512 @@ -81,7 +81,7 @@ static int cards_found;
7516 -static unsigned int pcnet32_portlist[] __initdata =
7517 +static unsigned int pcnet32_portlist[] __devinitdata =
7518 { 0x300, 0x320, 0x340, 0x360, 0 };
7520 static int pcnet32_debug = 0;
7521 diff -urNp linux-2.6.17.7/drivers/pci/proc.c linux-2.6.17.7/drivers/pci/proc.c
7522 --- linux-2.6.17.7/drivers/pci/proc.c 2006-07-24 23:36:01.000000000 -0400
7523 +++ linux-2.6.17.7/drivers/pci/proc.c 2006-08-01 20:29:46.000000000 -0400
7524 @@ -473,7 +473,15 @@ static int __init pci_proc_init(void)
7526 struct proc_dir_entry *entry;
7527 struct pci_dev *dev = NULL;
7528 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7529 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7530 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
7531 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7532 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
7535 proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
7537 entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
7539 entry->proc_fops = &proc_bus_pci_dev_operations;
7540 diff -urNp linux-2.6.17.7/drivers/pnp/pnpbios/bioscalls.c linux-2.6.17.7/drivers/pnp/pnpbios/bioscalls.c
7541 --- linux-2.6.17.7/drivers/pnp/pnpbios/bioscalls.c 2006-07-24 23:36:01.000000000 -0400
7542 +++ linux-2.6.17.7/drivers/pnp/pnpbios/bioscalls.c 2006-08-01 20:29:46.000000000 -0400
7543 @@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
7544 set_limit(gdt[(selname) >> 3], size); \
7547 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
7548 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
7551 * At some point we want to use this stack frame pointer to unwind
7552 @@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
7553 struct desc_struct save_desc_40;
7556 +#ifdef CONFIG_PAX_KERNEXEC
7557 + unsigned long cr0;
7561 * PnP BIOSes are generally not terribly re-entrant.
7562 * Also, don't rely on them to save everything correctly.
7563 @@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
7564 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
7565 spin_lock_irqsave(&pnp_bios_lock, flags);
7567 +#ifdef CONFIG_PAX_KERNEXEC
7568 + pax_open_kernel(cr0);
7571 /* The lock prevents us bouncing CPU here */
7573 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
7574 @@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
7578 - spin_unlock_irqrestore(&pnp_bios_lock, flags);
7580 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
7582 +#ifdef CONFIG_PAX_KERNEXEC
7583 + pax_close_kernel(cr0);
7586 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
7589 /* If we get here and this is set then the PnP BIOS faulted on us. */
7590 diff -urNp linux-2.6.17.7/drivers/video/i810/i810_main.c linux-2.6.17.7/drivers/video/i810/i810_main.c
7591 --- linux-2.6.17.7/drivers/video/i810/i810_main.c 2006-07-24 23:36:01.000000000 -0400
7592 +++ linux-2.6.17.7/drivers/video/i810/i810_main.c 2006-08-01 20:29:46.000000000 -0400
7593 @@ -1508,7 +1508,7 @@ static int i810fb_cursor(struct fb_info
7594 int size = ((cursor->image.width + 7) >> 3) *
7595 cursor->image.height;
7597 - u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
7598 + u8 *data = kmalloc(64 * 8, GFP_KERNEL);
7602 diff -urNp linux-2.6.17.7/drivers/video/vesafb.c linux-2.6.17.7/drivers/video/vesafb.c
7603 --- linux-2.6.17.7/drivers/video/vesafb.c 2006-07-24 23:36:01.000000000 -0400
7604 +++ linux-2.6.17.7/drivers/video/vesafb.c 2006-08-01 20:29:46.000000000 -0400
7605 @@ -259,7 +259,7 @@ static int __init vesafb_probe(struct pl
7606 size_remap = size_total;
7607 vesafb_fix.smem_len = size_remap;
7610 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
7611 screen_info.vesapm_seg = 0;
7614 diff -urNp linux-2.6.17.7/fs/Kconfig linux-2.6.17.7/fs/Kconfig
7615 --- linux-2.6.17.7/fs/Kconfig 2006-07-24 23:36:01.000000000 -0400
7616 +++ linux-2.6.17.7/fs/Kconfig 2006-08-01 20:29:46.000000000 -0400
7617 @@ -794,7 +794,7 @@ config PROC_FS
7620 bool "/proc/kcore support" if !ARM
7621 - depends on PROC_FS && MMU
7622 + depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
7625 bool "/proc/vmcore support (EXPERIMENTAL)"
7626 diff -urNp linux-2.6.17.7/fs/binfmt_aout.c linux-2.6.17.7/fs/binfmt_aout.c
7627 --- linux-2.6.17.7/fs/binfmt_aout.c 2006-07-24 23:36:01.000000000 -0400
7628 +++ linux-2.6.17.7/fs/binfmt_aout.c 2006-08-01 20:29:46.000000000 -0400
7630 #include <linux/personality.h>
7631 #include <linux/init.h>
7632 #include <linux/vs_memory.h>
7633 +#include <linux/grsecurity.h>
7635 #include <asm/system.h>
7636 #include <asm/uaccess.h>
7637 @@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
7638 /* If the size of the dump file exceeds the rlimit, then see what would happen
7639 if we wrote the stack, but not the data area. */
7641 + gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
7642 if ((dump.u_dsize+dump.u_ssize) >
7643 current->signal->rlim[RLIMIT_CORE].rlim_cur)
7646 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
7647 if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
7648 current->signal->rlim[RLIMIT_CORE].rlim_cur)
7650 @@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
7652 /* Make sure we have enough room to write the stack and data areas. */
7654 + gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
7655 if ((dump.u_ssize) >
7656 current->signal->rlim[RLIMIT_CORE].rlim_cur)
7659 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
7660 if ((dump.u_ssize+1) * PAGE_SIZE >
7661 current->signal->rlim[RLIMIT_CORE].rlim_cur)
7663 @@ -287,6 +292,8 @@ static int load_aout_binary(struct linux
7664 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
7665 if (rlim >= RLIM_INFINITY)
7668 + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
7669 if (ex.a_data + ex.a_bss > rlim)
7672 @@ -319,6 +326,28 @@ static int load_aout_binary(struct linux
7673 current->mm->mmap = NULL;
7674 compute_creds(bprm);
7675 current->flags &= ~PF_FORKNOEXEC;
7677 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
7678 + current->mm->pax_flags = 0UL;
7681 +#ifdef CONFIG_PAX_PAGEEXEC
7682 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
7683 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
7685 +#ifdef CONFIG_PAX_EMUTRAMP
7686 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
7687 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
7690 +#ifdef CONFIG_PAX_MPROTECT
7691 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
7692 + current->mm->pax_flags |= MF_PAX_MPROTECT;
7699 if (N_MAGIC(ex) == NMAGIC) {
7700 loff_t pos = fd_offset;
7701 @@ -414,7 +443,7 @@ static int load_aout_binary(struct linux
7703 down_write(¤t->mm->mmap_sem);
7704 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
7705 - PROT_READ | PROT_WRITE | PROT_EXEC,
7706 + PROT_READ | PROT_WRITE,
7707 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
7708 fd_offset + ex.a_text);
7709 up_write(¤t->mm->mmap_sem);
7710 diff -urNp linux-2.6.17.7/fs/binfmt_elf.c linux-2.6.17.7/fs/binfmt_elf.c
7711 --- linux-2.6.17.7/fs/binfmt_elf.c 2006-07-24 23:36:01.000000000 -0400
7712 +++ linux-2.6.17.7/fs/binfmt_elf.c 2006-08-01 20:29:46.000000000 -0400
7714 #include <linux/random.h>
7715 #include <linux/vs_memory.h>
7716 #include <linux/vs_cvirt.h>
7717 +#include <linux/grsecurity.h>
7719 #include <asm/uaccess.h>
7720 #include <asm/param.h>
7721 #include <asm/page.h>
7723 +#ifdef CONFIG_PAX_SEGMEXEC
7724 +#include <asm/desc.h>
7727 #include <linux/elf.h>
7729 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
7730 @@ -90,6 +95,8 @@ static struct linux_binfmt elf_format =
7732 static int set_brk(unsigned long start, unsigned long end)
7734 + unsigned long e = end;
7736 start = ELF_PAGEALIGN(start);
7737 end = ELF_PAGEALIGN(end);
7739 @@ -100,7 +107,7 @@ static int set_brk(unsigned long start,
7743 - current->mm->start_brk = current->mm->brk = end;
7744 + current->mm->start_brk = current->mm->brk = e;
7748 @@ -316,10 +323,9 @@ static unsigned long load_elf_interp(str
7750 struct elf_phdr *elf_phdata;
7751 struct elf_phdr *eppnt;
7752 - unsigned long load_addr = 0;
7753 - int load_addr_set = 0;
7754 + unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
7755 unsigned long last_bss = 0, elf_bss = 0;
7756 - unsigned long error = ~0UL;
7757 + unsigned long error = -EINVAL;
7758 int retval, i, size;
7760 /* First of all, some simple consistency checks */
7761 @@ -358,59 +364,80 @@ static unsigned long load_elf_interp(str
7765 +#ifdef CONFIG_PAX_SEGMEXEC
7766 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
7767 + task_size = SEGMEXEC_TASK_SIZE;
7771 + min_addr = task_size;
7775 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
7776 - if (eppnt->p_type == PT_LOAD) {
7777 - int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
7779 - unsigned long vaddr = 0;
7780 - unsigned long k, map_addr;
7782 - if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
7783 - if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
7784 - if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
7785 - vaddr = eppnt->p_vaddr;
7786 - if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
7787 - elf_type |= MAP_FIXED;
7789 - map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
7791 - if (BAD_ADDR(map_addr))
7794 - if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
7795 - load_addr = map_addr - ELF_PAGESTART(vaddr);
7796 - load_addr_set = 1;
7800 - * Check to see if the section's size will overflow the
7801 - * allowed task size. Note that p_filesz must always be
7802 - * <= p_memsize so it is only necessary to check p_memsz.
7804 - k = load_addr + eppnt->p_vaddr;
7805 - if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz ||
7806 - eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
7808 + if (eppnt->p_type != PT_LOAD)
7812 + * Check to see if the section's size will overflow the
7813 + * allowed task size. Note that p_filesz must always be
7814 + * <= p_memsize so it is only necessary to check p_memsz.
7816 + if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
7819 + if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
7820 + min_addr = ELF_PAGESTART(eppnt->p_vaddr);
7821 + if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
7822 + max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
7824 + if (min_addr >= max_addr)
7829 - * Find the end of the file mapping for this phdr, and keep
7830 - * track of the largest address we see for this.
7832 - k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
7837 - * Do the same thing for the memory mapping - between
7838 - * elf_bss and last_bss is the bss section.
7840 - k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
7844 + eppnt = elf_phdata;
7845 + for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
7846 + int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
7848 + unsigned long vaddr;
7849 + unsigned long k, map_addr;
7851 + if (eppnt->p_type != PT_LOAD)
7854 + if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
7855 + if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
7856 + if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
7857 + vaddr = eppnt->p_vaddr;
7859 + if (!load_addr && interp_elf_ex->e_type == ET_DYN) {
7860 + load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
7862 + if (load_addr > task_size)
7865 + load_addr -= min_addr;
7868 + map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
7870 + if (BAD_ADDR(map_addr))
7874 + * Find the end of the file mapping for this phdr, and keep
7875 + * track of the largest address we see for this.
7877 + k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
7882 + * Do the same thing for the memory mapping - between
7883 + * elf_bss and last_bss is the bss section.
7885 + k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
7891 @@ -447,7 +474,7 @@ out:
7892 static unsigned long load_aout_interp(struct exec * interp_ex,
7893 struct file * interpreter)
7895 - unsigned long text_data, elf_entry = ~0UL;
7896 + unsigned long text_data, elf_entry = -EINVAL;
7900 @@ -491,6 +518,180 @@ out:
7904 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
7905 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
7907 + unsigned long pax_flags = 0UL;
7909 +#ifdef CONFIG_PAX_PAGEEXEC
7910 + if (elf_phdata->p_flags & PF_PAGEEXEC)
7911 + pax_flags |= MF_PAX_PAGEEXEC;
7914 +#ifdef CONFIG_PAX_SEGMEXEC
7915 + if (elf_phdata->p_flags & PF_SEGMEXEC)
7916 + pax_flags |= MF_PAX_SEGMEXEC;
7919 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
7920 + if (pax_flags & MF_PAX_PAGEEXEC)
7921 + pax_flags &= ~MF_PAX_SEGMEXEC;
7924 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
7925 + if (pax_flags & MF_PAX_SEGMEXEC)
7926 + pax_flags &= ~MF_PAX_PAGEEXEC;
7929 +#ifdef CONFIG_PAX_EMUTRAMP
7930 + if (elf_phdata->p_flags & PF_EMUTRAMP)
7931 + pax_flags |= MF_PAX_EMUTRAMP;
7934 +#ifdef CONFIG_PAX_MPROTECT
7935 + if (elf_phdata->p_flags & PF_MPROTECT)
7936 + pax_flags |= MF_PAX_MPROTECT;
7939 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
7940 + if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
7941 + pax_flags |= MF_PAX_RANDMMAP;
7948 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
7949 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
7951 + unsigned long pax_flags = 0UL;
7953 +#ifdef CONFIG_PAX_PAGEEXEC
7954 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
7955 + pax_flags |= MF_PAX_PAGEEXEC;
7958 +#ifdef CONFIG_PAX_SEGMEXEC
7959 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
7960 + pax_flags |= MF_PAX_SEGMEXEC;
7963 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
7964 + if (pax_flags & MF_PAX_PAGEEXEC)
7965 + pax_flags &= ~MF_PAX_SEGMEXEC;
7968 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
7969 + if (pax_flags & MF_PAX_SEGMEXEC)
7970 + pax_flags &= ~MF_PAX_PAGEEXEC;
7973 +#ifdef CONFIG_PAX_EMUTRAMP
7974 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
7975 + pax_flags |= MF_PAX_EMUTRAMP;
7978 +#ifdef CONFIG_PAX_MPROTECT
7979 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
7980 + pax_flags |= MF_PAX_MPROTECT;
7983 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
7984 + if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
7985 + pax_flags |= MF_PAX_RANDMMAP;
7992 +#ifdef CONFIG_PAX_EI_PAX
7993 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
7995 + unsigned long pax_flags = 0UL;
7997 +#ifdef CONFIG_PAX_PAGEEXEC
7998 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
7999 + pax_flags |= MF_PAX_PAGEEXEC;
8002 +#ifdef CONFIG_PAX_SEGMEXEC
8003 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
8004 + pax_flags |= MF_PAX_SEGMEXEC;
8007 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
8008 + if (pax_flags & MF_PAX_PAGEEXEC)
8009 + pax_flags &= ~MF_PAX_SEGMEXEC;
8012 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
8013 + if (pax_flags & MF_PAX_SEGMEXEC)
8014 + pax_flags &= ~MF_PAX_PAGEEXEC;
8017 +#ifdef CONFIG_PAX_EMUTRAMP
8018 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
8019 + pax_flags |= MF_PAX_EMUTRAMP;
8022 +#ifdef CONFIG_PAX_MPROTECT
8023 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
8024 + pax_flags |= MF_PAX_MPROTECT;
8027 +#ifdef CONFIG_PAX_ASLR
8028 + if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
8029 + pax_flags |= MF_PAX_RANDMMAP;
8036 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
8037 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
8039 + unsigned long pax_flags = 0UL;
8041 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
8045 +#ifdef CONFIG_PAX_EI_PAX
8046 + pax_flags = pax_parse_ei_pax(elf_ex);
8049 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
8050 + for (i = 0UL; i < elf_ex->e_phnum; i++)
8051 + if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
8052 + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
8053 + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
8054 + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
8055 + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
8056 + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
8059 +#ifdef CONFIG_PAX_SOFTMODE
8061 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
8065 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
8070 + if (0 > pax_check_flags(&pax_flags))
8073 + current->mm->pax_flags = pax_flags;
8079 * These are the functions used to load ELF style executables and shared
8080 * libraries. There is no binary dependent code anywhere else.
8081 @@ -527,7 +728,7 @@ static int load_elf_binary(struct linux_
8082 char * elf_interpreter = NULL;
8083 unsigned int interpreter_type = INTERPRETER_NONE;
8084 unsigned char ibcs2_interpreter = 0;
8085 - unsigned long error;
8086 + unsigned long error = 0;
8087 struct elf_phdr * elf_ppnt, *elf_phdata;
8088 unsigned long elf_bss, elf_brk;
8089 int elf_exec_fileno;
8090 @@ -545,6 +746,7 @@ static int load_elf_binary(struct linux_
8091 struct elfhdr interp_elf_ex;
8092 struct exec interp_ex;
8094 + unsigned long task_size = TASK_SIZE;
8096 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
8098 @@ -770,14 +972,88 @@ static int load_elf_binary(struct linux_
8099 current->mm->end_code = 0;
8100 current->mm->mmap = NULL;
8101 current->flags &= ~PF_FORKNOEXEC;
8103 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
8104 + current->mm->pax_flags = 0UL;
8107 +#ifdef CONFIG_PAX_DLRESOLVE
8108 + current->mm->call_dl_resolve = 0UL;
8111 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
8112 + current->mm->call_syscall = 0UL;
8115 +#ifdef CONFIG_PAX_ASLR
8116 + current->mm->delta_mmap = 0UL;
8117 + current->mm->delta_exec = 0UL;
8118 + current->mm->delta_stack = 0UL;
8121 current->mm->def_flags = def_flags;
8123 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
8124 + if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
8125 + send_sig(SIGKILL, current, 0);
8126 + goto out_free_dentry;
8130 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
8131 + pax_set_initial_flags(bprm);
8132 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
8133 + if (pax_set_initial_flags_func)
8134 + (pax_set_initial_flags_func)(bprm);
8137 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
8138 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
8139 + current->mm->context.user_cs_limit = PAGE_SIZE;
8142 +#ifdef CONFIG_PAX_SEGMEXEC
8143 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
8144 + int cpu = get_cpu();
8146 + current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
8147 + current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
8148 + set_user_cs(current->mm, cpu);
8150 + task_size = SEGMEXEC_TASK_SIZE;
8154 +#ifdef CONFIG_PAX_ASLR
8155 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
8156 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
8158 + current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
8159 + current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
8160 + current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
8164 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8165 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
8166 + executable_stack = EXSTACK_DEFAULT;
8169 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
8170 may depend on the personality. */
8171 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
8173 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8174 + if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
8177 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
8178 current->personality |= READ_IMPLIES_EXEC;
8180 +#ifdef CONFIG_PAX_ASLR
8181 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
8184 if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8185 current->flags |= PF_RANDOMIZE;
8186 arch_pick_mmap_layout(current->mm);
8187 @@ -849,6 +1125,15 @@ static int load_elf_binary(struct linux_
8188 base, as well as whatever program they might try to exec. This
8189 is because the brk will follow the loader, and is not movable. */
8190 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
8192 +#ifdef CONFIG_PAX_RANDMMAP
8193 + /* PaX: randomize base address at the default exe base if requested */
8194 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
8195 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
8196 + elf_flags |= MAP_FIXED;
8202 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
8203 @@ -876,9 +1161,9 @@ static int load_elf_binary(struct linux_
8204 * allowed task size. Note that p_filesz must always be
8205 * <= p_memsz so it is only necessary to check p_memsz.
8207 - if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
8208 - elf_ppnt->p_memsz > TASK_SIZE ||
8209 - TASK_SIZE - elf_ppnt->p_memsz < k) {
8210 + if (k > task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
8211 + elf_ppnt->p_memsz > task_size ||
8212 + task_size - elf_ppnt->p_memsz < k) {
8213 /* set_brk can never work. Avoid overflows. */
8214 send_sig(SIGKILL, current, 0);
8215 goto out_free_dentry;
8216 @@ -905,6 +1190,12 @@ static int load_elf_binary(struct linux_
8217 start_data += load_bias;
8218 end_data += load_bias;
8220 +#ifdef CONFIG_PAX_RANDMMAP
8221 + if (current->mm->pax_flags & MF_PAX_RANDMMAP)
8222 + elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
8223 +#undef pax_delta_mask
8226 /* Calling set_brk effectively mmaps the pages that we need
8227 * for the bss and break sections. We must do this before
8228 * mapping in the interpreter, to make sure it doesn't wind
8229 @@ -933,7 +1224,7 @@ static int load_elf_binary(struct linux_
8230 printk(KERN_ERR "Unable to load interpreter %.128s\n",
8232 force_sig(SIGSEGV, current);
8233 - retval = -ENOEXEC; /* Nobody gets to see this, but.. */
8234 + retval = elf_entry; /* Nobody gets to see this, but.. */
8235 goto out_free_dentry;
8237 reloc_func_desc = interp_load_addr;
8238 @@ -1157,7 +1448,7 @@ static int dump_seek(struct file *file,
8240 * I think we should skip something. But I am not sure how. H.J.
8242 -static int maydump(struct vm_area_struct *vma)
8243 +static int maydump(struct vm_area_struct *vma, long signr)
8245 /* Do not dump I/O mapped devices or special mappings */
8246 if (vma->vm_flags & (VM_IO | VM_RESERVED))
8247 @@ -1168,7 +1459,7 @@ static int maydump(struct vm_area_struct
8248 return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
8250 /* If it hasn't been written to, don't write it out */
8251 - if (!vma->anon_vma)
8252 + if (signr != SIGKILL && !vma->anon_vma)
8256 @@ -1222,8 +1513,11 @@ static int writenote(struct memelfnote *
8259 #define DUMP_WRITE(addr, nr) \
8261 + gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
8262 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
8263 - goto end_coredump;
8264 + goto end_coredump; \
8266 #define DUMP_SEEK(off) \
8267 if (!dump_seek(file, (off))) \
8269 @@ -1573,7 +1867,7 @@ static int elf_core_dump(long signr, str
8270 phdr.p_offset = offset;
8271 phdr.p_vaddr = vma->vm_start;
8273 - phdr.p_filesz = maydump(vma) ? sz : 0;
8274 + phdr.p_filesz = maydump(vma, signr) ? sz : 0;
8276 offset += phdr.p_filesz;
8277 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
8278 @@ -1606,7 +1900,7 @@ static int elf_core_dump(long signr, str
8279 for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
8282 - if (!maydump(vma))
8283 + if (!maydump(vma, signr))
8286 for (addr = vma->vm_start;
8287 @@ -1625,6 +1919,7 @@ static int elf_core_dump(long signr, str
8289 flush_cache_page(vma, addr, page_to_pfn(page));
8291 + gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
8292 if ((size += PAGE_SIZE) > limit ||
8293 !dump_write(file, kaddr,
8295 diff -urNp linux-2.6.17.7/fs/binfmt_flat.c linux-2.6.17.7/fs/binfmt_flat.c
8296 --- linux-2.6.17.7/fs/binfmt_flat.c 2006-07-24 23:36:01.000000000 -0400
8297 +++ linux-2.6.17.7/fs/binfmt_flat.c 2006-08-01 20:29:46.000000000 -0400
8298 @@ -552,7 +552,9 @@ static int load_flat_file(struct linux_b
8299 realdatastart = (unsigned long) -ENOMEM;
8300 printk("Unable to allocate RAM for process data, errno %d\n",
8302 + down_write(¤t->mm->mmap_sem);
8303 do_munmap(current->mm, textpos, text_len);
8304 + up_write(¤t->mm->mmap_sem);
8305 ret = realdatastart;
8308 @@ -574,8 +576,10 @@ static int load_flat_file(struct linux_b
8310 if (result >= (unsigned long)-4096) {
8311 printk("Unable to read data+bss, errno %d\n", (int)-result);
8312 + down_write(¤t->mm->mmap_sem);
8313 do_munmap(current->mm, textpos, text_len);
8314 do_munmap(current->mm, realdatastart, data_len + extra);
8315 + up_write(¤t->mm->mmap_sem);
8319 @@ -639,8 +643,10 @@ static int load_flat_file(struct linux_b
8321 if (result >= (unsigned long)-4096) {
8322 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
8323 + down_write(¤t->mm->mmap_sem);
8324 do_munmap(current->mm, textpos, text_len + data_len + extra +
8325 MAX_SHARED_LIBS * sizeof(unsigned long));
8326 + up_write(¤t->mm->mmap_sem);
8330 diff -urNp linux-2.6.17.7/fs/binfmt_misc.c linux-2.6.17.7/fs/binfmt_misc.c
8331 --- linux-2.6.17.7/fs/binfmt_misc.c 2006-07-24 23:36:01.000000000 -0400
8332 +++ linux-2.6.17.7/fs/binfmt_misc.c 2006-08-01 20:29:46.000000000 -0400
8333 @@ -112,9 +112,11 @@ static int load_misc_binary(struct linux
8334 struct files_struct *files = NULL;
8338 + if (!enabled || bprm->misc)
8343 /* to keep locking time low, we copy the interpreter string */
8344 read_lock(&entries_lock);
8345 fmt = check_file(bprm);
8346 diff -urNp linux-2.6.17.7/fs/buffer.c linux-2.6.17.7/fs/buffer.c
8347 --- linux-2.6.17.7/fs/buffer.c 2006-07-24 23:36:01.000000000 -0400
8348 +++ linux-2.6.17.7/fs/buffer.c 2006-08-01 20:29:46.000000000 -0400
8350 #include <linux/bitops.h>
8351 #include <linux/mpage.h>
8352 #include <linux/bit_spinlock.h>
8353 +#include <linux/grsecurity.h>
8355 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
8356 static void invalidate_bh_lrus(void);
8357 @@ -2162,6 +2163,7 @@ static int __generic_cont_expand(struct
8360 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
8361 + gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
8362 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
8363 send_sig(SIGXFSZ, current, 0);
8365 diff -urNp linux-2.6.17.7/fs/compat.c linux-2.6.17.7/fs/compat.c
8366 --- linux-2.6.17.7/fs/compat.c 2006-07-24 23:36:01.000000000 -0400
8367 +++ linux-2.6.17.7/fs/compat.c 2006-08-01 20:29:46.000000000 -0400
8369 #include <linux/rwsem.h>
8370 #include <linux/acct.h>
8371 #include <linux/mm.h>
8372 +#include <linux/grsecurity.h>
8374 #include <net/sock.h> /* siocdevprivate_ioctl */
8376 @@ -1498,6 +1499,11 @@ int compat_do_execve(char * filename,
8380 +#ifdef CONFIG_GRKERNSEC
8381 + struct file *old_exec_file;
8382 + struct acl_subject_label *old_acl;
8383 + struct rlimit old_rlim[RLIM_NLIMITS];
8387 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
8388 @@ -1515,6 +1521,15 @@ int compat_do_execve(char * filename,
8390 bprm->filename = filename;
8391 bprm->interp = filename;
8393 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
8395 + if (gr_handle_nproc())
8398 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
8401 bprm->mm = mm_alloc();
8404 @@ -1553,10 +1568,39 @@ int compat_do_execve(char * filename,
8408 + if (!gr_tpe_allow(file)) {
8413 + if (gr_check_crash_exec(file)) {
8418 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
8420 + gr_handle_exec_args(bprm, (char __user * __user *)argv);
8422 +#ifdef CONFIG_GRKERNSEC
8423 + old_acl = current->acl;
8424 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
8425 + old_exec_file = current->exec_file;
8427 + current->exec_file = file;
8430 + gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
8432 retval = search_binary_handler(bprm, regs);
8434 free_arg_pages(bprm);
8436 +#ifdef CONFIG_GRKERNSEC
8437 + if (old_exec_file)
8438 + fput(old_exec_file);
8441 /* execve success */
8442 security_bprm_free(bprm);
8443 acct_update_integrals(current);
8444 @@ -1564,6 +1608,13 @@ int compat_do_execve(char * filename,
8448 +#ifdef CONFIG_GRKERNSEC
8449 + current->acl = old_acl;
8450 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
8451 + fput(current->exec_file);
8452 + current->exec_file = old_exec_file;
8456 /* Something went wrong, return the inode and free the argument pages*/
8457 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8458 diff -urNp linux-2.6.17.7/fs/dcache.c linux-2.6.17.7/fs/dcache.c
8459 --- linux-2.6.17.7/fs/dcache.c 2006-07-24 23:36:01.000000000 -0400
8460 +++ linux-2.6.17.7/fs/dcache.c 2006-08-01 20:29:46.000000000 -0400
8461 @@ -1389,7 +1389,7 @@ already_unhashed:
8463 * "buflen" should be positive. Caller holds the dcache_lock.
8465 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
8466 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
8467 struct dentry *root, struct vfsmount *rootmnt,
8468 char *buffer, int buflen)
8470 diff -urNp linux-2.6.17.7/fs/exec.c linux-2.6.17.7/fs/exec.c
8471 --- linux-2.6.17.7/fs/exec.c 2006-07-24 23:36:01.000000000 -0400
8472 +++ linux-2.6.17.7/fs/exec.c 2006-08-01 20:29:46.000000000 -0400
8474 #include <linux/cn_proc.h>
8475 #include <linux/vs_cvirt.h>
8476 #include <linux/vs_memory.h>
8477 +#include <linux/random.h>
8478 +#include <linux/grsecurity.h>
8480 #include <asm/uaccess.h>
8481 #include <asm/mmu_context.h>
8482 @@ -67,6 +69,15 @@ EXPORT_SYMBOL(suid_dumpable);
8483 static struct linux_binfmt *formats;
8484 static DEFINE_RWLOCK(binfmt_lock);
8486 +#ifdef CONFIG_PAX_SOFTMODE
8487 +unsigned int pax_softmode;
8490 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
8491 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
8492 +EXPORT_SYMBOL(pax_set_initial_flags_func);
8495 int register_binfmt(struct linux_binfmt * fmt)
8497 struct linux_binfmt ** tmp = &formats;
8498 @@ -312,6 +323,10 @@ void install_arg_page(struct vm_area_str
8499 if (unlikely(anon_vma_prepare(vma)))
8502 +#ifdef CONFIG_PAX_SEGMEXEC
8503 + if (page_count(page) == 1)
8506 flush_dcache_page(page);
8507 pte = get_locked_pte(mm, address, &ptl);
8509 @@ -321,9 +336,21 @@ void install_arg_page(struct vm_area_str
8512 inc_mm_counter(mm, anon_rss);
8514 +#ifdef CONFIG_PAX_SEGMEXEC
8515 + if (page_count(page) == 1)
8518 lru_cache_add_active(page);
8519 set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
8520 page, vma->vm_page_prot))));
8522 +#ifdef CONFIG_PAX_SEGMEXEC
8523 + if (page_count(page) != 1)
8524 + page_add_anon_rmap(page, vma, address);
8528 page_add_new_anon_rmap(page, vma, address);
8529 pte_unmap_unlock(pte, ptl);
8531 @@ -346,6 +373,10 @@ int setup_arg_pages(struct linux_binprm
8535 +#ifdef CONFIG_PAX_SEGMEXEC
8536 + struct vm_area_struct *mpnt_m = NULL;
8539 #ifdef CONFIG_STACK_GROWSUP
8540 /* Move the argument and environment strings to the bottom of the
8542 @@ -410,6 +441,18 @@ int setup_arg_pages(struct linux_binprm
8544 memset(mpnt, 0, sizeof(*mpnt));
8546 +#ifdef CONFIG_PAX_SEGMEXEC
8547 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
8548 + mpnt_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8550 + kmem_cache_free(vm_area_cachep, mpnt);
8554 + memset(mpnt_m, 0, sizeof(*mpnt_m));
8558 down_write(&mm->mmap_sem);
8561 @@ -430,14 +473,51 @@ int setup_arg_pages(struct linux_binprm
8563 mpnt->vm_flags = VM_STACK_FLAGS;
8564 mpnt->vm_flags |= mm->def_flags;
8566 +#ifdef CONFIG_PAX_PAGEEXEC
8567 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
8568 + mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & 0x7];
8572 mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
8573 if ((ret = insert_vm_struct(mm, mpnt))) {
8574 up_write(&mm->mmap_sem);
8575 kmem_cache_free(vm_area_cachep, mpnt);
8577 +#ifdef CONFIG_PAX_SEGMEXEC
8579 + kmem_cache_free(vm_area_cachep, mpnt_m);
8584 vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
8585 mm->stack_vm = mm->total_vm;
8587 +#ifdef CONFIG_PAX_SEGMEXEC
8590 + if (!(mpnt->vm_flags & VM_EXEC)) {
8591 + mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
8592 + mpnt_m->vm_page_prot = PAGE_NONE;
8594 + mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
8595 + mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
8596 + if ((ret = insert_vm_struct(mm, mpnt_m))) {
8597 + up_write(&mm->mmap_sem);
8598 + kmem_cache_free(vm_area_cachep, mpnt_m);
8601 + mpnt_m->vm_flags |= VM_MIRROR;
8602 + mpnt->vm_flags |= VM_MIRROR;
8603 + mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
8604 + mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
8605 + mpnt_m->vm_pgoff = mpnt->vm_pgoff;
8606 + mm->total_vm += vma_pages(mpnt_m);
8612 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8613 @@ -444,6 +524,14 @@ int setup_arg_pages(struct linux_binprm
8615 bprm->page[i] = NULL;
8616 install_arg_page(mpnt, page, stack_base);
8618 +#ifdef CONFIG_PAX_SEGMEXEC
8620 + page_cache_get(page);
8621 + install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
8626 stack_base += PAGE_SIZE;
8628 @@ -1147,6 +1235,11 @@ int do_execve(char * filename,
8632 +#ifdef CONFIG_GRKERNSEC
8633 + struct file *old_exec_file;
8634 + struct acl_subject_label *old_acl;
8635 + struct rlimit old_rlim[RLIM_NLIMITS];
8639 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
8640 @@ -1158,10 +1251,29 @@ int do_execve(char * filename,
8644 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
8646 + if (gr_handle_nproc()) {
8647 + allow_write_access(file);
8652 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
8653 + allow_write_access(file);
8660 bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
8662 +#ifdef CONFIG_PAX_RANDUSTACK
8663 + if (randomize_va_space)
8664 + bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
8668 bprm->filename = filename;
8669 bprm->interp = filename;
8670 @@ -1203,8 +1315,38 @@ int do_execve(char * filename,
8674 + if (!gr_tpe_allow(file)) {
8679 + if (gr_check_crash_exec(file)) {
8684 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
8686 + gr_handle_exec_args(bprm, argv);
8688 +#ifdef CONFIG_GRKERNSEC
8689 + old_acl = current->acl;
8690 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
8691 + old_exec_file = current->exec_file;
8693 + current->exec_file = file;
8696 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
8700 retval = search_binary_handler(bprm,regs);
8702 +#ifdef CONFIG_GRKERNSEC
8703 + if (old_exec_file)
8704 + fput(old_exec_file);
8706 free_arg_pages(bprm);
8708 /* execve success */
8709 @@ -1214,6 +1356,14 @@ int do_execve(char * filename,
8714 +#ifdef CONFIG_GRKERNSEC
8715 + current->acl = old_acl;
8716 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
8717 + fput(current->exec_file);
8718 + current->exec_file = old_exec_file;
8722 /* Something went wrong, return the inode and free the argument pages*/
8723 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8724 @@ -1374,6 +1524,114 @@ static void format_corename(char *corena
8728 +int pax_check_flags(unsigned long * flags)
8732 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
8733 + if (*flags & MF_PAX_SEGMEXEC)
8735 + *flags &= ~MF_PAX_SEGMEXEC;
8740 + if ((*flags & MF_PAX_PAGEEXEC)
8742 +#ifdef CONFIG_PAX_PAGEEXEC
8743 + && (*flags & MF_PAX_SEGMEXEC)
8748 + *flags &= ~MF_PAX_PAGEEXEC;
8752 + if ((*flags & MF_PAX_MPROTECT)
8754 +#ifdef CONFIG_PAX_MPROTECT
8755 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
8760 + *flags &= ~MF_PAX_MPROTECT;
8764 + if ((*flags & MF_PAX_EMUTRAMP)
8766 +#ifdef CONFIG_PAX_EMUTRAMP
8767 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
8772 + *flags &= ~MF_PAX_EMUTRAMP;
8779 +EXPORT_SYMBOL(pax_check_flags);
8781 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8782 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
8784 + struct task_struct *tsk = current;
8785 + struct mm_struct *mm = current->mm;
8786 + char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
8787 + char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
8788 + char* path_exec=NULL;
8789 + char* path_fault=NULL;
8790 + unsigned long start=0UL, end=0UL, offset=0UL;
8792 + if (buffer_exec && buffer_fault) {
8793 + struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
8795 + down_read(&mm->mmap_sem);
8797 + while (vma && (!vma_exec || !vma_fault)) {
8798 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
8800 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
8802 + vma = vma->vm_next;
8805 + path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
8806 + if (IS_ERR(path_exec))
8807 + path_exec = "<path too long>";
8810 + start = vma_fault->vm_start;
8811 + end = vma_fault->vm_end;
8812 + offset = vma_fault->vm_pgoff << PAGE_SHIFT;
8813 + if (vma_fault->vm_file) {
8814 + path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
8815 + if (IS_ERR(path_fault))
8816 + path_fault = "<path too long>";
8818 + path_fault = "<anonymous mapping>";
8820 + up_read(&mm->mmap_sem);
8822 + if (tsk->signal->curr_ip)
8823 + 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);
8825 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
8826 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
8827 + "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
8828 + tsk->uid, tsk->euid, pc, sp);
8829 + free_page((unsigned long)buffer_exec);
8830 + free_page((unsigned long)buffer_fault);
8831 + pax_report_insns(pc, sp);
8832 + do_coredump(SIGKILL, SIGKILL, regs);
8836 static void zap_threads (struct mm_struct *mm)
8838 struct task_struct *g, *p;
8839 @@ -1491,6 +1749,10 @@ int do_coredump(long signr, int exit_cod
8841 clear_thread_flag(TIF_SIGPENDING);
8843 + if (signr == SIGKILL || signr == SIGILL)
8844 + gr_handle_brute_attach(current);
8846 + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
8847 if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
8850 diff -urNp linux-2.6.17.7/fs/fcntl.c linux-2.6.17.7/fs/fcntl.c
8851 --- linux-2.6.17.7/fs/fcntl.c 2006-07-24 23:36:01.000000000 -0400
8852 +++ linux-2.6.17.7/fs/fcntl.c 2006-08-01 20:29:46.000000000 -0400
8854 #include <linux/signal.h>
8855 #include <linux/rcupdate.h>
8856 #include <linux/vs_limit.h>
8857 +#include <linux/grsecurity.h>
8859 #include <asm/poll.h>
8860 #include <asm/siginfo.h>
8861 @@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
8862 struct fdtable *fdt;
8865 + gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
8866 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
8869 @@ -83,6 +85,7 @@ repeat:
8873 + gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
8874 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
8877 @@ -141,6 +144,8 @@ asmlinkage long sys_dup2(unsigned int ol
8878 struct files_struct * files = current->files;
8879 struct fdtable *fdt;
8881 + gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
8883 spin_lock(&files->file_lock);
8884 if (!(file = fcheck(oldfd)))
8886 @@ -427,7 +432,8 @@ static inline int sigio_perm(struct task
8887 return (((fown->euid == 0) ||
8888 (fown->euid == p->suid) || (fown->euid == p->uid) ||
8889 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
8890 - !security_file_send_sigiotask(p, fown, sig));
8891 + !security_file_send_sigiotask(p, fown, sig) &&
8892 + !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
8895 static void send_sigio_to_task(struct task_struct *p,
8896 diff -urNp linux-2.6.17.7/fs/namei.c linux-2.6.17.7/fs/namei.c
8897 --- linux-2.6.17.7/fs/namei.c 2006-07-24 23:36:01.000000000 -0400
8898 +++ linux-2.6.17.7/fs/namei.c 2006-08-01 20:29:46.000000000 -0400
8900 #include <linux/vserver/inode.h>
8901 #include <linux/vs_tag.h>
8902 #include <linux/vserver/debug.h>
8903 +#include <linux/grsecurity.h>
8904 #include <asm/namei.h>
8905 #include <asm/uaccess.h>
8907 @@ -611,6 +612,13 @@ static inline int do_follow_link(struct
8908 err = security_inode_follow_link(path->dentry, nd);
8912 + if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
8913 + path->dentry->d_inode, path->dentry, nd->mnt)) {
8918 current->link_count++;
8919 current->total_link_count++;
8921 @@ -954,11 +962,18 @@ return_reval:
8925 + if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
8931 dput_path(&next, nd);
8934 + if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
8940 @@ -1601,6 +1616,17 @@ int open_namei(int dfd, const char *path
8945 + if (gr_handle_rawio(nd->dentry->d_inode)) {
8950 + if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
8958 @@ -1641,9 +1667,16 @@ do_last:
8960 /* Negative dentry, just create the file */
8961 if (!path.dentry->d_inode) {
8962 + if (!gr_acl_handle_creat(path.dentry, nd->dentry, nd->mnt, flag, mode)) {
8964 + mutex_unlock(&dir->d_inode->i_mutex);
8967 if (!IS_POSIXACL(dir->d_inode))
8968 mode &= ~current->fs->umask;
8969 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
8971 + gr_handle_create(path.dentry, nd->mnt);
8972 mutex_unlock(&dir->d_inode->i_mutex);
8974 nd->dentry = path.dentry;
8975 @@ -1658,6 +1691,23 @@ do_last:
8977 * It already exists.
8980 + if (gr_handle_rawio(path.dentry->d_inode)) {
8981 + mutex_unlock(&dir->d_inode->i_mutex);
8985 + if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
8986 + mutex_unlock(&dir->d_inode->i_mutex);
8990 + if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
8991 + mutex_unlock(&dir->d_inode->i_mutex);
8996 mutex_unlock(&dir->d_inode->i_mutex);
8999 @@ -1711,6 +1761,13 @@ do_link:
9000 error = security_inode_follow_link(path.dentry, nd);
9004 + if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
9005 + path.dentry, nd->mnt)) {
9010 error = __do_follow_link(&path, nd);
9012 /* Does someone understand code flow here? Or it is only
9013 @@ -1837,6 +1894,22 @@ asmlinkage long sys_mknodat(int dfd, con
9014 if (!IS_POSIXACL(nd.dentry->d_inode))
9015 mode &= ~current->fs->umask;
9016 if (!IS_ERR(dentry)) {
9017 + if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
9020 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
9021 + path_release(&nd);
9025 + if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
9028 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
9029 + path_release(&nd);
9033 switch (mode & S_IFMT) {
9034 case 0: case S_IFREG:
9035 error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
9036 @@ -1854,6 +1927,10 @@ asmlinkage long sys_mknodat(int dfd, con
9042 + gr_handle_create(dentry, nd.mnt);
9046 mutex_unlock(&nd.dentry->d_inode->i_mutex);
9047 @@ -1908,10 +1985,19 @@ asmlinkage long sys_mkdirat(int dfd, con
9048 dentry = lookup_create(&nd, 1);
9049 error = PTR_ERR(dentry);
9050 if (!IS_ERR(dentry)) {
9052 if (!IS_POSIXACL(nd.dentry->d_inode))
9053 mode &= ~current->fs->umask;
9054 - error = vfs_mkdir(nd.dentry->d_inode, dentry,
9057 + if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
9061 + error = vfs_mkdir(nd.dentry->d_inode, dentry,
9064 + gr_handle_create(dentry, nd.mnt);
9068 mutex_unlock(&nd.dentry->d_inode->i_mutex);
9069 @@ -1994,6 +2081,8 @@ static long do_rmdir(int dfd, const char
9071 struct dentry *dentry;
9072 struct nameidata nd;
9073 + ino_t saved_ino = 0;
9074 + dev_t saved_dev = 0;
9076 name = getname(pathname);
9078 @@ -2018,7 +2107,21 @@ static long do_rmdir(int dfd, const char
9079 dentry = lookup_hash(&nd);
9080 error = PTR_ERR(dentry);
9081 if (!IS_ERR(dentry)) {
9082 - error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
9084 + if (dentry->d_inode) {
9085 + if (dentry->d_inode->i_nlink <= 1) {
9086 + saved_ino = dentry->d_inode->i_ino;
9087 + saved_dev = dentry->d_inode->i_sb->s_dev;
9090 + if (!gr_acl_handle_rmdir(dentry, nd.mnt))
9095 + error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
9096 + if (!error && (saved_dev || saved_ino))
9097 + gr_handle_delete(saved_ino, saved_dev);
9100 mutex_unlock(&nd.dentry->d_inode->i_mutex);
9101 @@ -2077,6 +2180,8 @@ static long do_unlinkat(int dfd, const c
9102 struct dentry *dentry;
9103 struct nameidata nd;
9104 struct inode *inode = NULL;
9105 + ino_t saved_ino = 0;
9106 + dev_t saved_dev = 0;
9108 name = getname(pathname);
9110 @@ -2092,13 +2197,26 @@ static long do_unlinkat(int dfd, const c
9111 dentry = lookup_hash(&nd);
9112 error = PTR_ERR(dentry);
9113 if (!IS_ERR(dentry)) {
9115 /* Why not before? Because we want correct error value */
9116 if (nd.last.name[nd.last.len])
9118 inode = dentry->d_inode;
9121 + if (inode->i_nlink <= 1) {
9122 + saved_ino = inode->i_ino;
9123 + saved_dev = inode->i_sb->s_dev;
9126 + if (!gr_acl_handle_unlink(dentry, nd.mnt))
9129 atomic_inc(&inode->i_count);
9130 - error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
9133 + error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
9134 + if (!error && (saved_ino || saved_dev))
9135 + gr_handle_delete(saved_ino, saved_dev);
9139 @@ -2176,8 +2294,15 @@ asmlinkage long sys_symlinkat(const char
9140 dentry = lookup_create(&nd, 0);
9141 error = PTR_ERR(dentry);
9142 if (!IS_ERR(dentry)) {
9143 - error = vfs_symlink(nd.dentry->d_inode, dentry,
9144 - from, S_IALLUGO, &nd);
9146 + if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
9150 + error = vfs_symlink(nd.dentry->d_inode, dentry,
9151 + from, S_IALLUGO, &nd);
9153 + gr_handle_create(dentry, nd.mnt);
9156 mutex_unlock(&nd.dentry->d_inode->i_mutex);
9157 @@ -2268,8 +2394,20 @@ asmlinkage long sys_linkat(int olddfd, c
9158 new_dentry = lookup_create(&nd, 0);
9159 error = PTR_ERR(new_dentry);
9160 if (!IS_ERR(new_dentry)) {
9161 - error = vfs_link(old_nd.dentry, nd.dentry->d_inode,
9164 + if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
9165 + old_nd.dentry->d_inode,
9166 + old_nd.dentry->d_inode->i_mode, to))
9168 + if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
9169 + old_nd.dentry, old_nd.mnt, to))
9172 + error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry,
9175 + gr_handle_create(new_dentry, nd.mnt);
9179 mutex_unlock(&nd.dentry->d_inode->i_mutex);
9180 @@ -2494,8 +2633,16 @@ static int do_rename(int olddfd, const c
9181 if (new_dentry == trap)
9184 - error = vfs_rename(old_dir->d_inode, old_dentry,
9185 + error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
9186 + old_dentry, old_dir->d_inode, oldnd.mnt,
9190 + error = vfs_rename(old_dir->d_inode, old_dentry,
9191 new_dir->d_inode, new_dentry);
9193 + gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry,
9194 + new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
9198 diff -urNp linux-2.6.17.7/fs/namespace.c linux-2.6.17.7/fs/namespace.c
9199 --- linux-2.6.17.7/fs/namespace.c 2006-07-24 23:36:01.000000000 -0400
9200 +++ linux-2.6.17.7/fs/namespace.c 2006-08-01 20:29:46.000000000 -0400
9202 #include <linux/mount.h>
9203 #include <linux/vserver/namespace.h>
9204 #include <linux/vserver/tag.h>
9205 +#include <linux/sched.h>
9206 +#include <linux/grsecurity.h>
9207 #include <asm/uaccess.h>
9208 #include <asm/unistd.h>
9210 @@ -600,6 +602,8 @@ static int do_umount(struct vfsmount *mn
9212 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
9215 + gr_log_remount(mnt->mnt_devname, retval);
9217 up_write(&sb->s_umount);
9219 @@ -620,6 +624,9 @@ static int do_umount(struct vfsmount *mn
9220 security_sb_umount_busy(mnt);
9221 up_write(&namespace_sem);
9222 release_mounts(&umount_list);
9224 + gr_log_unmount(mnt->mnt_devname, retval);
9229 @@ -1346,6 +1353,11 @@ long do_mount(char *dev_name, char *dir_
9233 + if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
9238 if (flags & MS_REMOUNT)
9239 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
9241 @@ -1360,6 +1372,9 @@ long do_mount(char *dev_name, char *dir_
9242 dev_name, data_page);
9246 + gr_log_mount(dev_name, dir_name, retval);
9251 @@ -1612,6 +1627,9 @@ asmlinkage long sys_pivot_root(const cha
9252 if (!capable(CAP_SYS_ADMIN))
9255 + if (gr_handle_chroot_pivot())
9260 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
9261 diff -urNp linux-2.6.17.7/fs/open.c linux-2.6.17.7/fs/open.c
9262 --- linux-2.6.17.7/fs/open.c 2006-07-24 23:36:01.000000000 -0400
9263 +++ linux-2.6.17.7/fs/open.c 2006-08-01 20:29:46.000000000 -0400
9265 #include <linux/vs_limit.h>
9266 #include <linux/vs_dlimit.h>
9267 #include <linux/vserver/tag.h>
9268 +#include <linux/grsecurity.h>
9270 #include <asm/unistd.h>
9272 @@ -207,6 +208,9 @@ int do_truncate(struct dentry *dentry, l
9276 + if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
9279 newattrs.ia_size = length;
9280 newattrs.ia_valid = ATTR_SIZE | time_attrs;
9282 @@ -407,6 +411,12 @@ asmlinkage long sys_utime(char __user *
9283 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
9287 + if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
9289 + goto dput_and_out;
9292 mutex_lock(&inode->i_mutex);
9293 error = notify_change(nd.dentry, &newattrs);
9294 mutex_unlock(&inode->i_mutex);
9295 @@ -460,6 +470,12 @@ long do_utimes(int dfd, char __user *fil
9296 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
9300 + if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
9302 + goto dput_and_out;
9305 mutex_lock(&inode->i_mutex);
9306 error = notify_change(nd.dentry, &newattrs);
9307 mutex_unlock(&inode->i_mutex);
9308 @@ -526,6 +542,10 @@ asmlinkage long sys_faccessat(int dfd, c
9309 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
9310 && !special_file(nd.dentry->d_inode->i_mode))
9313 + if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
9319 @@ -554,6 +574,8 @@ asmlinkage long sys_chdir(const char __u
9323 + gr_log_chdir(nd.dentry, nd.mnt);
9325 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
9328 @@ -584,6 +606,13 @@ asmlinkage long sys_fchdir(unsigned int
9331 error = file_permission(file, MAY_EXEC);
9333 + if (!error && !gr_chroot_fchdir(dentry, mnt))
9337 + gr_log_chdir(dentry, mnt);
9340 set_fs_pwd(current->fs, mnt, dentry);
9342 @@ -609,8 +638,16 @@ asmlinkage long sys_chroot(const char __
9343 if (!capable(CAP_SYS_CHROOT))
9346 + if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
9347 + goto dput_and_out;
9349 set_fs_root(current->fs, nd.mnt, nd.dentry);
9352 + gr_handle_chroot_caps(current);
9354 + gr_handle_chroot_chdir(nd.dentry, nd.mnt);
9359 @@ -641,9 +678,22 @@ asmlinkage long sys_fchmod(unsigned int
9361 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9364 + if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
9369 mutex_lock(&inode->i_mutex);
9370 if (mode == (mode_t) -1)
9371 mode = inode->i_mode;
9373 + if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
9375 + mutex_unlock(&inode->i_mutex);
9379 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
9380 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
9381 err = notify_change(dentry, &newattrs);
9382 @@ -676,9 +726,21 @@ asmlinkage long sys_fchmodat(int dfd, co
9383 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9386 + if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
9388 + goto dput_and_out;
9391 mutex_lock(&inode->i_mutex);
9392 if (mode == (mode_t) -1)
9393 mode = inode->i_mode;
9395 + if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
9397 + mutex_unlock(&inode->i_mutex);
9398 + goto dput_and_out;
9401 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
9402 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
9403 error = notify_change(nd.dentry, &newattrs);
9404 @@ -712,6 +774,12 @@ static int chown_common(struct dentry *
9406 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9409 + if (!gr_acl_handle_chown(dentry, mnt)) {
9414 newattrs.ia_valid = ATTR_CTIME;
9415 if (user != (uid_t) -1) {
9416 newattrs.ia_valid |= ATTR_UID;
9417 @@ -995,6 +1063,7 @@ repeat:
9418 * N.B. For clone tasks sharing a files structure, this test
9419 * will limit the total number of files that can be opened.
9421 + gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
9422 if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
9425 diff -urNp linux-2.6.17.7/fs/pipe.c linux-2.6.17.7/fs/pipe.c
9426 --- linux-2.6.17.7/fs/pipe.c 2006-07-24 23:36:01.000000000 -0400
9427 +++ linux-2.6.17.7/fs/pipe.c 2006-08-01 20:29:46.000000000 -0400
9428 @@ -842,7 +842,7 @@ void free_pipe_info(struct inode *inode)
9429 inode->i_pipe = NULL;
9432 -static struct vfsmount *pipe_mnt __read_mostly;
9433 +struct vfsmount *pipe_mnt __read_mostly;
9434 static int pipefs_delete_dentry(struct dentry *dentry)
9437 diff -urNp linux-2.6.17.7/fs/proc/array.c linux-2.6.17.7/fs/proc/array.c
9438 --- linux-2.6.17.7/fs/proc/array.c 2006-07-24 23:36:01.000000000 -0400
9439 +++ linux-2.6.17.7/fs/proc/array.c 2006-08-01 20:29:46.000000000 -0400
9440 @@ -293,6 +293,21 @@ static inline char *task_cap(struct task
9441 cap_t(p->cap_effective));
9444 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9445 +static inline char *task_pax(struct task_struct *p, char *buffer)
9448 + return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
9449 + p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
9450 + p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
9451 + p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
9452 + p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
9453 + p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
9455 + return buffer + sprintf(buffer, "PaX:\t-----\n");
9459 int proc_pid_status(struct task_struct *task, char * buffer)
9461 char * orig = buffer;
9462 @@ -311,9 +326,20 @@ int proc_pid_status(struct task_struct *
9463 #if defined(CONFIG_S390)
9464 buffer = task_show_regs(task, buffer);
9467 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9468 + buffer = task_pax(task, buffer);
9471 return buffer - orig;
9474 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9475 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
9476 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
9477 + _mm->pax_flags & MF_PAX_SEGMEXEC))
9480 static int do_task_stat(struct task_struct *task, char * buffer, int whole)
9482 unsigned long vsize, eip, esp, wchan = ~0UL;
9483 @@ -398,6 +424,19 @@ static int do_task_stat(struct task_stru
9484 stime = task->stime;
9487 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9488 + if (PAX_RAND_FLAGS(mm)) {
9494 +#ifdef CONFIG_GRKERNSEC_HIDESYM
9500 /* scale priority and nice values from timeslices to -20..20 */
9501 /* to make it look like a "normal" Unix priority/nice value */
9502 priority = task_prio(task);
9503 @@ -437,9 +476,15 @@ static int do_task_stat(struct task_stru
9505 mm ? get_mm_rss(mm) : 0,
9507 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9508 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
9509 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
9510 + PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
9512 mm ? mm->start_code : 0,
9513 mm ? mm->end_code : 0,
9514 mm ? mm->start_stack : 0,
9518 /* The signal information here is obsolete.
9519 @@ -485,3 +530,14 @@ int proc_pid_statm(struct task_struct *t
9520 return sprintf(buffer,"%d %d %d %d %d %d %d\n",
9521 size, resident, shared, text, lib, data, 0);
9524 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9525 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
9529 + len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
9534 diff -urNp linux-2.6.17.7/fs/proc/base.c linux-2.6.17.7/fs/proc/base.c
9535 --- linux-2.6.17.7/fs/proc/base.c 2006-07-24 23:36:01.000000000 -0400
9536 +++ linux-2.6.17.7/fs/proc/base.c 2006-08-01 20:29:46.000000000 -0400
9538 #include <linux/poll.h>
9539 #include <linux/vs_network.h>
9540 #include <linux/vs_pid.h>
9541 +#include <linux/grsecurity.h>
9542 #include "internal.h"
9545 @@ -125,6 +126,9 @@ enum pid_directory_inos {
9546 #ifdef CONFIG_AUDITSYSCALL
9549 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9552 PROC_TGID_OOM_SCORE,
9553 PROC_TGID_OOM_ADJUST,
9555 @@ -204,6 +208,9 @@ static struct pid_entry tgid_base_stuff[
9556 E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
9557 E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
9558 E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
9559 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9560 + E(PROC_TGID_IPADDR, "ipaddr", S_IFREG|S_IRUSR),
9563 E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO),
9565 @@ -410,7 +417,7 @@ static int proc_task_root_link(struct in
9566 (task->parent == current && \
9567 (task->ptrace & PT_PTRACED) && \
9568 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
9569 - security_ptrace(current,task) == 0))
9570 + security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
9572 static int proc_pid_environ(struct task_struct *task, char * buffer)
9574 @@ -591,9 +598,25 @@ static int proc_check_root(struct inode
9576 static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
9578 + int ret = -EACCES;
9579 + struct task_struct *task;
9581 if (generic_permission(inode, mask, NULL) != 0)
9583 - return proc_check_root(inode);
9586 + ret = proc_check_root(inode);
9590 + task = proc_task(inode);
9595 + ret = gr_acl_handle_procpidmem(task);
9601 static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd)
9602 @@ -1372,6 +1395,9 @@ static struct inode *proc_pid_make_inode
9604 /* procfs is xid tagged */
9605 inode->i_tag = (tag_t)vx_task_xid(task);
9606 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9607 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
9609 security_task_to_inode(task, inode);
9612 @@ -1400,7 +1426,9 @@ static int pid_revalidate(struct dentry
9613 if (pid_alive(task)) {
9614 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
9615 inode->i_uid = task->euid;
9616 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
9617 inode->i_gid = task->egid;
9622 @@ -1730,6 +1758,12 @@ static struct dentry *proc_pident_lookup
9623 inode->i_fop = &proc_info_file_operations;
9624 ei->op.proc_read = proc_pid_status;
9626 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9627 + case PROC_TGID_IPADDR:
9628 + inode->i_fop = &proc_info_file_operations;
9629 + ei->op.proc_read = proc_pid_ipaddr;
9633 inode->i_fop = &proc_info_file_operations;
9634 ei->op.proc_read = proc_tid_stat;
9635 @@ -2140,11 +2173,34 @@ struct dentry *proc_pid_lookup(struct in
9636 if (!proc_pid_visible(task, tgid))
9639 + if (gr_check_hidden_task(task)) {
9640 + put_task_struct(task);
9644 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9645 + if (current->uid && (task->uid != current->uid)
9646 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9647 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
9650 + put_task_struct(task);
9655 inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
9659 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9660 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
9661 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9662 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
9663 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
9665 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
9667 inode->i_op = &proc_tgid_base_inode_operations;
9668 inode->i_fop = &proc_tgid_base_operations;
9669 inode->i_flags|=S_IMMUTABLE;
9670 @@ -2137,6 +2195,9 @@ out:
9671 static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
9673 struct task_struct *p;
9674 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9675 + struct task_struct *tmp = current;
9680 @@ -2157,6 +2218,18 @@ static int get_tgid_list(int index, unsi
9684 + if (gr_pid_is_chrooted(p))
9686 + if (gr_check_hidden_task(p))
9688 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9689 + if (tmp->uid && (p->uid != tmp->uid)
9690 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9691 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
9698 tgids[nr_tgids] = tgid;
9699 diff -urNp linux-2.6.17.7/fs/proc/inode.c linux-2.6.17.7/fs/proc/inode.c
9700 --- linux-2.6.17.7/fs/proc/inode.c 2006-07-24 23:36:01.000000000 -0400
9701 +++ linux-2.6.17.7/fs/proc/inode.c 2006-08-01 20:29:46.000000000 -0400
9702 @@ -169,7 +169,11 @@ struct inode *proc_get_inode(struct supe
9704 inode->i_mode = de->mode;
9705 inode->i_uid = de->uid;
9706 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9707 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
9709 inode->i_gid = de->gid;
9713 inode->i_size = de->size;
9714 diff -urNp linux-2.6.17.7/fs/proc/internal.h linux-2.6.17.7/fs/proc/internal.h
9715 --- linux-2.6.17.7/fs/proc/internal.h 2006-07-24 23:36:01.000000000 -0400
9716 +++ linux-2.6.17.7/fs/proc/internal.h 2006-08-01 20:29:46.000000000 -0400
9717 @@ -36,6 +36,9 @@ extern int proc_tid_stat(struct task_str
9718 extern int proc_tgid_stat(struct task_struct *, char *);
9719 extern int proc_pid_status(struct task_struct *, char *);
9720 extern int proc_pid_statm(struct task_struct *, char *);
9721 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9722 +extern int proc_pid_ipaddr(struct task_struct*,char*);
9725 void free_proc_entry(struct proc_dir_entry *de);
9727 diff -urNp linux-2.6.17.7/fs/proc/proc_misc.c linux-2.6.17.7/fs/proc/proc_misc.c
9728 --- linux-2.6.17.7/fs/proc/proc_misc.c 2006-07-24 23:36:01.000000000 -0400
9729 +++ linux-2.6.17.7/fs/proc/proc_misc.c 2006-08-01 20:29:46.000000000 -0400
9730 @@ -651,6 +651,8 @@ void create_seq_entry(char *name, mode_t
9731 void __init proc_misc_init(void)
9733 struct proc_dir_entry *entry;
9738 int (*read_proc)(char*,char**,off_t,int,int*,void*);
9739 @@ -666,7 +668,9 @@ void __init proc_misc_init(void)
9740 {"stram", stram_read_proc},
9742 {"filesystems", filesystems_read_proc},
9743 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
9744 {"cmdline", cmdline_read_proc},
9746 {"locks", locks_read_proc},
9747 {"execdomains", execdomains_read_proc},
9749 @@ -674,19 +678,36 @@ void __init proc_misc_init(void)
9750 for (p = simple_ones; p->name; p++)
9751 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
9753 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9754 + gr_mode = S_IRUSR;
9755 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9756 + gr_mode = S_IRUSR | S_IRGRP;
9758 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9759 + create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
9762 proc_symlink("mounts", NULL, "self/mounts");
9764 /* And now for trickier ones */
9765 entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
9767 entry->proc_fops = &proc_kmsg_operations;
9768 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9769 + create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
9771 create_seq_entry("devices", 0, &proc_devinfo_operations);
9773 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
9774 create_seq_entry("partitions", 0, &proc_partitions_operations);
9775 create_seq_entry("stat", 0, &proc_stat_operations);
9776 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
9778 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9779 + create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
9781 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
9783 #ifdef CONFIG_DEBUG_SLAB_LEAK
9784 create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
9786 @@ -701,7 +722,7 @@ void __init proc_misc_init(void)
9787 #ifdef CONFIG_SCHEDSTATS
9788 create_seq_entry("schedstat", 0, &proc_schedstat_operations);
9790 -#ifdef CONFIG_PROC_KCORE
9791 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
9792 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
9793 if (proc_root_kcore) {
9794 proc_root_kcore->proc_fops = &proc_kcore_operations;
9795 diff -urNp linux-2.6.17.7/fs/proc/root.c linux-2.6.17.7/fs/proc/root.c
9796 --- linux-2.6.17.7/fs/proc/root.c 2006-07-24 23:36:01.000000000 -0400
9797 +++ linux-2.6.17.7/fs/proc/root.c 2006-08-01 20:29:46.000000000 -0400
9798 @@ -53,7 +53,13 @@ void __init proc_root_init(void)
9802 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9803 + proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
9804 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9805 + proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
9807 proc_net = proc_mkdir("net", NULL);
9809 proc_net_stat = proc_mkdir("net/stat", NULL);
9811 #ifdef CONFIG_SYSVIPC
9812 @@ -77,7 +83,15 @@ void __init proc_root_init(void)
9813 #ifdef CONFIG_PROC_DEVICETREE
9814 proc_device_tree_init();
9816 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9817 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9818 + proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
9819 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9820 + proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
9823 proc_bus = proc_mkdir("bus", NULL);
9828 diff -urNp linux-2.6.17.7/fs/proc/task_mmu.c linux-2.6.17.7/fs/proc/task_mmu.c
9829 --- linux-2.6.17.7/fs/proc/task_mmu.c 2006-07-24 23:36:01.000000000 -0400
9830 +++ linux-2.6.17.7/fs/proc/task_mmu.c 2006-08-01 20:29:46.000000000 -0400
9831 @@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
9835 - "VmPTE:\t%8lu kB\n",
9836 - hiwater_vm << (PAGE_SHIFT-10),
9837 + "VmPTE:\t%8lu kB\n"
9839 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
9840 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
9843 + ,hiwater_vm << (PAGE_SHIFT-10),
9844 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
9845 mm->locked_vm << (PAGE_SHIFT-10),
9846 hiwater_rss << (PAGE_SHIFT-10),
9847 total_rss << (PAGE_SHIFT-10),
9848 data << (PAGE_SHIFT-10),
9849 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
9850 - (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
9851 + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
9853 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
9854 + , mm->context.user_cs_base, mm->context.user_cs_limit
9862 @@ -118,6 +130,12 @@ struct mem_size_stats
9863 unsigned long private_dirty;
9866 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9867 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
9868 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
9869 + _mm->pax_flags & MF_PAX_SEGMEXEC))
9872 static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
9874 struct task_struct *task = m->private;
9875 @@ -136,13 +154,30 @@ static int show_map_internal(struct seq_
9878 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
9879 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9880 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
9881 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
9888 + flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
9889 + flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
9890 + flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
9892 flags & VM_READ ? 'r' : '-',
9893 flags & VM_WRITE ? 'w' : '-',
9894 flags & VM_EXEC ? 'x' : '-',
9897 flags & VM_MAYSHARE ? 's' : 'p',
9898 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9899 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
9901 vma->vm_pgoff << PAGE_SHIFT,
9903 MAJOR(dev), MINOR(dev), ino, &len);
9906 @@ -154,13 +189,13 @@ static int show_map_internal(struct seq_
9907 seq_path(m, file->f_vfsmnt, file->f_dentry, "\n");
9910 - if (vma->vm_start <= mm->start_brk &&
9911 - vma->vm_end >= mm->brk) {
9912 + if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
9913 pad_len_spaces(m, len);
9914 seq_puts(m, "[heap]");
9916 - if (vma->vm_start <= mm->start_stack &&
9917 - vma->vm_end >= mm->start_stack) {
9918 + if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
9919 + (vma->vm_start <= mm->start_stack &&
9920 + vma->vm_end >= mm->start_stack)) {
9922 pad_len_spaces(m, len);
9923 seq_puts(m, "[stack]");
9924 @@ -173,7 +208,25 @@ static int show_map_internal(struct seq_
9931 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9932 + if (PAX_RAND_FLAGS(mm))
9936 + "Shared_Clean: %8lu kB\n"
9937 + "Shared_Dirty: %8lu kB\n"
9938 + "Private_Clean: %8lu kB\n"
9939 + "Private_Dirty: %8lu kB\n",
9951 @@ -187,6 +240,7 @@ static int show_map_internal(struct seq_
9952 mss->shared_dirty >> 10,
9953 mss->private_clean >> 10,
9954 mss->private_dirty >> 10);
9957 if (m->count < m->size) /* vma is copied successfully */
9958 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
9959 diff -urNp linux-2.6.17.7/fs/readdir.c linux-2.6.17.7/fs/readdir.c
9960 --- linux-2.6.17.7/fs/readdir.c 2006-07-24 23:36:01.000000000 -0400
9961 +++ linux-2.6.17.7/fs/readdir.c 2006-08-01 20:29:46.000000000 -0400
9963 #include <linux/security.h>
9964 #include <linux/syscalls.h>
9965 #include <linux/unistd.h>
9966 +#include <linux/namei.h>
9967 +#include <linux/grsecurity.h>
9969 #include <asm/uaccess.h>
9971 @@ -65,6 +67,7 @@ struct old_linux_dirent {
9973 struct readdir_callback {
9974 struct old_linux_dirent __user * dirent;
9975 + struct file * file;
9979 @@ -76,6 +79,10 @@ static int fillonedir(void * __buf, cons
9984 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
9988 dirent = buf->dirent;
9989 if (!access_ok(VERIFY_WRITE, dirent,
9990 @@ -107,6 +114,7 @@ asmlinkage long old_readdir(unsigned int
9993 buf.dirent = dirent;
9996 error = vfs_readdir(file, fillonedir, &buf);
9998 @@ -133,6 +141,7 @@ struct linux_dirent {
9999 struct getdents_callback {
10000 struct linux_dirent __user * current_dir;
10001 struct linux_dirent __user * previous;
10002 + struct file * file;
10006 @@ -147,6 +156,10 @@ static int filldir(void * __buf, const c
10007 buf->error = -EINVAL; /* only used if we fail.. */
10008 if (reclen > buf->count)
10011 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
10014 dirent = buf->previous;
10016 if (__put_user(offset, &dirent->d_off))
10017 @@ -191,6 +204,7 @@ asmlinkage long sys_getdents(unsigned in
10019 buf.current_dir = dirent;
10020 buf.previous = NULL;
10025 @@ -217,6 +231,7 @@ out:
10026 struct getdents_callback64 {
10027 struct linux_dirent64 __user * current_dir;
10028 struct linux_dirent64 __user * previous;
10029 + struct file * file;
10033 @@ -231,6 +246,10 @@ static int filldir64(void * __buf, const
10034 buf->error = -EINVAL; /* only used if we fail.. */
10035 if (reclen > buf->count)
10038 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
10041 dirent = buf->previous;
10043 if (__put_user(offset, &dirent->d_off))
10044 @@ -277,6 +296,7 @@ asmlinkage long sys_getdents64(unsigned
10046 buf.current_dir = dirent;
10047 buf.previous = NULL;
10052 diff -urNp linux-2.6.17.7/fs/xfs/linux-2.6/xfs_file.c linux-2.6.17.7/fs/xfs/linux-2.6/xfs_file.c
10053 --- linux-2.6.17.7/fs/xfs/linux-2.6/xfs_file.c 2006-07-24 23:36:01.000000000 -0400
10054 +++ linux-2.6.17.7/fs/xfs/linux-2.6/xfs_file.c 2006-08-01 20:29:46.000000000 -0400
10055 @@ -461,6 +461,11 @@ xfs_file_mmap(
10059 +#ifdef CONFIG_PAX_PAGEEXEC
10060 + if (vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC)
10061 + vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
10064 vma->vm_ops = &xfs_file_vm_ops;
10066 #ifdef CONFIG_XFS_DMAPI
10067 diff -urNp linux-2.6.17.7/grsecurity/Kconfig linux-2.6.17.7/grsecurity/Kconfig
10068 --- linux-2.6.17.7/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
10069 +++ linux-2.6.17.7/grsecurity/Kconfig 2006-08-01 20:29:47.000000000 -0400
10072 +# grecurity configuration
10078 + bool "Grsecurity"
10080 + select CRYPTO_SHA256
10082 + If you say Y here, you will be able to configure many features
10083 + that will enhance the security of your system. It is highly
10084 + recommended that you say Y here and read through the help
10085 + for each option so that you fully understand the features and
10086 + can evaluate their usefulness for your machine.
10089 + prompt "Security Level"
10090 + depends GRKERNSEC
10091 + default GRKERNSEC_CUSTOM
10093 +config GRKERNSEC_LOW
10095 + select GRKERNSEC_LINK
10096 + select GRKERNSEC_FIFO
10097 + select GRKERNSEC_RANDPID
10098 + select GRKERNSEC_EXECVE
10099 + select GRKERNSEC_RANDNET
10100 + select GRKERNSEC_DMESG
10101 + select GRKERNSEC_CHROOT_CHDIR
10102 + select GRKERNSEC_MODSTOP if (MODULES)
10105 + If you choose this option, several of the grsecurity options will
10106 + be enabled that will give you greater protection against a number
10107 + of attacks, while assuring that none of your software will have any
10108 + conflicts with the additional security measures. If you run a lot
10109 + of unusual software, or you are having problems with the higher
10110 + security levels, you should say Y here. With this option, the
10111 + following features are enabled:
10113 + - Linking restrictions
10114 + - FIFO restrictions
10115 + - Randomized PIDs
10116 + - Enforcing RLIMIT_NPROC on execve
10117 + - Restricted dmesg
10118 + - Enforced chdir("/") on chroot
10119 + - Runtime module disabling
10121 +config GRKERNSEC_MEDIUM
10124 + select PAX_EI_PAX
10125 + select PAX_PT_PAX_FLAGS
10126 + select PAX_HAVE_ACL_FLAGS
10127 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
10128 + select GRKERNSEC_CHROOT_SYSCTL
10129 + select GRKERNSEC_LINK
10130 + select GRKERNSEC_FIFO
10131 + select GRKERNSEC_RANDPID
10132 + select GRKERNSEC_EXECVE
10133 + select GRKERNSEC_DMESG
10134 + select GRKERNSEC_RANDNET
10135 + select GRKERNSEC_FORKFAIL
10136 + select GRKERNSEC_TIME
10137 + select GRKERNSEC_SIGNAL
10138 + select GRKERNSEC_CHROOT
10139 + select GRKERNSEC_CHROOT_UNIX
10140 + select GRKERNSEC_CHROOT_MOUNT
10141 + select GRKERNSEC_CHROOT_PIVOT
10142 + select GRKERNSEC_CHROOT_DOUBLE
10143 + select GRKERNSEC_CHROOT_CHDIR
10144 + select GRKERNSEC_CHROOT_MKNOD
10145 + select GRKERNSEC_PROC
10146 + select GRKERNSEC_PROC_USERGROUP
10147 + select GRKERNSEC_MODSTOP if (MODULES)
10148 + select PAX_RANDUSTACK
10150 + select PAX_RANDMMAP
10151 + select PAX_NOVSYSCALL if (X86 && !X86_64)
10154 + If you say Y here, several features in addition to those included
10155 + in the low additional security level will be enabled. These
10156 + features provide even more security to your system, though in rare
10157 + cases they may be incompatible with very old or poorly written
10158 + software. If you enable this option, make sure that your auth
10159 + service (identd) is running as gid 1001. With this option,
10160 + the following features (in addition to those provided in the
10161 + low additional security level) will be enabled:
10163 + - Randomized TCP source ports
10164 + - Failed fork logging
10165 + - Time change logging
10167 + - Deny mounts in chroot
10168 + - Deny double chrooting
10169 + - Deny sysctl writes in chroot
10170 + - Deny mknod in chroot
10171 + - Deny access to abstract AF_UNIX sockets out of chroot
10172 + - Deny pivot_root in chroot
10173 + - Denied writes of /dev/kmem, /dev/mem, and /dev/port
10174 + - /proc restrictions with special GID set to 10 (usually wheel)
10175 + - Address Space Layout Randomization (ASLR)
10177 +config GRKERNSEC_HIGH
10179 + select GRKERNSEC_LINK
10180 + select GRKERNSEC_FIFO
10181 + select GRKERNSEC_RANDPID
10182 + select GRKERNSEC_EXECVE
10183 + select GRKERNSEC_DMESG
10184 + select GRKERNSEC_FORKFAIL
10185 + select GRKERNSEC_TIME
10186 + select GRKERNSEC_SIGNAL
10187 + select GRKERNSEC_CHROOT_SHMAT
10188 + select GRKERNSEC_CHROOT_UNIX
10189 + select GRKERNSEC_CHROOT_MOUNT
10190 + select GRKERNSEC_CHROOT_FCHDIR
10191 + select GRKERNSEC_CHROOT_PIVOT
10192 + select GRKERNSEC_CHROOT_DOUBLE
10193 + select GRKERNSEC_CHROOT_CHDIR
10194 + select GRKERNSEC_CHROOT_MKNOD
10195 + select GRKERNSEC_CHROOT_CAPS
10196 + select GRKERNSEC_CHROOT_SYSCTL
10197 + select GRKERNSEC_CHROOT_FINDTASK
10198 + select GRKERNSEC_PROC
10199 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
10200 + select GRKERNSEC_HIDESYM
10201 + select GRKERNSEC_BRUTE
10202 + select GRKERNSEC_SHM if (SYSVIPC)
10203 + select GRKERNSEC_PROC_USERGROUP
10204 + select GRKERNSEC_KMEM
10205 + select GRKERNSEC_RESLOG
10206 + select GRKERNSEC_RANDNET
10207 + select GRKERNSEC_PROC_ADD
10208 + select GRKERNSEC_CHROOT_CHMOD
10209 + select GRKERNSEC_CHROOT_NICE
10210 + select GRKERNSEC_AUDIT_MOUNT
10211 + select GRKERNSEC_MODSTOP if (MODULES)
10213 + select PAX_RANDUSTACK
10215 + select PAX_RANDMMAP
10216 + select PAX_NOEXEC
10217 + select PAX_MPROTECT
10218 + select PAX_EI_PAX
10219 + select PAX_PT_PAX_FLAGS
10220 + select PAX_HAVE_ACL_FLAGS
10221 + select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
10222 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
10223 + select PAX_SEGMEXEC if (X86 && !X86_64)
10224 + select PAX_PAGEEXEC if (!X86)
10225 + select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
10226 + select PAX_DLRESOLVE if (SPARC32 || SPARC64)
10227 + select PAX_SYSCALL if (PPC32)
10228 + select PAX_EMUTRAMP if (PARISC)
10229 + select PAX_EMUSIGRT if (PARISC)
10230 + select PAX_NOVSYSCALL if (X86 && !X86_64)
10231 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
10233 + If you say Y here, many of the features of grsecurity will be
10234 + enabled, which will protect you against many kinds of attacks
10235 + against your system. The heightened security comes at a cost
10236 + of an increased chance of incompatibilities with rare software
10237 + on your machine. Since this security level enables PaX, you should
10238 + view <http://pax.grsecurity.net> and read about the PaX
10239 + project. While you are there, download chpax and run it on
10240 + binaries that cause problems with PaX. Also remember that
10241 + since the /proc restrictions are enabled, you must run your
10242 + identd as gid 1001. This security level enables the following
10243 + features in addition to those listed in the low and medium
10246 + - Additional /proc restrictions
10247 + - Chmod restrictions in chroot
10248 + - No signals, ptrace, or viewing of processes outside of chroot
10249 + - Capability restrictions in chroot
10250 + - Deny fchdir out of chroot
10251 + - Priority restrictions in chroot
10252 + - Segmentation-based implementation of PaX
10253 + - Mprotect restrictions
10254 + - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
10255 + - Kernel stack randomization
10256 + - Mount/unmount/remount logging
10257 + - Kernel symbol hiding
10258 + - Destroy unused shared memory
10259 + - Prevention of memory exhaustion-based exploits
10260 +config GRKERNSEC_CUSTOM
10263 + If you say Y here, you will be able to configure every grsecurity
10264 + option, which allows you to enable many more features that aren't
10265 + covered in the basic security levels. These additional features
10266 + include TPE, socket restrictions, and the sysctl system for
10267 + grsecurity. It is advised that you read through the help for
10268 + each option to determine its usefulness in your situation.
10272 +menu "Address Space Protection"
10273 +depends on GRKERNSEC
10275 +config GRKERNSEC_KMEM
10276 + bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
10278 + If you say Y here, /dev/kmem and /dev/mem won't be allowed to
10279 + be written to via mmap or otherwise to modify the running kernel.
10280 + /dev/port will also not be allowed to be opened. If you have module
10281 + support disabled, enabling this will close up four ways that are
10282 + currently used to insert malicious code into the running kernel.
10283 + Even with all these features enabled, we still highly recommend that
10284 + you use the RBAC system, as it is still possible for an attacker to
10285 + modify the running kernel through privileged I/O granted by ioperm/iopl.
10286 + If you are not using XFree86, you may be able to stop this additional
10287 + case by enabling the 'Disable privileged I/O' option. Though nothing
10288 + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
10289 + but only to video memory, which is the only writing we allow in this
10290 + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
10291 + not be allowed to mprotect it with PROT_WRITE later.
10292 + It is highly recommended that you say Y here if you meet all the
10293 + conditions above.
10295 +config GRKERNSEC_IO
10296 + bool "Disable privileged I/O"
10300 + If you say Y here, all ioperm and iopl calls will return an error.
10301 + Ioperm and iopl can be used to modify the running kernel.
10302 + Unfortunately, some programs need this access to operate properly,
10303 + the most notable of which are XFree86 and hwclock. hwclock can be
10304 + remedied by having RTC support in the kernel, so CONFIG_RTC is
10305 + enabled if this option is enabled, to ensure that hwclock operates
10306 + correctly. XFree86 still will not operate correctly with this option
10307 + enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
10308 + and you still want to protect your kernel against modification,
10309 + use the RBAC system.
10311 +config GRKERNSEC_PROC_MEMMAP
10312 + bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
10313 + depends on PAX_NOEXEC || PAX_ASLR
10315 + If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
10316 + give no information about the addresses of its mappings if
10317 + PaX features that rely on random addresses are enabled on the task.
10318 + If you use PaX it is greatly recommended that you say Y here as it
10319 + closes up a hole that makes the full ASLR useless for suid
10322 +config GRKERNSEC_BRUTE
10323 + bool "Deter exploit bruteforcing"
10325 + If you say Y here, attempts to bruteforce exploits against forking
10326 + daemons such as apache or sshd will be deterred. When a child of a
10327 + forking daemon is killed by PaX or crashes due to an illegal
10328 + instruction, the parent process will be delayed 30 seconds upon every
10329 + subsequent fork until the administrator is able to assess the
10330 + situation and restart the daemon. It is recommended that you also
10331 + enable signal logging in the auditing section so that logs are
10332 + generated when a process performs an illegal instruction.
10334 +config GRKERNSEC_MODSTOP
10335 + bool "Runtime module disabling"
10336 + depends on MODULES
10338 + If you say Y here, you will be able to disable the ability to (un)load
10339 + modules at runtime. This feature is useful if you need the ability
10340 + to load kernel modules at boot time, but do not want to allow an
10341 + attacker to load a rootkit kernel module into the system, or to remove
10342 + a loaded kernel module important to system functioning. You should
10343 + enable the /dev/mem protection feature as well, since rootkits can be
10344 + inserted into the kernel via other methods than kernel modules. Since
10345 + an untrusted module could still be loaded by modifying init scripts and
10346 + rebooting the system, it is also recommended that you enable the RBAC
10347 + system. If you enable this option, a sysctl option with name
10348 + "disable_modules" will be created. Setting this option to "1" disables
10349 + module loading. After this option is set, no further writes to it are
10350 + allowed until the system is rebooted.
10352 +config GRKERNSEC_HIDESYM
10353 + bool "Hide kernel symbols"
10355 + If you say Y here, getting information on loaded modules, and
10356 + displaying all kernel symbols through a syscall will be restricted
10357 + to users with CAP_SYS_MODULE. This option is only effective
10358 + provided the following conditions are met:
10359 + 1) The kernel using grsecurity is not precompiled by some distribution
10360 + 2) You are using the RBAC system and hiding other files such as your
10361 + kernel image and System.map
10362 + 3) You have the additional /proc restrictions enabled, which removes
10364 + If the above conditions are met, this option will aid to provide a
10365 + useful protection against local and remote kernel exploitation of
10366 + overflows and arbitrary read/write vulnerabilities.
10369 +menu "Role Based Access Control Options"
10370 +depends on GRKERNSEC
10372 +config GRKERNSEC_ACL_HIDEKERN
10373 + bool "Hide kernel processes"
10375 + If you say Y here, all kernel threads will be hidden to all
10376 + processes but those whose subject has the "view hidden processes"
10379 +config GRKERNSEC_ACL_MAXTRIES
10380 + int "Maximum tries before password lockout"
10383 + This option enforces the maximum number of times a user can attempt
10384 + to authorize themselves with the grsecurity RBAC system before being
10385 + denied the ability to attempt authorization again for a specified time.
10386 + The lower the number, the harder it will be to brute-force a password.
10388 +config GRKERNSEC_ACL_TIMEOUT
10389 + int "Time to wait after max password tries, in seconds"
10392 + This option specifies the time the user must wait after attempting to
10393 + authorize to the RBAC system with the maximum number of invalid
10394 + passwords. The higher the number, the harder it will be to brute-force
10398 +menu "Filesystem Protections"
10399 +depends on GRKERNSEC
10401 +config GRKERNSEC_PROC
10402 + bool "Proc restrictions"
10404 + If you say Y here, the permissions of the /proc filesystem
10405 + will be altered to enhance system security and privacy. You MUST
10406 + choose either a user only restriction or a user and group restriction.
10407 + Depending upon the option you choose, you can either restrict users to
10408 + see only the processes they themselves run, or choose a group that can
10409 + view all processes and files normally restricted to root if you choose
10410 + the "restrict to user only" option. NOTE: If you're running identd as
10411 + a non-root user, you will have to run it as the group you specify here.
10413 +config GRKERNSEC_PROC_USER
10414 + bool "Restrict /proc to user only"
10415 + depends on GRKERNSEC_PROC
10417 + If you say Y here, non-root users will only be able to view their own
10418 + processes, and restricts them from viewing network-related information,
10419 + and viewing kernel symbol and module information.
10421 +config GRKERNSEC_PROC_USERGROUP
10422 + bool "Allow special group"
10423 + depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
10425 + If you say Y here, you will be able to select a group that will be
10426 + able to view all processes, network-related information, and
10427 + kernel and symbol information. This option is useful if you want
10428 + to run identd as a non-root user.
10430 +config GRKERNSEC_PROC_GID
10431 + int "GID for special group"
10432 + depends on GRKERNSEC_PROC_USERGROUP
10435 +config GRKERNSEC_PROC_ADD
10436 + bool "Additional restrictions"
10437 + depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
10439 + If you say Y here, additional restrictions will be placed on
10440 + /proc that keep normal users from viewing device information and
10441 + slabinfo information that could be useful for exploits.
10443 +config GRKERNSEC_LINK
10444 + bool "Linking restrictions"
10446 + If you say Y here, /tmp race exploits will be prevented, since users
10447 + will no longer be able to follow symlinks owned by other users in
10448 + world-writable +t directories (i.e. /tmp), unless the owner of the
10449 + symlink is the owner of the directory. users will also not be
10450 + able to hardlink to files they do not own. If the sysctl option is
10451 + enabled, a sysctl option with name "linking_restrictions" is created.
10453 +config GRKERNSEC_FIFO
10454 + bool "FIFO restrictions"
10456 + If you say Y here, users will not be able to write to FIFOs they don't
10457 + own in world-writable +t directories (i.e. /tmp), unless the owner of
10458 + the FIFO is the same owner of the directory it's held in. If the sysctl
10459 + option is enabled, a sysctl option with name "fifo_restrictions" is
10462 +config GRKERNSEC_CHROOT
10463 + bool "Chroot jail restrictions"
10465 + If you say Y here, you will be able to choose several options that will
10466 + make breaking out of a chrooted jail much more difficult. If you
10467 + encounter no software incompatibilities with the following options, it
10468 + is recommended that you enable each one.
10470 +config GRKERNSEC_CHROOT_MOUNT
10471 + bool "Deny mounts"
10472 + depends on GRKERNSEC_CHROOT
10474 + If you say Y here, processes inside a chroot will not be able to
10475 + mount or remount filesystems. If the sysctl option is enabled, a
10476 + sysctl option with name "chroot_deny_mount" is created.
10478 +config GRKERNSEC_CHROOT_DOUBLE
10479 + bool "Deny double-chroots"
10480 + depends on GRKERNSEC_CHROOT
10482 + If you say Y here, processes inside a chroot will not be able to chroot
10483 + again outside the chroot. This is a widely used method of breaking
10484 + out of a chroot jail and should not be allowed. If the sysctl
10485 + option is enabled, a sysctl option with name
10486 + "chroot_deny_chroot" is created.
10488 +config GRKERNSEC_CHROOT_PIVOT
10489 + bool "Deny pivot_root in chroot"
10490 + depends on GRKERNSEC_CHROOT
10492 + If you say Y here, processes inside a chroot will not be able to use
10493 + a function called pivot_root() that was introduced in Linux 2.3.41. It
10494 + works similar to chroot in that it changes the root filesystem. This
10495 + function could be misused in a chrooted process to attempt to break out
10496 + of the chroot, and therefore should not be allowed. If the sysctl
10497 + option is enabled, a sysctl option with name "chroot_deny_pivot" is
10500 +config GRKERNSEC_CHROOT_CHDIR
10501 + bool "Enforce chdir(\"/\") on all chroots"
10502 + depends on GRKERNSEC_CHROOT
10504 + If you say Y here, the current working directory of all newly-chrooted
10505 + applications will be set to the the root directory of the chroot.
10506 + The man page on chroot(2) states:
10507 + Note that this call does not change the current working
10508 + directory, so that `.' can be outside the tree rooted at
10509 + `/'. In particular, the super-user can escape from a
10510 + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
10512 + It is recommended that you say Y here, since it's not known to break
10513 + any software. If the sysctl option is enabled, a sysctl option with
10514 + name "chroot_enforce_chdir" is created.
10516 +config GRKERNSEC_CHROOT_CHMOD
10517 + bool "Deny (f)chmod +s"
10518 + depends on GRKERNSEC_CHROOT
10520 + If you say Y here, processes inside a chroot will not be able to chmod
10521 + or fchmod files to make them have suid or sgid bits. This protects
10522 + against another published method of breaking a chroot. If the sysctl
10523 + option is enabled, a sysctl option with name "chroot_deny_chmod" is
10526 +config GRKERNSEC_CHROOT_FCHDIR
10527 + bool "Deny fchdir out of chroot"
10528 + depends on GRKERNSEC_CHROOT
10530 + If you say Y here, a well-known method of breaking chroots by fchdir'ing
10531 + to a file descriptor of the chrooting process that points to a directory
10532 + outside the filesystem will be stopped. If the sysctl option
10533 + is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
10535 +config GRKERNSEC_CHROOT_MKNOD
10536 + bool "Deny mknod"
10537 + depends on GRKERNSEC_CHROOT
10539 + If you say Y here, processes inside a chroot will not be allowed to
10540 + mknod. The problem with using mknod inside a chroot is that it
10541 + would allow an attacker to create a device entry that is the same
10542 + as one on the physical root of your system, which could range from
10543 + anything from the console device to a device for your harddrive (which
10544 + they could then use to wipe the drive or steal data). It is recommended
10545 + that you say Y here, unless you run into software incompatibilities.
10546 + If the sysctl option is enabled, a sysctl option with name
10547 + "chroot_deny_mknod" is created.
10549 +config GRKERNSEC_CHROOT_SHMAT
10550 + bool "Deny shmat() out of chroot"
10551 + depends on GRKERNSEC_CHROOT
10553 + If you say Y here, processes inside a chroot will not be able to attach
10554 + to shared memory segments that were created outside of the chroot jail.
10555 + It is recommended that you say Y here. If the sysctl option is enabled,
10556 + a sysctl option with name "chroot_deny_shmat" is created.
10558 +config GRKERNSEC_CHROOT_UNIX
10559 + bool "Deny access to abstract AF_UNIX sockets out of chroot"
10560 + depends on GRKERNSEC_CHROOT
10562 + If you say Y here, processes inside a chroot will not be able to
10563 + connect to abstract (meaning not belonging to a filesystem) Unix
10564 + domain sockets that were bound outside of a chroot. It is recommended
10565 + that you say Y here. If the sysctl option is enabled, a sysctl option
10566 + with name "chroot_deny_unix" is created.
10568 +config GRKERNSEC_CHROOT_FINDTASK
10569 + bool "Protect outside processes"
10570 + depends on GRKERNSEC_CHROOT
10572 + If you say Y here, processes inside a chroot will not be able to
10573 + kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
10574 + getsid, or view any process outside of the chroot. If the sysctl
10575 + option is enabled, a sysctl option with name "chroot_findtask" is
10578 +config GRKERNSEC_CHROOT_NICE
10579 + bool "Restrict priority changes"
10580 + depends on GRKERNSEC_CHROOT
10582 + If you say Y here, processes inside a chroot will not be able to raise
10583 + the priority of processes in the chroot, or alter the priority of
10584 + processes outside the chroot. This provides more security than simply
10585 + removing CAP_SYS_NICE from the process' capability set. If the
10586 + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
10589 +config GRKERNSEC_CHROOT_SYSCTL
10590 + bool "Deny sysctl writes"
10591 + depends on GRKERNSEC_CHROOT
10593 + If you say Y here, an attacker in a chroot will not be able to
10594 + write to sysctl entries, either by sysctl(2) or through a /proc
10595 + interface. It is strongly recommended that you say Y here. If the
10596 + sysctl option is enabled, a sysctl option with name
10597 + "chroot_deny_sysctl" is created.
10599 +config GRKERNSEC_CHROOT_CAPS
10600 + bool "Capability restrictions"
10601 + depends on GRKERNSEC_CHROOT
10603 + If you say Y here, the capabilities on all root processes within a
10604 + chroot jail will be lowered to stop module insertion, raw i/o,
10605 + system and net admin tasks, rebooting the system, modifying immutable
10606 + files, modifying IPC owned by another, and changing the system time.
10607 + This is left an option because it can break some apps. Disable this
10608 + if your chrooted apps are having problems performing those kinds of
10609 + tasks. If the sysctl option is enabled, a sysctl option with
10610 + name "chroot_caps" is created.
10613 +menu "Kernel Auditing"
10614 +depends on GRKERNSEC
10616 +config GRKERNSEC_AUDIT_GROUP
10617 + bool "Single group for auditing"
10619 + If you say Y here, the exec, chdir, (un)mount, and ipc logging features
10620 + will only operate on a group you specify. This option is recommended
10621 + if you only want to watch certain users instead of having a large
10622 + amount of logs from the entire system. If the sysctl option is enabled,
10623 + a sysctl option with name "audit_group" is created.
10625 +config GRKERNSEC_AUDIT_GID
10626 + int "GID for auditing"
10627 + depends on GRKERNSEC_AUDIT_GROUP
10630 +config GRKERNSEC_EXECLOG
10631 + bool "Exec logging"
10633 + If you say Y here, all execve() calls will be logged (since the
10634 + other exec*() calls are frontends to execve(), all execution
10635 + will be logged). Useful for shell-servers that like to keep track
10636 + of their users. If the sysctl option is enabled, a sysctl option with
10637 + name "exec_logging" is created.
10638 + WARNING: This option when enabled will produce a LOT of logs, especially
10639 + on an active system.
10641 +config GRKERNSEC_RESLOG
10642 + bool "Resource logging"
10644 + If you say Y here, all attempts to overstep resource limits will
10645 + be logged with the resource name, the requested size, and the current
10646 + limit. It is highly recommended that you say Y here. If the sysctl
10647 + option is enabled, a sysctl option with name "resource_logging" is
10648 + created. If the RBAC system is enabled, the sysctl value is ignored.
10650 +config GRKERNSEC_CHROOT_EXECLOG
10651 + bool "Log execs within chroot"
10653 + If you say Y here, all executions inside a chroot jail will be logged
10654 + to syslog. This can cause a large amount of logs if certain
10655 + applications (eg. djb's daemontools) are installed on the system, and
10656 + is therefore left as an option. If the sysctl option is enabled, a
10657 + sysctl option with name "chroot_execlog" is created.
10659 +config GRKERNSEC_AUDIT_CHDIR
10660 + bool "Chdir logging"
10662 + If you say Y here, all chdir() calls will be logged. If the sysctl
10663 + option is enabled, a sysctl option with name "audit_chdir" is created.
10665 +config GRKERNSEC_AUDIT_MOUNT
10666 + bool "(Un)Mount logging"
10668 + If you say Y here, all mounts and unmounts will be logged. If the
10669 + sysctl option is enabled, a sysctl option with name "audit_mount" is
10672 +config GRKERNSEC_AUDIT_IPC
10673 + bool "IPC logging"
10675 + If you say Y here, creation and removal of message queues, semaphores,
10676 + and shared memory will be logged. If the sysctl option is enabled, a
10677 + sysctl option with name "audit_ipc" is created.
10679 +config GRKERNSEC_SIGNAL
10680 + bool "Signal logging"
10682 + If you say Y here, certain important signals will be logged, such as
10683 + SIGSEGV, which will as a result inform you of when a error in a program
10684 + occurred, which in some cases could mean a possible exploit attempt.
10685 + If the sysctl option is enabled, a sysctl option with name
10686 + "signal_logging" is created.
10688 +config GRKERNSEC_FORKFAIL
10689 + bool "Fork failure logging"
10691 + If you say Y here, all failed fork() attempts will be logged.
10692 + This could suggest a fork bomb, or someone attempting to overstep
10693 + their process limit. If the sysctl option is enabled, a sysctl option
10694 + with name "forkfail_logging" is created.
10696 +config GRKERNSEC_TIME
10697 + bool "Time change logging"
10699 + If you say Y here, any changes of the system clock will be logged.
10700 + If the sysctl option is enabled, a sysctl option with name
10701 + "timechange_logging" is created.
10703 +config GRKERNSEC_PROC_IPADDR
10704 + bool "/proc/<pid>/ipaddr support"
10706 + If you say Y here, a new entry will be added to each /proc/<pid>
10707 + directory that contains the IP address of the person using the task.
10708 + The IP is carried across local TCP and AF_UNIX stream sockets.
10709 + This information can be useful for IDS/IPSes to perform remote response
10710 + to a local attack. The entry is readable by only the owner of the
10711 + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
10712 + the RBAC system), and thus does not create privacy concerns.
10714 +config GRKERNSEC_AUDIT_TEXTREL
10715 + bool 'ELF text relocations logging (READ HELP)'
10716 + depends on PAX_MPROTECT
10718 + If you say Y here, text relocations will be logged with the filename
10719 + of the offending library or binary. The purpose of the feature is
10720 + to help Linux distribution developers get rid of libraries and
10721 + binaries that need text relocations which hinder the future progress
10722 + of PaX. Only Linux distribution developers should say Y here, and
10723 + never on a production machine, as this option creates an information
10724 + leak that could aid an attacker in defeating the randomization of
10725 + a single memory region. If the sysctl option is enabled, a sysctl
10726 + option with name "audit_textrel" is created.
10730 +menu "Executable Protections"
10731 +depends on GRKERNSEC
10733 +config GRKERNSEC_EXECVE
10734 + bool "Enforce RLIMIT_NPROC on execs"
10736 + If you say Y here, users with a resource limit on processes will
10737 + have the value checked during execve() calls. The current system
10738 + only checks the system limit during fork() calls. If the sysctl option
10739 + is enabled, a sysctl option with name "execve_limiting" is created.
10741 +config GRKERNSEC_SHM
10742 + bool "Destroy unused shared memory"
10743 + depends on SYSVIPC
10745 + If you say Y here, shared memory will be destroyed when no one is
10746 + attached to it. Otherwise, resources involved with the shared
10747 + memory can be used up and not be associated with any process (as the
10748 + shared memory still exists, and the creating process has exited). If
10749 + the sysctl option is enabled, a sysctl option with name
10750 + "destroy_unused_shm" is created.
10752 +config GRKERNSEC_DMESG
10753 + bool "Dmesg(8) restriction"
10755 + If you say Y here, non-root users will not be able to use dmesg(8)
10756 + to view up to the last 4kb of messages in the kernel's log buffer.
10757 + If the sysctl option is enabled, a sysctl option with name "dmesg" is
10760 +config GRKERNSEC_RANDPID
10761 + bool "Randomized PIDs"
10763 + If you say Y here, all PIDs created on the system will be
10764 + pseudo-randomly generated. This is extremely effective along
10765 + with the /proc restrictions to disallow an attacker from guessing
10766 + pids of daemons, etc. PIDs are also used in some cases as part
10767 + of a naming system for temporary files, so this option would keep
10768 + those filenames from being predicted as well. We also use code
10769 + to make sure that PID numbers aren't reused too soon. If the sysctl
10770 + option is enabled, a sysctl option with name "rand_pids" is created.
10772 +config GRKERNSEC_TPE
10773 + bool "Trusted Path Execution (TPE)"
10775 + If you say Y here, you will be able to choose a gid to add to the
10776 + supplementary groups of users you want to mark as "untrusted."
10777 + These users will not be able to execute any files that are not in
10778 + root-owned directories writable only by root. If the sysctl option
10779 + is enabled, a sysctl option with name "tpe" is created.
10781 +config GRKERNSEC_TPE_ALL
10782 + bool "Partially restrict non-root users"
10783 + depends on GRKERNSEC_TPE
10785 + If you say Y here, All non-root users other than the ones in the
10786 + group specified in the main TPE option will only be allowed to
10787 + execute files in directories they own that are not group or
10788 + world-writable, or in directories owned by root and writable only by
10789 + root. If the sysctl option is enabled, a sysctl option with name
10790 + "tpe_restrict_all" is created.
10792 +config GRKERNSEC_TPE_INVERT
10793 + bool "Invert GID option"
10794 + depends on GRKERNSEC_TPE
10796 + If you say Y here, the group you specify in the TPE configuration will
10797 + decide what group TPE restrictions will be *disabled* for. This
10798 + option is useful if you want TPE restrictions to be applied to most
10799 + users on the system.
10801 +config GRKERNSEC_TPE_GID
10802 + int "GID for untrusted users"
10803 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
10806 + If you have selected the "Invert GID option" above, setting this
10807 + GID determines what group TPE restrictions will be *disabled* for.
10808 + If you have not selected the "Invert GID option" above, setting this
10809 + GID determines what group TPE restrictions will be *enabled* for.
10810 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
10813 +config GRKERNSEC_TPE_GID
10814 + int "GID for trusted users"
10815 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
10818 + If you have selected the "Invert GID option" above, setting this
10819 + GID determines what group TPE restrictions will be *disabled* for.
10820 + If you have not selected the "Invert GID option" above, setting this
10821 + GID determines what group TPE restrictions will be *enabled* for.
10822 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
10826 +menu "Network Protections"
10827 +depends on GRKERNSEC
10829 +config GRKERNSEC_RANDNET
10830 + bool "Larger entropy pools"
10832 + If you say Y here, the entropy pools used for many features of Linux
10833 + and grsecurity will be doubled in size. Since several grsecurity
10834 + features use additional randomness, it is recommended that you say Y
10835 + here. Saying Y here has a similar effect as modifying
10836 + /proc/sys/kernel/random/poolsize.
10838 +config GRKERNSEC_SOCKET
10839 + bool "Socket restrictions"
10841 + If you say Y here, you will be able to choose from several options.
10842 + If you assign a GID on your system and add it to the supplementary
10843 + groups of users you want to restrict socket access to, this patch
10844 + will perform up to three things, based on the option(s) you choose.
10846 +config GRKERNSEC_SOCKET_ALL
10847 + bool "Deny any sockets to group"
10848 + depends on GRKERNSEC_SOCKET
10850 + If you say Y here, you will be able to choose a GID of whose users will
10851 + be unable to connect to other hosts from your machine or run server
10852 + applications from your machine. If the sysctl option is enabled, a
10853 + sysctl option with name "socket_all" is created.
10855 +config GRKERNSEC_SOCKET_ALL_GID
10856 + int "GID to deny all sockets for"
10857 + depends on GRKERNSEC_SOCKET_ALL
10860 + Here you can choose the GID to disable socket access for. Remember to
10861 + add the users you want socket access disabled for to the GID
10862 + specified here. If the sysctl option is enabled, a sysctl option
10863 + with name "socket_all_gid" is created.
10865 +config GRKERNSEC_SOCKET_CLIENT
10866 + bool "Deny client sockets to group"
10867 + depends on GRKERNSEC_SOCKET
10869 + If you say Y here, you will be able to choose a GID of whose users will
10870 + be unable to connect to other hosts from your machine, but will be
10871 + able to run servers. If this option is enabled, all users in the group
10872 + you specify will have to use passive mode when initiating ftp transfers
10873 + from the shell on your machine. If the sysctl option is enabled, a
10874 + sysctl option with name "socket_client" is created.
10876 +config GRKERNSEC_SOCKET_CLIENT_GID
10877 + int "GID to deny client sockets for"
10878 + depends on GRKERNSEC_SOCKET_CLIENT
10881 + Here you can choose the GID to disable client socket access for.
10882 + Remember to add the users you want client socket access disabled for to
10883 + the GID specified here. If the sysctl option is enabled, a sysctl
10884 + option with name "socket_client_gid" is created.
10886 +config GRKERNSEC_SOCKET_SERVER
10887 + bool "Deny server sockets to group"
10888 + depends on GRKERNSEC_SOCKET
10890 + If you say Y here, you will be able to choose a GID of whose users will
10891 + be unable to run server applications from your machine. If the sysctl
10892 + option is enabled, a sysctl option with name "socket_server" is created.
10894 +config GRKERNSEC_SOCKET_SERVER_GID
10895 + int "GID to deny server sockets for"
10896 + depends on GRKERNSEC_SOCKET_SERVER
10899 + Here you can choose the GID to disable server socket access for.
10900 + Remember to add the users you want server socket access disabled for to
10901 + the GID specified here. If the sysctl option is enabled, a sysctl
10902 + option with name "socket_server_gid" is created.
10905 +menu "Sysctl support"
10906 +depends on GRKERNSEC && SYSCTL
10908 +config GRKERNSEC_SYSCTL
10909 + bool "Sysctl support"
10911 + If you say Y here, you will be able to change the options that
10912 + grsecurity runs with at bootup, without having to recompile your
10913 + kernel. You can echo values to files in /proc/sys/kernel/grsecurity
10914 + to enable (1) or disable (0) various features. All the sysctl entries
10915 + are mutable until the "grsec_lock" entry is set to a non-zero value.
10916 + All features enabled in the kernel configuration are disabled at boot
10917 + if you do not say Y to the "Turn on features by default" option.
10918 + All options should be set at startup, and the grsec_lock entry should
10919 + be set to a non-zero value after all the options are set.
10920 + *THIS IS EXTREMELY IMPORTANT*
10922 +config GRKERNSEC_SYSCTL_ON
10923 + bool "Turn on features by default"
10924 + depends on GRKERNSEC_SYSCTL
10926 + If you say Y here, instead of having all features enabled in the
10927 + kernel configuration disabled at boot time, the features will be
10928 + enabled at boot time. It is recommended you say Y here unless
10929 + there is some reason you would want all sysctl-tunable features to
10930 + be disabled by default. As mentioned elsewhere, it is important
10931 + to enable the grsec_lock entry once you have finished modifying
10932 + the sysctl entries.
10935 +menu "Logging Options"
10936 +depends on GRKERNSEC
10938 +config GRKERNSEC_FLOODTIME
10939 + int "Seconds in between log messages (minimum)"
10942 + This option allows you to enforce the number of seconds between
10943 + grsecurity log messages. The default should be suitable for most
10944 + people, however, if you choose to change it, choose a value small enough
10945 + to allow informative logs to be produced, but large enough to
10946 + prevent flooding.
10948 +config GRKERNSEC_FLOODBURST
10949 + int "Number of messages in a burst (maximum)"
10952 + This option allows you to choose the maximum number of messages allowed
10953 + within the flood time interval you chose in a separate option. The
10954 + default should be suitable for most people, however if you find that
10955 + many of your logs are being interpreted as flooding, you may want to
10956 + raise this value.
10961 diff -urNp linux-2.6.17.7/grsecurity/Makefile linux-2.6.17.7/grsecurity/Makefile
10962 --- linux-2.6.17.7/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
10963 +++ linux-2.6.17.7/grsecurity/Makefile 2006-08-01 20:29:47.000000000 -0400
10965 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
10966 +# during 2001-2005 it has been completely redesigned by Brad Spengler
10967 +# into an RBAC system
10969 +# All code in this directory and various hooks inserted throughout the kernel
10970 +# are copyright Brad Spengler, and released under the GPL v2 or higher
10972 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
10973 + grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
10974 + grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
10976 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
10977 + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
10978 + gracl_learn.o grsec_log.o
10979 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
10981 +ifndef CONFIG_GRKERNSEC
10982 +obj-y += grsec_disabled.o
10985 diff -urNp linux-2.6.17.7/grsecurity/gracl.c linux-2.6.17.7/grsecurity/gracl.c
10986 --- linux-2.6.17.7/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
10987 +++ linux-2.6.17.7/grsecurity/gracl.c 2006-08-01 20:29:47.000000000 -0400
10989 +#include <linux/kernel.h>
10990 +#include <linux/module.h>
10991 +#include <linux/sched.h>
10992 +#include <linux/mm.h>
10993 +#include <linux/file.h>
10994 +#include <linux/fs.h>
10995 +#include <linux/namei.h>
10996 +#include <linux/mount.h>
10997 +#include <linux/tty.h>
10998 +#include <linux/proc_fs.h>
10999 +#include <linux/smp_lock.h>
11000 +#include <linux/slab.h>
11001 +#include <linux/vmalloc.h>
11002 +#include <linux/types.h>
11003 +#include <linux/capability.h>
11004 +#include <linux/sysctl.h>
11005 +#include <linux/netdevice.h>
11006 +#include <linux/ptrace.h>
11007 +#include <linux/gracl.h>
11008 +#include <linux/gralloc.h>
11009 +#include <linux/grsecurity.h>
11010 +#include <linux/grinternal.h>
11011 +#include <linux/percpu.h>
11013 +#include <asm/uaccess.h>
11014 +#include <asm/errno.h>
11015 +#include <asm/mman.h>
11017 +static struct acl_role_db acl_role_set;
11018 +static struct name_db name_set;
11019 +static struct inodev_db inodev_set;
11021 +/* for keeping track of userspace pointers used for subjects, so we
11022 + can share references in the kernel as well
11025 +static struct dentry *real_root;
11026 +static struct vfsmount *real_root_mnt;
11028 +static struct acl_subj_map_db subj_map_set;
11030 +static struct acl_role_label *default_role;
11032 +static u16 acl_sp_role_value;
11034 +extern char *gr_shared_page[4];
11035 +static DECLARE_MUTEX(gr_dev_sem);
11036 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
11038 +struct gr_arg *gr_usermode;
11040 +static unsigned int gr_status = GR_STATUS_INIT;
11042 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
11043 +extern void gr_clear_learn_entries(void);
11045 +#ifdef CONFIG_GRKERNSEC_RESLOG
11046 +extern void gr_log_resource(const struct task_struct *task,
11047 + const int res, const unsigned long wanted, const int gt);
11050 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
11051 + struct dentry *root, struct vfsmount *rootmnt,
11052 + char *buffer, int buflen);
11054 +unsigned char *gr_system_salt;
11055 +unsigned char *gr_system_sum;
11057 +static struct sprole_pw **acl_special_roles = NULL;
11058 +static __u16 num_sprole_pws = 0;
11060 +static struct acl_role_label *kernel_role = NULL;
11062 +static unsigned int gr_auth_attempts = 0;
11063 +static unsigned long gr_auth_expires = 0UL;
11065 +extern struct vfsmount *sock_mnt;
11066 +extern struct vfsmount *pipe_mnt;
11067 +extern struct vfsmount *shm_mnt;
11068 +static struct acl_object_label *fakefs_obj;
11070 +extern int gr_init_uidset(void);
11071 +extern void gr_free_uidset(void);
11072 +extern void gr_remove_uid(uid_t uid);
11073 +extern int gr_find_uid(uid_t uid);
11076 +gr_acl_is_enabled(void)
11078 + return (gr_status & GR_READY);
11081 +char gr_roletype_to_char(void)
11083 + switch (current->role->roletype &
11084 + (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
11085 + GR_ROLE_SPECIAL)) {
11086 + case GR_ROLE_DEFAULT:
11088 + case GR_ROLE_USER:
11090 + case GR_ROLE_GROUP:
11092 + case GR_ROLE_SPECIAL:
11100 +gr_acl_tpe_check(void)
11102 + if (unlikely(!(gr_status & GR_READY)))
11104 + if (current->role->roletype & GR_ROLE_TPE)
11111 +gr_handle_rawio(const struct inode *inode)
11113 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11114 + if (inode && S_ISBLK(inode->i_mode) &&
11115 + grsec_enable_chroot_caps && proc_is_chrooted(current) &&
11116 + !capable(CAP_SYS_RAWIO))
11123 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
11126 + unsigned long *l1;
11127 + unsigned long *l2;
11128 + unsigned char *c1;
11129 + unsigned char *c2;
11132 + if (likely(lena != lenb))
11135 + l1 = (unsigned long *)a;
11136 + l2 = (unsigned long *)b;
11138 + num_longs = lena / sizeof(unsigned long);
11140 + for (i = num_longs; i--; l1++, l2++) {
11141 + if (unlikely(*l1 != *l2))
11145 + c1 = (unsigned char *) l1;
11146 + c2 = (unsigned char *) l2;
11148 + i = lena - (num_longs * sizeof(unsigned long));
11150 + for (; i--; c1++, c2++) {
11151 + if (unlikely(*c1 != *c2))
11159 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
11160 + struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
11162 + char *end = buf + buflen;
11168 + retval = end - 1;
11171 + if (dentry == root && vfsmnt == rootmnt)
11173 + if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
11174 + namelen = strlen(dentry->d_name.name);
11175 + buflen -= namelen;
11178 + if (dentry->d_parent != root || vfsmnt != rootmnt)
11182 + retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
11183 + if (unlikely(IS_ERR(retval)))
11185 + retval = strcpy(buf, "<path too long>");
11186 + else if (namelen != 0) {
11187 + end = buf + buflen - 1; // accounts for null termination
11188 + if (dentry->d_parent != root || vfsmnt != rootmnt)
11189 + *end++ = '/'; // accounted for above with buflen--
11190 + memcpy(end, dentry->d_name.name, namelen);
11197 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
11198 + char *buf, int buflen)
11202 + /* we can use real_root, real_root_mnt, because this is only called
11203 + by the RBAC system */
11204 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
11210 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
11211 + char *buf, int buflen)
11214 + struct dentry *root;
11215 + struct vfsmount *rootmnt;
11217 + /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
11218 + read_lock(&child_reaper->fs->lock);
11219 + root = dget(child_reaper->fs->root);
11220 + rootmnt = mntget(child_reaper->fs->rootmnt);
11221 + read_unlock(&child_reaper->fs->lock);
11223 + spin_lock(&dcache_lock);
11224 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
11225 + spin_unlock(&dcache_lock);
11233 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
11236 + spin_lock(&dcache_lock);
11237 + ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
11239 + spin_unlock(&dcache_lock);
11244 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
11246 + return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
11251 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
11253 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
11258 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
11260 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
11265 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
11267 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
11272 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
11274 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
11279 +to_gr_audit(const __u32 reqmode)
11281 + /* masks off auditable permission flags, then shifts them to create
11282 + auditing flags, and adds the special case of append auditing if
11283 + we're requesting write */
11284 + return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
11287 +struct acl_subject_label *
11288 +lookup_subject_map(const struct acl_subject_label *userp)
11290 + unsigned int index = shash(userp, subj_map_set.s_size);
11291 + struct subject_map *match;
11293 + match = subj_map_set.s_hash[index];
11295 + while (match && match->user != userp)
11296 + match = match->next;
11298 + if (match != NULL)
11299 + return match->kernel;
11305 +insert_subj_map_entry(struct subject_map *subjmap)
11307 + unsigned int index = shash(subjmap->user, subj_map_set.s_size);
11308 + struct subject_map **curr;
11310 + subjmap->prev = NULL;
11312 + curr = &subj_map_set.s_hash[index];
11313 + if (*curr != NULL)
11314 + (*curr)->prev = subjmap;
11316 + subjmap->next = *curr;
11322 +static struct acl_role_label *
11323 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
11326 + unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
11327 + struct acl_role_label *match;
11328 + struct role_allowed_ip *ipp;
11331 + match = acl_role_set.r_hash[index];
11334 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
11335 + for (x = 0; x < match->domain_child_num; x++) {
11336 + if (match->domain_children[x] == uid)
11339 + } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
11341 + match = match->next;
11344 + if (match == NULL) {
11346 + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
11347 + match = acl_role_set.r_hash[index];
11350 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
11351 + for (x = 0; x < match->domain_child_num; x++) {
11352 + if (match->domain_children[x] == gid)
11355 + } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
11357 + match = match->next;
11360 + if (match == NULL)
11361 + match = default_role;
11362 + if (match->allowed_ips == NULL)
11365 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
11367 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
11368 + (ntohl(ipp->addr) & ipp->netmask)))
11371 + match = default_role;
11373 + } else if (match->allowed_ips == NULL) {
11376 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
11378 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
11379 + (ntohl(ipp->addr) & ipp->netmask)))
11388 +struct acl_subject_label *
11389 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
11390 + const struct acl_role_label *role)
11392 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
11393 + struct acl_subject_label *match;
11395 + match = role->subj_hash[index];
11397 + while (match && (match->inode != ino || match->device != dev ||
11398 + (match->mode & GR_DELETED))) {
11399 + match = match->next;
11402 + if (match && !(match->mode & GR_DELETED))
11408 +static struct acl_object_label *
11409 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
11410 + const struct acl_subject_label *subj)
11412 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
11413 + struct acl_object_label *match;
11415 + match = subj->obj_hash[index];
11417 + while (match && (match->inode != ino || match->device != dev ||
11418 + (match->mode & GR_DELETED))) {
11419 + match = match->next;
11422 + if (match && !(match->mode & GR_DELETED))
11428 +static struct acl_object_label *
11429 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
11430 + const struct acl_subject_label *subj)
11432 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
11433 + struct acl_object_label *match;
11435 + match = subj->obj_hash[index];
11437 + while (match && (match->inode != ino || match->device != dev ||
11438 + !(match->mode & GR_DELETED))) {
11439 + match = match->next;
11442 + if (match && (match->mode & GR_DELETED))
11445 + match = subj->obj_hash[index];
11447 + while (match && (match->inode != ino || match->device != dev ||
11448 + (match->mode & GR_DELETED))) {
11449 + match = match->next;
11452 + if (match && !(match->mode & GR_DELETED))
11458 +static struct name_entry *
11459 +lookup_name_entry(const char *name)
11461 + unsigned int len = strlen(name);
11462 + unsigned int key = full_name_hash(name, len);
11463 + unsigned int index = key % name_set.n_size;
11464 + struct name_entry *match;
11466 + match = name_set.n_hash[index];
11468 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
11469 + match = match->next;
11474 +static struct inodev_entry *
11475 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
11477 + unsigned int index = fhash(ino, dev, inodev_set.i_size);
11478 + struct inodev_entry *match;
11480 + match = inodev_set.i_hash[index];
11482 + while (match && (match->nentry->inode != ino || match->nentry->device != dev))
11483 + match = match->next;
11489 +insert_inodev_entry(struct inodev_entry *entry)
11491 + unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
11492 + inodev_set.i_size);
11493 + struct inodev_entry **curr;
11495 + entry->prev = NULL;
11497 + curr = &inodev_set.i_hash[index];
11498 + if (*curr != NULL)
11499 + (*curr)->prev = entry;
11501 + entry->next = *curr;
11508 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
11510 + unsigned int index =
11511 + rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
11512 + struct acl_role_label **curr;
11514 + role->prev = NULL;
11516 + curr = &acl_role_set.r_hash[index];
11517 + if (*curr != NULL)
11518 + (*curr)->prev = role;
11520 + role->next = *curr;
11527 +insert_acl_role_label(struct acl_role_label *role)
11531 + if (role->roletype & GR_ROLE_DOMAIN) {
11532 + for (i = 0; i < role->domain_child_num; i++)
11533 + __insert_acl_role_label(role, role->domain_children[i]);
11535 + __insert_acl_role_label(role, role->uidgid);
11539 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
11541 + struct name_entry **curr, *nentry;
11542 + struct inodev_entry *ientry;
11543 + unsigned int len = strlen(name);
11544 + unsigned int key = full_name_hash(name, len);
11545 + unsigned int index = key % name_set.n_size;
11547 + curr = &name_set.n_hash[index];
11549 + while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
11550 + curr = &((*curr)->next);
11552 + if (*curr != NULL)
11555 + nentry = acl_alloc(sizeof (struct name_entry));
11556 + if (nentry == NULL)
11558 + ientry = acl_alloc(sizeof (struct inodev_entry));
11559 + if (ientry == NULL)
11561 + ientry->nentry = nentry;
11563 + nentry->key = key;
11564 + nentry->name = name;
11565 + nentry->inode = inode;
11566 + nentry->device = device;
11567 + nentry->len = len;
11569 + nentry->prev = NULL;
11570 + curr = &name_set.n_hash[index];
11571 + if (*curr != NULL)
11572 + (*curr)->prev = nentry;
11573 + nentry->next = *curr;
11576 + /* insert us into the table searchable by inode/dev */
11577 + insert_inodev_entry(ientry);
11583 +insert_acl_obj_label(struct acl_object_label *obj,
11584 + struct acl_subject_label *subj)
11586 + unsigned int index =
11587 + fhash(obj->inode, obj->device, subj->obj_hash_size);
11588 + struct acl_object_label **curr;
11591 + obj->prev = NULL;
11593 + curr = &subj->obj_hash[index];
11594 + if (*curr != NULL)
11595 + (*curr)->prev = obj;
11597 + obj->next = *curr;
11604 +insert_acl_subj_label(struct acl_subject_label *obj,
11605 + struct acl_role_label *role)
11607 + unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
11608 + struct acl_subject_label **curr;
11610 + obj->prev = NULL;
11612 + curr = &role->subj_hash[index];
11613 + if (*curr != NULL)
11614 + (*curr)->prev = obj;
11616 + obj->next = *curr;
11622 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
11625 +create_table(__u32 * len, int elementsize)
11627 + unsigned int table_sizes[] = {
11628 + 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
11629 + 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
11630 + 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
11631 + 268435399, 536870909, 1073741789, 2147483647
11633 + void *newtable = NULL;
11634 + unsigned int pwr = 0;
11636 + while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
11637 + table_sizes[pwr] <= *len)
11640 + if (table_sizes[pwr] <= *len)
11643 + if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
11645 + kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
11647 + newtable = vmalloc(table_sizes[pwr] * elementsize);
11649 + *len = table_sizes[pwr];
11655 +init_variables(const struct gr_arg *arg)
11657 + unsigned int stacksize;
11659 + subj_map_set.s_size = arg->role_db.num_subjects;
11660 + acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
11661 + name_set.n_size = arg->role_db.num_objects;
11662 + inodev_set.i_size = arg->role_db.num_objects;
11664 + if (!subj_map_set.s_size || !acl_role_set.r_size ||
11665 + !name_set.n_size || !inodev_set.i_size)
11668 + if (!gr_init_uidset())
11671 + /* set up the stack that holds allocation info */
11673 + stacksize = arg->role_db.num_pointers + 5;
11675 + if (!acl_alloc_stack_init(stacksize))
11678 + /* grab reference for the real root dentry and vfsmount */
11679 + read_lock(&child_reaper->fs->lock);
11680 + real_root_mnt = mntget(child_reaper->fs->rootmnt);
11681 + real_root = dget(child_reaper->fs->root);
11682 + read_unlock(&child_reaper->fs->lock);
11684 + fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
11685 + if (fakefs_obj == NULL)
11687 + fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
11689 + subj_map_set.s_hash =
11690 + (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
11691 + acl_role_set.r_hash =
11692 + (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
11693 + name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
11694 + inodev_set.i_hash =
11695 + (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
11697 + if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
11698 + !name_set.n_hash || !inodev_set.i_hash)
11701 + memset(subj_map_set.s_hash, 0,
11702 + sizeof(struct subject_map *) * subj_map_set.s_size);
11703 + memset(acl_role_set.r_hash, 0,
11704 + sizeof (struct acl_role_label *) * acl_role_set.r_size);
11705 + memset(name_set.n_hash, 0,
11706 + sizeof (struct name_entry *) * name_set.n_size);
11707 + memset(inodev_set.i_hash, 0,
11708 + sizeof (struct inodev_entry *) * inodev_set.i_size);
11713 +/* free information not needed after startup
11714 + currently contains user->kernel pointer mappings for subjects
11718 +free_init_variables(void)
11722 + if (subj_map_set.s_hash) {
11723 + for (i = 0; i < subj_map_set.s_size; i++) {
11724 + if (subj_map_set.s_hash[i]) {
11725 + kfree(subj_map_set.s_hash[i]);
11726 + subj_map_set.s_hash[i] = NULL;
11730 + if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
11732 + kfree(subj_map_set.s_hash);
11734 + vfree(subj_map_set.s_hash);
11741 +free_variables(void)
11743 + struct acl_subject_label *s;
11744 + struct acl_role_label *r;
11745 + struct task_struct *task, *task2;
11746 + unsigned int i, x;
11748 + gr_clear_learn_entries();
11750 + read_lock(&tasklist_lock);
11751 + do_each_thread(task2, task) {
11752 + task->acl_sp_role = 0;
11753 + task->acl_role_id = 0;
11754 + task->acl = NULL;
11755 + task->role = NULL;
11756 + } while_each_thread(task2, task);
11757 + read_unlock(&tasklist_lock);
11759 + /* release the reference to the real root dentry and vfsmount */
11762 + real_root = NULL;
11763 + if (real_root_mnt)
11764 + mntput(real_root_mnt);
11765 + real_root_mnt = NULL;
11767 + /* free all object hash tables */
11769 + FOR_EACH_ROLE_START(r, i)
11770 + if (r->subj_hash == NULL)
11772 + FOR_EACH_SUBJECT_START(r, s, x)
11773 + if (s->obj_hash == NULL)
11775 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
11776 + kfree(s->obj_hash);
11778 + vfree(s->obj_hash);
11779 + FOR_EACH_SUBJECT_END(s, x)
11780 + FOR_EACH_NESTED_SUBJECT_START(r, s)
11781 + if (s->obj_hash == NULL)
11783 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
11784 + kfree(s->obj_hash);
11786 + vfree(s->obj_hash);
11787 + FOR_EACH_NESTED_SUBJECT_END(s)
11788 + if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
11789 + kfree(r->subj_hash);
11791 + vfree(r->subj_hash);
11792 + r->subj_hash = NULL;
11793 + FOR_EACH_ROLE_END(r,i)
11797 + if (acl_role_set.r_hash) {
11798 + if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
11800 + kfree(acl_role_set.r_hash);
11802 + vfree(acl_role_set.r_hash);
11804 + if (name_set.n_hash) {
11805 + if ((name_set.n_size * sizeof (struct name_entry *)) <=
11807 + kfree(name_set.n_hash);
11809 + vfree(name_set.n_hash);
11812 + if (inodev_set.i_hash) {
11813 + if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
11815 + kfree(inodev_set.i_hash);
11817 + vfree(inodev_set.i_hash);
11820 + gr_free_uidset();
11822 + memset(&name_set, 0, sizeof (struct name_db));
11823 + memset(&inodev_set, 0, sizeof (struct inodev_db));
11824 + memset(&acl_role_set, 0, sizeof (struct acl_role_db));
11825 + memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
11827 + default_role = NULL;
11833 +count_user_objs(struct acl_object_label *userp)
11835 + struct acl_object_label o_tmp;
11839 + if (copy_from_user(&o_tmp, userp,
11840 + sizeof (struct acl_object_label)))
11843 + userp = o_tmp.prev;
11850 +static struct acl_subject_label *
11851 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
11854 +copy_user_glob(struct acl_object_label *obj)
11856 + struct acl_object_label *g_tmp, **guser;
11857 + unsigned int len;
11860 + if (obj->globbed == NULL)
11863 + guser = &obj->globbed;
11865 + g_tmp = (struct acl_object_label *)
11866 + acl_alloc(sizeof (struct acl_object_label));
11867 + if (g_tmp == NULL)
11870 + if (copy_from_user(g_tmp, *guser,
11871 + sizeof (struct acl_object_label)))
11874 + len = strnlen_user(g_tmp->filename, PATH_MAX);
11876 + if (!len || len >= PATH_MAX)
11879 + if ((tmp = (char *) acl_alloc(len)) == NULL)
11882 + if (copy_from_user(tmp, g_tmp->filename, len))
11885 + g_tmp->filename = tmp;
11888 + guser = &(g_tmp->next);
11895 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
11896 + struct acl_role_label *role)
11898 + struct acl_object_label *o_tmp;
11899 + unsigned int len;
11904 + if ((o_tmp = (struct acl_object_label *)
11905 + acl_alloc(sizeof (struct acl_object_label))) == NULL)
11908 + if (copy_from_user(o_tmp, userp,
11909 + sizeof (struct acl_object_label)))
11912 + userp = o_tmp->prev;
11914 + len = strnlen_user(o_tmp->filename, PATH_MAX);
11916 + if (!len || len >= PATH_MAX)
11919 + if ((tmp = (char *) acl_alloc(len)) == NULL)
11922 + if (copy_from_user(tmp, o_tmp->filename, len))
11925 + o_tmp->filename = tmp;
11927 + insert_acl_obj_label(o_tmp, subj);
11928 + if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
11932 + ret = copy_user_glob(o_tmp);
11936 + if (o_tmp->nested) {
11937 + o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
11938 + if (IS_ERR(o_tmp->nested))
11939 + return PTR_ERR(o_tmp->nested);
11941 + /* insert into nested subject list */
11942 + o_tmp->nested->next = role->hash->first;
11943 + role->hash->first = o_tmp->nested;
11951 +count_user_subjs(struct acl_subject_label *userp)
11953 + struct acl_subject_label s_tmp;
11957 + if (copy_from_user(&s_tmp, userp,
11958 + sizeof (struct acl_subject_label)))
11961 + userp = s_tmp.prev;
11962 + /* do not count nested subjects against this count, since
11963 + they are not included in the hash table, but are
11964 + attached to objects. We have already counted
11965 + the subjects in userspace for the allocation
11968 + if (!(s_tmp.mode & GR_NESTED))
11976 +copy_user_allowedips(struct acl_role_label *rolep)
11978 + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
11980 + ruserip = rolep->allowed_ips;
11982 + while (ruserip) {
11985 + if ((rtmp = (struct role_allowed_ip *)
11986 + acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
11989 + if (copy_from_user(rtmp, ruserip,
11990 + sizeof (struct role_allowed_ip)))
11993 + ruserip = rtmp->prev;
11996 + rtmp->prev = NULL;
11997 + rolep->allowed_ips = rtmp;
11999 + rlast->next = rtmp;
12000 + rtmp->prev = rlast;
12004 + rtmp->next = NULL;
12011 +copy_user_transitions(struct acl_role_label *rolep)
12013 + struct role_transition *rusertp, *rtmp = NULL, *rlast;
12015 + unsigned int len;
12018 + rusertp = rolep->transitions;
12020 + while (rusertp) {
12023 + if ((rtmp = (struct role_transition *)
12024 + acl_alloc(sizeof (struct role_transition))) == NULL)
12027 + if (copy_from_user(rtmp, rusertp,
12028 + sizeof (struct role_transition)))
12031 + rusertp = rtmp->prev;
12033 + len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
12035 + if (!len || len >= GR_SPROLE_LEN)
12038 + if ((tmp = (char *) acl_alloc(len)) == NULL)
12041 + if (copy_from_user(tmp, rtmp->rolename, len))
12044 + rtmp->rolename = tmp;
12047 + rtmp->prev = NULL;
12048 + rolep->transitions = rtmp;
12050 + rlast->next = rtmp;
12051 + rtmp->prev = rlast;
12055 + rtmp->next = NULL;
12061 +static struct acl_subject_label *
12062 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
12064 + struct acl_subject_label *s_tmp = NULL, *s_tmp2;
12065 + unsigned int len;
12068 + struct acl_ip_label **i_tmp, *i_utmp2;
12069 + struct gr_hash_struct ghash;
12070 + struct subject_map *subjmap;
12071 + unsigned int i_num;
12074 + s_tmp = lookup_subject_map(userp);
12076 + /* we've already copied this subject into the kernel, just return
12077 + the reference to it, and don't copy it over again
12082 + if ((s_tmp = (struct acl_subject_label *)
12083 + acl_alloc(sizeof (struct acl_subject_label))) == NULL)
12084 + return ERR_PTR(-ENOMEM);
12086 + subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
12087 + if (subjmap == NULL)
12088 + return ERR_PTR(-ENOMEM);
12090 + subjmap->user = userp;
12091 + subjmap->kernel = s_tmp;
12092 + insert_subj_map_entry(subjmap);
12094 + if (copy_from_user(s_tmp, userp,
12095 + sizeof (struct acl_subject_label)))
12096 + return ERR_PTR(-EFAULT);
12098 + len = strnlen_user(s_tmp->filename, PATH_MAX);
12100 + if (!len || len >= PATH_MAX)
12101 + return ERR_PTR(-EINVAL);
12103 + if ((tmp = (char *) acl_alloc(len)) == NULL)
12104 + return ERR_PTR(-ENOMEM);
12106 + if (copy_from_user(tmp, s_tmp->filename, len))
12107 + return ERR_PTR(-EFAULT);
12109 + s_tmp->filename = tmp;
12111 + if (!strcmp(s_tmp->filename, "/"))
12112 + role->root_label = s_tmp;
12114 + if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
12115 + return ERR_PTR(-EFAULT);
12117 + /* copy user and group transition tables */
12119 + if (s_tmp->user_trans_num) {
12122 + uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
12123 + if (uidlist == NULL)
12124 + return ERR_PTR(-ENOMEM);
12125 + if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
12126 + return ERR_PTR(-EFAULT);
12128 + s_tmp->user_transitions = uidlist;
12131 + if (s_tmp->group_trans_num) {
12134 + gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
12135 + if (gidlist == NULL)
12136 + return ERR_PTR(-ENOMEM);
12137 + if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
12138 + return ERR_PTR(-EFAULT);
12140 + s_tmp->group_transitions = gidlist;
12143 + /* set up object hash table */
12144 + num_objs = count_user_objs(ghash.first);
12146 + s_tmp->obj_hash_size = num_objs;
12147 + s_tmp->obj_hash =
12148 + (struct acl_object_label **)
12149 + create_table(&(s_tmp->obj_hash_size), sizeof(void *));
12151 + if (!s_tmp->obj_hash)
12152 + return ERR_PTR(-ENOMEM);
12154 + memset(s_tmp->obj_hash, 0,
12155 + s_tmp->obj_hash_size *
12156 + sizeof (struct acl_object_label *));
12158 + /* add in objects */
12159 + err = copy_user_objs(ghash.first, s_tmp, role);
12162 + return ERR_PTR(err);
12164 + /* set pointer for parent subject */
12165 + if (s_tmp->parent_subject) {
12166 + s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
12168 + if (IS_ERR(s_tmp2))
12171 + s_tmp->parent_subject = s_tmp2;
12174 + /* add in ip acls */
12176 + if (!s_tmp->ip_num) {
12177 + s_tmp->ips = NULL;
12182 + (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
12184 + acl_ip_label *));
12187 + return ERR_PTR(-ENOMEM);
12189 + for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
12190 + *(i_tmp + i_num) =
12191 + (struct acl_ip_label *)
12192 + acl_alloc(sizeof (struct acl_ip_label));
12193 + if (!*(i_tmp + i_num))
12194 + return ERR_PTR(-ENOMEM);
12196 + if (copy_from_user
12197 + (&i_utmp2, s_tmp->ips + i_num,
12198 + sizeof (struct acl_ip_label *)))
12199 + return ERR_PTR(-EFAULT);
12201 + if (copy_from_user
12202 + (*(i_tmp + i_num), i_utmp2,
12203 + sizeof (struct acl_ip_label)))
12204 + return ERR_PTR(-EFAULT);
12206 + if ((*(i_tmp + i_num))->iface == NULL)
12209 + len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
12210 + if (!len || len >= IFNAMSIZ)
12211 + return ERR_PTR(-EINVAL);
12212 + tmp = acl_alloc(len);
12214 + return ERR_PTR(-ENOMEM);
12215 + if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
12216 + return ERR_PTR(-EFAULT);
12217 + (*(i_tmp + i_num))->iface = tmp;
12220 + s_tmp->ips = i_tmp;
12223 + if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
12225 + return ERR_PTR(-ENOMEM);
12231 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
12233 + struct acl_subject_label s_pre;
12234 + struct acl_subject_label * ret;
12238 + if (copy_from_user(&s_pre, userp,
12239 + sizeof (struct acl_subject_label)))
12242 + /* do not add nested subjects here, add
12243 + while parsing objects
12246 + if (s_pre.mode & GR_NESTED) {
12247 + userp = s_pre.prev;
12251 + ret = do_copy_user_subj(userp, role);
12253 + err = PTR_ERR(ret);
12257 + insert_acl_subj_label(ret, role);
12259 + userp = s_pre.prev;
12266 +copy_user_acl(struct gr_arg *arg)
12268 + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
12269 + struct sprole_pw *sptmp;
12270 + struct gr_hash_struct *ghash;
12271 + uid_t *domainlist;
12272 + unsigned int r_num;
12273 + unsigned int len;
12279 + /* we need a default and kernel role */
12280 + if (arg->role_db.num_roles < 2)
12283 + /* copy special role authentication info from userspace */
12285 + num_sprole_pws = arg->num_sprole_pws;
12286 + acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
12288 + if (!acl_special_roles) {
12293 + for (i = 0; i < num_sprole_pws; i++) {
12294 + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
12299 + if (copy_from_user(sptmp, arg->sprole_pws + i,
12300 + sizeof (struct sprole_pw))) {
12306 + strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
12308 + if (!len || len >= GR_SPROLE_LEN) {
12313 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
12318 + if (copy_from_user(tmp, sptmp->rolename, len)) {
12323 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
12324 + printk(KERN_ALERT "Copying special role %s\n", tmp);
12326 + sptmp->rolename = tmp;
12327 + acl_special_roles[i] = sptmp;
12330 + r_utmp = (struct acl_role_label **) arg->role_db.r_table;
12332 + for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
12333 + r_tmp = acl_alloc(sizeof (struct acl_role_label));
12340 + if (copy_from_user(&r_utmp2, r_utmp + r_num,
12341 + sizeof (struct acl_role_label *))) {
12346 + if (copy_from_user(r_tmp, r_utmp2,
12347 + sizeof (struct acl_role_label))) {
12352 + len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
12354 + if (!len || len >= PATH_MAX) {
12359 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
12363 + if (copy_from_user(tmp, r_tmp->rolename, len)) {
12367 + r_tmp->rolename = tmp;
12369 + if (!strcmp(r_tmp->rolename, "default")
12370 + && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
12371 + default_role = r_tmp;
12372 + } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
12373 + kernel_role = r_tmp;
12376 + if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
12380 + if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
12385 + r_tmp->hash = ghash;
12387 + num_subjs = count_user_subjs(r_tmp->hash->first);
12389 + r_tmp->subj_hash_size = num_subjs;
12390 + r_tmp->subj_hash =
12391 + (struct acl_subject_label **)
12392 + create_table(&(r_tmp->subj_hash_size), sizeof(void *));
12394 + if (!r_tmp->subj_hash) {
12399 + err = copy_user_allowedips(r_tmp);
12403 + /* copy domain info */
12404 + if (r_tmp->domain_children != NULL) {
12405 + domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
12406 + if (domainlist == NULL) {
12410 + if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
12414 + r_tmp->domain_children = domainlist;
12417 + err = copy_user_transitions(r_tmp);
12421 + memset(r_tmp->subj_hash, 0,
12422 + r_tmp->subj_hash_size *
12423 + sizeof (struct acl_subject_label *));
12425 + err = copy_user_subjs(r_tmp->hash->first, r_tmp);
12430 + /* set nested subject list to null */
12431 + r_tmp->hash->first = NULL;
12433 + insert_acl_role_label(r_tmp);
12438 + free_variables();
12445 +gracl_init(struct gr_arg *args)
12449 + memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
12450 + memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
12452 + if (init_variables(args)) {
12453 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
12455 + free_variables();
12459 + error = copy_user_acl(args);
12460 + free_init_variables();
12462 + free_variables();
12466 + if ((error = gr_set_acls(0))) {
12467 + free_variables();
12471 + gr_status |= GR_READY;
12476 +/* derived from glibc fnmatch() 0: match, 1: no match*/
12479 +glob_match(const char *p, const char *n)
12483 + while ((c = *p++) != '\0') {
12488 + else if (*n == '/')
12496 + for (c = *p++; c == '?' || c == '*'; c = *p++) {
12499 + else if (c == '?') {
12509 + const char *endp;
12511 + if ((endp = strchr(n, '/')) == NULL)
12512 + endp = n + strlen(n);
12515 + for (--p; n < endp; ++n)
12516 + if (!glob_match(p, n))
12518 + } else if (c == '/') {
12519 + while (*n != '\0' && *n != '/')
12521 + if (*n == '/' && !glob_match(p, n + 1))
12524 + for (--p; n < endp; ++n)
12525 + if (*n == c && !glob_match(p, n))
12536 + if (*n == '\0' || *n == '/')
12539 + not = (*p == '!' || *p == '^');
12545 + unsigned char fn = (unsigned char)*n;
12555 + if (c == '-' && *p != ']') {
12556 + unsigned char cend = *p++;
12558 + if (cend == '\0')
12561 + if (cold <= fn && fn <= cend)
12575 + while (c != ']') {
12602 +static struct acl_object_label *
12603 +chk_glob_label(struct acl_object_label *globbed,
12604 + struct dentry *dentry, struct vfsmount *mnt, char **path)
12606 + struct acl_object_label *tmp;
12608 + if (*path == NULL)
12609 + *path = gr_to_filename_nolock(dentry, mnt);
12614 + if (!glob_match(tmp->filename, *path))
12622 +static struct acl_object_label *
12623 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
12624 + const ino_t curr_ino, const dev_t curr_dev,
12625 + const struct acl_subject_label *subj, char **path)
12627 + struct acl_subject_label *tmpsubj;
12628 + struct acl_object_label *retval;
12629 + struct acl_object_label *retval2;
12631 + tmpsubj = (struct acl_subject_label *) subj;
12632 + read_lock(&gr_inode_lock);
12634 + retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
12636 + if (retval->globbed) {
12637 + retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
12638 + (struct vfsmount *)orig_mnt, path);
12640 + retval = retval2;
12644 + } while ((tmpsubj = tmpsubj->parent_subject));
12645 + read_unlock(&gr_inode_lock);
12650 +static __inline__ struct acl_object_label *
12651 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
12652 + const struct dentry *curr_dentry,
12653 + const struct acl_subject_label *subj, char **path)
12655 + return __full_lookup(orig_dentry, orig_mnt,
12656 + curr_dentry->d_inode->i_ino,
12657 + curr_dentry->d_inode->i_sb->s_dev, subj, path);
12660 +static struct acl_object_label *
12661 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12662 + const struct acl_subject_label *subj, char *path)
12664 + struct dentry *dentry = (struct dentry *) l_dentry;
12665 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
12666 + struct acl_object_label *retval;
12668 + spin_lock(&dcache_lock);
12670 + if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt)) {
12671 + retval = fakefs_obj;
12676 + if (dentry == real_root && mnt == real_root_mnt)
12679 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
12680 + if (mnt->mnt_parent == mnt)
12683 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
12684 + if (retval != NULL)
12687 + dentry = mnt->mnt_mountpoint;
12688 + mnt = mnt->mnt_parent;
12692 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
12693 + if (retval != NULL)
12696 + dentry = dentry->d_parent;
12699 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
12701 + if (retval == NULL)
12702 + retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
12704 + spin_unlock(&dcache_lock);
12708 +static __inline__ struct acl_object_label *
12709 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12710 + const struct acl_subject_label *subj)
12712 + char *path = NULL;
12713 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
12716 +static __inline__ struct acl_object_label *
12717 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12718 + const struct acl_subject_label *subj, char *path)
12720 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
12723 +static struct acl_subject_label *
12724 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12725 + const struct acl_role_label *role)
12727 + struct dentry *dentry = (struct dentry *) l_dentry;
12728 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
12729 + struct acl_subject_label *retval;
12731 + spin_lock(&dcache_lock);
12734 + if (dentry == real_root && mnt == real_root_mnt)
12736 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
12737 + if (mnt->mnt_parent == mnt)
12740 + read_lock(&gr_inode_lock);
12742 + lookup_acl_subj_label(dentry->d_inode->i_ino,
12743 + dentry->d_inode->i_sb->s_dev, role);
12744 + read_unlock(&gr_inode_lock);
12745 + if (retval != NULL)
12748 + dentry = mnt->mnt_mountpoint;
12749 + mnt = mnt->mnt_parent;
12753 + read_lock(&gr_inode_lock);
12754 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
12755 + dentry->d_inode->i_sb->s_dev, role);
12756 + read_unlock(&gr_inode_lock);
12757 + if (retval != NULL)
12760 + dentry = dentry->d_parent;
12763 + read_lock(&gr_inode_lock);
12764 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
12765 + dentry->d_inode->i_sb->s_dev, role);
12766 + read_unlock(&gr_inode_lock);
12768 + if (unlikely(retval == NULL)) {
12769 + read_lock(&gr_inode_lock);
12770 + retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
12771 + real_root->d_inode->i_sb->s_dev, role);
12772 + read_unlock(&gr_inode_lock);
12775 + spin_unlock(&dcache_lock);
12781 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
12783 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
12784 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
12785 + task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
12786 + 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
12792 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
12793 + const unsigned int effective, const unsigned int fs)
12795 + security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
12796 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
12797 + task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
12798 + type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
12804 +gr_check_link(const struct dentry * new_dentry,
12805 + const struct dentry * parent_dentry,
12806 + const struct vfsmount * parent_mnt,
12807 + const struct dentry * old_dentry, const struct vfsmount * old_mnt)
12809 + struct acl_object_label *obj;
12810 + __u32 oldmode, newmode;
12813 + if (unlikely(!(gr_status & GR_READY)))
12814 + return (GR_CREATE | GR_LINK);
12816 + obj = chk_obj_label(old_dentry, old_mnt, current->acl);
12817 + oldmode = obj->mode;
12819 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
12820 + oldmode |= (GR_CREATE | GR_LINK);
12822 + needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
12823 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
12824 + needmode |= GR_SETID | GR_AUDIT_SETID;
12827 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
12828 + oldmode | needmode);
12830 + needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
12831 + GR_SETID | GR_READ | GR_FIND | GR_DELETE |
12832 + GR_INHERIT | GR_AUDIT_INHERIT);
12834 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
12837 + if ((oldmode & needmode) != needmode)
12840 + needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
12841 + if ((newmode & needmode) != needmode)
12844 + if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
12847 + needmode = oldmode;
12848 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
12849 + needmode |= GR_SETID;
12851 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
12852 + gr_log_learn(current, old_dentry, old_mnt, needmode);
12853 + return (GR_CREATE | GR_LINK);
12854 + } else if (newmode & GR_SUPPRESS)
12855 + return GR_SUPPRESS;
12861 +gr_search_file(const struct dentry * dentry, const __u32 mode,
12862 + const struct vfsmount * mnt)
12864 + __u32 retval = mode;
12865 + struct acl_subject_label *curracl;
12866 + struct acl_object_label *currobj;
12868 + if (unlikely(!(gr_status & GR_READY)))
12869 + return (mode & ~GR_AUDITS);
12871 + curracl = current->acl;
12873 + currobj = chk_obj_label(dentry, mnt, curracl);
12874 + retval = currobj->mode & mode;
12877 + ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
12878 + && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
12879 + __u32 new_mode = mode;
12881 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12883 + retval = new_mode;
12885 + if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
12886 + new_mode |= GR_INHERIT;
12888 + if (!(mode & GR_NOLEARN))
12889 + gr_log_learn(current, dentry, mnt, new_mode);
12896 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
12897 + const struct vfsmount * mnt, const __u32 mode)
12899 + struct name_entry *match;
12900 + struct acl_object_label *matchpo;
12901 + struct acl_subject_label *curracl;
12905 + if (unlikely(!(gr_status & GR_READY)))
12906 + return (mode & ~GR_AUDITS);
12908 + preempt_disable();
12909 + path = gr_to_filename_rbac(new_dentry, mnt);
12910 + match = lookup_name_entry(path);
12913 + goto check_parent;
12915 + curracl = current->acl;
12917 + read_lock(&gr_inode_lock);
12918 + matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
12919 + read_unlock(&gr_inode_lock);
12922 + if ((matchpo->mode & mode) !=
12923 + (mode & ~(GR_AUDITS | GR_SUPPRESS))
12924 + && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
12925 + __u32 new_mode = mode;
12927 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12929 + gr_log_learn(current, new_dentry, mnt, new_mode);
12931 + preempt_enable();
12934 + preempt_enable();
12935 + return (matchpo->mode & mode);
12939 + curracl = current->acl;
12941 + matchpo = chk_obj_create_label(parent, mnt, curracl, path);
12942 + retval = matchpo->mode & mode;
12944 + if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
12945 + && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
12946 + __u32 new_mode = mode;
12948 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12950 + gr_log_learn(current, new_dentry, mnt, new_mode);
12951 + preempt_enable();
12955 + preempt_enable();
12960 +gr_check_hidden_task(const struct task_struct *task)
12962 + if (unlikely(!(gr_status & GR_READY)))
12965 + if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
12972 +gr_check_protected_task(const struct task_struct *task)
12974 + if (unlikely(!(gr_status & GR_READY) || !task))
12977 + if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
12978 + task->acl != current->acl)
12985 +gr_copy_label(struct task_struct *tsk)
12987 + tsk->signal->used_accept = 0;
12988 + tsk->acl_sp_role = 0;
12989 + tsk->acl_role_id = current->acl_role_id;
12990 + tsk->acl = current->acl;
12991 + tsk->role = current->role;
12992 + tsk->signal->curr_ip = current->signal->curr_ip;
12993 + if (current->exec_file)
12994 + get_file(current->exec_file);
12995 + tsk->exec_file = current->exec_file;
12996 + tsk->is_writable = current->is_writable;
12997 + if (unlikely(current->signal->used_accept))
12998 + current->signal->curr_ip = 0;
13004 +gr_set_proc_res(struct task_struct *task)
13006 + struct acl_subject_label *proc;
13007 + unsigned short i;
13009 + proc = task->acl;
13011 + if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
13014 + for (i = 0; i < (GR_NLIMITS - 1); i++) {
13015 + if (!(proc->resmask & (1 << i)))
13018 + task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
13019 + task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
13026 +gr_check_user_change(int real, int effective, int fs)
13033 + int effectiveok = 0;
13036 + if (unlikely(!(gr_status & GR_READY)))
13039 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
13040 + gr_log_learn_id_change(current, 'u', real, effective, fs);
13042 + num = current->acl->user_trans_num;
13043 + uidlist = current->acl->user_transitions;
13045 + if (uidlist == NULL)
13050 + if (effective == -1)
13055 + if (current->acl->user_trans_type & GR_ID_ALLOW) {
13056 + for (i = 0; i < num; i++) {
13057 + curuid = (int)uidlist[i];
13058 + if (real == curuid)
13060 + if (effective == curuid)
13062 + if (fs == curuid)
13065 + } else if (current->acl->user_trans_type & GR_ID_DENY) {
13066 + for (i = 0; i < num; i++) {
13067 + curuid = (int)uidlist[i];
13068 + if (real == curuid)
13070 + if (effective == curuid)
13072 + if (fs == curuid)
13075 + /* not in deny list */
13083 + if (realok && effectiveok && fsok)
13086 + gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
13092 +gr_check_group_change(int real, int effective, int fs)
13099 + int effectiveok = 0;
13102 + if (unlikely(!(gr_status & GR_READY)))
13105 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
13106 + gr_log_learn_id_change(current, 'g', real, effective, fs);
13108 + num = current->acl->group_trans_num;
13109 + gidlist = current->acl->group_transitions;
13111 + if (gidlist == NULL)
13116 + if (effective == -1)
13121 + if (current->acl->group_trans_type & GR_ID_ALLOW) {
13122 + for (i = 0; i < num; i++) {
13123 + curgid = (int)gidlist[i];
13124 + if (real == curgid)
13126 + if (effective == curgid)
13128 + if (fs == curgid)
13131 + } else if (current->acl->group_trans_type & GR_ID_DENY) {
13132 + for (i = 0; i < num; i++) {
13133 + curgid = (int)gidlist[i];
13134 + if (real == curgid)
13136 + if (effective == curgid)
13138 + if (fs == curgid)
13141 + /* not in deny list */
13149 + if (realok && effectiveok && fsok)
13152 + gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
13158 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
13160 + struct acl_role_label *role = task->role;
13161 + struct acl_subject_label *subj = NULL;
13162 + struct acl_object_label *obj;
13163 + struct file *filp;
13165 + if (unlikely(!(gr_status & GR_READY)))
13168 + filp = task->exec_file;
13170 + /* kernel process, we'll give them the kernel role */
13171 + if (unlikely(!filp)) {
13172 + task->role = kernel_role;
13173 + task->acl = kernel_role->root_label;
13175 + } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
13176 + role = lookup_acl_role_label(task, uid, gid);
13178 + /* perform subject lookup in possibly new role
13179 + we can use this result below in the case where role == task->role
13181 + subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
13183 + /* if we changed uid/gid, but result in the same role
13184 + and are using inheritance, don't lose the inherited subject
13185 + if current subject is other than what normal lookup
13186 + would result in, we arrived via inheritance, don't
13189 + if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
13190 + (subj == task->acl)))
13191 + task->acl = subj;
13193 + task->role = role;
13195 + task->is_writable = 0;
13197 + /* ignore additional mmap checks for processes that are writable
13198 + by the default ACL */
13199 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
13200 + if (unlikely(obj->mode & GR_WRITE))
13201 + task->is_writable = 1;
13202 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
13203 + if (unlikely(obj->mode & GR_WRITE))
13204 + task->is_writable = 1;
13206 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13207 + printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
13210 + gr_set_proc_res(task);
13216 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
13218 + struct task_struct *task = current;
13219 + struct acl_subject_label *newacl;
13220 + struct acl_object_label *obj;
13223 + if (unlikely(!(gr_status & GR_READY)))
13226 + newacl = chk_subj_label(dentry, mnt, task->role);
13229 + if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
13230 + GR_POVERRIDE) && (task->acl != newacl) &&
13231 + !(task->role->roletype & GR_ROLE_GOD) &&
13232 + !gr_search_file(dentry, GR_PTRACERD, mnt) &&
13233 + !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
13234 + (atomic_read(&task->fs->count) > 1 ||
13235 + atomic_read(&task->files->count) > 1 ||
13236 + atomic_read(&task->sighand->count) > 1)) {
13237 + task_unlock(task);
13238 + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
13241 + task_unlock(task);
13243 + obj = chk_obj_label(dentry, mnt, task->acl);
13244 + retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
13246 + if (!(task->acl->mode & GR_INHERITLEARN) &&
13247 + ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
13249 + task->acl = obj->nested;
13251 + task->acl = newacl;
13252 + } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
13253 + gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
13255 + task->is_writable = 0;
13257 + /* ignore additional mmap checks for processes that are writable
13258 + by the default ACL */
13259 + obj = chk_obj_label(dentry, mnt, default_role->root_label);
13260 + if (unlikely(obj->mode & GR_WRITE))
13261 + task->is_writable = 1;
13262 + obj = chk_obj_label(dentry, mnt, task->role->root_label);
13263 + if (unlikely(obj->mode & GR_WRITE))
13264 + task->is_writable = 1;
13266 + gr_set_proc_res(task);
13268 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13269 + printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
13275 +do_handle_delete(const ino_t ino, const dev_t dev)
13277 + struct acl_object_label *matchpo;
13278 + struct acl_subject_label *matchps;
13279 + struct acl_subject_label *subj;
13280 + struct acl_role_label *role;
13281 + unsigned int i, x;
13283 + FOR_EACH_ROLE_START(role, i)
13284 + FOR_EACH_SUBJECT_START(role, subj, x)
13285 + if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
13286 + matchpo->mode |= GR_DELETED;
13287 + FOR_EACH_SUBJECT_END(subj,x)
13288 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
13289 + if (subj->inode == ino && subj->device == dev)
13290 + subj->mode |= GR_DELETED;
13291 + FOR_EACH_NESTED_SUBJECT_END(subj)
13292 + if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
13293 + matchps->mode |= GR_DELETED;
13294 + FOR_EACH_ROLE_END(role,i)
13300 +gr_handle_delete(const ino_t ino, const dev_t dev)
13302 + if (unlikely(!(gr_status & GR_READY)))
13305 + write_lock(&gr_inode_lock);
13306 + if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
13307 + do_handle_delete(ino, dev);
13308 + write_unlock(&gr_inode_lock);
13314 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
13315 + const ino_t newinode, const dev_t newdevice,
13316 + struct acl_subject_label *subj)
13318 + unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
13319 + struct acl_object_label *match;
13321 + match = subj->obj_hash[index];
13323 + while (match && (match->inode != oldinode ||
13324 + match->device != olddevice ||
13325 + !(match->mode & GR_DELETED)))
13326 + match = match->next;
13328 + if (match && (match->inode == oldinode)
13329 + && (match->device == olddevice)
13330 + && (match->mode & GR_DELETED)) {
13331 + if (match->prev == NULL) {
13332 + subj->obj_hash[index] = match->next;
13333 + if (match->next != NULL)
13334 + match->next->prev = NULL;
13336 + match->prev->next = match->next;
13337 + if (match->next != NULL)
13338 + match->next->prev = match->prev;
13340 + match->prev = NULL;
13341 + match->next = NULL;
13342 + match->inode = newinode;
13343 + match->device = newdevice;
13344 + match->mode &= ~GR_DELETED;
13346 + insert_acl_obj_label(match, subj);
13353 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
13354 + const ino_t newinode, const dev_t newdevice,
13355 + struct acl_role_label *role)
13357 + unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
13358 + struct acl_subject_label *match;
13360 + match = role->subj_hash[index];
13362 + while (match && (match->inode != oldinode ||
13363 + match->device != olddevice ||
13364 + !(match->mode & GR_DELETED)))
13365 + match = match->next;
13367 + if (match && (match->inode == oldinode)
13368 + && (match->device == olddevice)
13369 + && (match->mode & GR_DELETED)) {
13370 + if (match->prev == NULL) {
13371 + role->subj_hash[index] = match->next;
13372 + if (match->next != NULL)
13373 + match->next->prev = NULL;
13375 + match->prev->next = match->next;
13376 + if (match->next != NULL)
13377 + match->next->prev = match->prev;
13379 + match->prev = NULL;
13380 + match->next = NULL;
13381 + match->inode = newinode;
13382 + match->device = newdevice;
13383 + match->mode &= ~GR_DELETED;
13385 + insert_acl_subj_label(match, role);
13392 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
13393 + const ino_t newinode, const dev_t newdevice)
13395 + unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
13396 + struct inodev_entry *match;
13398 + match = inodev_set.i_hash[index];
13400 + while (match && (match->nentry->inode != oldinode ||
13401 + match->nentry->device != olddevice))
13402 + match = match->next;
13404 + if (match && (match->nentry->inode == oldinode)
13405 + && (match->nentry->device == olddevice)) {
13406 + if (match->prev == NULL) {
13407 + inodev_set.i_hash[index] = match->next;
13408 + if (match->next != NULL)
13409 + match->next->prev = NULL;
13411 + match->prev->next = match->next;
13412 + if (match->next != NULL)
13413 + match->next->prev = match->prev;
13415 + match->prev = NULL;
13416 + match->next = NULL;
13417 + match->nentry->inode = newinode;
13418 + match->nentry->device = newdevice;
13420 + insert_inodev_entry(match);
13427 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
13428 + const struct vfsmount *mnt)
13430 + struct acl_subject_label *subj;
13431 + struct acl_role_label *role;
13432 + unsigned int i, x;
13434 + FOR_EACH_ROLE_START(role, i)
13435 + update_acl_subj_label(matchn->inode, matchn->device,
13436 + dentry->d_inode->i_ino,
13437 + dentry->d_inode->i_sb->s_dev, role);
13439 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
13440 + if ((subj->inode == dentry->d_inode->i_ino) &&
13441 + (subj->device == dentry->d_inode->i_sb->s_dev)) {
13442 + subj->inode = dentry->d_inode->i_ino;
13443 + subj->device = dentry->d_inode->i_sb->s_dev;
13445 + FOR_EACH_NESTED_SUBJECT_END(subj)
13446 + FOR_EACH_SUBJECT_START(role, subj, x)
13447 + update_acl_obj_label(matchn->inode, matchn->device,
13448 + dentry->d_inode->i_ino,
13449 + dentry->d_inode->i_sb->s_dev, subj);
13450 + FOR_EACH_SUBJECT_END(subj,x)
13451 + FOR_EACH_ROLE_END(role,i)
13453 + update_inodev_entry(matchn->inode, matchn->device,
13454 + dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
13460 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
13462 + struct name_entry *matchn;
13464 + if (unlikely(!(gr_status & GR_READY)))
13467 + preempt_disable();
13468 + matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
13470 + if (unlikely((unsigned long)matchn)) {
13471 + write_lock(&gr_inode_lock);
13472 + do_handle_create(matchn, dentry, mnt);
13473 + write_unlock(&gr_inode_lock);
13475 + preempt_enable();
13481 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
13482 + struct dentry *old_dentry,
13483 + struct dentry *new_dentry,
13484 + struct vfsmount *mnt, const __u8 replace)
13486 + struct name_entry *matchn;
13488 + if (unlikely(!(gr_status & GR_READY)))
13491 + preempt_disable();
13492 + matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
13494 + /* we wouldn't have to check d_inode if it weren't for
13495 + NFS silly-renaming
13498 + write_lock(&gr_inode_lock);
13499 + if (unlikely(replace && new_dentry->d_inode)) {
13500 + if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
13501 + new_dentry->d_inode->i_sb->s_dev) &&
13502 + (old_dentry->d_inode->i_nlink <= 1)))
13503 + do_handle_delete(new_dentry->d_inode->i_ino,
13504 + new_dentry->d_inode->i_sb->s_dev);
13507 + if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
13508 + old_dentry->d_inode->i_sb->s_dev) &&
13509 + (old_dentry->d_inode->i_nlink <= 1)))
13510 + do_handle_delete(old_dentry->d_inode->i_ino,
13511 + old_dentry->d_inode->i_sb->s_dev);
13513 + if (unlikely((unsigned long)matchn))
13514 + do_handle_create(matchn, old_dentry, mnt);
13516 + write_unlock(&gr_inode_lock);
13517 + preempt_enable();
13523 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
13524 + unsigned char **sum)
13526 + struct acl_role_label *r;
13527 + struct role_allowed_ip *ipp;
13528 + struct role_transition *trans;
13532 + /* check transition table */
13534 + for (trans = current->role->transitions; trans; trans = trans->next) {
13535 + if (!strcmp(rolename, trans->rolename)) {
13544 + /* handle special roles that do not require authentication
13547 + FOR_EACH_ROLE_START(r, i)
13548 + if (!strcmp(rolename, r->rolename) &&
13549 + (r->roletype & GR_ROLE_SPECIAL)) {
13551 + if (r->allowed_ips != NULL) {
13552 + for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
13553 + if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
13554 + (ntohl(ipp->addr) & ipp->netmask))
13562 + if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
13563 + ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
13569 + FOR_EACH_ROLE_END(r,i)
13571 + for (i = 0; i < num_sprole_pws; i++) {
13572 + if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
13573 + *salt = acl_special_roles[i]->salt;
13574 + *sum = acl_special_roles[i]->sum;
13583 +assign_special_role(char *rolename)
13585 + struct acl_object_label *obj;
13586 + struct acl_role_label *r;
13587 + struct acl_role_label *assigned = NULL;
13588 + struct task_struct *tsk;
13589 + struct file *filp;
13592 + FOR_EACH_ROLE_START(r, i)
13593 + if (!strcmp(rolename, r->rolename) &&
13594 + (r->roletype & GR_ROLE_SPECIAL))
13596 + FOR_EACH_ROLE_END(r,i)
13601 + read_lock(&tasklist_lock);
13602 + read_lock(&grsec_exec_file_lock);
13604 + tsk = current->parent;
13608 + filp = tsk->exec_file;
13609 + if (filp == NULL)
13612 + tsk->is_writable = 0;
13614 + tsk->acl_sp_role = 1;
13615 + tsk->acl_role_id = ++acl_sp_role_value;
13616 + tsk->role = assigned;
13617 + tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
13619 + /* ignore additional mmap checks for processes that are writable
13620 + by the default ACL */
13621 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
13622 + if (unlikely(obj->mode & GR_WRITE))
13623 + tsk->is_writable = 1;
13624 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
13625 + if (unlikely(obj->mode & GR_WRITE))
13626 + tsk->is_writable = 1;
13628 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13629 + printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
13633 + read_unlock(&grsec_exec_file_lock);
13634 + read_unlock(&tasklist_lock);
13638 +int gr_check_secure_terminal(struct task_struct *task)
13640 + struct task_struct *p, *p2, *p3;
13641 + struct files_struct *files;
13642 + struct fdtable *fdt;
13643 + struct file *our_file = NULL, *file;
13646 + if (task->signal->tty == NULL)
13649 + files = get_files_struct(task);
13650 + if (files != NULL) {
13652 + fdt = files_fdtable(files);
13653 + for (i=0; i < fdt->max_fds; i++) {
13654 + file = fcheck_files(files, i);
13655 + if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
13660 + rcu_read_unlock();
13661 + put_files_struct(files);
13664 + if (our_file == NULL)
13667 + read_lock(&tasklist_lock);
13668 + do_each_thread(p2, p) {
13669 + files = get_files_struct(p);
13670 + if (files == NULL ||
13671 + (p->signal && p->signal->tty == task->signal->tty)) {
13672 + if (files != NULL)
13673 + put_files_struct(files);
13677 + fdt = files_fdtable(files);
13678 + for (i=0; i < fdt->max_fds; i++) {
13679 + file = fcheck_files(files, i);
13680 + if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
13681 + file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
13683 + while (p3->pid > 0) {
13690 + gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
13691 + gr_handle_alertkill(p);
13692 + rcu_read_unlock();
13693 + put_files_struct(files);
13694 + read_unlock(&tasklist_lock);
13699 + rcu_read_unlock();
13700 + put_files_struct(files);
13701 + } while_each_thread(p2, p);
13702 + read_unlock(&tasklist_lock);
13709 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
13711 + struct gr_arg_wrapper uwrap;
13712 + unsigned char *sprole_salt;
13713 + unsigned char *sprole_sum;
13714 + int error = sizeof (struct gr_arg_wrapper);
13717 + down(&gr_dev_sem);
13719 + if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
13724 + if (count != sizeof (struct gr_arg_wrapper)) {
13725 + gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
13731 + if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
13732 + gr_auth_expires = 0;
13733 + gr_auth_attempts = 0;
13736 + if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
13741 + if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
13746 + if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
13751 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
13752 + gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
13753 + time_after(gr_auth_expires, get_seconds())) {
13758 + /* if non-root trying to do anything other than use a special role,
13759 + do not attempt authentication, do not count towards authentication
13763 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
13764 + gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
13770 + /* ensure pw and special role name are null terminated */
13772 + gr_usermode->pw[GR_PW_LEN - 1] = '\0';
13773 + gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
13776 + * We have our enough of the argument structure..(we have yet
13777 + * to copy_from_user the tables themselves) . Copy the tables
13778 + * only if we need them, i.e. for loading operations. */
13780 + switch (gr_usermode->mode) {
13782 + if (gr_status & GR_READY) {
13784 + if (!gr_check_secure_terminal(current))
13790 + if ((gr_status & GR_READY)
13791 + && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
13792 + gr_status &= ~GR_READY;
13793 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
13794 + free_variables();
13795 + memset(gr_usermode, 0, sizeof (struct gr_arg));
13796 + memset(gr_system_salt, 0, GR_SALT_LEN);
13797 + memset(gr_system_sum, 0, GR_SHA_LEN);
13798 + } else if (gr_status & GR_READY) {
13799 + gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
13802 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
13807 + if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
13808 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
13810 + if (gr_status & GR_READY)
13814 + gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
13818 + if (!(gr_status & GR_READY)) {
13819 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
13821 + } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
13823 + gr_status &= ~GR_READY;
13824 + free_variables();
13825 + if (!(error2 = gracl_init(gr_usermode))) {
13827 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
13831 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
13834 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
13839 + if (unlikely(!(gr_status & GR_READY))) {
13840 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
13845 + if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
13846 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
13847 + if (gr_usermode->segv_device && gr_usermode->segv_inode) {
13848 + struct acl_subject_label *segvacl;
13850 + lookup_acl_subj_label(gr_usermode->segv_inode,
13851 + gr_usermode->segv_device,
13854 + segvacl->crashes = 0;
13855 + segvacl->expires = 0;
13857 + } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
13858 + gr_remove_uid(gr_usermode->segv_uid);
13861 + gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
13867 + if (unlikely(!(gr_status & GR_READY))) {
13868 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
13873 + if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
13874 + current->role->expires = 0;
13875 + current->role->auth_attempts = 0;
13878 + if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
13879 + time_after(current->role->expires, get_seconds())) {
13884 + if (lookup_special_role_auth
13885 + (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
13886 + && ((!sprole_salt && !sprole_sum)
13887 + || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
13889 + assign_special_role(gr_usermode->sp_role);
13890 + read_lock(&tasklist_lock);
13891 + if (current->parent)
13892 + p = current->parent->role->rolename;
13893 + read_unlock(&tasklist_lock);
13894 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
13895 + p, acl_sp_role_value);
13897 + gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
13899 + if(!(current->role->auth_attempts++))
13900 + current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
13906 + if (unlikely(!(gr_status & GR_READY))) {
13907 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
13912 + if (current->role->roletype & GR_ROLE_SPECIAL) {
13916 + read_lock(&tasklist_lock);
13917 + if (current->parent) {
13918 + p = current->parent->role->rolename;
13919 + i = current->parent->acl_role_id;
13921 + read_unlock(&tasklist_lock);
13923 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
13926 + gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
13932 + gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
13937 + if (error != -EPERM)
13940 + if(!(gr_auth_attempts++))
13941 + gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
13949 +gr_set_acls(const int type)
13951 + struct acl_object_label *obj;
13952 + struct task_struct *task, *task2;
13953 + struct file *filp;
13954 + struct acl_role_label *role = current->role;
13955 + __u16 acl_role_id = current->acl_role_id;
13957 + read_lock(&tasklist_lock);
13958 + read_lock(&grsec_exec_file_lock);
13959 + do_each_thread(task2, task) {
13960 + /* check to see if we're called from the exit handler,
13961 + if so, only replace ACLs that have inherited the admin
13964 + if (type && (task->role != role ||
13965 + task->acl_role_id != acl_role_id))
13968 + task->acl_role_id = 0;
13969 + task->acl_sp_role = 0;
13971 + if ((filp = task->exec_file)) {
13972 + task->role = lookup_acl_role_label(task, task->uid, task->gid);
13975 + chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
13978 + struct acl_subject_label *curr;
13979 + curr = task->acl;
13981 + task->is_writable = 0;
13982 + /* ignore additional mmap checks for processes that are writable
13983 + by the default ACL */
13984 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
13985 + if (unlikely(obj->mode & GR_WRITE))
13986 + task->is_writable = 1;
13987 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
13988 + if (unlikely(obj->mode & GR_WRITE))
13989 + task->is_writable = 1;
13991 + gr_set_proc_res(task);
13993 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13994 + printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
13997 + read_unlock(&grsec_exec_file_lock);
13998 + read_unlock(&tasklist_lock);
13999 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
14003 + // it's a kernel process
14004 + task->role = kernel_role;
14005 + task->acl = kernel_role->root_label;
14006 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
14007 + task->acl->mode &= ~GR_PROCFIND;
14010 + } while_each_thread(task2, task);
14011 + read_unlock(&grsec_exec_file_lock);
14012 + read_unlock(&tasklist_lock);
14017 +gr_learn_resource(const struct task_struct *task,
14018 + const int res, const unsigned long wanted, const int gt)
14020 + struct acl_subject_label *acl;
14022 + if (unlikely((gr_status & GR_READY) &&
14023 + task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
14024 + goto skip_reslog;
14026 +#ifdef CONFIG_GRKERNSEC_RESLOG
14027 + gr_log_resource(task, res, wanted, gt);
14031 + if (unlikely(!(gr_status & GR_READY) || !wanted))
14036 + if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
14037 + !(acl->resmask & (1 << (unsigned short) res))))
14040 + if (wanted >= acl->res[res].rlim_cur) {
14041 + unsigned long res_add;
14043 + res_add = wanted;
14046 + res_add += GR_RLIM_CPU_BUMP;
14048 + case RLIMIT_FSIZE:
14049 + res_add += GR_RLIM_FSIZE_BUMP;
14051 + case RLIMIT_DATA:
14052 + res_add += GR_RLIM_DATA_BUMP;
14054 + case RLIMIT_STACK:
14055 + res_add += GR_RLIM_STACK_BUMP;
14057 + case RLIMIT_CORE:
14058 + res_add += GR_RLIM_CORE_BUMP;
14061 + res_add += GR_RLIM_RSS_BUMP;
14063 + case RLIMIT_NPROC:
14064 + res_add += GR_RLIM_NPROC_BUMP;
14066 + case RLIMIT_NOFILE:
14067 + res_add += GR_RLIM_NOFILE_BUMP;
14069 + case RLIMIT_MEMLOCK:
14070 + res_add += GR_RLIM_MEMLOCK_BUMP;
14073 + res_add += GR_RLIM_AS_BUMP;
14075 + case RLIMIT_LOCKS:
14076 + res_add += GR_RLIM_LOCKS_BUMP;
14080 + acl->res[res].rlim_cur = res_add;
14082 + if (wanted > acl->res[res].rlim_max)
14083 + acl->res[res].rlim_max = res_add;
14085 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
14086 + task->role->roletype, acl->filename,
14087 + acl->res[res].rlim_cur, acl->res[res].rlim_max,
14088 + "", (unsigned long) res);
14094 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14096 +pax_set_initial_flags(struct linux_binprm *bprm)
14098 + struct task_struct *task = current;
14099 + struct acl_subject_label *proc;
14100 + unsigned long flags;
14102 + if (unlikely(!(gr_status & GR_READY)))
14105 + flags = pax_get_flags(task);
14107 + proc = task->acl;
14109 + if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
14110 + flags &= ~MF_PAX_PAGEEXEC;
14111 + if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
14112 + flags &= ~MF_PAX_SEGMEXEC;
14113 + if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
14114 + flags &= ~MF_PAX_RANDMMAP;
14115 + if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
14116 + flags &= ~MF_PAX_EMUTRAMP;
14117 + if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
14118 + flags &= ~MF_PAX_MPROTECT;
14120 + if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
14121 + flags |= MF_PAX_PAGEEXEC;
14122 + if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
14123 + flags |= MF_PAX_SEGMEXEC;
14124 + if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
14125 + flags |= MF_PAX_RANDMMAP;
14126 + if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
14127 + flags |= MF_PAX_EMUTRAMP;
14128 + if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
14129 + flags |= MF_PAX_MPROTECT;
14131 + pax_set_flags(task, flags);
14137 +#ifdef CONFIG_SYSCTL
14138 +extern struct proc_dir_entry *proc_sys_root;
14140 +/* the following function is called under the BKL */
14143 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
14144 + const void *newval)
14146 + struct proc_dir_entry *tmp;
14147 + struct nameidata nd;
14148 + const char *proc_sys = "/proc/sys";
14150 + struct acl_object_label *obj;
14151 + unsigned short len = 0, pos = 0, depth = 0, i;
14155 + if (unlikely(!(gr_status & GR_READY)))
14158 + path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
14163 + mode |= GR_WRITE;
14165 + /* convert the requested sysctl entry into a pathname */
14167 + for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
14168 + len += strlen(tmp->name);
14173 + if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
14174 + return 0; /* deny */
14176 + memset(path, 0, PAGE_SIZE);
14178 + memcpy(path, proc_sys, strlen(proc_sys));
14180 + pos += strlen(proc_sys);
14182 + for (; depth > 0; depth--) {
14185 + for (i = 1, tmp = table->de; tmp != proc_sys_root;
14186 + tmp = tmp->parent) {
14187 + if (depth == i) {
14188 + memcpy(path + pos, tmp->name,
14189 + strlen(tmp->name));
14190 + pos += strlen(tmp->name);
14196 + err = path_lookup(path, LOOKUP_FOLLOW, &nd);
14201 + obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
14202 + err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
14204 + if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
14205 + ((err & mode) != mode))) {
14206 + __u32 new_mode = mode;
14208 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
14211 + gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
14212 + } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
14213 + gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
14214 + path, (mode & GR_READ) ? " reading" : "",
14215 + (mode & GR_WRITE) ? " writing" : "");
14217 + } else if ((err & mode) != mode) {
14219 + } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
14220 + gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
14221 + path, (mode & GR_READ) ? " reading" : "",
14222 + (mode & GR_WRITE) ? " writing" : "");
14225 + path_release(&nd);
14233 +gr_handle_proc_ptrace(struct task_struct *task)
14235 + struct file *filp;
14236 + struct task_struct *tmp = task;
14237 + struct task_struct *curtemp = current;
14240 + if (unlikely(!(gr_status & GR_READY)))
14243 + read_lock(&tasklist_lock);
14244 + read_lock(&grsec_exec_file_lock);
14245 + filp = task->exec_file;
14247 + while (tmp->pid > 0) {
14248 + if (tmp == curtemp)
14250 + tmp = tmp->parent;
14253 + if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
14254 + read_unlock(&grsec_exec_file_lock);
14255 + read_unlock(&tasklist_lock);
14259 + retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
14260 + read_unlock(&grsec_exec_file_lock);
14261 + read_unlock(&tasklist_lock);
14263 + if (retmode & GR_NOPTRACE)
14266 + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
14267 + && (current->acl != task->acl || (current->acl != current->role->root_label
14268 + && current->pid != task->pid)))
14275 +gr_handle_ptrace(struct task_struct *task, const long request)
14277 + struct task_struct *tmp = task;
14278 + struct task_struct *curtemp = current;
14281 + if (unlikely(!(gr_status & GR_READY)))
14284 + read_lock(&tasklist_lock);
14285 + while (tmp->pid > 0) {
14286 + if (tmp == curtemp)
14288 + tmp = tmp->parent;
14291 + if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
14292 + read_unlock(&tasklist_lock);
14293 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
14296 + read_unlock(&tasklist_lock);
14298 + read_lock(&grsec_exec_file_lock);
14299 + if (unlikely(!task->exec_file)) {
14300 + read_unlock(&grsec_exec_file_lock);
14304 + retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
14305 + read_unlock(&grsec_exec_file_lock);
14307 + if (retmode & GR_NOPTRACE) {
14308 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
14312 + if (retmode & GR_PTRACERD) {
14313 + switch (request) {
14314 + case PTRACE_POKETEXT:
14315 + case PTRACE_POKEDATA:
14316 + case PTRACE_POKEUSR:
14317 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
14318 + case PTRACE_SETREGS:
14319 + case PTRACE_SETFPREGS:
14322 + case PTRACE_SETFPXREGS:
14324 +#ifdef CONFIG_ALTIVEC
14325 + case PTRACE_SETVRREGS:
14331 + } else if (!(current->acl->mode & GR_POVERRIDE) &&
14332 + !(current->role->roletype & GR_ROLE_GOD) &&
14333 + (current->acl != task->acl)) {
14334 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
14341 +static int is_writable_mmap(const struct file *filp)
14343 + struct task_struct *task = current;
14344 + struct acl_object_label *obj, *obj2;
14346 + if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
14347 + !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
14348 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
14349 + obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
14350 + task->role->root_label);
14351 + if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
14352 + gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
14360 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
14364 + if (unlikely(!file || !(prot & PROT_EXEC)))
14367 + if (is_writable_mmap(file))
14371 + gr_search_file(file->f_dentry,
14372 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
14375 + if (!gr_tpe_allow(file))
14378 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
14379 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
14381 + } else if (unlikely(!(mode & GR_EXEC))) {
14383 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
14384 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
14392 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
14396 + if (unlikely(!file || !(prot & PROT_EXEC)))
14399 + if (is_writable_mmap(file))
14403 + gr_search_file(file->f_dentry,
14404 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
14407 + if (!gr_tpe_allow(file))
14410 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
14411 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
14413 + } else if (unlikely(!(mode & GR_EXEC))) {
14415 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
14416 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
14424 +gr_acl_handle_psacct(struct task_struct *task, const long code)
14426 + unsigned long runtime;
14427 + unsigned long cputime;
14428 + unsigned int wday, cday;
14433 + if (unlikely(!(gr_status & GR_READY) || !task->acl ||
14434 + !(task->acl->mode & GR_PROCACCT)))
14437 + runtime = xtime.tv_sec - task->start_time.tv_sec;
14438 + wday = runtime / (3600 * 24);
14439 + runtime -= wday * (3600 * 24);
14440 + whr = runtime / 3600;
14441 + runtime -= whr * 3600;
14442 + wmin = runtime / 60;
14443 + runtime -= wmin * 60;
14446 + cputime = (task->utime + task->stime) / HZ;
14447 + cday = cputime / (3600 * 24);
14448 + cputime -= cday * (3600 * 24);
14449 + chr = cputime / 3600;
14450 + cputime -= chr * 3600;
14451 + cmin = cputime / 60;
14452 + cputime -= cmin * 60;
14455 + gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
14460 +void gr_set_kernel_label(struct task_struct *task)
14462 + if (gr_status & GR_READY) {
14463 + task->role = kernel_role;
14464 + task->acl = kernel_role->root_label;
14469 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
14471 + struct task_struct *task = current;
14472 + struct dentry *dentry = file->f_dentry;
14473 + struct vfsmount *mnt = file->f_vfsmnt;
14474 + struct acl_object_label *obj, *tmp;
14475 + struct acl_subject_label *subj;
14476 + unsigned int bufsize;
14480 + if (unlikely(!(gr_status & GR_READY)))
14483 + if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
14486 + subj = task->acl;
14488 + obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
14490 + return (obj->mode & GR_FIND) ? 1 : 0;
14491 + } while ((subj = subj->parent_subject));
14493 + obj = chk_obj_label(dentry, mnt, task->acl);
14494 + if (obj->globbed == NULL)
14495 + return (obj->mode & GR_FIND) ? 1 : 0;
14497 + is_not_root = ((obj->filename[0] == '/') &&
14498 + (obj->filename[1] == '\0')) ? 0 : 1;
14499 + bufsize = PAGE_SIZE - namelen - is_not_root;
14501 + /* check bufsize > PAGE_SIZE || bufsize == 0 */
14502 + if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
14505 + preempt_disable();
14506 + path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
14509 + bufsize = strlen(path);
14511 + /* if base is "/", don't append an additional slash */
14513 + *(path + bufsize) = '/';
14514 + memcpy(path + bufsize + is_not_root, name, namelen);
14515 + *(path + bufsize + namelen + is_not_root) = '\0';
14517 + tmp = obj->globbed;
14519 + if (!glob_match(tmp->filename, path)) {
14520 + preempt_enable();
14521 + return (tmp->mode & GR_FIND) ? 1 : 0;
14525 + preempt_enable();
14526 + return (obj->mode & GR_FIND) ? 1 : 0;
14529 +EXPORT_SYMBOL(gr_learn_resource);
14530 +EXPORT_SYMBOL(gr_set_kernel_label);
14531 +#ifdef CONFIG_SECURITY
14532 +EXPORT_SYMBOL(gr_check_user_change);
14533 +EXPORT_SYMBOL(gr_check_group_change);
14536 diff -urNp linux-2.6.17.7/grsecurity/gracl_alloc.c linux-2.6.17.7/grsecurity/gracl_alloc.c
14537 --- linux-2.6.17.7/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
14538 +++ linux-2.6.17.7/grsecurity/gracl_alloc.c 2006-08-01 20:29:46.000000000 -0400
14540 +#include <linux/kernel.h>
14541 +#include <linux/mm.h>
14542 +#include <linux/slab.h>
14543 +#include <linux/vmalloc.h>
14544 +#include <linux/gracl.h>
14545 +#include <linux/grsecurity.h>
14547 +static unsigned long alloc_stack_next = 1;
14548 +static unsigned long alloc_stack_size = 1;
14549 +static void **alloc_stack;
14551 +static __inline__ int
14554 + if (alloc_stack_next == 1)
14557 + kfree(alloc_stack[alloc_stack_next - 2]);
14559 + alloc_stack_next--;
14564 +static __inline__ void
14565 +alloc_push(void *buf)
14567 + if (alloc_stack_next >= alloc_stack_size)
14570 + alloc_stack[alloc_stack_next - 1] = buf;
14572 + alloc_stack_next++;
14578 +acl_alloc(unsigned long len)
14582 + if (len > PAGE_SIZE)
14585 + ret = kmalloc(len, GFP_KERNEL);
14594 +acl_free_all(void)
14596 + if (gr_acl_is_enabled() || !alloc_stack)
14599 + while (alloc_pop()) ;
14601 + if (alloc_stack) {
14602 + if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
14603 + kfree(alloc_stack);
14605 + vfree(alloc_stack);
14608 + alloc_stack = NULL;
14609 + alloc_stack_size = 1;
14610 + alloc_stack_next = 1;
14616 +acl_alloc_stack_init(unsigned long size)
14618 + if ((size * sizeof (void *)) <= PAGE_SIZE)
14620 + (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
14622 + alloc_stack = (void **) vmalloc(size * sizeof (void *));
14624 + alloc_stack_size = size;
14626 + if (!alloc_stack)
14631 diff -urNp linux-2.6.17.7/grsecurity/gracl_cap.c linux-2.6.17.7/grsecurity/gracl_cap.c
14632 --- linux-2.6.17.7/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
14633 +++ linux-2.6.17.7/grsecurity/gracl_cap.c 2006-08-01 20:29:47.000000000 -0400
14635 +#include <linux/kernel.h>
14636 +#include <linux/module.h>
14637 +#include <linux/sched.h>
14638 +#include <linux/capability.h>
14639 +#include <linux/gracl.h>
14640 +#include <linux/grsecurity.h>
14641 +#include <linux/grinternal.h>
14643 +static const char *captab_log[] = {
14645 + "CAP_DAC_OVERRIDE",
14646 + "CAP_DAC_READ_SEARCH",
14653 + "CAP_LINUX_IMMUTABLE",
14654 + "CAP_NET_BIND_SERVICE",
14655 + "CAP_NET_BROADCAST",
14660 + "CAP_SYS_MODULE",
14662 + "CAP_SYS_CHROOT",
14663 + "CAP_SYS_PTRACE",
14668 + "CAP_SYS_RESOURCE",
14670 + "CAP_SYS_TTY_CONFIG",
14675 +EXPORT_SYMBOL(gr_task_is_capable);
14678 +gr_task_is_capable(struct task_struct *task, const int cap)
14680 + struct acl_subject_label *curracl;
14681 + __u32 cap_drop = 0, cap_mask = 0;
14683 + if (!gr_acl_is_enabled())
14686 + curracl = task->acl;
14688 + cap_drop = curracl->cap_lower;
14689 + cap_mask = curracl->cap_mask;
14691 + while ((curracl = curracl->parent_subject)) {
14692 + if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
14693 + cap_drop |= curracl->cap_lower & (1 << cap);
14694 + cap_mask |= curracl->cap_mask;
14697 + if (!cap_raised(cap_drop, cap))
14700 + curracl = task->acl;
14702 + if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
14703 + && cap_raised(task->cap_effective, cap)) {
14704 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
14705 + task->role->roletype, task->uid,
14706 + task->gid, task->exec_file ?
14707 + gr_to_filename(task->exec_file->f_dentry,
14708 + task->exec_file->f_vfsmnt) : curracl->filename,
14709 + curracl->filename, 0UL,
14710 + 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
14714 + if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
14715 + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
14721 +gr_is_capable_nolog(const int cap)
14723 + struct acl_subject_label *curracl;
14724 + __u32 cap_drop = 0, cap_mask = 0;
14726 + if (!gr_acl_is_enabled())
14729 + curracl = current->acl;
14731 + cap_drop = curracl->cap_lower;
14732 + cap_mask = curracl->cap_mask;
14734 + while ((curracl = curracl->parent_subject)) {
14735 + cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
14736 + cap_mask |= curracl->cap_mask;
14739 + if (!cap_raised(cap_drop, cap))
14745 diff -urNp linux-2.6.17.7/grsecurity/gracl_fs.c linux-2.6.17.7/grsecurity/gracl_fs.c
14746 --- linux-2.6.17.7/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
14747 +++ linux-2.6.17.7/grsecurity/gracl_fs.c 2006-08-01 20:29:47.000000000 -0400
14749 +#include <linux/kernel.h>
14750 +#include <linux/sched.h>
14751 +#include <linux/types.h>
14752 +#include <linux/fs.h>
14753 +#include <linux/file.h>
14754 +#include <linux/stat.h>
14755 +#include <linux/grsecurity.h>
14756 +#include <linux/grinternal.h>
14757 +#include <linux/gracl.h>
14760 +gr_acl_handle_hidden_file(const struct dentry * dentry,
14761 + const struct vfsmount * mnt)
14765 + if (unlikely(!dentry->d_inode))
14769 + gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
14771 + if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
14772 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
14774 + } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
14775 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
14777 + } else if (unlikely(!(mode & GR_FIND)))
14784 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
14787 + __u32 reqmode = GR_FIND;
14790 + if (unlikely(!dentry->d_inode))
14793 + if (unlikely(fmode & O_APPEND))
14794 + reqmode |= GR_APPEND;
14795 + else if (unlikely(fmode & FMODE_WRITE))
14796 + reqmode |= GR_WRITE;
14797 + if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
14798 + reqmode |= GR_READ;
14801 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
14804 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
14805 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
14806 + reqmode & GR_READ ? " reading" : "",
14807 + reqmode & GR_WRITE ? " writing" : reqmode &
14808 + GR_APPEND ? " appending" : "");
14811 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
14813 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
14814 + reqmode & GR_READ ? " reading" : "",
14815 + reqmode & GR_WRITE ? " writing" : reqmode &
14816 + GR_APPEND ? " appending" : "");
14818 + } else if (unlikely((mode & reqmode) != reqmode))
14825 +gr_acl_handle_creat(const struct dentry * dentry,
14826 + const struct dentry * p_dentry,
14827 + const struct vfsmount * p_mnt, const int fmode,
14830 + __u32 reqmode = GR_WRITE | GR_CREATE;
14833 + if (unlikely(fmode & O_APPEND))
14834 + reqmode |= GR_APPEND;
14835 + if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
14836 + reqmode |= GR_READ;
14837 + if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
14838 + reqmode |= GR_SETID;
14841 + gr_check_create(dentry, p_dentry, p_mnt,
14842 + reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
14844 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
14845 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
14846 + reqmode & GR_READ ? " reading" : "",
14847 + reqmode & GR_WRITE ? " writing" : reqmode &
14848 + GR_APPEND ? " appending" : "");
14851 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
14853 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
14854 + reqmode & GR_READ ? " reading" : "",
14855 + reqmode & GR_WRITE ? " writing" : reqmode &
14856 + GR_APPEND ? " appending" : "");
14858 + } else if (unlikely((mode & reqmode) != reqmode))
14865 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
14868 + __u32 mode, reqmode = GR_FIND;
14870 + if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
14871 + reqmode |= GR_EXEC;
14872 + if (fmode & S_IWOTH)
14873 + reqmode |= GR_WRITE;
14874 + if (fmode & S_IROTH)
14875 + reqmode |= GR_READ;
14878 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
14881 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
14882 + gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
14883 + reqmode & GR_READ ? " reading" : "",
14884 + reqmode & GR_WRITE ? " writing" : "",
14885 + reqmode & GR_EXEC ? " executing" : "");
14888 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
14890 + gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
14891 + reqmode & GR_READ ? " reading" : "",
14892 + reqmode & GR_WRITE ? " writing" : "",
14893 + reqmode & GR_EXEC ? " executing" : "");
14895 + } else if (unlikely((mode & reqmode) != reqmode))
14901 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
14905 + mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
14907 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
14908 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
14910 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
14911 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
14913 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
14916 + return (reqmode);
14920 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
14922 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
14926 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
14928 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
14932 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
14934 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
14938 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
14940 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
14944 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
14947 + if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
14950 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
14951 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
14952 + GR_FCHMOD_ACL_MSG);
14954 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
14959 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
14962 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
14963 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
14964 + GR_CHMOD_ACL_MSG);
14966 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
14971 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
14973 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
14977 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
14979 + return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
14983 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
14985 + return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
14986 + GR_UNIXCONNECT_ACL_MSG);
14989 +/* hardlinks require at minimum create permission,
14990 + any additional privilege required is based on the
14991 + privilege of the file being linked to
14994 +gr_acl_handle_link(const struct dentry * new_dentry,
14995 + const struct dentry * parent_dentry,
14996 + const struct vfsmount * parent_mnt,
14997 + const struct dentry * old_dentry,
14998 + const struct vfsmount * old_mnt, const char *to)
15001 + __u32 needmode = GR_CREATE | GR_LINK;
15002 + __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
15005 + gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
15008 + if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
15009 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
15011 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
15012 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
15014 + } else if (unlikely((mode & needmode) != needmode))
15021 +gr_acl_handle_symlink(const struct dentry * new_dentry,
15022 + const struct dentry * parent_dentry,
15023 + const struct vfsmount * parent_mnt, const char *from)
15025 + __u32 needmode = GR_WRITE | GR_CREATE;
15029 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
15030 + GR_CREATE | GR_AUDIT_CREATE |
15031 + GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
15033 + if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
15034 + gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
15036 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
15037 + gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
15039 + } else if (unlikely((mode & needmode) != needmode))
15042 + return (GR_WRITE | GR_CREATE);
15045 +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)
15049 + mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
15051 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
15052 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
15054 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
15055 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
15057 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
15060 + return (reqmode);
15064 +gr_acl_handle_mknod(const struct dentry * new_dentry,
15065 + const struct dentry * parent_dentry,
15066 + const struct vfsmount * parent_mnt,
15069 + __u32 reqmode = GR_WRITE | GR_CREATE;
15070 + if (unlikely(mode & (S_ISUID | S_ISGID)))
15071 + reqmode |= GR_SETID;
15073 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
15074 + reqmode, GR_MKNOD_ACL_MSG);
15078 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
15079 + const struct dentry *parent_dentry,
15080 + const struct vfsmount *parent_mnt)
15082 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
15083 + GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
15086 +#define RENAME_CHECK_SUCCESS(old, new) \
15087 + (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
15088 + ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
15091 +gr_acl_handle_rename(struct dentry *new_dentry,
15092 + struct dentry *parent_dentry,
15093 + const struct vfsmount *parent_mnt,
15094 + struct dentry *old_dentry,
15095 + struct inode *old_parent_inode,
15096 + struct vfsmount *old_mnt, const char *newname)
15098 + __u32 comp1, comp2;
15101 + if (unlikely(!gr_acl_is_enabled()))
15104 + if (!new_dentry->d_inode) {
15105 + comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
15106 + GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
15107 + GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
15108 + comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
15109 + GR_DELETE | GR_AUDIT_DELETE |
15110 + GR_AUDIT_READ | GR_AUDIT_WRITE |
15111 + GR_SUPPRESS, old_mnt);
15113 + comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
15114 + GR_CREATE | GR_DELETE |
15115 + GR_AUDIT_CREATE | GR_AUDIT_DELETE |
15116 + GR_AUDIT_READ | GR_AUDIT_WRITE |
15117 + GR_SUPPRESS, parent_mnt);
15119 + gr_search_file(old_dentry,
15120 + GR_READ | GR_WRITE | GR_AUDIT_READ |
15121 + GR_DELETE | GR_AUDIT_DELETE |
15122 + GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
15125 + if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
15126 + ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
15127 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
15128 + else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
15129 + && !(comp2 & GR_SUPPRESS)) {
15130 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
15132 + } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
15139 +gr_acl_handle_exit(void)
15143 + struct file *exec_file;
15145 + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
15146 + id = current->acl_role_id;
15147 + rolename = current->role->rolename;
15149 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
15152 + write_lock(&grsec_exec_file_lock);
15153 + exec_file = current->exec_file;
15154 + current->exec_file = NULL;
15155 + write_unlock(&grsec_exec_file_lock);
15162 +gr_acl_handle_procpidmem(const struct task_struct *task)
15164 + if (unlikely(!gr_acl_is_enabled()))
15167 + if (task->acl->mode & GR_PROTPROCFD)
15172 diff -urNp linux-2.6.17.7/grsecurity/gracl_ip.c linux-2.6.17.7/grsecurity/gracl_ip.c
15173 --- linux-2.6.17.7/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
15174 +++ linux-2.6.17.7/grsecurity/gracl_ip.c 2006-08-01 20:29:47.000000000 -0400
15176 +#include <linux/kernel.h>
15177 +#include <asm/uaccess.h>
15178 +#include <asm/errno.h>
15179 +#include <net/sock.h>
15180 +#include <linux/file.h>
15181 +#include <linux/fs.h>
15182 +#include <linux/net.h>
15183 +#include <linux/in.h>
15184 +#include <linux/skbuff.h>
15185 +#include <linux/ip.h>
15186 +#include <linux/udp.h>
15187 +#include <linux/smp_lock.h>
15188 +#include <linux/types.h>
15189 +#include <linux/sched.h>
15190 +#include <linux/netdevice.h>
15191 +#include <linux/inetdevice.h>
15192 +#include <linux/gracl.h>
15193 +#include <linux/grsecurity.h>
15194 +#include <linux/grinternal.h>
15196 +#define GR_BIND 0x01
15197 +#define GR_CONNECT 0x02
15198 +#define GR_INVERT 0x04
15200 +static const char * gr_protocols[256] = {
15201 + "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
15202 + "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
15203 + "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
15204 + "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
15205 + "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
15206 + "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
15207 + "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
15208 + "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
15209 + "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
15210 + "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
15211 + "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
15212 + "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
15213 + "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
15214 + "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
15215 + "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
15216 + "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
15217 + "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
15218 + "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
15219 + "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
15220 + "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
15221 + "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
15222 + "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
15223 + "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
15224 + "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
15225 + "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
15226 + "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
15227 + "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
15228 + "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
15229 + "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
15230 + "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
15231 + "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
15232 + "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
15235 +static const char * gr_socktypes[11] = {
15236 + "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
15237 + "unknown:7", "unknown:8", "unknown:9", "packet"
15241 +gr_proto_to_name(unsigned char proto)
15243 + return gr_protocols[proto];
15247 +gr_socktype_to_name(unsigned char type)
15249 + return gr_socktypes[type];
15253 +gr_search_socket(const int domain, const int type, const int protocol)
15255 + struct acl_subject_label *curr;
15257 + if (unlikely(!gr_acl_is_enabled()))
15260 + if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
15261 + || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
15262 + goto exit; // let the kernel handle it
15264 + curr = current->acl;
15269 + if ((curr->ip_type & (1 << type)) &&
15270 + (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
15273 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
15274 + /* we don't place acls on raw sockets , and sometimes
15275 + dgram/ip sockets are opened for ioctl and not
15276 + bind/connect, so we'll fake a bind learn log */
15277 + if (type == SOCK_RAW || type == SOCK_PACKET) {
15278 + __u32 fakeip = 0;
15279 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
15280 + current->role->roletype, current->uid,
15281 + current->gid, current->exec_file ?
15282 + gr_to_filename(current->exec_file->f_dentry,
15283 + current->exec_file->f_vfsmnt) :
15284 + curr->filename, curr->filename,
15285 + NIPQUAD(fakeip), 0, type,
15286 + protocol, GR_CONNECT,
15287 +NIPQUAD(current->signal->curr_ip));
15288 + } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
15289 + __u32 fakeip = 0;
15290 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
15291 + current->role->roletype, current->uid,
15292 + current->gid, current->exec_file ?
15293 + gr_to_filename(current->exec_file->f_dentry,
15294 + current->exec_file->f_vfsmnt) :
15295 + curr->filename, curr->filename,
15296 + NIPQUAD(fakeip), 0, type,
15297 + protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
15299 + /* we'll log when they use connect or bind */
15303 + gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
15304 + gr_socktype_to_name(type), gr_proto_to_name(protocol));
15311 +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)
15313 + if ((ip->mode & mode) &&
15314 + (ip_port >= ip->low) &&
15315 + (ip_port <= ip->high) &&
15316 + ((ntohl(ip_addr) & our_netmask) ==
15317 + (ntohl(our_addr) & our_netmask))
15318 + && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
15319 + && (ip->type & (1 << type))) {
15320 + if (ip->mode & GR_INVERT)
15321 + return 2; // specifically denied
15323 + return 1; // allowed
15326 + return 0; // not specifically allowed, may continue parsing
15330 +gr_search_connectbind(const int mode, const struct sock *sk,
15331 + const struct sockaddr_in *addr, const int type)
15333 + char iface[IFNAMSIZ] = {0};
15334 + struct acl_subject_label *curr;
15335 + struct acl_ip_label *ip;
15336 + struct net_device *dev;
15337 + struct in_device *idev;
15340 + __u32 ip_addr = 0;
15342 + __u32 our_netmask;
15344 + __u16 ip_port = 0;
15346 + if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
15349 + curr = current->acl;
15354 + ip_addr = addr->sin_addr.s_addr;
15355 + ip_port = ntohs(addr->sin_port);
15357 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
15358 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
15359 + current->role->roletype, current->uid,
15360 + current->gid, current->exec_file ?
15361 + gr_to_filename(current->exec_file->f_dentry,
15362 + current->exec_file->f_vfsmnt) :
15363 + curr->filename, curr->filename,
15364 + NIPQUAD(ip_addr), ip_port, type,
15365 + sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
15369 + for (i = 0; i < curr->ip_num; i++) {
15370 + ip = *(curr->ips + i);
15371 + if (ip->iface != NULL) {
15372 + strncpy(iface, ip->iface, IFNAMSIZ - 1);
15373 + p = strchr(iface, ':');
15376 + dev = dev_get_by_name(iface);
15379 + idev = in_dev_get(dev);
15380 + if (idev == NULL) {
15386 + if (!strcmp(ip->iface, ifa->ifa_label)) {
15387 + our_addr = ifa->ifa_address;
15388 + our_netmask = 0xffffffff;
15389 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
15391 + rcu_read_unlock();
15392 + in_dev_put(idev);
15395 + } else if (ret == 2) {
15396 + rcu_read_unlock();
15397 + in_dev_put(idev);
15402 + } endfor_ifa(idev);
15403 + rcu_read_unlock();
15404 + in_dev_put(idev);
15407 + our_addr = ip->addr;
15408 + our_netmask = ip->netmask;
15409 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
15412 + else if (ret == 2)
15418 + if (mode == GR_BIND)
15419 + 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));
15420 + else if (mode == GR_CONNECT)
15421 + 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));
15427 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
15429 + return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
15433 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
15435 + return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
15438 +int gr_search_listen(const struct socket *sock)
15440 + struct sock *sk = sock->sk;
15441 + struct sockaddr_in addr;
15443 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
15444 + addr.sin_port = inet_sk(sk)->sport;
15446 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
15449 +int gr_search_accept(const struct socket *sock)
15451 + struct sock *sk = sock->sk;
15452 + struct sockaddr_in addr;
15454 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
15455 + addr.sin_port = inet_sk(sk)->sport;
15457 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
15461 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
15464 + return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
15466 + struct sockaddr_in sin;
15467 + const struct inet_sock *inet = inet_sk(sk);
15469 + sin.sin_addr.s_addr = inet->daddr;
15470 + sin.sin_port = inet->dport;
15472 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
15477 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
15479 + struct sockaddr_in sin;
15481 + if (unlikely(skb->len < sizeof (struct udphdr)))
15482 + return 1; // skip this packet
15484 + sin.sin_addr.s_addr = skb->nh.iph->saddr;
15485 + sin.sin_port = skb->h.uh->source;
15487 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
15489 diff -urNp linux-2.6.17.7/grsecurity/gracl_learn.c linux-2.6.17.7/grsecurity/gracl_learn.c
15490 --- linux-2.6.17.7/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
15491 +++ linux-2.6.17.7/grsecurity/gracl_learn.c 2006-08-01 20:29:47.000000000 -0400
15493 +#include <linux/kernel.h>
15494 +#include <linux/mm.h>
15495 +#include <linux/sched.h>
15496 +#include <linux/poll.h>
15497 +#include <linux/smp_lock.h>
15498 +#include <linux/string.h>
15499 +#include <linux/file.h>
15500 +#include <linux/types.h>
15501 +#include <linux/vmalloc.h>
15502 +#include <linux/grinternal.h>
15504 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
15505 + size_t count, loff_t *ppos);
15506 +extern int gr_acl_is_enabled(void);
15508 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
15509 +static int gr_learn_attached;
15511 +/* use a 512k buffer */
15512 +#define LEARN_BUFFER_SIZE (512 * 1024)
15514 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
15515 +static DECLARE_MUTEX(gr_learn_user_sem);
15517 +/* we need to maintain two buffers, so that the kernel context of grlearn
15518 + uses a semaphore around the userspace copying, and the other kernel contexts
15519 + use a spinlock when copying into the buffer, since they cannot sleep
15521 +static char *learn_buffer;
15522 +static char *learn_buffer_user;
15523 +static int learn_buffer_len;
15524 +static int learn_buffer_user_len;
15527 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
15529 + DECLARE_WAITQUEUE(wait, current);
15530 + ssize_t retval = 0;
15532 + add_wait_queue(&learn_wait, &wait);
15533 + set_current_state(TASK_INTERRUPTIBLE);
15535 + down(&gr_learn_user_sem);
15536 + spin_lock(&gr_learn_lock);
15537 + if (learn_buffer_len)
15539 + spin_unlock(&gr_learn_lock);
15540 + up(&gr_learn_user_sem);
15541 + if (file->f_flags & O_NONBLOCK) {
15542 + retval = -EAGAIN;
15545 + if (signal_pending(current)) {
15546 + retval = -ERESTARTSYS;
15553 + memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
15554 + learn_buffer_user_len = learn_buffer_len;
15555 + retval = learn_buffer_len;
15556 + learn_buffer_len = 0;
15558 + spin_unlock(&gr_learn_lock);
15560 + if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
15561 + retval = -EFAULT;
15563 + up(&gr_learn_user_sem);
15565 + set_current_state(TASK_RUNNING);
15566 + remove_wait_queue(&learn_wait, &wait);
15570 +static unsigned int
15571 +poll_learn(struct file * file, poll_table * wait)
15573 + poll_wait(file, &learn_wait, wait);
15575 + if (learn_buffer_len)
15576 + return (POLLIN | POLLRDNORM);
15582 +gr_clear_learn_entries(void)
15586 + down(&gr_learn_user_sem);
15587 + if (learn_buffer != NULL) {
15588 + spin_lock(&gr_learn_lock);
15589 + tmp = learn_buffer;
15590 + learn_buffer = NULL;
15591 + spin_unlock(&gr_learn_lock);
15592 + vfree(learn_buffer);
15594 + if (learn_buffer_user != NULL) {
15595 + vfree(learn_buffer_user);
15596 + learn_buffer_user = NULL;
15598 + learn_buffer_len = 0;
15599 + up(&gr_learn_user_sem);
15605 +gr_add_learn_entry(const char *fmt, ...)
15608 + unsigned int len;
15610 + if (!gr_learn_attached)
15613 + spin_lock(&gr_learn_lock);
15615 + /* leave a gap at the end so we know when it's "full" but don't have to
15616 + compute the exact length of the string we're trying to append
15618 + if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
15619 + spin_unlock(&gr_learn_lock);
15620 + wake_up_interruptible(&learn_wait);
15623 + if (learn_buffer == NULL) {
15624 + spin_unlock(&gr_learn_lock);
15628 + va_start(args, fmt);
15629 + len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
15632 + learn_buffer_len += len + 1;
15634 + spin_unlock(&gr_learn_lock);
15635 + wake_up_interruptible(&learn_wait);
15641 +open_learn(struct inode *inode, struct file *file)
15643 + if (file->f_mode & FMODE_READ && gr_learn_attached)
15645 + if (file->f_mode & FMODE_READ) {
15646 + down(&gr_learn_user_sem);
15647 + if (learn_buffer == NULL)
15648 + learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
15649 + if (learn_buffer_user == NULL)
15650 + learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
15651 + if (learn_buffer == NULL)
15653 + if (learn_buffer_user == NULL)
15655 + learn_buffer_len = 0;
15656 + learn_buffer_user_len = 0;
15657 + gr_learn_attached = 1;
15658 + up(&gr_learn_user_sem);
15664 +close_learn(struct inode *inode, struct file *file)
15668 + if (file->f_mode & FMODE_READ) {
15669 + down(&gr_learn_user_sem);
15670 + if (learn_buffer != NULL) {
15671 + spin_lock(&gr_learn_lock);
15672 + tmp = learn_buffer;
15673 + learn_buffer = NULL;
15674 + spin_unlock(&gr_learn_lock);
15677 + if (learn_buffer_user != NULL) {
15678 + vfree(learn_buffer_user);
15679 + learn_buffer_user = NULL;
15681 + learn_buffer_len = 0;
15682 + learn_buffer_user_len = 0;
15683 + gr_learn_attached = 0;
15684 + up(&gr_learn_user_sem);
15690 +struct file_operations grsec_fops = {
15691 + .read = read_learn,
15692 + .write = write_grsec_handler,
15693 + .open = open_learn,
15694 + .release = close_learn,
15695 + .poll = poll_learn,
15697 diff -urNp linux-2.6.17.7/grsecurity/gracl_res.c linux-2.6.17.7/grsecurity/gracl_res.c
15698 --- linux-2.6.17.7/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
15699 +++ linux-2.6.17.7/grsecurity/gracl_res.c 2006-08-01 20:29:47.000000000 -0400
15701 +#include <linux/kernel.h>
15702 +#include <linux/sched.h>
15703 +#include <linux/gracl.h>
15704 +#include <linux/grinternal.h>
15706 +static const char *restab_log[] = {
15707 + [RLIMIT_CPU] = "RLIMIT_CPU",
15708 + [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
15709 + [RLIMIT_DATA] = "RLIMIT_DATA",
15710 + [RLIMIT_STACK] = "RLIMIT_STACK",
15711 + [RLIMIT_CORE] = "RLIMIT_CORE",
15712 + [RLIMIT_RSS] = "RLIMIT_RSS",
15713 + [RLIMIT_NPROC] = "RLIMIT_NPROC",
15714 + [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
15715 + [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
15716 + [RLIMIT_AS] = "RLIMIT_AS",
15717 + [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
15718 + [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
15722 +gr_log_resource(const struct task_struct *task,
15723 + const int res, const unsigned long wanted, const int gt)
15725 + if (res == RLIMIT_NPROC &&
15726 + (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
15727 + cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
15729 + else if (res == RLIMIT_MEMLOCK &&
15730 + cap_raised(task->cap_effective, CAP_IPC_LOCK))
15733 + if (!gr_acl_is_enabled() && !grsec_resource_logging)
15736 + preempt_disable();
15738 + if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
15739 + (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
15740 + task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
15741 + gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
15742 + preempt_enable_no_resched();
15746 diff -urNp linux-2.6.17.7/grsecurity/gracl_segv.c linux-2.6.17.7/grsecurity/gracl_segv.c
15747 --- linux-2.6.17.7/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
15748 +++ linux-2.6.17.7/grsecurity/gracl_segv.c 2006-08-01 20:29:47.000000000 -0400
15750 +#include <linux/kernel.h>
15751 +#include <linux/mm.h>
15752 +#include <asm/uaccess.h>
15753 +#include <asm/errno.h>
15754 +#include <asm/mman.h>
15755 +#include <net/sock.h>
15756 +#include <linux/file.h>
15757 +#include <linux/fs.h>
15758 +#include <linux/net.h>
15759 +#include <linux/in.h>
15760 +#include <linux/smp_lock.h>
15761 +#include <linux/slab.h>
15762 +#include <linux/types.h>
15763 +#include <linux/sched.h>
15764 +#include <linux/timer.h>
15765 +#include <linux/gracl.h>
15766 +#include <linux/grsecurity.h>
15767 +#include <linux/grinternal.h>
15769 +static struct crash_uid *uid_set;
15770 +static unsigned short uid_used;
15771 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
15772 +extern rwlock_t gr_inode_lock;
15773 +extern struct acl_subject_label *
15774 + lookup_acl_subj_label(const ino_t inode, const dev_t dev,
15775 + struct acl_role_label *role);
15776 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
15779 +gr_init_uidset(void)
15782 + kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
15785 + return uid_set ? 1 : 0;
15789 +gr_free_uidset(void)
15798 +gr_find_uid(const uid_t uid)
15800 + struct crash_uid *tmp = uid_set;
15802 + int low = 0, high = uid_used - 1, mid;
15804 + while (high >= low) {
15805 + mid = (low + high) >> 1;
15806 + buid = tmp[mid].uid;
15818 +static __inline__ void
15819 +gr_insertsort(void)
15821 + unsigned short i, j;
15822 + struct crash_uid index;
15824 + for (i = 1; i < uid_used; i++) {
15825 + index = uid_set[i];
15827 + while ((j > 0) && uid_set[j - 1].uid > index.uid) {
15828 + uid_set[j] = uid_set[j - 1];
15831 + uid_set[j] = index;
15837 +static __inline__ void
15838 +gr_insert_uid(const uid_t uid, const unsigned long expires)
15842 + if (uid_used == GR_UIDTABLE_MAX)
15845 + loc = gr_find_uid(uid);
15848 + uid_set[loc].expires = expires;
15852 + uid_set[uid_used].uid = uid;
15853 + uid_set[uid_used].expires = expires;
15862 +gr_remove_uid(const unsigned short loc)
15864 + unsigned short i;
15866 + for (i = loc + 1; i < uid_used; i++)
15867 + uid_set[i - 1] = uid_set[i];
15875 +gr_check_crash_uid(const uid_t uid)
15880 + if (unlikely(!gr_acl_is_enabled()))
15883 + spin_lock(&gr_uid_lock);
15884 + loc = gr_find_uid(uid);
15889 + if (time_before_eq(uid_set[loc].expires, get_seconds()))
15890 + gr_remove_uid(loc);
15895 + spin_unlock(&gr_uid_lock);
15899 +static __inline__ int
15900 +proc_is_setxid(const struct task_struct *task)
15902 + if (task->uid != task->euid || task->uid != task->suid ||
15903 + task->uid != task->fsuid)
15905 + if (task->gid != task->egid || task->gid != task->sgid ||
15906 + task->gid != task->fsgid)
15911 +static __inline__ int
15912 +gr_fake_force_sig(int sig, struct task_struct *t)
15914 + unsigned long int flags;
15917 + spin_lock_irqsave(&t->sighand->siglock, flags);
15918 + if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
15919 + t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
15920 + sigdelset(&t->blocked, sig);
15921 + recalc_sigpending_tsk(t);
15923 + ret = specific_send_sig_info(sig, (void*)1L, t);
15924 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
15930 +gr_handle_crash(struct task_struct *task, const int sig)
15932 + struct acl_subject_label *curr;
15933 + struct acl_subject_label *curr2;
15934 + struct task_struct *tsk, *tsk2;
15936 + if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
15939 + if (unlikely(!gr_acl_is_enabled()))
15942 + curr = task->acl;
15944 + if (!(curr->resmask & (1 << GR_CRASH_RES)))
15947 + if (time_before_eq(curr->expires, get_seconds())) {
15948 + curr->expires = 0;
15949 + curr->crashes = 0;
15954 + if (!curr->expires)
15955 + curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
15957 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
15958 + time_after(curr->expires, get_seconds())) {
15959 + if (task->uid && proc_is_setxid(task)) {
15960 + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
15961 + spin_lock(&gr_uid_lock);
15962 + gr_insert_uid(task->uid, curr->expires);
15963 + spin_unlock(&gr_uid_lock);
15964 + curr->expires = 0;
15965 + curr->crashes = 0;
15966 + read_lock(&tasklist_lock);
15967 + do_each_thread(tsk2, tsk) {
15968 + if (tsk != task && tsk->uid == task->uid)
15969 + gr_fake_force_sig(SIGKILL, tsk);
15970 + } while_each_thread(tsk2, tsk);
15971 + read_unlock(&tasklist_lock);
15973 + gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
15974 + read_lock(&tasklist_lock);
15975 + do_each_thread(tsk2, tsk) {
15976 + if (likely(tsk != task)) {
15977 + curr2 = tsk->acl;
15979 + if (curr2->device == curr->device &&
15980 + curr2->inode == curr->inode)
15981 + gr_fake_force_sig(SIGKILL, tsk);
15983 + } while_each_thread(tsk2, tsk);
15984 + read_unlock(&tasklist_lock);
15992 +gr_check_crash_exec(const struct file *filp)
15994 + struct acl_subject_label *curr;
15996 + if (unlikely(!gr_acl_is_enabled()))
15999 + read_lock(&gr_inode_lock);
16000 + curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
16001 + filp->f_dentry->d_inode->i_sb->s_dev,
16003 + read_unlock(&gr_inode_lock);
16005 + if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
16006 + (!curr->crashes && !curr->expires))
16009 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
16010 + time_after(curr->expires, get_seconds()))
16012 + else if (time_before_eq(curr->expires, get_seconds())) {
16013 + curr->crashes = 0;
16014 + curr->expires = 0;
16021 +gr_handle_alertkill(struct task_struct *task)
16023 + struct acl_subject_label *curracl;
16025 + struct task_struct *p, *p2;
16027 + if (unlikely(!gr_acl_is_enabled()))
16030 + curracl = task->acl;
16031 + curr_ip = task->signal->curr_ip;
16033 + if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
16034 + read_lock(&tasklist_lock);
16035 + do_each_thread(p2, p) {
16036 + if (p->signal->curr_ip == curr_ip)
16037 + gr_fake_force_sig(SIGKILL, p);
16038 + } while_each_thread(p2, p);
16039 + read_unlock(&tasklist_lock);
16040 + } else if (curracl->mode & GR_KILLPROC)
16041 + gr_fake_force_sig(SIGKILL, task);
16045 diff -urNp linux-2.6.17.7/grsecurity/gracl_shm.c linux-2.6.17.7/grsecurity/gracl_shm.c
16046 --- linux-2.6.17.7/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
16047 +++ linux-2.6.17.7/grsecurity/gracl_shm.c 2006-08-01 20:29:47.000000000 -0400
16049 +#include <linux/kernel.h>
16050 +#include <linux/mm.h>
16051 +#include <linux/sched.h>
16052 +#include <linux/file.h>
16053 +#include <linux/ipc.h>
16054 +#include <linux/gracl.h>
16055 +#include <linux/grsecurity.h>
16056 +#include <linux/grinternal.h>
16057 +#include <linux/vs_pid.h>
16060 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16061 + const time_t shm_createtime, const uid_t cuid, const int shmid)
16063 + struct task_struct *task;
16065 + if (!gr_acl_is_enabled())
16068 + task = find_task_by_pid(shm_cprid);
16070 + if (unlikely(!task))
16071 + task = find_task_by_pid(shm_lapid);
16073 + if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
16074 + (task->pid == shm_lapid)) &&
16075 + (task->acl->mode & GR_PROTSHM) &&
16076 + (task->acl != current->acl))) {
16077 + gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
16083 diff -urNp linux-2.6.17.7/grsecurity/grsec_chdir.c linux-2.6.17.7/grsecurity/grsec_chdir.c
16084 --- linux-2.6.17.7/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
16085 +++ linux-2.6.17.7/grsecurity/grsec_chdir.c 2006-08-01 20:29:47.000000000 -0400
16087 +#include <linux/kernel.h>
16088 +#include <linux/sched.h>
16089 +#include <linux/fs.h>
16090 +#include <linux/file.h>
16091 +#include <linux/grsecurity.h>
16092 +#include <linux/grinternal.h>
16095 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
16097 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
16098 + if ((grsec_enable_chdir && grsec_enable_group &&
16099 + in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
16100 + !grsec_enable_group)) {
16101 + gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
16106 diff -urNp linux-2.6.17.7/grsecurity/grsec_chroot.c linux-2.6.17.7/grsecurity/grsec_chroot.c
16107 --- linux-2.6.17.7/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
16108 +++ linux-2.6.17.7/grsecurity/grsec_chroot.c 2006-08-01 20:29:47.000000000 -0400
16110 +#include <linux/kernel.h>
16111 +#include <linux/module.h>
16112 +#include <linux/sched.h>
16113 +#include <linux/file.h>
16114 +#include <linux/fs.h>
16115 +#include <linux/mount.h>
16116 +#include <linux/types.h>
16117 +#include <linux/grinternal.h>
16120 +gr_handle_chroot_unix(const pid_t pid)
16122 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
16123 + struct pid *spid = NULL;
16125 + if (unlikely(!grsec_enable_chroot_unix))
16128 + if (likely(!proc_is_chrooted(current)))
16131 + read_lock(&tasklist_lock);
16133 + spid = find_pid(pid);
16135 + struct task_struct *p;
16136 + p = pid_task(spid, PIDTYPE_PID);
16138 + if (unlikely(!have_same_root(current, p))) {
16140 + read_unlock(&tasklist_lock);
16141 + gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
16146 + read_unlock(&tasklist_lock);
16152 +gr_handle_chroot_nice(void)
16154 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16155 + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
16156 + gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
16164 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
16166 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16167 + if (grsec_enable_chroot_nice && (niceval < task_nice(p))
16168 + && proc_is_chrooted(current)) {
16169 + gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
16177 +gr_handle_chroot_rawio(const struct inode *inode)
16179 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16180 + if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
16181 + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
16188 +gr_pid_is_chrooted(struct task_struct *p)
16190 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
16191 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !p)
16195 + if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
16196 + !have_same_root(current, p)) {
16205 +EXPORT_SYMBOL(gr_pid_is_chrooted);
16207 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
16208 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
16210 + struct dentry *dentry = (struct dentry *)u_dentry;
16211 + struct vfsmount *mnt = (struct vfsmount *)u_mnt;
16212 + struct dentry *realroot;
16213 + struct vfsmount *realrootmnt;
16214 + struct dentry *currentroot;
16215 + struct vfsmount *currentmnt;
16218 + read_lock(&child_reaper->fs->lock);
16219 + realrootmnt = mntget(child_reaper->fs->rootmnt);
16220 + realroot = dget(child_reaper->fs->root);
16221 + read_unlock(&child_reaper->fs->lock);
16223 + read_lock(¤t->fs->lock);
16224 + currentmnt = mntget(current->fs->rootmnt);
16225 + currentroot = dget(current->fs->root);
16226 + read_unlock(¤t->fs->lock);
16228 + spin_lock(&dcache_lock);
16230 + if (unlikely((dentry == realroot && mnt == realrootmnt)
16231 + || (dentry == currentroot && mnt == currentmnt)))
16233 + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
16234 + if (mnt->mnt_parent == mnt)
16236 + dentry = mnt->mnt_mountpoint;
16237 + mnt = mnt->mnt_parent;
16240 + dentry = dentry->d_parent;
16242 + spin_unlock(&dcache_lock);
16244 + dput(currentroot);
16245 + mntput(currentmnt);
16247 + /* access is outside of chroot */
16248 + if (dentry == realroot && mnt == realrootmnt)
16252 + mntput(realrootmnt);
16258 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
16260 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
16261 + if (!grsec_enable_chroot_fchdir)
16264 + if (!proc_is_chrooted(current))
16266 + else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
16267 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
16275 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16276 + const time_t shm_createtime)
16278 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
16279 + struct pid *pid = NULL;
16280 + time_t starttime;
16282 + if (unlikely(!grsec_enable_chroot_shmat))
16285 + if (likely(!proc_is_chrooted(current)))
16288 + read_lock(&tasklist_lock);
16290 + pid = find_pid(shm_cprid);
16292 + struct task_struct *p;
16293 + p = pid_task(pid, PIDTYPE_PID);
16295 + starttime = p->start_time.tv_sec;
16296 + if (unlikely(!have_same_root(current, p) &&
16297 + time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
16299 + read_unlock(&tasklist_lock);
16300 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
16305 + pid = find_pid(shm_lapid);
16307 + struct task_struct *p;
16308 + p = pid_task(pid, PIDTYPE_PID);
16310 + if (unlikely(!have_same_root(current, p))) {
16312 + read_unlock(&tasklist_lock);
16313 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
16320 + read_unlock(&tasklist_lock);
16326 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
16328 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
16329 + if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
16330 + gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
16336 +gr_handle_chroot_mknod(const struct dentry *dentry,
16337 + const struct vfsmount *mnt, const int mode)
16339 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
16340 + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
16341 + proc_is_chrooted(current)) {
16342 + gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
16350 +gr_handle_chroot_mount(const struct dentry *dentry,
16351 + const struct vfsmount *mnt, const char *dev_name)
16353 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
16354 + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
16355 + gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
16363 +gr_handle_chroot_pivot(void)
16365 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
16366 + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
16367 + gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
16375 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
16377 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
16378 + if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
16379 + !gr_is_outside_chroot(dentry, mnt)) {
16380 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
16388 +gr_handle_chroot_caps(struct task_struct *task)
16390 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16391 + if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
16392 + task->cap_permitted =
16393 + cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
16394 + task->cap_inheritable =
16395 + cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
16396 + task->cap_effective =
16397 + cap_drop(task->cap_effective, GR_CHROOT_CAPS);
16404 +gr_handle_chroot_sysctl(const int op)
16406 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
16407 + if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
16415 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
16417 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
16418 + if (grsec_enable_chroot_chdir)
16419 + set_fs_pwd(current->fs, mnt, dentry);
16425 +gr_handle_chroot_chmod(const struct dentry *dentry,
16426 + const struct vfsmount *mnt, const int mode)
16428 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
16429 + if (grsec_enable_chroot_chmod &&
16430 + ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
16431 + proc_is_chrooted(current)) {
16432 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
16439 +#ifdef CONFIG_SECURITY
16440 +EXPORT_SYMBOL(gr_handle_chroot_caps);
16442 diff -urNp linux-2.6.17.7/grsecurity/grsec_disabled.c linux-2.6.17.7/grsecurity/grsec_disabled.c
16443 --- linux-2.6.17.7/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
16444 +++ linux-2.6.17.7/grsecurity/grsec_disabled.c 2006-08-01 20:29:47.000000000 -0400
16446 +#include <linux/kernel.h>
16447 +#include <linux/module.h>
16448 +#include <linux/config.h>
16449 +#include <linux/sched.h>
16450 +#include <linux/file.h>
16451 +#include <linux/fs.h>
16452 +#include <linux/kdev_t.h>
16453 +#include <linux/net.h>
16454 +#include <linux/in.h>
16455 +#include <linux/ip.h>
16456 +#include <linux/skbuff.h>
16457 +#include <linux/sysctl.h>
16459 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
16461 +pax_set_initial_flags(struct linux_binprm *bprm)
16467 +#ifdef CONFIG_SYSCTL
16469 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
16476 +gr_acl_is_enabled(void)
16482 +gr_handle_rawio(const struct inode *inode)
16488 +gr_acl_handle_psacct(struct task_struct *task, const long code)
16494 +gr_handle_ptrace(struct task_struct *task, const long request)
16500 +gr_handle_proc_ptrace(struct task_struct *task)
16506 +gr_learn_resource(const struct task_struct *task,
16507 + const int res, const unsigned long wanted, const int gt)
16513 +gr_set_acls(const int type)
16519 +gr_check_hidden_task(const struct task_struct *tsk)
16525 +gr_check_protected_task(const struct task_struct *task)
16531 +gr_copy_label(struct task_struct *tsk)
16537 +gr_set_pax_flags(struct task_struct *task)
16543 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
16549 +gr_handle_delete(const ino_t ino, const dev_t dev)
16555 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
16561 +gr_handle_crash(struct task_struct *task, const int sig)
16567 +gr_check_crash_exec(const struct file *filp)
16573 +gr_check_crash_uid(const uid_t uid)
16579 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
16580 + struct dentry *old_dentry,
16581 + struct dentry *new_dentry,
16582 + struct vfsmount *mnt, const __u8 replace)
16588 +gr_search_socket(const int family, const int type, const int protocol)
16594 +gr_search_connectbind(const int mode, const struct socket *sock,
16595 + const struct sockaddr_in *addr)
16601 +gr_task_is_capable(struct task_struct *task, const int cap)
16607 +gr_is_capable_nolog(const int cap)
16613 +gr_handle_alertkill(struct task_struct *task)
16619 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
16625 +gr_acl_handle_hidden_file(const struct dentry * dentry,
16626 + const struct vfsmount * mnt)
16632 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
16639 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
16645 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
16651 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
16652 + unsigned int *vm_flags)
16658 +gr_acl_handle_truncate(const struct dentry * dentry,
16659 + const struct vfsmount * mnt)
16665 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
16671 +gr_acl_handle_access(const struct dentry * dentry,
16672 + const struct vfsmount * mnt, const int fmode)
16678 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
16685 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
16692 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
16698 +grsecurity_init(void)
16704 +gr_acl_handle_mknod(const struct dentry * new_dentry,
16705 + const struct dentry * parent_dentry,
16706 + const struct vfsmount * parent_mnt,
16713 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
16714 + const struct dentry * parent_dentry,
16715 + const struct vfsmount * parent_mnt)
16721 +gr_acl_handle_symlink(const struct dentry * new_dentry,
16722 + const struct dentry * parent_dentry,
16723 + const struct vfsmount * parent_mnt, const char *from)
16729 +gr_acl_handle_link(const struct dentry * new_dentry,
16730 + const struct dentry * parent_dentry,
16731 + const struct vfsmount * parent_mnt,
16732 + const struct dentry * old_dentry,
16733 + const struct vfsmount * old_mnt, const char *to)
16739 +gr_acl_handle_rename(const struct dentry *new_dentry,
16740 + const struct dentry *parent_dentry,
16741 + const struct vfsmount *parent_mnt,
16742 + const struct dentry *old_dentry,
16743 + const struct inode *old_parent_inode,
16744 + const struct vfsmount *old_mnt, const char *newname)
16750 +gr_acl_handle_filldir(const struct file *file, const char *name,
16751 + const int namelen, const ino_t ino)
16757 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16758 + const time_t shm_createtime, const uid_t cuid, const int shmid)
16764 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
16770 +gr_search_accept(const struct socket *sock)
16776 +gr_search_listen(const struct socket *sock)
16782 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
16788 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
16794 +gr_acl_handle_creat(const struct dentry * dentry,
16795 + const struct dentry * p_dentry,
16796 + const struct vfsmount * p_mnt, const int fmode,
16803 +gr_acl_handle_exit(void)
16809 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
16815 +gr_set_role_label(const uid_t uid, const gid_t gid)
16821 +gr_acl_handle_procpidmem(const struct task_struct *task)
16827 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
16833 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
16839 +gr_set_kernel_label(struct task_struct *task)
16845 +gr_check_user_change(int real, int effective, int fs)
16851 +gr_check_group_change(int real, int effective, int fs)
16857 +EXPORT_SYMBOL(gr_task_is_capable);
16858 +EXPORT_SYMBOL(gr_learn_resource);
16859 +EXPORT_SYMBOL(gr_set_kernel_label);
16860 +#ifdef CONFIG_SECURITY
16861 +EXPORT_SYMBOL(gr_check_user_change);
16862 +EXPORT_SYMBOL(gr_check_group_change);
16864 diff -urNp linux-2.6.17.7/grsecurity/grsec_exec.c linux-2.6.17.7/grsecurity/grsec_exec.c
16865 --- linux-2.6.17.7/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
16866 +++ linux-2.6.17.7/grsecurity/grsec_exec.c 2006-08-01 20:29:47.000000000 -0400
16868 +#include <linux/kernel.h>
16869 +#include <linux/sched.h>
16870 +#include <linux/file.h>
16871 +#include <linux/binfmts.h>
16872 +#include <linux/smp_lock.h>
16873 +#include <linux/fs.h>
16874 +#include <linux/types.h>
16875 +#include <linux/grdefs.h>
16876 +#include <linux/grinternal.h>
16877 +#include <linux/capability.h>
16879 +#include <asm/uaccess.h>
16881 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16882 +static char gr_exec_arg_buf[132];
16883 +static DECLARE_MUTEX(gr_exec_arg_sem);
16887 +gr_handle_nproc(void)
16889 +#ifdef CONFIG_GRKERNSEC_EXECVE
16890 + if (grsec_enable_execve && current->user &&
16891 + (atomic_read(¤t->user->processes) >
16892 + current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
16893 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
16894 + gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
16902 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
16904 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16905 + char *grarg = gr_exec_arg_buf;
16906 + unsigned int i, x, execlen = 0;
16909 + if (!((grsec_enable_execlog && grsec_enable_group &&
16910 + in_group_p(grsec_audit_gid))
16911 + || (grsec_enable_execlog && !grsec_enable_group)))
16914 + down(&gr_exec_arg_sem);
16915 + memset(grarg, 0, sizeof(gr_exec_arg_buf));
16917 + if (unlikely(argv == NULL))
16920 + for (i = 0; i < bprm->argc && execlen < 128; i++) {
16921 + const char __user *p;
16922 + unsigned int len;
16924 + if (copy_from_user(&p, argv + i, sizeof(p)))
16928 + len = strnlen_user(p, 128 - execlen);
16929 + if (len > 128 - execlen)
16930 + len = 128 - execlen;
16931 + else if (len > 0)
16933 + if (copy_from_user(grarg + execlen, p, len))
16936 + /* rewrite unprintable characters */
16937 + for (x = 0; x < len; x++) {
16938 + c = *(grarg + execlen + x);
16939 + if (c < 32 || c > 126)
16940 + *(grarg + execlen + x) = ' ';
16944 + *(grarg + execlen) = ' ';
16945 + *(grarg + execlen + 1) = '\0';
16950 + gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
16951 + bprm->file->f_vfsmnt, grarg);
16952 + up(&gr_exec_arg_sem);
16956 diff -urNp linux-2.6.17.7/grsecurity/grsec_fifo.c linux-2.6.17.7/grsecurity/grsec_fifo.c
16957 --- linux-2.6.17.7/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
16958 +++ linux-2.6.17.7/grsecurity/grsec_fifo.c 2006-08-01 20:29:47.000000000 -0400
16960 +#include <linux/kernel.h>
16961 +#include <linux/sched.h>
16962 +#include <linux/fs.h>
16963 +#include <linux/file.h>
16964 +#include <linux/grinternal.h>
16967 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
16968 + const struct dentry *dir, const int flag, const int acc_mode)
16970 +#ifdef CONFIG_GRKERNSEC_FIFO
16971 + if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
16972 + !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
16973 + (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
16974 + (current->fsuid != dentry->d_inode->i_uid)) {
16975 + if (!generic_permission(dentry->d_inode, acc_mode, NULL))
16976 + gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
16982 diff -urNp linux-2.6.17.7/grsecurity/grsec_fork.c linux-2.6.17.7/grsecurity/grsec_fork.c
16983 --- linux-2.6.17.7/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
16984 +++ linux-2.6.17.7/grsecurity/grsec_fork.c 2006-08-01 20:49:45.000000000 -0400
16986 +#include <linux/kernel.h>
16987 +#include <linux/sched.h>
16988 +#include <linux/grsecurity.h>
16989 +#include <linux/grinternal.h>
16990 +#include <linux/errno.h>
16993 +gr_log_forkfail(const int retval)
16995 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
16996 + if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
16997 + gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
17001 diff -urNp linux-2.6.17.7/grsecurity/grsec_init.c linux-2.6.17.7/grsecurity/grsec_init.c
17002 --- linux-2.6.17.7/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
17003 +++ linux-2.6.17.7/grsecurity/grsec_init.c 2006-08-01 20:29:47.000000000 -0400
17005 +#include <linux/kernel.h>
17006 +#include <linux/sched.h>
17007 +#include <linux/mm.h>
17008 +#include <linux/smp_lock.h>
17009 +#include <linux/gracl.h>
17010 +#include <linux/slab.h>
17011 +#include <linux/vmalloc.h>
17012 +#include <linux/percpu.h>
17014 +int grsec_enable_shm;
17015 +int grsec_enable_link;
17016 +int grsec_enable_dmesg;
17017 +int grsec_enable_fifo;
17018 +int grsec_enable_execve;
17019 +int grsec_enable_execlog;
17020 +int grsec_enable_signal;
17021 +int grsec_enable_forkfail;
17022 +int grsec_enable_time;
17023 +int grsec_enable_audit_textrel;
17024 +int grsec_enable_group;
17025 +int grsec_audit_gid;
17026 +int grsec_enable_chdir;
17027 +int grsec_enable_audit_ipc;
17028 +int grsec_enable_mount;
17029 +int grsec_enable_chroot_findtask;
17030 +int grsec_enable_chroot_mount;
17031 +int grsec_enable_chroot_shmat;
17032 +int grsec_enable_chroot_fchdir;
17033 +int grsec_enable_chroot_double;
17034 +int grsec_enable_chroot_pivot;
17035 +int grsec_enable_chroot_chdir;
17036 +int grsec_enable_chroot_chmod;
17037 +int grsec_enable_chroot_mknod;
17038 +int grsec_enable_chroot_nice;
17039 +int grsec_enable_chroot_execlog;
17040 +int grsec_enable_chroot_caps;
17041 +int grsec_enable_chroot_sysctl;
17042 +int grsec_enable_chroot_unix;
17043 +int grsec_enable_tpe;
17044 +int grsec_tpe_gid;
17045 +int grsec_enable_tpe_all;
17046 +int grsec_enable_randpid;
17047 +int grsec_enable_socket_all;
17048 +int grsec_socket_all_gid;
17049 +int grsec_enable_socket_client;
17050 +int grsec_socket_client_gid;
17051 +int grsec_enable_socket_server;
17052 +int grsec_socket_server_gid;
17053 +int grsec_resource_logging;
17056 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
17057 +unsigned long grsec_alert_wtime = 0;
17058 +unsigned long grsec_alert_fyet = 0;
17060 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
17062 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
17064 +char *gr_shared_page[4];
17066 +char *gr_alert_log_fmt;
17067 +char *gr_audit_log_fmt;
17068 +char *gr_alert_log_buf;
17069 +char *gr_audit_log_buf;
17071 +extern struct gr_arg *gr_usermode;
17072 +extern unsigned char *gr_system_salt;
17073 +extern unsigned char *gr_system_sum;
17076 +grsecurity_init(void)
17079 + /* create the per-cpu shared pages */
17081 + preempt_disable();
17082 + for (j = 0; j < 4; j++) {
17083 + gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
17084 + if (gr_shared_page[j] == NULL) {
17085 + panic("Unable to allocate grsecurity shared page");
17089 + preempt_enable();
17091 + /* allocate log buffers */
17092 + gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
17093 + if (!gr_alert_log_fmt) {
17094 + panic("Unable to allocate grsecurity alert log format buffer");
17097 + gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
17098 + if (!gr_audit_log_fmt) {
17099 + panic("Unable to allocate grsecurity audit log format buffer");
17102 + gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
17103 + if (!gr_alert_log_buf) {
17104 + panic("Unable to allocate grsecurity alert log buffer");
17107 + gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
17108 + if (!gr_audit_log_buf) {
17109 + panic("Unable to allocate grsecurity audit log buffer");
17113 + /* allocate memory for authentication structure */
17114 + gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
17115 + gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
17116 + gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
17118 + if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
17119 + panic("Unable to allocate grsecurity authentication structure");
17123 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
17124 +#ifndef CONFIG_GRKERNSEC_SYSCTL
17127 +#ifdef CONFIG_GRKERNSEC_SHM
17128 + grsec_enable_shm = 1;
17130 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
17131 + grsec_enable_audit_textrel = 1;
17133 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
17134 + grsec_enable_group = 1;
17135 + grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
17137 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
17138 + grsec_enable_chdir = 1;
17140 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17141 + grsec_enable_audit_ipc = 1;
17143 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17144 + grsec_enable_mount = 1;
17146 +#ifdef CONFIG_GRKERNSEC_LINK
17147 + grsec_enable_link = 1;
17149 +#ifdef CONFIG_GRKERNSEC_DMESG
17150 + grsec_enable_dmesg = 1;
17152 +#ifdef CONFIG_GRKERNSEC_FIFO
17153 + grsec_enable_fifo = 1;
17155 +#ifdef CONFIG_GRKERNSEC_EXECVE
17156 + grsec_enable_execve = 1;
17158 +#ifdef CONFIG_GRKERNSEC_EXECLOG
17159 + grsec_enable_execlog = 1;
17161 +#ifdef CONFIG_GRKERNSEC_SIGNAL
17162 + grsec_enable_signal = 1;
17164 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
17165 + grsec_enable_forkfail = 1;
17167 +#ifdef CONFIG_GRKERNSEC_TIME
17168 + grsec_enable_time = 1;
17170 +#ifdef CONFIG_GRKERNSEC_RESLOG
17171 + grsec_resource_logging = 1;
17173 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
17174 + grsec_enable_chroot_findtask = 1;
17176 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
17177 + grsec_enable_chroot_unix = 1;
17179 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
17180 + grsec_enable_chroot_mount = 1;
17182 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
17183 + grsec_enable_chroot_fchdir = 1;
17185 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
17186 + grsec_enable_chroot_shmat = 1;
17188 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
17189 + grsec_enable_chroot_double = 1;
17191 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
17192 + grsec_enable_chroot_pivot = 1;
17194 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
17195 + grsec_enable_chroot_chdir = 1;
17197 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
17198 + grsec_enable_chroot_chmod = 1;
17200 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
17201 + grsec_enable_chroot_mknod = 1;
17203 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17204 + grsec_enable_chroot_nice = 1;
17206 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
17207 + grsec_enable_chroot_execlog = 1;
17209 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17210 + grsec_enable_chroot_caps = 1;
17212 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
17213 + grsec_enable_chroot_sysctl = 1;
17215 +#ifdef CONFIG_GRKERNSEC_TPE
17216 + grsec_enable_tpe = 1;
17217 + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
17218 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
17219 + grsec_enable_tpe_all = 1;
17222 +#ifdef CONFIG_GRKERNSEC_RANDPID
17223 + grsec_enable_randpid = 1;
17225 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
17226 + grsec_enable_socket_all = 1;
17227 + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
17229 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
17230 + grsec_enable_socket_client = 1;
17231 + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
17233 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
17234 + grsec_enable_socket_server = 1;
17235 + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
17241 diff -urNp linux-2.6.17.7/grsecurity/grsec_ipc.c linux-2.6.17.7/grsecurity/grsec_ipc.c
17242 --- linux-2.6.17.7/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
17243 +++ linux-2.6.17.7/grsecurity/grsec_ipc.c 2006-08-01 20:29:47.000000000 -0400
17245 +#include <linux/kernel.h>
17246 +#include <linux/sched.h>
17247 +#include <linux/types.h>
17248 +#include <linux/ipc.h>
17249 +#include <linux/grsecurity.h>
17250 +#include <linux/grinternal.h>
17253 +gr_log_msgget(const int ret, const int msgflg)
17255 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17256 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17257 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
17258 + !grsec_enable_group)) && (ret >= 0)
17259 + && (msgflg & IPC_CREAT))
17260 + gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
17266 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
17268 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17269 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17270 + grsec_enable_audit_ipc) ||
17271 + (grsec_enable_audit_ipc && !grsec_enable_group))
17272 + gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
17278 +gr_log_semget(const int err, const int semflg)
17280 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17281 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17282 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
17283 + !grsec_enable_group)) && (err >= 0)
17284 + && (semflg & IPC_CREAT))
17285 + gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
17291 +gr_log_semrm(const uid_t uid, const uid_t cuid)
17293 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17294 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17295 + grsec_enable_audit_ipc) ||
17296 + (grsec_enable_audit_ipc && !grsec_enable_group))
17297 + gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
17303 +gr_log_shmget(const int err, const int shmflg, const size_t size)
17305 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17306 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17307 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
17308 + !grsec_enable_group)) && (err >= 0)
17309 + && (shmflg & IPC_CREAT))
17310 + gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
17316 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
17318 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17319 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17320 + grsec_enable_audit_ipc) ||
17321 + (grsec_enable_audit_ipc && !grsec_enable_group))
17322 + gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
17326 diff -urNp linux-2.6.17.7/grsecurity/grsec_link.c linux-2.6.17.7/grsecurity/grsec_link.c
17327 --- linux-2.6.17.7/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
17328 +++ linux-2.6.17.7/grsecurity/grsec_link.c 2006-08-01 20:29:47.000000000 -0400
17330 +#include <linux/kernel.h>
17331 +#include <linux/sched.h>
17332 +#include <linux/fs.h>
17333 +#include <linux/file.h>
17334 +#include <linux/grinternal.h>
17337 +gr_handle_follow_link(const struct inode *parent,
17338 + const struct inode *inode,
17339 + const struct dentry *dentry, const struct vfsmount *mnt)
17341 +#ifdef CONFIG_GRKERNSEC_LINK
17342 + if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
17343 + (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
17344 + (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
17345 + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
17353 +gr_handle_hardlink(const struct dentry *dentry,
17354 + const struct vfsmount *mnt,
17355 + struct inode *inode, const int mode, const char *to)
17357 +#ifdef CONFIG_GRKERNSEC_LINK
17358 + if (grsec_enable_link && current->fsuid != inode->i_uid &&
17359 + (!S_ISREG(mode) || (mode & S_ISUID) ||
17360 + ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
17361 + (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
17362 + !capable(CAP_FOWNER) && current->uid) {
17363 + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
17369 diff -urNp linux-2.6.17.7/grsecurity/grsec_log.c linux-2.6.17.7/grsecurity/grsec_log.c
17370 --- linux-2.6.17.7/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
17371 +++ linux-2.6.17.7/grsecurity/grsec_log.c 2006-08-01 20:29:47.000000000 -0400
17373 +#include <linux/kernel.h>
17374 +#include <linux/sched.h>
17375 +#include <linux/file.h>
17376 +#include <linux/tty.h>
17377 +#include <linux/fs.h>
17378 +#include <linux/grinternal.h>
17380 +#define BEGIN_LOCKS(x) \
17381 + read_lock(&tasklist_lock); \
17382 + read_lock(&grsec_exec_file_lock); \
17383 + if (x != GR_DO_AUDIT) \
17384 + spin_lock(&grsec_alert_lock); \
17386 + spin_lock(&grsec_audit_lock)
17388 +#define END_LOCKS(x) \
17389 + if (x != GR_DO_AUDIT) \
17390 + spin_unlock(&grsec_alert_lock); \
17392 + spin_unlock(&grsec_audit_lock); \
17393 + read_unlock(&grsec_exec_file_lock); \
17394 + read_unlock(&tasklist_lock); \
17395 + if (x == GR_DONT_AUDIT) \
17396 + gr_handle_alertkill(current)
17403 +extern char *gr_alert_log_fmt;
17404 +extern char *gr_audit_log_fmt;
17405 +extern char *gr_alert_log_buf;
17406 +extern char *gr_audit_log_buf;
17408 +static int gr_log_start(int audit)
17410 + char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
17411 + char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
17412 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
17414 + if (audit == GR_DO_AUDIT)
17417 + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
17418 + grsec_alert_wtime = jiffies;
17419 + grsec_alert_fyet = 0;
17420 + } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
17421 + grsec_alert_fyet++;
17422 + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
17423 + grsec_alert_wtime = jiffies;
17424 + grsec_alert_fyet++;
17425 + printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
17427 + } else return FLOODING;
17430 + memset(buf, 0, PAGE_SIZE);
17431 + if (current->signal->curr_ip && gr_acl_is_enabled()) {
17432 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
17433 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
17434 + } else if (current->signal->curr_ip) {
17435 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
17436 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
17437 + } else if (gr_acl_is_enabled()) {
17438 + sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
17439 + snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
17441 + sprintf(fmt, "%s%s", loglevel, "grsec: ");
17442 + strcpy(buf, fmt);
17445 + return NO_FLOODING;
17448 +static void gr_log_middle(int audit, const char *msg, va_list ap)
17450 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
17451 + unsigned int len = strlen(buf);
17453 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
17458 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
17460 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
17461 + unsigned int len = strlen(buf);
17464 + va_start(ap, msg);
17465 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
17471 +static void gr_log_end(int audit)
17473 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
17474 + unsigned int len = strlen(buf);
17476 + snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
17477 + printk("%s\n", buf);
17482 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
17485 + char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
17486 + char *str1, *str2, *str3;
17488 + unsigned long ulong1, ulong2;
17489 + struct dentry *dentry;
17490 + struct vfsmount *mnt;
17491 + struct file *file;
17492 + struct task_struct *task;
17495 + BEGIN_LOCKS(audit);
17496 + logtype = gr_log_start(audit);
17497 + if (logtype == FLOODING) {
17498 + END_LOCKS(audit);
17501 + va_start(ap, argtypes);
17502 + switch (argtypes) {
17503 + case GR_TTYSNIFF:
17504 + task = va_arg(ap, struct task_struct *);
17505 + 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);
17508 + dentry = va_arg(ap, struct dentry *);
17509 + mnt = va_arg(ap, struct vfsmount *);
17510 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
17512 + case GR_RBAC_STR:
17513 + dentry = va_arg(ap, struct dentry *);
17514 + mnt = va_arg(ap, struct vfsmount *);
17515 + str1 = va_arg(ap, char *);
17516 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
17518 + case GR_STR_RBAC:
17519 + str1 = va_arg(ap, char *);
17520 + dentry = va_arg(ap, struct dentry *);
17521 + mnt = va_arg(ap, struct vfsmount *);
17522 + gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
17524 + case GR_RBAC_MODE2:
17525 + dentry = va_arg(ap, struct dentry *);
17526 + mnt = va_arg(ap, struct vfsmount *);
17527 + str1 = va_arg(ap, char *);
17528 + str2 = va_arg(ap, char *);
17529 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
17531 + case GR_RBAC_MODE3:
17532 + dentry = va_arg(ap, struct dentry *);
17533 + mnt = va_arg(ap, struct vfsmount *);
17534 + str1 = va_arg(ap, char *);
17535 + str2 = va_arg(ap, char *);
17536 + str3 = va_arg(ap, char *);
17537 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
17539 + case GR_FILENAME:
17540 + dentry = va_arg(ap, struct dentry *);
17541 + mnt = va_arg(ap, struct vfsmount *);
17542 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
17544 + case GR_STR_FILENAME:
17545 + str1 = va_arg(ap, char *);
17546 + dentry = va_arg(ap, struct dentry *);
17547 + mnt = va_arg(ap, struct vfsmount *);
17548 + gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
17550 + case GR_FILENAME_STR:
17551 + dentry = va_arg(ap, struct dentry *);
17552 + mnt = va_arg(ap, struct vfsmount *);
17553 + str1 = va_arg(ap, char *);
17554 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
17556 + case GR_FILENAME_TWO_INT:
17557 + dentry = va_arg(ap, struct dentry *);
17558 + mnt = va_arg(ap, struct vfsmount *);
17559 + num1 = va_arg(ap, int);
17560 + num2 = va_arg(ap, int);
17561 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
17563 + case GR_FILENAME_TWO_INT_STR:
17564 + dentry = va_arg(ap, struct dentry *);
17565 + mnt = va_arg(ap, struct vfsmount *);
17566 + num1 = va_arg(ap, int);
17567 + num2 = va_arg(ap, int);
17568 + str1 = va_arg(ap, char *);
17569 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
17572 + file = va_arg(ap, struct file *);
17573 + ulong1 = va_arg(ap, unsigned long);
17574 + ulong2 = va_arg(ap, unsigned long);
17575 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
17578 + task = va_arg(ap, struct task_struct *);
17579 + gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt) : "(none)", task->comm, task->pid);
17581 + case GR_RESOURCE:
17582 + task = va_arg(ap, struct task_struct *);
17583 + ulong1 = va_arg(ap, unsigned long);
17584 + str1 = va_arg(ap, char *);
17585 + ulong2 = va_arg(ap, unsigned long);
17586 + 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);
17589 + task = va_arg(ap, struct task_struct *);
17590 + str1 = va_arg(ap, char *);
17591 + 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);
17594 + task = va_arg(ap, struct task_struct *);
17595 + num1 = va_arg(ap, int);
17596 + 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);
17599 + task = va_arg(ap, struct task_struct *);
17600 + ulong1 = va_arg(ap, unsigned long);
17601 + 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);
17604 + task = va_arg(ap, struct task_struct *);
17605 + ulong1 = va_arg(ap, unsigned long);
17606 + 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);
17610 + unsigned int wday, cday;
17614 + char cur_tty[64] = { 0 };
17615 + char parent_tty[64] = { 0 };
17617 + task = va_arg(ap, struct task_struct *);
17618 + wday = va_arg(ap, unsigned int);
17619 + cday = va_arg(ap, unsigned int);
17620 + whr = va_arg(ap, int);
17621 + chr = va_arg(ap, int);
17622 + wmin = va_arg(ap, int);
17623 + cmin = va_arg(ap, int);
17624 + wsec = va_arg(ap, int);
17625 + csec = va_arg(ap, int);
17626 + ulong1 = va_arg(ap, unsigned long);
17628 + 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);
17632 + gr_log_middle(audit, msg, ap);
17635 + gr_log_end(audit);
17636 + END_LOCKS(audit);
17638 diff -urNp linux-2.6.17.7/grsecurity/grsec_mem.c linux-2.6.17.7/grsecurity/grsec_mem.c
17639 --- linux-2.6.17.7/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
17640 +++ linux-2.6.17.7/grsecurity/grsec_mem.c 2006-08-01 20:29:47.000000000 -0400
17642 +#include <linux/kernel.h>
17643 +#include <linux/sched.h>
17644 +#include <linux/mm.h>
17645 +#include <linux/mman.h>
17646 +#include <linux/grinternal.h>
17649 +gr_handle_ioperm(void)
17651 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
17656 +gr_handle_iopl(void)
17658 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
17663 +gr_handle_mem_write(void)
17665 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
17670 +gr_handle_kmem_write(void)
17672 + gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
17677 +gr_handle_open_port(void)
17679 + gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
17684 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
17686 + unsigned long start, end;
17689 + end = start + vma->vm_end - vma->vm_start;
17691 + if (start > end) {
17692 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
17696 + /* allowed ranges : ISA I/O BIOS */
17697 + if ((start >= __pa(high_memory))
17699 + || (start >= 0x000a0000 && end <= 0x00100000)
17700 + || (start >= 0x00000000 && end <= 0x00001000)
17705 + if (vma->vm_flags & VM_WRITE) {
17706 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
17709 + vma->vm_flags &= ~VM_MAYWRITE;
17713 diff -urNp linux-2.6.17.7/grsecurity/grsec_mount.c linux-2.6.17.7/grsecurity/grsec_mount.c
17714 --- linux-2.6.17.7/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
17715 +++ linux-2.6.17.7/grsecurity/grsec_mount.c 2006-08-01 20:29:47.000000000 -0400
17717 +#include <linux/kernel.h>
17718 +#include <linux/sched.h>
17719 +#include <linux/grsecurity.h>
17720 +#include <linux/grinternal.h>
17723 +gr_log_remount(const char *devname, const int retval)
17725 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17726 + if (grsec_enable_mount && (retval >= 0))
17727 + gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
17733 +gr_log_unmount(const char *devname, const int retval)
17735 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17736 + if (grsec_enable_mount && (retval >= 0))
17737 + gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
17743 +gr_log_mount(const char *from, const char *to, const int retval)
17745 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17746 + if (grsec_enable_mount && (retval >= 0))
17747 + gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
17751 diff -urNp linux-2.6.17.7/grsecurity/grsec_rand.c linux-2.6.17.7/grsecurity/grsec_rand.c
17752 --- linux-2.6.17.7/grsecurity/grsec_rand.c 1969-12-31 19:00:00.000000000 -0500
17753 +++ linux-2.6.17.7/grsecurity/grsec_rand.c 2006-08-01 20:29:47.000000000 -0400
17755 +#include <linux/kernel.h>
17756 +#include <linux/sched.h>
17757 +#include <linux/smp_lock.h>
17758 +#include <linux/grsecurity.h>
17759 +#include <linux/grinternal.h>
17761 +extern int pid_max;
17764 +gr_random_pid(void)
17766 +#ifdef CONFIG_GRKERNSEC_RANDPID
17769 + if (grsec_enable_randpid && current->fs->root) {
17770 + /* return a pid in the range 1 ... pid_max - 1
17771 + optimize this so we don't have to do a real division
17773 + pid = 1 + (get_random_long() % pid_max);
17774 + if (pid == pid_max)
17775 + pid = pid_max - 1;
17781 diff -urNp linux-2.6.17.7/grsecurity/grsec_sig.c linux-2.6.17.7/grsecurity/grsec_sig.c
17782 --- linux-2.6.17.7/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
17783 +++ linux-2.6.17.7/grsecurity/grsec_sig.c 2006-08-01 20:29:47.000000000 -0400
17785 +#include <linux/kernel.h>
17786 +#include <linux/sched.h>
17787 +#include <linux/grsecurity.h>
17788 +#include <linux/grinternal.h>
17791 +gr_log_signal(const int sig, const struct task_struct *t)
17793 +#ifdef CONFIG_GRKERNSEC_SIGNAL
17794 + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
17795 + (sig == SIGABRT) || (sig == SIGBUS))) {
17796 + if (t->pid == current->pid) {
17797 + gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
17799 + gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
17807 +gr_handle_signal(const struct task_struct *p, const int sig)
17809 +#ifdef CONFIG_GRKERNSEC
17810 + if (current->pid > 1 && gr_check_protected_task(p)) {
17811 + gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
17813 + } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
17820 +void gr_handle_brute_attach(struct task_struct *p)
17822 +#ifdef CONFIG_GRKERNSEC_BRUTE
17823 + read_lock(&tasklist_lock);
17824 + read_lock(&grsec_exec_file_lock);
17825 + if (p->parent && p->parent->exec_file == p->exec_file)
17826 + p->parent->brute = 1;
17827 + read_unlock(&grsec_exec_file_lock);
17828 + read_unlock(&tasklist_lock);
17833 +void gr_handle_brute_check(void)
17835 +#ifdef CONFIG_GRKERNSEC_BRUTE
17836 + if (current->brute) {
17837 + set_current_state(TASK_UNINTERRUPTIBLE);
17838 + schedule_timeout(30 * HZ);
17844 diff -urNp linux-2.6.17.7/grsecurity/grsec_sock.c linux-2.6.17.7/grsecurity/grsec_sock.c
17845 --- linux-2.6.17.7/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
17846 +++ linux-2.6.17.7/grsecurity/grsec_sock.c 2006-08-01 20:29:47.000000000 -0400
17848 +#include <linux/kernel.h>
17849 +#include <linux/module.h>
17850 +#include <linux/sched.h>
17851 +#include <linux/file.h>
17852 +#include <linux/net.h>
17853 +#include <linux/in.h>
17854 +#include <linux/ip.h>
17855 +#include <net/sock.h>
17856 +#include <net/inet_sock.h>
17857 +#include <linux/grsecurity.h>
17858 +#include <linux/grinternal.h>
17859 +#include <linux/gracl.h>
17861 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
17862 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
17863 +EXPORT_SYMBOL(udp_v4_lookup);
17866 +EXPORT_SYMBOL(gr_cap_rtnetlink);
17868 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
17869 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
17871 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
17872 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
17874 +#ifdef CONFIG_UNIX_MODULE
17875 +EXPORT_SYMBOL(gr_acl_handle_unix);
17876 +EXPORT_SYMBOL(gr_acl_handle_mknod);
17877 +EXPORT_SYMBOL(gr_handle_chroot_unix);
17878 +EXPORT_SYMBOL(gr_handle_create);
17881 +#ifdef CONFIG_GRKERNSEC
17882 +#define gr_conn_table_size 32749
17883 +struct conn_table_entry {
17884 + struct conn_table_entry *next;
17885 + struct signal_struct *sig;
17888 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
17889 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
17891 +extern const char * gr_socktype_to_name(unsigned char type);
17892 +extern const char * gr_proto_to_name(unsigned char proto);
17894 +static __inline__ int
17895 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
17897 + return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
17900 +static __inline__ int
17901 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
17902 + __u16 sport, __u16 dport)
17904 + if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
17905 + sig->gr_sport == sport && sig->gr_dport == dport))
17911 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
17913 + struct conn_table_entry **match;
17914 + unsigned int index;
17916 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
17917 + sig->gr_sport, sig->gr_dport,
17918 + gr_conn_table_size);
17920 + newent->sig = sig;
17922 + match = &gr_conn_table[index];
17923 + newent->next = *match;
17929 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
17931 + struct conn_table_entry *match, *last = NULL;
17932 + unsigned int index;
17934 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
17935 + sig->gr_sport, sig->gr_dport,
17936 + gr_conn_table_size);
17938 + match = gr_conn_table[index];
17939 + while (match && !conn_match(match->sig,
17940 + sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
17941 + sig->gr_dport)) {
17943 + match = match->next;
17948 + last->next = match->next;
17950 + gr_conn_table[index] = NULL;
17957 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
17958 + __u16 sport, __u16 dport)
17960 + struct conn_table_entry *match;
17961 + unsigned int index;
17963 + index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
17965 + match = gr_conn_table[index];
17966 + while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
17967 + match = match->next;
17970 + return match->sig;
17977 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
17979 +#ifdef CONFIG_GRKERNSEC
17980 + struct signal_struct *sig = task->signal;
17981 + struct conn_table_entry *newent;
17983 + newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
17984 + if (newent == NULL)
17986 + /* no bh lock needed since we are called with bh disabled */
17987 + spin_lock(&gr_conn_table_lock);
17988 + gr_del_task_from_ip_table_nolock(sig);
17989 + sig->gr_saddr = inet->rcv_saddr;
17990 + sig->gr_daddr = inet->daddr;
17991 + sig->gr_sport = inet->sport;
17992 + sig->gr_dport = inet->dport;
17993 + gr_add_to_task_ip_table_nolock(sig, newent);
17994 + spin_unlock(&gr_conn_table_lock);
17999 +void gr_del_task_from_ip_table(struct task_struct *task)
18001 +#ifdef CONFIG_GRKERNSEC
18002 + spin_lock(&gr_conn_table_lock);
18003 + gr_del_task_from_ip_table_nolock(task->signal);
18004 + spin_unlock(&gr_conn_table_lock);
18010 +gr_attach_curr_ip(const struct sock *sk)
18012 +#ifdef CONFIG_GRKERNSEC
18013 + struct signal_struct *p, *set;
18014 + const struct inet_sock *inet = inet_sk(sk);
18016 + if (unlikely(sk->sk_protocol != IPPROTO_TCP))
18019 + set = current->signal;
18021 + spin_lock_bh(&gr_conn_table_lock);
18022 + p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
18023 + inet->dport, inet->sport);
18024 + if (unlikely(p != NULL)) {
18025 + set->curr_ip = p->curr_ip;
18026 + set->used_accept = 1;
18027 + gr_del_task_from_ip_table_nolock(p);
18028 + spin_unlock_bh(&gr_conn_table_lock);
18031 + spin_unlock_bh(&gr_conn_table_lock);
18033 + set->curr_ip = inet->daddr;
18034 + set->used_accept = 1;
18040 +gr_handle_sock_all(const int family, const int type, const int protocol)
18042 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
18043 + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
18044 + (family != AF_UNIX) && (family != AF_LOCAL)) {
18045 + gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
18053 +gr_handle_sock_server(const struct sockaddr *sck)
18055 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18056 + if (grsec_enable_socket_server &&
18057 + in_group_p(grsec_socket_server_gid) &&
18058 + sck && (sck->sa_family != AF_UNIX) &&
18059 + (sck->sa_family != AF_LOCAL)) {
18060 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
18068 +gr_handle_sock_server_other(const struct sock *sck)
18070 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18071 + if (grsec_enable_socket_server &&
18072 + in_group_p(grsec_socket_server_gid) &&
18073 + sck && (sck->sk_family != AF_UNIX) &&
18074 + (sck->sk_family != AF_LOCAL)) {
18075 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
18083 +gr_handle_sock_client(const struct sockaddr *sck)
18085 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
18086 + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
18087 + sck && (sck->sa_family != AF_UNIX) &&
18088 + (sck->sa_family != AF_LOCAL)) {
18089 + gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
18097 +gr_cap_rtnetlink(void)
18099 +#ifdef CONFIG_GRKERNSEC
18100 + if (!gr_acl_is_enabled())
18101 + return current->cap_effective;
18102 + else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
18103 + gr_task_is_capable(current, CAP_NET_ADMIN))
18104 + return current->cap_effective;
18108 + return current->cap_effective;
18111 diff -urNp linux-2.6.17.7/grsecurity/grsec_sysctl.c linux-2.6.17.7/grsecurity/grsec_sysctl.c
18112 --- linux-2.6.17.7/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
18113 +++ linux-2.6.17.7/grsecurity/grsec_sysctl.c 2006-08-01 20:29:47.000000000 -0400
18115 +#include <linux/kernel.h>
18116 +#include <linux/sched.h>
18117 +#include <linux/sysctl.h>
18118 +#include <linux/grsecurity.h>
18119 +#include <linux/grinternal.h>
18121 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18122 +int grsec_modstop;
18126 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
18128 +#ifdef CONFIG_GRKERNSEC_SYSCTL
18129 + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
18130 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
18134 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18135 + if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
18136 + grsec_modstop && (op & 002)) {
18137 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
18144 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
18145 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
18146 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
18147 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
18148 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
18149 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
18150 +GS_RANDPID, GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
18151 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID,
18152 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
18153 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
18156 +ctl_table grsecurity_table[] = {
18157 +#ifdef CONFIG_GRKERNSEC_SYSCTL
18158 +#ifdef CONFIG_GRKERNSEC_LINK
18160 + .ctl_name = GS_LINK,
18161 + .procname = "linking_restrictions",
18162 + .data = &grsec_enable_link,
18163 + .maxlen = sizeof(int),
18165 + .proc_handler = &proc_dointvec,
18168 +#ifdef CONFIG_GRKERNSEC_FIFO
18170 + .ctl_name = GS_FIFO,
18171 + .procname = "fifo_restrictions",
18172 + .data = &grsec_enable_fifo,
18173 + .maxlen = sizeof(int),
18175 + .proc_handler = &proc_dointvec,
18178 +#ifdef CONFIG_GRKERNSEC_EXECVE
18180 + .ctl_name = GS_EXECVE,
18181 + .procname = "execve_limiting",
18182 + .data = &grsec_enable_execve,
18183 + .maxlen = sizeof(int),
18185 + .proc_handler = &proc_dointvec,
18188 +#ifdef CONFIG_GRKERNSEC_EXECLOG
18190 + .ctl_name = GS_EXECLOG,
18191 + .procname = "exec_logging",
18192 + .data = &grsec_enable_execlog,
18193 + .maxlen = sizeof(int),
18195 + .proc_handler = &proc_dointvec,
18198 +#ifdef CONFIG_GRKERNSEC_SIGNAL
18200 + .ctl_name = GS_SIGNAL,
18201 + .procname = "signal_logging",
18202 + .data = &grsec_enable_signal,
18203 + .maxlen = sizeof(int),
18205 + .proc_handler = &proc_dointvec,
18208 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
18210 + .ctl_name = GS_FORKFAIL,
18211 + .procname = "forkfail_logging",
18212 + .data = &grsec_enable_forkfail,
18213 + .maxlen = sizeof(int),
18215 + .proc_handler = &proc_dointvec,
18218 +#ifdef CONFIG_GRKERNSEC_TIME
18220 + .ctl_name = GS_TIME,
18221 + .procname = "timechange_logging",
18222 + .data = &grsec_enable_time,
18223 + .maxlen = sizeof(int),
18225 + .proc_handler = &proc_dointvec,
18228 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
18230 + .ctl_name = GS_CHROOT_SHMAT,
18231 + .procname = "chroot_deny_shmat",
18232 + .data = &grsec_enable_chroot_shmat,
18233 + .maxlen = sizeof(int),
18235 + .proc_handler = &proc_dointvec,
18238 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
18240 + .ctl_name = GS_CHROOT_UNIX,
18241 + .procname = "chroot_deny_unix",
18242 + .data = &grsec_enable_chroot_unix,
18243 + .maxlen = sizeof(int),
18245 + .proc_handler = &proc_dointvec,
18248 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
18250 + .ctl_name = GS_CHROOT_MNT,
18251 + .procname = "chroot_deny_mount",
18252 + .data = &grsec_enable_chroot_mount,
18253 + .maxlen = sizeof(int),
18255 + .proc_handler = &proc_dointvec,
18258 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
18260 + .ctl_name = GS_CHROOT_FCHDIR,
18261 + .procname = "chroot_deny_fchdir",
18262 + .data = &grsec_enable_chroot_fchdir,
18263 + .maxlen = sizeof(int),
18265 + .proc_handler = &proc_dointvec,
18268 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
18270 + .ctl_name = GS_CHROOT_DBL,
18271 + .procname = "chroot_deny_chroot",
18272 + .data = &grsec_enable_chroot_double,
18273 + .maxlen = sizeof(int),
18275 + .proc_handler = &proc_dointvec,
18278 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
18280 + .ctl_name = GS_CHROOT_PVT,
18281 + .procname = "chroot_deny_pivot",
18282 + .data = &grsec_enable_chroot_pivot,
18283 + .maxlen = sizeof(int),
18285 + .proc_handler = &proc_dointvec,
18288 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
18290 + .ctl_name = GS_CHROOT_CD,
18291 + .procname = "chroot_enforce_chdir",
18292 + .data = &grsec_enable_chroot_chdir,
18293 + .maxlen = sizeof(int),
18295 + .proc_handler = &proc_dointvec,
18298 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
18300 + .ctl_name = GS_CHROOT_CM,
18301 + .procname = "chroot_deny_chmod",
18302 + .data = &grsec_enable_chroot_chmod,
18303 + .maxlen = sizeof(int),
18305 + .proc_handler = &proc_dointvec,
18308 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
18310 + .ctl_name = GS_CHROOT_MK,
18311 + .procname = "chroot_deny_mknod",
18312 + .data = &grsec_enable_chroot_mknod,
18313 + .maxlen = sizeof(int),
18315 + .proc_handler = &proc_dointvec,
18318 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
18320 + .ctl_name = GS_CHROOT_NI,
18321 + .procname = "chroot_restrict_nice",
18322 + .data = &grsec_enable_chroot_nice,
18323 + .maxlen = sizeof(int),
18325 + .proc_handler = &proc_dointvec,
18328 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
18330 + .ctl_name = GS_CHROOT_EXECLOG,
18331 + .procname = "chroot_execlog",
18332 + .data = &grsec_enable_chroot_execlog,
18333 + .maxlen = sizeof(int),
18335 + .proc_handler = &proc_dointvec,
18338 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
18340 + .ctl_name = GS_CHROOT_CAPS,
18341 + .procname = "chroot_caps",
18342 + .data = &grsec_enable_chroot_caps,
18343 + .maxlen = sizeof(int),
18345 + .proc_handler = &proc_dointvec,
18348 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
18350 + .ctl_name = GS_CHROOT_SYSCTL,
18351 + .procname = "chroot_deny_sysctl",
18352 + .data = &grsec_enable_chroot_sysctl,
18353 + .maxlen = sizeof(int),
18355 + .proc_handler = &proc_dointvec,
18358 +#ifdef CONFIG_GRKERNSEC_TPE
18360 + .ctl_name = GS_TPE,
18361 + .procname = "tpe",
18362 + .data = &grsec_enable_tpe,
18363 + .maxlen = sizeof(int),
18365 + .proc_handler = &proc_dointvec,
18368 + .ctl_name = GS_TPE_GID,
18369 + .procname = "tpe_gid",
18370 + .data = &grsec_tpe_gid,
18371 + .maxlen = sizeof(int),
18373 + .proc_handler = &proc_dointvec,
18376 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
18378 + .ctl_name = GS_TPE_ALL,
18379 + .procname = "tpe_restrict_all",
18380 + .data = &grsec_enable_tpe_all,
18381 + .maxlen = sizeof(int),
18383 + .proc_handler = &proc_dointvec,
18386 +#ifdef CONFIG_GRKERNSEC_RANDPID
18388 + .ctl_name = GS_RANDPID,
18389 + .procname = "rand_pids",
18390 + .data = &grsec_enable_randpid,
18391 + .maxlen = sizeof(int),
18393 + .proc_handler = &proc_dointvec,
18396 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
18398 + .ctl_name = GS_SOCKET_ALL,
18399 + .procname = "socket_all",
18400 + .data = &grsec_enable_socket_all,
18401 + .maxlen = sizeof(int),
18403 + .proc_handler = &proc_dointvec,
18406 + .ctl_name = GS_SOCKET_ALL_GID,
18407 + .procname = "socket_all_gid",
18408 + .data = &grsec_socket_all_gid,
18409 + .maxlen = sizeof(int),
18411 + .proc_handler = &proc_dointvec,
18414 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
18416 + .ctl_name = GS_SOCKET_CLIENT,
18417 + .procname = "socket_client",
18418 + .data = &grsec_enable_socket_client,
18419 + .maxlen = sizeof(int),
18421 + .proc_handler = &proc_dointvec,
18424 + .ctl_name = GS_SOCKET_CLIENT_GID,
18425 + .procname = "socket_client_gid",
18426 + .data = &grsec_socket_client_gid,
18427 + .maxlen = sizeof(int),
18429 + .proc_handler = &proc_dointvec,
18432 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18434 + .ctl_name = GS_SOCKET_SERVER,
18435 + .procname = "socket_server",
18436 + .data = &grsec_enable_socket_server,
18437 + .maxlen = sizeof(int),
18439 + .proc_handler = &proc_dointvec,
18442 + .ctl_name = GS_SOCKET_SERVER_GID,
18443 + .procname = "socket_server_gid",
18444 + .data = &grsec_socket_server_gid,
18445 + .maxlen = sizeof(int),
18447 + .proc_handler = &proc_dointvec,
18450 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
18452 + .ctl_name = GS_GROUP,
18453 + .procname = "audit_group",
18454 + .data = &grsec_enable_group,
18455 + .maxlen = sizeof(int),
18457 + .proc_handler = &proc_dointvec,
18460 + .ctl_name = GS_GID,
18461 + .procname = "audit_gid",
18462 + .data = &grsec_audit_gid,
18463 + .maxlen = sizeof(int),
18465 + .proc_handler = &proc_dointvec,
18468 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
18470 + .ctl_name = GS_ACHDIR,
18471 + .procname = "audit_chdir",
18472 + .data = &grsec_enable_chdir,
18473 + .maxlen = sizeof(int),
18475 + .proc_handler = &proc_dointvec,
18478 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18480 + .ctl_name = GS_AMOUNT,
18481 + .procname = "audit_mount",
18482 + .data = &grsec_enable_mount,
18483 + .maxlen = sizeof(int),
18485 + .proc_handler = &proc_dointvec,
18488 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18490 + .ctl_name = GS_AIPC,
18491 + .procname = "audit_ipc",
18492 + .data = &grsec_enable_audit_ipc,
18493 + .maxlen = sizeof(int),
18495 + .proc_handler = &proc_dointvec,
18498 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
18500 + .ctl_name = GS_TEXTREL,
18501 + .procname = "audit_textrel",
18502 + .data = &grsec_enable_audit_textrel,
18503 + .maxlen = sizeof(int),
18505 + .proc_handler = &proc_dointvec,
18508 +#ifdef CONFIG_GRKERNSEC_DMESG
18510 + .ctl_name = GS_DMSG,
18511 + .procname = "dmesg",
18512 + .data = &grsec_enable_dmesg,
18513 + .maxlen = sizeof(int),
18515 + .proc_handler = &proc_dointvec,
18518 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
18520 + .ctl_name = GS_FINDTASK,
18521 + .procname = "chroot_findtask",
18522 + .data = &grsec_enable_chroot_findtask,
18523 + .maxlen = sizeof(int),
18525 + .proc_handler = &proc_dointvec,
18528 +#ifdef CONFIG_GRKERNSEC_SHM
18530 + .ctl_name = GS_SHM,
18531 + .procname = "destroy_unused_shm",
18532 + .data = &grsec_enable_shm,
18533 + .maxlen = sizeof(int),
18535 + .proc_handler = &proc_dointvec,
18538 +#ifdef CONFIG_GRKERNSEC_RESLOG
18540 + .ctl_name = GS_RESLOG,
18541 + .procname = "resource_logging",
18542 + .data = &grsec_resource_logging,
18543 + .maxlen = sizeof(int),
18545 + .proc_handler = &proc_dointvec,
18549 + .ctl_name = GS_LOCK,
18550 + .procname = "grsec_lock",
18551 + .data = &grsec_lock,
18552 + .maxlen = sizeof(int),
18554 + .proc_handler = &proc_dointvec,
18557 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18559 + .ctl_name = GS_MODSTOP,
18560 + .procname = "disable_modules",
18561 + .data = &grsec_modstop,
18562 + .maxlen = sizeof(int),
18564 + .proc_handler = &proc_dointvec,
18567 + { .ctl_name = 0 }
18571 +int gr_check_modstop(void)
18573 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18574 + if (grsec_modstop == 1) {
18575 + gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
18581 diff -urNp linux-2.6.17.7/grsecurity/grsec_textrel.c linux-2.6.17.7/grsecurity/grsec_textrel.c
18582 --- linux-2.6.17.7/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
18583 +++ linux-2.6.17.7/grsecurity/grsec_textrel.c 2006-08-01 20:29:47.000000000 -0400
18585 +#include <linux/kernel.h>
18586 +#include <linux/sched.h>
18587 +#include <linux/mm.h>
18588 +#include <linux/file.h>
18589 +#include <linux/grinternal.h>
18590 +#include <linux/grsecurity.h>
18593 +gr_log_textrel(struct vm_area_struct * vma)
18595 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
18596 + if (grsec_enable_audit_textrel)
18597 + gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
18601 diff -urNp linux-2.6.17.7/grsecurity/grsec_time.c linux-2.6.17.7/grsecurity/grsec_time.c
18602 --- linux-2.6.17.7/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
18603 +++ linux-2.6.17.7/grsecurity/grsec_time.c 2006-08-01 20:29:47.000000000 -0400
18605 +#include <linux/kernel.h>
18606 +#include <linux/sched.h>
18607 +#include <linux/grinternal.h>
18610 +gr_log_timechange(void)
18612 +#ifdef CONFIG_GRKERNSEC_TIME
18613 + if (grsec_enable_time)
18614 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
18618 diff -urNp linux-2.6.17.7/grsecurity/grsec_tpe.c linux-2.6.17.7/grsecurity/grsec_tpe.c
18619 --- linux-2.6.17.7/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
18620 +++ linux-2.6.17.7/grsecurity/grsec_tpe.c 2006-08-01 20:29:47.000000000 -0400
18622 +#include <linux/kernel.h>
18623 +#include <linux/sched.h>
18624 +#include <linux/file.h>
18625 +#include <linux/fs.h>
18626 +#include <linux/grinternal.h>
18628 +extern int gr_acl_tpe_check(void);
18631 +gr_tpe_allow(const struct file *file)
18633 +#ifdef CONFIG_GRKERNSEC
18634 + struct inode *inode = file->f_dentry->d_parent->d_inode;
18636 + if (current->uid && ((grsec_enable_tpe &&
18637 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
18638 + !in_group_p(grsec_tpe_gid)
18640 + in_group_p(grsec_tpe_gid)
18642 + ) || gr_acl_tpe_check()) &&
18643 + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
18644 + (inode->i_mode & S_IWOTH))))) {
18645 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
18648 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
18649 + if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
18650 + ((inode->i_uid && (inode->i_uid != current->uid)) ||
18651 + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
18652 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
18659 diff -urNp linux-2.6.17.7/grsecurity/grsum.c linux-2.6.17.7/grsecurity/grsum.c
18660 --- linux-2.6.17.7/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
18661 +++ linux-2.6.17.7/grsecurity/grsum.c 2006-08-01 20:29:47.000000000 -0400
18663 +#include <linux/kernel.h>
18664 +#include <linux/sched.h>
18665 +#include <linux/mm.h>
18666 +#include <asm/scatterlist.h>
18667 +#include <linux/crypto.h>
18668 +#include <linux/gracl.h>
18671 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
18672 +#error "crypto and sha256 must be built into the kernel"
18676 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
18679 + struct crypto_tfm *tfm;
18680 + unsigned char temp_sum[GR_SHA_LEN];
18681 + struct scatterlist sg[2];
18682 + volatile int retval = 0;
18683 + volatile int dummy = 0;
18686 + tfm = crypto_alloc_tfm("sha256", 0);
18687 + if (tfm == NULL) {
18688 + /* should never happen, since sha256 should be built in */
18692 + crypto_digest_init(tfm);
18695 + sg[0].page = virt_to_page(p);
18696 + sg[0].offset = ((long) p & ~PAGE_MASK);
18697 + sg[0].length = GR_SALT_LEN;
18699 + crypto_digest_update(tfm, sg, 1);
18702 + sg[0].page = virt_to_page(p);
18703 + sg[0].offset = ((long) p & ~PAGE_MASK);
18704 + sg[0].length = strlen(entry->pw);
18706 + crypto_digest_update(tfm, sg, 1);
18708 + crypto_digest_final(tfm, temp_sum);
18710 + memset(entry->pw, 0, GR_PW_LEN);
18712 + for (i = 0; i < GR_SHA_LEN; i++)
18713 + if (sum[i] != temp_sum[i])
18716 + dummy = 1; // waste a cycle
18718 + crypto_free_tfm(tfm);
18722 diff -urNp linux-2.6.17.7/include/asm-alpha/a.out.h linux-2.6.17.7/include/asm-alpha/a.out.h
18723 --- linux-2.6.17.7/include/asm-alpha/a.out.h 2006-07-24 23:36:01.000000000 -0400
18724 +++ linux-2.6.17.7/include/asm-alpha/a.out.h 2006-08-01 20:29:47.000000000 -0400
18725 @@ -98,7 +98,7 @@ struct exec
18726 set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
18727 ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
18729 -#define STACK_TOP \
18730 +#define __STACK_TOP \
18731 (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
18734 diff -urNp linux-2.6.17.7/include/asm-alpha/elf.h linux-2.6.17.7/include/asm-alpha/elf.h
18735 --- linux-2.6.17.7/include/asm-alpha/elf.h 2006-07-24 23:36:01.000000000 -0400
18736 +++ linux-2.6.17.7/include/asm-alpha/elf.h 2006-08-01 20:29:47.000000000 -0400
18737 @@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
18739 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
18741 +#ifdef CONFIG_PAX_ASLR
18742 +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
18744 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
18745 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
18746 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
18747 +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
18748 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
18749 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
18752 /* $0 is set by ld.so to a pointer to a function which might be
18753 registered using atexit. This provides a mean for the dynamic
18754 linker to call DT_FINI functions for shared libraries that have
18755 diff -urNp linux-2.6.17.7/include/asm-alpha/kmap_types.h linux-2.6.17.7/include/asm-alpha/kmap_types.h
18756 --- linux-2.6.17.7/include/asm-alpha/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
18757 +++ linux-2.6.17.7/include/asm-alpha/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
18758 @@ -25,7 +25,8 @@ D(9) KM_IRQ0,
18763 +D(13) KM_CLEARPAGE,
18768 diff -urNp linux-2.6.17.7/include/asm-alpha/page.h linux-2.6.17.7/include/asm-alpha/page.h
18769 --- linux-2.6.17.7/include/asm-alpha/page.h 2006-07-24 23:36:01.000000000 -0400
18770 +++ linux-2.6.17.7/include/asm-alpha/page.h 2006-08-01 20:29:47.000000000 -0400
18771 @@ -93,6 +93,16 @@ typedef unsigned long pgprot_t;
18773 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
18774 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18776 +#ifdef CONFIG_PAX_PAGEEXEC
18777 +#ifdef CONFIG_PAX_MPROTECT
18778 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18779 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18781 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18785 #endif /* __KERNEL__ */
18787 #include <asm-generic/memory_model.h>
18788 diff -urNp linux-2.6.17.7/include/asm-alpha/pgtable.h linux-2.6.17.7/include/asm-alpha/pgtable.h
18789 --- linux-2.6.17.7/include/asm-alpha/pgtable.h 2006-07-24 23:36:01.000000000 -0400
18790 +++ linux-2.6.17.7/include/asm-alpha/pgtable.h 2006-08-01 20:29:47.000000000 -0400
18791 @@ -102,6 +102,17 @@ struct vm_area_struct;
18792 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
18793 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
18794 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
18796 +#ifdef CONFIG_PAX_PAGEEXEC
18797 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
18798 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
18799 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
18801 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
18802 +# define PAGE_COPY_NOEXEC PAGE_COPY
18803 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
18806 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
18808 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
18809 diff -urNp linux-2.6.17.7/include/asm-arm/a.out.h linux-2.6.17.7/include/asm-arm/a.out.h
18810 --- linux-2.6.17.7/include/asm-arm/a.out.h 2006-07-24 23:36:01.000000000 -0400
18811 +++ linux-2.6.17.7/include/asm-arm/a.out.h 2006-08-01 20:29:47.000000000 -0400
18812 @@ -28,7 +28,7 @@ struct exec
18816 -#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
18817 +#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
18818 TASK_SIZE : TASK_SIZE_26)
18821 diff -urNp linux-2.6.17.7/include/asm-arm/elf.h linux-2.6.17.7/include/asm-arm/elf.h
18822 --- linux-2.6.17.7/include/asm-arm/elf.h 2006-07-24 23:36:01.000000000 -0400
18823 +++ linux-2.6.17.7/include/asm-arm/elf.h 2006-08-01 20:29:47.000000000 -0400
18824 @@ -56,6 +56,17 @@ typedef struct user_fp elf_fpregset_t;
18826 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
18828 +#ifdef CONFIG_PAX_ASLR
18829 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x00008000UL
18831 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
18832 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
18833 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
18834 +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
18835 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
18836 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
18839 /* When the program starts, a1 contains a pointer to a function to be
18840 registered with atexit, as per the SVR4 ABI. A value of 0 means we
18841 have no such handler. */
18842 diff -urNp linux-2.6.17.7/include/asm-arm/kmap_types.h linux-2.6.17.7/include/asm-arm/kmap_types.h
18843 --- linux-2.6.17.7/include/asm-arm/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
18844 +++ linux-2.6.17.7/include/asm-arm/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
18845 @@ -18,6 +18,7 @@ enum km_type {
18853 diff -urNp linux-2.6.17.7/include/asm-arm26/kmap_types.h linux-2.6.17.7/include/asm-arm26/kmap_types.h
18854 --- linux-2.6.17.7/include/asm-arm26/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
18855 +++ linux-2.6.17.7/include/asm-arm26/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
18866 diff -urNp linux-2.6.17.7/include/asm-cris/kmap_types.h linux-2.6.17.7/include/asm-cris/kmap_types.h
18867 --- linux-2.6.17.7/include/asm-cris/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
18868 +++ linux-2.6.17.7/include/asm-cris/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
18869 @@ -19,6 +19,7 @@ enum km_type {
18877 diff -urNp linux-2.6.17.7/include/asm-frv/kmap_types.h linux-2.6.17.7/include/asm-frv/kmap_types.h
18878 --- linux-2.6.17.7/include/asm-frv/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
18879 +++ linux-2.6.17.7/include/asm-frv/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
18880 @@ -23,6 +23,7 @@ enum km_type {
18888 diff -urNp linux-2.6.17.7/include/asm-h8300/kmap_types.h linux-2.6.17.7/include/asm-h8300/kmap_types.h
18889 --- linux-2.6.17.7/include/asm-h8300/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
18890 +++ linux-2.6.17.7/include/asm-h8300/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
18891 @@ -15,6 +15,7 @@ enum km_type {
18899 diff -urNp linux-2.6.17.7/include/asm-i386/a.out.h linux-2.6.17.7/include/asm-i386/a.out.h
18900 --- linux-2.6.17.7/include/asm-i386/a.out.h 2006-07-24 23:36:01.000000000 -0400
18901 +++ linux-2.6.17.7/include/asm-i386/a.out.h 2006-08-01 20:29:47.000000000 -0400
18902 @@ -19,7 +19,11 @@ struct exec
18906 -#define STACK_TOP TASK_SIZE
18907 +#ifdef CONFIG_PAX_SEGMEXEC
18908 +#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
18910 +#define __STACK_TOP TASK_SIZE
18915 diff -urNp linux-2.6.17.7/include/asm-i386/alternative.h linux-2.6.17.7/include/asm-i386/alternative.h
18916 --- linux-2.6.17.7/include/asm-i386/alternative.h 2006-07-24 23:36:01.000000000 -0400
18917 +++ linux-2.6.17.7/include/asm-i386/alternative.h 2006-08-01 20:29:47.000000000 -0400
18918 @@ -47,7 +47,7 @@ extern void alternatives_smp_switch(int
18919 " .byte 662b-661b\n" /* sourcelen */ \
18920 " .byte 664f-663f\n" /* replacementlen */ \
18922 - ".section .altinstr_replacement,\"ax\"\n" \
18923 + ".section .altinstr_replacement,\"a\"\n" \
18924 "663:\n\t" newinstr "\n664:\n" /* replacement */\
18925 ".previous" :: "i" (feature) : "memory")
18927 @@ -71,7 +71,7 @@ extern void alternatives_smp_switch(int
18928 " .byte 662b-661b\n" /* sourcelen */ \
18929 " .byte 664f-663f\n" /* replacementlen */ \
18931 - ".section .altinstr_replacement,\"ax\"\n" \
18932 + ".section .altinstr_replacement,\"a\"\n" \
18933 "663:\n\t" newinstr "\n664:\n" /* replacement */\
18934 ".previous" :: "i" (feature), ##input)
18936 @@ -110,7 +110,7 @@ extern void alternatives_smp_switch(int
18937 " .byte 662b-661b\n" /* sourcelen */ \
18938 " .byte 664f-663f\n" /* replacementlen */ \
18940 - ".section .smp_altinstr_replacement,\"awx\"\n" \
18941 + ".section .smp_altinstr_replacement,\"aw\"\n" \
18942 "663:\n\t" upinstr "\n" /* replacement */ \
18943 "664:\n\t.fill 662b-661b,1,0x42\n" /* space for original */ \
18944 ".previous" : args)
18945 diff -urNp linux-2.6.17.7/include/asm-i386/auxvec.h linux-2.6.17.7/include/asm-i386/auxvec.h
18946 --- linux-2.6.17.7/include/asm-i386/auxvec.h 2006-07-24 23:36:01.000000000 -0400
18947 +++ linux-2.6.17.7/include/asm-i386/auxvec.h 2006-08-01 20:29:47.000000000 -0400
18949 * Architecture-neutral AT_ values in 0-17, leave some room
18950 * for more of them, start the x86-specific ones at 32.
18952 +#ifndef CONFIG_PAX_NOVSYSCALL
18953 #define AT_SYSINFO 32
18954 #define AT_SYSINFO_EHDR 33
18958 diff -urNp linux-2.6.17.7/include/asm-i386/checksum.h linux-2.6.17.7/include/asm-i386/checksum.h
18959 --- linux-2.6.17.7/include/asm-i386/checksum.h 2006-07-24 23:36:01.000000000 -0400
18960 +++ linux-2.6.17.7/include/asm-i386/checksum.h 2006-08-01 20:29:47.000000000 -0400
18961 @@ -30,6 +30,12 @@ asmlinkage unsigned int csum_partial(con
18962 asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned char *dst,
18963 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
18965 +asmlinkage unsigned int csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
18966 + int len, int sum, int *src_err_ptr, int *dst_err_ptr);
18968 +asmlinkage unsigned int csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
18969 + int len, int sum, int *src_err_ptr, int *dst_err_ptr);
18972 * Note: when you get a NULL pointer exception here this means someone
18973 * passed in an incorrect kernel address to one of these functions.
18974 @@ -49,7 +55,7 @@ unsigned int csum_partial_copy_from_user
18975 int len, int sum, int *err_ptr)
18978 - return csum_partial_copy_generic((__force unsigned char *)src, dst,
18979 + return csum_partial_copy_generic_from_user((__force unsigned char *)src, dst,
18980 len, sum, err_ptr, NULL);
18983 @@ -183,7 +189,7 @@ static __inline__ unsigned int csum_and_
18986 if (access_ok(VERIFY_WRITE, dst, len))
18987 - return csum_partial_copy_generic(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
18988 + return csum_partial_copy_generic_to_user(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
18991 *err_ptr = -EFAULT;
18992 diff -urNp linux-2.6.17.7/include/asm-i386/desc.h linux-2.6.17.7/include/asm-i386/desc.h
18993 --- linux-2.6.17.7/include/asm-i386/desc.h 2006-07-24 23:36:01.000000000 -0400
18994 +++ linux-2.6.17.7/include/asm-i386/desc.h 2006-08-01 20:29:47.000000000 -0400
18995 @@ -10,11 +10,13 @@
18997 #include <linux/preempt.h>
18998 #include <linux/smp.h>
18999 -#include <linux/percpu.h>
19000 +#include <linux/sched.h>
19002 #include <asm/mmu.h>
19003 +#include <asm/pgtable.h>
19004 +#include <asm/tlbflush.h>
19006 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
19007 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
19009 DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
19011 @@ -24,13 +26,53 @@ struct Xgt_desc_struct {
19012 unsigned short pad;
19013 } __attribute__ ((packed));
19015 -extern struct Xgt_desc_struct idt_descr;
19016 -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
19018 +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
19020 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
19022 - return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
19023 + return cpu_gdt_table[cpu];
19026 +#define pax_open_kernel(cr0) \
19028 + typecheck(unsigned long,cr0); \
19029 + preempt_disable(); \
19030 + cr0 = read_cr0(); \
19031 + write_cr0(cr0 & ~0x10000UL); \
19034 +#define pax_close_kernel(cr0) \
19036 + typecheck(unsigned long,cr0); \
19037 + write_cr0(cr0); \
19038 + preempt_enable_no_resched(); \
19041 +static inline void set_user_cs(struct mm_struct *mm, int cpu)
19043 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19044 + unsigned long base = mm->context.user_cs_base;
19045 + unsigned long limit = mm->context.user_cs_limit;
19047 +#ifdef CONFIG_PAX_KERNEXEC
19048 + unsigned long cr0;
19050 + pax_open_kernel(cr0);
19053 + if (likely(limit)) {
19058 + get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].a = (limit & 0xFFFFUL) | (base << 16);
19059 + get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].b = (limit & 0xF0000UL) | 0xC0FB00UL | (base & 0xFF000000UL) | ((base >> 16) & 0xFFUL);
19061 +#ifdef CONFIG_PAX_KERNEXEC
19062 + pax_close_kernel(cr0);
19068 #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
19069 @@ -50,7 +92,7 @@ static inline struct desc_struct *get_cp
19070 * This is the ldt that every process will get unless we need
19071 * something other than this.
19073 -extern struct desc_struct default_ldt[];
19074 +extern const struct desc_struct default_ldt[];
19075 extern void set_intr_gate(unsigned int irq, void * addr);
19077 #define _set_tssldt_desc(n,addr,limit,type) \
19078 @@ -64,7 +106,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
19080 : "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
19082 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
19083 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
19085 _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
19086 offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
19087 @@ -72,11 +114,28 @@ static inline void __set_tss_desc(unsign
19089 #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
19091 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
19092 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
19094 _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
19097 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
19100 +#ifdef CONFIG_PAX_KERNEXEC
19101 + unsigned long cr0;
19103 + pax_open_kernel(cr0);
19106 + _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
19108 +#ifdef CONFIG_PAX_KERNEXEC
19109 + pax_close_kernel(cr0);
19114 #define LDT_entry_a(info) \
19115 ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
19117 @@ -90,7 +149,7 @@ static inline void set_ldt_desc(unsigned
19118 ((info)->seg_32bit << 22) | \
19119 ((info)->limit_in_pages << 23) | \
19120 ((info)->useable << 20) | \
19124 #define LDT_empty(info) (\
19125 (info)->base_addr == 0 && \
19126 @@ -134,7 +193,7 @@ static inline void clear_LDT(void)
19128 static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
19130 - void *segments = pc->ldt;
19131 + const void *segments = pc->ldt;
19132 int count = pc->size;
19134 if (likely(!count)) {
19135 @@ -162,6 +221,22 @@ static inline unsigned long get_desc_bas
19139 +static inline void _load_LDT(mm_context_t *pc)
19141 + int cpu = get_cpu();
19142 + const void *segments = pc->ldt;
19143 + int count = pc->size;
19145 + if (likely(!count)) {
19146 + segments = &default_ldt[0];
19150 + __set_ldt_desc(cpu, segments, count);
19155 #endif /* !__ASSEMBLY__ */
19158 diff -urNp linux-2.6.17.7/include/asm-i386/elf.h linux-2.6.17.7/include/asm-i386/elf.h
19159 --- linux-2.6.17.7/include/asm-i386/elf.h 2006-07-24 23:36:01.000000000 -0400
19160 +++ linux-2.6.17.7/include/asm-i386/elf.h 2006-08-01 20:29:47.000000000 -0400
19161 @@ -71,6 +71,17 @@ typedef struct user_fxsr_struct elf_fpxr
19163 #define ELF_ET_DYN_BASE ((TASK_UNMAPPED_BASE) * 2)
19165 +#ifdef CONFIG_PAX_ASLR
19166 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000000UL
19168 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
19169 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
19170 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
19171 +#define PAX_DELTA_EXEC_LEN(tsk) 15
19172 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
19173 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
19176 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
19177 now struct_user_regs, they are different) */
19179 @@ -131,7 +146,14 @@ extern int dump_task_extended_fpu (struc
19181 #define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
19182 #define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
19184 +#ifndef CONFIG_PAX_NOVSYSCALL
19185 +#ifdef CONFIG_PAX_SEGMEXEC
19186 +#define VSYSCALL_ENTRY ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? (unsigned long) &__kernel_vsyscall - SEGMEXEC_TASK_SIZE : (unsigned long) &__kernel_vsyscall)
19188 #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
19191 extern void __kernel_vsyscall;
19193 #define ARCH_DLINFO \
19194 @@ -187,3 +209,5 @@ do { \
19200 diff -urNp linux-2.6.17.7/include/asm-i386/kmap_types.h linux-2.6.17.7/include/asm-i386/kmap_types.h
19201 --- linux-2.6.17.7/include/asm-i386/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
19202 +++ linux-2.6.17.7/include/asm-i386/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
19203 @@ -23,7 +23,8 @@ D(9) KM_IRQ0,
19208 +D(13) KM_CLEARPAGE,
19213 diff -urNp linux-2.6.17.7/include/asm-i386/mach-default/apm.h linux-2.6.17.7/include/asm-i386/mach-default/apm.h
19214 --- linux-2.6.17.7/include/asm-i386/mach-default/apm.h 2006-07-24 23:36:01.000000000 -0400
19215 +++ linux-2.6.17.7/include/asm-i386/mach-default/apm.h 2006-08-01 20:29:47.000000000 -0400
19216 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
19217 __asm__ __volatile__(APM_DO_ZERO_SEGS
19220 - "lcall *%%cs:apm_bios_entry\n\t"
19221 + "lcall *%%ss:apm_bios_entry\n\t"
19225 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
19226 __asm__ __volatile__(APM_DO_ZERO_SEGS
19229 - "lcall *%%cs:apm_bios_entry\n\t"
19230 + "lcall *%%ss:apm_bios_entry\n\t"
19234 diff -urNp linux-2.6.17.7/include/asm-i386/mach-default/do_timer.h linux-2.6.17.7/include/asm-i386/mach-default/do_timer.h
19235 --- linux-2.6.17.7/include/asm-i386/mach-default/do_timer.h 2006-07-24 23:36:01.000000000 -0400
19236 +++ linux-2.6.17.7/include/asm-i386/mach-default/do_timer.h 2006-08-01 20:29:47.000000000 -0400
19237 @@ -18,7 +18,7 @@ static inline void do_timer_interrupt_ho
19241 - update_process_times(user_mode_vm(regs));
19242 + update_process_times(user_mode(regs));
19245 * In the SMP case we use the local APIC timer interrupt to do the
19246 diff -urNp linux-2.6.17.7/include/asm-i386/mach-visws/do_timer.h linux-2.6.17.7/include/asm-i386/mach-visws/do_timer.h
19247 --- linux-2.6.17.7/include/asm-i386/mach-visws/do_timer.h 2006-07-24 23:36:01.000000000 -0400
19248 +++ linux-2.6.17.7/include/asm-i386/mach-visws/do_timer.h 2006-08-01 20:29:47.000000000 -0400
19249 @@ -11,7 +11,7 @@ static inline void do_timer_interrupt_ho
19253 - update_process_times(user_mode_vm(regs));
19254 + update_process_times(user_mode(regs));
19257 * In the SMP case we use the local APIC timer interrupt to do the
19258 diff -urNp linux-2.6.17.7/include/asm-i386/mach-voyager/do_timer.h linux-2.6.17.7/include/asm-i386/mach-voyager/do_timer.h
19259 --- linux-2.6.17.7/include/asm-i386/mach-voyager/do_timer.h 2006-07-24 23:36:01.000000000 -0400
19260 +++ linux-2.6.17.7/include/asm-i386/mach-voyager/do_timer.h 2006-08-01 20:29:47.000000000 -0400
19261 @@ -5,7 +5,7 @@ static inline void do_timer_interrupt_ho
19265 - update_process_times(user_mode_vm(regs));
19266 + update_process_times(user_mode(regs));
19269 voyager_timer_interrupt(regs);
19270 diff -urNp linux-2.6.17.7/include/asm-i386/mman.h linux-2.6.17.7/include/asm-i386/mman.h
19271 --- linux-2.6.17.7/include/asm-i386/mman.h 2006-07-24 23:36:01.000000000 -0400
19272 +++ linux-2.6.17.7/include/asm-i386/mman.h 2006-08-01 20:29:47.000000000 -0400
19274 #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
19275 #define MAP_NONBLOCK 0x10000 /* do not block on IO */
19277 +#ifdef CONFIG_PAX_SEGMEXEC
19278 +#define MAP_MIRROR 0x20000
19281 #define MCL_CURRENT 1 /* lock all current mappings */
19282 #define MCL_FUTURE 2 /* lock all future mappings */
19284 diff -urNp linux-2.6.17.7/include/asm-i386/mmu.h linux-2.6.17.7/include/asm-i386/mmu.h
19285 --- linux-2.6.17.7/include/asm-i386/mmu.h 2006-07-24 23:36:01.000000000 -0400
19286 +++ linux-2.6.17.7/include/asm-i386/mmu.h 2006-08-01 20:29:47.000000000 -0400
19287 @@ -12,6 +12,17 @@ typedef struct {
19289 struct semaphore sem;
19292 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19293 + unsigned long user_cs_base;
19294 + unsigned long user_cs_limit;
19296 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
19297 + cpumask_t cpu_user_cs_mask;
19305 diff -urNp linux-2.6.17.7/include/asm-i386/mmu_context.h linux-2.6.17.7/include/asm-i386/mmu_context.h
19306 --- linux-2.6.17.7/include/asm-i386/mmu_context.h 2006-07-24 23:36:01.000000000 -0400
19307 +++ linux-2.6.17.7/include/asm-i386/mmu_context.h 2006-08-01 20:29:47.000000000 -0400
19308 @@ -46,6 +46,18 @@ static inline void switch_mm(struct mm_s
19310 if (unlikely(prev->context.ldt != next->context.ldt))
19311 load_LDT_nolock(&next->context, cpu);
19313 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
19314 + cpu_clear(cpu, prev->context.cpu_user_cs_mask);
19315 + cpu_set(cpu, next->context.cpu_user_cs_mask);
19318 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19319 + if (prev->context.user_cs_base != next->context.user_cs_base ||
19320 + prev->context.user_cs_limit != next->context.user_cs_limit)
19323 + set_user_cs(next, cpu);
19327 @@ -58,6 +70,12 @@ static inline void switch_mm(struct mm_s
19329 load_cr3(next->pgd);
19330 load_LDT_nolock(&next->context, cpu);
19332 +#ifdef CONFIG_PAX_PAGEEXEC
19333 + cpu_set(cpu, next->context.cpu_user_cs_mask);
19336 + set_user_cs(next, cpu);
19340 diff -urNp linux-2.6.17.7/include/asm-i386/module.h linux-2.6.17.7/include/asm-i386/module.h
19341 --- linux-2.6.17.7/include/asm-i386/module.h 2006-07-24 23:36:01.000000000 -0400
19342 +++ linux-2.6.17.7/include/asm-i386/module.h 2006-08-01 20:29:47.000000000 -0400
19343 @@ -72,6 +72,12 @@ struct mod_arch_specific
19344 #define MODULE_STACKSIZE ""
19347 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
19348 +#ifdef CONFIG_GRKERNSEC
19349 +#define MODULE_GRSEC "GRSECURITY "
19351 +#define MODULE_GRSEC ""
19354 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
19356 #endif /* _ASM_I386_MODULE_H */
19357 diff -urNp linux-2.6.17.7/include/asm-i386/page.h linux-2.6.17.7/include/asm-i386/page.h
19358 --- linux-2.6.17.7/include/asm-i386/page.h 2006-07-24 23:36:01.000000000 -0400
19359 +++ linux-2.6.17.7/include/asm-i386/page.h 2006-08-01 20:29:47.000000000 -0400
19360 @@ -57,7 +57,6 @@ typedef struct { unsigned long long pgpr
19361 typedef struct { unsigned long pte_low; } pte_t;
19362 typedef struct { unsigned long pgd; } pgd_t;
19363 typedef struct { unsigned long pgprot; } pgprot_t;
19364 -#define boot_pte_t pte_t /* or would you rather have a typedef */
19365 #define pte_val(x) ((x).pte_low)
19366 #define HPAGE_SHIFT 22
19368 @@ -118,6 +117,15 @@ extern int page_is_ram(unsigned long pag
19370 #define __KERNEL_START (__PAGE_OFFSET + __PHYSICAL_START)
19372 +#ifdef CONFIG_PAX_KERNEXEC
19373 +#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + ((__PHYSICAL_START + ~(4*1024*1024)) & (4*1024*1024)))
19374 +#ifndef __ASSEMBLY__
19375 +extern unsigned char MODULES_VADDR[];
19376 +extern unsigned char MODULES_END[];
19379 +#define __KERNEL_TEXT_OFFSET (0)
19382 #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
19383 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
19384 @@ -137,6 +145,19 @@ extern int page_is_ram(unsigned long pag
19385 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
19386 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
19388 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19389 +#ifdef CONFIG_PAX_MPROTECT
19390 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
19391 + ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
19393 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
19397 +#ifdef CONFIG_PAX_PAGEEXEC
19398 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
19401 #endif /* __KERNEL__ */
19403 #include <asm-generic/memory_model.h>
19404 diff -urNp linux-2.6.17.7/include/asm-i386/pgalloc.h linux-2.6.17.7/include/asm-i386/pgalloc.h
19405 --- linux-2.6.17.7/include/asm-i386/pgalloc.h 2006-07-24 23:36:01.000000000 -0400
19406 +++ linux-2.6.17.7/include/asm-i386/pgalloc.h 2006-08-01 20:29:47.000000000 -0400
19409 #include <linux/config.h>
19410 #include <asm/fixmap.h>
19411 +#include <asm/desc.h>
19412 #include <linux/threads.h>
19413 #include <linux/mm.h> /* for struct page */
19415 +#ifdef CONFIG_PAX_NOVSYSCALL
19416 +#define pmd_populate_kernel(mm, pmd, pte) \
19417 + set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
19419 #define pmd_populate_kernel(mm, pmd, pte) \
19420 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
19423 #define pmd_populate(mm, pmd, pte) \
19424 set_pmd(pmd, __pmd(_PAGE_TABLE + \
19425 diff -urNp linux-2.6.17.7/include/asm-i386/pgtable.h linux-2.6.17.7/include/asm-i386/pgtable.h
19426 --- linux-2.6.17.7/include/asm-i386/pgtable.h 2006-07-24 23:36:01.000000000 -0400
19427 +++ linux-2.6.17.7/include/asm-i386/pgtable.h 2006-08-01 20:29:47.000000000 -0400
19428 @@ -34,7 +34,6 @@ struct vm_area_struct;
19430 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
19431 extern unsigned long empty_zero_page[1024];
19432 -extern pgd_t swapper_pg_dir[1024];
19433 extern kmem_cache_t *pgd_cache;
19434 extern kmem_cache_t *pmd_cache;
19435 extern spinlock_t pgd_lock;
19436 @@ -59,6 +58,11 @@ void paging_init(void);
19437 # include <asm/pgtable-2level-defs.h>
19440 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
19441 +#ifdef CONFIG_X86_PAE
19442 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
19445 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
19446 #define PGDIR_MASK (~(PGDIR_SIZE-1))
19448 @@ -68,9 +72,11 @@ void paging_init(void);
19449 #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
19450 #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
19452 +#ifndef CONFIG_X86_PAE
19453 #define TWOLEVEL_PGDIR_SHIFT 22
19454 #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
19455 #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
19458 /* Just any arbitrary offset to the start of the vmalloc VM area: the
19459 * current 8MB value just means that there will be a 8MB "hole" after the
19460 @@ -141,17 +147,26 @@ void paging_init(void);
19462 #define PAGE_SHARED_EXEC \
19463 __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
19464 -#define PAGE_COPY_NOEXEC \
19465 - __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
19466 #define PAGE_COPY_EXEC \
19467 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
19468 -#define PAGE_COPY \
19470 #define PAGE_READONLY \
19471 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
19472 #define PAGE_READONLY_EXEC \
19473 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
19475 +#ifdef CONFIG_PAX_PAGEEXEC
19476 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
19477 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
19478 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
19480 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
19481 +# define PAGE_COPY_NOEXEC \
19482 + __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
19483 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
19486 +#define PAGE_COPY \
19488 #define _PAGE_KERNEL \
19489 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
19490 #define _PAGE_KERNEL_EXEC \
19491 @@ -176,18 +191,18 @@ extern unsigned long long __PAGE_KERNEL,
19492 * This is the closest we can get..
19494 #define __P000 PAGE_NONE
19495 -#define __P001 PAGE_READONLY
19496 -#define __P010 PAGE_COPY
19497 -#define __P011 PAGE_COPY
19498 +#define __P001 PAGE_READONLY_NOEXEC
19499 +#define __P010 PAGE_COPY_NOEXEC
19500 +#define __P011 PAGE_COPY_NOEXEC
19501 #define __P100 PAGE_READONLY_EXEC
19502 #define __P101 PAGE_READONLY_EXEC
19503 #define __P110 PAGE_COPY_EXEC
19504 #define __P111 PAGE_COPY_EXEC
19506 #define __S000 PAGE_NONE
19507 -#define __S001 PAGE_READONLY
19508 -#define __S010 PAGE_SHARED
19509 -#define __S011 PAGE_SHARED
19510 +#define __S001 PAGE_READONLY_NOEXEC
19511 +#define __S010 PAGE_SHARED_NOEXEC
19512 +#define __S011 PAGE_SHARED_NOEXEC
19513 #define __S100 PAGE_READONLY_EXEC
19514 #define __S101 PAGE_READONLY_EXEC
19515 #define __S110 PAGE_SHARED_EXEC
19516 @@ -431,6 +446,9 @@ extern void noexec_setup(const char *str
19518 #endif /* !__ASSEMBLY__ */
19520 +#define HAVE_ARCH_UNMAPPED_AREA
19521 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
19523 #ifdef CONFIG_FLATMEM
19524 #define kern_addr_valid(addr) (1)
19525 #endif /* CONFIG_FLATMEM */
19526 diff -urNp linux-2.6.17.7/include/asm-i386/processor.h linux-2.6.17.7/include/asm-i386/processor.h
19527 --- linux-2.6.17.7/include/asm-i386/processor.h 2006-07-24 23:36:01.000000000 -0400
19528 +++ linux-2.6.17.7/include/asm-i386/processor.h 2006-08-01 20:29:47.000000000 -0400
19530 #include <linux/cache.h>
19531 #include <linux/config.h>
19532 #include <linux/threads.h>
19533 -#include <asm/percpu.h>
19534 #include <linux/cpumask.h>
19536 /* flag for disabling the tsc */
19537 @@ -94,8 +93,6 @@ struct cpuinfo_x86 {
19539 extern struct cpuinfo_x86 boot_cpu_data;
19540 extern struct cpuinfo_x86 new_cpu_data;
19541 -extern struct tss_struct doublefault_tss;
19542 -DECLARE_PER_CPU(struct tss_struct, init_tss);
19545 extern struct cpuinfo_x86 cpu_data[];
19546 @@ -325,10 +322,19 @@ extern int bootloader_type;
19548 #define TASK_SIZE (PAGE_OFFSET)
19550 +#ifdef CONFIG_PAX_SEGMEXEC
19551 +#define SEGMEXEC_TASK_SIZE ((PAGE_OFFSET) / 2)
19554 /* This decides where the kernel will search for a free chunk of vm
19555 * space during mmap's.
19558 +#ifdef CONFIG_PAX_SEGMEXEC
19559 +#define TASK_UNMAPPED_BASE (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
19561 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
19564 #define HAVE_ARCH_PICK_MMAP_LAYOUT
19566 @@ -444,6 +450,9 @@ struct tss_struct {
19568 #define ARCH_MIN_TASKALIGN 16
19570 +extern struct tss_struct doublefault_tss;
19571 +extern struct tss_struct init_tss[NR_CPUS];
19573 struct thread_struct {
19574 /* cached TLS descriptors. */
19575 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
19576 @@ -472,6 +481,7 @@ struct thread_struct {
19579 #define INIT_THREAD { \
19580 + .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
19581 .vm86_info = NULL, \
19582 .sysenter_cs = __KERNEL_CS, \
19583 .io_bitmap_ptr = NULL, \
19584 @@ -484,7 +494,7 @@ struct thread_struct {
19585 * be within the limit.
19587 #define INIT_TSS { \
19588 - .esp0 = sizeof(init_stack) + (long)&init_stack, \
19589 + .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
19590 .ss0 = __KERNEL_DS, \
19591 .ss1 = __KERNEL_CS, \
19592 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
19593 @@ -560,11 +570,7 @@ void show_trace(struct task_struct *task
19594 unsigned long get_wchan(struct task_struct *p);
19596 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
19597 -#define KSTK_TOP(info) \
19599 - unsigned long *__ptr = (unsigned long *)(info); \
19600 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
19602 +#define KSTK_TOP(info) ((info)->task.thread.esp0)
19605 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
19606 @@ -579,7 +585,7 @@ unsigned long get_wchan(struct task_stru
19607 #define task_pt_regs(task) \
19609 struct pt_regs *__regs__; \
19610 - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
19611 + __regs__ = (struct pt_regs *)((task)->thread.esp0); \
19615 diff -urNp linux-2.6.17.7/include/asm-i386/ptrace.h linux-2.6.17.7/include/asm-i386/ptrace.h
19616 --- linux-2.6.17.7/include/asm-i386/ptrace.h 2006-07-24 23:36:01.000000000 -0400
19617 +++ linux-2.6.17.7/include/asm-i386/ptrace.h 2006-08-01 20:29:47.000000000 -0400
19618 @@ -65,17 +65,18 @@ struct task_struct;
19619 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
19622 - * user_mode_vm(regs) determines whether a register set came from user mode.
19623 + * user_mode(regs) determines whether a register set came from user mode.
19624 * This is true if V8086 mode was enabled OR if the register set was from
19625 * protected mode with RPL-3 CS value. This tricky test checks that with
19626 * one comparison. Many places in the kernel can bypass this full check
19627 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
19628 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
19631 -static inline int user_mode(struct pt_regs *regs)
19632 +static inline int user_mode_novm(struct pt_regs *regs)
19634 return (regs->xcs & 3) != 0;
19636 -static inline int user_mode_vm(struct pt_regs *regs)
19637 +static inline int user_mode(struct pt_regs *regs)
19639 return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
19641 diff -urNp linux-2.6.17.7/include/asm-i386/system.h linux-2.6.17.7/include/asm-i386/system.h
19642 --- linux-2.6.17.7/include/asm-i386/system.h 2006-07-24 23:36:01.000000000 -0400
19643 +++ linux-2.6.17.7/include/asm-i386/system.h 2006-08-01 20:29:47.000000000 -0400
19645 #include <linux/kernel.h>
19646 #include <asm/segment.h>
19647 #include <asm/cpufeature.h>
19648 +#include <asm/page.h>
19649 #include <linux/bitops.h> /* for LOCK_PREFIX */
19652 @@ -151,7 +152,7 @@ static inline unsigned long get_limit(un
19653 unsigned long __limit;
19654 __asm__("lsll %1,%0"
19655 :"=r" (__limit):"r" (segment));
19656 - return __limit+1;
19660 #define nop() __asm__ __volatile__ ("nop")
19661 @@ -496,7 +497,7 @@ static inline void sched_cacheflush(void
19665 -extern unsigned long arch_align_stack(unsigned long sp);
19666 +#define arch_align_stack(x) (x)
19667 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
19669 void default_idle(void);
19670 diff -urNp linux-2.6.17.7/include/asm-i386/uaccess.h linux-2.6.17.7/include/asm-i386/uaccess.h
19671 --- linux-2.6.17.7/include/asm-i386/uaccess.h 2006-07-24 23:36:01.000000000 -0400
19672 +++ linux-2.6.17.7/include/asm-i386/uaccess.h 2006-08-01 20:29:47.000000000 -0400
19674 #include <linux/prefetch.h>
19675 #include <linux/string.h>
19676 #include <asm/page.h>
19677 +#include <asm/segment.h>
19678 +#include <asm/desc.h>
19680 #define VERIFY_READ 0
19681 #define VERIFY_WRITE 1
19684 #define get_ds() (KERNEL_DS)
19685 #define get_fs() (current_thread_info()->addr_limit)
19686 -#define set_fs(x) (current_thread_info()->addr_limit = (x))
19687 +void __set_fs(mm_segment_t x, int cpu);
19688 +void set_fs(mm_segment_t x);
19690 #define segment_eq(a,b) ((a).seg == (b).seg)
19692 @@ -281,9 +284,12 @@ extern void __put_user_8(void);
19694 #define __put_user_u64(x, addr, err) \
19695 __asm__ __volatile__( \
19696 - "1: movl %%eax,0(%2)\n" \
19697 - "2: movl %%edx,4(%2)\n" \
19698 + " movw %w5,%%ds\n" \
19699 + "1: movl %%eax,%%ds:0(%2)\n" \
19700 + "2: movl %%edx,%%ds:4(%2)\n" \
19702 + " pushl %%ss\n" \
19704 ".section .fixup,\"ax\"\n" \
19705 "4: movl %3,%0\n" \
19707 @@ -294,7 +300,8 @@ extern void __put_user_8(void);
19711 - : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
19712 + : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
19715 #ifdef CONFIG_X86_WP_WORKS_OK
19717 @@ -333,8 +340,11 @@ struct __large_struct { unsigned long bu
19719 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
19720 __asm__ __volatile__( \
19721 - "1: mov"itype" %"rtype"1,%2\n" \
19722 + " movw %w5,%%ds\n" \
19723 + "1: mov"itype" %"rtype"1,%%ds:%2\n" \
19725 + " pushl %%ss\n" \
19727 ".section .fixup,\"ax\"\n" \
19728 "3: movl %3,%0\n" \
19730 @@ -344,7 +354,8 @@ struct __large_struct { unsigned long bu
19734 - : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
19735 + : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
19739 #define __get_user_nocheck(x,ptr,size) \
19740 @@ -372,8 +383,11 @@ do { \
19742 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
19743 __asm__ __volatile__( \
19744 - "1: mov"itype" %2,%"rtype"1\n" \
19745 + " movw %w5,%%ds\n" \
19746 + "1: mov"itype" %%ds:%2,%"rtype"1\n" \
19748 + " pushl %%ss\n" \
19750 ".section .fixup,\"ax\"\n" \
19751 "3: movl %3,%0\n" \
19752 " xor"itype" %"rtype"1,%"rtype"1\n" \
19753 @@ -384,7 +398,7 @@ do { \
19756 : "=r"(err), ltype (x) \
19757 - : "m"(__m(addr)), "i"(errret), "0"(err))
19758 + : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
19761 unsigned long __must_check __copy_to_user_ll(void __user *to,
19762 diff -urNp linux-2.6.17.7/include/asm-ia64/elf.h linux-2.6.17.7/include/asm-ia64/elf.h
19763 --- linux-2.6.17.7/include/asm-ia64/elf.h 2006-07-24 23:36:01.000000000 -0400
19764 +++ linux-2.6.17.7/include/asm-ia64/elf.h 2006-08-01 20:29:47.000000000 -0400
19765 @@ -163,6 +163,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
19766 typedef struct ia64_fpreg elf_fpreg_t;
19767 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
19769 +#ifdef CONFIG_PAX_ASLR
19770 +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
19772 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
19773 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
19774 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
19775 +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
19776 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
19777 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
19781 struct pt_regs; /* forward declaration... */
19782 diff -urNp linux-2.6.17.7/include/asm-ia64/kmap_types.h linux-2.6.17.7/include/asm-ia64/kmap_types.h
19783 --- linux-2.6.17.7/include/asm-ia64/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
19784 +++ linux-2.6.17.7/include/asm-ia64/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
19785 @@ -23,7 +23,8 @@ D(9) KM_IRQ0,
19790 +D(13) KM_CLEARPAGE,
19795 diff -urNp linux-2.6.17.7/include/asm-ia64/page.h linux-2.6.17.7/include/asm-ia64/page.h
19796 --- linux-2.6.17.7/include/asm-ia64/page.h 2006-07-24 23:36:01.000000000 -0400
19797 +++ linux-2.6.17.7/include/asm-ia64/page.h 2006-08-01 20:29:47.000000000 -0400
19798 @@ -229,4 +229,13 @@ get_order (unsigned long size)
19799 (((current->personality & READ_IMPLIES_EXEC) != 0) \
19802 +#ifdef CONFIG_PAX_PAGEEXEC
19803 +#ifdef CONFIG_PAX_MPROTECT
19804 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
19805 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
19807 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
19811 #endif /* _ASM_IA64_PAGE_H */
19812 diff -urNp linux-2.6.17.7/include/asm-ia64/pgtable.h linux-2.6.17.7/include/asm-ia64/pgtable.h
19813 --- linux-2.6.17.7/include/asm-ia64/pgtable.h 2006-07-24 23:36:01.000000000 -0400
19814 +++ linux-2.6.17.7/include/asm-ia64/pgtable.h 2006-08-01 20:29:47.000000000 -0400
19815 @@ -144,6 +144,17 @@
19816 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
19817 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
19818 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
19820 +#ifdef CONFIG_PAX_PAGEEXEC
19821 +# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
19822 +# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
19823 +# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
19825 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
19826 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
19827 +# define PAGE_COPY_NOEXEC PAGE_COPY
19830 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
19831 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
19832 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
19833 diff -urNp linux-2.6.17.7/include/asm-ia64/processor.h linux-2.6.17.7/include/asm-ia64/processor.h
19834 --- linux-2.6.17.7/include/asm-ia64/processor.h 2006-07-24 23:36:01.000000000 -0400
19835 +++ linux-2.6.17.7/include/asm-ia64/processor.h 2006-08-01 20:29:47.000000000 -0400
19836 @@ -284,7 +284,7 @@ struct thread_struct {
19839 .map_base = DEFAULT_MAP_BASE, \
19840 - .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
19841 + .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \
19842 .task_size = DEFAULT_TASK_SIZE, \
19843 .last_fph_cpu = -1, \
19845 diff -urNp linux-2.6.17.7/include/asm-ia64/ustack.h linux-2.6.17.7/include/asm-ia64/ustack.h
19846 --- linux-2.6.17.7/include/asm-ia64/ustack.h 2006-07-24 23:36:01.000000000 -0400
19847 +++ linux-2.6.17.7/include/asm-ia64/ustack.h 2006-08-01 20:29:47.000000000 -0400
19849 #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
19850 /* Make a default stack size of 2GB */
19851 #define DEFAULT_USER_STACK_SIZE (1UL << 31)
19852 -#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
19853 +#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
19855 #endif /* _ASM_IA64_USTACK_H */
19856 diff -urNp linux-2.6.17.7/include/asm-m32r/kmap_types.h linux-2.6.17.7/include/asm-m32r/kmap_types.h
19857 --- linux-2.6.17.7/include/asm-m32r/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
19858 +++ linux-2.6.17.7/include/asm-m32r/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
19859 @@ -25,7 +25,8 @@ D(9) KM_IRQ0,
19864 +D(13) KM_CLEARPAGE,
19869 diff -urNp linux-2.6.17.7/include/asm-m68k/kmap_types.h linux-2.6.17.7/include/asm-m68k/kmap_types.h
19870 --- linux-2.6.17.7/include/asm-m68k/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
19871 +++ linux-2.6.17.7/include/asm-m68k/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
19872 @@ -15,6 +15,7 @@ enum km_type {
19880 diff -urNp linux-2.6.17.7/include/asm-m68knommu/kmap_types.h linux-2.6.17.7/include/asm-m68knommu/kmap_types.h
19881 --- linux-2.6.17.7/include/asm-m68knommu/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
19882 +++ linux-2.6.17.7/include/asm-m68knommu/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
19883 @@ -15,6 +15,7 @@ enum km_type {
19891 diff -urNp linux-2.6.17.7/include/asm-mips/a.out.h linux-2.6.17.7/include/asm-mips/a.out.h
19892 --- linux-2.6.17.7/include/asm-mips/a.out.h 2006-07-24 23:36:01.000000000 -0400
19893 +++ linux-2.6.17.7/include/asm-mips/a.out.h 2006-08-01 20:29:47.000000000 -0400
19894 @@ -36,10 +36,10 @@ struct exec
19897 #ifdef CONFIG_32BIT
19898 -#define STACK_TOP TASK_SIZE
19899 +#define __STACK_TOP TASK_SIZE
19901 #ifdef CONFIG_64BIT
19902 -#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
19903 +#define __STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
19907 diff -urNp linux-2.6.17.7/include/asm-mips/elf.h linux-2.6.17.7/include/asm-mips/elf.h
19908 --- linux-2.6.17.7/include/asm-mips/elf.h 2006-07-24 23:36:01.000000000 -0400
19909 +++ linux-2.6.17.7/include/asm-mips/elf.h 2006-08-01 20:29:47.000000000 -0400
19910 @@ -372,4 +372,15 @@ extern int dump_task_fpu(struct task_str
19911 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
19914 +#ifdef CONFIG_PAX_ASLR
19915 +#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
19917 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
19918 +#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
19919 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
19920 +#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
19921 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
19922 +#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
19925 #endif /* _ASM_ELF_H */
19926 diff -urNp linux-2.6.17.7/include/asm-mips/kmap_types.h linux-2.6.17.7/include/asm-mips/kmap_types.h
19927 --- linux-2.6.17.7/include/asm-mips/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
19928 +++ linux-2.6.17.7/include/asm-mips/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
19929 @@ -23,7 +23,8 @@ D(9) KM_IRQ0,
19934 +D(13) KM_CLEARPAGE,
19939 diff -urNp linux-2.6.17.7/include/asm-mips/page.h linux-2.6.17.7/include/asm-mips/page.h
19940 --- linux-2.6.17.7/include/asm-mips/page.h 2006-07-24 23:36:01.000000000 -0400
19941 +++ linux-2.6.17.7/include/asm-mips/page.h 2006-08-01 20:29:47.000000000 -0400
19942 @@ -151,6 +151,15 @@ typedef struct { unsigned long pgprot; }
19943 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
19944 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
19946 +#ifdef CONFIG_PAX_PAGEEXEC
19947 +#ifdef CONFIG_PAX_MPROTECT
19948 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
19949 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
19951 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
19955 #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
19956 #define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
19958 diff -urNp linux-2.6.17.7/include/asm-parisc/a.out.h linux-2.6.17.7/include/asm-parisc/a.out.h
19959 --- linux-2.6.17.7/include/asm-parisc/a.out.h 2006-07-24 23:36:01.000000000 -0400
19960 +++ linux-2.6.17.7/include/asm-parisc/a.out.h 2006-08-01 20:29:47.000000000 -0400
19961 @@ -22,7 +22,7 @@ struct exec
19962 /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
19965 -#define STACK_TOP TASK_SIZE
19966 +#define __STACK_TOP TASK_SIZE
19970 diff -urNp linux-2.6.17.7/include/asm-parisc/elf.h linux-2.6.17.7/include/asm-parisc/elf.h
19971 --- linux-2.6.17.7/include/asm-parisc/elf.h 2006-07-24 23:36:01.000000000 -0400
19972 +++ linux-2.6.17.7/include/asm-parisc/elf.h 2006-08-01 20:29:47.000000000 -0400
19973 @@ -337,6 +337,17 @@ struct pt_regs; /* forward declaration..
19975 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
19977 +#ifdef CONFIG_PAX_ASLR
19978 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
19980 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
19981 +#define PAX_DELTA_MMAP_LEN(tsk) 16
19982 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
19983 +#define PAX_DELTA_EXEC_LEN(tsk) 16
19984 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
19985 +#define PAX_DELTA_STACK_LEN(tsk) 16
19988 /* This yields a mask that user programs can use to figure out what
19989 instruction set this CPU supports. This could be done in user space,
19990 but it's not easy, and we've already done it here. */
19991 diff -urNp linux-2.6.17.7/include/asm-parisc/kmap_types.h linux-2.6.17.7/include/asm-parisc/kmap_types.h
19992 --- linux-2.6.17.7/include/asm-parisc/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
19993 +++ linux-2.6.17.7/include/asm-parisc/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
19994 @@ -23,7 +23,8 @@ D(9) KM_IRQ0,
19999 +D(13) KM_CLEARPAGE,
20004 diff -urNp linux-2.6.17.7/include/asm-parisc/page.h linux-2.6.17.7/include/asm-parisc/page.h
20005 --- linux-2.6.17.7/include/asm-parisc/page.h 2006-07-24 23:36:01.000000000 -0400
20006 +++ linux-2.6.17.7/include/asm-parisc/page.h 2006-08-01 20:29:47.000000000 -0400
20007 @@ -189,6 +189,15 @@ extern int npmem_ranges;
20008 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
20009 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20011 +#ifdef CONFIG_PAX_PAGEEXEC
20012 +#ifdef CONFIG_PAX_MPROTECT
20013 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20014 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20016 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20020 #endif /* __KERNEL__ */
20022 #include <asm-generic/memory_model.h>
20023 diff -urNp linux-2.6.17.7/include/asm-parisc/pgtable.h linux-2.6.17.7/include/asm-parisc/pgtable.h
20024 --- linux-2.6.17.7/include/asm-parisc/pgtable.h 2006-07-24 23:36:01.000000000 -0400
20025 +++ linux-2.6.17.7/include/asm-parisc/pgtable.h 2006-08-01 20:29:47.000000000 -0400
20026 @@ -220,6 +220,17 @@ extern void *vmalloc_start;
20027 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
20028 #define PAGE_COPY PAGE_EXECREAD
20029 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
20031 +#ifdef CONFIG_PAX_PAGEEXEC
20032 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
20033 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
20034 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
20036 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
20037 +# define PAGE_COPY_NOEXEC PAGE_COPY
20038 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
20041 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
20042 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
20043 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
20044 diff -urNp linux-2.6.17.7/include/asm-powerpc/a.out.h linux-2.6.17.7/include/asm-powerpc/a.out.h
20045 --- linux-2.6.17.7/include/asm-powerpc/a.out.h 2006-07-24 23:36:01.000000000 -0400
20046 +++ linux-2.6.17.7/include/asm-powerpc/a.out.h 2006-08-01 20:29:47.000000000 -0400
20047 @@ -23,12 +23,12 @@ struct exec
20048 #define STACK_TOP_USER64 TASK_SIZE_USER64
20049 #define STACK_TOP_USER32 TASK_SIZE_USER32
20051 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20052 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20053 STACK_TOP_USER32 : STACK_TOP_USER64)
20055 #else /* __powerpc64__ */
20057 -#define STACK_TOP TASK_SIZE
20058 +#define __STACK_TOP TASK_SIZE
20060 #endif /* __powerpc64__ */
20061 #endif /* __KERNEL__ */
20062 diff -urNp linux-2.6.17.7/include/asm-powerpc/elf.h linux-2.6.17.7/include/asm-powerpc/elf.h
20063 --- linux-2.6.17.7/include/asm-powerpc/elf.h 2006-07-24 23:36:01.000000000 -0400
20064 +++ linux-2.6.17.7/include/asm-powerpc/elf.h 2006-08-01 20:29:47.000000000 -0400
20065 @@ -176,6 +176,26 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF
20067 #define ELF_ET_DYN_BASE (0x08000000)
20069 +#ifdef CONFIG_PAX_ASLR
20070 +#define PAX_ELF_ET_DYN_BASE(tsk) (0x10000000UL)
20072 +#ifdef __powerpc64__
20073 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
20074 +#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 16 : 28)
20075 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
20076 +#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 16 : 28)
20077 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
20078 +#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 16 : 28)
20080 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
20081 +#define PAX_DELTA_MMAP_LEN(tsk) 15
20082 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
20083 +#define PAX_DELTA_EXEC_LEN(tsk) 15
20084 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
20085 +#define PAX_DELTA_STACK_LEN(tsk) 15
20091 /* Common routine for both 32-bit and 64-bit processes */
20092 diff -urNp linux-2.6.17.7/include/asm-powerpc/kmap_types.h linux-2.6.17.7/include/asm-powerpc/kmap_types.h
20093 --- linux-2.6.17.7/include/asm-powerpc/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
20094 +++ linux-2.6.17.7/include/asm-powerpc/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
20095 @@ -26,6 +26,7 @@ enum km_type {
20098 KM_PPC_SYNC_ICACHE,
20103 diff -urNp linux-2.6.17.7/include/asm-powerpc/page_64.h linux-2.6.17.7/include/asm-powerpc/page_64.h
20104 --- linux-2.6.17.7/include/asm-powerpc/page_64.h 2006-07-24 23:36:01.000000000 -0400
20105 +++ linux-2.6.17.7/include/asm-powerpc/page_64.h 2006-08-01 20:29:47.000000000 -0400
20106 @@ -170,6 +170,15 @@ extern unsigned int HPAGE_SHIFT;
20107 (test_thread_flag(TIF_32BIT) ? \
20108 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
20110 +#ifdef CONFIG_PAX_PAGEEXEC
20111 +#ifdef CONFIG_PAX_MPROTECT
20112 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20113 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20115 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20119 #include <asm-generic/page.h>
20121 #endif /* __KERNEL__ */
20122 diff -urNp linux-2.6.17.7/include/asm-ppc/page.h linux-2.6.17.7/include/asm-ppc/page.h
20123 --- linux-2.6.17.7/include/asm-ppc/page.h 2006-07-24 23:36:01.000000000 -0400
20124 +++ linux-2.6.17.7/include/asm-ppc/page.h 2006-08-01 20:29:47.000000000 -0400
20125 @@ -175,6 +175,15 @@ extern __inline__ int get_order(unsigned
20126 /* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
20127 #define __HAVE_ARCH_GATE_AREA 1
20129 +#ifdef CONFIG_PAX_PAGEEXEC
20130 +#ifdef CONFIG_PAX_MPROTECT
20131 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20132 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20134 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20138 #include <asm-generic/memory_model.h>
20139 #endif /* __KERNEL__ */
20140 #endif /* _PPC_PAGE_H */
20141 diff -urNp linux-2.6.17.7/include/asm-ppc/pgtable.h linux-2.6.17.7/include/asm-ppc/pgtable.h
20142 --- linux-2.6.17.7/include/asm-ppc/pgtable.h 2006-07-24 23:36:01.000000000 -0400
20143 +++ linux-2.6.17.7/include/asm-ppc/pgtable.h 2006-08-01 20:29:47.000000000 -0400
20144 @@ -441,11 +441,21 @@ extern unsigned long ioremap_bot, iorema
20146 #define PAGE_NONE __pgprot(_PAGE_BASE)
20147 #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
20148 -#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
20149 +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
20150 #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
20151 -#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
20152 +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
20153 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
20154 -#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
20155 +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
20157 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
20158 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
20159 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
20160 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
20162 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
20163 +# define PAGE_COPY_NOEXEC PAGE_COPY
20164 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
20167 #define PAGE_KERNEL __pgprot(_PAGE_RAM)
20168 #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
20169 @@ -457,21 +467,21 @@ extern unsigned long ioremap_bot, iorema
20170 * This is the closest we can get..
20172 #define __P000 PAGE_NONE
20173 -#define __P001 PAGE_READONLY_X
20174 -#define __P010 PAGE_COPY
20175 -#define __P011 PAGE_COPY_X
20176 -#define __P100 PAGE_READONLY
20177 +#define __P001 PAGE_READONLY_NOEXEC
20178 +#define __P010 PAGE_COPY_NOEXEC
20179 +#define __P011 PAGE_COPY_NOEXEC
20180 +#define __P100 PAGE_READONLY_X
20181 #define __P101 PAGE_READONLY_X
20182 -#define __P110 PAGE_COPY
20183 +#define __P110 PAGE_COPY_X
20184 #define __P111 PAGE_COPY_X
20186 #define __S000 PAGE_NONE
20187 -#define __S001 PAGE_READONLY_X
20188 -#define __S010 PAGE_SHARED
20189 -#define __S011 PAGE_SHARED_X
20190 -#define __S100 PAGE_READONLY
20191 +#define __S001 PAGE_READONLY_NOEXEC
20192 +#define __S010 PAGE_SHARED_NOEXEC
20193 +#define __S011 PAGE_SHARED_NOEXEC
20194 +#define __S100 PAGE_READONLY_X
20195 #define __S101 PAGE_READONLY_X
20196 -#define __S110 PAGE_SHARED
20197 +#define __S110 PAGE_SHARED_X
20198 #define __S111 PAGE_SHARED_X
20200 #ifndef __ASSEMBLY__
20201 diff -urNp linux-2.6.17.7/include/asm-s390/kmap_types.h linux-2.6.17.7/include/asm-s390/kmap_types.h
20202 --- linux-2.6.17.7/include/asm-s390/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
20203 +++ linux-2.6.17.7/include/asm-s390/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
20204 @@ -16,6 +16,7 @@ enum km_type {
20212 diff -urNp linux-2.6.17.7/include/asm-sh/kmap_types.h linux-2.6.17.7/include/asm-sh/kmap_types.h
20213 --- linux-2.6.17.7/include/asm-sh/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
20214 +++ linux-2.6.17.7/include/asm-sh/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
20215 @@ -25,7 +25,8 @@ D(9) KM_IRQ0,
20220 +D(13) KM_CLEARPAGE,
20225 diff -urNp linux-2.6.17.7/include/asm-sparc/a.out.h linux-2.6.17.7/include/asm-sparc/a.out.h
20226 --- linux-2.6.17.7/include/asm-sparc/a.out.h 2006-07-24 23:36:01.000000000 -0400
20227 +++ linux-2.6.17.7/include/asm-sparc/a.out.h 2006-08-01 20:29:47.000000000 -0400
20228 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
20230 #include <asm/page.h>
20232 -#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
20233 +#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
20235 #endif /* __KERNEL__ */
20237 diff -urNp linux-2.6.17.7/include/asm-sparc/elf.h linux-2.6.17.7/include/asm-sparc/elf.h
20238 --- linux-2.6.17.7/include/asm-sparc/elf.h 2006-07-24 23:36:01.000000000 -0400
20239 +++ linux-2.6.17.7/include/asm-sparc/elf.h 2006-08-01 20:29:47.000000000 -0400
20240 @@ -145,6 +145,17 @@ typedef struct {
20242 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
20244 +#ifdef CONFIG_PAX_ASLR
20245 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
20247 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
20248 +#define PAX_DELTA_MMAP_LEN(tsk) 16
20249 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
20250 +#define PAX_DELTA_EXEC_LEN(tsk) 16
20251 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
20252 +#define PAX_DELTA_STACK_LEN(tsk) 16
20255 /* This yields a mask that user programs can use to figure out what
20256 instruction set this cpu supports. This can NOT be done in userspace
20258 diff -urNp linux-2.6.17.7/include/asm-sparc/kmap_types.h linux-2.6.17.7/include/asm-sparc/kmap_types.h
20259 --- linux-2.6.17.7/include/asm-sparc/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
20260 +++ linux-2.6.17.7/include/asm-sparc/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
20261 @@ -15,6 +15,7 @@ enum km_type {
20269 diff -urNp linux-2.6.17.7/include/asm-sparc/page.h linux-2.6.17.7/include/asm-sparc/page.h
20270 --- linux-2.6.17.7/include/asm-sparc/page.h 2006-07-24 23:36:01.000000000 -0400
20271 +++ linux-2.6.17.7/include/asm-sparc/page.h 2006-08-01 20:29:47.000000000 -0400
20272 @@ -161,6 +161,15 @@ extern unsigned long pfn_base;
20273 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
20274 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20276 +#ifdef CONFIG_PAX_PAGEEXEC
20277 +#ifdef CONFIG_PAX_MPROTECT
20278 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20279 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20281 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20285 #endif /* __KERNEL__ */
20287 #include <asm-generic/memory_model.h>
20288 diff -urNp linux-2.6.17.7/include/asm-sparc/pgtable.h linux-2.6.17.7/include/asm-sparc/pgtable.h
20289 --- linux-2.6.17.7/include/asm-sparc/pgtable.h 2006-07-24 23:36:01.000000000 -0400
20290 +++ linux-2.6.17.7/include/asm-sparc/pgtable.h 2006-08-01 20:29:47.000000000 -0400
20291 @@ -50,6 +50,13 @@ BTFIXUPDEF_INT(page_none)
20292 BTFIXUPDEF_INT(page_shared)
20293 BTFIXUPDEF_INT(page_copy)
20294 BTFIXUPDEF_INT(page_readonly)
20296 +#ifdef CONFIG_PAX_PAGEEXEC
20297 +BTFIXUPDEF_INT(page_shared_noexec)
20298 +BTFIXUPDEF_INT(page_copy_noexec)
20299 +BTFIXUPDEF_INT(page_readonly_noexec)
20302 BTFIXUPDEF_INT(page_kernel)
20304 #define PMD_SHIFT SUN4C_PMD_SHIFT
20305 @@ -71,6 +78,16 @@ BTFIXUPDEF_INT(page_kernel)
20306 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
20307 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
20309 +#ifdef CONFIG_PAX_PAGEEXEC
20310 +# define PAGE_SHARED_NOEXEC __pgprot(BTFIXUP_INT(page_shared_noexec))
20311 +# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
20312 +# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
20314 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
20315 +# define PAGE_COPY_NOEXEC PAGE_COPY
20316 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
20319 extern unsigned long page_kernel;
20322 diff -urNp linux-2.6.17.7/include/asm-sparc/pgtsrmmu.h linux-2.6.17.7/include/asm-sparc/pgtsrmmu.h
20323 --- linux-2.6.17.7/include/asm-sparc/pgtsrmmu.h 2006-07-24 23:36:01.000000000 -0400
20324 +++ linux-2.6.17.7/include/asm-sparc/pgtsrmmu.h 2006-08-01 20:29:47.000000000 -0400
20325 @@ -115,6 +115,16 @@
20326 SRMMU_EXEC | SRMMU_REF)
20327 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20328 SRMMU_EXEC | SRMMU_REF)
20330 +#ifdef CONFIG_PAX_PAGEEXEC
20331 +#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20332 + SRMMU_WRITE | SRMMU_REF)
20333 +#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20335 +#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20339 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
20340 SRMMU_DIRTY | SRMMU_REF)
20342 diff -urNp linux-2.6.17.7/include/asm-sparc/uaccess.h linux-2.6.17.7/include/asm-sparc/uaccess.h
20343 --- linux-2.6.17.7/include/asm-sparc/uaccess.h 2006-07-24 23:36:01.000000000 -0400
20344 +++ linux-2.6.17.7/include/asm-sparc/uaccess.h 2006-08-01 20:29:47.000000000 -0400
20346 * No one can read/write anything from userland in the kernel space by setting
20347 * large size and address near to PAGE_OFFSET - a fault will break his intentions.
20349 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
20350 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
20351 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
20352 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
20353 #define access_ok(type, addr, size) \
20354 diff -urNp linux-2.6.17.7/include/asm-sparc64/a.out.h linux-2.6.17.7/include/asm-sparc64/a.out.h
20355 --- linux-2.6.17.7/include/asm-sparc64/a.out.h 2006-07-24 23:36:01.000000000 -0400
20356 +++ linux-2.6.17.7/include/asm-sparc64/a.out.h 2006-08-01 20:29:47.000000000 -0400
20357 @@ -98,7 +98,7 @@ struct relocation_info /* used when head
20358 #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
20359 #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL))
20361 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20362 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20363 STACK_TOP32 : STACK_TOP64)
20366 diff -urNp linux-2.6.17.7/include/asm-sparc64/elf.h linux-2.6.17.7/include/asm-sparc64/elf.h
20367 --- linux-2.6.17.7/include/asm-sparc64/elf.h 2006-07-24 23:36:01.000000000 -0400
20368 +++ linux-2.6.17.7/include/asm-sparc64/elf.h 2006-08-01 20:29:47.000000000 -0400
20369 @@ -142,6 +142,16 @@ typedef struct {
20370 #define ELF_ET_DYN_BASE 0x0000010000000000UL
20373 +#ifdef CONFIG_PAX_ASLR
20374 +#define PAX_ELF_ET_DYN_BASE(tsk) (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
20376 +#define PAX_DELTA_MMAP_LSB(tsk) (PAGE_SHIFT + 1)
20377 +#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 14 : 28 )
20378 +#define PAX_DELTA_EXEC_LSB(tsk) (PAGE_SHIFT + 1)
20379 +#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 14 : 28 )
20380 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
20381 +#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 15 : 29 )
20384 /* This yields a mask that user programs can use to figure out what
20385 instruction set this cpu supports. */
20386 diff -urNp linux-2.6.17.7/include/asm-sparc64/kmap_types.h linux-2.6.17.7/include/asm-sparc64/kmap_types.h
20387 --- linux-2.6.17.7/include/asm-sparc64/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
20388 +++ linux-2.6.17.7/include/asm-sparc64/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
20389 @@ -19,6 +19,7 @@ enum km_type {
20397 diff -urNp linux-2.6.17.7/include/asm-sparc64/page.h linux-2.6.17.7/include/asm-sparc64/page.h
20398 --- linux-2.6.17.7/include/asm-sparc64/page.h 2006-07-24 23:36:01.000000000 -0400
20399 +++ linux-2.6.17.7/include/asm-sparc64/page.h 2006-08-01 20:29:47.000000000 -0400
20400 @@ -142,6 +142,15 @@ typedef unsigned long pgprot_t;
20401 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
20402 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20404 +#ifdef CONFIG_PAX_PAGEEXEC
20405 +#ifdef CONFIG_PAX_MPROTECT
20406 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20407 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20409 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20413 #endif /* !(__KERNEL__) */
20415 #include <asm-generic/page.h>
20416 diff -urNp linux-2.6.17.7/include/asm-v850/kmap_types.h linux-2.6.17.7/include/asm-v850/kmap_types.h
20417 --- linux-2.6.17.7/include/asm-v850/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
20418 +++ linux-2.6.17.7/include/asm-v850/kmap_types.h 2006-08-01 20:29:48.000000000 -0400
20419 @@ -13,6 +13,7 @@ enum km_type {
20427 diff -urNp linux-2.6.17.7/include/asm-x86_64/a.out.h linux-2.6.17.7/include/asm-x86_64/a.out.h
20428 --- linux-2.6.17.7/include/asm-x86_64/a.out.h 2006-07-24 23:36:01.000000000 -0400
20429 +++ linux-2.6.17.7/include/asm-x86_64/a.out.h 2006-08-01 20:29:48.000000000 -0400
20430 @@ -21,7 +21,7 @@ struct exec
20433 #include <linux/thread_info.h>
20434 -#define STACK_TOP TASK_SIZE
20435 +#define __STACK_TOP TASK_SIZE
20438 #endif /* __A_OUT_GNU_H__ */
20439 diff -urNp linux-2.6.17.7/include/asm-x86_64/elf.h linux-2.6.17.7/include/asm-x86_64/elf.h
20440 --- linux-2.6.17.7/include/asm-x86_64/elf.h 2006-07-24 23:36:01.000000000 -0400
20441 +++ linux-2.6.17.7/include/asm-x86_64/elf.h 2006-08-01 20:29:48.000000000 -0400
20442 @@ -90,6 +90,17 @@ typedef struct user_i387_struct elf_fpre
20444 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
20446 +#ifdef CONFIG_PAX_ASLR
20447 +#define PAX_ELF_ET_DYN_BASE(tsk) (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
20449 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
20450 +#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 32)
20451 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
20452 +#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 32)
20453 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
20454 +#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 32)
20457 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
20458 now struct_user_regs, they are different). Assumes current is the process
20460 diff -urNp linux-2.6.17.7/include/asm-x86_64/ia32.h linux-2.6.17.7/include/asm-x86_64/ia32.h
20461 --- linux-2.6.17.7/include/asm-x86_64/ia32.h 2006-07-24 23:36:01.000000000 -0400
20462 +++ linux-2.6.17.7/include/asm-x86_64/ia32.h 2006-08-01 20:29:48.000000000 -0400
20463 @@ -157,7 +157,13 @@ struct ustat32 {
20467 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
20468 +#ifdef CONFIG_PAX_RANDUSTACK
20469 +#define IA32_DELTA_STACK (current->mm->delta_stack)
20471 +#define IA32_DELTA_STACK 0UL
20474 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
20478 diff -urNp linux-2.6.17.7/include/asm-x86_64/kmap_types.h linux-2.6.17.7/include/asm-x86_64/kmap_types.h
20479 --- linux-2.6.17.7/include/asm-x86_64/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
20480 +++ linux-2.6.17.7/include/asm-x86_64/kmap_types.h 2006-08-01 20:29:48.000000000 -0400
20481 @@ -13,6 +13,7 @@ enum km_type {
20489 diff -urNp linux-2.6.17.7/include/asm-x86_64/page.h linux-2.6.17.7/include/asm-x86_64/page.h
20490 --- linux-2.6.17.7/include/asm-x86_64/page.h 2006-07-24 23:36:01.000000000 -0400
20491 +++ linux-2.6.17.7/include/asm-x86_64/page.h 2006-08-01 20:29:48.000000000 -0400
20492 @@ -134,6 +134,15 @@ typedef struct { unsigned long pgprot; }
20493 (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
20494 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20496 +#ifdef CONFIG_PAX_PAGEEXEC
20497 +#ifdef CONFIG_PAX_MPROTECT
20498 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20499 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20501 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20505 #define __HAVE_ARCH_GATE_AREA 1
20507 #endif /* __KERNEL__ */
20508 diff -urNp linux-2.6.17.7/include/asm-x86_64/pgalloc.h linux-2.6.17.7/include/asm-x86_64/pgalloc.h
20509 --- linux-2.6.17.7/include/asm-x86_64/pgalloc.h 2006-07-24 23:36:01.000000000 -0400
20510 +++ linux-2.6.17.7/include/asm-x86_64/pgalloc.h 2006-08-01 20:29:48.000000000 -0400
20512 #include <linux/mm.h>
20514 #define pmd_populate_kernel(mm, pmd, pte) \
20515 - set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
20516 + set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
20517 #define pud_populate(mm, pud, pmd) \
20518 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
20519 #define pgd_populate(mm, pgd, pud) \
20520 diff -urNp linux-2.6.17.7/include/asm-x86_64/pgtable.h linux-2.6.17.7/include/asm-x86_64/pgtable.h
20521 --- linux-2.6.17.7/include/asm-x86_64/pgtable.h 2006-07-24 23:36:01.000000000 -0400
20522 +++ linux-2.6.17.7/include/asm-x86_64/pgtable.h 2006-08-01 20:29:48.000000000 -0400
20523 @@ -180,6 +180,10 @@ static inline pte_t ptep_get_and_clear_f
20524 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
20525 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
20526 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
20528 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
20529 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
20531 #define __PAGE_KERNEL \
20532 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
20533 #define __PAGE_KERNEL_EXEC \
20534 @@ -268,7 +272,13 @@ static inline pte_t pfn_pte(unsigned lon
20535 #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
20536 static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
20537 static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
20538 -static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
20539 +extern inline int pte_exec(pte_t pte)
20541 + if (__supported_pte_mask & _PAGE_NX)
20542 + return pte_val(pte) & _PAGE_NX;
20544 + return pte_val(pte) & _PAGE_USER;
20546 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
20547 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
20548 static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
20549 @@ -276,12 +286,26 @@ static inline int pte_file(pte_t pte) {
20550 static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; }
20552 static inline pte_t pte_rdprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
20553 -static inline pte_t pte_exprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
20554 +extern inline pte_t pte_exprotect(pte_t pte)
20556 + if (__supported_pte_mask & _PAGE_NX)
20557 + set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
20559 + set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
20562 static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
20563 static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
20564 static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
20565 static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
20566 -static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
20567 +extern inline pte_t pte_mkexec(pte_t pte)
20569 + if (__supported_pte_mask & _PAGE_NX)
20570 + set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
20572 + set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
20575 static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
20576 static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
20577 static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
20578 diff -urNp linux-2.6.17.7/include/asm-x86_64/system.h linux-2.6.17.7/include/asm-x86_64/system.h
20579 --- linux-2.6.17.7/include/asm-x86_64/system.h 2006-07-24 23:36:01.000000000 -0400
20580 +++ linux-2.6.17.7/include/asm-x86_64/system.h 2006-08-01 20:29:48.000000000 -0400
20581 @@ -366,6 +366,6 @@ static inline unsigned long __cmpxchg(vo
20583 void cpu_idle_wait(void);
20585 -extern unsigned long arch_align_stack(unsigned long sp);
20586 +#define arch_align_stack(x) (x)
20589 diff -urNp linux-2.6.17.7/include/asm-xtensa/kmap_types.h linux-2.6.17.7/include/asm-xtensa/kmap_types.h
20590 --- linux-2.6.17.7/include/asm-xtensa/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
20591 +++ linux-2.6.17.7/include/asm-xtensa/kmap_types.h 2006-08-01 20:29:48.000000000 -0400
20592 @@ -25,6 +25,7 @@ enum km_type {
20600 diff -urNp linux-2.6.17.7/include/linux/a.out.h linux-2.6.17.7/include/linux/a.out.h
20601 --- linux-2.6.17.7/include/linux/a.out.h 2006-07-24 23:36:01.000000000 -0400
20602 +++ linux-2.6.17.7/include/linux/a.out.h 2006-08-01 20:29:48.000000000 -0400
20605 #include <asm/a.out.h>
20607 +#ifdef CONFIG_PAX_RANDUSTACK
20608 +#define __DELTA_STACK (current->mm->delta_stack)
20610 +#define __DELTA_STACK 0UL
20614 +#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
20617 #endif /* __STRUCT_EXEC_OVERRIDE__ */
20619 /* these go in the N_MACHTYPE field */
20620 @@ -37,6 +47,14 @@ enum machine_type {
20621 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
20624 +/* Constants for the N_FLAGS field */
20625 +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
20626 +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
20627 +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
20628 +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
20629 +/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
20630 +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
20632 #if !defined (N_MAGIC)
20633 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
20635 diff -urNp linux-2.6.17.7/include/linux/binfmts.h linux-2.6.17.7/include/linux/binfmts.h
20636 --- linux-2.6.17.7/include/linux/binfmts.h 2006-07-24 23:36:01.000000000 -0400
20637 +++ linux-2.6.17.7/include/linux/binfmts.h 2006-08-01 20:29:48.000000000 -0400
20638 @@ -7,10 +7,10 @@ struct pt_regs;
20641 * MAX_ARG_PAGES defines the number of pages allocated for arguments
20642 - * and envelope for the new program. 32 should suffice, this gives
20643 - * a maximum env+arg of 128kB w/4KB pages!
20644 + * and envelope for the new program. 33 should suffice, this gives
20645 + * a maximum env+arg of 132kB w/4KB pages!
20647 -#define MAX_ARG_PAGES 32
20648 +#define MAX_ARG_PAGES 33
20650 /* sizeof(linux_binprm->buf) */
20651 #define BINPRM_BUF_SIZE 128
20652 @@ -38,6 +38,7 @@ struct linux_binprm{
20653 unsigned interp_flags;
20654 unsigned interp_data;
20655 unsigned long loader, exec;
20659 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
20660 @@ -87,5 +88,8 @@ extern void compute_creds(struct linux_b
20661 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
20662 extern int set_binfmt(struct linux_binfmt *new);
20664 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
20665 +void pax_report_insns(void *pc, void *sp);
20667 #endif /* __KERNEL__ */
20668 #endif /* _LINUX_BINFMTS_H */
20669 diff -urNp linux-2.6.17.7/include/linux/capability.h linux-2.6.17.7/include/linux/capability.h
20670 --- linux-2.6.17.7/include/linux/capability.h 2006-07-24 23:36:01.000000000 -0400
20671 +++ linux-2.6.17.7/include/linux/capability.h 2006-08-01 20:29:48.000000000 -0400
20672 @@ -358,6 +358,7 @@ static inline kernel_cap_t cap_invert(ke
20673 #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK)
20675 int capable(int cap);
20676 +int capable_nolog(int cap);
20677 int __capable(struct task_struct *t, int cap);
20679 #endif /* __KERNEL__ */
20680 diff -urNp linux-2.6.17.7/include/linux/elf.h linux-2.6.17.7/include/linux/elf.h
20681 --- linux-2.6.17.7/include/linux/elf.h 2006-07-24 23:36:01.000000000 -0400
20682 +++ linux-2.6.17.7/include/linux/elf.h 2006-08-01 20:29:48.000000000 -0400
20684 #include <linux/auxvec.h>
20685 #include <asm/elf.h>
20687 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20688 +#undef elf_read_implies_exec
20691 #ifndef elf_read_implies_exec
20692 /* Executables for which elf_read_implies_exec() returns TRUE will
20693 have the READ_IMPLIES_EXEC personality flag set automatically.
20694 @@ -46,6 +50,16 @@ typedef __s64 Elf64_Sxword;
20696 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
20698 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
20700 +/* Constants for the e_flags field */
20701 +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
20702 +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
20703 +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
20704 +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
20705 +/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
20706 +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
20708 /* These constants define the different elf file types */
20711 @@ -138,6 +152,8 @@ typedef __s64 Elf64_Sxword;
20712 #define DT_DEBUG 21
20713 #define DT_TEXTREL 22
20714 #define DT_JMPREL 23
20715 +#define DT_FLAGS 30
20716 + #define DF_TEXTREL 0x00000004
20717 #define DT_LOPROC 0x70000000
20718 #define DT_HIPROC 0x7fffffff
20720 @@ -267,6 +283,19 @@ typedef struct elf64_hdr {
20724 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
20725 +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
20726 +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
20727 +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
20728 +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
20729 +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
20730 +/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
20731 +/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
20732 +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
20733 +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
20734 +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
20735 +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
20737 typedef struct elf32_phdr{
20739 Elf32_Off p_offset;
20740 @@ -359,6 +388,8 @@ typedef struct elf64_shdr {
20746 #define ELFMAG0 0x7f /* EI_MAG */
20747 #define ELFMAG1 'E'
20748 #define ELFMAG2 'L'
20749 @@ -415,6 +446,7 @@ extern Elf32_Dyn _DYNAMIC [];
20750 #define elfhdr elf32_hdr
20751 #define elf_phdr elf32_phdr
20752 #define elf_note elf32_note
20753 +#define elf_dyn Elf32_Dyn
20757 @@ -422,6 +454,7 @@ extern Elf64_Dyn _DYNAMIC [];
20758 #define elfhdr elf64_hdr
20759 #define elf_phdr elf64_phdr
20760 #define elf_note elf64_note
20761 +#define elf_dyn Elf64_Dyn
20765 diff -urNp linux-2.6.17.7/include/linux/gracl.h linux-2.6.17.7/include/linux/gracl.h
20766 --- linux-2.6.17.7/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
20767 +++ linux-2.6.17.7/include/linux/gracl.h 2006-08-01 20:29:48.000000000 -0400
20772 +#include <linux/grdefs.h>
20773 +#include <linux/resource.h>
20774 +#include <linux/dcache.h>
20775 +#include <asm/resource.h>
20777 +/* Major status information */
20779 +#define GR_VERSION "grsecurity 2.1.9"
20780 +#define GRSECURITY_VERSION 0x219
20795 +/* Password setup definitions
20796 + * kernel/grhash.c */
20799 + GR_SALT_LEN = 16,
20804 + GR_SPROLE_LEN = 64,
20807 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
20809 +/* Begin Data Structures */
20811 +struct sprole_pw {
20812 + unsigned char *rolename;
20813 + unsigned char salt[GR_SALT_LEN];
20814 + unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
20817 +struct name_entry {
20823 + struct name_entry *prev;
20824 + struct name_entry *next;
20827 +struct inodev_entry {
20828 + struct name_entry *nentry;
20829 + struct inodev_entry *prev;
20830 + struct inodev_entry *next;
20833 +struct acl_role_db {
20834 + struct acl_role_label **r_hash;
20838 +struct inodev_db {
20839 + struct inodev_entry **i_hash;
20844 + struct name_entry **n_hash;
20848 +struct crash_uid {
20850 + unsigned long expires;
20853 +struct gr_hash_struct {
20855 + void **nametable;
20857 + __u32 table_size;
20862 +/* Userspace Grsecurity ACL data structures */
20864 +struct acl_subject_label {
20872 + struct rlimit res[GR_NLIMITS];
20875 + __u8 user_trans_type;
20876 + __u8 group_trans_type;
20877 + uid_t *user_transitions;
20878 + gid_t *group_transitions;
20879 + __u16 user_trans_num;
20880 + __u16 group_trans_num;
20882 + __u32 ip_proto[8];
20884 + struct acl_ip_label **ips;
20888 + unsigned long expires;
20890 + struct acl_subject_label *parent_subject;
20891 + struct gr_hash_struct *hash;
20892 + struct acl_subject_label *prev;
20893 + struct acl_subject_label *next;
20895 + struct acl_object_label **obj_hash;
20896 + __u32 obj_hash_size;
20900 +struct role_allowed_ip {
20904 + struct role_allowed_ip *prev;
20905 + struct role_allowed_ip *next;
20908 +struct role_transition {
20911 + struct role_transition *prev;
20912 + struct role_transition *next;
20915 +struct acl_role_label {
20920 + __u16 auth_attempts;
20921 + unsigned long expires;
20923 + struct acl_subject_label *root_label;
20924 + struct gr_hash_struct *hash;
20926 + struct acl_role_label *prev;
20927 + struct acl_role_label *next;
20929 + struct role_transition *transitions;
20930 + struct role_allowed_ip *allowed_ips;
20931 + uid_t *domain_children;
20932 + __u16 domain_child_num;
20934 + struct acl_subject_label **subj_hash;
20935 + __u32 subj_hash_size;
20938 +struct user_acl_role_db {
20939 + struct acl_role_label **r_table;
20940 + __u32 num_pointers; /* Number of allocations to track */
20941 + __u32 num_roles; /* Number of roles */
20942 + __u32 num_domain_children; /* Number of domain children */
20943 + __u32 num_subjects; /* Number of subjects */
20944 + __u32 num_objects; /* Number of objects */
20947 +struct acl_object_label {
20953 + struct acl_subject_label *nested;
20954 + struct acl_object_label *globbed;
20956 + /* next two structures not used */
20958 + struct acl_object_label *prev;
20959 + struct acl_object_label *next;
20962 +struct acl_ip_label {
20971 + /* next two structures not used */
20973 + struct acl_ip_label *prev;
20974 + struct acl_ip_label *next;
20978 + struct user_acl_role_db role_db;
20979 + unsigned char pw[GR_PW_LEN];
20980 + unsigned char salt[GR_SALT_LEN];
20981 + unsigned char sum[GR_SHA_LEN];
20982 + unsigned char sp_role[GR_SPROLE_LEN];
20983 + struct sprole_pw *sprole_pws;
20984 + dev_t segv_device;
20985 + ino_t segv_inode;
20987 + __u16 num_sprole_pws;
20991 +struct gr_arg_wrapper {
20992 + struct gr_arg *arg;
20997 +struct subject_map {
20998 + struct acl_subject_label *user;
20999 + struct acl_subject_label *kernel;
21000 + struct subject_map *prev;
21001 + struct subject_map *next;
21004 +struct acl_subj_map_db {
21005 + struct subject_map **s_hash;
21009 +/* End Data Structures Section */
21011 +/* Hash functions generated by empirical testing by Brad Spengler
21012 + Makes good use of the low bits of the inode. Generally 0-1 times
21013 + in loop for successful match. 0-3 for unsuccessful match.
21014 + Shift/add algorithm with modulus of table size and an XOR*/
21016 +static __inline__ unsigned int
21017 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
21019 + return (((uid << type) + (uid ^ type)) % sz);
21022 + static __inline__ unsigned int
21023 +shash(const struct acl_subject_label *userp, const unsigned int sz)
21025 + return ((const unsigned long)userp % sz);
21028 +static __inline__ unsigned int
21029 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
21031 + return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
21034 +static __inline__ unsigned int
21035 +nhash(const char *name, const __u16 len, const unsigned int sz)
21037 + return full_name_hash(name, len) % sz;
21040 +#define FOR_EACH_ROLE_START(role,iter) \
21043 + while (iter < acl_role_set.r_size) { \
21044 + if (role == NULL) \
21045 + role = acl_role_set.r_hash[iter]; \
21046 + if (role == NULL) { \
21051 +#define FOR_EACH_ROLE_END(role,iter) \
21052 + role = role->next; \
21053 + if (role == NULL) \
21057 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
21060 + while (iter < role->subj_hash_size) { \
21061 + if (subj == NULL) \
21062 + subj = role->subj_hash[iter]; \
21063 + if (subj == NULL) { \
21068 +#define FOR_EACH_SUBJECT_END(subj,iter) \
21069 + subj = subj->next; \
21070 + if (subj == NULL) \
21075 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
21076 + subj = role->hash->first; \
21077 + while (subj != NULL) {
21079 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
21080 + subj = subj->next; \
21085 diff -urNp linux-2.6.17.7/include/linux/gralloc.h linux-2.6.17.7/include/linux/gralloc.h
21086 --- linux-2.6.17.7/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
21087 +++ linux-2.6.17.7/include/linux/gralloc.h 2006-08-01 20:29:48.000000000 -0400
21089 +#ifndef __GRALLOC_H
21090 +#define __GRALLOC_H
21092 +void acl_free_all(void);
21093 +int acl_alloc_stack_init(unsigned long size);
21094 +void *acl_alloc(unsigned long len);
21097 diff -urNp linux-2.6.17.7/include/linux/grdefs.h linux-2.6.17.7/include/linux/grdefs.h
21098 --- linux-2.6.17.7/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
21099 +++ linux-2.6.17.7/include/linux/grdefs.h 2006-08-01 20:29:48.000000000 -0400
21104 +/* Begin grsecurity status declarations */
21108 + GR_STATUS_INIT = 0x00 // disabled state
21111 +/* Begin ACL declarations */
21116 + GR_ROLE_USER = 0x0001,
21117 + GR_ROLE_GROUP = 0x0002,
21118 + GR_ROLE_DEFAULT = 0x0004,
21119 + GR_ROLE_SPECIAL = 0x0008,
21120 + GR_ROLE_AUTH = 0x0010,
21121 + GR_ROLE_NOPW = 0x0020,
21122 + GR_ROLE_GOD = 0x0040,
21123 + GR_ROLE_LEARN = 0x0080,
21124 + GR_ROLE_TPE = 0x0100,
21125 + GR_ROLE_DOMAIN = 0x0200,
21126 + GR_ROLE_PAM = 0x0400
21129 +/* ACL Subject and Object mode flags */
21131 + GR_DELETED = 0x80000000
21134 +/* ACL Object-only mode flags */
21136 + GR_READ = 0x00000001,
21137 + GR_APPEND = 0x00000002,
21138 + GR_WRITE = 0x00000004,
21139 + GR_EXEC = 0x00000008,
21140 + GR_FIND = 0x00000010,
21141 + GR_INHERIT = 0x00000020,
21142 + GR_SETID = 0x00000040,
21143 + GR_CREATE = 0x00000080,
21144 + GR_DELETE = 0x00000100,
21145 + GR_LINK = 0x00000200,
21146 + GR_AUDIT_READ = 0x00000400,
21147 + GR_AUDIT_APPEND = 0x00000800,
21148 + GR_AUDIT_WRITE = 0x00001000,
21149 + GR_AUDIT_EXEC = 0x00002000,
21150 + GR_AUDIT_FIND = 0x00004000,
21151 + GR_AUDIT_INHERIT= 0x00008000,
21152 + GR_AUDIT_SETID = 0x00010000,
21153 + GR_AUDIT_CREATE = 0x00020000,
21154 + GR_AUDIT_DELETE = 0x00040000,
21155 + GR_AUDIT_LINK = 0x00080000,
21156 + GR_PTRACERD = 0x00100000,
21157 + GR_NOPTRACE = 0x00200000,
21158 + GR_SUPPRESS = 0x00400000,
21159 + GR_NOLEARN = 0x00800000
21162 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
21163 + GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
21164 + GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
21166 +/* ACL subject-only mode flags */
21168 + GR_KILL = 0x00000001,
21169 + GR_VIEW = 0x00000002,
21170 + GR_PROTECTED = 0x00000004,
21171 + GR_LEARN = 0x00000008,
21172 + GR_OVERRIDE = 0x00000010,
21173 + /* just a placeholder, this mode is only used in userspace */
21174 + GR_DUMMY = 0x00000020,
21175 + GR_PROTSHM = 0x00000040,
21176 + GR_KILLPROC = 0x00000080,
21177 + GR_KILLIPPROC = 0x00000100,
21178 + /* just a placeholder, this mode is only used in userspace */
21179 + GR_NOTROJAN = 0x00000200,
21180 + GR_PROTPROCFD = 0x00000400,
21181 + GR_PROCACCT = 0x00000800,
21182 + GR_RELAXPTRACE = 0x00001000,
21183 + GR_NESTED = 0x00002000,
21184 + GR_INHERITLEARN = 0x00004000,
21185 + GR_PROCFIND = 0x00008000,
21186 + GR_POVERRIDE = 0x00010000,
21187 + GR_KERNELAUTH = 0x00020000,
21191 + GR_PAX_ENABLE_SEGMEXEC = 0x0001,
21192 + GR_PAX_ENABLE_PAGEEXEC = 0x0002,
21193 + GR_PAX_ENABLE_MPROTECT = 0x0004,
21194 + GR_PAX_ENABLE_RANDMMAP = 0x0008,
21195 + GR_PAX_ENABLE_EMUTRAMP = 0x0010,
21196 + GR_PAX_DISABLE_SEGMEXEC = 0x8001,
21197 + GR_PAX_DISABLE_PAGEEXEC = 0x8002,
21198 + GR_PAX_DISABLE_MPROTECT = 0x8004,
21199 + GR_PAX_DISABLE_RANDMMAP = 0x8008,
21200 + GR_PAX_DISABLE_EMUTRAMP = 0x8010,
21204 + GR_ID_USER = 0x01,
21205 + GR_ID_GROUP = 0x02,
21209 + GR_ID_ALLOW = 0x01,
21210 + GR_ID_DENY = 0x02,
21213 +#define GR_CRASH_RES 11
21214 +#define GR_UIDTABLE_MAX 500
21216 +/* begin resource learning section */
21218 + GR_RLIM_CPU_BUMP = 60,
21219 + GR_RLIM_FSIZE_BUMP = 50000,
21220 + GR_RLIM_DATA_BUMP = 10000,
21221 + GR_RLIM_STACK_BUMP = 1000,
21222 + GR_RLIM_CORE_BUMP = 10000,
21223 + GR_RLIM_RSS_BUMP = 500000,
21224 + GR_RLIM_NPROC_BUMP = 1,
21225 + GR_RLIM_NOFILE_BUMP = 5,
21226 + GR_RLIM_MEMLOCK_BUMP = 50000,
21227 + GR_RLIM_AS_BUMP = 500000,
21228 + GR_RLIM_LOCKS_BUMP = 2
21232 diff -urNp linux-2.6.17.7/include/linux/grinternal.h linux-2.6.17.7/include/linux/grinternal.h
21233 --- linux-2.6.17.7/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
21234 +++ linux-2.6.17.7/include/linux/grinternal.h 2006-08-01 20:29:48.000000000 -0400
21236 +#ifndef __GRINTERNAL_H
21237 +#define __GRINTERNAL_H
21239 +#ifdef CONFIG_GRKERNSEC
21241 +#include <linux/fs.h>
21242 +#include <linux/gracl.h>
21243 +#include <linux/grdefs.h>
21244 +#include <linux/grmsg.h>
21246 +extern void gr_add_learn_entry(const char *fmt, ...);
21247 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
21248 + const struct vfsmount *mnt);
21249 +extern __u32 gr_check_create(const struct dentry *new_dentry,
21250 + const struct dentry *parent,
21251 + const struct vfsmount *mnt, const __u32 mode);
21252 +extern int gr_check_protected_task(const struct task_struct *task);
21253 +extern __u32 to_gr_audit(const __u32 reqmode);
21254 +extern int gr_set_acls(const int type);
21256 +extern int gr_acl_is_enabled(void);
21257 +extern char gr_roletype_to_char(void);
21259 +extern void gr_handle_alertkill(struct task_struct *task);
21260 +extern char *gr_to_filename(const struct dentry *dentry,
21261 + const struct vfsmount *mnt);
21262 +extern char *gr_to_filename1(const struct dentry *dentry,
21263 + const struct vfsmount *mnt);
21264 +extern char *gr_to_filename2(const struct dentry *dentry,
21265 + const struct vfsmount *mnt);
21266 +extern char *gr_to_filename3(const struct dentry *dentry,
21267 + const struct vfsmount *mnt);
21269 +extern int grsec_enable_link;
21270 +extern int grsec_enable_fifo;
21271 +extern int grsec_enable_execve;
21272 +extern int grsec_enable_shm;
21273 +extern int grsec_enable_execlog;
21274 +extern int grsec_enable_signal;
21275 +extern int grsec_enable_forkfail;
21276 +extern int grsec_enable_time;
21277 +extern int grsec_enable_chroot_shmat;
21278 +extern int grsec_enable_chroot_findtask;
21279 +extern int grsec_enable_chroot_mount;
21280 +extern int grsec_enable_chroot_double;
21281 +extern int grsec_enable_chroot_pivot;
21282 +extern int grsec_enable_chroot_chdir;
21283 +extern int grsec_enable_chroot_chmod;
21284 +extern int grsec_enable_chroot_mknod;
21285 +extern int grsec_enable_chroot_fchdir;
21286 +extern int grsec_enable_chroot_nice;
21287 +extern int grsec_enable_chroot_execlog;
21288 +extern int grsec_enable_chroot_caps;
21289 +extern int grsec_enable_chroot_sysctl;
21290 +extern int grsec_enable_chroot_unix;
21291 +extern int grsec_enable_tpe;
21292 +extern int grsec_tpe_gid;
21293 +extern int grsec_enable_tpe_all;
21294 +extern int grsec_enable_sidcaps;
21295 +extern int grsec_enable_randpid;
21296 +extern int grsec_enable_socket_all;
21297 +extern int grsec_socket_all_gid;
21298 +extern int grsec_enable_socket_client;
21299 +extern int grsec_socket_client_gid;
21300 +extern int grsec_enable_socket_server;
21301 +extern int grsec_socket_server_gid;
21302 +extern int grsec_audit_gid;
21303 +extern int grsec_enable_group;
21304 +extern int grsec_enable_audit_ipc;
21305 +extern int grsec_enable_audit_textrel;
21306 +extern int grsec_enable_mount;
21307 +extern int grsec_enable_chdir;
21308 +extern int grsec_resource_logging;
21309 +extern int grsec_lock;
21311 +extern struct task_struct *child_reaper;
21313 +extern spinlock_t grsec_alert_lock;
21314 +extern unsigned long grsec_alert_wtime;
21315 +extern unsigned long grsec_alert_fyet;
21317 +extern spinlock_t grsec_audit_lock;
21319 +extern rwlock_t grsec_exec_file_lock;
21321 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
21322 + gr_to_filename2(tsk->exec_file->f_dentry, \
21323 + tsk->exec_file->f_vfsmnt) : "/")
21325 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
21326 + gr_to_filename3(tsk->parent->exec_file->f_dentry, \
21327 + tsk->parent->exec_file->f_vfsmnt) : "/")
21329 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
21330 + gr_to_filename(tsk->exec_file->f_dentry, \
21331 + tsk->exec_file->f_vfsmnt) : "/")
21333 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
21334 + gr_to_filename1(tsk->parent->exec_file->f_dentry, \
21335 + tsk->parent->exec_file->f_vfsmnt) : "/")
21337 +#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
21338 + ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
21339 + child_reaper->fs->root->d_inode->i_sb->s_dev) || \
21340 + (tsk_a->fs->root->d_inode->i_ino != \
21341 + child_reaper->fs->root->d_inode->i_ino)))
21343 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
21344 + (tsk_a->fs->root->d_inode->i_sb->s_dev == \
21345 + tsk_b->fs->root->d_inode->i_sb->s_dev) && \
21346 + (tsk_a->fs->root->d_inode->i_ino == \
21347 + tsk_b->fs->root->d_inode->i_ino))
21349 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
21350 + task->pid, task->uid, \
21351 + task->euid, task->gid, task->egid, \
21352 + gr_parent_task_fullpath(task), \
21353 + task->parent->comm, task->parent->pid, \
21354 + task->parent->uid, task->parent->euid, \
21355 + task->parent->gid, task->parent->egid
21357 +#define GR_CHROOT_CAPS ( \
21358 + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
21359 + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
21360 + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
21361 + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
21362 + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
21363 + CAP_TO_MASK(CAP_IPC_OWNER))
21365 +#define security_learn(normal_msg,args...) \
21367 + read_lock(&grsec_exec_file_lock); \
21368 + gr_add_learn_entry(normal_msg "\n", ## args); \
21369 + read_unlock(&grsec_exec_file_lock); \
21375 + GR_DONT_AUDIT_GOOD
21388 + GR_ONE_INT_TWO_STR,
21393 + GR_FIVE_INT_TWO_STR,
21399 + GR_FILENAME_TWO_INT,
21400 + GR_FILENAME_TWO_INT_STR,
21411 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
21412 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
21413 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
21414 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
21415 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
21416 +#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)
21417 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
21418 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
21419 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
21420 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
21421 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
21422 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
21423 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
21424 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
21425 +#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)
21426 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
21427 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
21428 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
21429 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
21430 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
21431 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
21432 +#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)
21433 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
21434 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
21435 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
21436 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
21437 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
21438 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
21439 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
21440 +#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)
21442 +extern void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
21447 diff -urNp linux-2.6.17.7/include/linux/grmsg.h linux-2.6.17.7/include/linux/grmsg.h
21448 --- linux-2.6.17.7/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
21449 +++ linux-2.6.17.7/include/linux/grmsg.h 2006-08-01 20:29:48.000000000 -0400
21451 +#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"
21452 +#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"
21453 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
21454 +#define GR_STOPMOD_MSG "denied modification of module state by "
21455 +#define GR_IOPERM_MSG "denied use of ioperm() by "
21456 +#define GR_IOPL_MSG "denied use of iopl() by "
21457 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
21458 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
21459 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
21460 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
21461 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
21462 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
21463 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
21464 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
21465 +#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"
21466 +#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"
21467 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
21468 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
21469 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
21470 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
21471 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
21472 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
21473 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
21474 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
21475 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
21476 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
21477 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
21478 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
21479 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
21480 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
21481 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
21482 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
21483 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
21484 +#define GR_NPROC_MSG "denied overstep of process limit by "
21485 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
21486 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
21487 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
21488 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
21489 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
21490 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
21491 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
21492 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
21493 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
21494 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
21495 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
21496 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
21497 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
21498 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
21499 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
21500 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
21501 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
21502 +#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"
21503 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
21504 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
21505 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
21506 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
21507 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
21508 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
21509 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
21510 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
21511 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
21512 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
21513 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
21514 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
21515 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
21516 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
21517 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
21518 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
21519 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
21520 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
21521 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
21522 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
21523 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
21524 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
21525 +#define GR_NICE_CHROOT_MSG "denied priority change by "
21526 +#define GR_UNISIGLOG_MSG "signal %d sent to "
21527 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
21528 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
21529 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
21530 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
21531 +#define GR_TIME_MSG "time set by "
21532 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
21533 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
21534 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
21535 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
21536 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
21537 +#define GR_BIND_MSG "denied bind() by "
21538 +#define GR_CONNECT_MSG "denied connect() by "
21539 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
21540 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
21541 +#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"
21542 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
21543 +#define GR_CAP_ACL_MSG "use of %s denied for "
21544 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
21545 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
21546 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
21547 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
21548 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
21549 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
21550 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
21551 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
21552 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
21553 +#define GR_SEM_AUDIT_MSG "semaphore created by "
21554 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
21555 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
21556 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
21557 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
21558 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
21559 diff -urNp linux-2.6.17.7/include/linux/grsecurity.h linux-2.6.17.7/include/linux/grsecurity.h
21560 --- linux-2.6.17.7/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
21561 +++ linux-2.6.17.7/include/linux/grsecurity.h 2006-08-01 20:29:48.000000000 -0400
21563 +#ifndef GR_SECURITY_H
21564 +#define GR_SECURITY_H
21565 +#include <linux/fs.h>
21566 +#include <linux/binfmts.h>
21567 +#include <linux/gracl.h>
21569 +extern void gr_handle_brute_attach(struct task_struct *p);
21570 +extern void gr_handle_brute_check(void);
21572 +extern char gr_roletype_to_char(void);
21574 +extern int gr_check_user_change(int real, int effective, int fs);
21575 +extern int gr_check_group_change(int real, int effective, int fs);
21577 +extern void gr_del_task_from_ip_table(struct task_struct *p);
21579 +extern int gr_pid_is_chrooted(struct task_struct *p);
21580 +extern int gr_handle_chroot_nice(void);
21581 +extern int gr_handle_chroot_sysctl(const int op);
21582 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
21583 + const int niceval);
21584 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
21585 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
21586 + const struct vfsmount *mnt);
21587 +extern void gr_handle_chroot_caps(struct task_struct *task);
21588 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
21589 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
21590 + const struct vfsmount *mnt, const int mode);
21591 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
21592 + const struct vfsmount *mnt, const int mode);
21593 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
21594 + const struct vfsmount *mnt,
21595 + const char *dev_name);
21596 +extern int gr_handle_chroot_pivot(void);
21597 +extern int gr_handle_chroot_unix(const pid_t pid);
21599 +extern int gr_handle_rawio(const struct inode *inode);
21600 +extern int gr_handle_nproc(void);
21602 +extern void gr_handle_ioperm(void);
21603 +extern void gr_handle_iopl(void);
21605 +extern int gr_tpe_allow(const struct file *file);
21607 +extern int gr_random_pid(void);
21609 +extern void gr_log_forkfail(const int retval);
21610 +extern void gr_log_timechange(void);
21611 +extern void gr_log_signal(const int sig, const struct task_struct *t);
21612 +extern void gr_log_chdir(const struct dentry *dentry,
21613 + const struct vfsmount *mnt);
21614 +extern void gr_log_chroot_exec(const struct dentry *dentry,
21615 + const struct vfsmount *mnt);
21616 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
21617 +extern void gr_log_remount(const char *devname, const int retval);
21618 +extern void gr_log_unmount(const char *devname, const int retval);
21619 +extern void gr_log_mount(const char *from, const char *to, const int retval);
21620 +extern void gr_log_msgget(const int ret, const int msgflg);
21621 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
21622 +extern void gr_log_semget(const int err, const int semflg);
21623 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
21624 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
21625 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
21626 +extern void gr_log_textrel(struct vm_area_struct *vma);
21628 +extern int gr_handle_follow_link(const struct inode *parent,
21629 + const struct inode *inode,
21630 + const struct dentry *dentry,
21631 + const struct vfsmount *mnt);
21632 +extern int gr_handle_fifo(const struct dentry *dentry,
21633 + const struct vfsmount *mnt,
21634 + const struct dentry *dir, const int flag,
21635 + const int acc_mode);
21636 +extern int gr_handle_hardlink(const struct dentry *dentry,
21637 + const struct vfsmount *mnt,
21638 + struct inode *inode,
21639 + const int mode, const char *to);
21641 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
21642 +extern int gr_is_capable_nolog(const int cap);
21643 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
21644 + const unsigned long wanted, const int gt);
21645 +extern void gr_copy_label(struct task_struct *tsk);
21646 +extern void gr_handle_crash(struct task_struct *task, const int sig);
21647 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
21648 +extern int gr_check_crash_uid(const uid_t uid);
21649 +extern int gr_check_protected_task(const struct task_struct *task);
21650 +extern int gr_acl_handle_mmap(const struct file *file,
21651 + const unsigned long prot);
21652 +extern int gr_acl_handle_mprotect(const struct file *file,
21653 + const unsigned long prot);
21654 +extern int gr_check_hidden_task(const struct task_struct *tsk);
21655 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
21656 + const struct vfsmount *mnt);
21657 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
21658 + const struct vfsmount *mnt);
21659 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
21660 + const struct vfsmount *mnt, const int fmode);
21661 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
21662 + const struct vfsmount *mnt, mode_t mode);
21663 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
21664 + const struct vfsmount *mnt, mode_t mode);
21665 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
21666 + const struct vfsmount *mnt);
21667 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
21668 +extern int gr_handle_proc_ptrace(struct task_struct *task);
21669 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
21670 + const struct vfsmount *mnt);
21671 +extern int gr_check_crash_exec(const struct file *filp);
21672 +extern int gr_acl_is_enabled(void);
21673 +extern void gr_set_kernel_label(struct task_struct *task);
21674 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
21675 + const gid_t gid);
21676 +extern int gr_set_proc_label(const struct dentry *dentry,
21677 + const struct vfsmount *mnt);
21678 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
21679 + const struct vfsmount *mnt);
21680 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
21681 + const struct vfsmount *mnt, const int fmode);
21682 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
21683 + const struct dentry *p_dentry,
21684 + const struct vfsmount *p_mnt, const int fmode,
21685 + const int imode);
21686 +extern void gr_handle_create(const struct dentry *dentry,
21687 + const struct vfsmount *mnt);
21688 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
21689 + const struct dentry *parent_dentry,
21690 + const struct vfsmount *parent_mnt,
21692 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
21693 + const struct dentry *parent_dentry,
21694 + const struct vfsmount *parent_mnt);
21695 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
21696 + const struct vfsmount *mnt);
21697 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
21698 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
21699 + const struct vfsmount *mnt);
21700 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
21701 + const struct dentry *parent_dentry,
21702 + const struct vfsmount *parent_mnt,
21703 + const char *from);
21704 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
21705 + const struct dentry *parent_dentry,
21706 + const struct vfsmount *parent_mnt,
21707 + const struct dentry *old_dentry,
21708 + const struct vfsmount *old_mnt, const char *to);
21709 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
21710 + struct dentry *parent_dentry,
21711 + const struct vfsmount *parent_mnt,
21712 + struct dentry *old_dentry,
21713 + struct inode *old_parent_inode,
21714 + struct vfsmount *old_mnt, const char *newname);
21715 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
21716 + struct dentry *old_dentry,
21717 + struct dentry *new_dentry,
21718 + struct vfsmount *mnt, const __u8 replace);
21719 +extern __u32 gr_check_link(const struct dentry *new_dentry,
21720 + const struct dentry *parent_dentry,
21721 + const struct vfsmount *parent_mnt,
21722 + const struct dentry *old_dentry,
21723 + const struct vfsmount *old_mnt);
21724 +extern int gr_acl_handle_filldir(const struct file *file, const char *name,
21725 + const unsigned int namelen, const ino_t ino);
21727 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
21728 + const struct vfsmount *mnt);
21729 +extern void gr_acl_handle_exit(void);
21730 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
21731 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
21732 +extern __u32 gr_cap_rtnetlink(void);
21734 +#ifdef CONFIG_SYSVIPC
21735 +extern void gr_shm_exit(struct task_struct *task);
21737 +static inline void gr_shm_exit(struct task_struct *task)
21743 +#ifdef CONFIG_GRKERNSEC
21744 +extern void gr_handle_mem_write(void);
21745 +extern void gr_handle_kmem_write(void);
21746 +extern void gr_handle_open_port(void);
21747 +extern int gr_handle_mem_mmap(const unsigned long offset,
21748 + struct vm_area_struct *vma);
21750 +extern unsigned long pax_get_random_long(void);
21751 +#define get_random_long() pax_get_random_long()
21753 +extern int grsec_enable_dmesg;
21754 +extern int grsec_enable_randsrc;
21755 +extern int grsec_enable_shm;
21759 diff -urNp linux-2.6.17.7/include/linux/highmem.h linux-2.6.17.7/include/linux/highmem.h
21760 --- linux-2.6.17.7/include/linux/highmem.h 2006-07-24 23:36:01.000000000 -0400
21761 +++ linux-2.6.17.7/include/linux/highmem.h 2006-08-01 20:29:48.000000000 -0400
21762 @@ -70,9 +70,9 @@ alloc_zeroed_user_highpage(struct vm_are
21764 static inline void clear_highpage(struct page *page)
21766 - void *kaddr = kmap_atomic(page, KM_USER0);
21767 + void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
21769 - kunmap_atomic(kaddr, KM_USER0);
21770 + kunmap_atomic(kaddr, KM_CLEARPAGE);
21774 diff -urNp linux-2.6.17.7/include/linux/mm.h linux-2.6.17.7/include/linux/mm.h
21775 --- linux-2.6.17.7/include/linux/mm.h 2006-07-24 23:36:01.000000000 -0400
21776 +++ linux-2.6.17.7/include/linux/mm.h 2006-08-01 20:29:48.000000000 -0400
21777 @@ -38,6 +38,7 @@ extern int sysctl_legacy_va_layout;
21778 #include <asm/pgtable.h>
21779 #include <asm/processor.h>
21780 #include <asm/atomic.h>
21781 +#include <asm/mman.h>
21783 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
21785 @@ -111,8 +112,43 @@ struct vm_area_struct {
21787 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
21790 + unsigned long vm_mirror; /* PaX: mirror distance */
21793 +#ifdef CONFIG_PAX_SOFTMODE
21794 +extern unsigned int pax_softmode;
21797 +extern int pax_check_flags(unsigned long *);
21799 +/* if tsk != current then task_lock must be held on it */
21800 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21801 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
21803 + if (likely(tsk->mm))
21804 + return tsk->mm->pax_flags;
21809 +/* if tsk != current then task_lock must be held on it */
21810 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
21812 + if (likely(tsk->mm)) {
21813 + tsk->mm->pax_flags = flags;
21820 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
21821 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
21822 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
21823 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
21827 * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
21828 * disabled, then there's a single shared list of VMAs maintained by the
21829 @@ -167,6 +203,18 @@ extern unsigned int kobjsize(const void
21830 #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */
21831 #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */
21833 +#ifdef CONFIG_PAX_SEGMEXEC
21834 +#define VM_MIRROR 0x04000000 /* vma is mirroring another */
21837 +#ifdef CONFIG_PAX_MPROTECT
21838 +#define VM_MAYNOTWRITE 0x08000000 /* vma cannot be granted VM_WRITE any more */
21841 +#ifdef __VM_STACK_FLAGS
21842 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
21845 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
21846 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
21848 @@ -1058,5 +1106,11 @@ void drop_slab(void);
21849 extern int randomize_va_space;
21852 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
21853 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
21855 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
21858 #endif /* __KERNEL__ */
21859 #endif /* _LINUX_MM_H */
21860 diff -urNp linux-2.6.17.7/include/linux/mman.h linux-2.6.17.7/include/linux/mman.h
21861 --- linux-2.6.17.7/include/linux/mman.h 2006-07-24 23:36:01.000000000 -0400
21862 +++ linux-2.6.17.7/include/linux/mman.h 2006-08-01 20:29:48.000000000 -0400
21863 @@ -59,6 +59,11 @@ static inline unsigned long
21864 calc_vm_flag_bits(unsigned long flags)
21866 return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
21868 +#ifdef CONFIG_PAX_SEGMEXEC
21869 + _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
21872 _calc_vm_trans(flags, MAP_DENYWRITE, VM_DENYWRITE ) |
21873 _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
21874 _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED );
21875 diff -urNp linux-2.6.17.7/include/linux/module.h linux-2.6.17.7/include/linux/module.h
21876 --- linux-2.6.17.7/include/linux/module.h 2006-07-24 23:36:01.000000000 -0400
21877 +++ linux-2.6.17.7/include/linux/module.h 2006-08-01 20:29:48.000000000 -0400
21878 @@ -273,16 +273,16 @@ struct module
21881 /* If this is non-NULL, vfree after init() returns */
21882 - void *module_init;
21883 + void *module_init_rx, *module_init_rw;
21885 /* Here is the actual code + data, vfree'd on unload. */
21886 - void *module_core;
21887 + void *module_core_rx, *module_core_rw;
21889 /* Here are the sizes of the init and core sections */
21890 - unsigned long init_size, core_size;
21891 + unsigned long init_size_rw, core_size_rw;
21893 /* The size of the executable code in each section. */
21894 - unsigned long init_text_size, core_text_size;
21895 + unsigned long init_size_rx, core_size_rx;
21897 /* Arch-specific module values */
21898 struct mod_arch_specific arch;
21899 diff -urNp linux-2.6.17.7/include/linux/moduleloader.h linux-2.6.17.7/include/linux/moduleloader.h
21900 --- linux-2.6.17.7/include/linux/moduleloader.h 2006-07-24 23:36:01.000000000 -0400
21901 +++ linux-2.6.17.7/include/linux/moduleloader.h 2006-08-01 20:29:48.000000000 -0400
21902 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
21903 sections. Returns NULL on failure. */
21904 void *module_alloc(unsigned long size);
21906 +#ifdef CONFIG_PAX_KERNEXEC
21907 +void *module_alloc_exec(unsigned long size);
21909 +#define module_alloc_exec(x) module_alloc(x)
21912 /* Free memory returned from module_alloc. */
21913 void module_free(struct module *mod, void *module_region);
21915 +#ifdef CONFIG_PAX_KERNEXEC
21916 +void module_free_exec(struct module *mod, void *module_region);
21918 +#define module_free_exec(x, y) module_free(x, y)
21921 /* Apply the given relocation to the (simplified) ELF. Return -error
21923 int apply_relocate(Elf_Shdr *sechdrs,
21924 diff -urNp linux-2.6.17.7/include/linux/random.h linux-2.6.17.7/include/linux/random.h
21925 --- linux-2.6.17.7/include/linux/random.h 2006-07-24 23:36:01.000000000 -0400
21926 +++ linux-2.6.17.7/include/linux/random.h 2006-08-01 20:29:48.000000000 -0400
21927 @@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
21928 extern u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
21929 __u16 sport, __u16 dport);
21931 +extern unsigned long pax_get_random_long(void);
21934 extern struct file_operations random_fops, urandom_fops;
21936 diff -urNp linux-2.6.17.7/include/linux/sched.h linux-2.6.17.7/include/linux/sched.h
21937 --- linux-2.6.17.7/include/linux/sched.h 2006-07-24 23:36:01.000000000 -0400
21938 +++ linux-2.6.17.7/include/linux/sched.h 2006-08-01 20:29:48.000000000 -0400
21940 #include <linux/auxvec.h> /* For AT_VECTOR_SIZE */
21942 struct exec_domain;
21943 +struct linux_binprm;
21947 @@ -350,8 +351,34 @@ struct mm_struct {
21949 rwlock_t ioctx_list_lock;
21950 struct kioctx *ioctx_list;
21952 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21953 + unsigned long pax_flags;
21956 +#ifdef CONFIG_PAX_DLRESOLVE
21957 + unsigned long call_dl_resolve;
21960 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
21961 + unsigned long call_syscall;
21964 +#ifdef CONFIG_PAX_ASLR
21965 + unsigned long delta_mmap; /* randomized offset */
21966 + unsigned long delta_exec; /* randomized offset */
21967 + unsigned long delta_stack; /* randomized offset */
21972 +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
21973 +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
21974 +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
21975 +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
21976 +/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
21977 +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
21979 struct sighand_struct {
21981 struct k_sigaction action[_NSIG];
21982 @@ -449,6 +476,15 @@ struct signal_struct {
21983 struct key *session_keyring; /* keyring inherited over fork */
21984 struct key *process_keyring; /* keyring private to this process */
21987 +#ifdef CONFIG_GRKERNSEC
21993 + u8 used_accept:1;
21997 /* Context switch must be unlocked if interrupts are to be enabled */
21998 @@ -881,6 +917,17 @@ struct task_struct {
21999 struct compat_robust_list_head __user *compat_robust_list;
22002 +#ifdef CONFIG_GRKERNSEC
22004 + struct acl_subject_label *acl;
22005 + struct acl_role_label *role;
22006 + struct file *exec_file;
22008 + u8 acl_sp_role:1;
22009 + u8 is_writable:1;
22013 atomic_t fs_excl; /* holding fs exclusive resources */
22014 struct rcu_head rcu;
22016 @@ -1393,6 +1440,12 @@ extern void arch_pick_mmap_layout(struct
22017 static inline void arch_pick_mmap_layout(struct mm_struct *mm)
22019 mm->mmap_base = TASK_UNMAPPED_BASE;
22021 +#ifdef CONFIG_PAX_RANDMMAP
22022 + if (mm->pax_flags & MF_PAX_RANDMMAP)
22023 + mm->mmap_base += mm->delta_mmap;
22026 mm->get_unmapped_area = arch_get_unmapped_area;
22027 mm->unmap_area = arch_unmap_area;
22029 diff -urNp linux-2.6.17.7/include/linux/shm.h linux-2.6.17.7/include/linux/shm.h
22030 --- linux-2.6.17.7/include/linux/shm.h 2006-07-24 23:36:01.000000000 -0400
22031 +++ linux-2.6.17.7/include/linux/shm.h 2006-08-01 20:29:48.000000000 -0400
22032 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
22035 struct user_struct *mlock_user;
22036 +#ifdef CONFIG_GRKERNSEC
22037 + time_t shm_createtime;
22042 /* shm_mode upper byte flags */
22043 diff -urNp linux-2.6.17.7/include/linux/sysctl.h linux-2.6.17.7/include/linux/sysctl.h
22044 --- linux-2.6.17.7/include/linux/sysctl.h 2006-07-24 23:36:01.000000000 -0400
22045 +++ linux-2.6.17.7/include/linux/sysctl.h 2006-08-01 20:29:48.000000000 -0400
22047 INOTIFY_MAX_QUEUED_EVENTS=3 /* max queued events per instance */
22050 +#ifdef CONFIG_PAX_SOFTMODE
22052 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
22056 /* CTL_KERN names: */
22059 +#ifdef CONFIG_GRKERNSEC
22060 + KERN_GRSECURITY=98, /* grsecurity */
22063 +#ifdef CONFIG_PAX_SOFTMODE
22064 + KERN_PAX=99, /* PaX control */
22066 KERN_OSTYPE=1, /* string: system version */
22067 KERN_OSRELEASE=2, /* string: system release */
22068 KERN_OSREV=3, /* int: system revision */
22069 diff -urNp linux-2.6.17.7/init/Kconfig linux-2.6.17.7/init/Kconfig
22070 --- linux-2.6.17.7/init/Kconfig 2006-07-24 23:36:01.000000000 -0400
22071 +++ linux-2.6.17.7/init/Kconfig 2006-08-01 20:29:48.000000000 -0400
22072 @@ -268,6 +268,7 @@ menuconfig EMBEDDED
22074 bool "Load all symbols for debugging/kksymoops" if EMBEDDED
22076 + depends on !GRKERNSEC_HIDESYM
22078 Say Y here to let the kernel print out symbolic crash information and
22079 symbolic stack backtraces. This increases the size of the kernel
22080 diff -urNp linux-2.6.17.7/init/main.c linux-2.6.17.7/init/main.c
22081 --- linux-2.6.17.7/init/main.c 2006-07-24 23:36:01.000000000 -0400
22082 +++ linux-2.6.17.7/init/main.c 2006-08-01 20:29:48.000000000 -0400
22083 @@ -100,6 +100,7 @@ static inline void mark_rodata_ro(void)
22085 extern void tc_init(void);
22087 +extern void grsecurity_init(void);
22089 enum system_states system_state;
22090 EXPORT_SYMBOL(system_state);
22091 @@ -150,6 +151,15 @@ static int __init maxcpus(char *str)
22093 __setup("maxcpus=", maxcpus);
22095 +#ifdef CONFIG_PAX_SOFTMODE
22096 +static int __init setup_pax_softmode(char *str)
22098 + get_option(&str, &pax_softmode);
22101 +__setup("pax_softmode=", setup_pax_softmode);
22104 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
22105 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
22106 static const char *panic_later, *panic_param;
22107 @@ -692,6 +702,8 @@ static int init(void * unused)
22108 prepare_namespace();
22111 + grsecurity_init();
22114 * Ok, we have completed the initial bootup, and
22115 * we're essentially up and running. Get rid of the
22116 diff -urNp linux-2.6.17.7/ipc/msg.c linux-2.6.17.7/ipc/msg.c
22117 --- linux-2.6.17.7/ipc/msg.c 2006-07-24 23:36:01.000000000 -0400
22118 +++ linux-2.6.17.7/ipc/msg.c 2006-08-01 20:29:48.000000000 -0400
22120 #include <linux/audit.h>
22121 #include <linux/seq_file.h>
22122 #include <linux/mutex.h>
22123 +#include <linux/grsecurity.h>
22125 #include <asm/current.h>
22126 #include <asm/uaccess.h>
22127 @@ -237,6 +238,9 @@ asmlinkage long sys_msgget (key_t key, i
22130 mutex_unlock(&msg_ids.mutex);
22132 + gr_log_msgget(ret, msgflg);
22137 @@ -495,6 +499,8 @@ asmlinkage long sys_msgctl (int msqid, i
22141 + gr_log_msgrm(ipcp->uid, ipcp->cuid);
22143 freeque (msq, msqid);
22146 diff -urNp linux-2.6.17.7/ipc/sem.c linux-2.6.17.7/ipc/sem.c
22147 --- linux-2.6.17.7/ipc/sem.c 2006-07-24 23:36:01.000000000 -0400
22148 +++ linux-2.6.17.7/ipc/sem.c 2006-08-01 20:29:48.000000000 -0400
22150 #include <linux/seq_file.h>
22151 #include <linux/mutex.h>
22152 #include <linux/vs_limit.h>
22153 +#include <linux/grsecurity.h>
22155 #include <asm/uaccess.h>
22157 @@ -247,6 +248,9 @@ asmlinkage long sys_semget (key_t key, i
22160 mutex_unlock(&sem_ids.mutex);
22162 + gr_log_semget(err, semflg);
22167 @@ -840,6 +844,8 @@ static int semctl_down(int semid, int se
22171 + gr_log_semrm(ipcp->uid, ipcp->cuid);
22173 freeary(sma, semid);
22176 diff -urNp linux-2.6.17.7/ipc/shm.c linux-2.6.17.7/ipc/shm.c
22177 --- linux-2.6.17.7/ipc/shm.c 2006-07-24 23:36:01.000000000 -0400
22178 +++ linux-2.6.17.7/ipc/shm.c 2006-08-01 20:29:48.000000000 -0400
22180 #include <linux/mutex.h>
22181 #include <linux/vs_context.h>
22182 #include <linux/vs_limit.h>
22183 +#include <linux/grsecurity.h>
22185 #include <asm/uaccess.h>
22187 @@ -56,6 +57,14 @@ static void shm_close (struct vm_area_st
22188 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
22191 +#ifdef CONFIG_GRKERNSEC
22192 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22193 + const time_t shm_createtime, const uid_t cuid,
22194 + const int shmid);
22195 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22196 + const time_t shm_createtime);
22199 size_t shm_ctlmax = SHMMAX;
22200 size_t shm_ctlall = SHMALL;
22201 int shm_ctlmni = SHMMNI;
22202 @@ -149,6 +158,17 @@ static void shm_close (struct vm_area_st
22203 shp->shm_lprid = current->tgid;
22204 shp->shm_dtim = get_seconds();
22206 +#ifdef CONFIG_GRKERNSEC_SHM
22207 + if (grsec_enable_shm) {
22208 + if (shp->shm_nattch == 0) {
22209 + shp->shm_perm.mode |= SHM_DEST;
22210 + shm_destroy(shp);
22213 + mutex_unlock(&shm_ids.mutex);
22217 if(shp->shm_nattch == 0 &&
22218 shp->shm_perm.mode & SHM_DEST)
22220 @@ -248,6 +268,9 @@ static int newseg (key_t key, int shmflg
22221 shp->shm_lprid = 0;
22222 shp->shm_atim = shp->shm_dtim = 0;
22223 shp->shm_ctim = get_seconds();
22224 +#ifdef CONFIG_GRKERNSEC
22225 + shp->shm_createtime = get_seconds();
22227 shp->shm_segsz = size;
22228 shp->shm_nattch = 0;
22229 shp->id = shm_buildid(id,shp->shm_perm.seq);
22230 @@ -302,6 +325,8 @@ asmlinkage long sys_shmget (key_t key, s
22232 mutex_unlock(&shm_ids.mutex);
22234 + gr_log_shmget(err, shmflg, size);
22239 @@ -615,6 +640,8 @@ asmlinkage long sys_shmctl (int shmid, i
22241 goto out_unlock_up;
22243 + gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
22245 if (shp->shm_nattch){
22246 shp->shm_perm.mode |= SHM_DEST;
22247 /* Do not find it any more */
22248 @@ -763,9 +790,27 @@ long do_shmat(int shmid, char __user *sh
22252 +#ifdef CONFIG_GRKERNSEC
22253 + if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
22254 + shp->shm_perm.cuid, shmid)) {
22259 + if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
22265 file = shp->shm_file;
22266 size = i_size_read(file->f_dentry->d_inode);
22269 +#ifdef CONFIG_GRKERNSEC
22270 + shp->shm_lapid = current->pid;
22275 down_write(¤t->mm->mmap_sem);
22276 @@ -935,3 +980,24 @@ static int sysvipc_shm_proc_show(struct
22281 +void gr_shm_exit(struct task_struct *task)
22283 +#ifdef CONFIG_GRKERNSEC_SHM
22285 + struct shmid_kernel *shp;
22287 + if (!grsec_enable_shm)
22290 + for (i = 0; i <= shm_ids.max_id; i++) {
22291 + shp = shm_get(i);
22292 + if (shp && (shp->shm_cprid == task->pid) &&
22293 + (shp->shm_nattch <= 0)) {
22294 + shp->shm_perm.mode |= SHM_DEST;
22295 + shm_destroy(shp);
22301 diff -urNp linux-2.6.17.7/kernel/capability.c linux-2.6.17.7/kernel/capability.c
22302 --- linux-2.6.17.7/kernel/capability.c 2006-07-24 23:36:01.000000000 -0400
22303 +++ linux-2.6.17.7/kernel/capability.c 2006-08-01 20:29:48.000000000 -0400
22305 #include <linux/security.h>
22306 #include <linux/syscalls.h>
22307 #include <linux/vs_pid.h>
22308 +#include <linux/grsecurity.h>
22309 #include <asm/uaccess.h>
22311 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
22312 @@ -234,14 +235,25 @@ out:
22316 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
22317 +extern int gr_is_capable_nolog(const int cap);
22319 int __capable(struct task_struct *t, int cap)
22321 - if (security_capable(t, cap) == 0) {
22322 + if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
22323 t->flags |= PF_SUPERPRIV;
22328 +int capable_nolog(int cap)
22330 + if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
22331 + current->flags |= PF_SUPERPRIV;
22336 EXPORT_SYMBOL(__capable);
22338 int capable(int cap)
22339 @@ -249,4 +261,5 @@ int capable(int cap)
22340 return __capable(current, cap);
22342 EXPORT_SYMBOL(capable);
22343 +EXPORT_SYMBOL(capable_nolog);
22345 diff -urNp linux-2.6.17.7/kernel/configs.c linux-2.6.17.7/kernel/configs.c
22346 --- linux-2.6.17.7/kernel/configs.c 2006-07-24 23:36:01.000000000 -0400
22347 +++ linux-2.6.17.7/kernel/configs.c 2006-08-01 20:29:48.000000000 -0400
22348 @@ -89,8 +89,16 @@ static int __init ikconfig_init(void)
22349 struct proc_dir_entry *entry;
22351 /* create the current config file */
22352 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
22353 +#ifdef CONFIG_GRKERNSEC_PROC_USER
22354 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
22355 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
22356 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
22359 entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
22365 diff -urNp linux-2.6.17.7/kernel/exit.c linux-2.6.17.7/kernel/exit.c
22366 --- linux-2.6.17.7/kernel/exit.c 2006-07-24 23:36:01.000000000 -0400
22367 +++ linux-2.6.17.7/kernel/exit.c 2006-08-01 20:29:48.000000000 -0400
22369 #include <linux/vs_network.h>
22370 #include <linux/vs_pid.h>
22371 +#include <linux/grsecurity.h>
22373 +#ifdef CONFIG_GRKERNSEC
22374 +extern rwlock_t grsec_exec_file_lock;
22377 #include <asm/uaccess.h>
22378 #include <asm/unistd.h>
22379 @@ -115,6 +120,7 @@ static void __exit_signal(struct task_st
22381 __unhash_process(tsk);
22383 + gr_del_task_from_ip_table(tsk);
22384 tsk->signal = NULL;
22385 tsk->sighand = NULL;
22386 spin_unlock(&sighand->siglock);
22387 @@ -287,6 +293,15 @@ static void reparent_to_init(void)
22389 write_lock_irq(&tasklist_lock);
22391 +#ifdef CONFIG_GRKERNSEC
22392 + write_lock(&grsec_exec_file_lock);
22393 + if (current->exec_file) {
22394 + fput(current->exec_file);
22395 + current->exec_file = NULL;
22397 + write_unlock(&grsec_exec_file_lock);
22400 ptrace_unlink(current);
22401 /* Reparent to init */
22402 remove_parent(current);
22403 @@ -294,6 +309,8 @@ static void reparent_to_init(void)
22404 current->real_parent = child_reaper;
22405 add_parent(current);
22407 + gr_set_kernel_label(current);
22409 /* Set the exit signal to SIGCHLD so we signal init on exit */
22410 current->exit_signal = SIGCHLD;
22412 @@ -390,6 +407,17 @@ void daemonize(const char *name, ...)
22413 vsnprintf(current->comm, sizeof(current->comm), name, args);
22416 +#ifdef CONFIG_GRKERNSEC
22417 + write_lock(&grsec_exec_file_lock);
22418 + if (current->exec_file) {
22419 + fput(current->exec_file);
22420 + current->exec_file = NULL;
22422 + write_unlock(&grsec_exec_file_lock);
22425 + gr_set_kernel_label(current);
22428 * If we were started as result of loading a module, close all of the
22429 * user space pages. We don't need them, and if we didn't close them
22430 @@ -905,9 +933,14 @@ fastcall NORET_TYPE void do_exit(long co
22432 if (unlikely(tsk->audit_context))
22435 + gr_acl_handle_psacct(tsk, code);
22436 + gr_acl_handle_exit();
22441 + gr_shm_exit(tsk);
22444 exit_namespace(tsk);
22445 diff -urNp linux-2.6.17.7/kernel/fork.c linux-2.6.17.7/kernel/fork.c
22446 --- linux-2.6.17.7/kernel/fork.c 2006-07-24 23:36:01.000000000 -0400
22447 +++ linux-2.6.17.7/kernel/fork.c 2006-08-01 20:29:48.000000000 -0400
22449 #include <linux/vs_network.h>
22450 #include <linux/vs_limit.h>
22451 #include <linux/vs_memory.h>
22452 +#include <linux/grsecurity.h>
22454 #include <asm/pgtable.h>
22455 #include <asm/pgalloc.h>
22456 @@ -198,8 +199,8 @@ static inline int dup_mmap(struct mm_str
22459 mm->mmap_cache = NULL;
22460 - mm->free_area_cache = oldmm->mmap_base;
22461 - mm->cached_hole_size = ~0UL;
22462 + mm->free_area_cache = oldmm->free_area_cache;
22463 + mm->cached_hole_size = oldmm->cached_hole_size;
22465 cpus_clear(mm->cpu_vm_mask);
22466 mm->mm_rb = RB_ROOT;
22467 @@ -324,7 +325,7 @@ static struct mm_struct * mm_init(struct
22468 spin_lock_init(&mm->page_table_lock);
22469 rwlock_init(&mm->ioctx_list_lock);
22470 mm->ioctx_list = NULL;
22471 - mm->free_area_cache = TASK_UNMAPPED_BASE;
22472 + mm->free_area_cache = ~0UL;
22473 mm->cached_hole_size = ~0UL;
22475 if (likely(!mm_alloc_pgd(mm))) {
22476 @@ -956,6 +957,8 @@ static task_t *copy_process(unsigned lon
22477 if (!vx_nproc_avail(1))
22478 goto bad_fork_cleanup_vm;
22480 + gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
22482 if (atomic_read(&p->user->processes) >=
22483 p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
22484 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
22485 @@ -1066,6 +1070,8 @@ static task_t *copy_process(unsigned lon
22487 goto bad_fork_cleanup_namespace;
22489 + gr_copy_label(p);
22491 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
22493 * Clear TID on mm_release()?
22494 @@ -1255,6 +1261,8 @@ bad_fork_cleanup_count:
22498 + gr_log_forkfail(retval);
22500 return ERR_PTR(retval);
22503 @@ -1328,6 +1336,8 @@ long do_fork(unsigned long clone_flags,
22505 struct completion vfork;
22507 + gr_handle_brute_check();
22509 if (clone_flags & CLONE_VFORK) {
22510 p->vfork_done = &vfork;
22511 init_completion(&vfork);
22512 diff -urNp linux-2.6.17.7/kernel/futex.c linux-2.6.17.7/kernel/futex.c
22513 --- linux-2.6.17.7/kernel/futex.c 2006-07-24 23:36:01.000000000 -0400
22514 +++ linux-2.6.17.7/kernel/futex.c 2006-08-01 20:29:48.000000000 -0400
22515 @@ -151,6 +151,11 @@ static int get_futex_key(unsigned long u
22519 +#ifdef CONFIG_PAX_SEGMEXEC
22520 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (uaddr >= SEGMEXEC_TASK_SIZE))
22525 * The futex address must be "naturally" aligned.
22527 diff -urNp linux-2.6.17.7/kernel/kallsyms.c linux-2.6.17.7/kernel/kallsyms.c
22528 --- linux-2.6.17.7/kernel/kallsyms.c 2006-07-24 23:36:01.000000000 -0400
22529 +++ linux-2.6.17.7/kernel/kallsyms.c 2006-08-01 20:29:48.000000000 -0400
22530 @@ -301,7 +301,6 @@ static unsigned long get_ksymbol_core(st
22532 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
22534 - iter->name[0] = '\0';
22535 iter->nameoff = get_symbol_offset(new_pos);
22536 iter->pos = new_pos;
22538 @@ -380,7 +379,7 @@ static int kallsyms_open(struct inode *i
22539 struct kallsym_iter *iter;
22542 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
22543 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
22546 reset_iter(iter, 0);
22547 @@ -411,7 +410,15 @@ static int __init kallsyms_init(void)
22549 struct proc_dir_entry *entry;
22551 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
22552 +#ifdef CONFIG_GRKERNSEC_PROC_USER
22553 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
22554 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
22555 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
22558 entry = create_proc_entry("kallsyms", 0444, NULL);
22561 entry->proc_fops = &kallsyms_operations;
22563 diff -urNp linux-2.6.17.7/kernel/kprobes.c linux-2.6.17.7/kernel/kprobes.c
22564 --- linux-2.6.17.7/kernel/kprobes.c 2006-07-24 23:36:01.000000000 -0400
22565 +++ linux-2.6.17.7/kernel/kprobes.c 2006-08-01 20:29:48.000000000 -0400
22566 @@ -106,7 +106,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
22567 * kernel image and loaded module images reside. This is required
22568 * so x86_64 can correctly handle the %rip-relative fixups.
22570 - kip->insns = module_alloc(PAGE_SIZE);
22571 + kip->insns = module_alloc_exec(PAGE_SIZE);
22575 diff -urNp linux-2.6.17.7/kernel/module.c linux-2.6.17.7/kernel/module.c
22576 --- linux-2.6.17.7/kernel/module.c 2006-07-24 23:36:01.000000000 -0400
22577 +++ linux-2.6.17.7/kernel/module.c 2006-08-01 20:29:48.000000000 -0400
22578 @@ -40,10 +40,15 @@
22579 #include <linux/string.h>
22580 #include <linux/sched.h>
22581 #include <linux/mutex.h>
22582 +#include <linux/kallsyms.h>
22583 #include <asm/uaccess.h>
22584 #include <asm/semaphore.h>
22585 #include <asm/cacheflush.h>
22587 +#ifdef CONFIG_PAX_KERNEXEC
22588 +#include <asm/desc.h>
22592 #define DEBUGP printk
22594 @@ -66,6 +71,8 @@ static LIST_HEAD(modules);
22596 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
22598 +extern int gr_check_modstop(void);
22600 int register_module_notifier(struct notifier_block * nb)
22602 return blocking_notifier_chain_register(&module_notify_list, nb);
22603 @@ -594,6 +601,9 @@ sys_delete_module(const char __user *nam
22604 char name[MODULE_NAME_LEN];
22605 int ret, forced = 0;
22607 + if (gr_check_modstop())
22610 if (!capable(CAP_SYS_MODULE))
22613 @@ -1058,13 +1068,15 @@ static void free_module(struct module *m
22614 module_unload_free(mod);
22616 /* This may be NULL, but that's OK */
22617 - module_free(mod, mod->module_init);
22618 + module_free(mod, mod->module_init_rw);
22619 + module_free_exec(mod, mod->module_init_rx);
22622 percpu_modfree(mod->percpu);
22624 /* Finally, free the core (containing the module structure) */
22625 - module_free(mod, mod->module_core);
22626 + module_free_exec(mod, mod->module_core_rx);
22627 + module_free(mod, mod->module_core_rw);
22630 void *__symbol_get(const char *symbol)
22631 @@ -1221,11 +1233,14 @@ static void layout_sections(struct modul
22632 || strncmp(secstrings + s->sh_name,
22635 - s->sh_entsize = get_offset(&mod->core_size, s);
22636 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
22637 + s->sh_entsize = get_offset(&mod->core_size_rw, s);
22639 + s->sh_entsize = get_offset(&mod->core_size_rx, s);
22640 DEBUGP("\t%s\n", secstrings + s->sh_name);
22643 - mod->core_text_size = mod->core_size;
22644 + mod->core_size_rx = mod->core_size_rx;
22647 DEBUGP("Init section allocation order:\n");
22648 @@ -1239,12 +1254,15 @@ static void layout_sections(struct modul
22649 || strncmp(secstrings + s->sh_name,
22652 - s->sh_entsize = (get_offset(&mod->init_size, s)
22653 - | INIT_OFFSET_MASK);
22654 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
22655 + s->sh_entsize = get_offset(&mod->init_size_rw, s);
22657 + s->sh_entsize = get_offset(&mod->init_size_rx, s);
22658 + s->sh_entsize |= INIT_OFFSET_MASK;
22659 DEBUGP("\t%s\n", secstrings + s->sh_name);
22662 - mod->init_text_size = mod->init_size;
22663 + mod->init_size_rx = mod->init_size_rx;
22667 @@ -1419,6 +1437,10 @@ static struct module *load_module(void _
22668 struct exception_table_entry *extable;
22669 mm_segment_t old_fs;
22671 +#ifdef CONFIG_PAX_KERNEXEC
22672 + unsigned long cr0;
22675 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
22677 if (len < sizeof(*hdr))
22678 @@ -1568,21 +1590,57 @@ static struct module *load_module(void _
22679 layout_sections(mod, hdr, sechdrs, secstrings);
22681 /* Do the allocs. */
22682 - ptr = module_alloc(mod->core_size);
22683 + ptr = module_alloc(mod->core_size_rw);
22688 - memset(ptr, 0, mod->core_size);
22689 - mod->module_core = ptr;
22690 + memset(ptr, 0, mod->core_size_rw);
22691 + mod->module_core_rw = ptr;
22693 + ptr = module_alloc(mod->init_size_rw);
22694 + if (!ptr && mod->init_size_rw) {
22696 + goto free_core_rw;
22698 + memset(ptr, 0, mod->init_size_rw);
22699 + mod->module_init_rw = ptr;
22701 + ptr = module_alloc_exec(mod->core_size_rx);
22704 + goto free_init_rw;
22707 +#ifdef CONFIG_PAX_KERNEXEC
22708 + pax_open_kernel(cr0);
22711 + memset(ptr, 0, mod->core_size_rx);
22713 +#ifdef CONFIG_PAX_KERNEXEC
22714 + pax_close_kernel(cr0);
22717 + mod->module_core_rx = ptr;
22719 - ptr = module_alloc(mod->init_size);
22720 - if (!ptr && mod->init_size) {
22721 + ptr = module_alloc_exec(mod->init_size_rx);
22722 + if (!ptr && mod->init_size_rx) {
22725 + goto free_core_rx;
22727 - memset(ptr, 0, mod->init_size);
22728 - mod->module_init = ptr;
22730 +#ifdef CONFIG_PAX_KERNEXEC
22731 + pax_open_kernel(cr0);
22734 + memset(ptr, 0, mod->init_size_rx);
22736 +#ifdef CONFIG_PAX_KERNEXEC
22737 + pax_close_kernel(cr0);
22740 + mod->module_init_rx = ptr;
22742 /* Transfer each section which specifies SHF_ALLOC */
22743 DEBUGP("final section addresses:\n");
22744 @@ -1592,17 +1650,44 @@ static struct module *load_module(void _
22745 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
22748 - if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
22749 - dest = mod->module_init
22750 - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
22752 - dest = mod->module_core + sechdrs[i].sh_entsize;
22753 + if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
22754 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
22755 + dest = mod->module_init_rw
22756 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
22758 + dest = mod->module_init_rx
22759 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
22761 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
22762 + dest = mod->module_core_rw + sechdrs[i].sh_entsize;
22764 + dest = mod->module_core_rx + sechdrs[i].sh_entsize;
22767 + if (sechdrs[i].sh_type != SHT_NOBITS) {
22769 +#ifdef CONFIG_PAX_KERNEXEC
22770 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
22771 + pax_open_kernel(cr0);
22774 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
22776 - if (sechdrs[i].sh_type != SHT_NOBITS)
22777 - memcpy(dest, (void *)sechdrs[i].sh_addr,
22778 - sechdrs[i].sh_size);
22779 +#ifdef CONFIG_PAX_KERNEXEC
22780 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
22781 + pax_close_kernel(cr0);
22785 /* Update sh_addr to point to copy in image. */
22786 - sechdrs[i].sh_addr = (unsigned long)dest;
22788 +#ifdef CONFIG_PAX_KERNEXEC
22789 + if (sechdrs[i].sh_flags & SHF_EXECINSTR)
22790 + sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
22794 + sechdrs[i].sh_addr = (unsigned long)dest;
22795 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
22797 /* Module has been moved. */
22798 @@ -1623,8 +1708,18 @@ static struct module *load_module(void _
22799 setup_modinfo(mod, sechdrs, infoindex);
22801 /* Fix up syms, so that st_value is a pointer to location. */
22803 +#ifdef CONFIG_PAX_KERNEXEC
22804 + pax_open_kernel(cr0);
22807 err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
22810 +#ifdef CONFIG_PAX_KERNEXEC
22811 + pax_close_kernel(cr0);
22817 @@ -1666,11 +1761,20 @@ static struct module *load_module(void _
22818 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
22821 +#ifdef CONFIG_PAX_KERNEXEC
22822 + pax_open_kernel(cr0);
22825 if (sechdrs[i].sh_type == SHT_REL)
22826 err = apply_relocate(sechdrs, strtab, symindex, i,mod);
22827 else if (sechdrs[i].sh_type == SHT_RELA)
22828 err = apply_relocate_add(sechdrs, strtab, symindex, i,
22831 +#ifdef CONFIG_PAX_KERNEXEC
22832 + pax_close_kernel(cr0);
22838 @@ -1684,14 +1788,31 @@ static struct module *load_module(void _
22839 /* Set up and sort exception table */
22840 mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
22841 mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
22843 +#ifdef CONFIG_PAX_KERNEXEC
22844 + pax_open_kernel(cr0);
22847 sort_extable(extable, extable + mod->num_exentries);
22849 +#ifdef CONFIG_PAX_KERNEXEC
22850 + pax_close_kernel(cr0);
22853 /* Finally, copy percpu area over. */
22854 percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
22855 sechdrs[pcpuindex].sh_size);
22857 +#ifdef CONFIG_PAX_KERNEXEC
22858 + pax_open_kernel(cr0);
22861 add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
22863 +#ifdef CONFIG_PAX_KERNEXEC
22864 + pax_close_kernel(cr0);
22867 err = module_finalize(hdr, sechdrs, mod);
22870 @@ -1705,12 +1826,12 @@ static struct module *load_module(void _
22871 * Do it before processing of module parameters, so the module
22872 * can provide parameter accessor functions of its own.
22874 - if (mod->module_init)
22875 - flush_icache_range((unsigned long)mod->module_init,
22876 - (unsigned long)mod->module_init
22877 - + mod->init_size);
22878 - flush_icache_range((unsigned long)mod->module_core,
22879 - (unsigned long)mod->module_core + mod->core_size);
22880 + if (mod->module_init_rx)
22881 + flush_icache_range((unsigned long)mod->module_init_rx,
22882 + (unsigned long)mod->module_init_rx
22883 + + mod->init_size_rx);
22884 + flush_icache_range((unsigned long)mod->module_core_rx,
22885 + (unsigned long)mod->module_core_rx + mod->core_size_rx);
22889 @@ -1748,9 +1869,13 @@ static struct module *load_module(void _
22890 module_arch_cleanup(mod);
22892 module_unload_free(mod);
22893 - module_free(mod, mod->module_init);
22895 - module_free(mod, mod->module_core);
22896 + module_free_exec(mod, mod->module_init_rx);
22898 + module_free_exec(mod, mod->module_core_rx);
22900 + module_free(mod, mod->module_init_rw);
22902 + module_free(mod, mod->module_core_rw);
22905 percpu_modfree(percpu);
22906 @@ -1786,6 +1911,9 @@ sys_init_module(void __user *umod,
22907 struct module *mod;
22910 + if (gr_check_modstop())
22913 /* Must have permission */
22914 if (!capable(CAP_SYS_MODULE))
22916 @@ -1836,10 +1964,12 @@ sys_init_module(void __user *umod,
22917 mod->state = MODULE_STATE_LIVE;
22918 /* Drop initial reference. */
22920 - module_free(mod, mod->module_init);
22921 - mod->module_init = NULL;
22922 - mod->init_size = 0;
22923 - mod->init_text_size = 0;
22924 + module_free(mod, mod->module_init_rw);
22925 + module_free_exec(mod, mod->module_init_rx);
22926 + mod->module_init_rw = NULL;
22927 + mod->module_init_rx = NULL;
22928 + mod->init_size_rw = 0;
22929 + mod->init_size_rx = 0;
22930 mutex_unlock(&module_mutex);
22933 @@ -1870,10 +2000,14 @@ static const char *get_ksymbol(struct mo
22934 unsigned long nextval;
22936 /* At worse, next value is at end of module */
22937 - if (within(addr, mod->module_init, mod->init_size))
22938 - nextval = (unsigned long)mod->module_init+mod->init_text_size;
22940 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
22941 + if (within(addr, mod->module_init_rx, mod->init_size_rx))
22942 + nextval = (unsigned long)mod->module_init_rw;
22943 + else if (within(addr, mod->module_init_rw, mod->init_size_rw))
22944 + nextval = (unsigned long)mod->module_core_rx;
22945 + else if (within(addr, mod->module_core_rx, mod->core_size_rx))
22946 + nextval = (unsigned long)mod->module_core_rw;
22948 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
22950 /* Scan for closest preceeding symbol, and next symbol. (ELF
22951 starts real symbols at 1). */
22952 @@ -1914,8 +2048,10 @@ const char *module_address_lookup(unsign
22953 struct module *mod;
22955 list_for_each_entry(mod, &modules, list) {
22956 - if (within(addr, mod->module_init, mod->init_size)
22957 - || within(addr, mod->module_core, mod->core_size)) {
22958 + if (within(addr, mod->module_init_rx, mod->init_size_rx)
22959 + || within(addr, mod->module_init_rw, mod->init_size_rw)
22960 + || within(addr, mod->module_core_rx, mod->core_size_rx)
22961 + || within(addr, mod->module_core_rw, mod->core_size_rw)) {
22962 *modname = mod->name;
22963 return get_ksymbol(mod, addr, size, offset);
22965 @@ -1926,7 +2062,7 @@ const char *module_address_lookup(unsign
22966 struct module *module_get_kallsym(unsigned int symnum,
22967 unsigned long *value,
22969 - char namebuf[128])
22970 + char namebuf[KSYM_NAME_LEN+1])
22972 struct module *mod;
22974 @@ -1937,7 +2073,7 @@ struct module *module_get_kallsym(unsign
22975 *type = mod->symtab[symnum].st_info;
22977 mod->strtab + mod->symtab[symnum].st_name,
22980 mutex_unlock(&module_mutex);
22983 @@ -2014,7 +2150,7 @@ static int m_show(struct seq_file *m, vo
22985 struct module *mod = list_entry(p, struct module, list);
22986 seq_printf(m, "%s %lu",
22987 - mod->name, mod->init_size + mod->core_size);
22988 + mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
22989 print_unload_info(m, mod);
22991 /* Informative for users. */
22992 @@ -2023,7 +2159,7 @@ static int m_show(struct seq_file *m, vo
22993 mod->state == MODULE_STATE_COMING ? "Loading":
22995 /* Used by oprofile and other similar tools. */
22996 - seq_printf(m, " 0x%p", mod->module_core);
22997 + seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
22999 seq_printf(m, "\n");
23001 @@ -2071,9 +2207,13 @@ struct module *__module_text_address(uns
23003 struct module *mod;
23005 +#ifdef CONFIG_PAX_KERNEXEC
23006 + addr += __KERNEL_TEXT_OFFSET;
23009 list_for_each_entry(mod, &modules, list)
23010 - if (within(addr, mod->module_init, mod->init_text_size)
23011 - || within(addr, mod->module_core, mod->core_text_size))
23012 + if (within(addr, mod->module_init_rx, mod->init_size_rx)
23013 + || within(addr, mod->module_core_rx, mod->core_size_rx))
23017 diff -urNp linux-2.6.17.7/kernel/pid.c linux-2.6.17.7/kernel/pid.c
23018 --- linux-2.6.17.7/kernel/pid.c 2006-07-24 23:36:01.000000000 -0400
23019 +++ linux-2.6.17.7/kernel/pid.c 2006-08-01 20:29:48.000000000 -0400
23021 #include <linux/init.h>
23022 #include <linux/bootmem.h>
23023 #include <linux/hash.h>
23024 +#include <linux/grsecurity.h>
23026 #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
23027 static struct hlist_head *pid_hash;
23028 @@ -90,7 +91,9 @@ static int alloc_pidmap(void)
23029 int i, offset, max_scan, pid, last = last_pid;
23033 + pid = gr_random_pid();
23035 + pid = last_pid + 1;
23036 if (pid >= pid_max)
23037 pid = RESERVED_PIDS;
23038 offset = pid & BITS_PER_PAGE_MASK;
23039 @@ -269,7 +272,14 @@ struct task_struct * fastcall pid_task(s
23041 task_t *find_task_by_pid_type(int type, int nr)
23043 - return pid_task(find_pid(nr), type);
23046 + task = pid_task(find_pid(nr), type);
23048 + if (gr_pid_is_chrooted(task))
23054 EXPORT_SYMBOL(find_task_by_pid_type);
23055 diff -urNp linux-2.6.17.7/kernel/posix-cpu-timers.c linux-2.6.17.7/kernel/posix-cpu-timers.c
23056 --- linux-2.6.17.7/kernel/posix-cpu-timers.c 2006-07-24 23:36:01.000000000 -0400
23057 +++ linux-2.6.17.7/kernel/posix-cpu-timers.c 2006-08-01 20:29:48.000000000 -0400
23059 #include <asm/uaccess.h>
23060 #include <linux/errno.h>
23061 #include <linux/vs_pid.h>
23062 +#include <linux/grsecurity.h>
23064 static int check_clock(const clockid_t which_clock)
23066 @@ -1125,6 +1126,7 @@ static void check_process_timers(struct
23067 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
23070 + gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
23071 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
23073 * At the soft limit, send a SIGXCPU every second.
23074 diff -urNp linux-2.6.17.7/kernel/printk.c linux-2.6.17.7/kernel/printk.c
23075 --- linux-2.6.17.7/kernel/printk.c 2006-07-24 23:36:01.000000000 -0400
23076 +++ linux-2.6.17.7/kernel/printk.c 2006-08-01 20:29:48.000000000 -0400
23078 #include <linux/bootmem.h>
23079 #include <linux/syscalls.h>
23080 #include <linux/vs_context.h>
23081 #include <linux/vserver/cvirt.h>
23082 +#include <linux/grsecurity.h>
23084 #include <asm/uaccess.h>
23086 @@ -185,6 +186,11 @@ int do_syslog(int type, char __user *buf
23090 +#ifdef CONFIG_GRKERNSEC_DMESG
23091 + if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
23095 error = security_syslog(type);
23098 diff -urNp linux-2.6.17.7/kernel/ptrace.c linux-2.6.17.7/kernel/ptrace.c
23099 --- linux-2.6.17.7/kernel/ptrace.c 2006-07-24 23:36:01.000000000 -0400
23100 +++ linux-2.6.17.7/kernel/ptrace.c 2006-08-01 20:29:48.000000000 -0400
23102 #include <linux/security.h>
23103 #include <linux/signal.h>
23104 #include <linux/vs_pid.h>
23105 +#include <linux/grsecurity.h>
23107 #include <asm/pgtable.h>
23108 #include <asm/uaccess.h>
23109 @@ -127,10 +128,10 @@ static int may_attach(struct task_struct
23110 (current->uid != task->uid) ||
23111 (current->gid != task->egid) ||
23112 (current->gid != task->sgid) ||
23113 - (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
23114 + (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
23117 - if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
23118 + if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
23121 return security_ptrace(current, task);
23122 @@ -515,6 +516,11 @@ asmlinkage long sys_ptrace(long request,
23124 goto out_put_task_struct;
23126 + if (gr_handle_ptrace(child, request)) {
23128 + goto out_put_task_struct;
23131 ret = arch_ptrace(child, request, addr, data);
23133 goto out_put_task_struct;
23134 diff -urNp linux-2.6.17.7/kernel/resource.c linux-2.6.17.7/kernel/resource.c
23135 --- linux-2.6.17.7/kernel/resource.c 2006-07-24 23:36:01.000000000 -0400
23136 +++ linux-2.6.17.7/kernel/resource.c 2006-08-01 20:29:48.000000000 -0400
23137 @@ -136,10 +136,27 @@ static int __init ioresources_init(void)
23139 struct proc_dir_entry *entry;
23141 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
23142 +#ifdef CONFIG_GRKERNSEC_PROC_USER
23143 + entry = create_proc_entry("ioports", S_IRUSR, NULL);
23144 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
23145 + entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
23148 entry = create_proc_entry("ioports", 0, NULL);
23151 entry->proc_fops = &proc_ioports_operations;
23153 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
23154 +#ifdef CONFIG_GRKERNSEC_PROC_USER
23155 + entry = create_proc_entry("iomem", S_IRUSR, NULL);
23156 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
23157 + entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
23160 entry = create_proc_entry("iomem", 0, NULL);
23163 entry->proc_fops = &proc_iomem_operations;
23165 diff -urNp linux-2.6.17.7/kernel/sched.c linux-2.6.17.7/kernel/sched.c
23166 --- linux-2.6.17.7/kernel/sched.c 2006-07-24 23:36:01.000000000 -0400
23167 +++ linux-2.6.17.7/kernel/sched.c 2006-08-01 20:29:48.000000000 -0400
23169 #include <linux/times.h>
23170 #include <linux/acct.h>
23171 #include <linux/kprobes.h>
23172 +#include <linux/grsecurity.h>
23173 #include <asm/tlb.h>
23175 #include <asm/unistd.h>
23176 @@ -3565,7 +3566,8 @@ asmlinkage long sys_nice(int increment)
23180 - if (increment < 0 && !can_nice(current, nice))
23181 + if (increment < 0 && (!can_nice(current, nice) ||
23182 + gr_handle_chroot_nice()))
23183 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
23185 retval = security_task_setnice(current, nice);
23186 diff -urNp linux-2.6.17.7/kernel/signal.c linux-2.6.17.7/kernel/signal.c
23187 --- linux-2.6.17.7/kernel/signal.c 2006-07-24 23:36:01.000000000 -0400
23188 +++ linux-2.6.17.7/kernel/signal.c 2006-08-01 20:29:48.000000000 -0400
23190 #include <linux/audit.h>
23191 #include <linux/capability.h>
23192 #include <linux/vs_pid.h>
23193 +#include <linux/grsecurity.h>
23194 #include <asm/param.h>
23195 #include <asm/uaccess.h>
23196 #include <asm/unistd.h>
23197 @@ -583,11 +583,11 @@ static int check_kill_permission(int sig
23198 (!is_si_special(info) && SI_FROMUSER(info)));
23201 - if (user && ((sig != SIGCONT) ||
23202 + if (user && ((((sig != SIGCONT) ||
23203 (current->signal->session != t->signal->session))
23204 && (current->euid ^ t->suid) && (current->euid ^ t->uid)
23205 && (current->uid ^ t->suid) && (current->uid ^ t->uid)
23206 - && !capable(CAP_KILL))
23207 + && !capable(CAP_KILL)) || gr_handle_signal(t, sig)))
23211 @@ -595,8 +595,10 @@ static int check_kill_permission(int sig
23214 error = security_task_kill(t, info, sig);
23217 audit_signal_info(sig, t); /* Let audit system see the signal */
23218 + gr_log_signal(sig, t);
23223 @@ -764,7 +767,7 @@ out_set:
23224 (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
23229 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
23232 @@ -809,6 +812,10 @@ force_sig_info(int sig, struct siginfo *
23234 recalc_sigpending_tsk(t);
23235 ret = specific_send_sig_info(sig, info, t);
23237 + gr_log_signal(sig, t);
23238 + gr_handle_crash(t, sig);
23240 spin_unlock_irqrestore(&t->sighand->siglock, flags);
23243 diff -urNp linux-2.6.17.7/kernel/sys.c linux-2.6.17.7/kernel/sys.c
23244 --- linux-2.6.17.7/kernel/sys.c 2006-07-24 23:36:01.000000000 -0400
23245 +++ linux-2.6.17.7/kernel/sys.c 2006-08-01 20:29:48.000000000 -0400
23247 #include <linux/cn_proc.h>
23248 #include <linux/vs_cvirt.h>
23249 #include <linux/vs_pid.h>
23250 +#include <linux/grsecurity.h>
23252 #include <linux/compat.h>
23253 #include <linux/syscalls.h>
23254 @@ -442,6 +443,12 @@ static int set_one_prio(struct task_stru
23259 + if (gr_handle_chroot_setpriority(p, niceval)) {
23264 no_nice = security_task_setnice(p, niceval);
23267 @@ -831,6 +838,9 @@ asmlinkage long sys_setregid(gid_t rgid,
23268 if (rgid != (gid_t) -1 ||
23269 (egid != (gid_t) -1 && egid != old_rgid))
23270 current->sgid = new_egid;
23272 + gr_set_role_label(current, current->uid, new_rgid);
23274 current->fsgid = new_egid;
23275 current->egid = new_egid;
23276 current->gid = new_rgid;
23277 @@ -860,6 +870,9 @@ asmlinkage long sys_setgid(gid_t gid)
23278 current->mm->dumpable = suid_dumpable;
23282 + gr_set_role_label(current, current->uid, gid);
23284 current->gid = current->egid = current->sgid = current->fsgid = gid;
23286 else if ((gid == current->gid) || (gid == current->sgid))
23287 @@ -901,6 +914,9 @@ static int set_user(uid_t new_ruid, int
23288 current->mm->dumpable = suid_dumpable;
23292 + gr_set_role_label(current, new_ruid, current->gid);
23294 current->uid = new_ruid;
23297 @@ -1004,6 +1020,9 @@ asmlinkage long sys_setuid(uid_t uid)
23298 } else if ((uid != current->uid) && (uid != new_suid))
23301 + if (gr_check_crash_uid(uid))
23304 if (old_euid != uid)
23306 current->mm->dumpable = suid_dumpable;
23307 @@ -1109,8 +1128,10 @@ asmlinkage long sys_setresgid(gid_t rgid
23308 current->egid = egid;
23310 current->fsgid = current->egid;
23311 - if (rgid != (gid_t) -1)
23312 + if (rgid != (gid_t) -1) {
23313 + gr_set_role_label(current, current->uid, rgid);
23314 current->gid = rgid;
23316 if (sgid != (gid_t) -1)
23317 current->sgid = sgid;
23319 diff -urNp linux-2.6.17.7/kernel/sysctl.c linux-2.6.17.7/kernel/sysctl.c
23320 --- linux-2.6.17.7/kernel/sysctl.c 2006-07-24 23:36:01.000000000 -0400
23321 +++ linux-2.6.17.7/kernel/sysctl.c 2006-08-01 20:29:48.000000000 -0400
23322 @@ -54,6 +54,14 @@ extern int proc_nr_files(ctl_table *tabl
23323 void __user *buffer, size_t *lenp, loff_t *ppos);
23325 #if defined(CONFIG_SYSCTL)
23326 +#include <linux/grsecurity.h>
23327 +#include <linux/grinternal.h>
23329 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
23330 + const void *newval);
23331 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
23333 +extern int gr_handle_chroot_sysctl(const int op);
23335 /* External variables not in a header file. */
23337 @@ -157,6 +165,22 @@ extern ctl_table inotify_table[];
23338 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
23339 int sysctl_legacy_va_layout;
23341 +extern ctl_table grsecurity_table[];
23343 +#ifdef CONFIG_PAX_SOFTMODE
23344 +static ctl_table pax_table[] = {
23346 + .ctl_name = PAX_SOFTMODE,
23347 + .procname = "softmode",
23348 + .data = &pax_softmode,
23349 + .maxlen = sizeof(unsigned int),
23351 + .proc_handler = &proc_dointvec,
23354 + { .ctl_name = 0 }
23358 /* /proc declarations: */
23360 @@ -683,6 +707,24 @@ static ctl_table kern_table[] = {
23361 .proc_handler = &proc_dointvec,
23365 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
23367 + .ctl_name = KERN_GRSECURITY,
23368 + .procname = "grsecurity",
23370 + .child = grsecurity_table,
23374 +#ifdef CONFIG_PAX_SOFTMODE
23376 + .ctl_name = KERN_PAX,
23377 + .procname = "pax",
23379 + .child = pax_table,
23385 @@ -1180,6 +1222,10 @@ static int test_perm(int mode, int op)
23386 static inline int ctl_perm(ctl_table *table, int op)
23389 + if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
23391 + if (gr_handle_chroot_sysctl(op))
23393 error = security_sysctl(table, op);
23396 @@ -1216,6 +1262,10 @@ repeat:
23397 table = table->child;
23401 + if (!gr_handle_sysctl(table, oldval, newval))
23404 error = do_sysctl_strategy(table, name, nlen,
23406 newval, newlen, context);
23407 diff -urNp linux-2.6.17.7/kernel/time.c linux-2.6.17.7/kernel/time.c
23408 --- linux-2.6.17.7/kernel/time.c 2006-07-24 23:36:01.000000000 -0400
23409 +++ linux-2.6.17.7/kernel/time.c 2006-08-01 20:29:48.000000000 -0400
23411 #include <linux/security.h>
23412 #include <linux/fs.h>
23413 #include <linux/module.h>
23414 +#include <linux/grsecurity.h>
23416 #include <asm/uaccess.h>
23417 #include <asm/unistd.h>
23418 @@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user
23421 vx_settimeofday(&tv);
23423 + gr_log_timechange();
23428 @@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct
23432 + gr_log_timechange();
23434 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
23437 diff -urNp linux-2.6.17.7/mm/filemap.c linux-2.6.17.7/mm/filemap.c
23438 --- linux-2.6.17.7/mm/filemap.c 2006-07-24 23:36:01.000000000 -0400
23439 +++ linux-2.6.17.7/mm/filemap.c 2006-08-01 20:29:48.000000000 -0400
23441 #include <linux/security.h>
23442 #include <linux/syscalls.h>
23443 #include <linux/cpuset.h>
23444 +#include <linux/grsecurity.h>
23445 #include "filemap.h"
23446 #include "internal.h"
23448 @@ -1650,7 +1651,13 @@ int generic_file_mmap(struct file * file
23449 struct address_space *mapping = file->f_mapping;
23451 if (!mapping->a_ops->readpage)
23455 +#ifdef CONFIG_PAX_PAGEEXEC
23456 + if (vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC)
23457 + vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
23460 file_accessed(file);
23461 vma->vm_ops = &generic_file_vm_ops;
23463 @@ -1872,6 +1879,7 @@ inline int generic_write_checks(struct f
23464 *pos = i_size_read(inode);
23466 if (limit != RLIM_INFINITY) {
23467 + gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
23468 if (*pos >= limit) {
23469 send_sig(SIGXFSZ, current, 0);
23471 diff -urNp linux-2.6.17.7/mm/madvise.c linux-2.6.17.7/mm/madvise.c
23472 --- linux-2.6.17.7/mm/madvise.c 2006-07-24 23:36:01.000000000 -0400
23473 +++ linux-2.6.17.7/mm/madvise.c 2006-08-01 20:29:48.000000000 -0400
23475 * We can potentially split a vm area into separate
23476 * areas, each area with its own behavior.
23479 +#ifdef CONFIG_PAX_SEGMEXEC
23480 +static long __madvise_behavior(struct vm_area_struct * vma,
23481 + struct vm_area_struct **prev,
23482 + unsigned long start, unsigned long end, int behavior);
23484 +static long madvise_behavior(struct vm_area_struct * vma,
23485 + struct vm_area_struct **prev,
23486 + unsigned long start, unsigned long end, int behavior)
23488 + if (vma->vm_flags & VM_MIRROR) {
23489 + struct vm_area_struct * vma_m, * prev_m;
23490 + unsigned long start_m, end_m;
23493 + start_m = vma->vm_start + vma->vm_mirror;
23494 + vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
23495 + if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
23496 + start_m = start + vma->vm_mirror;
23497 + end_m = end + vma->vm_mirror;
23498 + error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
23502 + printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
23507 + return __madvise_behavior(vma, prev, start, end, behavior);
23510 +static long __madvise_behavior(struct vm_area_struct * vma,
23511 + struct vm_area_struct **prev,
23512 + unsigned long start, unsigned long end, int behavior)
23514 static long madvise_behavior(struct vm_area_struct * vma,
23515 struct vm_area_struct **prev,
23516 unsigned long start, unsigned long end, int behavior)
23519 struct mm_struct * mm = vma->vm_mm;
23521 diff -urNp linux-2.6.17.7/mm/memory.c linux-2.6.17.7/mm/memory.c
23522 --- linux-2.6.17.7/mm/memory.c 2006-07-24 23:36:01.000000000 -0400
23523 +++ linux-2.6.17.7/mm/memory.c 2006-08-01 20:29:48.000000000 -0400
23525 #include <linux/rmap.h>
23526 #include <linux/module.h>
23527 #include <linux/init.h>
23528 +#include <linux/grsecurity.h>
23530 #include <asm/pgalloc.h>
23531 #include <asm/uaccess.h>
23532 @@ -320,6 +321,11 @@ int __pte_alloc(struct mm_struct *mm, pm
23534 int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
23537 +#ifdef CONFIG_PAX_KERNEXEC
23538 + unsigned long cr0;
23541 pte_t *new = pte_alloc_one_kernel(&init_mm, address);
23544 @@ -327,8 +333,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
23545 spin_lock(&init_mm.page_table_lock);
23546 if (pmd_present(*pmd)) /* Another has populated it */
23547 pte_free_kernel(new);
23551 +#ifdef CONFIG_PAX_KERNEXEC
23552 + pax_open_kernel(cr0);
23555 pmd_populate_kernel(&init_mm, pmd, new);
23557 +#ifdef CONFIG_PAX_KERNEXEC
23558 + pax_close_kernel(cr0);
23562 spin_unlock(&init_mm.page_table_lock);
23565 @@ -1421,6 +1438,88 @@ static inline void cow_user_page(struct
23566 copy_user_highpage(dst, src, va);
23569 +#ifdef CONFIG_PAX_SEGMEXEC
23570 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
23572 + * the ptl of the lower mapped page is held on entry and is not released on exit
23573 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
23575 +static void pax_mirror_fault(struct vm_area_struct *vma, unsigned long address, pte_t *pte)
23577 + struct mm_struct *mm = vma->vm_mm;
23578 + unsigned long address_m, pfn_m;
23579 + struct vm_area_struct * vma_m = NULL;
23580 + pte_t * pte_m, entry_m;
23581 + struct page * page_m = NULL;
23583 + address_m = vma->vm_start + vma->vm_mirror;
23584 + vma_m = find_vma(mm, address_m);
23585 + BUG_ON(!vma_m || vma_m->vm_start != address_m);
23587 + address_m = address + vma->vm_mirror;
23588 + pte_m = pte_offset_map_nested(pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m), address_m);
23590 + if (pte_same(*pte, *pte_m)) {
23591 + pte_unmap_nested(pte_m);
23595 + pfn_m = pte_pfn(*pte);
23596 + if (pte_present(*pte_m)) {
23597 + page_m = vm_normal_page(vma_m, address_m, *pte_m);
23599 + flush_cache_page(vma_m, address_m, pfn_m);
23600 + flush_icache_page(vma_m, page_m);
23604 + if (pte_present(*pte_m))
23605 + entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
23607 + entry_m = ptep_get_and_clear(mm, address_m, pte_m);
23609 + if (pte_none(entry_m)) {
23610 + } else if (pte_present(entry_m)) {
23612 + page_remove_rmap(page_m);
23613 + if (PageAnon(page_m))
23614 + dec_mm_counter(mm, anon_rss);
23616 + dec_mm_counter(mm, file_rss);
23617 + page_cache_release(page_m);
23619 + } else if (!pte_file(entry_m)) {
23620 + free_swap_and_cache(pte_to_swp_entry(entry_m));
23622 + printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
23623 + address, vma->vm_start, address_m, vma_m->vm_start);
23626 + page_m = vm_normal_page(vma, address, *pte);
23627 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
23628 + if (pte_write(*pte))
23629 + entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
23631 + page_cache_get(page_m);
23633 + * we can test PAGE_MAPPING_ANON without holding page_map_lock because
23634 + * we hold the page table lock and have a reference to page_m
23636 + if (PageAnon(page_m)) {
23637 + page_add_anon_rmap(page_m, vma_m, address_m);
23638 + inc_mm_counter(mm, anon_rss);
23640 + page_add_file_rmap(page_m);
23641 + inc_mm_counter(mm, file_rss);
23644 + set_pte_at(mm, address_m, pte_m, entry_m);
23645 + update_mmu_cache(vma_m, address_m, entry_m);
23646 + lazy_mmu_prot_update(entry_m);
23647 + pte_unmap_nested(pte_m);
23652 * This routine handles present pages, when users try to write
23653 * to a shared page. It is done by copying the page to a new address
23654 @@ -1511,6 +1610,12 @@ gotten:
23655 /* Free the old page.. */
23656 new_page = old_page;
23657 ret |= VM_FAULT_WRITE;
23659 +#ifdef CONFIG_PAX_SEGMEXEC
23660 + if (vma->vm_flags & VM_MIRROR)
23661 + pax_mirror_fault(vma, address, page_table);
23666 page_cache_release(new_page);
23667 @@ -1761,6 +1866,7 @@ int vmtruncate(struct inode * inode, lof
23670 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
23671 + gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
23672 if (limit != RLIM_INFINITY && offset > limit)
23674 if (offset > inode->i_sb->s_maxbytes)
23675 @@ -1950,6 +2056,12 @@ again:
23676 /* No need to invalidate - it was non-present before */
23677 update_mmu_cache(vma, address, pte);
23678 lazy_mmu_prot_update(pte);
23680 +#ifdef CONFIG_PAX_SEGMEXEC
23681 + if (vma->vm_flags & VM_MIRROR)
23682 + pax_mirror_fault(vma, address, page_table);
23686 pte_unmap_unlock(page_table, ptl);
23688 @@ -2012,6 +2124,12 @@ static int do_anonymous_page(struct mm_s
23689 /* No need to invalidate - it was non-present before */
23690 update_mmu_cache(vma, address, entry);
23691 lazy_mmu_prot_update(entry);
23693 +#ifdef CONFIG_PAX_SEGMEXEC
23694 + if (vma->vm_flags & VM_MIRROR)
23695 + pax_mirror_fault(vma, address, page_table);
23699 pte_unmap_unlock(page_table, ptl);
23700 return VM_FAULT_MINOR;
23701 @@ -2137,6 +2255,12 @@ retry:
23702 /* no need to invalidate: a not-present page shouldn't be cached */
23703 update_mmu_cache(vma, address, entry);
23704 lazy_mmu_prot_update(entry);
23706 +#ifdef CONFIG_PAX_SEGMEXEC
23707 + if (vma->vm_flags & VM_MIRROR)
23708 + pax_mirror_fault(vma, address, page_table);
23712 pte_unmap_unlock(page_table, ptl);
23714 @@ -2246,6 +2370,12 @@ static inline int handle_pte_fault(struc
23715 flush_tlb_page(vma, address);
23719 +#ifdef CONFIG_PAX_SEGMEXEC
23720 + if (vma->vm_flags & VM_MIRROR)
23721 + pax_mirror_fault(vma, address, pte);
23724 pte_unmap_unlock(pte, ptl);
23725 return VM_FAULT_MINOR;
23727 @@ -2268,6 +2398,49 @@ int __handle_mm_fault(struct mm_struct *
23728 if (unlikely(is_vm_hugetlb_page(vma)))
23729 return hugetlb_fault(mm, vma, address, write_access);
23731 +#ifdef CONFIG_PAX_SEGMEXEC
23732 + if (vma->vm_flags & VM_MIRROR) {
23733 + unsigned long address_m;
23734 + struct vm_area_struct * vma_m;
23739 + address_m = vma->vm_start + vma->vm_mirror;
23740 + vma_m = find_vma(mm, address_m);
23742 + /* PaX: sanity checks */
23744 + printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
23745 + address, vma, address_m, vma_m);
23746 + return VM_FAULT_SIGBUS;
23747 + } else if (!(vma_m->vm_flags & VM_MIRROR) ||
23748 + vma_m->vm_start != address_m ||
23749 + vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
23751 + printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
23752 + address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
23753 + return VM_FAULT_SIGBUS;
23756 + if (address_m < address) {
23757 + address += vma->vm_mirror;
23761 + address_m = address + vma->vm_mirror;
23762 + pgd_m = pgd_offset(mm, address_m);
23763 + pud_m = pud_alloc(mm, pgd_m, address_m);
23765 + return VM_FAULT_OOM;
23766 + pmd_m = pmd_alloc(mm, pud_m, address_m);
23768 + return VM_FAULT_OOM;
23769 + if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
23770 + return VM_FAULT_OOM;
23774 pgd = pgd_offset(mm, address);
23775 pud = pud_alloc(mm, pgd, address);
23777 diff -urNp linux-2.6.17.7/mm/mempolicy.c linux-2.6.17.7/mm/mempolicy.c
23778 --- linux-2.6.17.7/mm/mempolicy.c 2006-07-24 23:36:01.000000000 -0400
23779 +++ linux-2.6.17.7/mm/mempolicy.c 2006-08-01 20:29:48.000000000 -0400
23780 @@ -346,6 +346,12 @@ check_range(struct mm_struct *mm, unsign
23781 if (prev && prev->vm_end < vma->vm_start)
23782 return ERR_PTR(-EFAULT);
23785 +#ifdef CONFIG_PAX_SEGMEXEC
23786 + if (vma->vm_flags & VM_MIRROR)
23787 + return ERR_PTR(-EFAULT);
23790 if (!is_vm_hugetlb_page(vma) &&
23791 ((flags & MPOL_MF_STRICT) ||
23792 ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
23793 diff -urNp linux-2.6.17.7/mm/mlock.c linux-2.6.17.7/mm/mlock.c
23794 --- linux-2.6.17.7/mm/mlock.c 2006-07-24 23:36:01.000000000 -0400
23795 +++ linux-2.6.17.7/mm/mlock.c 2006-08-01 20:29:48.000000000 -0400
23796 @@ -10,14 +10,85 @@
23797 #include <linux/mempolicy.h>
23798 #include <linux/syscalls.h>
23799 #include <linux/vs_memory.h>
23800 +#include <linux/grsecurity.h>
23802 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
23803 + unsigned long start, unsigned long end, unsigned int newflags);
23805 static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
23806 unsigned long start, unsigned long end, unsigned int newflags)
23808 struct mm_struct * mm = vma->vm_mm;
23813 +#ifdef CONFIG_PAX_SEGMEXEC
23814 + struct vm_area_struct * vma_m = NULL, *prev_m;
23815 + unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
23817 + if (vma->vm_flags & VM_MIRROR) {
23818 + start_m = vma->vm_start + vma->vm_mirror;
23819 + vma_m = find_vma_prev(mm, start_m, &prev_m);
23820 + if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
23821 + printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
23825 + start_m = start + vma->vm_mirror;
23826 + end_m = end + vma->vm_mirror;
23827 + if (newflags & VM_LOCKED)
23828 + newflags_m = vma_m->vm_flags | VM_LOCKED;
23830 + newflags_m = vma_m->vm_flags & ~VM_LOCKED;
23831 + ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
23837 + ret = __mlock_fixup(vma, prev, start, end, newflags);
23842 + * vm_flags is protected by the mmap_sem held in write mode.
23843 + * It's okay if try_to_unmap_one unmaps a page just after we
23844 + * set VM_LOCKED, make_pages_present below will bring it back.
23846 + vma->vm_flags = newflags;
23848 +#ifdef CONFIG_PAX_SEGMEXEC
23849 + if (vma->vm_flags & VM_MIRROR)
23850 + vma_m->vm_flags = newflags_m;
23854 + * Keep track of amount of locked VM.
23856 + pages = (end - start) >> PAGE_SHIFT;
23857 + if (newflags & VM_LOCKED) {
23859 + if (!(newflags & VM_IO))
23860 + ret = make_pages_present(start, end);
23863 + mm->locked_vm -= pages;
23865 +#ifdef CONFIG_PAX_SEGMEXEC
23866 + if (vma->vm_flags & VM_MIRROR)
23867 + mm->locked_vm -= pages;
23870 + if (ret == -ENOMEM)
23875 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
23876 + unsigned long start, unsigned long end, unsigned int newflags)
23878 + struct mm_struct * mm = vma->vm_mm;
23882 if (newflags == vma->vm_flags) {
23883 @@ -30,7 +101,7 @@ static int mlock_fixup(struct vm_area_st
23884 vma->vm_file, pgoff, vma_policy(vma));
23892 @@ -41,31 +112,9 @@ static int mlock_fixup(struct vm_area_st
23896 - if (end != vma->vm_end) {
23897 + if (end != vma->vm_end)
23898 ret = split_vma(mm, vma, end, 0);
23905 - * vm_flags is protected by the mmap_sem held in write mode.
23906 - * It's okay if try_to_unmap_one unmaps a page just after we
23907 - * set VM_LOCKED, make_pages_present below will bring it back.
23909 - vma->vm_flags = newflags;
23912 - * Keep track of amount of locked VM.
23914 - pages = (end - start) >> PAGE_SHIFT;
23915 - if (newflags & VM_LOCKED) {
23917 - if (!(newflags & VM_IO))
23918 - ret = make_pages_present(start, end);
23921 - vx_vmlocked_sub(vma->vm_mm, pages);
23923 if (ret == -ENOMEM)
23925 @@ -84,6 +133,17 @@ static int do_mlock(unsigned long start,
23930 +#ifdef CONFIG_PAX_SEGMEXEC
23931 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
23932 + if (end > SEGMEXEC_TASK_SIZE)
23937 + if (end > TASK_SIZE)
23940 vma = find_vma_prev(current->mm, start, &prev);
23941 if (!vma || vma->vm_start > start)
23943 @@ -141,6 +201,7 @@ asmlinkage long sys_mlock(unsigned long
23944 lock_limit >>= PAGE_SHIFT;
23946 /* check against resource limits */
23947 + gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
23948 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
23949 error = do_mlock(start, len, 1);
23951 @@ -173,6 +234,16 @@ static int do_mlockall(int flags)
23952 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
23953 unsigned int newflags;
23955 +#ifdef CONFIG_PAX_SEGMEXEC
23956 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
23957 + if (vma->vm_end > SEGMEXEC_TASK_SIZE)
23962 + if (vma->vm_end > TASK_SIZE)
23965 newflags = vma->vm_flags | VM_LOCKED;
23966 if (!(flags & MCL_CURRENT))
23967 newflags &= ~VM_LOCKED;
23968 @@ -202,6 +273,7 @@ asmlinkage long sys_mlockall(int flags)
23970 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
23972 + gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
23973 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
23974 capable(CAP_IPC_LOCK))
23975 ret = do_mlockall(flags);
23976 diff -urNp linux-2.6.17.7/mm/mmap.c linux-2.6.17.7/mm/mmap.c
23977 --- linux-2.6.17.7/mm/mmap.c 2006-07-24 23:36:01.000000000 -0400
23978 +++ linux-2.6.17.7/mm/mmap.c 2006-08-01 20:29:48.000000000 -0400
23980 #include <linux/mount.h>
23981 #include <linux/mempolicy.h>
23982 #include <linux/rmap.h>
23983 +#include <linux/grsecurity.h>
23985 #include <asm/uaccess.h>
23986 #include <asm/cacheflush.h>
23987 @@ -60,6 +61,8 @@ pgprot_t protection_map[16] = {
23988 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
23991 +EXPORT_SYMBOL(protection_map);
23993 int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
23994 int sysctl_overcommit_ratio = 50; /* default is 50% */
23995 int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
23996 @@ -240,6 +243,7 @@ asmlinkage unsigned long sys_brk(unsigne
23997 * not page aligned -Ram Gupta
23999 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
24000 + gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
24001 if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
24004 @@ -628,11 +632,17 @@ again: remove_next = 1 + (end > next->
24005 * If the vma has a ->close operation then the driver probably needs to release
24006 * per-vma resources, so we don't attempt to merge those.
24008 +#ifdef CONFIG_PAX_SEGMEXEC
24009 +#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
24011 #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
24014 static inline int is_mergeable_vma(struct vm_area_struct *vma,
24015 struct file *file, unsigned long vm_flags)
24017 + if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
24019 if (vma->vm_flags != vm_flags)
24021 if (vma->vm_file != file)
24022 @@ -857,14 +867,11 @@ none:
24023 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
24024 struct file *file, long pages)
24026 - const unsigned long stack_flags
24027 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
24030 mm->shared_vm += pages;
24031 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
24032 mm->exec_vm += pages;
24033 - } else if (flags & stack_flags)
24034 + } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
24035 mm->stack_vm += pages;
24036 if (flags & (VM_RESERVED|VM_IO))
24037 mm->reserved_vm += pages;
24038 @@ -875,10 +882,55 @@ void vm_stat_account(struct mm_struct *m
24039 * The caller must hold down_write(current->mm->mmap_sem).
24042 +#ifdef CONFIG_PAX_SEGMEXEC
24043 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
24044 + unsigned long len, unsigned long prot,
24045 + unsigned long flags, unsigned long pgoff);
24047 unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
24048 unsigned long len, unsigned long prot,
24049 unsigned long flags, unsigned long pgoff)
24051 + unsigned long ret = -EINVAL;
24053 + if (flags & MAP_MIRROR)
24056 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
24057 + (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
24060 + ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
24062 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
24064 +#ifdef CONFIG_PAX_MPROTECT
24065 + && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
24070 + unsigned long ret_m;
24071 + prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
24072 + ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
24073 + if (ret_m >= TASK_SIZE) {
24074 + do_munmap(current->mm, ret, len);
24082 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
24083 + unsigned long len, unsigned long prot,
24084 + unsigned long flags, unsigned long pgoff)
24086 +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
24087 + unsigned long len, unsigned long prot,
24088 + unsigned long flags, unsigned long pgoff)
24091 struct mm_struct * mm = current->mm;
24092 struct vm_area_struct * vma, * prev;
24093 struct inode *inode;
24094 @@ -889,6 +941,28 @@ unsigned long do_mmap_pgoff(struct file
24095 int accountable = 1;
24096 unsigned long charged = 0, reqprot = prot;
24098 +#ifdef CONFIG_PAX_SEGMEXEC
24099 + struct vm_area_struct * vma_m = NULL;
24101 + if (flags & MAP_MIRROR) {
24102 + /* PaX: sanity checks, to be removed when proved to be stable */
24103 + if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
24106 + vma_m = find_vma(mm, pgoff);
24108 + if (!vma_m || is_vm_hugetlb_page(vma_m) ||
24109 + vma_m->vm_start != pgoff ||
24110 + (vma_m->vm_flags & VM_SPECIAL) ||
24111 + (prot & PROT_WRITE))
24114 + file = vma_m->vm_file;
24115 + pgoff = vma_m->vm_pgoff;
24116 + len = vma_m->vm_end - vma_m->vm_start;
24121 if (is_file_hugepages(file))
24123 @@ -929,7 +1003,7 @@ unsigned long do_mmap_pgoff(struct file
24124 /* Obtain the address to map to. we verify (or select) it and ensure
24125 * that it represents a valid section of the address space.
24127 - addr = get_unmapped_area(file, addr, len, pgoff, flags);
24128 + addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
24129 if (addr & ~PAGE_MASK)
24132 @@ -940,6 +1014,24 @@ unsigned long do_mmap_pgoff(struct file
24133 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
24134 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
24136 + if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
24137 + vm_flags &= ~VM_MAYEXEC;
24139 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
24140 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
24142 +#ifdef CONFIG_PAX_MPROTECT
24143 + if (mm->pax_flags & MF_PAX_MPROTECT) {
24144 + if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
24145 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
24147 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
24154 if (flags & MAP_LOCKED) {
24155 if (!can_do_mlock())
24157 @@ -952,6 +1044,7 @@ unsigned long do_mmap_pgoff(struct file
24158 locked += mm->locked_vm;
24159 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
24160 lock_limit >>= PAGE_SHIFT;
24161 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
24162 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
24165 @@ -999,6 +1092,11 @@ unsigned long do_mmap_pgoff(struct file
24167 * Set pgoff according to addr for anon_vma.
24170 +#ifdef CONFIG_PAX_SEGMEXEC
24171 + if (!(flags & MAP_MIRROR))
24174 pgoff = addr >> PAGE_SHIFT;
24177 @@ -1010,14 +1108,17 @@ unsigned long do_mmap_pgoff(struct file
24181 + if (!gr_acl_handle_mmap(file, prot))
24184 /* Clear old maps */
24187 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24188 if (vma && vma->vm_start < addr + len) {
24189 if (do_munmap(mm, addr, len))
24191 - goto munmap_back;
24192 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24193 + BUG_ON(vma && vma->vm_start < addr + len);
24196 /* Check against address space limit. */
24197 @@ -1065,6 +1166,13 @@ munmap_back:
24198 vma->vm_start = addr;
24199 vma->vm_end = addr + len;
24200 vma->vm_flags = vm_flags;
24202 +#ifdef CONFIG_PAX_PAGEEXEC
24203 + if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
24204 + vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
24208 vma->vm_page_prot = protection_map[vm_flags & 0x0f];
24209 vma->vm_pgoff = pgoff;
24211 @@ -1089,6 +1197,14 @@ munmap_back:
24215 +#ifdef CONFIG_PAX_SEGMEXEC
24216 + if (flags & MAP_MIRROR) {
24217 + vma_m->vm_flags |= VM_MIRROR;
24218 + vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
24219 + vma->vm_mirror = vma_m->vm_start - vma->vm_start;
24223 /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
24224 * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
24225 * that memory reservation must be checked; but that reservation
24226 @@ -1124,6 +1240,7 @@ munmap_back:
24228 mm->total_vm += len >> PAGE_SHIFT;
24229 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
24230 + track_exec_limit(mm, addr, addr + len, vm_flags);
24231 if (vm_flags & VM_LOCKED) {
24232 mm->locked_vm += len >> PAGE_SHIFT;
24233 make_pages_present(addr, addr + len);
24234 @@ -1178,6 +1295,10 @@ arch_get_unmapped_area(struct file *filp
24235 if (len > TASK_SIZE)
24238 +#ifdef CONFIG_PAX_RANDMMAP
24239 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
24243 addr = PAGE_ALIGN(addr);
24244 vma = find_vma(mm, addr);
24245 @@ -1188,7 +1309,7 @@ arch_get_unmapped_area(struct file *filp
24246 if (len > mm->cached_hole_size) {
24247 start_addr = addr = mm->free_area_cache;
24249 - start_addr = addr = TASK_UNMAPPED_BASE;
24250 + start_addr = addr = mm->mmap_base;
24251 mm->cached_hole_size = 0;
24254 @@ -1200,9 +1321,8 @@ full_search:
24255 * Start a new search - just in case we missed
24258 - if (start_addr != TASK_UNMAPPED_BASE) {
24259 - addr = TASK_UNMAPPED_BASE;
24260 - start_addr = addr;
24261 + if (start_addr != mm->mmap_base) {
24262 + start_addr = addr = mm->mmap_base;
24263 mm->cached_hole_size = 0;
24266 @@ -1227,7 +1347,7 @@ void arch_unmap_area(struct mm_struct *m
24268 * Is this a new hole at the lowest possible address?
24270 - if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
24271 + if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
24272 mm->free_area_cache = addr;
24273 mm->cached_hole_size = ~0UL;
24275 @@ -1245,12 +1365,16 @@ arch_get_unmapped_area_topdown(struct fi
24277 struct vm_area_struct *vma;
24278 struct mm_struct *mm = current->mm;
24279 - unsigned long addr = addr0;
24280 + unsigned long base = mm->mmap_base, addr = addr0;
24282 /* requested length too big for entire address space */
24283 if (len > TASK_SIZE)
24286 +#ifdef CONFIG_PAX_RANDMMAP
24287 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
24290 /* requesting a specific address */
24292 addr = PAGE_ALIGN(addr);
24293 @@ -1308,13 +1432,21 @@ bottomup:
24294 * can happen with large stack limits and large mmap()
24297 + mm->mmap_base = TASK_UNMAPPED_BASE;
24299 +#ifdef CONFIG_PAX_RANDMMAP
24300 + if (mm->pax_flags & MF_PAX_RANDMMAP)
24301 + mm->mmap_base += mm->delta_mmap;
24304 + mm->free_area_cache = mm->mmap_base;
24305 mm->cached_hole_size = ~0UL;
24306 - mm->free_area_cache = TASK_UNMAPPED_BASE;
24307 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
24309 * Restore the topdown base:
24311 - mm->free_area_cache = mm->mmap_base;
24312 + mm->mmap_base = base;
24313 + mm->free_area_cache = base;
24314 mm->cached_hole_size = ~0UL;
24317 @@ -1330,8 +1462,10 @@ void arch_unmap_area_topdown(struct mm_s
24318 mm->free_area_cache = addr;
24320 /* dont allow allocations above current base */
24321 - if (mm->free_area_cache > mm->mmap_base)
24322 + if (mm->free_area_cache > mm->mmap_base) {
24323 mm->free_area_cache = mm->mmap_base;
24324 + mm->cached_hole_size = ~0UL;
24329 @@ -1464,6 +1598,7 @@ static int acct_stack_growth(struct vm_a
24332 /* Stack limit test */
24333 + gr_learn_resource(current, RLIMIT_STACK, size, 1);
24334 if (size > rlim[RLIMIT_STACK].rlim_cur)
24337 @@ -1473,6 +1608,7 @@ static int acct_stack_growth(struct vm_a
24338 unsigned long limit;
24339 locked = mm->locked_vm + grow;
24340 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
24341 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
24342 if (locked > limit && !capable(CAP_IPC_LOCK))
24345 @@ -1590,13 +1726,49 @@ int expand_stack(struct vm_area_struct *
24346 if (address < vma->vm_start) {
24347 unsigned long size, grow;
24349 +#ifdef CONFIG_PAX_SEGMEXEC
24350 + struct vm_area_struct *vma_m = NULL;
24351 + unsigned long address_m = 0UL;
24353 + if (vma->vm_flags & VM_MIRROR) {
24354 + address_m = vma->vm_start + vma->vm_mirror;
24355 + vma_m = find_vma(vma->vm_mm, address_m);
24356 + if (!vma_m || vma_m->vm_start != address_m ||
24357 + !(vma_m->vm_flags & VM_MIRROR) ||
24358 + vma->vm_end - vma->vm_start !=
24359 + vma_m->vm_end - vma_m->vm_start ||
24360 + vma->anon_vma != vma_m->anon_vma) {
24361 + printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
24362 + address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
24363 + anon_vma_unlock(vma);
24366 + address_m = address + vma->vm_mirror;
24370 size = vma->vm_end - address;
24371 grow = (vma->vm_start - address) >> PAGE_SHIFT;
24373 +#ifdef CONFIG_PAX_SEGMEXEC
24375 + error = acct_stack_growth(vma, size, 2*grow);
24379 error = acct_stack_growth(vma, size, grow);
24381 vma->vm_start = address;
24382 vma->vm_pgoff -= grow;
24383 + track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
24385 +#ifdef CONFIG_PAX_SEGMEXEC
24387 + vma_m->vm_start = address_m;
24388 + vma_m->vm_pgoff -= grow;
24394 anon_vma_unlock(vma);
24395 @@ -1758,7 +1930,24 @@ int split_vma(struct mm_struct * mm, str
24396 * work. This now handles partial unmappings.
24397 * Jeremy Fitzhardinge <jeremy@goop.org>
24399 +#ifdef CONFIG_PAX_SEGMEXEC
24400 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
24402 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
24404 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
24405 + int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
24410 + return __do_munmap(mm, start, len);
24413 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
24415 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
24419 struct vm_area_struct *vma, *prev, *last;
24420 @@ -1812,6 +2001,8 @@ int do_munmap(struct mm_struct *mm, unsi
24421 /* Fix up all other VM information */
24422 remove_vma_list(mm, vma);
24424 + track_exec_limit(mm, start, end, 0UL);
24429 @@ -1824,6 +2015,12 @@ asmlinkage long sys_munmap(unsigned long
24431 profile_munmap(addr);
24433 +#ifdef CONFIG_PAX_SEGMEXEC
24434 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
24435 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
24439 down_write(&mm->mmap_sem);
24440 ret = do_munmap(mm, addr, len);
24441 up_write(&mm->mmap_sem);
24442 @@ -1845,11 +2042,35 @@ static inline void verify_mm_writelocked
24443 * anonymous maps. eventually we may be able to do some
24444 * brk-specific accounting here.
24446 +#ifdef CONFIG_PAX_SEGMEXEC
24447 +static unsigned long __do_brk(unsigned long addr, unsigned long len);
24449 unsigned long do_brk(unsigned long addr, unsigned long len)
24451 + unsigned long ret;
24453 + ret = __do_brk(addr, len);
24454 + if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
24455 + unsigned long ret_m;
24457 + ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
24458 + if (ret_m > TASK_SIZE) {
24459 + do_munmap(current->mm, addr, len);
24467 +static unsigned long __do_brk(unsigned long addr, unsigned long len)
24469 +unsigned long do_brk(unsigned long addr, unsigned long len)
24472 struct mm_struct * mm = current->mm;
24473 struct vm_area_struct * vma, * prev;
24474 - unsigned long flags;
24475 + unsigned long flags, task_size = TASK_SIZE;
24476 struct rb_node ** rb_link, * rb_parent;
24477 pgoff_t pgoff = addr >> PAGE_SHIFT;
24479 @@ -1857,7 +2078,12 @@ unsigned long do_brk(unsigned long addr,
24483 - if ((addr + len) > TASK_SIZE || (addr + len) < addr)
24484 +#ifdef CONFIG_PAX_SEGMEXEC
24485 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
24486 + task_size = SEGMEXEC_TASK_SIZE;
24489 + if ((addr + len) > task_size || (addr + len) < addr)
24493 @@ -1869,6 +2095,7 @@ unsigned long do_brk(unsigned long addr,
24494 locked += mm->locked_vm;
24495 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
24496 lock_limit >>= PAGE_SHIFT;
24497 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
24498 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
24501 @@ -1882,12 +2109,12 @@ unsigned long do_brk(unsigned long addr,
24503 * Clear old maps. this also does some error checking for us
24506 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24507 if (vma && vma->vm_start < addr + len) {
24508 if (do_munmap(mm, addr, len))
24510 - goto munmap_back;
24511 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24512 + BUG_ON(vma && vma->vm_start < addr + len);
24515 /* Check against address space limits *after* clearing old maps... */
24516 @@ -1902,6 +2129,18 @@ unsigned long do_brk(unsigned long addr,
24518 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
24520 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
24521 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
24522 + flags &= ~VM_EXEC;
24524 +#ifdef CONFIG_PAX_MPROTECT
24525 + if (mm->pax_flags & MF_PAX_MPROTECT)
24526 + flags &= ~VM_MAYEXEC;
24532 /* Can we just expand an old private anonymous mapping? */
24533 if (vma_merge(mm, prev, addr, addr + len, flags,
24534 NULL, NULL, pgoff, NULL))
24535 @@ -1921,6 +2160,13 @@ unsigned long do_brk(unsigned long addr,
24536 vma->vm_end = addr + len;
24537 vma->vm_pgoff = pgoff;
24538 vma->vm_flags = flags;
24540 +#ifdef CONFIG_PAX_PAGEEXEC
24541 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
24542 + vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
24546 vma->vm_page_prot = protection_map[flags & 0x0f];
24547 vma_link(mm, vma, prev, rb_link, rb_parent);
24549 @@ -1929,6 +2175,7 @@ out:
24550 mm->locked_vm += len >> PAGE_SHIFT;
24551 make_pages_present(addr, addr + len);
24553 + track_exec_limit(mm, addr, addr + len, flags);
24557 @@ -2061,7 +2308,7 @@ int may_expand_vm(struct mm_struct *mm,
24560 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
24562 + gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
24563 if (cur + npages > lim)
24566 diff -urNp linux-2.6.17.7/mm/mprotect.c linux-2.6.17.7/mm/mprotect.c
24567 --- linux-2.6.17.7/mm/mprotect.c 2006-07-24 23:36:01.000000000 -0400
24568 +++ linux-2.6.17.7/mm/mprotect.c 2006-08-01 20:29:48.000000000 -0400
24569 @@ -19,11 +19,18 @@
24570 #include <linux/mempolicy.h>
24571 #include <linux/personality.h>
24572 #include <linux/syscalls.h>
24573 +#include <linux/grsecurity.h>
24575 +#ifdef CONFIG_PAX_MPROTECT
24576 +#include <linux/elf.h>
24577 +#include <linux/fs.h>
24580 #include <asm/uaccess.h>
24581 #include <asm/pgtable.h>
24582 #include <asm/cacheflush.h>
24583 #include <asm/tlbflush.h>
24584 +#include <asm/mmu_context.h>
24586 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
24587 unsigned long addr, unsigned long end, pgprot_t newprot)
24588 @@ -98,6 +105,94 @@ static void change_protection(struct vm_
24589 flush_tlb_range(vma, start, end);
24592 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
24593 +/* called while holding the mmap semaphor for writing */
24594 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
24596 + struct vm_area_struct *vma = find_vma(mm, start);
24598 + for (; vma && vma->vm_start < end; vma = vma->vm_next)
24599 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
24603 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
24605 + unsigned long oldlimit, newlimit = 0UL;
24607 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
24610 + spin_lock(&mm->page_table_lock);
24611 + oldlimit = mm->context.user_cs_limit;
24612 + if ((prot & VM_EXEC) && oldlimit < end)
24613 + /* USER_CS limit moved up */
24615 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
24616 + /* USER_CS limit moved down */
24617 + newlimit = start;
24620 + mm->context.user_cs_limit = newlimit;
24624 + cpus_clear(mm->context.cpu_user_cs_mask);
24625 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
24628 + set_user_cs(mm, smp_processor_id());
24630 + spin_unlock(&mm->page_table_lock);
24631 + if (newlimit == end)
24632 + establish_user_cs_limit(mm, oldlimit, end);
24636 +#ifdef CONFIG_PAX_SEGMEXEC
24637 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24638 + unsigned long start, unsigned long end, unsigned int newflags);
24640 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24641 + unsigned long start, unsigned long end, unsigned int newflags)
24643 + if (vma->vm_flags & VM_MIRROR) {
24644 + struct vm_area_struct * vma_m, * prev_m;
24645 + unsigned long start_m, end_m;
24648 + start_m = vma->vm_start + vma->vm_mirror;
24649 + vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
24650 + if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
24651 + start_m = start + vma->vm_mirror;
24652 + end_m = end + vma->vm_mirror;
24654 + if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
24655 + error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
24657 + error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
24661 + printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
24666 + return __mprotect_fixup(vma, pprev, start, end, newflags);
24669 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24670 + unsigned long start, unsigned long end, unsigned int newflags)
24672 + struct mm_struct * mm = vma->vm_mm;
24673 + unsigned long oldflags = vma->vm_flags;
24674 + long nrpages = (end - start) >> PAGE_SHIFT;
24675 + unsigned long charged = 0;
24676 + pgprot_t newprot;
24681 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24682 unsigned long start, unsigned long end, unsigned long newflags)
24683 @@ -114,6 +209,7 @@ mprotect_fixup(struct vm_area_struct *vm
24690 * If we make a private mapping writable we increase our commit;
24691 @@ -132,6 +228,12 @@ mprotect_fixup(struct vm_area_struct *vm
24695 +#ifdef CONFIG_PAX_PAGEEXEC
24696 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
24697 + newprot = protection_map[(newflags | VM_EXEC) & 0xf];
24701 newprot = protection_map[newflags & 0xf];
24704 @@ -179,6 +281,69 @@ fail:
24708 +#ifdef CONFIG_PAX_MPROTECT
24709 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
24710 + * therefore we'll grant them VM_MAYWRITE once during their life.
24712 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
24713 + * basis because we want to allow the common case and not the special ones.
24715 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
24717 + struct elfhdr elf_h;
24718 + struct elf_phdr elf_p, p_dyn;
24720 + unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
24722 +#ifndef CONFIG_PAX_NOELFRELOCS
24723 + if ((vma->vm_start != start) ||
24725 + !(vma->vm_flags & VM_MAYEXEC) ||
24726 + (vma->vm_flags & VM_MAYNOTWRITE))
24731 + if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
24732 + memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
24734 +#ifdef CONFIG_PAX_ETEXECRELOCS
24735 + (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
24737 + elf_h.e_type != ET_DYN ||
24740 + !elf_check_arch(&elf_h) ||
24741 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
24742 + elf_h.e_phnum > j)
24745 + for (i = 0UL; i < elf_h.e_phnum; i++) {
24746 + if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
24748 + if (elf_p.p_type == PT_DYNAMIC) {
24753 + if (elf_h.e_phnum <= j)
24758 + if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
24760 + if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
24761 + vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
24762 + gr_log_textrel(vma);
24766 + } while (dyn.d_tag != DT_NULL);
24772 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
24774 @@ -198,6 +363,17 @@ sys_mprotect(unsigned long start, size_t
24779 +#ifdef CONFIG_PAX_SEGMEXEC
24780 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
24781 + if (end > SEGMEXEC_TASK_SIZE)
24786 + if (end > TASK_SIZE)
24789 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
24792 @@ -238,6 +414,16 @@ sys_mprotect(unsigned long start, size_t
24793 if (start > vma->vm_start)
24796 +#ifdef CONFIG_PAX_MPROTECT
24797 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
24798 + pax_handle_maywrite(vma, start);
24801 + if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
24806 for (nstart = start ; ; ) {
24807 unsigned long newflags;
24809 @@ -251,6 +437,12 @@ sys_mprotect(unsigned long start, size_t
24813 +#ifdef CONFIG_PAX_MPROTECT
24814 + /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
24815 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
24816 + newflags &= ~VM_MAYWRITE;
24819 error = security_file_mprotect(vma, reqprot, prot);
24822 @@ -274,6 +466,9 @@ sys_mprotect(unsigned long start, size_t
24827 + track_exec_limit(current->mm, start, end, vm_flags);
24830 up_write(¤t->mm->mmap_sem);
24832 diff -urNp linux-2.6.17.7/mm/mremap.c linux-2.6.17.7/mm/mremap.c
24833 --- linux-2.6.17.7/mm/mremap.c 2006-07-24 23:36:01.000000000 -0400
24834 +++ linux-2.6.17.7/mm/mremap.c 2006-08-01 20:29:48.000000000 -0400
24835 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
24836 pte = ptep_clear_flush(vma, old_addr, old_pte);
24837 /* ZERO_PAGE can be dependant on virtual addr */
24838 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
24840 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
24841 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
24842 + pte_exprotect(pte);
24845 set_pte_at(mm, new_addr, new_pte, pte);
24848 @@ -253,6 +259,7 @@ unsigned long do_mremap(unsigned long ad
24849 struct vm_area_struct *vma;
24850 unsigned long ret = -EINVAL;
24851 unsigned long charged = 0;
24852 + unsigned long task_size = TASK_SIZE;
24854 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
24856 @@ -271,6 +278,15 @@ unsigned long do_mremap(unsigned long ad
24860 +#ifdef CONFIG_PAX_SEGMEXEC
24861 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
24862 + task_size = SEGMEXEC_TASK_SIZE;
24865 + if (new_len > task_size || addr > task_size-new_len ||
24866 + old_len > task_size || addr > task_size-old_len)
24869 /* new_addr is only valid if MREMAP_FIXED is specified */
24870 if (flags & MREMAP_FIXED) {
24871 if (new_addr & ~PAGE_MASK)
24872 @@ -278,16 +294,13 @@ unsigned long do_mremap(unsigned long ad
24873 if (!(flags & MREMAP_MAYMOVE))
24876 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
24877 + if (new_addr > task_size - new_len)
24880 /* Check if the location we're moving into overlaps the
24881 * old location at all, and fail if it does.
24883 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
24886 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
24887 + if (addr + old_len > new_addr && new_addr + new_len > addr)
24890 ret = do_munmap(mm, new_addr, new_len);
24891 @@ -321,6 +334,14 @@ unsigned long do_mremap(unsigned long ad
24896 +#ifdef CONFIG_PAX_SEGMEXEC
24897 + if (vma->vm_flags & VM_MIRROR) {
24903 /* We can't remap across vm area boundaries */
24904 if (old_len > vma->vm_end - addr)
24906 @@ -354,7 +375,7 @@ unsigned long do_mremap(unsigned long ad
24907 if (old_len == vma->vm_end - addr &&
24908 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
24909 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
24910 - unsigned long max_addr = TASK_SIZE;
24911 + unsigned long max_addr = task_size;
24913 max_addr = vma->vm_next->vm_start;
24914 /* can we just expand the current mapping? */
24915 @@ -372,6 +393,7 @@ unsigned long do_mremap(unsigned long ad
24919 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
24923 @@ -382,8 +404,8 @@ unsigned long do_mremap(unsigned long ad
24926 if (flags & MREMAP_MAYMOVE) {
24927 + unsigned long map_flags = 0;
24928 if (!(flags & MREMAP_FIXED)) {
24929 - unsigned long map_flags = 0;
24930 if (vma->vm_flags & VM_MAYSHARE)
24931 map_flags |= MAP_SHARED;
24933 @@ -393,7 +415,12 @@ unsigned long do_mremap(unsigned long ad
24934 if (new_addr & ~PAGE_MASK)
24937 + map_flags = vma->vm_flags;
24938 ret = move_vma(vma, addr, old_len, new_len, new_addr);
24939 + if (!(ret & ~PAGE_MASK)) {
24940 + track_exec_limit(current->mm, addr, addr + old_len, 0UL);
24941 + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
24945 if (ret & ~PAGE_MASK)
24946 diff -urNp linux-2.6.17.7/mm/page_alloc.c linux-2.6.17.7/mm/page_alloc.c
24947 --- linux-2.6.17.7/mm/page_alloc.c 2006-07-24 23:36:01.000000000 -0400
24948 +++ linux-2.6.17.7/mm/page_alloc.c 2006-08-01 20:29:48.000000000 -0400
24949 @@ -334,7 +334,7 @@ static inline int page_is_buddy(struct p
24950 static inline void __free_one_page(struct page *page,
24951 struct zone *zone, unsigned int order)
24953 - unsigned long page_idx;
24954 + unsigned long page_idx, index;
24955 int order_size = 1 << order;
24957 if (unlikely(PageCompound(page)))
24958 @@ -345,6 +345,11 @@ static inline void __free_one_page(struc
24959 BUG_ON(page_idx & (order_size - 1));
24960 BUG_ON(bad_range(zone, page));
24962 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
24963 + for (index = order_size; index; --index)
24964 + clear_highpage(page + index - 1);
24967 zone->free_pages += order_size;
24968 while (order < MAX_ORDER-1) {
24969 unsigned long combined_idx;
24970 diff -urNp linux-2.6.17.7/mm/rmap.c linux-2.6.17.7/mm/rmap.c
24971 --- linux-2.6.17.7/mm/rmap.c 2006-07-24 23:36:01.000000000 -0400
24972 +++ linux-2.6.17.7/mm/rmap.c 2006-08-01 20:29:48.000000000 -0400
24973 @@ -106,6 +106,19 @@ int anon_vma_prepare(struct vm_area_stru
24974 list_add(&vma->anon_vma_node, &anon_vma->head);
24978 +#ifdef CONFIG_PAX_SEGMEXEC
24979 + if (vma->vm_flags & VM_MIRROR) {
24980 + struct vm_area_struct *vma_m;
24982 + vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
24983 + BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
24984 + BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
24985 + vma_m->anon_vma = anon_vma;
24986 + __anon_vma_link(vma_m);
24990 spin_unlock(&mm->page_table_lock);
24993 diff -urNp linux-2.6.17.7/mm/shmem.c linux-2.6.17.7/mm/shmem.c
24994 --- linux-2.6.17.7/mm/shmem.c 2006-07-24 23:36:01.000000000 -0400
24995 +++ linux-2.6.17.7/mm/shmem.c 2006-08-01 20:29:48.000000000 -0400
24996 @@ -2245,7 +2245,7 @@ static struct file_system_type tmpfs_fs_
24997 .get_sb = shmem_get_sb,
24998 .kill_sb = kill_litter_super,
25000 -static struct vfsmount *shm_mnt;
25001 +struct vfsmount *shm_mnt;
25003 static int __init init_tmpfs(void)
25005 diff -urNp linux-2.6.17.7/mm/tiny-shmem.c linux-2.6.17.7/mm/tiny-shmem.c
25006 --- linux-2.6.17.7/mm/tiny-shmem.c 2006-07-24 23:36:01.000000000 -0400
25007 +++ linux-2.6.17.7/mm/tiny-shmem.c 2006-08-01 20:29:48.000000000 -0400
25008 @@ -27,7 +27,7 @@ static struct file_system_type tmpfs_fs_
25009 .kill_sb = kill_litter_super,
25012 -static struct vfsmount *shm_mnt;
25013 +struct vfsmount *shm_mnt;
25015 static int __init init_tmpfs(void)
25017 diff -urNp linux-2.6.17.7/mm/vmalloc.c linux-2.6.17.7/mm/vmalloc.c
25018 --- linux-2.6.17.7/mm/vmalloc.c 2006-07-24 23:36:01.000000000 -0400
25019 +++ linux-2.6.17.7/mm/vmalloc.c 2006-08-01 20:29:48.000000000 -0400
25020 @@ -193,6 +193,8 @@ struct vm_struct *__get_vm_area_node(uns
25022 write_lock(&vmlist_lock);
25023 for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
25024 + if (addr > end - size)
25026 if ((unsigned long)tmp->addr < addr) {
25027 if((unsigned long)tmp->addr + tmp->size >= addr)
25028 addr = ALIGN(tmp->size +
25029 @@ -204,8 +206,6 @@ struct vm_struct *__get_vm_area_node(uns
25030 if (size + addr <= (unsigned long)tmp->addr)
25032 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
25033 - if (addr > end - size)
25038 diff -urNp linux-2.6.17.7/net/ipv4/inet_connection_sock.c linux-2.6.17.7/net/ipv4/inet_connection_sock.c
25039 --- linux-2.6.17.7/net/ipv4/inet_connection_sock.c 2006-07-24 23:36:01.000000000 -0400
25040 +++ linux-2.6.17.7/net/ipv4/inet_connection_sock.c 2006-08-01 20:29:48.000000000 -0400
25042 #include <linux/config.h>
25043 #include <linux/module.h>
25044 #include <linux/jhash.h>
25045 +#include <linux/grsecurity.h>
25047 #include <net/inet_connection_sock.h>
25048 #include <net/inet_hashtables.h>
25049 diff -urNp linux-2.6.17.7/net/ipv4/inet_hashtables.c linux-2.6.17.7/net/ipv4/inet_hashtables.c
25050 --- linux-2.6.17.7/net/ipv4/inet_hashtables.c 2006-07-24 23:36:01.000000000 -0400
25051 +++ linux-2.6.17.7/net/ipv4/inet_hashtables.c 2006-08-01 20:29:48.000000000 -0400
25052 @@ -19,11 +19,14 @@
25053 #include <linux/sched.h>
25054 #include <linux/slab.h>
25055 #include <linux/wait.h>
25056 +#include <linux/grsecurity.h>
25058 #include <net/inet_connection_sock.h>
25059 #include <net/inet_hashtables.h>
25060 #include <net/ip.h>
25062 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
25065 * Allocate and initialize a new local port bind bucket.
25066 * The bindhash mutex for snum's hash chain must be held here.
25067 @@ -310,6 +313,8 @@ ok:
25069 spin_unlock(&head->lock);
25071 + gr_update_task_in_ip_table(current, inet_sk(sk));
25074 inet_twsk_deschedule(tw, death_row);
25076 diff -urNp linux-2.6.17.7/net/ipv4/netfilter/Kconfig linux-2.6.17.7/net/ipv4/netfilter/Kconfig
25077 --- linux-2.6.17.7/net/ipv4/netfilter/Kconfig 2006-07-24 23:36:01.000000000 -0400
25078 +++ linux-2.6.17.7/net/ipv4/netfilter/Kconfig 2006-08-01 20:29:48.000000000 -0400
25079 @@ -314,6 +314,21 @@ config IP_NF_MATCH_HASHLIMIT
25080 destination IP' or `500pps from any given source IP' with a single
25083 +config IP_NF_MATCH_STEALTH
25084 + tristate "stealth match support"
25085 + depends on IP_NF_IPTABLES
25087 + Enabling this option will drop all syn packets coming to unserved tcp
25088 + ports as well as all packets coming to unserved udp ports. If you
25089 + are using your system to route any type of packets (ie. via NAT)
25090 + you should put this module at the end of your ruleset, since it will
25091 + drop packets that aren't going to ports that are listening on your
25092 + machine itself, it doesn't take into account that the packet might be
25093 + destined for someone on your internal network if you're using NAT for
25096 + To compile it as a module, choose M here. If unsure, say N.
25098 # `filter', generic and specific targets
25099 config IP_NF_FILTER
25100 tristate "Packet filtering"
25101 @@ -614,4 +629,3 @@ config IP_NF_ARP_MANGLE
25102 hardware and network addresses.
25106 diff -urNp linux-2.6.17.7/net/ipv4/netfilter/Makefile linux-2.6.17.7/net/ipv4/netfilter/Makefile
25107 --- linux-2.6.17.7/net/ipv4/netfilter/Makefile 2006-07-24 23:36:01.000000000 -0400
25108 +++ linux-2.6.17.7/net/ipv4/netfilter/Makefile 2006-08-01 20:29:48.000000000 -0400
25109 @@ -61,6 +61,7 @@ obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_ds
25110 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
25111 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
25112 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
25113 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
25116 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
25117 diff -urNp linux-2.6.17.7/net/ipv4/netfilter/ipt_stealth.c linux-2.6.17.7/net/ipv4/netfilter/ipt_stealth.c
25118 --- linux-2.6.17.7/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
25119 +++ linux-2.6.17.7/net/ipv4/netfilter/ipt_stealth.c 2006-08-01 20:29:48.000000000 -0400
25121 +/* Kernel module to add stealth support.
25123 + * Copyright (C) 2002,2005 Brad Spengler <spender@grsecurity.net>
25127 +#include <linux/kernel.h>
25128 +#include <linux/module.h>
25129 +#include <linux/skbuff.h>
25130 +#include <linux/net.h>
25131 +#include <linux/sched.h>
25132 +#include <linux/inet.h>
25133 +#include <linux/stddef.h>
25135 +#include <net/ip.h>
25136 +#include <net/sock.h>
25137 +#include <net/tcp.h>
25138 +#include <net/udp.h>
25139 +#include <net/route.h>
25140 +#include <net/inet_common.h>
25142 +#include <linux/netfilter_ipv4/ip_tables.h>
25144 +MODULE_LICENSE("GPL");
25146 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
25149 +match(const struct sk_buff *skb,
25150 + const struct net_device *in,
25151 + const struct net_device *out,
25152 + const void *matchinfo,
25156 + struct iphdr *ip = skb->nh.iph;
25157 + struct tcphdr th;
25158 + struct udphdr uh;
25159 + struct sock *sk = NULL;
25161 + if (!ip || offset) return 0;
25163 + switch(ip->protocol) {
25164 + case IPPROTO_TCP:
25165 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
25169 + if (!(th.syn && !th.ack)) return 0;
25170 + sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);
25172 + case IPPROTO_UDP:
25173 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
25177 + sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
25183 + if(!sk) // port is being listened on, match this
25191 +/* Called when user tries to insert an entry of this type. */
25193 +checkentry(const char *tablename,
25194 + const struct ipt_ip *ip,
25196 + unsigned int matchsize,
25197 + unsigned int hook_mask)
25199 + if (matchsize != IPT_ALIGN(0))
25202 + if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
25203 + ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
25204 + && (hook_mask & (1 << NF_IP_LOCAL_IN)))
25207 + printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
25213 +static struct ipt_match stealth_match = {
25214 + .name = "stealth",
25216 + .checkentry = &checkentry,
25218 + .me = THIS_MODULE
25221 +static int __init init(void)
25223 + return ipt_register_match(&stealth_match);
25226 +static void __exit fini(void)
25228 + ipt_unregister_match(&stealth_match);
25231 +module_init(init);
25232 +module_exit(fini);
25233 diff -urNp linux-2.6.17.7/net/ipv4/tcp_ipv4.c linux-2.6.17.7/net/ipv4/tcp_ipv4.c
25234 --- linux-2.6.17.7/net/ipv4/tcp_ipv4.c 2006-07-24 23:36:01.000000000 -0400
25235 +++ linux-2.6.17.7/net/ipv4/tcp_ipv4.c 2006-08-01 20:29:48.000000000 -0400
25237 #include <linux/jhash.h>
25238 #include <linux/init.h>
25239 #include <linux/times.h>
25240 +#include <linux/grsecurity.h>
25242 #include <net/icmp.h>
25243 #include <net/inet_hashtables.h>
25244 diff -urNp linux-2.6.17.7/net/ipv4/udp.c linux-2.6.17.7/net/ipv4/udp.c
25245 --- linux-2.6.17.7/net/ipv4/udp.c 2006-07-24 23:36:01.000000000 -0400
25246 +++ linux-2.6.17.7/net/ipv4/udp.c 2006-08-01 20:29:48.000000000 -0400
25247 @@ -102,6 +102,7 @@
25248 #include <linux/skbuff.h>
25249 #include <linux/proc_fs.h>
25250 #include <linux/seq_file.h>
25251 +#include <linux/grsecurity.h>
25252 #include <net/sock.h>
25253 #include <net/udp.h>
25254 #include <net/icmp.h>
25255 @@ -110,6 +111,12 @@
25256 #include <net/checksum.h>
25257 #include <net/xfrm.h>
25259 +extern int gr_search_udp_recvmsg(const struct sock *sk,
25260 + const struct sk_buff *skb);
25261 +extern int gr_search_udp_sendmsg(const struct sock *sk,
25262 + const struct sockaddr_in *addr);
25266 * Snmp MIB for the UDP layer
25268 @@ -266,8 +273,7 @@ static struct sock *udp_v4_lookup_longwa
25272 -static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
25273 - u32 daddr, u16 dport, int dif)
25274 +struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
25278 @@ -542,9 +548,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
25279 dport = usin->sin_port;
25283 + if (!gr_search_udp_sendmsg(sk, usin))
25286 if (sk->sk_state != TCP_ESTABLISHED)
25287 return -EDESTADDRREQ;
25289 + if (!gr_search_udp_sendmsg(sk, NULL))
25292 daddr = inet->daddr;
25293 dport = inet->dport;
25294 /* Open fast path for connected socket.
25295 @@ -798,6 +811,11 @@ try_again:
25299 + if (!gr_search_udp_recvmsg(sk, skb)) {
25304 copied = skb->len - sizeof(struct udphdr);
25305 if (copied > len) {
25307 diff -urNp linux-2.6.17.7/net/socket.c linux-2.6.17.7/net/socket.c
25308 --- linux-2.6.17.7/net/socket.c 2006-07-24 23:36:01.000000000 -0400
25309 +++ linux-2.6.17.7/net/socket.c 2006-08-01 20:29:48.000000000 -0400
25311 #include <linux/kmod.h>
25312 #include <linux/audit.h>
25313 #include <linux/wireless.h>
25314 +#include <linux/in.h>
25316 #include <asm/uaccess.h>
25317 #include <asm/unistd.h>
25319 #include <net/sock.h>
25320 #include <linux/netfilter.h>
25322 +extern void gr_attach_curr_ip(const struct sock *sk);
25323 +extern int gr_handle_sock_all(const int family, const int type,
25324 + const int protocol);
25325 +extern int gr_handle_sock_server(const struct sockaddr *sck);
25326 +extern int gr_handle_sock_server_other(const struct socket *sck);
25327 +extern int gr_handle_sock_client(const struct sockaddr *sck);
25328 +extern int gr_search_connect(const struct socket * sock,
25329 + const struct sockaddr_in * addr);
25330 +extern int gr_search_bind(const struct socket * sock,
25331 + const struct sockaddr_in * addr);
25332 +extern int gr_search_listen(const struct socket * sock);
25333 +extern int gr_search_accept(const struct socket * sock);
25334 +extern int gr_search_socket(const int domain, const int type,
25335 + const int protocol);
25337 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
25338 static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
25339 size_t size, loff_t pos);
25340 @@ -341,7 +357,7 @@ static struct super_block *sockfs_get_sb
25341 return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
25344 -static struct vfsmount *sock_mnt __read_mostly;
25345 +struct vfsmount *sock_mnt __read_mostly;
25347 static struct file_system_type sock_fs_type = {
25349 @@ -1240,6 +1256,16 @@ asmlinkage long sys_socket(int family, i
25351 struct socket *sock;
25353 + if(!gr_search_socket(family, type, protocol)) {
25354 + retval = -EACCES;
25358 + if (gr_handle_sock_all(family, type, protocol)) {
25359 + retval = -EACCES;
25363 retval = sock_create(family, type, protocol, &sock);
25366 @@ -1335,16 +1361,25 @@ asmlinkage long sys_bind(int fd, struct
25368 struct socket *sock;
25369 char address[MAX_SOCK_ADDR];
25370 + struct sockaddr *sck;
25371 int err, fput_needed;
25373 if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
25375 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
25376 + sck = (struct sockaddr *)address;
25377 + if (!gr_search_bind(sock, (struct sockaddr_in *)sck) ||
25378 + gr_handle_sock_server(sck)) {
25383 err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
25385 err = sock->ops->bind(sock,
25386 (struct sockaddr *)address, addrlen);
25389 fput_light(sock->file, fput_needed);
25392 @@ -1368,10 +1403,17 @@ asmlinkage long sys_listen(int fd, int b
25393 if ((unsigned) backlog > sysctl_somaxconn)
25394 backlog = sysctl_somaxconn;
25396 + if (gr_handle_sock_server_other(sock) ||
25397 + !gr_search_listen(sock)) {
25402 err = security_socket_listen(sock, backlog);
25404 err = sock->ops->listen(sock, backlog);
25407 fput_light(sock->file, fput_needed);
25410 @@ -1408,6 +1450,13 @@ asmlinkage long sys_accept(int fd, struc
25411 newsock->type = sock->type;
25412 newsock->ops = sock->ops;
25414 + if (gr_handle_sock_server_other(sock) ||
25415 + !gr_search_accept(sock)) {
25417 + sock_release(newsock);
25422 * We don't need try_module_get here, as the listening socket (sock)
25423 * has the protocol module (sock->ops->owner) held.
25424 @@ -1449,6 +1498,7 @@ asmlinkage long sys_accept(int fd, struc
25427 security_socket_post_accept(sock, newsock);
25428 + gr_attach_curr_ip(newsock->sk);
25431 fput_light(sock->file, fput_needed);
25432 @@ -1477,6 +1527,7 @@ asmlinkage long sys_connect(int fd, stru
25434 struct socket *sock;
25435 char address[MAX_SOCK_ADDR];
25436 + struct sockaddr *sck;
25437 int err, fput_needed;
25439 sock = sockfd_lookup_light(fd, &err, &fput_needed);
25440 @@ -1486,6 +1537,13 @@ asmlinkage long sys_connect(int fd, stru
25444 + sck = (struct sockaddr *)address;
25445 + if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
25446 + gr_handle_sock_client(sck)) {
25451 err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
25454 @@ -1740,6 +1798,7 @@ asmlinkage long sys_shutdown(int fd, int
25455 err = sock->ops->shutdown(sock, how);
25456 fput_light(sock->file, fput_needed);
25462 diff -urNp linux-2.6.17.7/net/unix/af_unix.c linux-2.6.17.7/net/unix/af_unix.c
25463 --- linux-2.6.17.7/net/unix/af_unix.c 2006-07-24 23:36:01.000000000 -0400
25464 +++ linux-2.6.17.7/net/unix/af_unix.c 2006-08-01 20:29:48.000000000 -0400
25465 @@ -117,6 +117,7 @@
25466 #include <linux/vs_context.h>
25467 #include <linux/vs_network.h>
25468 #include <linux/vs_limit.h>
25469 +#include <linux/grsecurity.h>
25471 int sysctl_unix_max_dgram_qlen = 10;
25473 @@ -680,6 +681,11 @@ static struct sock *unix_find_other(stru
25477 + if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
25482 err = -ECONNREFUSED;
25483 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
25485 @@ -703,6 +709,13 @@ static struct sock *unix_find_other(stru
25487 struct dentry *dentry;
25488 dentry = unix_sk(u)->dentry;
25490 + if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
25497 touch_atime(unix_sk(u)->mnt, dentry);
25499 @@ -781,9 +794,18 @@ static int unix_bind(struct socket *sock
25502 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
25504 + if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
25506 + goto out_mknod_dput;
25509 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
25511 goto out_mknod_dput;
25513 + gr_handle_create(dentry, nd.mnt);
25515 mutex_unlock(&nd.dentry->d_inode->i_mutex);
25517 nd.dentry = dentry;
25518 @@ -801,6 +823,10 @@ static int unix_bind(struct socket *sock
25522 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
25523 + sk->sk_peercred.pid = current->pid;
25526 list = &unix_socket_table[addr->hash];
25528 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
25529 diff -urNp linux-2.6.17.7/security/Kconfig linux-2.6.17.7/security/Kconfig
25530 --- linux-2.6.17.7/security/Kconfig 2006-07-24 23:36:01.000000000 -0400
25531 +++ linux-2.6.17.7/security/Kconfig 2006-08-01 20:29:48.000000000 -0400
25534 menu "Security options"
25539 + bool "Enable various PaX features"
25540 + depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
25542 + This allows you to enable various PaX features. PaX adds
25543 + intrusion prevention mechanisms to the kernel that reduce
25544 + the risks posed by exploitable memory corruption bugs.
25546 +menu "PaX Control"
25549 +config PAX_SOFTMODE
25550 + bool 'Support soft mode'
25552 + Enabling this option will allow you to run PaX in soft mode, that
25553 + is, PaX features will not be enforced by default, only on executables
25554 + marked explicitly. You must also enable PT_PAX_FLAGS support as it
25555 + is the only way to mark executables for soft mode use.
25557 + Soft mode can be activated by using the "pax_softmode=1" kernel command
25558 + line option on boot. Furthermore you can control various PaX features
25559 + at runtime via the entries in /proc/sys/kernel/pax.
25562 + bool 'Use legacy ELF header marking'
25564 + Enabling this option will allow you to control PaX features on
25565 + a per executable basis via the 'chpax' utility available at
25566 + http://pax.grsecurity.net/. The control flags will be read from
25567 + an otherwise reserved part of the ELF header. This marking has
25568 + numerous drawbacks (no support for soft-mode, toolchain does not
25569 + know about the non-standard use of the ELF header) therefore it
25570 + has been deprecated in favour of PT_PAX_FLAGS support.
25572 + If you have applications not marked by the PT_PAX_FLAGS ELF
25573 + program header then you MUST enable this option otherwise they
25574 + will not get any protection.
25576 + Note that if you enable PT_PAX_FLAGS marking support as well,
25577 + the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
25579 +config PAX_PT_PAX_FLAGS
25580 + bool 'Use ELF program header marking'
25582 + Enabling this option will allow you to control PaX features on
25583 + a per executable basis via the 'paxctl' utility available at
25584 + http://pax.grsecurity.net/. The control flags will be read from
25585 + a PaX specific ELF program header (PT_PAX_FLAGS). This marking
25586 + has the benefits of supporting both soft mode and being fully
25587 + integrated into the toolchain (the binutils patch is available
25588 + from http://pax.grsecurity.net).
25590 + If you have applications not marked by the PT_PAX_FLAGS ELF
25591 + program header then you MUST enable the EI_PAX marking support
25592 + otherwise they will not get any protection.
25594 + Note that if you enable the legacy EI_PAX marking support as well,
25595 + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
25598 + prompt 'MAC system integration'
25599 + default PAX_HAVE_ACL_FLAGS
25601 + Mandatory Access Control systems have the option of controlling
25602 + PaX flags on a per executable basis, choose the method supported
25603 + by your particular system.
25605 + - "none": if your MAC system does not interact with PaX,
25606 + - "direct": if your MAC system defines pax_set_flags() itself,
25607 + - "hook": if your MAC system uses the pax_set_flags_func callback.
25609 + NOTE: this option is for developers/integrators only.
25611 +config PAX_NO_ACL_FLAGS
25614 +config PAX_HAVE_ACL_FLAGS
25617 +config PAX_HOOK_ACL_FLAGS
25623 +menu "Non-executable pages"
25627 + bool "Enforce non-executable pages"
25628 + 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)
25630 + By design some architectures do not allow for protecting memory
25631 + pages against execution or even if they do, Linux does not make
25632 + use of this feature. In practice this means that if a page is
25633 + readable (such as the stack or heap) it is also executable.
25635 + There is a well known exploit technique that makes use of this
25636 + fact and a common programming mistake where an attacker can
25637 + introduce code of his choice somewhere in the attacked program's
25638 + memory (typically the stack or the heap) and then execute it.
25640 + If the attacked program was running with different (typically
25641 + higher) privileges than that of the attacker, then he can elevate
25642 + his own privilege level (e.g. get a root shell, write to files for
25643 + which he does not have write access to, etc).
25645 + Enabling this option will let you choose from various features
25646 + that prevent the injection and execution of 'foreign' code in
25649 + This will also break programs that rely on the old behaviour and
25650 + expect that dynamically allocated memory via the malloc() family
25651 + of functions is executable (which it is not). Notable examples
25652 + are the XFree86 4.x server, the java runtime and wine.
25654 +config PAX_PAGEEXEC
25655 + bool "Paging based non-executable pages"
25656 + depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
25657 + select PAX_NOVSYSCALL if X86_32
25659 + This implementation is based on the paging feature of the CPU.
25660 + On i386 and ppc there is a variable but usually low performance
25661 + impact on applications. On alpha, ia64, parisc, sparc, sparc64
25662 + and x86_64 there is no performance impact.
25664 +config PAX_SEGMEXEC
25665 + bool "Segmentation based non-executable pages"
25666 + depends on PAX_NOEXEC && X86_32
25667 + select PAX_NOVSYSCALL
25669 + This implementation is based on the segmentation feature of the
25670 + CPU and has little performance impact, however applications will
25671 + be limited to a 1.5 GB address space instead of the normal 3 GB.
25674 + prompt "Default non-executable page method"
25675 + depends on PAX_PAGEEXEC && PAX_SEGMEXEC
25676 + default PAX_DEFAULT_SEGMEXEC
25678 + Select the default non-executable page method applied to applications
25679 + that do not select one themselves.
25681 +config PAX_DEFAULT_PAGEEXEC
25684 +config PAX_DEFAULT_SEGMEXEC
25688 +config PAX_EMUTRAMP
25689 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
25690 + default y if PARISC || PPC32
25692 + There are some programs and libraries that for one reason or
25693 + another attempt to execute special small code snippets from
25694 + non-executable memory pages. Most notable examples are the
25695 + signal handler return code generated by the kernel itself and
25696 + the GCC trampolines.
25698 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
25699 + such programs will no longer work under your kernel.
25701 + As a remedy you can say Y here and use the 'chpax' or 'paxctl'
25702 + utilities to enable trampoline emulation for the affected programs
25703 + yet still have the protection provided by the non-executable pages.
25705 + On parisc and ppc you MUST enable this option and EMUSIGRT as
25706 + well, otherwise your system will not even boot.
25708 + Alternatively you can say N here and use the 'chpax' or 'paxctl'
25709 + utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
25710 + for the affected files.
25712 + NOTE: enabling this feature *may* open up a loophole in the
25713 + protection provided by non-executable pages that an attacker
25714 + could abuse. Therefore the best solution is to not have any
25715 + files on your system that would require this option. This can
25716 + be achieved by not using libc5 (which relies on the kernel
25717 + signal handler return code) and not using or rewriting programs
25718 + that make use of the nested function implementation of GCC.
25719 + Skilled users can just fix GCC itself so that it implements
25720 + nested function calls in a way that does not interfere with PaX.
25722 +config PAX_EMUSIGRT
25723 + bool "Automatically emulate sigreturn trampolines"
25724 + depends on PAX_EMUTRAMP && (PARISC || PPC32)
25727 + Enabling this option will have the kernel automatically detect
25728 + and emulate signal return trampolines executing on the stack
25729 + that would otherwise lead to task termination.
25731 + This solution is intended as a temporary one for users with
25732 + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
25733 + Modula-3 runtime, etc) or executables linked to such, basically
25734 + everything that does not specify its own SA_RESTORER function in
25735 + normal executable memory like glibc 2.1+ does.
25737 + On parisc and ppc you MUST enable this option, otherwise your
25738 + system will not even boot.
25740 + NOTE: this feature cannot be disabled on a per executable basis
25741 + and since it *does* open up a loophole in the protection provided
25742 + by non-executable pages, the best solution is to not have any
25743 + files on your system that would require this option.
25745 +config PAX_MPROTECT
25746 + bool "Restrict mprotect()"
25747 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
25749 + Enabling this option will prevent programs from
25750 + - changing the executable status of memory pages that were
25751 + not originally created as executable,
25752 + - making read-only executable pages writable again,
25753 + - creating executable pages from anonymous memory.
25755 + You should say Y here to complete the protection provided by
25756 + the enforcement of non-executable pages.
25758 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
25759 + this feature on a per file basis.
25761 +config PAX_NOELFRELOCS
25762 + bool "Disallow ELF text relocations"
25763 + depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
25765 + Non-executable pages and mprotect() restrictions are effective
25766 + in preventing the introduction of new executable code into an
25767 + attacked task's address space. There remain only two venues
25768 + for this kind of attack: if the attacker can execute already
25769 + existing code in the attacked task then he can either have it
25770 + create and mmap() a file containing his code or have it mmap()
25771 + an already existing ELF library that does not have position
25772 + independent code in it and use mprotect() on it to make it
25773 + writable and copy his code there. While protecting against
25774 + the former approach is beyond PaX, the latter can be prevented
25775 + by having only PIC ELF libraries on one's system (which do not
25776 + need to relocate their code). If you are sure this is your case,
25777 + then enable this option otherwise be careful as you may not even
25778 + be able to boot or log on your system (for example, some PAM
25779 + modules are erroneously compiled as non-PIC by default).
25781 + NOTE: if you are using dynamic ELF executables (as suggested
25782 + when using ASLR) then you must have made sure that you linked
25783 + your files using the PIC version of crt1 (the et_dyn.tar.gz package
25784 + referenced there has already been updated to support this).
25786 +config PAX_ETEXECRELOCS
25787 + bool "Allow ELF ET_EXEC text relocations"
25788 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
25791 + On some architectures there are incorrectly created applications
25792 + that require text relocations and would not work without enabling
25793 + this option. If you are an alpha, ia64 or parisc user, you should
25794 + enable this option and disable it once you have made sure that
25795 + none of your applications need it.
25798 + bool "Automatically emulate ELF PLT"
25799 + depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
25802 + Enabling this option will have the kernel automatically detect
25803 + and emulate the Procedure Linkage Table entries in ELF files.
25804 + On some architectures such entries are in writable memory, and
25805 + become non-executable leading to task termination. Therefore
25806 + it is mandatory that you enable this option on alpha, parisc, ppc,
25807 + sparc and sparc64, otherwise your system would not even boot.
25809 + NOTE: this feature *does* open up a loophole in the protection
25810 + provided by the non-executable pages, therefore the proper
25811 + solution is to modify the toolchain to produce a PLT that does
25812 + not need to be writable.
25814 +config PAX_DLRESOLVE
25816 + depends on PAX_EMUPLT && (SPARC32 || SPARC64)
25819 +config PAX_SYSCALL
25821 + depends on PAX_PAGEEXEC && PPC32
25824 +config PAX_KERNEXEC
25825 + bool "Enforce non-executable kernel pages"
25826 + depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !DEBUG_RODATA
25827 + select PAX_NOVSYSCALL
25829 + This is the kernel land equivalent of PAGEEXEC and MPROTECT,
25830 + that is, enabling this option will make it harder to inject
25831 + and execute 'foreign' code in kernel memory itself.
25835 +menu "Address Space Layout Randomization"
25839 + bool "Address Space Layout Randomization"
25840 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
25842 + Many if not most exploit techniques rely on the knowledge of
25843 + certain addresses in the attacked program. The following options
25844 + will allow the kernel to apply a certain amount of randomization
25845 + to specific parts of the program thereby forcing an attacker to
25846 + guess them in most cases. Any failed guess will most likely crash
25847 + the attacked program which allows the kernel to detect such attempts
25848 + and react on them. PaX itself provides no reaction mechanisms,
25849 + instead it is strongly encouraged that you make use of Nergal's
25850 + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
25851 + (http://www.grsecurity.net/) built-in crash detection features or
25852 + develop one yourself.
25854 + By saying Y here you can choose to randomize the following areas:
25855 + - top of the task's kernel stack
25856 + - top of the task's userland stack
25857 + - base address for mmap() requests that do not specify one
25858 + (this includes all libraries)
25859 + - base address of the main executable
25861 + It is strongly recommended to say Y here as address space layout
25862 + randomization has negligible impact on performance yet it provides
25863 + a very effective protection.
25865 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
25866 + this feature on a per file basis.
25868 +config PAX_RANDKSTACK
25869 + bool "Randomize kernel stack base"
25870 + depends on PAX_ASLR && X86_TSC && X86_32
25872 + By saying Y here the kernel will randomize every task's kernel
25873 + stack on every system call. This will not only force an attacker
25874 + to guess it but also prevent him from making use of possible
25875 + leaked information about it.
25877 + Since the kernel stack is a rather scarce resource, randomization
25878 + may cause unexpected stack overflows, therefore you should very
25879 + carefully test your system. Note that once enabled in the kernel
25880 + configuration, this feature cannot be disabled on a per file basis.
25882 +config PAX_RANDUSTACK
25883 + bool "Randomize user stack base"
25884 + depends on PAX_ASLR
25886 + By saying Y here the kernel will randomize every task's userland
25887 + stack. The randomization is done in two steps where the second
25888 + one may apply a big amount of shift to the top of the stack and
25889 + cause problems for programs that want to use lots of memory (more
25890 + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
25891 + For this reason the second step can be controlled by 'chpax' or
25892 + 'paxctl' on a per file basis.
25894 +config PAX_RANDMMAP
25895 + bool "Randomize mmap() base"
25896 + depends on PAX_ASLR
25898 + By saying Y here the kernel will use a randomized base address for
25899 + mmap() requests that do not specify one themselves. As a result
25900 + all dynamically loaded libraries will appear at random addresses
25901 + and therefore be harder to exploit by a technique where an attacker
25902 + attempts to execute library code for his purposes (e.g. spawn a
25903 + shell from an exploited program that is running at an elevated
25904 + privilege level).
25906 + Furthermore, if a program is relinked as a dynamic ELF file, its
25907 + base address will be randomized as well, completing the full
25908 + randomization of the address space layout. Attacking such programs
25909 + becomes a guess game. You can find an example of doing this at
25910 + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
25911 + http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
25913 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
25914 + feature on a per file basis.
25916 +config PAX_NOVSYSCALL
25917 + bool "Disable the vsyscall page"
25918 + depends on PAX_ASLR && X86_32
25920 + The Linux 2.6 kernel introduced a new feature that speeds up or
25921 + simplifies certain operations, such as system calls or returns
25922 + from signal handlers.
25924 + Unfortunately the implementation also gives a powerful instrument
25925 + into the hands of exploit writers: the so-called vsyscall page exists
25926 + in every task at the same fixed address and it contains machine code
25927 + that is very useful in performing the return-to-libc style attack.
25929 + Since this exploit technique cannot in general be protected against
25930 + via kernel solutions, this option will allow you to disable the use
25931 + of the vsyscall page and revert back to the old behaviour.
25935 +menu "Miscellaneous hardening features"
25937 +config PAX_MEMORY_SANITIZE
25938 + bool "Sanitize all freed memory"
25940 + By saying Y here the kernel will erase memory pages as soon as they
25941 + are freed. This in turn reduces the lifetime of data stored in the
25942 + pages, making it less likely that sensitive information such as
25943 + passwords, cryptographic secrets, etc stay in memory for too long.
25945 + This is especially useful for programs whose runtime is short, long
25946 + lived processes and the kernel itself benefit from this as long as
25947 + they operate on whole memory pages and ensure timely freeing of pages
25948 + that may hold sensitive information.
25950 + The tradeoff is performance impact, on a single CPU system kernel
25951 + compilation sees a 3% slowdown, other systems and workloads may vary
25952 + and you are advised to test this feature on your expected workload
25953 + before deploying it.
25955 + Note that this feature does not protect data stored in live pages,
25956 + e.g., process memory swapped to disk may stay there for a long time.
25958 +config PAX_MEMORY_UDEREF
25959 + bool "Prevent invalid userland pointer dereference"
25960 + depends on X86_32
25961 + select PAX_NOVSYSCALL
25963 + By saying Y here the kernel will be prevented from dereferencing
25964 + userland pointers in contexts where the kernel expects only kernel
25965 + pointers. This is both a useful runtime debugging feature and a
25966 + security measure that prevents exploiting a class of kernel bugs.
25968 + The tradeoff is that some virtualization solutions may experience
25969 + a huge slowdown and therefore you should not enable this feature
25970 + for kernels meant to run in such environments. Whether a given VM
25971 + solution is affected or not is best determined by simply trying it
25972 + out, the performance impact will be obvious right on boot as this
25973 + mechanism engages from very early on. A good rule of thumb is that
25974 + VMs running on CPUs without hardware virtualization support (i.e.,
25975 + the majority of IA-32 CPUs) will likely experience the slowdown.
25981 +source grsecurity/Kconfig
25984 bool "Enable access key retention support"
25986 diff -urNp linux-2.6.17.7/security/commoncap.c linux-2.6.17.7/security/commoncap.c
25987 --- linux-2.6.17.7/security/commoncap.c 2006-07-24 23:36:01.000000000 -0400
25988 +++ linux-2.6.17.7/security/commoncap.c 2006-08-01 20:29:48.000000000 -0400
25990 #include <linux/ptrace.h>
25991 #include <linux/xattr.h>
25992 #include <linux/hugetlb.h>
25993 +#include <linux/grsecurity.h>
25995 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
25997 @@ -45,7 +46,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
25998 int cap_capable (struct task_struct *tsk, int cap)
26000 /* Derived from include/linux/sched.h:capable. */
26001 - if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
26002 + if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
26007 +int cap_capable_nolog (struct task_struct *tsk, int cap)
26009 + /* Derived from include/linux/sched.h:capable. */
26010 + if (cap_raised (tsk->cap_effective, cap))
26014 @@ -164,8 +173,11 @@ void cap_bprm_apply_creds (struct linux_
26018 - current->suid = current->euid = current->fsuid = bprm->e_uid;
26019 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
26020 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
26021 + current->suid = current->euid = current->fsuid = bprm->e_uid;
26023 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
26024 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
26026 /* For init, we want to retain the capabilities set
26027 * in the init_task struct. Thus we skip the usual
26028 @@ -176,6 +188,8 @@ void cap_bprm_apply_creds (struct linux_
26029 cap_intersect (new_permitted, bprm->cap_effective);
26032 + gr_handle_chroot_caps(current);
26034 /* AUD: Audit candidate if current->cap_effective is set */
26036 current->keep_capabilities = 0;
26037 @@ -321,12 +335,13 @@ int cap_vm_enough_memory(long pages)
26039 int cap_sys_admin = 0;
26041 - if (cap_capable(current, CAP_SYS_ADMIN) == 0)
26042 + if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
26044 return __vm_enough_memory(pages, cap_sys_admin);
26047 EXPORT_SYMBOL(cap_capable);
26048 +EXPORT_SYMBOL(cap_capable_nolog);
26049 EXPORT_SYMBOL(cap_settime);
26050 EXPORT_SYMBOL(cap_ptrace);
26051 EXPORT_SYMBOL(cap_capget);
26052 diff -urNp linux-2.6.17.7/security/dummy.c linux-2.6.17.7/security/dummy.c
26053 --- linux-2.6.17.7/security/dummy.c 2006-07-24 23:36:01.000000000 -0400
26054 +++ linux-2.6.17.7/security/dummy.c 2006-08-01 20:29:48.000000000 -0400
26056 #include <linux/hugetlb.h>
26057 #include <linux/ptrace.h>
26058 #include <linux/file.h>
26059 +#include <linux/grsecurity.h>
26061 static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
26063 @@ -139,8 +140,11 @@ static void dummy_bprm_apply_creds (stru
26067 - current->suid = current->euid = current->fsuid = bprm->e_uid;
26068 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
26069 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
26070 + current->suid = current->euid = current->fsuid = bprm->e_uid;
26072 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
26073 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
26075 dummy_capget(current, ¤t->cap_effective, ¤t->cap_inheritable, ¤t->cap_permitted);