summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Hale <tseng@gentoo.org>2004-06-16 03:43:01 +0000
committerBrandon Hale <tseng@gentoo.org>2004-06-16 03:43:01 +0000
commitd6dfef208d31b656f17b6efcc4afd45a12bf0fab (patch)
tree9ef005d0d17ea11f94caab3a7853d676c3689248 /src/kernel
parentAdd security fixes (diff)
downloadgentoo-d6dfef208d31b656f17b6efcc4afd45a12bf0fab.tar.gz
gentoo-d6dfef208d31b656f17b6efcc4afd45a12bf0fab.tar.bz2
gentoo-d6dfef208d31b656f17b6efcc4afd45a12bf0fab.zip
remove
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/hardened-patches/hardened-patches-2.6-5.5/1000_grsecurity-2.0-2.6.5.patch21403
1 files changed, 0 insertions, 21403 deletions
diff --git a/src/kernel/hardened-patches/hardened-patches-2.6-5.5/1000_grsecurity-2.0-2.6.5.patch b/src/kernel/hardened-patches/hardened-patches-2.6-5.5/1000_grsecurity-2.0-2.6.5.patch
deleted file mode 100644
index a569b46926..0000000000
--- a/src/kernel/hardened-patches/hardened-patches-2.6-5.5/1000_grsecurity-2.0-2.6.5.patch
+++ /dev/null
@@ -1,21403 +0,0 @@
-diff -urN linux-2.6.5/Makefile linux-2.6.5/Makefile
---- linux-2.6.5/Makefile 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/Makefile 2004-04-18 11:05:50.000000000 -0400
-@@ -1,7 +1,7 @@
- VERSION = 2
- PATCHLEVEL = 6
- SUBLEVEL = 5
--EXTRAVERSION =
-+EXTRAVERSION = -grsec
- NAME=Zonked Quokka
-
- # *DOCUMENTATION*
-@@ -424,7 +424,7 @@
- CFLAGS := $(CPPFLAGS) $(CFLAGS)
- AFLAGS := $(CPPFLAGS) $(AFLAGS)
-
--core-y += kernel/ mm/ fs/ ipc/ security/ crypto/
-+core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ grsecurity/
-
- SUBDIRS += $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
- $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
-diff -urN linux-2.6.5/arch/alpha/kernel/osf_sys.c linux-2.6.5/arch/alpha/kernel/osf_sys.c
---- linux-2.6.5/arch/alpha/kernel/osf_sys.c 2004-04-03 22:36:11.000000000 -0500
-+++ linux-2.6.5/arch/alpha/kernel/osf_sys.c 2004-04-18 11:05:50.000000000 -0400
-@@ -37,6 +37,7 @@
- #include <linux/namei.h>
- #include <linux/uio.h>
- #include <linux/vfs.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/fpu.h>
- #include <asm/io.h>
-@@ -179,6 +180,11 @@
- struct file *file = NULL;
- unsigned long ret = -EBADF;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- #if 0
- if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
- printk("%s: unimplemented OSF mmap flags %04lx\n",
-@@ -189,6 +195,13 @@
- if (!file)
- goto out;
- }
-+
-+ if (gr_handle_mmap(file, prot)) {
-+ fput(file);
-+ ret = -EACCES;
-+ goto out;
-+ }
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down_write(&current->mm->mmap_sem);
- ret = do_mmap(file, addr, len, prot, flags, off);
-@@ -1295,6 +1308,10 @@
- merely specific addresses, but regions of memory -- perhaps
- this feature should be incorporated into all ports? */
-
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
-+#endif
-+
- if (addr) {
- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
- if (addr != (unsigned long) -ENOMEM)
-@@ -1302,8 +1319,16 @@
- }
-
- /* Next, try allocating at TASK_UNMAPPED_BASE. */
-- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
-- len, limit);
-+
-+ addr = TASK_UNMAPPED_BASE;
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (current->flags & PF_PAX_RANDMMAP)
-+ addr += current->mm->delta_mmap;
-+#endif
-+
-+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
-+
- if (addr != (unsigned long) -ENOMEM)
- return addr;
-
-diff -urN linux-2.6.5/arch/alpha/kernel/ptrace.c linux-2.6.5/arch/alpha/kernel/ptrace.c
---- linux-2.6.5/arch/alpha/kernel/ptrace.c 2004-04-03 22:38:13.000000000 -0500
-+++ linux-2.6.5/arch/alpha/kernel/ptrace.c 2004-04-18 11:05:50.000000000 -0400
-@@ -14,6 +14,7 @@
- #include <linux/user.h>
- #include <linux/slab.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -288,6 +289,9 @@
- if (!child)
- goto out_notsk;
-
-+ if (gr_handle_ptrace(child, request))
-+ goto out;
-+
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out;
-diff -urN linux-2.6.5/arch/alpha/mm/fault.c linux-2.6.5/arch/alpha/mm/fault.c
---- linux-2.6.5/arch/alpha/mm/fault.c 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/arch/alpha/mm/fault.c 2004-04-18 11:05:50.000000000 -0400
-@@ -25,6 +25,7 @@
- #include <linux/smp_lock.h>
- #include <linux/interrupt.h>
- #include <linux/module.h>
-+#include <linux/binfmts.h>
-
- #include <asm/system.h>
- #include <asm/uaccess.h>
-@@ -56,6 +57,142 @@
- __reload_thread(pcb);
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/*
-+ * PaX: decide what to do with offenders (regs->pc = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when patched PLT trampoline was detected
-+ * 3 when unpatched PLT trampoline was detected
-+ * 4 when legitimate ET_EXEC was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ int err;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ if (regs->pc >= current->mm->start_code &&
-+ regs->pc < current->mm->end_code)
-+ {
-+ if (regs->r26 == regs->pc)
-+ return 1;
-+
-+ regs->pc += current->mm->delta_exec;
-+ return 4;
-+ }
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ do { /* PaX: patched PLT emulation #1 */
-+ unsigned int ldah, ldq, jmp;
-+
-+ err = get_user(ldah, (unsigned int *)regs->pc);
-+ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
-+ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
-+
-+ if (err)
-+ break;
-+
-+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
-+ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
-+ jmp == 0x6BFB0000U)
-+ {
-+ unsigned long r27, addr;
-+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
-+ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
-+
-+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
-+ err = get_user(r27, (unsigned long*)addr);
-+ if (err)
-+ break;
-+
-+ regs->r27 = r27;
-+ regs->pc = r27;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: patched PLT emulation #2 */
-+ unsigned int ldah, lda, br;
-+
-+ err = get_user(ldah, (unsigned int *)regs->pc);
-+ err |= get_user(lda, (unsigned int *)(regs->pc+4));
-+ err |= get_user(br, (unsigned int *)(regs->pc+8));
-+
-+ if (err)
-+ break;
-+
-+ if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
-+ (lda & 0xFFFF0000U) == 0xA77B0000U &&
-+ (br & 0xFFE00000U) == 0xC3E00000U)
-+ {
-+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
-+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
-+ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
-+
-+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
-+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: unpatched PLT emulation */
-+ unsigned int br;
-+
-+ err = get_user(br, (unsigned int *)regs->pc);
-+
-+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
-+ unsigned int br2, ldq, nop, jmp;
-+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
-+
-+ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
-+ err = get_user(br2, (unsigned int *)addr);
-+ err |= get_user(ldq, (unsigned int *)(addr+4));
-+ err |= get_user(nop, (unsigned int *)(addr+8));
-+ err |= get_user(jmp, (unsigned int *)(addr+12));
-+ err |= get_user(resolver, (unsigned long *)(addr+16));
-+
-+ if (err)
-+ break;
-+
-+ if (br2 == 0xC3600000U &&
-+ ldq == 0xA77B000CU &&
-+ nop == 0x47FF041FU &&
-+ jmp == 0x6B7B0000U)
-+ {
-+ regs->r28 = regs->pc+4;
-+ regs->r27 = addr+16;
-+ regs->pc = resolver;
-+ return 3;
-+ }
-+ }
-+ } while (0);
-+#endif
-+
-+ return 1;
-+}
-+
-+void pax_report_insns(void *pc, void *sp)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 5; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned int*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-
- /*
- * This routine handles page faults. It determines the address,
-@@ -133,8 +270,34 @@
- good_area:
- si_code = SEGV_ACCERR;
- if (cause < 0) {
-- if (!(vma->vm_flags & VM_EXEC))
-+ if (!(vma->vm_flags & VM_EXEC)) {
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->pc)
-+ goto bad_area;
-+
-+ up_read(&mm->mmap_sem);
-+ switch(pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ case 2:
-+ case 3:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 4:
-+ return;
-+#endif
-+
-+ }
-+ pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
-+ do_exit(SIGKILL);
-+#else
- goto bad_area;
-+#endif
-+
-+ }
- } else if (!cause) {
- /* Allow reads even for write-only mappings */
- if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
-diff -urN linux-2.6.5/arch/i386/Kconfig linux-2.6.5/arch/i386/Kconfig
---- linux-2.6.5/arch/i386/Kconfig 2004-04-03 22:36:25.000000000 -0500
-+++ linux-2.6.5/arch/i386/Kconfig 2004-04-18 11:05:50.000000000 -0400
-@@ -390,7 +390,7 @@
-
- config X86_ALIGNMENT_16
- bool
-- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
-+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
- default y
-
- config X86_GOOD_APIC
-diff -urN linux-2.6.5/arch/i386/kernel/apm.c linux-2.6.5/arch/i386/kernel/apm.c
---- linux-2.6.5/arch/i386/kernel/apm.c 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/apm.c 2004-04-18 11:05:50.000000000 -0400
-@@ -597,19 +597,40 @@
- int cpu;
- struct desc_struct save_desc_40;
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ unsigned long cr3;
-+#endif
-+
- cpus = apm_save_cpus();
-
- cpu = get_cpu();
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_open_kernel(flags, cr3);
-+#endif
-+
- save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
- cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
-
-+#ifndef CONFIG_PAX_KERNEXEC
- local_save_flags(flags);
- APM_DO_CLI;
-+#endif
-+
- APM_DO_SAVE_SEGS;
- apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
- APM_DO_RESTORE_SEGS;
-+
-+#ifndef CONFIG_PAX_KERNEXEC
- local_irq_restore(flags);
-+#endif
-+
- cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_close_kernel(flags, cr3);
-+#endif
-+
- put_cpu();
- apm_restore_cpus(cpus);
-
-@@ -639,20 +660,40 @@
- int cpu;
- struct desc_struct save_desc_40;
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ unsigned long cr3;
-+#endif
-
- cpus = apm_save_cpus();
-
- cpu = get_cpu();
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_open_kernel(flags, cr3);
-+#endif
-+
- save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
- cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
-
-+#ifndef CONFIG_PAX_KERNEXEC
- local_save_flags(flags);
- APM_DO_CLI;
-+#endif
-+
- APM_DO_SAVE_SEGS;
- error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
- APM_DO_RESTORE_SEGS;
-+
-+#ifndef CONFIG_PAX_KERNEXEC
- local_irq_restore(flags);
-+#endif
-+
- cpu_gdt_table[smp_processor_id()][0x40 / 8] = save_desc_40;
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_close_kernel(flags, cr3);
-+#endif
-+
- put_cpu();
- apm_restore_cpus(cpus);
- return error;
-diff -urN linux-2.6.5/arch/i386/kernel/cpu/common.c linux-2.6.5/arch/i386/kernel/cpu/common.c
---- linux-2.6.5/arch/i386/kernel/cpu/common.c 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/cpu/common.c 2004-04-18 11:05:50.000000000 -0400
-@@ -319,6 +319,10 @@
- if (this_cpu->c_init)
- this_cpu->c_init(c);
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_NOVSYSCALL)
-+ clear_bit(X86_FEATURE_SEP, c->x86_capability);
-+#endif
-+
- /* Disable the PN if appropriate */
- squash_the_stupid_serial_number(c);
-
-@@ -514,7 +518,7 @@
- set_tss_desc(cpu,t);
- cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
- load_TR_desc();
-- load_LDT(&init_mm.context);
-+ _load_LDT(&init_mm.context);
-
- /* Set up doublefault TSS pointer in the GDT */
- __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
-diff -urN linux-2.6.5/arch/i386/kernel/entry.S linux-2.6.5/arch/i386/kernel/entry.S
---- linux-2.6.5/arch/i386/kernel/entry.S 2004-04-03 22:36:52.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/entry.S 2004-04-18 11:05:50.000000000 -0400
-@@ -272,6 +272,11 @@
- movl TI_FLAGS(%ebp), %ecx
- testw $_TIF_ALLWORK_MASK, %cx
- jne syscall_exit_work
-+
-+#ifdef CONFIG_PAX_RANDKSTACK
-+ call pax_randomize_kstack
-+#endif
-+
- /* if something modifies registers it must also disable sysexit */
- movl EIP(%esp), %edx
- movl OLDESP(%esp), %ecx
-@@ -299,6 +304,11 @@
- movl TI_FLAGS(%ebp), %ecx
- testw $_TIF_ALLWORK_MASK, %cx # current->work
- jne syscall_exit_work
-+
-+#ifdef CONFIG_PAX_RANDKSTACK
-+ call pax_randomize_kstack
-+#endif
-+
- restore_all:
- RESTORE_ALL
-
-@@ -591,7 +601,13 @@
- jmp error_code
-
- ENTRY(page_fault)
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ ALIGN
-+ pushl $pax_do_page_fault
-+#else
- pushl $do_page_fault
-+#endif
-+
- jmp error_code
-
- #ifdef CONFIG_X86_MCE
-@@ -606,7 +622,7 @@
- pushl $do_spurious_interrupt_bug
- jmp error_code
-
--.data
-+.section .rodata,"a",@progbits
- ENTRY(sys_call_table)
- .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
- .long sys_exit
-diff -urN linux-2.6.5/arch/i386/kernel/head.S linux-2.6.5/arch/i386/kernel/head.S
---- linux-2.6.5/arch/i386/kernel/head.S 2004-04-03 22:36:18.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/head.S 2004-04-18 11:05:50.000000000 -0400
-@@ -49,6 +49,12 @@
-
-
- /*
-+ * Real beginning of normal "text" segment
-+ */
-+ENTRY(stext)
-+ENTRY(_stext)
-+
-+/*
- * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
- * %esi points to the real-mode code as a 32-bit pointer.
- * CS and DS must be 4 GB flat segments, but we don't depend on
-@@ -80,9 +86,9 @@
-
- movl $(pg0 - __PAGE_OFFSET), %edi
- movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
-- movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
-+ movl $0x067, %eax /* 0x067 = DIRTY+ACCESSED+PRESENT+RW+USER */
- 10:
-- leal 0x007(%edi),%ecx /* Create PDE entry */
-+ leal 0x067(%edi),%ecx /* Create PDE entry */
- movl %ecx,(%edx) /* Store identity PDE entry */
- movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
- addl $4,%edx
-@@ -92,8 +98,8 @@
- addl $0x1000,%eax
- loop 11b
- /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
-- /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
-- leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
-+ /* bytes beyond the end of our own page tables; the +0x067 is the attribute bits */
-+ leal (INIT_MAP_BEYOND_END+0x067)(%edi),%ebp
- cmpl %ebp,%eax
- jb 10b
- movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
-@@ -152,7 +158,7 @@
- movl %cr0,%eax
- orl $0x80000000,%eax
- movl %eax,%cr0 /* ..and set paging (PG) bit */
-- ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */
-+ ljmp $__BOOT_CS,$1f + __KERNEL_TEXT_OFFSET /* Clear prefetch and normalize %eip */
- 1:
- /* Set up the stack pointer */
- lss stack_start,%esp
-@@ -304,8 +310,6 @@
- jmp L6 # main should never return here, but
- # just in case, we know what happens.
-
--ready: .byte 0
--
- /*
- * We depend on ET to be correct. This checks for 287/387.
- */
-@@ -353,13 +357,6 @@
- jne rp_sidt
- ret
-
--ENTRY(stack_start)
-- .long init_thread_union+THREAD_SIZE
-- .long __BOOT_DS
--
--/* This is the default interrupt "handler" :-) */
--int_msg:
-- .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
- ALIGN
- ignore_int:
- cld
-@@ -386,6 +383,56 @@
- iret
-
- /*
-+ * This starts the data section. Note that the above is all
-+ * in the text section because it has alignment requirements
-+ * that we cannot fulfill any other way except for PaX ;-).
-+ */
-+.data
-+ready: .byte 0
-+
-+/*
-+ * swapper_pg_dir is the main page directory, address 0x00101000
-+ *
-+ * This is initialized to create an identity-mapping at 0 (for bootup
-+ * purposes) and another mapping at virtual address PAGE_OFFSET. The
-+ * values put here should be all invalid (zero); the valid
-+ * entries are created dynamically at boot time.
-+ *
-+ * The code creates enough page tables to map 0-_end, the page tables
-+ * themselves, plus INIT_MAP_BEYOND_END bytes; see comment at beginning.
-+ */
-+.section .data.swapper_pg_dir,"a",@progbits
-+ENTRY(swapper_pg_dir)
-+ .fill 1024,4,0
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ENTRY(kernexec_pg_dir)
-+ .fill 1024,4,0
-+#endif
-+
-+.section .rodata.empty_zero_page,"a",@progbits
-+ENTRY(empty_zero_page)
-+ .fill 4096,1,0
-+
-+/*
-+ * The IDT has to be page-aligned to simplify the Pentium
-+ * F0 0F bug workaround.. We have a special link segment
-+ * for this.
-+ */
-+.section .rodata.idt,"a",@progbits
-+ENTRY(idt_table)
-+ .fill 256,8,0
-+
-+.section .rodata,"a",@progbits
-+ENTRY(stack_start)
-+ .long init_thread_union+THREAD_SIZE
-+ .long __BOOT_DS
-+
-+/* This is the default interrupt "handler" :-) */
-+int_msg:
-+ .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
-+
-+/*
- * The IDT and GDT 'descriptors' are a strange 48-bit object
- * only used by the lidt and lgdt instructions. They are not
- * like usual segment descriptors - they consist of a 16-bit
-@@ -417,47 +464,14 @@
- .fill NR_CPUS-1,8,0 # space for the other GDT descriptors
-
- /*
-- * swapper_pg_dir is the main page directory, address 0x00101000
-- *
-- * This is initialized to create an identity-mapping at 0 (for bootup
-- * purposes) and another mapping at virtual address PAGE_OFFSET. The
-- * values put here should be all invalid (zero); the valid
-- * entries are created dynamically at boot time.
-- *
-- * The code creates enough page tables to map 0-_end, the page tables
-- * themselves, plus INIT_MAP_BEYOND_END bytes; see comment at beginning.
-- */
--.org 0x1000
--ENTRY(swapper_pg_dir)
-- .fill 1024,4,0
--
--.org 0x2000
--ENTRY(empty_zero_page)
-- .fill 4096,1,0
--
--.org 0x3000
--/*
-- * Real beginning of normal "text" segment
-- */
--ENTRY(stext)
--ENTRY(_stext)
--
--/*
-- * This starts the data section. Note that the above is all
-- * in the text section because it has alignment requirements
-- * that we cannot fulfill any other way.
-- */
--.data
--
--/*
- * The boot_gdt_table must mirror the equivalent in setup.S and is
- * used only for booting.
- */
- .align L1_CACHE_BYTES
- ENTRY(boot_gdt_table)
- .fill GDT_ENTRY_BOOT_CS,8,0
-- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
-- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
-+ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
-+ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
-
- /*
- * The Global Descriptor Table contains 28 quadwords, per-CPU.
-@@ -468,7 +482,13 @@
- .quad 0x0000000000000000 /* 0x0b reserved */
- .quad 0x0000000000000000 /* 0x13 reserved */
- .quad 0x0000000000000000 /* 0x1b reserved */
-+
-+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
-+ .quad 0x00cf9b000000ffff /* 0x20 kernel 4GB code at 0x00000000 */
-+#else
- .quad 0x0000000000000000 /* 0x20 unused */
-+#endif
-+
- .quad 0x0000000000000000 /* 0x28 unused */
- .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
- .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
-@@ -477,27 +497,32 @@
- .quad 0x0000000000000000 /* 0x53 reserved */
- .quad 0x0000000000000000 /* 0x5b reserved */
-
-- .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
-- .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
-- .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */
-- .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */
-+#ifdef CONFIG_PAX_KERNEXEC
-+ .quad 0xc0cf9b400000ffff /* 0x60 kernel 4GB code at 0xc0400000 */
-+#else
-+ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
-+#endif
-+
-+ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
-+ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
-+ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
-
- .quad 0x0000000000000000 /* 0x80 TSS descriptor */
- .quad 0x0000000000000000 /* 0x88 LDT descriptor */
-
- /* Segments used for calling PnP BIOS */
-- .quad 0x00c09a0000000000 /* 0x90 32-bit code */
-- .quad 0x00809a0000000000 /* 0x98 16-bit code */
-- .quad 0x0080920000000000 /* 0xa0 16-bit data */
-- .quad 0x0080920000000000 /* 0xa8 16-bit data */
-- .quad 0x0080920000000000 /* 0xb0 16-bit data */
-+ .quad 0x00c09b0000000000 /* 0x90 32-bit code */
-+ .quad 0x00809b0000000000 /* 0x98 16-bit code */
-+ .quad 0x0080930000000000 /* 0xa0 16-bit data */
-+ .quad 0x0080930000000000 /* 0xa8 16-bit data */
-+ .quad 0x0080930000000000 /* 0xb0 16-bit data */
- /*
- * The APM segments have byte granularity and their bases
- * and limits are set at run time.
- */
-- .quad 0x00409a0000000000 /* 0xb8 APM CS code */
-- .quad 0x00009a0000000000 /* 0xc0 APM CS 16 code (16 bit) */
-- .quad 0x0040920000000000 /* 0xc8 APM DS data */
-+ .quad 0x00409b0000000000 /* 0xb8 APM CS code */
-+ .quad 0x00009b0000000000 /* 0xc0 APM CS 16 code (16 bit) */
-+ .quad 0x0040930000000000 /* 0xc8 APM DS data */
-
- .quad 0x0000000000000000 /* 0xd0 - unused */
- .quad 0x0000000000000000 /* 0xd8 - unused */
-diff -urN linux-2.6.5/arch/i386/kernel/ioport.c linux-2.6.5/arch/i386/kernel/ioport.c
---- linux-2.6.5/arch/i386/kernel/ioport.c 2004-04-03 22:37:06.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/ioport.c 2004-04-18 11:05:50.000000000 -0400
-@@ -15,6 +15,7 @@
- #include <linux/stddef.h>
- #include <linux/slab.h>
- #include <linux/thread_info.h>
-+#include <linux/grsecurity.h>
-
- /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
- static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
-@@ -62,9 +63,16 @@
-
- if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
- return -EINVAL;
-+#ifdef CONFIG_GRKERNSEC_IO
-+ if (turn_on) {
-+ gr_handle_ioperm();
-+#else
- if (turn_on && !capable(CAP_SYS_RAWIO))
-+#endif
- return -EPERM;
--
-+#ifdef CONFIG_GRKERNSEC_IO
-+ }
-+#endif
- /*
- * If it's the first ioperm() call in this thread's lifetime, set the
- * IO bitmap up. ioperm() is much less timing critical than clone(),
-@@ -115,8 +123,13 @@
- return -EINVAL;
- /* Trying to gain more privileges? */
- if (level > old) {
-+#ifdef CONFIG_GRKERNSEC_IO
-+ gr_handle_iopl();
-+ return -EPERM;
-+#else
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
-+#endif
- }
- regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
- /* Make sure we return the long way (not sysenter) */
-diff -urN linux-2.6.5/arch/i386/kernel/ldt.c linux-2.6.5/arch/i386/kernel/ldt.c
---- linux-2.6.5/arch/i386/kernel/ldt.c 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/ldt.c 2004-04-18 11:05:50.000000000 -0400
-@@ -154,7 +154,7 @@
- {
- int err;
- unsigned long size;
-- void *address;
-+ const void *address;
-
- err = 0;
- address = &default_ldt[0];
-@@ -211,6 +211,13 @@
- }
- }
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if ((current->flags & PF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) {
-+ error = -EINVAL;
-+ goto out_unlock;
-+ }
-+#endif
-+
- entry_1 = LDT_entry_a(&ldt_info);
- entry_2 = LDT_entry_b(&ldt_info);
- if (oldmode)
-diff -urN linux-2.6.5/arch/i386/kernel/process.c linux-2.6.5/arch/i386/kernel/process.c
---- linux-2.6.5/arch/i386/kernel/process.c 2004-04-03 22:36:10.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/process.c 2004-04-18 11:05:50.000000000 -0400
-@@ -344,7 +344,7 @@
- struct task_struct *tsk;
- int err;
-
-- childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
-+ childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info - sizeof(unsigned long))) - 1;
- struct_cpy(childregs, regs);
- childregs->eax = 0;
- childregs->esp = esp;
-@@ -446,9 +446,8 @@
- int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
- {
- struct pt_regs ptregs;
--
-- ptregs = *(struct pt_regs *)
-- ((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs));
-+
-+ ptregs = *(struct pt_regs *)(tsk->thread.esp0 - sizeof(ptregs));
- ptregs.xcs &= 0xffff;
- ptregs.xds &= 0xffff;
- ptregs.xes &= 0xffff;
-@@ -501,10 +500,22 @@
- int cpu = smp_processor_id();
- struct tss_struct *tss = init_tss + cpu;
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ unsigned long flags, cr3;
-+#endif
-+
- /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
-
- __unlazy_fpu(prev_p);
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_open_kernel(flags, cr3);
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ pax_switch_segments(next_p, cpu);
-+#endif
-+
- /*
- * Reload esp0, LDT and the page table pointer:
- */
-@@ -515,6 +526,10 @@
- */
- load_TLS(next, cpu);
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_close_kernel(flags, cr3);
-+#endif
-+
- /*
- * Save away %fs and %gs. No need to save %es and %ds, as
- * those are always kernel segments while inside the kernel.
-@@ -689,6 +704,10 @@
- struct desc_struct *desc;
- int cpu, idx;
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ unsigned long flags, cr3;
-+#endif
-+
- if (copy_from_user(&info, u_info, sizeof(info)))
- return -EFAULT;
- idx = info.entry_number;
-@@ -722,8 +741,17 @@
- desc->a = LDT_entry_a(&info);
- desc->b = LDT_entry_b(&info);
- }
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_open_kernel(flags, cr3);
-+#endif
-+
- load_TLS(t, cpu);
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_close_kernel(flags, cr3);
-+#endif
-+
- put_cpu();
-
- return 0;
-@@ -777,3 +805,29 @@
- return 0;
- }
-
-+#ifdef CONFIG_PAX_RANDKSTACK
-+asmlinkage void pax_randomize_kstack(void)
-+{
-+ struct tss_struct *tss = init_tss + smp_processor_id();
-+ unsigned long time;
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (!pax_aslr)
-+ return;
-+#endif
-+
-+ rdtscl(time);
-+
-+ /* P4 seems to return a 0 LSB, ignore it */
-+#ifdef CONFIG_MPENTIUM4
-+ time &= 0x3EUL;
-+ time <<= 1;
-+#else
-+ time &= 0x1FUL;
-+ time <<= 2;
-+#endif
-+
-+ tss->esp0 ^= time;
-+ current->thread.esp0 = tss->esp0;
-+}
-+#endif
-diff -urN linux-2.6.5/arch/i386/kernel/ptrace.c linux-2.6.5/arch/i386/kernel/ptrace.c
---- linux-2.6.5/arch/i386/kernel/ptrace.c 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/ptrace.c 2004-04-18 11:05:50.000000000 -0400
-@@ -14,6 +14,7 @@
- #include <linux/ptrace.h>
- #include <linux/user.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -262,6 +263,9 @@
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
-+ if (gr_handle_ptrace(child, request))
-+ goto out_tsk;
-+
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
-@@ -340,6 +344,17 @@
- if(addr == (long) &dummy->u_debugreg[5]) break;
- if(addr < (long) &dummy->u_debugreg[4] &&
- ((unsigned long) data) >= TASK_SIZE-3) break;
-+
-+#ifdef CONFIG_GRKERNSEC
-+ if(addr >= (long) &dummy->u_debugreg[0] &&
-+ addr <= (long) &dummy->u_debugreg[3]){
-+ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
-+ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
-+ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
-+ if((type & 1) && (data & align))
-+ break;
-+ }
-+#endif
-
- if(addr == (long) &dummy->u_debugreg[7]) {
- data &= ~DR_CONTROL_RESERVED;
-diff -urN linux-2.6.5/arch/i386/kernel/reboot.c linux-2.6.5/arch/i386/kernel/reboot.c
---- linux-2.6.5/arch/i386/kernel/reboot.c 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/reboot.c 2004-04-18 11:05:50.000000000 -0400
-@@ -74,18 +74,18 @@
- doesn't work with at least one type of 486 motherboard. It is easy
- to stop this code working; hence the copious comments. */
-
--static unsigned long long
-+static const unsigned long long
- real_mode_gdt_entries [3] =
- {
- 0x0000000000000000ULL, /* Null descriptor */
-- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
-- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
-+ 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
-+ 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
- };
-
- static struct
- {
- unsigned short size __attribute__ ((packed));
-- unsigned long long * base __attribute__ ((packed));
-+ const unsigned long long * base __attribute__ ((packed));
- }
- real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
- real_mode_idt = { 0x3ff, 0 },
-diff -urN linux-2.6.5/arch/i386/kernel/setup.c linux-2.6.5/arch/i386/kernel/setup.c
---- linux-2.6.5/arch/i386/kernel/setup.c 2004-04-03 22:37:06.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/setup.c 2004-04-18 11:05:50.000000000 -0400
-@@ -1202,6 +1202,15 @@
- #endif
- }
-
-+#ifdef CONFIG_PAX_SOFTMODE
-+static int __init setup_pax_softmode(char *str)
-+{
-+ get_option (&str, &pax_softmode);
-+ return 1;
-+}
-+__setup("pax_softmode=", setup_pax_softmode);
-+#endif
-+
- #include "setup_arch_post.h"
- /*
- * Local Variables:
-diff -urN linux-2.6.5/arch/i386/kernel/signal.c linux-2.6.5/arch/i386/kernel/signal.c
---- linux-2.6.5/arch/i386/kernel/signal.c 2004-04-03 22:36:58.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/signal.c 2004-04-18 11:05:50.000000000 -0400
-@@ -371,7 +371,17 @@
- if (err)
- goto give_sigsegv;
-
-+#ifdef CONFIG_PAX_NOVSYSCALL
-+ restorer = frame->retcode;
-+#else
- restorer = &__kernel_sigreturn;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC)
-+ restorer -= SEGMEXEC_TASK_SIZE;
-+#endif
-+#endif
-+
- if (ka->sa.sa_flags & SA_RESTORER)
- restorer = ka->sa.sa_restorer;
-
-@@ -454,7 +464,18 @@
- goto give_sigsegv;
-
- /* Set up to return from userspace. */
-+
-+#ifdef CONFIG_PAX_NOVSYSCALL
-+ restorer = frame->retcode;
-+#else
- restorer = &__kernel_rt_sigreturn;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC)
-+ restorer -= SEGMEXEC_TASK_SIZE;
-+#endif
-+#endif
-+
- if (ka->sa.sa_flags & SA_RESTORER)
- restorer = ka->sa.sa_restorer;
- err |= __put_user(restorer, &frame->pretcode);
-diff -urN linux-2.6.5/arch/i386/kernel/sys_i386.c linux-2.6.5/arch/i386/kernel/sys_i386.c
---- linux-2.6.5/arch/i386/kernel/sys_i386.c 2004-04-03 22:38:21.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/sys_i386.c 2004-04-18 11:05:50.000000000 -0400
-@@ -19,6 +19,7 @@
- #include <linux/mman.h>
- #include <linux/file.h>
- #include <linux/utsname.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/ipc.h>
-@@ -49,6 +50,11 @@
- int error = -EBADF;
- struct file * file = NULL;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
-@@ -56,8 +62,14 @@
- goto out;
- }
-
-+ if (gr_handle_mmap(file, prot)) {
-+ fput(file);
-+ error = -EACCES;
-+ goto out;
-+ }
-+
- down_write(&current->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+ error = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
- up_write(&current->mm->mmap_sem);
-
- if (file)
-diff -urN linux-2.6.5/arch/i386/kernel/sysenter.c linux-2.6.5/arch/i386/kernel/sysenter.c
---- linux-2.6.5/arch/i386/kernel/sysenter.c 2004-04-03 22:38:24.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/sysenter.c 2004-04-18 11:05:50.000000000 -0400
-@@ -41,13 +41,15 @@
- extern const char vsyscall_int80_start, vsyscall_int80_end;
- extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
-
-+#ifndef CONFIG_PAX_NOVSYSCALL
- static int __init sysenter_setup(void)
- {
- unsigned long page = get_zeroed_page(GFP_ATOMIC);
-
- __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY);
-
-- if (!boot_cpu_has(X86_FEATURE_SEP)) {
-+ if (!boot_cpu_has(X86_FEATURE_SEP))
-+ {
- memcpy((void *) page,
- &vsyscall_int80_start,
- &vsyscall_int80_end - &vsyscall_int80_start);
-@@ -63,3 +65,4 @@
- }
-
- __initcall(sysenter_setup);
-+#endif
-diff -urN linux-2.6.5/arch/i386/kernel/trampoline.S linux-2.6.5/arch/i386/kernel/trampoline.S
---- linux-2.6.5/arch/i386/kernel/trampoline.S 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/trampoline.S 2004-04-18 11:05:50.000000000 -0400
-@@ -58,7 +58,7 @@
- inc %ax # protected mode (PE) bit
- lmsw %ax # into protected mode
- # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S
-- ljmpl $__BOOT_CS, $(startup_32_smp-__PAGE_OFFSET)
-+ ljmpl $__BOOT_CS, $(startup_32_smp+__KERNEL_TEXT_OFFSET-__PAGE_OFFSET)
-
- # These need to be in the same 64K segment as the above;
- # hence we don't use the boot_gdt_descr defined in head.S
-diff -urN linux-2.6.5/arch/i386/kernel/traps.c linux-2.6.5/arch/i386/kernel/traps.c
---- linux-2.6.5/arch/i386/kernel/traps.c 2004-04-03 22:36:25.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/traps.c 2004-04-18 11:05:50.000000000 -0400
-@@ -59,18 +59,13 @@
- asmlinkage void lcall7(void);
- asmlinkage void lcall27(void);
-
--struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
-+const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 } };
-
- /* Do we ignore FPU interrupts ? */
- char ignore_fpu_irq = 0;
-
--/*
-- * The IDT has to be page-aligned to simplify the Pentium
-- * F0 0F bug workaround.. We have a special link segment
-- * for this.
-- */
--struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
-+extern struct desc_struct idt_table[256];
-
- asmlinkage void divide_error(void);
- asmlinkage void debug(void);
-@@ -97,6 +92,7 @@
- void show_trace(struct task_struct *task, unsigned long * stack)
- {
- unsigned long addr;
-+ int i = kstack_depth_to_print;
-
- if (!stack)
- stack = (unsigned long*)&stack;
-@@ -105,11 +101,12 @@
- #ifdef CONFIG_KALLSYMS
- printk("\n");
- #endif
-- while (!kstack_end(stack)) {
-+ while (i && !kstack_end(stack)) {
- addr = *stack++;
- if (kernel_text_address(addr)) {
- printk(" [<%08lx>] ", addr);
- print_symbol("%s\n", addr);
-+ --i;
- }
- }
- printk("\n");
-@@ -199,14 +196,23 @@
- show_stack(NULL, (unsigned long*)esp);
-
- printk("Code: ");
-+
-+#ifndef CONFIG_PAX_KERNEXEC
- if(regs->eip < PAGE_OFFSET)
- goto bad;
-+#endif
-
- for(i=0;i<20;i++)
- {
- unsigned char c;
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ if(__get_user(c, &((unsigned char*)regs->eip)[i+__KERNEL_TEXT_OFFSET])) {
-+#else
- if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
- bad:
-+#endif
-+
- printk(" Bad EIP value.");
- break;
- }
-@@ -229,8 +235,13 @@
-
- eip = regs->eip;
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ eip += __KERNEL_TEXT_OFFSET;
-+#else
- if (eip < PAGE_OFFSET)
- goto no_bug;
-+#endif
-+
- if (__get_user(ud2, (unsigned short *)eip))
- goto no_bug;
- if (ud2 != 0x0b0f)
-@@ -238,7 +249,13 @@
- if (__get_user(line, (unsigned short *)(eip + 2)))
- goto bug;
- if (__get_user(file, (char **)(eip + 4)) ||
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ __get_user(c, file + __KERNEL_TEXT_OFFSET))
-+#else
- (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
-+#endif
-+
- file = "<bad filename>";
-
- printk("------------[ cut here ]------------\n");
-@@ -411,8 +428,16 @@
- return;
-
- gp_in_kernel:
-- if (!fixup_exception(regs))
-+ if (!fixup_exception(regs)) {
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
-+ die("PAX: suspicious general protection fault", regs, error_code);
-+ else
-+#endif
-+
- die("general protection fault", regs, error_code);
-+ }
- }
-
- static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
-@@ -845,7 +870,7 @@
- _set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
- }
-
--static void __init set_call_gate(void *a, void *addr)
-+static void __init set_call_gate(const void *a, void *addr)
- {
- _set_gate(a,12,3,addr,__KERNEL_CS);
- }
-diff -urN linux-2.6.5/arch/i386/kernel/vmlinux.lds.S linux-2.6.5/arch/i386/kernel/vmlinux.lds.S
---- linux-2.6.5/arch/i386/kernel/vmlinux.lds.S 2004-04-03 22:36:26.000000000 -0500
-+++ linux-2.6.5/arch/i386/kernel/vmlinux.lds.S 2004-04-18 11:05:50.000000000 -0400
-@@ -2,7 +2,12 @@
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-
-+#include <linux/config.h>
-+
- #include <asm-generic/vmlinux.lds.h>
-+#include <asm-i386/page.h>
-+#include <asm-i386/segment.h>
-+
- #include <asm/thread_info.h>
-
- OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-@@ -11,25 +16,16 @@
- jiffies = jiffies_64;
- SECTIONS
- {
-- . = 0xC0000000 + 0x100000;
-- /* read-only */
-- _text = .; /* Text and read-only data */
-- .text : {
-- *(.text)
-- *(.fixup)
-- *(.gnu.warning)
-- } = 0x9090
--
-- _etext = .; /* End of text section */
--
-- . = ALIGN(16); /* Exception table */
-- __start___ex_table = .;
-- __ex_table : { *(__ex_table) }
-- __stop___ex_table = .;
--
-- RODATA
-+ . = __PAGE_OFFSET + 0x100000;
-+ .text.startup : {
-+ BYTE(0xEA) /* jmp far */
-+ LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET)
-+ SHORT(__BOOT_CS)
-+ }
-
- /* writeable */
-+ . = ALIGN(32);
-+ _data = .;
- .data : { /* Data */
- *(.data)
- CONSTRUCTORS
-@@ -41,25 +37,28 @@
- . = ALIGN(4096);
- __nosave_end = .;
-
-- . = ALIGN(4096);
-- .data.page_aligned : { *(.data.idt) }
--
- . = ALIGN(32);
- .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
-- _edata = .; /* End of data section */
--
- . = ALIGN(THREAD_SIZE); /* init_task */
- .data.init_task : { *(.data.init_task) }
-
-+ . = ALIGN(4096);
-+ .data.page_aligned : { *(.data.swapper_pg_dir) }
-+
-+ _edata = .; /* End of data section */
-+
-+ __bss_start = .; /* BSS */
-+ .bss : {
-+ *(.bss)
-+ LONG(0)
-+ }
-+ . = ALIGN(4);
-+ __bss_stop = .;
-+
- /* will be freed after init */
- . = ALIGN(4096); /* Init code and data */
- __init_begin = .;
-- .init.text : {
-- _sinittext = .;
-- *(.init.text)
-- _einittext = .;
-- }
- .init.data : { *(.init.data) }
- . = ALIGN(16);
- __setup_start = .;
-@@ -100,16 +99,68 @@
- __per_cpu_start = .;
- .data.percpu : { *(.data.percpu) }
- __per_cpu_end = .;
-+
-+ /* read-only */
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ __init_text_start = .;
-+ .init.text (. - __KERNEL_TEXT_OFFSET) : AT (__init_text_start) {
-+ _sinittext = .;
-+ *(.init.text)
-+ _einittext = .;
-+ . = ALIGN(4*1024*1024) - 1;
-+ BYTE(0)
-+ }
-+ . = ALIGN(4096);
-+ __init_end = . + __KERNEL_TEXT_OFFSET;
-+ /* freed after init ends here */
-+
-+/*
-+ * PaX: this must be kept in synch with the KERNEL_CS base
-+ * in the GDTs in arch/i386/kernel/head.S
-+ */
-+ _text = .; /* Text and read-only data */
-+ .text : AT (. + __KERNEL_TEXT_OFFSET) {
-+#else
-+ .init.text : {
-+ _sinittext = .;
-+ *(.init.text)
-+ _einittext = .;
-+ }
- . = ALIGN(4096);
- __init_end = .;
- /* freed after init ends here */
--
-- __bss_start = .; /* BSS */
-- .bss : { *(.bss) }
-- . = ALIGN(4);
-- __bss_stop = .;
-
-+ _text = .; /* Text and read-only data */
-+ .text : {
-+#endif
-+
-+ *(.text)
-+ *(.fixup)
-+ *(.gnu.warning)
-+ } = 0x9090
-+
-+ _etext = .; /* End of text section */
-+ . += __KERNEL_TEXT_OFFSET;
-+ . = ALIGN(16); /* Exception table */
-+ __start___ex_table = .;
-+ __ex_table : { *(__ex_table) }
-+ __stop___ex_table = .;
-+
-+ . = ALIGN(4096);
-+ .rodata.page_aligned : {
-+ *(.rodata.empty_zero_page)
-+ *(.rodata.idt)
-+ }
-+
-+ RODATA
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ _end = ALIGN(4*1024*1024);
-+ . = _end ;
-+#else
- _end = . ;
-+#endif
-
- /* This is where the kernel creates the early boot page tables */
- . = ALIGN(4096);
-diff -urN linux-2.6.5/arch/i386/mm/fault.c linux-2.6.5/arch/i386/mm/fault.c
---- linux-2.6.5/arch/i386/mm/fault.c 2004-04-03 22:36:13.000000000 -0500
-+++ linux-2.6.5/arch/i386/mm/fault.c 2004-04-18 11:05:50.000000000 -0400
-@@ -21,6 +21,9 @@
- #include <linux/vt_kern.h> /* For unblank_screen() */
- #include <linux/highmem.h>
- #include <linux/module.h>
-+#include <linux/unistd.h>
-+#include <linux/compiler.h>
-+#include <linux/binfmts.h>
-
- #include <asm/system.h>
- #include <asm/uaccess.h>
-@@ -199,6 +202,10 @@
-
- asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
-
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+static int pax_handle_fetch_fault(struct pt_regs *regs);
-+#endif
-+
- /*
- * This routine handles page faults. It determines the address,
- * and the problem, and then passes it off to one of the appropriate
-@@ -209,22 +216,31 @@
- * bit 1 == 0 means read, 1 means write
- * bit 2 == 0 means kernel, 1 means user-mode
- */
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+static void do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
-+#else
- asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
-+#endif
- {
- struct task_struct *tsk;
- struct mm_struct *mm;
- struct vm_area_struct * vma;
-+#ifndef CONFIG_PAX_PAGEEXEC
- unsigned long address;
-+#endif
- unsigned long page;
- int write;
- siginfo_t info;
-
-+#ifndef CONFIG_PAX_PAGEEXEC
- /* get the address */
- __asm__("movl %%cr2,%0":"=r" (address));
-
- /* It's safe to allow irq's after cr2 has been saved */
- if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
- local_irq_enable();
-+#endif
-
- tsk = current;
-
-@@ -358,6 +374,34 @@
- if (is_prefetch(regs, address))
- return;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+
-+#if defined(CONFIG_PAX_EMUTRAMP) || defined(CONFIG_PAX_RANDEXEC)
-+ if ((error_code == 4) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
-+ switch (pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 3:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ case 2:
-+ return;
-+#endif
-+
-+ }
-+ }
-+#endif
-+
-+ if (address >= SEGMEXEC_TASK_SIZE) {
-+ pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
-+ do_exit(SIGKILL);
-+ }
-+ }
-+#endif
-+
- tsk->thread.cr2 = address;
- /* Kernel addresses are always protection faults */
- tsk->thread.error_code = error_code | (address >= TASK_SIZE);
-@@ -408,6 +452,13 @@
-
- if (address < PAGE_SIZE)
- printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address && address < init_mm.end_code + __KERNEL_TEXT_OFFSET)
-+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
-+ tsk->comm, tsk->pid, tsk->uid, tsk->euid);
-+#endif
-+
- else
- printk(KERN_ALERT "Unable to handle kernel paging request");
- printk(" at virtual address %08lx\n",address);
-@@ -509,3 +560,361 @@
- return;
- }
- }
-+
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+/*
-+ * PaX: decide what to do with offenders (regs->eip = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when gcc trampoline was detected
-+ * 3 when legitimate ET_EXEC was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
-+#endif
-+
-+#if defined(CONFIG_PAX_RANDEXEC) || defined(CONFIG_PAX_EMUTRAMP)
-+ int err;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ unsigned long esp_4;
-+
-+ if (regs->eip >= current->mm->start_code &&
-+ regs->eip < current->mm->end_code)
-+ {
-+ err = get_user(esp_4, (unsigned long*)(regs->esp-4UL));
-+ if (err || esp_4 == regs->eip)
-+ return 1;
-+
-+ regs->eip += current->mm->delta_exec;
-+ return 3;
-+ }
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ do { /* PaX: gcc trampoline emulation #1 */
-+ unsigned char mov1, mov2;
-+ unsigned short jmp;
-+ unsigned long addr1, addr2, ret;
-+ unsigned short call;
-+
-+ err = get_user(mov1, (unsigned char *)regs->eip);
-+ err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
-+ err |= get_user(mov2, (unsigned char *)(regs->eip + 5));
-+ err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
-+ err |= get_user(jmp, (unsigned short *)(regs->eip + 10));
-+ err |= get_user(ret, (unsigned long *)regs->esp);
-+
-+ if (err)
-+ break;
-+
-+ err = get_user(call, (unsigned short *)(ret-2));
-+ if (err)
-+ break;
-+
-+ if ((mov1 & 0xF8) == 0xB8 &&
-+ (mov2 & 0xF8) == 0xB8 &&
-+ (mov1 & 0x07) != (mov2 & 0x07) &&
-+ (jmp & 0xF8FF) == 0xE0FF &&
-+ (mov2 & 0x07) == ((jmp>>8) & 0x07) &&
-+ (call & 0xF8FF) == 0xD0FF &&
-+ regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
-+ {
-+ ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
-+ ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
-+ regs->eip = addr2;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: gcc trampoline emulation #2 */
-+ unsigned char mov, jmp;
-+ unsigned long addr1, addr2, ret;
-+ unsigned short call;
-+
-+ err = get_user(mov, (unsigned char *)regs->eip);
-+ err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
-+ err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
-+ err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
-+ err |= get_user(ret, (unsigned long *)regs->esp);
-+
-+ if (err)
-+ break;
-+
-+ err = get_user(call, (unsigned short *)(ret-2));
-+ if (err)
-+ break;
-+
-+ if ((mov & 0xF8) == 0xB8 &&
-+ jmp == 0xE9 &&
-+ (call & 0xF8FF) == 0xD0FF &&
-+ regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
-+ {
-+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
-+ regs->eip += addr2 + 10;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: gcc trampoline emulation #3 */
-+ unsigned char mov, jmp;
-+ char offset;
-+ unsigned long addr1, addr2, ret;
-+ unsigned short call;
-+
-+ err = get_user(mov, (unsigned char *)regs->eip);
-+ err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
-+ err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
-+ err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
-+ err |= get_user(ret, (unsigned long *)regs->esp);
-+
-+ if (err)
-+ break;
-+
-+ err = get_user(call, (unsigned short *)(ret-3));
-+ err |= get_user(offset, (char *)(ret-1));
-+ if (err)
-+ break;
-+
-+ if ((mov & 0xF8) == 0xB8 &&
-+ jmp == 0xE9 &&
-+ call == 0x55FF)
-+ {
-+ unsigned long addr;
-+
-+ err = get_user(addr, (unsigned long*)(regs->ebp + (unsigned long)(long)offset));
-+ if (err || regs->eip != addr)
-+ break;
-+
-+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
-+ regs->eip += addr2 + 10;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: gcc trampoline emulation #4 */
-+ unsigned char mov, jmp, sib;
-+ char offset;
-+ unsigned long addr1, addr2, ret;
-+ unsigned short call;
-+
-+ err = get_user(mov, (unsigned char *)regs->eip);
-+ err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
-+ err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
-+ err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
-+ err |= get_user(ret, (unsigned long *)regs->esp);
-+
-+ if (err)
-+ break;
-+
-+ err = get_user(call, (unsigned short *)(ret-4));
-+ err |= get_user(sib, (unsigned char *)(ret-2));
-+ err |= get_user(offset, (char *)(ret-1));
-+ if (err)
-+ break;
-+
-+ if ((mov & 0xF8) == 0xB8 &&
-+ jmp == 0xE9 &&
-+ call == 0x54FF &&
-+ sib == 0x24)
-+ {
-+ unsigned long addr;
-+
-+ err = get_user(addr, (unsigned long*)(regs->esp + 4 + (unsigned long)(long)offset));
-+ if (err || regs->eip != addr)
-+ break;
-+
-+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
-+ regs->eip += addr2 + 10;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: gcc trampoline emulation #5 */
-+ unsigned char mov, jmp, sib;
-+ unsigned long addr1, addr2, ret, offset;
-+ unsigned short call;
-+
-+ err = get_user(mov, (unsigned char *)regs->eip);
-+ err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
-+ err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
-+ err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
-+ err |= get_user(ret, (unsigned long *)regs->esp);
-+
-+ if (err)
-+ break;
-+
-+ err = get_user(call, (unsigned short *)(ret-7));
-+ err |= get_user(sib, (unsigned char *)(ret-5));
-+ err |= get_user(offset, (unsigned long *)(ret-4));
-+ if (err)
-+ break;
-+
-+ if ((mov & 0xF8) == 0xB8 &&
-+ jmp == 0xE9 &&
-+ call == 0x94FF &&
-+ sib == 0x24)
-+ {
-+ unsigned long addr;
-+
-+ err = get_user(addr, (unsigned long*)(regs->esp + 4 + offset));
-+ if (err || regs->eip != addr)
-+ break;
-+
-+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
-+ regs->eip += addr2 + 10;
-+ return 2;
-+ }
-+ } while (0);
-+#endif
-+
-+ return 1; /* PaX in action */
-+}
-+
-+void pax_report_insns(void *pc, void *sp)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 20; i++) {
-+ unsigned char c;
-+ if (get_user(c, (unsigned char*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%02x ", c);
-+ }
-+ printk("\n");
-+
-+ printk(KERN_ERR "PAX: bytes at SP: ");
-+ for (i = 0; i < 20; i++) {
-+ unsigned long c;
-+ if (get_user(c, (unsigned long*)sp+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08lx ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/* PaX: called with the page_table_lock spinlock held */
-+static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address)
-+{
-+ pgd_t *pgd;
-+ pmd_t *pmd;
-+
-+ pgd = pgd_offset(mm, address);
-+ if (!pgd || !pgd_present(*pgd))
-+ return 0;
-+ pmd = pmd_offset(pgd, address);
-+ if (!pmd || !pmd_present(*pmd))
-+ return 0;
-+ return pte_offset_map(pmd, address);
-+}
-+
-+/*
-+ * PaX: handle the extra page faults or pass it down to the original handler
-+ */
-+asmlinkage void pax_do_page_fault(struct pt_regs *regs, unsigned long error_code)
-+{
-+ struct mm_struct *mm = current->mm;
-+ unsigned long address;
-+ pte_t *pte;
-+ unsigned char pte_mask;
-+ int ret;
-+
-+ __asm__("movl %%cr2,%0":"=r" (address));
-+
-+ /* It's safe to allow irq's after cr2 has been saved */
-+ if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
-+ local_irq_enable();
-+
-+ if (unlikely((error_code & 5) != 5 ||
-+ address >= TASK_SIZE ||
-+ !(current->flags & PF_PAX_PAGEEXEC)))
-+ return do_page_fault(regs, error_code, address);
-+
-+ /* PaX: it's our fault, let's handle it if we can */
-+
-+ /* PaX: take a look at read faults before acquiring any locks */
-+ if (unlikely((error_code == 5) && (regs->eip == address))) {
-+ /* instruction fetch attempt from a protected page in user mode */
-+ ret = pax_handle_fetch_fault(regs);
-+ switch (ret) {
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 3:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ case 2:
-+ return;
-+#endif
-+
-+ case 1:
-+ default:
-+ pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
-+ do_exit(SIGKILL);
-+ }
-+ }
-+
-+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
-+
-+ spin_lock(&mm->page_table_lock);
-+ pte = pax_get_pte(mm, address);
-+ if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) {
-+ pte_unmap(pte);
-+ spin_unlock(&mm->page_table_lock);
-+ do_page_fault(regs, error_code, address);
-+ return;
-+ }
-+
-+ if (unlikely((error_code == 7) && !pte_write(*pte))) {
-+ /* write attempt to a protected page in user mode */
-+ pte_unmap(pte);
-+ spin_unlock(&mm->page_table_lock);
-+ do_page_fault(regs, error_code, address);
-+ return;
-+ }
-+
-+ /*
-+ * PaX: fill DTLB with user rights and retry
-+ */
-+ __asm__ __volatile__ (
-+ "orb %2,%1\n"
-+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
-+/*
-+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
-+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
-+ * page fault when examined during a TLB load attempt. this is true not only
-+ * for PTEs holding a non-present entry but also present entries that will
-+ * raise a page fault (such as those set up by PaX, or the copy-on-write
-+ * mechanism). in effect it means that we do *not* need to flush the TLBs
-+ * for our target pages since their PTEs are simply not in the TLBs at all.
-+
-+ * the best thing in omitting it is that we gain around 15-20% speed in the
-+ * fast path of the page fault handler and can get rid of tracing since we
-+ * can no longer flush unintended entries.
-+ */
-+ "invlpg %0\n"
-+#endif
-+ "testb $0,%0\n"
-+ "xorb %3,%1\n"
-+ :
-+ : "m" (*(char*)address), "m" (*(char*)pte), "q" (pte_mask), "i" (_PAGE_USER)
-+ : "memory", "cc");
-+ pte_unmap(pte);
-+ spin_unlock(&mm->page_table_lock);
-+ return;
-+}
-+#endif
-diff -urN linux-2.6.5/arch/i386/mm/init.c linux-2.6.5/arch/i386/mm/init.c
---- linux-2.6.5/arch/i386/mm/init.c 2004-04-03 22:37:39.000000000 -0500
-+++ linux-2.6.5/arch/i386/mm/init.c 2004-04-18 11:05:50.000000000 -0400
-@@ -40,6 +40,7 @@
- #include <asm/tlb.h>
- #include <asm/tlbflush.h>
- #include <asm/sections.h>
-+#include <asm/desc.h>
-
- DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
- unsigned long highstart_pfn, highend_pfn;
-@@ -394,6 +395,10 @@
- #endif
- __flush_tlb_all();
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ memcpy(kernexec_pg_dir, swapper_pg_dir, sizeof(kernexec_pg_dir));
-+#endif
-+
- kmap_init();
- zone_sizes_init();
- }
-@@ -488,7 +493,7 @@
- set_highmem_pages_init(bad_ppro);
-
- codesize = (unsigned long) &_etext - (unsigned long) &_text;
-- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
-+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
- initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
- kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
-@@ -587,6 +592,42 @@
- totalram_pages++;
- }
- printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ /* PaX: limit KERNEL_CS to actual size */
-+ {
-+ unsigned long limit;
-+ int cpu;
-+ pgd_t *pgd;
-+ pmd_t *pmd;
-+
-+ limit = (unsigned long)&_etext >> PAGE_SHIFT;
-+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
-+ cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].a = (cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
-+ cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].b = (cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
-+
-+#ifdef CONFIG_PCI_BIOS
-+ printk(KERN_INFO "PAX: warning, PCI BIOS might still be in use, keeping flat KERNEL_CS.\n");
-+#endif
-+
-+ }
-+
-+ /* PaX: make KERNEL_CS read-only */
-+ for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
-+ pgd = pgd_offset_k(addr);
-+ pmd = pmd_offset(pgd, addr);
-+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_GLOBAL));
-+ }
-+ memcpy(kernexec_pg_dir, swapper_pg_dir, sizeof(kernexec_pg_dir));
-+ for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
-+ pgd = pgd_offset_k(addr);
-+ pmd = pmd_offset(pgd, addr);
-+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
-+ }
-+ flush_tlb_all();
-+ }
-+#endif
-+
- }
-
- #ifdef CONFIG_BLK_DEV_INITRD
-diff -urN linux-2.6.5/arch/i386/pci/pcbios.c linux-2.6.5/arch/i386/pci/pcbios.c
---- linux-2.6.5/arch/i386/pci/pcbios.c 2004-04-03 22:36:17.000000000 -0500
-+++ linux-2.6.5/arch/i386/pci/pcbios.c 2004-04-18 11:05:50.000000000 -0400
-@@ -6,7 +6,7 @@
- #include <linux/init.h>
- #include "pci.h"
- #include "pci-functions.h"
--
-+#include <asm/desc.h>
-
- /* BIOS32 signature: "_32_" */
- #define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
-@@ -33,6 +33,12 @@
- * and the PCI BIOS specification.
- */
-
-+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
-+#define __FLAT_KERNEL_CS 0x20
-+#else
-+#define __FLAT_KERNEL_CS __KERNEL_CS
-+#endif
-+
- union bios32 {
- struct {
- unsigned long signature; /* _32_ */
-@@ -55,7 +61,7 @@
- static struct {
- unsigned long address;
- unsigned short segment;
--} bios32_indirect = { 0, __KERNEL_CS };
-+} bios32_indirect = { 0, __FLAT_KERNEL_CS };
-
- /*
- * Returns the entry point for the given service, NULL on error
-@@ -96,7 +102,9 @@
- static struct {
- unsigned long address;
- unsigned short segment;
--} pci_indirect = { 0, __KERNEL_CS };
-+} pci_indirect = { 0, __FLAT_KERNEL_CS };
-+
-+#undef __FLAT_KERNEL_CS
-
- static int pci_bios_present;
-
-diff -urN linux-2.6.5/arch/ia64/ia32/binfmt_elf32.c linux-2.6.5/arch/ia64/ia32/binfmt_elf32.c
---- linux-2.6.5/arch/ia64/ia32/binfmt_elf32.c 2004-04-03 22:38:16.000000000 -0500
-+++ linux-2.6.5/arch/ia64/ia32/binfmt_elf32.c 2004-04-18 11:05:50.000000000 -0400
-@@ -41,6 +41,17 @@
- #undef SET_PERSONALITY
- #define SET_PERSONALITY(ex, ibcs2) elf32_set_personality()
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) IA32_PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) IA32_PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) IA32_PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
-+#endif
-+
- /* Ugly but avoids duplication */
- #include "../../../fs/binfmt_elf.c"
-
-@@ -178,7 +189,7 @@
- mpnt->vm_mm = current->mm;
- mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
- mpnt->vm_end = IA32_STACK_TOP;
-- mpnt->vm_page_prot = PAGE_COPY;
-+ mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
- mpnt->vm_flags = VM_STACK_FLAGS;
- mpnt->vm_ops = NULL;
- mpnt->vm_pgoff = 0;
-diff -urN linux-2.6.5/arch/ia64/ia32/ia32priv.h linux-2.6.5/arch/ia64/ia32/ia32priv.h
---- linux-2.6.5/arch/ia64/ia32/ia32priv.h 2004-04-03 22:38:22.000000000 -0500
-+++ linux-2.6.5/arch/ia64/ia32/ia32priv.h 2004-04-18 11:05:50.000000000 -0400
-@@ -295,7 +295,14 @@
- #define ELF_ARCH EM_386
-
- #define IA32_PAGE_OFFSET 0xc0000000
--#define IA32_STACK_TOP IA32_PAGE_OFFSET
-+
-+#ifdef CONFIG_PAX_RANDUSTACK
-+#define __IA32_DELTA_STACK (current->mm->delta_stack)
-+#else
-+#define __IA32_DELTA_STACK 0UL
-+#endif
-+
-+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
-
- /*
- * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can
-diff -urN linux-2.6.5/arch/ia64/ia32/sys_ia32.c linux-2.6.5/arch/ia64/ia32/sys_ia32.c
---- linux-2.6.5/arch/ia64/ia32/sys_ia32.c 2004-04-03 22:37:24.000000000 -0500
-+++ linux-2.6.5/arch/ia64/ia32/sys_ia32.c 2004-04-18 11:05:50.000000000 -0400
-@@ -475,6 +475,11 @@
-
- flags = a.flags;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(a.fd);
-@@ -496,6 +501,11 @@
- struct file *file = NULL;
- unsigned long retval;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
-diff -urN linux-2.6.5/arch/ia64/kernel/ptrace.c linux-2.6.5/arch/ia64/kernel/ptrace.c
---- linux-2.6.5/arch/ia64/kernel/ptrace.c 2004-04-03 22:38:22.000000000 -0500
-+++ linux-2.6.5/arch/ia64/kernel/ptrace.c 2004-04-18 11:05:50.000000000 -0400
-@@ -17,6 +17,7 @@
- #include <linux/smp_lock.h>
- #include <linux/user.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/pgtable.h>
- #include <asm/processor.h>
-@@ -1314,6 +1315,9 @@
- if (pid == 1) /* no messing around with init! */
- goto out_tsk;
-
-+ if (gr_handle_ptrace(child, request))
-+ goto out_tsk;
-+
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
-diff -urN linux-2.6.5/arch/ia64/kernel/sys_ia64.c linux-2.6.5/arch/ia64/kernel/sys_ia64.c
---- linux-2.6.5/arch/ia64/kernel/sys_ia64.c 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/arch/ia64/kernel/sys_ia64.c 2004-04-18 11:05:50.000000000 -0400
-@@ -18,6 +18,7 @@
- #include <linux/syscalls.h>
- #include <linux/highuid.h>
- #include <linux/hugetlb.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/shmparam.h>
- #include <asm/uaccess.h>
-@@ -38,6 +39,13 @@
- if (REGION_NUMBER(addr) == REGION_HPAGE)
- addr = 0;
- #endif
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && addr && filp)
-+ addr = mm->free_area_cache;
-+ else
-+#endif
-+
- if (!addr)
- addr = mm->free_area_cache;
-
-@@ -58,6 +66,13 @@
- if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
- if (start_addr != TASK_UNMAPPED_BASE) {
- /* Start a new search --- just in case we missed some holes. */
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (current->flags & PF_PAX_RANDMMAP)
-+ addr = TASK_UNMAPPED_BASE + mm->delta_mmap;
-+ else
-+#endif
-+
- addr = TASK_UNMAPPED_BASE;
- goto full_search;
- }
-@@ -185,6 +200,11 @@
- unsigned long roff;
- struct file *file = 0;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
-@@ -216,6 +236,11 @@
- goto out;
- }
-
-+ if (gr_handle_mmap(file, prot)) {
-+ addr = -EACCES;
-+ goto out;
-+ }
-+
- down_write(&current->mm->mmap_sem);
- addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up_write(&current->mm->mmap_sem);
-diff -urN linux-2.6.5/arch/ia64/mm/fault.c linux-2.6.5/arch/ia64/mm/fault.c
---- linux-2.6.5/arch/ia64/mm/fault.c 2004-04-03 22:38:20.000000000 -0500
-+++ linux-2.6.5/arch/ia64/mm/fault.c 2004-04-18 11:05:50.000000000 -0400
-@@ -9,6 +9,7 @@
- #include <linux/mm.h>
- #include <linux/smp_lock.h>
- #include <linux/interrupt.h>
-+#include <linux/binfmts.h>
-
- #include <asm/pgtable.h>
- #include <asm/processor.h>
-@@ -70,6 +71,54 @@
- return pte_present(pte);
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/*
-+ * PaX: decide what to do with offenders (regs->cr_iip = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when legitimate ET_EXEC was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ int err;
-+
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ if (regs->cr_iip >= current->mm->start_code &&
-+ regs->cr_iip < current->mm->end_code)
-+ {
-+#if 0
-+ /* PaX: this needs fixing */
-+ if (regs->b0 == regs->cr_iip)
-+ return 1;
-+#endif
-+ regs->cr_iip += current->mm->delta_exec;
-+ return 2;
-+ }
-+ }
-+#endif
-+
-+ return 1;
-+}
-+
-+void pax_report_insns(void *pc, void *sp)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 8; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned int*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
- void
- ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
- {
-@@ -125,9 +174,31 @@
- | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
- | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
-
-- if ((vma->vm_flags & mask) != mask)
-+ if ((vma->vm_flags & mask) != mask) {
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
-+ if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->cr_iip)
-+ goto bad_area;
-+
-+ up_read(&mm->mmap_sem);
-+ switch(pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 2:
-+ return;
-+#endif
-+
-+ }
-+ pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
-+ do_exit(SIGKILL);
-+ }
-+#endif
-+
- goto bad_area;
-
-+ }
-+
- survive:
- /*
- * If for any reason at all we couldn't handle the fault, make
-diff -urN linux-2.6.5/arch/mips/kernel/binfmt_elfn32.c linux-2.6.5/arch/mips/kernel/binfmt_elfn32.c
---- linux-2.6.5/arch/mips/kernel/binfmt_elfn32.c 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/arch/mips/kernel/binfmt_elfn32.c 2004-04-18 11:05:50.000000000 -0400
-@@ -50,6 +50,17 @@
- #undef ELF_ET_DYN_BASE
- #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#endif
-+
- #include <asm/processor.h>
- #include <linux/module.h>
- #include <linux/config.h>
-diff -urN linux-2.6.5/arch/mips/kernel/binfmt_elfo32.c linux-2.6.5/arch/mips/kernel/binfmt_elfo32.c
---- linux-2.6.5/arch/mips/kernel/binfmt_elfo32.c 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/arch/mips/kernel/binfmt_elfo32.c 2004-04-18 11:05:50.000000000 -0400
-@@ -52,6 +52,17 @@
- #undef ELF_ET_DYN_BASE
- #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#endif
-+
- #include <asm/processor.h>
- #include <linux/module.h>
- #include <linux/config.h>
-diff -urN linux-2.6.5/arch/mips/kernel/syscall.c linux-2.6.5/arch/mips/kernel/syscall.c
---- linux-2.6.5/arch/mips/kernel/syscall.c 2004-04-03 22:37:41.000000000 -0500
-+++ linux-2.6.5/arch/mips/kernel/syscall.c 2004-04-18 11:05:50.000000000 -0400
-@@ -79,6 +79,11 @@
- do_color_align = 0;
- if (filp || (flags & MAP_SHARED))
- do_color_align = 1;
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
-+#endif
-+
- if (addr) {
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
-@@ -89,6 +94,13 @@
- (!vmm || addr + len <= vmm->vm_start))
- return addr;
- }
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
-+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
-+ else
-+#endif
-+
- addr = TASK_UNMAPPED_BASE;
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
-diff -urN linux-2.6.5/arch/mips/mm/fault.c linux-2.6.5/arch/mips/mm/fault.c
---- linux-2.6.5/arch/mips/mm/fault.c 2004-04-03 22:36:53.000000000 -0500
-+++ linux-2.6.5/arch/mips/mm/fault.c 2004-04-18 11:05:50.000000000 -0400
-@@ -28,6 +28,24 @@
- #include <asm/uaccess.h>
- #include <asm/ptrace.h>
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+void pax_report_insns(void *pc)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 5; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned int*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
- /*
- * This routine handles page faults. It determines the address,
- * and the problem, and then passes it off to one of the appropriate
-diff -urN linux-2.6.5/arch/parisc/kernel/ptrace.c linux-2.6.5/arch/parisc/kernel/ptrace.c
---- linux-2.6.5/arch/parisc/kernel/ptrace.c 2004-04-03 22:36:19.000000000 -0500
-+++ linux-2.6.5/arch/parisc/kernel/ptrace.c 2004-04-18 11:05:50.000000000 -0400
-@@ -17,6 +17,7 @@
- #include <linux/personality.h>
- #include <linux/security.h>
- #include <linux/compat.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -114,6 +115,9 @@
- if (pid == 1) /* no messing around with init! */
- goto out_tsk;
-
-+ if (gr_handle_ptrace(child, request))
-+ goto out_tsk;
-+
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
-diff -urN linux-2.6.5/arch/parisc/kernel/sys_parisc.c linux-2.6.5/arch/parisc/kernel/sys_parisc.c
---- linux-2.6.5/arch/parisc/kernel/sys_parisc.c 2004-04-03 22:38:12.000000000 -0500
-+++ linux-2.6.5/arch/parisc/kernel/sys_parisc.c 2004-04-18 11:05:50.000000000 -0400
-@@ -31,6 +31,7 @@
- #include <linux/shm.h>
- #include <linux/smp_lock.h>
- #include <linux/syscalls.h>
-+#include <linux/grsecurity.h>
-
- int sys_pipe(int *fildes)
- {
-@@ -114,6 +115,13 @@
- {
- if (len > TASK_SIZE)
- return -ENOMEM;
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
-+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
-+ else
-+#endif
-+
- if (!addr)
- addr = TASK_UNMAPPED_BASE;
-
-@@ -131,12 +139,23 @@
- {
- struct file * file = NULL;
- unsigned long error = -EBADF;
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
- goto out;
- }
-
-+ if (gr_handle_mmap(file, prot)) {
-+ fput(file);
-+ return -EACCES;
-+ }
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
- down_write(&current->mm->mmap_sem);
-diff -urN linux-2.6.5/arch/parisc/kernel/sys_parisc32.c linux-2.6.5/arch/parisc/kernel/sys_parisc32.c
---- linux-2.6.5/arch/parisc/kernel/sys_parisc32.c 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/arch/parisc/kernel/sys_parisc32.c 2004-04-18 11:05:50.000000000 -0400
-@@ -48,6 +48,8 @@
- #include <linux/ptrace.h>
- #include <linux/swap.h>
- #include <linux/syscalls.h>
-+#include <linux/random.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/types.h>
- #include <asm/uaccess.h>
-@@ -171,6 +173,11 @@
- struct file *file;
- int retval;
- int i;
-+#ifdef CONFIG_GRKERNSEC
-+ struct file *old_exec_file;
-+ struct acl_subject_label *old_acl;
-+ struct rlimit old_rlim[RLIM_NLIMITS];
-+#endif
-
- file = open_exec(filename);
-
-@@ -178,7 +185,26 @@
- if (IS_ERR(file))
- return retval;
-
-+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes, 1);
-+
-+ if (gr_handle_nproc()) {
-+ allow_write_access(file);
-+ fput(file);
-+ return -EAGAIN;
-+ }
-+
-+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
-+ allow_write_access(file);
-+ fput(file);
-+ return -EACCES;
-+ }
-+
- bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
-+
-+#ifdef CONFIG_PAX_RANDUSTACK
-+ bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
-+#endif
-+
- memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
-
- DBG(("do_execve32(%s, %p, %p, %p)\n", filename, argv, envp, regs));
-@@ -209,11 +235,24 @@
- if (retval < 0)
- goto out;
-
-+ if (!gr_tpe_allow(file)) {
-+ retval = -EACCES;
-+ goto out;
-+ }
-+
-+ if (gr_check_crash_exec(file)) {
-+ retval = -EACCES;
-+ goto out;
-+ }
-+
- retval = copy_strings_kernel(1, &bprm.filename, &bprm);
- if (retval < 0)
- goto out;
-
- bprm.exec = bprm.p;
-+
-+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
-+
- retval = copy_strings32(bprm.envc, envp, &bprm);
- if (retval < 0)
- goto out;
-@@ -222,10 +261,32 @@
- if (retval < 0)
- goto out;
-
-+#ifdef CONFIG_GRKERNSEC
-+ old_acl = current->acl;
-+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
-+ old_exec_file = current->exec_file;
-+ get_file(file);
-+ current->exec_file = file;
-+#endif
-+
-+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
-+
- retval = search_binary_handler(&bprm,regs);
-- if (retval >= 0)
-+ if (retval >= 0) {
-+#ifdef CONFIG_GRKERNSEC
-+ if (old_exec_file)
-+ fput(old_exec_file);
-+#endif
- /* execve success */
- return retval;
-+ }
-+
-+#ifdef CONFIG_GRKERNSEC
-+ current->acl = old_acl;
-+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
-+ fput(current->exec_file);
-+ current->exec_file = old_exec_file;
-+#endif
-
- out:
- /* Something went wrong, return the inode and free the argument pages*/
-diff -urN linux-2.6.5/arch/parisc/kernel/traps.c linux-2.6.5/arch/parisc/kernel/traps.c
---- linux-2.6.5/arch/parisc/kernel/traps.c 2004-04-03 22:38:27.000000000 -0500
-+++ linux-2.6.5/arch/parisc/kernel/traps.c 2004-04-18 11:05:50.000000000 -0400
-@@ -661,9 +661,7 @@
-
- down_read(&current->mm->mmap_sem);
- vma = find_vma(current->mm,regs->iaoq[0]);
-- if (vma && (regs->iaoq[0] >= vma->vm_start)
-- && (vma->vm_flags & VM_EXEC)) {
--
-+ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
- fault_address = regs->iaoq[0];
- fault_space = regs->iasq[0];
-
-diff -urN linux-2.6.5/arch/parisc/mm/fault.c linux-2.6.5/arch/parisc/mm/fault.c
---- linux-2.6.5/arch/parisc/mm/fault.c 2004-04-03 22:38:13.000000000 -0500
-+++ linux-2.6.5/arch/parisc/mm/fault.c 2004-04-18 11:05:50.000000000 -0400
-@@ -16,6 +16,8 @@
- #include <linux/sched.h>
- #include <linux/interrupt.h>
- #include <linux/module.h>
-+#include <linux/unistd.h>
-+#include <linux/binfmts.h>
-
- #include <asm/uaccess.h>
- #include <asm/traps.h>
-@@ -54,7 +56,7 @@
- static unsigned long
- parisc_acctyp(unsigned long code, unsigned int inst)
- {
-- if (code == 6 || code == 16)
-+ if (code == 6 || code == 7 || code == 16)
- return VM_EXEC;
-
- switch (inst & 0xf0000000) {
-@@ -140,6 +142,139 @@
- }
- #endif
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/*
-+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when rt_sigreturn trampoline was detected
-+ * 3 when unpatched PLT trampoline was detected
-+ * 4 when legitimate ET_EXEC was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+
-+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUTRAMP)
-+ int err;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ if (instruction_pointer(regs) >= current->mm->start_code &&
-+ instruction_pointer(regs) < current->mm->end_code)
-+ {
-+#if 0
-+ /* PaX: this needs fixing */
-+ if ((regs->gr[2] & ~3UL) == instruction_pointer(regs))
-+ return 1;
-+#endif
-+ regs->iaoq[0] += current->mm->delta_exec;
-+ if ((regs->iaoq[1] & ~3UL) >= current->mm->start_code &&
-+ (regs->iaoq[1] & ~3UL) < current->mm->end_code)
-+ regs->iaoq[1] += current->mm->delta_exec;
-+ return 4;
-+ }
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ do { /* PaX: unpatched PLT emulation */
-+ unsigned int bl, depwi;
-+
-+ err = get_user(bl, (unsigned int*)instruction_pointer(regs));
-+ err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
-+
-+ if (err)
-+ break;
-+
-+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
-+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
-+
-+ err = get_user(ldw, (unsigned int*)addr);
-+ err |= get_user(bv, (unsigned int*)(addr+4));
-+ err |= get_user(ldw2, (unsigned int*)(addr+8));
-+
-+ if (err)
-+ break;
-+
-+ if (ldw == 0x0E801096U &&
-+ bv == 0xEAC0C000U &&
-+ ldw2 == 0x0E881095U)
-+ {
-+ unsigned int resolver, map;
-+
-+ err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
-+ err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
-+ if (err)
-+ break;
-+
-+ regs->gr[20] = instruction_pointer(regs)+8;
-+ regs->gr[21] = map;
-+ regs->gr[22] = resolver;
-+ regs->iaoq[0] = resolver | 3UL;
-+ regs->iaoq[1] = regs->iaoq[0] + 4;
-+ return 3;
-+ }
-+ }
-+ } while (0);
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+
-+#ifndef CONFIG_PAX_EMUSIGRT
-+ if (!(current->flags & PF_PAX_EMUTRAMP))
-+ return 1;
-+#endif
-+
-+ do { /* PaX: rt_sigreturn emulation */
-+ unsigned int ldi1, ldi2, bel, nop;
-+
-+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
-+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
-+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
-+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
-+
-+ if (err)
-+ break;
-+
-+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
-+ ldi2 == 0x3414015AU &&
-+ bel == 0xE4008200U &&
-+ nop == 0x08000240U)
-+ {
-+ regs->gr[25] = (ldi1 & 2) >> 1;
-+ regs->gr[20] = __NR_rt_sigreturn;
-+ regs->gr[31] = regs->iaoq[1] + 16;
-+ regs->sr[0] = regs->iasq[1];
-+ regs->iaoq[0] = 0x100UL;
-+ regs->iaoq[1] = regs->iaoq[0] + 4;
-+ regs->iasq[0] = regs->sr[2];
-+ regs->iasq[1] = regs->sr[2];
-+ return 2;
-+ }
-+ } while (0);
-+#endif
-+
-+ return 1;
-+}
-+
-+void pax_report_insns(void *pc, void *sp)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 5; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned int*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
- void do_page_fault(struct pt_regs *regs, unsigned long code,
- unsigned long address)
- {
-@@ -165,8 +300,38 @@
-
- acc_type = parisc_acctyp(code,regs->iir);
-
-- if ((vma->vm_flags & acc_type) != acc_type)
-+ if ((vma->vm_flags & acc_type) != acc_type) {
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if ((current->flags & PF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
-+ (address & ~3UL) == instruction_pointer(regs))
-+ {
-+ up_read(&mm->mmap_sem);
-+ switch(pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 4:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ case 3:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ case 2:
-+ return;
-+#endif
-+
-+ }
-+ pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
-+ do_exit(SIGKILL);
-+ }
-+#endif
-+
- goto bad_area;
-+ }
-
- /*
- * If for any reason at all we couldn't handle the fault, make
-diff -urN linux-2.6.5/arch/ppc/kernel/ptrace.c linux-2.6.5/arch/ppc/kernel/ptrace.c
---- linux-2.6.5/arch/ppc/kernel/ptrace.c 2004-04-03 22:36:52.000000000 -0500
-+++ linux-2.6.5/arch/ppc/kernel/ptrace.c 2004-04-18 11:05:50.000000000 -0400
-@@ -26,6 +26,7 @@
- #include <linux/ptrace.h>
- #include <linux/user.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/page.h>
-@@ -202,6 +203,9 @@
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
-+ if (gr_handle_ptrace(child, request))
-+ goto out_tsk;
-+
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
-diff -urN linux-2.6.5/arch/ppc/kernel/syscalls.c linux-2.6.5/arch/ppc/kernel/syscalls.c
---- linux-2.6.5/arch/ppc/kernel/syscalls.c 2004-04-03 22:38:18.000000000 -0500
-+++ linux-2.6.5/arch/ppc/kernel/syscalls.c 2004-04-18 11:05:50.000000000 -0400
-@@ -36,6 +36,7 @@
- #include <linux/utsname.h>
- #include <linux/file.h>
- #include <linux/unistd.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/ipc.h>
-@@ -165,14 +166,25 @@
- struct file * file = NULL;
- int ret = -EBADF;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- if (!(file = fget(fd)))
- goto out;
- }
-
-+ if (gr_handle_mmap(file, prot)) {
-+ fput(file);
-+ ret = -EACCES;
-+ goto out;
-+ }
-+
- down_write(&current->mm->mmap_sem);
-- ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+ ret = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
- up_write(&current->mm->mmap_sem);
- if (file)
- fput(file);
-diff -urN linux-2.6.5/arch/ppc/mm/fault.c linux-2.6.5/arch/ppc/mm/fault.c
---- linux-2.6.5/arch/ppc/mm/fault.c 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/arch/ppc/mm/fault.c 2004-04-18 11:05:50.000000000 -0400
-@@ -28,6 +28,11 @@
- #include <linux/interrupt.h>
- #include <linux/highmem.h>
- #include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
-+#include <linux/compiler.h>
-+#include <linux/binfmts.h>
-+#include <linux/unistd.h>
-
- #include <asm/page.h>
- #include <asm/pgtable.h>
-@@ -56,6 +61,366 @@
- void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
- extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
-
-+#ifdef CONFIG_PAX_EMUSIGRT
-+void pax_syscall_close(struct vm_area_struct * vma)
-+{
-+ vma->vm_mm->call_syscall = 0UL;
-+}
-+
-+static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
-+{
-+ struct page* page;
-+ unsigned int *kaddr;
-+
-+ page = alloc_page(GFP_HIGHUSER);
-+ if (!page)
-+ return NOPAGE_OOM;
-+
-+ kaddr = kmap(page);
-+ memset(kaddr, 0, PAGE_SIZE);
-+ kaddr[0] = 0x44000002U; /* sc */
-+ __flush_dcache_icache(kaddr);
-+ kunmap(page);
-+ if (type)
-+ *type = VM_FAULT_MAJOR;
-+ return page;
-+}
-+
-+static struct vm_operations_struct pax_vm_ops = {
-+ close: pax_syscall_close,
-+ nopage: pax_syscall_nopage,
-+};
-+
-+static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
-+{
-+ vma->vm_mm = current->mm;
-+ vma->vm_start = addr;
-+ vma->vm_end = addr + PAGE_SIZE;
-+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
-+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
-+ vma->vm_ops = &pax_vm_ops;
-+ vma->vm_pgoff = 0UL;
-+ vma->vm_file = NULL;
-+ vma->vm_private_data = NULL;
-+ INIT_LIST_HEAD(&vma->shared);
-+ insert_vm_struct(current->mm, vma);
-+ ++current->mm->total_vm;
-+}
-+#endif
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/*
-+ * PaX: decide what to do with offenders (regs->nip = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when patched GOT trampoline was detected
-+ * 3 when patched PLT trampoline was detected
-+ * 4 when unpatched PLT trampoline was detected
-+ * 5 when legitimate ET_EXEC was detected
-+ * 6 when sigreturn trampoline was detected
-+ * 7 when rt_sigreturn trampoline was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+
-+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
-+ int err;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ if (regs->nip >= current->mm->start_code &&
-+ regs->nip < current->mm->end_code)
-+ {
-+ if (regs->link == regs->nip)
-+ return 1;
-+
-+ regs->nip += current->mm->delta_exec;
-+ return 5;
-+ }
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ do { /* PaX: patched GOT emulation */
-+ unsigned int blrl;
-+
-+ err = get_user(blrl, (unsigned int*)regs->nip);
-+
-+ if (!err && blrl == 0x4E800021U) {
-+ unsigned long temp = regs->nip;
-+
-+ regs->nip = regs->link & 0xFFFFFFFCUL;
-+ regs->link = temp + 4UL;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: patched PLT emulation #1 */
-+ unsigned int b;
-+
-+ err = get_user(b, (unsigned int *)regs->nip);
-+
-+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
-+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
-+ return 3;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: unpatched PLT emulation #1 */
-+ unsigned int li, b;
-+
-+ err = get_user(li, (unsigned int *)regs->nip);
-+ err |= get_user(b, (unsigned int *)(regs->nip+4));
-+
-+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
-+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
-+ unsigned long addr = b | 0xFC000000UL;
-+
-+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
-+ err = get_user(rlwinm, (unsigned int*)addr);
-+ err |= get_user(add, (unsigned int*)(addr+4));
-+ err |= get_user(li2, (unsigned int*)(addr+8));
-+ err |= get_user(addis2, (unsigned int*)(addr+12));
-+ err |= get_user(mtctr, (unsigned int*)(addr+16));
-+ err |= get_user(li3, (unsigned int*)(addr+20));
-+ err |= get_user(addis3, (unsigned int*)(addr+24));
-+ err |= get_user(bctr, (unsigned int*)(addr+28));
-+
-+ if (err)
-+ break;
-+
-+ if (rlwinm == 0x556C083CU &&
-+ add == 0x7D6C5A14U &&
-+ (li2 & 0xFFFF0000U) == 0x39800000U &&
-+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
-+ mtctr == 0x7D8903A6U &&
-+ (li3 & 0xFFFF0000U) == 0x39800000U &&
-+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
-+ bctr == 0x4E800420U)
-+ {
-+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
-+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
-+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
-+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
-+ regs->ctr += (addis2 & 0xFFFFU) << 16;
-+ regs->nip = regs->ctr;
-+ return 4;
-+ }
-+ }
-+ } while (0);
-+
-+#if 0
-+ do { /* PaX: unpatched PLT emulation #2 */
-+ unsigned int lis, lwzu, b, bctr;
-+
-+ err = get_user(lis, (unsigned int *)regs->nip);
-+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
-+ err |= get_user(b, (unsigned int *)(regs->nip+8));
-+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
-+
-+ if (err)
-+ break;
-+
-+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
-+ (lwzu & 0xU) == 0xU &&
-+ (b & 0xFC000003U) == 0x48000000U &&
-+ bctr == 0x4E800420U)
-+ {
-+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
-+ unsigned long addr = b | 0xFC000000UL;
-+
-+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
-+ err = get_user(addis, (unsigned int*)addr);
-+ err |= get_user(addi, (unsigned int*)(addr+4));
-+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
-+ err |= get_user(add, (unsigned int*)(addr+12));
-+ err |= get_user(li2, (unsigned int*)(addr+16));
-+ err |= get_user(addis2, (unsigned int*)(addr+20));
-+ err |= get_user(mtctr, (unsigned int*)(addr+24));
-+ err |= get_user(li3, (unsigned int*)(addr+28));
-+ err |= get_user(addis3, (unsigned int*)(addr+32));
-+ err |= get_user(bctr, (unsigned int*)(addr+36));
-+
-+ if (err)
-+ break;
-+
-+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
-+ (addi & 0xFFFF0000U) == 0x396B0000U &&
-+ rlwinm == 0x556C083CU &&
-+ add == 0x7D6C5A14U &&
-+ (li2 & 0xFFFF0000U) == 0x39800000U &&
-+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
-+ mtctr == 0x7D8903A6U &&
-+ (li3 & 0xFFFF0000U) == 0x39800000U &&
-+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
-+ bctr == 0x4E800420U)
-+ {
-+ regs->gpr[PT_R11] =
-+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
-+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
-+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
-+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
-+ regs->ctr += (addis2 & 0xFFFFU) << 16;
-+ regs->nip = regs->ctr;
-+ return 4;
-+ }
-+ }
-+ } while (0);
-+#endif
-+
-+ do { /* PaX: unpatched PLT emulation #3 */
-+ unsigned int li, b;
-+
-+ err = get_user(li, (unsigned int *)regs->nip);
-+ err |= get_user(b, (unsigned int *)(regs->nip+4));
-+
-+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
-+ unsigned int addis, lwz, mtctr, bctr;
-+ unsigned long addr = b | 0xFC000000UL;
-+
-+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
-+ err = get_user(addis, (unsigned int*)addr);
-+ err |= get_user(lwz, (unsigned int*)(addr+4));
-+ err |= get_user(mtctr, (unsigned int*)(addr+8));
-+ err |= get_user(bctr, (unsigned int*)(addr+12));
-+
-+ if (err)
-+ break;
-+
-+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
-+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
-+ mtctr == 0x7D6903A6U &&
-+ bctr == 0x4E800420U)
-+ {
-+ unsigned int r11;
-+
-+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
-+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
-+
-+ err = get_user(r11, (unsigned int*)addr);
-+ if (err)
-+ break;
-+
-+ regs->gpr[PT_R11] = r11;
-+ regs->ctr = r11;
-+ regs->nip = r11;
-+ return 4;
-+ }
-+ }
-+ } while (0);
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUSIGRT
-+ do { /* PaX: sigreturn emulation */
-+ unsigned int li, sc;
-+
-+ err = get_user(li, (unsigned int *)regs->nip);
-+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
-+
-+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
-+ struct vm_area_struct *vma;
-+ unsigned long call_syscall;
-+
-+ down_read(&current->mm->mmap_sem);
-+ call_syscall = current->mm->call_syscall;
-+ up_read(&current->mm->mmap_sem);
-+ if (likely(call_syscall))
-+ goto emulate;
-+
-+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-+
-+ down_write(&current->mm->mmap_sem);
-+ if (current->mm->call_syscall) {
-+ call_syscall = current->mm->call_syscall;
-+ up_write(&current->mm->mmap_sem);
-+ if (vma) kmem_cache_free(vm_area_cachep, vma);
-+ goto emulate;
-+ }
-+
-+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
-+ if (!vma || (call_syscall & ~PAGE_MASK)) {
-+ up_write(&current->mm->mmap_sem);
-+ if (vma) kmem_cache_free(vm_area_cachep, vma);
-+ return 1;
-+ }
-+
-+ pax_insert_vma(vma, call_syscall);
-+ current->mm->call_syscall = call_syscall;
-+ up_write(&current->mm->mmap_sem);
-+
-+emulate:
-+ regs->gpr[PT_R0] = __NR_sigreturn;
-+ regs->nip = call_syscall;
-+ return 6;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: rt_sigreturn emulation */
-+ unsigned int li, sc;
-+
-+ err = get_user(li, (unsigned int *)regs->nip);
-+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
-+
-+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
-+ struct vm_area_struct *vma;
-+ unsigned int call_syscall;
-+
-+ down_read(&current->mm->mmap_sem);
-+ call_syscall = current->mm->call_syscall;
-+ up_read(&current->mm->mmap_sem);
-+ if (likely(call_syscall))
-+ goto rt_emulate;
-+
-+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-+
-+ down_write(&current->mm->mmap_sem);
-+ if (current->mm->call_syscall) {
-+ call_syscall = current->mm->call_syscall;
-+ up_write(&current->mm->mmap_sem);
-+ if (vma) kmem_cache_free(vm_area_cachep, vma);
-+ goto rt_emulate;
-+ }
-+
-+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
-+ if (!vma || (call_syscall & ~PAGE_MASK)) {
-+ up_write(&current->mm->mmap_sem);
-+ if (vma) kmem_cache_free(vm_area_cachep, vma);
-+ return 1;
-+ }
-+
-+ pax_insert_vma(vma, call_syscall);
-+ current->mm->call_syscall = call_syscall;
-+ up_write(&current->mm->mmap_sem);
-+
-+rt_emulate:
-+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
-+ regs->nip = call_syscall;
-+ return 7;
-+ }
-+ } while (0);
-+#endif
-+
-+ return 1;
-+}
-+
-+void pax_report_insns(void *pc, void *sp)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 5; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned int*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
- /*
- * Check whether the instruction at regs->nip is a store using
- * an update addressing form which will update r1.
-@@ -116,7 +481,7 @@
- * indicate errors in DSISR but can validly be set in SRR1.
- */
- if (TRAP(regs) == 0x400)
-- error_code &= 0x48200000;
-+ error_code &= 0x58200000;
- else
- is_write = error_code & 0x02000000;
- #endif /* CONFIG_4xx */
-@@ -211,15 +576,14 @@
- } else if (TRAP(regs) == 0x400) {
- pte_t *ptep;
-
--#if 0
-+#if 1
- /* It would be nice to actually enforce the VM execute
- permission on CPUs which can do so, but far too
- much stuff in userspace doesn't get the permissions
- right, so we let any page be executed for now. */
- if (! (vma->vm_flags & VM_EXEC))
- goto bad_area;
--#endif
--
-+#else
- /* Since 4xx supports per-page execute permission,
- * we lazily flush dcache to icache. */
- ptep = NULL;
-@@ -240,6 +604,7 @@
- if (ptep != NULL)
- pte_unmap(ptep);
- #endif
-+#endif
- /* a read */
- } else {
- /* protection fault */
-@@ -285,6 +650,38 @@
-
- /* User mode accesses cause a SIGSEGV */
- if (user_mode(regs)) {
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (current->flags & PF_PAX_PAGEEXEC) {
-+ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
-+ switch (pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ case 2:
-+ case 3:
-+ case 4:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 5:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUSIGRT
-+ case 6:
-+ case 7:
-+ return;
-+#endif
-+
-+ }
-+
-+ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
-+ do_exit(SIGKILL);
-+ }
-+ }
-+#endif
-+
- info.si_signo = SIGSEGV;
- info.si_errno = 0;
- info.si_code = code;
-diff -urN linux-2.6.5/arch/sparc/kernel/ptrace.c linux-2.6.5/arch/sparc/kernel/ptrace.c
---- linux-2.6.5/arch/sparc/kernel/ptrace.c 2004-04-03 22:38:24.000000000 -0500
-+++ linux-2.6.5/arch/sparc/kernel/ptrace.c 2004-04-18 11:05:50.000000000 -0400
-@@ -18,6 +18,7 @@
- #include <linux/smp.h>
- #include <linux/smp_lock.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/pgtable.h>
- #include <asm/system.h>
-@@ -320,6 +321,11 @@
- goto out;
- }
-
-+ if (gr_handle_ptrace(child, request)) {
-+ pt_error_return(regs, EPERM);
-+ goto out_tsk;
-+ }
-+
- if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
- || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
- if (ptrace_attach(child)) {
-diff -urN linux-2.6.5/arch/sparc/kernel/sys_sparc.c linux-2.6.5/arch/sparc/kernel/sys_sparc.c
---- linux-2.6.5/arch/sparc/kernel/sys_sparc.c 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/arch/sparc/kernel/sys_sparc.c 2004-04-18 11:05:50.000000000 -0400
-@@ -21,6 +21,7 @@
- #include <linux/utsname.h>
- #include <linux/smp.h>
- #include <linux/smp_lock.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/ipc.h>
-@@ -55,6 +56,13 @@
- return -ENOMEM;
- if (ARCH_SUN4C_SUN4 && len > 0x20000000)
- return -ENOMEM;
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
-+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
-+ else
-+#endif
-+
- if (!addr)
- addr = TASK_UNMAPPED_BASE;
-
-@@ -224,6 +232,11 @@
- struct file * file = NULL;
- unsigned long retval = -EBADF;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
-@@ -242,6 +255,12 @@
- if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
- goto out_putf;
-
-+ if (gr_handle_mmap(file, prot)) {
-+ fput(file);
-+ retval = -EACCES;
-+ goto out;
-+ }
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
- down_write(&current->mm->mmap_sem);
-diff -urN linux-2.6.5/arch/sparc/kernel/sys_sunos.c linux-2.6.5/arch/sparc/kernel/sys_sunos.c
---- linux-2.6.5/arch/sparc/kernel/sys_sunos.c 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/arch/sparc/kernel/sys_sunos.c 2004-04-18 11:05:50.000000000 -0400
-@@ -71,6 +71,11 @@
- struct file * file = NULL;
- unsigned long retval, ret_type;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if(flags & MAP_NORESERVE) {
- static int cnt;
- if (cnt++ < 10)
-diff -urN linux-2.6.5/arch/sparc/mm/fault.c linux-2.6.5/arch/sparc/mm/fault.c
---- linux-2.6.5/arch/sparc/mm/fault.c 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/arch/sparc/mm/fault.c 2004-04-18 11:05:50.000000000 -0400
-@@ -21,6 +21,10 @@
- #include <linux/smp_lock.h>
- #include <linux/interrupt.h>
- #include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
-+#include <linux/compiler.h>
-+#include <linux/binfmts.h>
-
- #include <asm/system.h>
- #include <asm/segment.h>
-@@ -201,6 +205,272 @@
- return 0;
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+void pax_emuplt_close(struct vm_area_struct * vma)
-+{
-+ vma->vm_mm->call_dl_resolve = 0UL;
-+}
-+
-+static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
-+{
-+ struct page* page;
-+ unsigned int *kaddr;
-+
-+ page = alloc_page(GFP_HIGHUSER);
-+ if (!page)
-+ return NOPAGE_OOM;
-+
-+ kaddr = kmap(page);
-+ memset(kaddr, 0, PAGE_SIZE);
-+ kaddr[0] = 0x9DE3BFA8U; /* save */
-+ flush_dcache_page(page);
-+ kunmap(page);
-+ if (type)
-+ *type = VM_FAULT_MAJOR;
-+
-+ return page;
-+}
-+
-+static struct vm_operations_struct pax_vm_ops = {
-+ close: pax_emuplt_close,
-+ nopage: pax_emuplt_nopage,
-+};
-+
-+static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
-+{
-+ vma->vm_mm = current->mm;
-+ vma->vm_start = addr;
-+ vma->vm_end = addr + PAGE_SIZE;
-+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
-+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
-+ vma->vm_ops = &pax_vm_ops;
-+ vma->vm_pgoff = 0UL;
-+ vma->vm_file = NULL;
-+ vma->vm_private_data = NULL;
-+ INIT_LIST_HEAD(&vma->shared);
-+ insert_vm_struct(current->mm, vma);
-+ ++current->mm->total_vm;
-+}
-+
-+/*
-+ * PaX: decide what to do with offenders (regs->pc = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when patched PLT trampoline was detected
-+ * 3 when unpatched PLT trampoline was detected
-+ * 4 when legitimate ET_EXEC was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ int err;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ if (regs->pc >= current->mm->start_code &&
-+ regs->pc < current->mm->end_code)
-+ {
-+ if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc)
-+ return 1;
-+
-+ regs->pc += current->mm->delta_exec;
-+ if (regs->npc >= current->mm->start_code &&
-+ regs->npc < current->mm->end_code)
-+ regs->npc += current->mm->delta_exec;
-+ return 4;
-+ }
-+ if (regs->pc >= current->mm->start_code + current->mm->delta_exec &&
-+ regs->pc < current->mm->end_code + current->mm->delta_exec)
-+ {
-+ regs->pc -= current->mm->delta_exec;
-+ if (regs->npc >= current->mm->start_code + current->mm->delta_exec &&
-+ regs->npc < current->mm->end_code + current->mm->delta_exec)
-+ regs->npc -= current->mm->delta_exec;
-+ }
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ do { /* PaX: patched PLT emulation #1 */
-+ unsigned int sethi1, sethi2, jmpl;
-+
-+ err = get_user(sethi1, (unsigned int*)regs->pc);
-+ err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
-+ err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
-+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
-+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
-+ {
-+ unsigned int addr;
-+
-+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
-+ addr = regs->u_regs[UREG_G1];
-+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
-+ regs->pc = addr;
-+ regs->npc = addr+4;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ { /* PaX: patched PLT emulation #2 */
-+ unsigned int ba;
-+
-+ err = get_user(ba, (unsigned int*)regs->pc);
-+
-+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
-+ unsigned int addr;
-+
-+ addr = regs->pc + 4 + (((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U);
-+ regs->pc = addr;
-+ regs->npc = addr+4;
-+ return 2;
-+ }
-+ }
-+
-+ do { /* PaX: patched PLT emulation #3 */
-+ unsigned int sethi, jmpl, nop;
-+
-+ err = get_user(sethi, (unsigned int*)regs->pc);
-+ err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
-+ err |= get_user(nop, (unsigned int*)(regs->pc+8));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
-+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned int addr;
-+
-+ addr = (sethi & 0x003FFFFFU) << 10;
-+ regs->u_regs[UREG_G1] = addr;
-+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
-+ regs->pc = addr;
-+ regs->npc = addr+4;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: unpatched PLT emulation step 1 */
-+ unsigned int sethi, ba, nop;
-+
-+ err = get_user(sethi, (unsigned int*)regs->pc);
-+ err |= get_user(ba, (unsigned int*)(regs->pc+4));
-+ err |= get_user(nop, (unsigned int*)(regs->pc+8));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
-+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned int addr, save, call;
-+
-+ if ((ba & 0xFFC00000U) == 0x30800000U)
-+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
-+ else
-+ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
-+
-+ err = get_user(save, (unsigned int*)addr);
-+ err |= get_user(call, (unsigned int*)(addr+4));
-+ err |= get_user(nop, (unsigned int*)(addr+8));
-+ if (err)
-+ break;
-+
-+ if (save == 0x9DE3BFA8U &&
-+ (call & 0xC0000000U) == 0x40000000U &&
-+ nop == 0x01000000U)
-+ {
-+ struct vm_area_struct *vma;
-+ unsigned long call_dl_resolve;
-+
-+ down_read(&current->mm->mmap_sem);
-+ call_dl_resolve = current->mm->call_dl_resolve;
-+ up_read(&current->mm->mmap_sem);
-+ if (likely(call_dl_resolve))
-+ goto emulate;
-+
-+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-+
-+ down_write(&current->mm->mmap_sem);
-+ if (current->mm->call_dl_resolve) {
-+ call_dl_resolve = current->mm->call_dl_resolve;
-+ up_write(&current->mm->mmap_sem);
-+ if (vma) kmem_cache_free(vm_area_cachep, vma);
-+ goto emulate;
-+ }
-+
-+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
-+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
-+ up_write(&current->mm->mmap_sem);
-+ if (vma) kmem_cache_free(vm_area_cachep, vma);
-+ return 1;
-+ }
-+
-+ pax_insert_vma(vma, call_dl_resolve);
-+ current->mm->call_dl_resolve = call_dl_resolve;
-+ up_write(&current->mm->mmap_sem);
-+
-+emulate:
-+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
-+ regs->pc = call_dl_resolve;
-+ regs->npc = addr+4;
-+ return 3;
-+ }
-+ }
-+ } while (0);
-+
-+ do { /* PaX: unpatched PLT emulation step 2 */
-+ unsigned int save, call, nop;
-+
-+ err = get_user(save, (unsigned int*)(regs->pc-4));
-+ err |= get_user(call, (unsigned int*)regs->pc);
-+ err |= get_user(nop, (unsigned int*)(regs->pc+4));
-+ if (err)
-+ break;
-+
-+ if (save == 0x9DE3BFA8U &&
-+ (call & 0xC0000000U) == 0x40000000U &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
-+
-+ regs->u_regs[UREG_RETPC] = regs->pc;
-+ regs->pc = dl_resolve;
-+ regs->npc = dl_resolve+4;
-+ return 3;
-+ }
-+ } while (0);
-+#endif
-+
-+ return 1;
-+}
-+
-+void pax_report_insns(void *pc, void *sp)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 5; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned int*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
- asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
- unsigned long address)
- {
-@@ -264,6 +534,29 @@
- if(!(vma->vm_flags & VM_WRITE))
- goto bad_area;
- } else {
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if ((current->flags & PF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
-+ up_read(&mm->mmap_sem);
-+ switch (pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ case 2:
-+ case 3:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 4:
-+ return;
-+#endif
-+
-+ }
-+ pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
-+ do_exit(SIGKILL);
-+ }
-+#endif
-+
- /* Allow reads even for write-only mappings */
- if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
- goto bad_area;
-diff -urN linux-2.6.5/arch/sparc/mm/init.c linux-2.6.5/arch/sparc/mm/init.c
---- linux-2.6.5/arch/sparc/mm/init.c 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/arch/sparc/mm/init.c 2004-04-18 11:05:50.000000000 -0400
-@@ -337,17 +337,17 @@
-
- /* Initialize the protection map with non-constant, MMU dependent values. */
- protection_map[0] = PAGE_NONE;
-- protection_map[1] = PAGE_READONLY;
-- protection_map[2] = PAGE_COPY;
-- protection_map[3] = PAGE_COPY;
-+ protection_map[1] = PAGE_READONLY_NOEXEC;
-+ protection_map[2] = PAGE_COPY_NOEXEC;
-+ protection_map[3] = PAGE_COPY_NOEXEC;
- protection_map[4] = PAGE_READONLY;
- protection_map[5] = PAGE_READONLY;
- protection_map[6] = PAGE_COPY;
- protection_map[7] = PAGE_COPY;
- protection_map[8] = PAGE_NONE;
-- protection_map[9] = PAGE_READONLY;
-- protection_map[10] = PAGE_SHARED;
-- protection_map[11] = PAGE_SHARED;
-+ protection_map[9] = PAGE_READONLY_NOEXEC;
-+ protection_map[10] = PAGE_SHARED_NOEXEC;
-+ protection_map[11] = PAGE_SHARED_NOEXEC;
- protection_map[12] = PAGE_READONLY;
- protection_map[13] = PAGE_READONLY;
- protection_map[14] = PAGE_SHARED;
-diff -urN linux-2.6.5/arch/sparc/mm/srmmu.c linux-2.6.5/arch/sparc/mm/srmmu.c
---- linux-2.6.5/arch/sparc/mm/srmmu.c 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/arch/sparc/mm/srmmu.c 2004-04-18 11:05:50.000000000 -0400
-@@ -2138,6 +2138,13 @@
- BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
- BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
- BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
-+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
-+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
-+#endif
-+
- BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
- page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
- pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
-diff -urN linux-2.6.5/arch/sparc64/kernel/itlb_base.S linux-2.6.5/arch/sparc64/kernel/itlb_base.S
---- linux-2.6.5/arch/sparc64/kernel/itlb_base.S 2004-04-03 22:36:18.000000000 -0500
-+++ linux-2.6.5/arch/sparc64/kernel/itlb_base.S 2004-04-18 11:05:50.000000000 -0400
-@@ -41,7 +41,9 @@
- CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
- ldxa [%g3 + %g6] ASI_P, %g5 ! Load VPTE
- 1: brgez,pn %g5, 3f ! Not valid, branch out
-- nop ! Delay-slot
-+ and %g5, _PAGE_EXEC, %g4
-+ brz,pn %g4, 3f ! Not executable, branch out
-+ nop ! Delay-slot
- 2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB
- retry ! Trap return
- 3: rdpr %pstate, %g4 ! Move into alternate globals
-@@ -74,8 +76,6 @@
- nop
- nop
- nop
-- nop
-- nop
- CREATE_VPTE_NOP
-
- #undef CREATE_VPTE_OFFSET1
-diff -urN linux-2.6.5/arch/sparc64/kernel/ptrace.c linux-2.6.5/arch/sparc64/kernel/ptrace.c
---- linux-2.6.5/arch/sparc64/kernel/ptrace.c 2004-04-03 22:38:22.000000000 -0500
-+++ linux-2.6.5/arch/sparc64/kernel/ptrace.c 2004-04-18 11:05:50.000000000 -0400
-@@ -19,6 +19,7 @@
- #include <linux/smp.h>
- #include <linux/smp_lock.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/asi.h>
- #include <asm/pgtable.h>
-@@ -169,6 +170,11 @@
- goto out;
- }
-
-+ if (gr_handle_ptrace(child, (long)request)) {
-+ pt_error_return(regs, EPERM);
-+ goto out_tsk;
-+ }
-+
- if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
- || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
- if (ptrace_attach(child)) {
-diff -urN linux-2.6.5/arch/sparc64/kernel/sys_sparc.c linux-2.6.5/arch/sparc64/kernel/sys_sparc.c
---- linux-2.6.5/arch/sparc64/kernel/sys_sparc.c 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/arch/sparc64/kernel/sys_sparc.c 2004-04-18 11:05:50.000000000 -0400
-@@ -25,6 +25,7 @@
- #include <linux/syscalls.h>
- #include <linux/ipc.h>
- #include <linux/personality.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/ipc.h>
-@@ -71,6 +72,10 @@
- if (filp || (flags & MAP_SHARED))
- do_color_align = 1;
-
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
-+#endif
-+
- if (addr) {
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
-@@ -101,6 +106,13 @@
- }
- if (task_size < addr) {
- if (start_addr != TASK_UNMAPPED_BASE) {
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (current->flags & PF_PAX_RANDMMAP)
-+ start_addr = addr = TASK_UNMAPPED_BASE + mm->delta_mmap;
-+ else
-+#endif
-+
- start_addr = addr = TASK_UNMAPPED_BASE;
- goto full_search;
- }
-@@ -310,11 +322,22 @@
- struct file * file = NULL;
- unsigned long retval = -EBADF;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
- goto out;
- }
-+
-+ if (gr_handle_mmap(file, prot)) {
-+ retval = -EACCES;
-+ goto out_putf;
-+ }
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- len = PAGE_ALIGN(len);
- retval = -EINVAL;
-diff -urN linux-2.6.5/arch/sparc64/kernel/sys_sparc32.c linux-2.6.5/arch/sparc64/kernel/sys_sparc32.c
---- linux-2.6.5/arch/sparc64/kernel/sys_sparc32.c 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/arch/sparc64/kernel/sys_sparc32.c 2004-04-18 11:05:50.000000000 -0400
-@@ -54,6 +54,8 @@
- #include <linux/netfilter_ipv4/ip_tables.h>
- #include <linux/ptrace.h>
- #include <linux/highuid.h>
-+#include <linux/random.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/types.h>
- #include <asm/ipc.h>
-@@ -1759,6 +1761,11 @@
- struct file * file;
- int retval;
- int i;
-+#ifdef CONFIG_GRKERNSEC
-+ struct file *old_exec_file;
-+ struct acl_subject_label *old_acl;
-+ struct rlimit old_rlim[RLIM_NLIMITS];
-+#endif
-
- sched_balance_exec();
-
-@@ -1768,7 +1775,26 @@
- if (IS_ERR(file))
- return retval;
-
-+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
-+
-+ if (gr_handle_nproc()) {
-+ allow_write_access(file);
-+ fput(file);
-+ return -EAGAIN;
-+ }
-+
-+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
-+ allow_write_access(file);
-+ fput(file);
-+ return -EACCES;
-+ }
-+
- bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
-+
-+#ifdef CONFIG_PAX_RANDUSTACK
-+ bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
-+#endif
-+
- memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
-
- bprm.file = file;
-@@ -1803,11 +1829,24 @@
- if (retval < 0)
- goto out;
-
-+ if (!gr_tpe_allow(file)) {
-+ retval = -EACCES;
-+ goto out;
-+ }
-+
-+ if (gr_check_crash_exec(file)) {
-+ retval = -EACCES;
-+ goto out;
-+ }
-+
- retval = copy_strings_kernel(1, &bprm.filename, &bprm);
- if (retval < 0)
- goto out;
-
- bprm.exec = bprm.p;
-+
-+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
-+
- retval = copy_strings32(bprm.envc, envp, &bprm);
- if (retval < 0)
- goto out;
-@@ -1816,13 +1855,34 @@
- if (retval < 0)
- goto out;
-
-+#ifdef CONFIG_GRKERNSEC
-+ old_acl = current->acl;
-+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
-+ old_exec_file = current->exec_file;
-+ get_file(file);
-+ current->exec_file = file;
-+#endif
-+
-+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
-+
- retval = search_binary_handler(&bprm, regs);
- if (retval >= 0) {
- /* execve success */
-+#ifdef CONFIG_GRKERNSEC
-+ if (old_exec_file)
-+ fput(old_exec_file);
-+#endif
- security_bprm_free(&bprm);
- return retval;
- }
-
-+#ifdef CONFIG_GRKERNSEC
-+ current->acl = old_acl;
-+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
-+ fput(current->exec_file);
-+ current->exec_file = old_exec_file;
-+#endif
-+
- out:
- /* Something went wrong, return the inode and free the argument pages*/
- for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
-diff -urN linux-2.6.5/arch/sparc64/kernel/sys_sunos32.c linux-2.6.5/arch/sparc64/kernel/sys_sunos32.c
---- linux-2.6.5/arch/sparc64/kernel/sys_sunos32.c 2004-04-03 22:37:24.000000000 -0500
-+++ linux-2.6.5/arch/sparc64/kernel/sys_sunos32.c 2004-04-18 11:05:50.000000000 -0400
-@@ -75,6 +75,11 @@
- struct file *file = NULL;
- unsigned long retval, ret_type;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if (flags & MAP_NORESERVE) {
- static int cnt;
- if (cnt++ < 10)
-diff -urN linux-2.6.5/arch/sparc64/mm/fault.c linux-2.6.5/arch/sparc64/mm/fault.c
---- linux-2.6.5/arch/sparc64/mm/fault.c 2004-04-03 22:38:20.000000000 -0500
-+++ linux-2.6.5/arch/sparc64/mm/fault.c 2004-04-18 11:05:50.000000000 -0400
-@@ -18,6 +18,10 @@
- #include <linux/smp_lock.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
-+#include <linux/compiler.h>
-+#include <linux/binfmts.h>
-
- #include <asm/page.h>
- #include <asm/pgtable.h>
-@@ -303,6 +307,364 @@
- unhandled_fault (address, current, regs);
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_EMUPLT
-+static void pax_emuplt_close(struct vm_area_struct * vma)
-+{
-+ vma->vm_mm->call_dl_resolve = 0UL;
-+}
-+
-+static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
-+{
-+ struct page* page;
-+ unsigned int *kaddr;
-+
-+ page = alloc_page(GFP_HIGHUSER);
-+ if (!page)
-+ return NOPAGE_OOM;
-+
-+ kaddr = kmap(page);
-+ memset(kaddr, 0, PAGE_SIZE);
-+ kaddr[0] = 0x9DE3BFA8U; /* save */
-+ flush_dcache_page(page);
-+ kunmap(page);
-+ if (type)
-+ *type = VM_FAULT_MAJOR;
-+ return page;
-+}
-+
-+static struct vm_operations_struct pax_vm_ops = {
-+ close: pax_emuplt_close,
-+ nopage: pax_emuplt_nopage,
-+};
-+
-+static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
-+{
-+ vma->vm_mm = current->mm;
-+ vma->vm_start = addr;
-+ vma->vm_end = addr + PAGE_SIZE;
-+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
-+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
-+ vma->vm_ops = &pax_vm_ops;
-+ vma->vm_pgoff = 0UL;
-+ vma->vm_file = NULL;
-+ vma->vm_private_data = NULL;
-+ INIT_LIST_HEAD(&vma->shared);
-+ insert_vm_struct(current->mm, vma);
-+ ++current->mm->total_vm;
-+}
-+#endif
-+
-+/*
-+ * PaX: decide what to do with offenders (regs->tpc = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when patched PLT trampoline was detected
-+ * 3 when unpatched PLT trampoline was detected
-+ * 4 when legitimate ET_EXEC was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ int err;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ if (regs->tpc >= current->mm->start_code &&
-+ regs->tpc < current->mm->end_code)
-+ {
-+ if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc)
-+ return 1;
-+
-+ regs->tpc += current->mm->delta_exec;
-+ if (regs->tnpc >= current->mm->start_code &&
-+ regs->tnpc < current->mm->end_code)
-+ regs->tnpc += current->mm->delta_exec;
-+ return 4;
-+ }
-+ if (regs->tpc >= current->mm->start_code + current->mm->delta_exec &&
-+ regs->tpc < current->mm->end_code + current->mm->delta_exec)
-+ {
-+ regs->tpc -= current->mm->delta_exec;
-+ if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec &&
-+ regs->tnpc < current->mm->end_code + current->mm->delta_exec)
-+ regs->tnpc -= current->mm->delta_exec;
-+ }
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ do { /* PaX: patched PLT emulation #1 */
-+ unsigned int sethi1, sethi2, jmpl;
-+
-+ err = get_user(sethi1, (unsigned int*)regs->tpc);
-+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
-+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
-+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
-+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
-+ {
-+ unsigned long addr;
-+
-+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
-+ addr = regs->u_regs[UREG_G1];
-+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
-+ regs->tpc = addr;
-+ regs->tnpc = addr+4;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ { /* PaX: patched PLT emulation #2 */
-+ unsigned int ba;
-+
-+ err = get_user(ba, (unsigned int*)regs->tpc);
-+
-+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
-+ unsigned long addr;
-+
-+ addr = regs->tpc + 4 + (((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL);
-+ regs->tpc = addr;
-+ regs->tnpc = addr+4;
-+ return 2;
-+ }
-+ }
-+
-+ do { /* PaX: patched PLT emulation #3 */
-+ unsigned int sethi, jmpl, nop;
-+
-+ err = get_user(sethi, (unsigned int*)regs->tpc);
-+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
-+ err |= get_user(nop, (unsigned int*)(regs->tpc+8));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
-+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned long addr;
-+
-+ addr = (sethi & 0x003FFFFFU) << 10;
-+ regs->u_regs[UREG_G1] = addr;
-+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
-+ regs->tpc = addr;
-+ regs->tnpc = addr+4;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: patched PLT emulation #4 */
-+ unsigned int mov1, call, mov2;
-+
-+ err = get_user(mov1, (unsigned int*)regs->tpc);
-+ err |= get_user(call, (unsigned int*)(regs->tpc+4));
-+ err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
-+
-+ if (err)
-+ break;
-+
-+ if (mov1 == 0x8210000FU &&
-+ (call & 0xC0000000U) == 0x40000000U &&
-+ mov2 == 0x9E100001U)
-+ {
-+ unsigned long addr;
-+
-+ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
-+ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
-+ regs->tpc = addr;
-+ regs->tnpc = addr+4;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: patched PLT emulation #5 */
-+ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
-+
-+ err = get_user(sethi1, (unsigned int*)regs->tpc);
-+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
-+ err |= get_user(or1, (unsigned int*)(regs->tpc+8));
-+ err |= get_user(or2, (unsigned int*)(regs->tpc+12));
-+ err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
-+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
-+ err |= get_user(nop, (unsigned int*)(regs->tpc+24));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
-+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
-+ (or1 & 0xFFFFE000U) == 0x82106000U &&
-+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
-+ sllx == 0x83287020 &&
-+ jmpl == 0x81C04005U &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned long addr;
-+
-+ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
-+ regs->u_regs[UREG_G1] <<= 32;
-+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
-+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
-+ regs->tpc = addr;
-+ regs->tnpc = addr+4;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: patched PLT emulation #6 */
-+ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
-+
-+ err = get_user(sethi1, (unsigned int*)regs->tpc);
-+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
-+ err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
-+ err |= get_user(or, (unsigned int*)(regs->tpc+12));
-+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
-+ err |= get_user(nop, (unsigned int*)(regs->tpc+20));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
-+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
-+ sllx == 0x83287020 &&
-+ (or & 0xFFFFE000U) == 0x8A116000U &&
-+ jmpl == 0x81C04005U &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned long addr;
-+
-+ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
-+ regs->u_regs[UREG_G1] <<= 32;
-+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
-+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
-+ regs->tpc = addr;
-+ regs->tnpc = addr+4;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: unpatched PLT emulation step 1 */
-+ unsigned int sethi, ba, nop;
-+
-+ err = get_user(sethi, (unsigned int*)regs->tpc);
-+ err |= get_user(ba, (unsigned int*)(regs->tpc+4));
-+ err |= get_user(nop, (unsigned int*)(regs->tpc+8));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
-+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned long addr;
-+ unsigned int save, call;
-+
-+ if ((ba & 0xFFC00000U) == 0x30800000U)
-+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
-+ else
-+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
-+
-+ err = get_user(save, (unsigned int*)addr);
-+ err |= get_user(call, (unsigned int*)(addr+4));
-+ err |= get_user(nop, (unsigned int*)(addr+8));
-+ if (err)
-+ break;
-+
-+ if (save == 0x9DE3BFA8U &&
-+ (call & 0xC0000000U) == 0x40000000U &&
-+ nop == 0x01000000U)
-+ {
-+ struct vm_area_struct *vma;
-+ unsigned long call_dl_resolve;
-+
-+ down_read(&current->mm->mmap_sem);
-+ call_dl_resolve = current->mm->call_dl_resolve;
-+ up_read(&current->mm->mmap_sem);
-+ if (likely(call_dl_resolve))
-+ goto emulate;
-+
-+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-+
-+ down_write(&current->mm->mmap_sem);
-+ if (current->mm->call_dl_resolve) {
-+ call_dl_resolve = current->mm->call_dl_resolve;
-+ up_write(&current->mm->mmap_sem);
-+ if (vma) kmem_cache_free(vm_area_cachep, vma);
-+ goto emulate;
-+ }
-+
-+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
-+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
-+ up_write(&current->mm->mmap_sem);
-+ if (vma) kmem_cache_free(vm_area_cachep, vma);
-+ return 1;
-+ }
-+
-+ pax_insert_vma(vma, call_dl_resolve);
-+ current->mm->call_dl_resolve = call_dl_resolve;
-+ up_write(&current->mm->mmap_sem);
-+
-+emulate:
-+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
-+ regs->tpc = call_dl_resolve;
-+ regs->tnpc = addr+4;
-+ return 3;
-+ }
-+ }
-+ } while (0);
-+
-+ do { /* PaX: unpatched PLT emulation step 2 */
-+ unsigned int save, call, nop;
-+
-+ err = get_user(save, (unsigned int*)(regs->tpc-4));
-+ err |= get_user(call, (unsigned int*)regs->tpc);
-+ err |= get_user(nop, (unsigned int*)(regs->tpc+4));
-+ if (err)
-+ break;
-+
-+ if (save == 0x9DE3BFA8U &&
-+ (call & 0xC0000000U) == 0x40000000U &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
-+
-+ regs->u_regs[UREG_RETPC] = regs->tpc;
-+ regs->tpc = dl_resolve;
-+ regs->tnpc = dl_resolve+4;
-+ return 3;
-+ }
-+ } while (0);
-+#endif
-+
-+ return 1;
-+}
-+
-+void pax_report_insns(void *pc, void *sp)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 5; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned int*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
- asmlinkage void do_sparc64_fault(struct pt_regs *regs)
- {
- struct mm_struct *mm = current->mm;
-@@ -340,8 +702,10 @@
- goto intr_or_no_mm;
-
- if (test_thread_flag(TIF_32BIT)) {
-- if (!(regs->tstate & TSTATE_PRIV))
-+ if (!(regs->tstate & TSTATE_PRIV)) {
- regs->tpc &= 0xffffffff;
-+ regs->tnpc &= 0xffffffff;
-+ }
- address &= 0xffffffff;
- }
-
-@@ -350,6 +714,34 @@
- if (!vma)
- goto bad_area;
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ /* PaX: detect ITLB misses on non-exec pages */
-+ if ((current->flags & PF_PAX_PAGEEXEC) && vma->vm_start <= address &&
-+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
-+ {
-+ if (address != regs->tpc)
-+ goto good_area;
-+
-+ up_read(&mm->mmap_sem);
-+ switch (pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ case 2:
-+ case 3:
-+ goto fault_done;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 4:
-+ goto fault_done;
-+#endif
-+
-+ }
-+ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
-+ do_exit(SIGKILL);
-+ }
-+#endif
-+
- /* Pure DTLB misses do not tell us whether the fault causing
- * load/store/atomic was a write or not, it only says that there
- * was no match. So in such a case we (carefully) read the
-diff -urN linux-2.6.5/arch/sparc64/solaris/misc.c linux-2.6.5/arch/sparc64/solaris/misc.c
---- linux-2.6.5/arch/sparc64/solaris/misc.c 2004-04-03 22:38:19.000000000 -0500
-+++ linux-2.6.5/arch/sparc64/solaris/misc.c 2004-04-18 11:05:50.000000000 -0400
-@@ -56,6 +56,11 @@
- struct file *file = NULL;
- unsigned long retval, ret_type;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- /* Do we need it here? */
- set_personality(PER_SVR4);
- if (flags & MAP_NORESERVE) {
-diff -urN linux-2.6.5/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.5/arch/x86_64/ia32/ia32_binfmt.c
---- linux-2.6.5/arch/x86_64/ia32/ia32_binfmt.c 2004-04-03 22:36:15.000000000 -0500
-+++ linux-2.6.5/arch/x86_64/ia32/ia32_binfmt.c 2004-04-18 11:05:50.000000000 -0400
-@@ -185,6 +185,17 @@
- //#include <asm/ia32.h>
- #include <linux/elf.h>
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 24)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 24)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 24)
-+#endif
-+
- typedef struct user_i387_ia32_struct elf_fpregset_t;
- typedef struct user32_fxsr_struct elf_fpxregset_t;
-
-@@ -354,7 +365,13 @@
- mpnt->vm_mm = mm;
- mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
- mpnt->vm_end = IA32_STACK_TOP;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ mpnt->vm_flags = VM_STACK_FLAGS;
-+#else
- mpnt->vm_flags = vm_stack_flags32;
-+#endif
-+
- mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ?
- PAGE_COPY_EXEC : PAGE_COPY;
- mpnt->vm_ops = NULL;
-diff -urN linux-2.6.5/arch/x86_64/ia32/sys_ia32.c linux-2.6.5/arch/x86_64/ia32/sys_ia32.c
---- linux-2.6.5/arch/x86_64/ia32/sys_ia32.c 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/arch/x86_64/ia32/sys_ia32.c 2004-04-18 11:05:50.000000000 -0400
-@@ -1235,6 +1235,11 @@
- unsigned long error;
- struct file * file = NULL;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
-diff -urN linux-2.6.5/arch/x86_64/kernel/ptrace.c linux-2.6.5/arch/x86_64/kernel/ptrace.c
---- linux-2.6.5/arch/x86_64/kernel/ptrace.c 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/arch/x86_64/kernel/ptrace.c 2004-04-18 11:05:50.000000000 -0400
-@@ -16,6 +16,7 @@
- #include <linux/ptrace.h>
- #include <linux/user.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -212,6 +213,9 @@
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
-+ if (gr_handle_ptrace(child, request))
-+ goto out_tsk;
-+
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
-diff -urN linux-2.6.5/arch/x86_64/kernel/setup64.c linux-2.6.5/arch/x86_64/kernel/setup64.c
---- linux-2.6.5/arch/x86_64/kernel/setup64.c 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/arch/x86_64/kernel/setup64.c 2004-04-18 11:05:50.000000000 -0400
-@@ -42,8 +42,15 @@
-
- unsigned long __supported_pte_mask = ~0UL;
- static int do_not_nx __initdata = 0;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+unsigned long vm_stack_flags = VM_GROWSDOWN | __VM_DATA_DEFAULT_FLAGS;
-+unsigned long vm_stack_flags32 = VM_GROWSDOWN | __VM_DATA_DEFAULT_FLAGS;
-+#else
- unsigned long vm_stack_flags = __VM_STACK_FLAGS;
- unsigned long vm_stack_flags32 = __VM_STACK_FLAGS;
-+#endif
-+
- unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS;
- unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS;
- unsigned long vm_force_exec32 = PROT_EXEC;
-diff -urN linux-2.6.5/arch/x86_64/kernel/sys_x86_64.c linux-2.6.5/arch/x86_64/kernel/sys_x86_64.c
---- linux-2.6.5/arch/x86_64/kernel/sys_x86_64.c 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/arch/x86_64/kernel/sys_x86_64.c 2004-04-18 11:05:50.000000000 -0400
-@@ -48,6 +48,11 @@
- if (off & ~PAGE_MASK)
- goto out;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ goto out;
-+#endif
-+
- error = -EBADF;
- file = NULL;
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-@@ -102,6 +107,15 @@
-
- find_start_end(flags, &begin, &end);
-
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp)) {
-+ if (begin == 0x40000000)
-+ begin += current->mm->delta_mmap & 0x0FFFFFFFU;
-+ else
-+ begin += current->mm->delta_mmap;
-+ }
-+#endif
-+
- if (len > end)
- return -ENOMEM;
-
-diff -urN linux-2.6.5/arch/x86_64/mm/fault.c linux-2.6.5/arch/x86_64/mm/fault.c
---- linux-2.6.5/arch/x86_64/mm/fault.c 2004-04-03 22:36:14.000000000 -0500
-+++ linux-2.6.5/arch/x86_64/mm/fault.c 2004-04-18 11:05:50.000000000 -0400
-@@ -23,6 +23,7 @@
- #include <linux/vt_kern.h> /* For unblank_screen() */
- #include <linux/compiler.h>
- #include <linux/module.h>
-+#include <linux/binfmts.h>
-
- #include <asm/system.h>
- #include <asm/uaccess.h>
-@@ -217,6 +218,63 @@
- (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/*
-+ * PaX: decide what to do with offenders (regs->rip = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when legitimate ET_EXEC was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ int err;
-+
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ if (regs->rip >= current->mm->start_code &&
-+ regs->rip < current->mm->end_code)
-+ {
-+ if (test_thread_flag(TIF_IA32)) {
-+ unsigned int esp_4;
-+
-+ err = get_user(esp_4, (unsigned int*)(regs->rsp-4UL));
-+ if (err || esp_4 == regs->rip)
-+ return 1;
-+ } else {
-+ unsigned long esp_8;
-+
-+ err = get_user(esp_8, (unsigned long*)(regs->rsp-8UL));
-+ if (err || esp_8 == regs->rip)
-+ return 1;
-+ }
-+
-+ regs->rip += current->mm->delta_exec;
-+ return 2;
-+ }
-+ }
-+#endif
-+
-+ return 1;
-+}
-+
-+void pax_report_insns(void *pc, void *sp)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 20; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned char*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
- int page_fault_trace;
- int exception_trace = 1;
-
-@@ -302,6 +360,23 @@
- * we can handle it..
- */
- good_area:
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if ((current->flags & PF_PAX_PAGEEXEC) && (error_code & 16) && !(vma->vm_flags & VM_EXEC)) {
-+ up_read(&mm->mmap_sem);
-+ switch(pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 2:
-+ return;
-+#endif
-+
-+ }
-+ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
-+ do_exit(SIGKILL);
-+ }
-+#endif
-+
- info.si_code = SEGV_ACCERR;
- write = 0;
- switch (error_code & 3) {
-diff -urN linux-2.6.5/drivers/char/keyboard.c linux-2.6.5/drivers/char/keyboard.c
---- linux-2.6.5/drivers/char/keyboard.c 2004-04-03 22:38:28.000000000 -0500
-+++ linux-2.6.5/drivers/char/keyboard.c 2004-04-18 11:05:50.000000000 -0400
-@@ -606,6 +606,16 @@
- kbd->kbdmode == VC_MEDIUMRAW) &&
- value != KVAL(K_SAK))
- return; /* SAK is allowed even in raw mode */
-+
-+#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
-+ {
-+ void *func = fn_handler[value];
-+ if (func == fn_show_state || func == fn_show_ptregs ||
-+ func == fn_show_mem)
-+ return;
-+ }
-+#endif
-+
- fn_handler[value](vc, regs);
- }
-
-diff -urN linux-2.6.5/drivers/char/mem.c linux-2.6.5/drivers/char/mem.c
---- linux-2.6.5/drivers/char/mem.c 2004-04-03 22:37:07.000000000 -0500
-+++ linux-2.6.5/drivers/char/mem.c 2004-04-18 11:05:50.000000000 -0400
-@@ -23,6 +23,7 @@
- #include <linux/devfs_fs_kernel.h>
- #include <linux/ptrace.h>
- #include <linux/device.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/io.h>
-@@ -39,6 +40,10 @@
- extern void tapechar_init(void);
- #endif
-
-+#ifdef CONFIG_GRKERNSEC
-+extern struct file_operations grsec_fops;
-+#endif
-+
- /*
- * Architectures vary in how they handle caching for addresses
- * outside of main memory.
-@@ -178,6 +183,12 @@
-
- if (!valid_phys_addr_range(p, &count))
- return -EFAULT;
-+
-+#ifdef CONFIG_GRKERNSEC_KMEM
-+ gr_handle_mem_write();
-+ return -EPERM;
-+#endif
-+
- return do_write_mem(__va(p), p, buf, count, ppos);
- }
-
-@@ -192,6 +203,11 @@
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- #endif
-
-+#ifdef CONFIG_GRKERNSEC_KMEM
-+ if (gr_handle_mem_mmap(offset, vma))
-+ return -EPERM;
-+#endif
-+
- /* Don't try to swap out physical pages.. */
- vma->vm_flags |= VM_RESERVED;
-
-@@ -285,6 +301,11 @@
- ssize_t written;
- char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
-
-+#ifdef CONFIG_GRKERNSEC_KMEM
-+ gr_handle_kmem_write();
-+ return -EPERM;
-+#endif
-+
- if (p < (unsigned long) high_memory) {
-
- wrote = count;
-@@ -411,7 +432,23 @@
- count = size;
-
- zap_page_range(vma, addr, count);
-- zeromap_page_range(vma, addr, count, PAGE_COPY);
-+ zeromap_page_range(vma, addr, count, vma->vm_page_prot);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (vma->vm_flags & VM_MIRROR) {
-+ unsigned long addr_m;
-+ struct vm_area_struct * vma_m;
-+
-+ addr_m = vma->vm_start + (unsigned long)vma->vm_private_data;
-+ vma_m = find_vma(mm, addr_m);
-+ if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
-+ addr_m = addr + (unsigned long)vma->vm_private_data;
-+ zap_page_range(vma_m, addr_m, count);
-+ } else
-+ printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
-+ addr, vma->vm_start);
-+ }
-+#endif
-
- size -= count;
- buf += count;
-@@ -560,6 +597,16 @@
-
- static int open_port(struct inode * inode, struct file * filp)
- {
-+#ifdef CONFIG_GRKERNSEC_KMEM
-+ gr_handle_open_port();
-+ return -EPERM;
-+#endif
-+
-+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
-+}
-+
-+static int open_mem(struct inode * inode, struct file * filp)
-+{
- return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
- }
-
-@@ -568,7 +615,6 @@
- #define full_lseek null_lseek
- #define write_zero write_null
- #define read_full read_zero
--#define open_mem open_port
- #define open_kmem open_mem
-
- static struct file_operations mem_fops = {
-@@ -666,6 +712,11 @@
- case 9:
- filp->f_op = &urandom_fops;
- break;
-+#ifdef CONFIG_GRKERNSEC
-+ case 10:
-+ filp->f_op = &grsec_fops;
-+ break;
-+#endif
- case 11:
- filp->f_op = &kmsg_fops;
- break;
-@@ -697,6 +748,9 @@
- {7, "full", S_IRUGO | S_IWUGO, &full_fops},
- {8, "random", S_IRUGO | S_IWUSR, &random_fops},
- {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops},
-+#ifdef CONFIG_GRKERNSEC
-+ {10,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
-+#endif
- {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops},
- };
-
-diff -urN linux-2.6.5/drivers/char/random.c linux-2.6.5/drivers/char/random.c
---- linux-2.6.5/drivers/char/random.c 2004-04-03 22:36:17.000000000 -0500
-+++ linux-2.6.5/drivers/char/random.c 2004-04-18 11:05:50.000000000 -0400
-@@ -263,9 +263,15 @@
- /*
- * Configuration information
- */
-+#ifdef CONFIG_GRKERNSEC_RANDNET
-+#define DEFAULT_POOL_SIZE 1024
-+#define SECONDARY_POOL_SIZE 256
-+#define BATCH_ENTROPY_SIZE 512
-+#else
- #define DEFAULT_POOL_SIZE 512
- #define SECONDARY_POOL_SIZE 128
- #define BATCH_ENTROPY_SIZE 256
-+#endif
- #define USE_SHA
-
- /*
-@@ -2361,6 +2367,29 @@
- return halfMD4Transform(hash, keyptr->secret);
- }
-
-+#ifdef CONFIG_GRKERNSEC
-+/* the following function is provided by PaX under the GPL */
-+unsigned long get_random_long(void)
-+{
-+ static time_t rekey_time;
-+ static __u32 secret[12];
-+ time_t t;
-+
-+ /*
-+ * Pick a random secret every REKEY_INTERVAL seconds
-+ */
-+ t = get_seconds();
-+ if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
-+ rekey_time = t;
-+ get_random_bytes(secret, sizeof(secret));
-+ }
-+
-+ secret[1] = halfMD4Transform(secret+8, secret);
-+ secret[0] = halfMD4Transform(secret+8, secret);
-+ return *(unsigned long *)secret;
-+}
-+#endif
-+
- #ifdef CONFIG_SYN_COOKIES
- /*
- * Secure SYN cookie computation. This is the algorithm worked out by
-@@ -2460,3 +2489,25 @@
- return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */
- }
- #endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+unsigned long pax_get_random_long(void)
-+{
-+ static time_t rekey_time;
-+ static __u32 secret[12];
-+ time_t t;
-+
-+ /*
-+ * Pick a random secret every REKEY_INTERVAL seconds.
-+ */
-+ t = get_seconds();
-+ if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
-+ rekey_time = t;
-+ get_random_bytes(secret, sizeof(secret));
-+ }
-+
-+ secret[1] = halfMD4Transform(secret+8, secret);
-+ secret[0] = halfMD4Transform(secret+8, secret);
-+ return *(unsigned long *)secret;
-+}
-+#endif
-diff -urN linux-2.6.5/drivers/char/vt_ioctl.c linux-2.6.5/drivers/char/vt_ioctl.c
---- linux-2.6.5/drivers/char/vt_ioctl.c 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/drivers/char/vt_ioctl.c 2004-04-18 11:05:50.000000000 -0400
-@@ -96,6 +96,12 @@
- case KDSKBENT:
- if (!perm)
- return -EPERM;
-+
-+#ifdef CONFIG_GRKERNSEC
-+ if (!capable(CAP_SYS_TTY_CONFIG))
-+ return -EPERM;
-+#endif
-+
- if (!i && v == K_NOSUCHMAP) {
- /* disallocate map */
- key_map = key_maps[s];
-@@ -232,6 +238,13 @@
- goto reterr;
- }
-
-+#ifdef CONFIG_GRKERNSEC
-+ if (!capable(CAP_SYS_TTY_CONFIG)) {
-+ return -EPERM;
-+ goto reterr;
-+ }
-+#endif
-+
- q = func_table[i];
- first_free = funcbufptr + (funcbufsize - funcbufleft);
- for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
-diff -urN linux-2.6.5/drivers/pci/proc.c linux-2.6.5/drivers/pci/proc.c
---- linux-2.6.5/drivers/pci/proc.c 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/drivers/pci/proc.c 2004-04-18 11:05:50.000000000 -0400
-@@ -565,7 +565,15 @@
-
- static void legacy_proc_init(void)
- {
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR, NULL);
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
-+#endif
-+#else
- struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
-+#endif
- if (entry)
- entry->proc_fops = &proc_pci_operations;
- }
-@@ -594,7 +602,15 @@
- {
- struct proc_dir_entry *entry;
- struct pci_dev *dev = NULL;
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
-+#endif
-+#else
- proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
-+#endif
- entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
- if (entry)
- entry->proc_fops = &proc_bus_pci_dev_operations;
-diff -urN linux-2.6.5/drivers/pnp/pnpbios/bioscalls.c linux-2.6.5/drivers/pnp/pnpbios/bioscalls.c
---- linux-2.6.5/drivers/pnp/pnpbios/bioscalls.c 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/drivers/pnp/pnpbios/bioscalls.c 2004-04-18 11:05:50.000000000 -0400
-@@ -79,7 +79,7 @@
- set_limit(cpu_gdt_table[cpu][(selname) >> 3], size); \
- } while(0)
-
--static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
-+static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
-
- /*
- * At some point we want to use this stack frame pointer to unwind
-@@ -107,6 +107,10 @@
- struct desc_struct save_desc_40;
- int cpu;
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+ unsigned long cr3;
-+#endif
-+
- /*
- * PnP BIOSes are generally not terribly re-entrant.
- * Also, don't rely on them to save everything correctly.
-@@ -115,11 +119,21 @@
- return PNP_FUNCTION_NOT_SUPPORTED;
-
- cpu = get_cpu();
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_open_kernel(flags, cr3);
-+#endif
-+
- save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
- cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
-
- /* On some boxes IRQ's during PnP BIOS calls are deadly. */
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ spin_lock_irq(&pnp_bios_lock);
-+#else
- spin_lock_irqsave(&pnp_bios_lock, flags);
-+#endif
-
- /* The lock prevents us bouncing CPU here */
- if (ts1_size)
-@@ -156,9 +170,19 @@
- "i" (0)
- : "memory"
- );
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ spin_unlock_irq(&pnp_bios_lock);
-+#else
- spin_unlock_irqrestore(&pnp_bios_lock, flags);
-+#endif
-
- cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_close_kernel(flags, cr3);
-+#endif
-+
- put_cpu();
-
- /* If we get here and this is set then the PnP BIOS faulted on us. */
-diff -urN linux-2.6.5/drivers/scsi/scsi_devinfo.c linux-2.6.5/drivers/scsi/scsi_devinfo.c
---- linux-2.6.5/drivers/scsi/scsi_devinfo.c 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/drivers/scsi/scsi_devinfo.c 2004-04-18 11:05:50.000000000 -0400
-@@ -27,7 +27,7 @@
- static const char spaces[] = " "; /* 16 of them */
- static unsigned scsi_default_dev_flags;
- static LIST_HEAD(scsi_dev_info_list);
--static __init char scsi_dev_flags[256];
-+static __initdata char scsi_dev_flags[256];
-
- /*
- * scsi_static_device_list: deprecated list of devices that require
-diff -urN linux-2.6.5/drivers/video/vesafb.c linux-2.6.5/drivers/video/vesafb.c
---- linux-2.6.5/drivers/video/vesafb.c 2004-04-03 22:36:17.000000000 -0500
-+++ linux-2.6.5/drivers/video/vesafb.c 2004-04-18 11:05:50.000000000 -0400
-@@ -239,7 +239,7 @@
- if (vesafb_fix.smem_len > 16 * 1024 * 1024)
- vesafb_fix.smem_len = 16 * 1024 * 1024;
-
--#ifndef __i386__
-+#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
- screen_info.vesapm_seg = 0;
- #endif
-
-diff -urN linux-2.6.5/fs/Kconfig linux-2.6.5/fs/Kconfig
---- linux-2.6.5/fs/Kconfig 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/fs/Kconfig 2004-04-18 11:05:50.000000000 -0400
-@@ -778,6 +778,7 @@
-
- config PROC_KCORE
- bool
-+ depends on !GRKERNSEC_PROC_ADD
- default y if !ARM
-
- config DEVFS_FS
-diff -urN linux-2.6.5/fs/binfmt_aout.c linux-2.6.5/fs/binfmt_aout.c
---- linux-2.6.5/fs/binfmt_aout.c 2004-04-03 22:36:26.000000000 -0500
-+++ linux-2.6.5/fs/binfmt_aout.c 2004-04-18 11:05:50.000000000 -0400
-@@ -24,6 +24,7 @@
- #include <linux/binfmts.h>
- #include <linux/personality.h>
- #include <linux/init.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/system.h>
- #include <asm/uaccess.h>
-@@ -118,10 +119,12 @@
- /* If the size of the dump file exceeds the rlimit, then see what would happen
- if we wrote the stack, but not the data area. */
- #ifdef __sparc__
-+ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
- if ((dump.u_dsize+dump.u_ssize) >
- current->rlim[RLIMIT_CORE].rlim_cur)
- dump.u_dsize = 0;
- #else
-+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
- if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
- current->rlim[RLIMIT_CORE].rlim_cur)
- dump.u_dsize = 0;
-@@ -129,10 +132,12 @@
-
- /* Make sure we have enough room to write the stack and data areas. */
- #ifdef __sparc__
-+ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
- if ((dump.u_ssize) >
- current->rlim[RLIMIT_CORE].rlim_cur)
- dump.u_ssize = 0;
- #else
-+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
- if ((dump.u_ssize+1) * PAGE_SIZE >
- current->rlim[RLIMIT_CORE].rlim_cur)
- dump.u_ssize = 0;
-@@ -281,6 +286,8 @@
- rlim = current->rlim[RLIMIT_DATA].rlim_cur;
- if (rlim >= RLIM_INFINITY)
- rlim = ~0;
-+
-+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
- if (ex.a_data + ex.a_bss > rlim)
- return -ENOMEM;
-
-@@ -309,10 +316,33 @@
- (current->mm->start_brk = N_BSSADDR(ex));
- current->mm->free_area_cache = TASK_UNMAPPED_BASE;
-
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (current->flags & PF_PAX_RANDMMAP)
-+ current->mm->free_area_cache += current->mm->delta_mmap;
-+#endif
-+
- current->mm->rss = 0;
- current->mm->mmap = NULL;
- compute_creds(bprm);
- current->flags &= ~PF_FORKNOEXEC;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
-+ current->flags |= PF_PAX_PAGEEXEC;
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
-+ current->flags |= PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
-+ current->flags |= PF_PAX_MPROTECT;
-+#endif
-+
-+ }
-+#endif
-+
- #ifdef __sparc__
- if (N_MAGIC(ex) == NMAGIC) {
- loff_t pos = fd_offset;
-@@ -399,7 +429,7 @@
-
- down_write(&current->mm->mmap_sem);
- error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
-- PROT_READ | PROT_WRITE | PROT_EXEC,
-+ PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
- fd_offset + ex.a_text);
- up_write(&current->mm->mmap_sem);
-diff -urN linux-2.6.5/fs/binfmt_elf.c linux-2.6.5/fs/binfmt_elf.c
---- linux-2.6.5/fs/binfmt_elf.c 2004-04-03 22:36:58.000000000 -0500
-+++ linux-2.6.5/fs/binfmt_elf.c 2004-04-18 11:05:50.000000000 -0400
-@@ -37,11 +37,17 @@
- #include <linux/pagemap.h>
- #include <linux/security.h>
- #include <linux/syscalls.h>
-+#include <linux/random.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/param.h>
- #include <asm/pgalloc.h>
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+#include <asm/desc.h>
-+#endif
-+
- #include <linux/elf.h>
-
- static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
-@@ -85,14 +91,22 @@
-
- static int set_brk(unsigned long start, unsigned long end)
- {
-+ current->mm->start_brk = current->mm->brk = end;
- start = ELF_PAGEALIGN(start);
- end = ELF_PAGEALIGN(end);
- if (end > start) {
- unsigned long addr = do_brk(start, end - start);
- if (BAD_ADDR(addr))
- return addr;
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (current->flags & PF_PAX_RANDEXEC)
-+ addr = do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start);
-+ if (BAD_ADDR(addr))
-+ return addr;
-+#endif
-+
- }
-- current->mm->start_brk = current->mm->brk = end;
- return 0;
- }
-
-@@ -444,6 +458,203 @@
- return elf_entry;
- }
-
-+#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
-+static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
-+{
-+ unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (elf_phdata->p_flags & PF_PAGEEXEC)
-+ pax_flags |= PF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (elf_phdata->p_flags & PF_SEGMEXEC) {
-+ pax_flags &= ~PF_PAX_PAGEEXEC;
-+ pax_flags |= PF_PAX_SEGMEXEC;
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ if (elf_phdata->p_flags & PF_EMUTRAMP)
-+ pax_flags |= PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if (elf_phdata->p_flags & PF_MPROTECT)
-+ pax_flags |= PF_PAX_MPROTECT;
-+#endif
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (elf_phdata->p_flags & PF_RANDMMAP)
-+ pax_flags |= PF_PAX_RANDMMAP;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (elf_phdata->p_flags & PF_RANDEXEC)
-+ pax_flags |= PF_PAX_RANDEXEC;
-+#endif
-+
-+ return pax_flags;
-+}
-+#endif
-+
-+#ifdef CONFIG_PAX_PT_PAX_FLAGS
-+static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
-+{
-+ unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
-+ pax_flags |= PF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC)) {
-+ pax_flags &= ~PF_PAX_PAGEEXEC;
-+ pax_flags |= PF_PAX_SEGMEXEC;
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
-+ pax_flags |= PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
-+ pax_flags |= PF_PAX_MPROTECT;
-+#endif
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (!(elf_phdata->p_flags & PF_NORANDMMAP))
-+ pax_flags |= PF_PAX_RANDMMAP;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (!(elf_phdata->p_flags & PF_NORANDEXEC))
-+ pax_flags |= PF_PAX_RANDEXEC;
-+#endif
-+
-+ return pax_flags;
-+}
-+#endif
-+
-+#ifdef CONFIG_PAX_EI_PAX
-+static int pax_parse_ei_pax(const struct elfhdr * const elf_ex)
-+{
-+ unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
-+ pax_flags |= PF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) {
-+ pax_flags &= ~PF_PAX_PAGEEXEC;
-+ pax_flags |= PF_PAX_SEGMEXEC;
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ if ((pax_flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
-+ pax_flags |= PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if ((pax_flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
-+ pax_flags |= PF_PAX_MPROTECT;
-+#endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
-+ pax_flags |= PF_PAX_RANDMMAP;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if ((elf_ex->e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex->e_type == ET_EXEC) && (pax_flags & PF_PAX_MPROTECT))
-+ pax_flags |= PF_PAX_RANDEXEC;
-+#endif
-+
-+ return pax_flags;
-+}
-+#endif
-+
-+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
-+static int pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
-+{
-+ unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PT_PAX_FLAGS
-+ unsigned long i;
-+#endif
-+
-+#ifdef CONFIG_PAX_EI_PAX
-+ pax_flags = pax_parse_ei_pax(elf_ex);
-+#endif
-+
-+#ifdef CONFIG_PAX_PT_PAX_FLAGS
-+ for (i = 0UL; i < elf_ex->e_phnum; i++)
-+ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
-+ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
-+ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
-+ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
-+ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
-+ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)) ||
-+ ((elf_phdata[i].p_flags & PF_RANDEXEC) && ((elf_phdata[i].p_flags & PF_NORANDEXEC) || elf_ex->e_type == ET_DYN || !(elf_phdata[i].p_flags & PF_MPROTECT))) ||
-+ (!(elf_phdata[i].p_flags & PF_NORANDEXEC) && (elf_ex->e_type == ET_DYN || (elf_phdata[i].p_flags & PF_NOMPROTECT))))
-+ return -EINVAL;
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_softmode)
-+ pax_flags = pax_parse_softmode(&elf_phdata[i]);
-+ else
-+#endif
-+
-+ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
-+ break;
-+ }
-+#endif
-+
-+ if (0 > pax_check_flags(&pax_flags))
-+ return -EINVAL;
-+
-+ current->flags |= pax_flags;
-+ return 0;
-+}
-+#endif
-+
- /*
- * These are the functions used to load ELF style executables and shared
- * libraries. There is no binary dependent code anywhere else.
-@@ -476,7 +687,12 @@
- struct exec interp_ex;
- char passed_fileno[6];
- struct files_struct *files;
--
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ unsigned long load_addr_random = 0UL;
-+ unsigned long load_bias_random = 0UL;
-+#endif
-+
- /* Get the exec-header */
- elf_ex = *((struct elfhdr *) bprm->buf);
-
-@@ -664,8 +880,44 @@
- current->mm->end_data = 0;
- current->mm->end_code = 0;
- current->mm->mmap = NULL;
-+
-+#ifdef CONFIG_PAX_ASLR
-+ current->mm->delta_mmap = 0UL;
-+ current->mm->delta_exec = 0UL;
-+ current->mm->delta_stack = 0UL;
-+#endif
-+
- current->flags &= ~PF_FORKNOEXEC;
-
-+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
-+ if (0 > pax_parse_elf_flags(&elf_ex, elf_phdata)) {
-+ send_sig(SIGKILL, current, 0);
-+ goto out_free_dentry;
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
-+ pax_set_flags(bprm);
-+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
-+ if (pax_set_flags_func)
-+ (pax_set_flags_func)(bprm);
-+#endif
-+
-+#ifdef CONFIG_PAX_DLRESOLVE
-+ if (current->flags & PF_PAX_PAGEEXEC)
-+ current->mm->call_dl_resolve = 0UL;
-+#endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+ if (current->flags & PF_PAX_RANDMMAP) {
-+#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
-+
-+ current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
-+ current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
-+ current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
-+ }
-+#endif
-+
- /* Do this immediately, since STACK_TOP as used in setup_arg_pages
- may depend on the personality. */
- SET_PERSONALITY(elf_ex, ibcs2_interpreter);
-@@ -674,6 +926,12 @@
- change some of these later */
- current->mm->rss = 0;
- current->mm->free_area_cache = TASK_UNMAPPED_BASE;
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (current->flags & PF_PAX_RANDMMAP)
-+ current->mm->free_area_cache += current->mm->delta_mmap;
-+#endif
-+
- retval = setup_arg_pages(bprm);
- if (retval < 0) {
- send_sig(SIGKILL, current, 0);
-@@ -729,11 +987,85 @@
- base, as well as whatever program they might try to exec. This
- is because the brk will follow the loader, and is not movable. */
- load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ /* PaX: randomize base address at the default exe base if requested */
-+ if (current->flags & PF_PAX_RANDMMAP) {
-+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
-+ elf_flags |= MAP_FIXED;
-+ }
-+#endif
-+
- }
-
-- error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
-- if (BAD_ADDR(error))
-- continue;
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) {
-+ error = -ENOMEM;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (current->flags & PF_PAX_PAGEEXEC)
-+ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags);
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ unsigned long addr, len;
-+
-+ addr = ELF_PAGESTART(load_bias + vaddr);
-+ len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
-+ if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)
-+ continue;
-+ down_write(&current->mm->mmap_sem);
-+ error = do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT);
-+ up_write(&current->mm->mmap_sem);
-+ }
-+#endif
-+
-+ if (BAD_ADDR(error))
-+ continue;
-+
-+ /* PaX: mirror at a randomized base */
-+ down_write(&current->mm->mmap_sem);
-+
-+ if (!load_addr_set) {
-+ load_addr_random = get_unmapped_area(bprm->file, 0UL, elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT, MAP_PRIVATE);
-+ if (BAD_ADDR(load_addr_random)) {
-+ up_write(&current->mm->mmap_sem);
-+ continue;
-+ }
-+ load_bias_random = load_addr_random - vaddr;
-+ }
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (current->flags & PF_PAX_PAGEEXEC)
-+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (elf_prot & PROT_EXEC) {
-+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), elf_ppnt->p_memsz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), PROT_NONE, MAP_PRIVATE | MAP_FIXED, 0UL);
-+ if (!BAD_ADDR(load_addr_random)) {
-+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
-+ if (!BAD_ADDR(load_addr_random))
-+ load_addr_random -= SEGMEXEC_TASK_SIZE;
-+ }
-+ } else
-+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
-+ }
-+#endif
-+
-+ up_write(&current->mm->mmap_sem);
-+ if (BAD_ADDR(load_addr_random))
-+ continue;
-+ } else
-+#endif
-+
-+ {
-+ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
-+ if (BAD_ADDR(error))
-+ continue;
-+ }
-
- if (!load_addr_set) {
- load_addr_set = 1;
-@@ -744,6 +1076,11 @@
- load_addr += load_bias;
- reloc_func_desc = load_bias;
- }
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ current->mm->delta_exec = load_addr_random - load_addr;
-+#endif
-+
- }
- k = elf_ppnt->p_vaddr;
- if (k < start_code) start_code = k;
-@@ -770,6 +1107,16 @@
- start_data += load_bias;
- end_data += load_bias;
-
-+#ifdef CONFIG_PAX_RANDMMAP
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ elf_brk += pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
-+#undef pax_delta_mask
-+#endif
-+
- /* Calling set_brk effectively mmaps the pages that we need
- * for the bss and break sections. We must do this before
- * mapping in the interpreter, to make sure it doesn't wind
-@@ -850,6 +1197,26 @@
- ELF_PLAT_INIT(regs, reloc_func_desc);
- #endif
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ i = get_cpu();
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ {
-+ unsigned long flags, cr3;
-+
-+ pax_open_kernel(flags, cr3);
-+#endif
-+
-+ pax_switch_segments(current, i);
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_close_kernel(flags, cr3);
-+ }
-+#endif
-+
-+ put_cpu();
-+#endif
-+
- start_thread(regs, elf_entry, bprm->p);
- if (unlikely(current->ptrace & PT_PTRACED)) {
- if (current->ptrace & PT_TRACE_EXEC)
-@@ -1062,8 +1429,11 @@
- #undef DUMP_SEEK
-
- #define DUMP_WRITE(addr, nr) \
-+ do { \
-+ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
- if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
-- goto end_coredump;
-+ goto end_coredump; \
-+ } while (0);
- #define DUMP_SEEK(off) \
- if (!dump_seek(file, (off))) \
- goto end_coredump;
-diff -urN linux-2.6.5/fs/binfmt_misc.c linux-2.6.5/fs/binfmt_misc.c
---- linux-2.6.5/fs/binfmt_misc.c 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/fs/binfmt_misc.c 2004-04-18 11:05:50.000000000 -0400
-@@ -108,9 +108,11 @@
- int retval;
-
- retval = -ENOEXEC;
-- if (!enabled)
-+ if (!enabled || bprm->misc)
- goto _ret;
-
-+ bprm->misc++;
-+
- /* to keep locking time low, we copy the interpreter string */
- read_lock(&entries_lock);
- fmt = check_file(bprm);
-diff -urN linux-2.6.5/fs/buffer.c linux-2.6.5/fs/buffer.c
---- linux-2.6.5/fs/buffer.c 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/fs/buffer.c 2004-04-18 11:05:50.000000000 -0400
-@@ -37,6 +37,7 @@
- #include <linux/bio.h>
- #include <linux/notifier.h>
- #include <linux/cpu.h>
-+#include <linux/grsecurity.h>
- #include <asm/bitops.h>
-
- static void invalidate_bh_lrus(void);
-@@ -2162,6 +2163,9 @@
- int err;
-
- err = -EFBIG;
-+
-+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
-+
- limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
- if (limit != RLIM_INFINITY && size > (loff_t)limit) {
- send_sig(SIGXFSZ, current, 0);
-diff -urN linux-2.6.5/fs/dcache.c linux-2.6.5/fs/dcache.c
---- linux-2.6.5/fs/dcache.c 2004-04-03 22:36:24.000000000 -0500
-+++ linux-2.6.5/fs/dcache.c 2004-04-18 11:05:50.000000000 -0400
-@@ -1256,7 +1256,7 @@
- *
- * "buflen" should be positive. Caller holds the dcache_lock.
- */
--static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
-+char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
- struct dentry *root, struct vfsmount *rootmnt,
- char *buffer, int buflen)
- {
-diff -urN linux-2.6.5/fs/exec.c linux-2.6.5/fs/exec.c
---- linux-2.6.5/fs/exec.c 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/fs/exec.c 2004-04-18 11:05:50.000000000 -0400
-@@ -46,6 +46,8 @@
- #include <linux/security.h>
- #include <linux/syscalls.h>
- #include <linux/rmap-locking.h>
-+#include <linux/random.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgalloc.h>
-@@ -62,6 +64,20 @@
- static struct linux_binfmt *formats;
- static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
-
-+#ifdef CONFIG_PAX_SOFTMODE
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
-+unsigned int pax_aslr=1;
-+#endif
-+
-+unsigned int pax_softmode;
-+#endif
-+
-+#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
-+void (*pax_set_flags_func)(struct linux_binprm * bprm);
-+EXPORT_SYMBOL(pax_set_flags_func);
-+#endif
-+
- int register_binfmt(struct linux_binfmt * fmt)
- {
- struct linux_binfmt ** tmp = &formats;
-@@ -303,7 +319,12 @@
- pte_t * pte;
- struct pte_chain *pte_chain;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (page_count(page) != 1 && (!(tsk->flags & PF_PAX_SEGMEXEC) || page_count(page) != 3))
-+#else
- if (page_count(page) != 1)
-+#endif
-+
- printk(KERN_ERR "mem_map disagrees with %p at %08lx\n",
- page, address);
-
-@@ -322,8 +343,18 @@
- pte_unmap(pte);
- goto out;
- }
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (page_count(page) == 1) {
-+#endif
-+
- lru_cache_add_active(page);
- flush_dcache_page(page);
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ }
-+#endif
-+
- set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, prot))));
- pte_chain = page_add_rmap(page, pte, pte_chain);
- pte_unmap(pte);
-@@ -350,6 +381,10 @@
- int i;
- long arg_size;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ struct vm_area_struct *mpnt_m = NULL;
-+#endif
-+
- #ifdef CONFIG_STACK_GROWSUP
- /* Move the argument and environment strings to the bottom of the
- * stack space.
-@@ -409,6 +444,16 @@
- if (!mpnt)
- return -ENOMEM;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if ((current->flags & PF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
-+ mpnt_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-+ if (!mpnt_m) {
-+ kmem_cache_free(vm_area_cachep, mpnt);
-+ return -ENOMEM;
-+ }
-+ }
-+#endif
-+
- if (security_vm_enough_memory(arg_size >> PAGE_SHIFT)) {
- kmem_cache_free(vm_area_cachep, mpnt);
- return -ENOMEM;
-@@ -425,6 +470,13 @@
- mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
- mpnt->vm_end = STACK_TOP;
- #endif
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(current->flags & PF_PAX_PAGEEXEC))
-+ mpnt->vm_page_prot = protection_map[(VM_STACK_FLAGS | VM_EXEC) & 0x7];
-+ else
-+#endif
-+
- mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
- mpnt->vm_flags = VM_STACK_FLAGS;
- mpnt->vm_ops = NULL;
-@@ -434,6 +486,26 @@
- mpnt->vm_private_data = (void *) 0;
- insert_vm_struct(mm, mpnt);
- mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (mpnt_m) {
-+ *mpnt_m = *mpnt;
-+ INIT_LIST_HEAD(&mpnt_m->shared);
-+ if (!(VM_STACK_FLAGS & VM_EXEC)) {
-+ mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
-+ mpnt_m->vm_page_prot = PAGE_NONE;
-+ }
-+ mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
-+ mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
-+ mpnt_m->vm_flags |= VM_MIRROR;
-+ mpnt->vm_flags |= VM_MIRROR;
-+ mpnt_m->vm_private_data = (void *)(mpnt->vm_start - mpnt_m->vm_start);
-+ mpnt->vm_private_data = (void *)(mpnt_m->vm_start - mpnt->vm_start);
-+ insert_vm_struct(mm, mpnt_m);
-+ current->mm->total_vm = (mpnt_m->vm_end - mpnt_m->vm_start) >> PAGE_SHIFT;
-+ }
-+#endif
-+
- }
-
- for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
-@@ -442,6 +514,15 @@
- bprm->page[i] = NULL;
- put_dirty_page(current, page, stack_base,
- mpnt->vm_page_prot);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) && defined(CONFIG_PAX_MPROTECT)
-+ if (mpnt_m) {
-+ page_cache_get(page);
-+ put_dirty_page(current, page, stack_base + SEGMEXEC_TASK_SIZE,
-+ mpnt_m->vm_page_prot);
-+ }
-+#endif
-+
- }
- stack_base += PAGE_SIZE;
- }
-@@ -830,6 +911,30 @@
- }
- current->comm[i] = '\0';
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ current->flags &= ~PF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ current->flags &= ~PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ current->flags &= ~PF_PAX_MPROTECT;
-+#endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+ current->flags &= ~PF_PAX_RANDMMAP;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ current->flags &= ~PF_PAX_RANDEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ current->flags &= ~PF_PAX_SEGMEXEC;
-+#endif
-+
- flush_thread();
-
- if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
-@@ -908,6 +1013,9 @@
- if (retval)
- return retval;
-
-+ if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt))
-+ return -EACCES;
-+
- memset(bprm->buf,0,BINPRM_BUF_SIZE);
- return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
- }
-@@ -946,8 +1054,13 @@
- }
- }
-
-- current->suid = current->euid = current->fsuid = bprm->e_uid;
-- current->sgid = current->egid = current->fsgid = bprm->e_gid;
-+ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
-+ current->suid = current->euid = current->fsuid = bprm->e_uid;
-+
-+ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
-+ current->sgid = current->egid = current->fsgid = bprm->e_gid;
-+
-+ gr_handle_chroot_caps(current);
-
- task_unlock(current);
-
-@@ -1091,6 +1204,11 @@
- struct file *file;
- int retval;
- int i;
-+#ifdef CONFIG_GRKERNSEC
-+ struct file *old_exec_file;
-+ struct acl_subject_label *old_acl;
-+ struct rlimit old_rlim[RLIM_NLIMITS];
-+#endif
-
- sched_balance_exec();
-
-@@ -1100,13 +1218,39 @@
- if (IS_ERR(file))
- return retval;
-
-+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
-+
-+ if (gr_handle_nproc()) {
-+ allow_write_access(file);
-+ fput(file);
-+ return -EAGAIN;
-+ }
-+
-+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
-+ allow_write_access(file);
-+ fput(file);
-+ return -EACCES;
-+ }
-+
-+
- bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
-+
-+#ifdef CONFIG_PAX_RANDUSTACK
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
-+#endif
-+
- memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
-
- bprm.file = file;
- bprm.filename = filename;
- bprm.interp = filename;
- bprm.sh_bang = 0;
-+ bprm.misc = 0;
- bprm.loader = 0;
- bprm.exec = 0;
- bprm.security = NULL;
-@@ -1135,11 +1279,26 @@
- if (retval < 0)
- goto out;
-
-+ if (!gr_tpe_allow(file)) {
-+ retval = -EACCES;
-+ goto out;
-+ }
-+
-+ if (gr_check_crash_exec(file)) {
-+ retval = -EACCES;
-+ goto out;
-+ }
-+
- retval = copy_strings_kernel(1, &bprm.filename, &bprm);
- if (retval < 0)
- goto out;
-
- bprm.exec = bprm.p;
-+
-+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
-+
-+ gr_handle_exec_args(&bprm, argv);
-+
- retval = copy_strings(bprm.envc, envp, &bprm);
- if (retval < 0)
- goto out;
-@@ -1148,8 +1307,22 @@
- if (retval < 0)
- goto out;
-
-+#ifdef CONFIG_GRKERNSEC
-+ old_acl = current->acl;
-+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
-+ old_exec_file = current->exec_file;
-+ get_file(file);
-+ current->exec_file = file;
-+#endif
-+
-+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
-+
- retval = search_binary_handler(&bprm,regs);
- if (retval >= 0) {
-+#ifdef CONFIG_GRKERNSEC
-+ if (old_exec_file)
-+ fput(old_exec_file);
-+#endif
- free_arg_pages(&bprm);
-
- /* execve success */
-@@ -1157,6 +1330,13 @@
- return retval;
- }
-
-+#ifdef CONFIG_GRKERNSEC
-+ current->acl = old_acl;
-+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
-+ fput(current->exec_file);
-+ current->exec_file = old_exec_file;
-+#endif
-+
- out:
- /* Something went wrong, return the inode and free the argument pages*/
- for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
-@@ -1314,6 +1494,128 @@
- *out_ptr = 0;
- }
-
-+int pax_check_flags(unsigned long * flags)
-+{
-+ int retval = 0;
-+
-+#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
-+ if (*flags & PF_PAX_SEGMEXEC)
-+ {
-+ *flags &= ~PF_PAX_SEGMEXEC;
-+ retval = -EINVAL;
-+ }
-+#endif
-+
-+ if ((*flags & PF_PAX_PAGEEXEC)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ && (*flags & PF_PAX_SEGMEXEC)
-+#endif
-+
-+ )
-+ {
-+ *flags &= ~PF_PAX_PAGEEXEC;
-+ retval = -EINVAL;
-+ }
-+
-+ if ((*flags & PF_PAX_MPROTECT)
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
-+#endif
-+
-+ )
-+ {
-+ *flags &= ~PF_PAX_MPROTECT;
-+ retval = -EINVAL;
-+ }
-+
-+ if ((*flags & PF_PAX_EMUTRAMP)
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
-+#endif
-+
-+ )
-+ {
-+ *flags &= ~PF_PAX_EMUTRAMP;
-+ retval = -EINVAL;
-+ }
-+
-+ if ((*flags & PF_PAX_RANDEXEC)
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ && !(*flags & PF_PAX_MPROTECT)
-+#endif
-+
-+ )
-+ {
-+ *flags &= ~PF_PAX_RANDEXEC;
-+ retval = -EINVAL;
-+ }
-+
-+ return retval;
-+}
-+
-+EXPORT_SYMBOL(pax_check_flags);
-+
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
-+{
-+ struct task_struct *tsk = current;
-+ struct mm_struct *mm = current->mm;
-+ char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
-+ char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
-+ char* path_exec=NULL;
-+ char* path_fault=NULL;
-+ unsigned long start=0UL, end=0UL, offset=0UL;
-+
-+ if (buffer_exec && buffer_fault) {
-+ struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
-+
-+ down_read(&mm->mmap_sem);
-+ vma = mm->mmap;
-+ while (vma && (!vma_exec || !vma_fault)) {
-+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
-+ vma_exec = vma;
-+ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
-+ vma_fault = vma;
-+ vma = vma->vm_next;
-+ }
-+ if (vma_exec) {
-+ path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
-+ if (IS_ERR(path_exec))
-+ path_exec = "<path too long>";
-+ }
-+ if (vma_fault) {
-+ start = vma_fault->vm_start;
-+ end = vma_fault->vm_end;
-+ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
-+ if (vma_fault->vm_file) {
-+ path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
-+ if (IS_ERR(path_fault))
-+ path_fault = "<path too long>";
-+ } else
-+ path_fault = "<anonymous mapping>";
-+ }
-+ up_read(&mm->mmap_sem);
-+ }
-+#ifdef CONFIG_GRKERNSEC
-+ if (tsk->curr_ip)
-+ printk(KERN_ERR "PAX: execution attempt from %u.%u.%u.%u in: %s, %08lx-%08lx %08lx\n", NIPQUAD(tsk->curr_ip), path_fault, start, end, offset);
-+ else
-+#endif
-+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
-+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
-+ "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
-+ tsk->uid, tsk->euid, pc, sp);
-+ if (buffer_exec) free_page((unsigned long)buffer_exec);
-+ if (buffer_fault) free_page((unsigned long)buffer_fault);
-+ pax_report_insns(pc, sp);
-+ do_coredump(SIGKILL, SIGKILL, regs);
-+}
-+#endif
-+
- static void zap_threads (struct mm_struct *mm)
- {
- struct task_struct *g, *p;
-@@ -1383,6 +1685,7 @@
- current->signal->group_exit_code = exit_code;
- coredump_wait(mm);
-
-+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
- if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
- goto fail_unlock;
-
-@@ -1402,7 +1705,7 @@
- goto close_fail;
- if (!file->f_op->write)
- goto close_fail;
-- if (do_truncate(file->f_dentry, 0) != 0)
-+ if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
- goto close_fail;
-
- retval = binfmt->core_dump(signr, regs, file);
-diff -urN linux-2.6.5/fs/fcntl.c linux-2.6.5/fs/fcntl.c
---- linux-2.6.5/fs/fcntl.c 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/fs/fcntl.c 2004-04-18 11:05:50.000000000 -0400
-@@ -14,6 +14,7 @@
- #include <linux/module.h>
- #include <linux/security.h>
- #include <linux/ptrace.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/poll.h>
- #include <asm/siginfo.h>
-@@ -86,6 +87,9 @@
- int error;
-
- error = -EINVAL;
-+
-+ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
-+
- if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur)
- goto out;
-
-@@ -105,6 +109,9 @@
- }
-
- error = -EMFILE;
-+
-+ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
-+
- if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
- goto out;
-
-@@ -154,6 +161,8 @@
- struct file * file, *tofree;
- struct files_struct * files = current->files;
-
-+ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
-+
- spin_lock(&files->file_lock);
- if (!(file = fcheck(oldfd)))
- goto out_unlock;
-@@ -485,13 +494,15 @@
- if (pid > 0) {
- p = find_task_by_pid(pid);
- if (p) {
-- send_sigio_to_task(p, fown, fd, band);
-+ if (!gr_check_protected_task(p))
-+ send_sigio_to_task(p, fown, fd, band);
- }
- } else {
- struct list_head *l;
- struct pid *pidptr;
- for_each_task_pid(-pid, PIDTYPE_PGID, p, l, pidptr) {
-- send_sigio_to_task(p, fown, fd, band);
-+ if (!gr_check_protected_task(p) && !gr_pid_is_chrooted(p))
-+ send_sigio_to_task(p, fown, fd, band);
- }
- }
- read_unlock(&tasklist_lock);
-diff -urN linux-2.6.5/fs/namei.c linux-2.6.5/fs/namei.c
---- linux-2.6.5/fs/namei.c 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/fs/namei.c 2004-04-18 11:05:50.000000000 -0400
-@@ -26,6 +26,7 @@
- #include <linux/personality.h>
- #include <linux/security.h>
- #include <linux/mount.h>
-+#include <linux/grsecurity.h>
- #include <asm/namei.h>
- #include <asm/uaccess.h>
-
-@@ -410,6 +411,13 @@
- err = security_inode_follow_link(dentry, nd);
- if (err)
- goto loop;
-+
-+ if (gr_handle_follow_link(dentry->d_parent->d_inode,
-+ dentry->d_inode, dentry, nd->mnt)) {
-+ err = -EACCES;
-+ goto loop;
-+ }
-+
- current->link_count++;
- current->total_link_count++;
- touch_atime(nd->mnt, dentry);
-@@ -761,6 +769,10 @@
- break;
- }
- return_base:
-+ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
-+ path_release(nd);
-+ return -ENOENT;
-+ }
- return 0;
- out_dput:
- dput(next.dentry);
-@@ -1214,7 +1226,7 @@
- if (!error) {
- DQUOT_INIT(inode);
-
-- error = do_truncate(dentry, 0);
-+ error = do_truncate(dentry, 0, nd->mnt);
- }
- put_write_access(inode);
- if (error)
-@@ -1265,6 +1277,17 @@
- error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);
- if (error)
- return error;
-+
-+ if (gr_handle_rawio(nd->dentry->d_inode)) {
-+ error = -EPERM;
-+ goto exit;
-+ }
-+
-+ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
-+ error = -EACCES;
-+ goto exit;
-+ }
-+
- goto ok;
- }
-
-@@ -1298,9 +1321,19 @@
-
- /* Negative dentry, just create the file */
- if (!dentry->d_inode) {
-+ if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
-+ error = -EACCES;
-+ up(&dir->d_inode->i_sem);
-+ goto exit_dput;
-+ }
-+
- if (!IS_POSIXACL(dir->d_inode))
- mode &= ~current->fs->umask;
- error = vfs_create(dir->d_inode, dentry, mode, nd);
-+
-+ if (!error)
-+ gr_handle_create(dentry, nd->mnt);
-+
- up(&dir->d_inode->i_sem);
- dput(nd->dentry);
- nd->dentry = dentry;
-@@ -1315,6 +1348,25 @@
- /*
- * It already exists.
- */
-+
-+ if (gr_handle_rawio(dentry->d_inode)) {
-+ error = -EPERM;
-+ up(&dir->d_inode->i_sem);
-+ goto exit_dput;
-+ }
-+
-+ if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
-+ up(&dir->d_inode->i_sem);
-+ error = -EACCES;
-+ goto exit_dput;
-+ }
-+
-+ if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
-+ up(&dir->d_inode->i_sem);
-+ error = -EACCES;
-+ goto exit_dput;
-+ }
-+
- up(&dir->d_inode->i_sem);
-
- error = -EEXIST;
-@@ -1368,6 +1420,13 @@
- error = security_inode_follow_link(dentry, nd);
- if (error)
- goto exit_dput;
-+
-+ if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
-+ dentry, nd->mnt)) {
-+ error = -EACCES;
-+ goto exit_dput;
-+ }
-+
- touch_atime(nd->mnt, dentry);
- error = dentry->d_inode->i_op->follow_link(dentry, nd);
- dput(dentry);
-@@ -1475,6 +1534,22 @@
- if (!IS_POSIXACL(nd.dentry->d_inode))
- mode &= ~current->fs->umask;
- if (!IS_ERR(dentry)) {
-+ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
-+ error = -EPERM;
-+ dput(dentry);
-+ up(&nd.dentry->d_inode->i_sem);
-+ path_release(&nd);
-+ goto out;
-+ }
-+
-+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
-+ error = -EACCES;
-+ dput(dentry);
-+ up(&nd.dentry->d_inode->i_sem);
-+ path_release(&nd);
-+ goto out;
-+ }
-+
- switch (mode & S_IFMT) {
- case 0: case S_IFREG:
- error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
-@@ -1492,6 +1567,10 @@
- default:
- error = -EINVAL;
- }
-+
-+ if (!error)
-+ gr_handle_create(dentry, nd.mnt);
-+
- dput(dentry);
- }
- up(&nd.dentry->d_inode->i_sem);
-@@ -1543,9 +1622,19 @@
- dentry = lookup_create(&nd, 1);
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry)) {
-+ error = 0;
- if (!IS_POSIXACL(nd.dentry->d_inode))
- mode &= ~current->fs->umask;
-- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
-+
-+ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
-+ error = -EACCES;
-+
-+ if (!error)
-+ error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
-+
-+ if (!error)
-+ gr_handle_create(dentry, nd.mnt);
-+
- dput(dentry);
- }
- up(&nd.dentry->d_inode->i_sem);
-@@ -1629,6 +1718,8 @@
- char * name;
- struct dentry *dentry;
- struct nameidata nd;
-+ ino_t saved_ino = 0;
-+ dev_t saved_dev = 0;
-
- name = getname(pathname);
- if(IS_ERR(name))
-@@ -1653,7 +1744,21 @@
- dentry = lookup_hash(&nd.last, nd.dentry);
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry)) {
-- error = vfs_rmdir(nd.dentry->d_inode, dentry);
-+ error = 0;
-+ if (dentry->d_inode) {
-+ if (dentry->d_inode->i_nlink <= 1) {
-+ saved_ino = dentry->d_inode->i_ino;
-+ saved_dev = dentry->d_inode->i_sb->s_dev;
-+ }
-+
-+ if (!gr_acl_handle_rmdir(dentry, nd.mnt))
-+ error = -EACCES;
-+ }
-+
-+ if (!error)
-+ error = vfs_rmdir(nd.dentry->d_inode, dentry);
-+ if (!error && (saved_dev || saved_ino))
-+ gr_handle_delete(saved_ino, saved_dev);
- dput(dentry);
- }
- up(&nd.dentry->d_inode->i_sem);
-@@ -1707,6 +1812,8 @@
- struct dentry *dentry;
- struct nameidata nd;
- struct inode *inode = NULL;
-+ ino_t saved_ino = 0;
-+ dev_t saved_dev = 0;
-
- name = getname(pathname);
- if(IS_ERR(name))
-@@ -1722,13 +1829,26 @@
- dentry = lookup_hash(&nd.last, nd.dentry);
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry)) {
-+ error = 0;
- /* Why not before? Because we want correct error value */
- if (nd.last.name[nd.last.len])
- goto slashes;
- inode = dentry->d_inode;
-- if (inode)
-+ if (inode) {
-+ if (inode->i_nlink <= 1) {
-+ saved_ino = inode->i_ino;
-+ saved_dev = inode->i_sb->s_dev;
-+ }
-+
-+ if (!gr_acl_handle_unlink(dentry, nd.mnt))
-+ error = -EACCES;
-+
- atomic_inc(&inode->i_count);
-- error = vfs_unlink(nd.dentry->d_inode, dentry);
-+ }
-+ if (!error)
-+ error = vfs_unlink(nd.dentry->d_inode, dentry);
-+ if (!error && (saved_ino || saved_dev))
-+ gr_handle_delete(saved_ino, saved_dev);
- exit2:
- dput(dentry);
- }
-@@ -1792,7 +1912,15 @@
- dentry = lookup_create(&nd, 0);
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry)) {
-- error = vfs_symlink(nd.dentry->d_inode, dentry, from);
-+ error = 0;
-+ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
-+ error = -EACCES;
-+
-+ if (!error)
-+ error = vfs_symlink(nd.dentry->d_inode, dentry, from);
-+
-+ if (!error)
-+ gr_handle_create(dentry, nd.mnt);
- dput(dentry);
- }
- up(&nd.dentry->d_inode->i_sem);
-@@ -1876,7 +2004,20 @@
- new_dentry = lookup_create(&nd, 0);
- error = PTR_ERR(new_dentry);
- if (!IS_ERR(new_dentry)) {
-- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-+ error = 0;
-+ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
-+ old_nd.dentry->d_inode,
-+ old_nd.dentry->d_inode->i_mode, to))
-+ error = -EPERM;
-+ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
-+ old_nd.dentry, old_nd.mnt, to))
-+ error = -EACCES;
-+ if (!error)
-+ error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-+
-+ if (!error)
-+ gr_handle_create(new_dentry, nd.mnt);
-+
- dput(new_dentry);
- }
- up(&nd.dentry->d_inode->i_sem);
-@@ -2098,8 +2239,16 @@
- if (new_dentry == trap)
- goto exit5;
-
-- error = vfs_rename(old_dir->d_inode, old_dentry,
-+ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
-+ old_dentry, old_dir->d_inode, oldnd.mnt,
-+ newname);
-+
-+ if (!error)
-+ error = vfs_rename(old_dir->d_inode, old_dentry,
- new_dir->d_inode, new_dentry);
-+ if (!error)
-+ gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry,
-+ new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
- exit5:
- dput(new_dentry);
- exit4:
-diff -urN linux-2.6.5/fs/namespace.c linux-2.6.5/fs/namespace.c
---- linux-2.6.5/fs/namespace.c 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/fs/namespace.c 2004-04-18 11:05:50.000000000 -0400
-@@ -21,6 +21,8 @@
- #include <linux/namei.h>
- #include <linux/security.h>
- #include <linux/mount.h>
-+#include <linux/sched.h>
-+#include <linux/grsecurity.h>
- #include <asm/uaccess.h>
-
- extern int __init init_rootfs(void);
-@@ -334,6 +336,8 @@
- lock_kernel();
- retval = do_remount_sb(sb, MS_RDONLY, 0, 0);
- unlock_kernel();
-+
-+ gr_log_remount(mnt->mnt_devname, retval);
- }
- up_write(&sb->s_umount);
- return retval;
-@@ -362,6 +366,9 @@
- if (retval)
- security_sb_umount_busy(mnt);
- up_write(&current->namespace->sem);
-+
-+ gr_log_unmount(mnt->mnt_devname, retval);
-+
- return retval;
- }
-
-@@ -780,6 +787,11 @@
- if (retval)
- goto dput_out;
-
-+ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
-+ retval = -EPERM;
-+ goto dput_out;
-+ }
-+
- if (flags & MS_REMOUNT)
- retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
- data_page);
-@@ -792,6 +804,9 @@
- dev_name, data_page);
- dput_out:
- path_release(&nd);
-+
-+ gr_log_mount(dev_name, dir_name, retval);
-+
- return retval;
- }
-
-@@ -1014,6 +1029,9 @@
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
-+ if (gr_handle_chroot_pivot())
-+ return -EPERM;
-+
- lock_kernel();
-
- error = __user_walk(new_root, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
-diff -urN linux-2.6.5/fs/open.c linux-2.6.5/fs/open.c
---- linux-2.6.5/fs/open.c 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/fs/open.c 2004-04-18 11:05:50.000000000 -0400
-@@ -22,6 +22,7 @@
- #include <asm/uaccess.h>
- #include <linux/fs.h>
- #include <linux/pagemap.h>
-+#include <linux/grsecurity.h>
-
- int vfs_statfs(struct super_block *sb, struct kstatfs *buf)
- {
-@@ -180,7 +181,7 @@
- return error;
- }
-
--int do_truncate(struct dentry *dentry, loff_t length)
-+int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
- {
- int err;
- struct iattr newattrs;
-@@ -189,6 +190,9 @@
- if (length < 0)
- return -EINVAL;
-
-+ if (!gr_acl_handle_truncate(dentry, mnt))
-+ return -EACCES;
-+
- newattrs.ia_size = length;
- newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
- down(&dentry->d_inode->i_sem);
-@@ -247,7 +251,7 @@
- error = locks_verify_truncate(inode, NULL, length);
- if (!error) {
- DQUOT_INIT(inode);
-- error = do_truncate(nd.dentry, length);
-+ error = do_truncate(nd.dentry, length, nd.mnt);
- }
- put_write_access(inode);
-
-@@ -299,7 +303,7 @@
-
- error = locks_verify_truncate(inode, file, length);
- if (!error)
-- error = do_truncate(dentry, length);
-+ error = do_truncate(dentry, length, file->f_vfsmnt);
- out_putf:
- fput(file);
- out:
-@@ -378,6 +382,11 @@
- (error = permission(inode,MAY_WRITE,&nd)) != 0)
- goto dput_and_out;
- }
-+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
-+ error = -EACCES;
-+ goto dput_and_out;
-+ }
-+
- down(&inode->i_sem);
- error = notify_change(nd.dentry, &newattrs);
- up(&inode->i_sem);
-@@ -431,6 +440,12 @@
- (error = permission(inode,MAY_WRITE,&nd)) != 0)
- goto dput_and_out;
- }
-+
-+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
-+ error = -EACCES;
-+ goto dput_and_out;
-+ }
-+
- down(&inode->i_sem);
- error = notify_change(nd.dentry, &newattrs);
- up(&inode->i_sem);
-@@ -492,6 +507,10 @@
- if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
- && !special_file(nd.dentry->d_inode->i_mode))
- res = -EROFS;
-+
-+ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
-+ res = -EACCES;
-+
- path_release(&nd);
- }
-
-@@ -515,6 +534,8 @@
- if (error)
- goto dput_and_out;
-
-+ gr_log_chdir(nd.dentry, nd.mnt);
-+
- set_fs_pwd(current->fs, nd.mnt, nd.dentry);
-
- dput_and_out:
-@@ -545,6 +566,13 @@
- goto out_putf;
-
- error = permission(inode, MAY_EXEC, NULL);
-+
-+ if (!error && !gr_chroot_fchdir(dentry, mnt))
-+ error = -EPERM;
-+
-+ if (!error)
-+ gr_log_chdir(dentry, mnt);
-+
- if (!error)
- set_fs_pwd(current->fs, mnt, dentry);
- out_putf:
-@@ -570,8 +598,16 @@
- if (!capable(CAP_SYS_CHROOT))
- goto dput_and_out;
-
-+ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
-+ goto dput_and_out;
-+
- set_fs_root(current->fs, nd.mnt, nd.dentry);
- set_fs_altroot();
-+
-+ gr_handle_chroot_caps(current);
-+
-+ gr_handle_chroot_chdir(nd.dentry, nd.mnt);
-+
- error = 0;
- dput_and_out:
- path_release(&nd);
-@@ -600,9 +636,22 @@
- err = -EPERM;
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- goto out_putf;
-+
-+ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
-+ err = -EACCES;
-+ goto out_putf;
-+ }
-+
- down(&inode->i_sem);
- if (mode == (mode_t) -1)
- mode = inode->i_mode;
-+
-+ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
-+ err = -EPERM;
-+ up(&inode->i_sem);
-+ goto out_putf;
-+ }
-+
- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
- err = notify_change(dentry, &newattrs);
-@@ -634,9 +683,21 @@
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- goto dput_and_out;
-
-+ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
-+ error = -EACCES;
-+ goto dput_and_out;
-+ }
-+
- down(&inode->i_sem);
- if (mode == (mode_t) -1)
- mode = inode->i_mode;
-+
-+ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
-+ error = -EACCES;
-+ up(&inode->i_sem);
-+ goto dput_and_out;
-+ }
-+
- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
- error = notify_change(nd.dentry, &newattrs);
-@@ -648,7 +709,7 @@
- return error;
- }
-
--static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
-+static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
- {
- struct inode * inode;
- int error;
-@@ -665,6 +726,12 @@
- error = -EPERM;
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- goto out;
-+
-+ if (!gr_acl_handle_chown(dentry, mnt)) {
-+ error = -EACCES;
-+ goto out;
-+ }
-+
- newattrs.ia_valid = ATTR_CTIME;
- if (user != (uid_t) -1) {
- newattrs.ia_valid |= ATTR_UID;
-@@ -690,7 +757,7 @@
-
- error = user_path_walk(filename, &nd);
- if (!error) {
-- error = chown_common(nd.dentry, user, group);
-+ error = chown_common(nd.dentry, user, group, nd.mnt);
- path_release(&nd);
- }
- return error;
-@@ -703,7 +770,7 @@
-
- error = user_path_walk_link(filename, &nd);
- if (!error) {
-- error = chown_common(nd.dentry, user, group);
-+ error = chown_common(nd.dentry, user, group, nd.mnt);
- path_release(&nd);
- }
- return error;
-@@ -717,7 +784,8 @@
-
- file = fget(fd);
- if (file) {
-- error = chown_common(file->f_dentry, user, group);
-+ error = chown_common(file->f_dentry, user,
-+ group, file->f_vfsmnt);
- fput(file);
- }
- return error;
-@@ -839,6 +907,7 @@
- * N.B. For clone tasks sharing a files structure, this test
- * will limit the total number of files that can be opened.
- */
-+ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
- if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
- goto out;
-
-diff -urN linux-2.6.5/fs/proc/array.c linux-2.6.5/fs/proc/array.c
---- linux-2.6.5/fs/proc/array.c 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/fs/proc/array.c 2004-04-18 11:05:50.000000000 -0400
-@@ -271,6 +271,19 @@
- cap_t(p->cap_effective));
- }
-
-+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
-+static inline char *task_pax(struct task_struct *p, char *buffer)
-+{
-+ return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c%c\n",
-+ p->flags & PF_PAX_PAGEEXEC ? 'P' : 'p',
-+ p->flags & PF_PAX_EMUTRAMP ? 'E' : 'e',
-+ p->flags & PF_PAX_MPROTECT ? 'M' : 'm',
-+ p->flags & PF_PAX_RANDMMAP ? 'R' : 'r',
-+ p->flags & PF_PAX_RANDEXEC ? 'X' : 'x',
-+ p->flags & PF_PAX_SEGMEXEC ? 'S' : 's');
-+}
-+#endif
-+
- extern char *task_mem(struct mm_struct *, char *);
- int proc_pid_status(struct task_struct *task, char * buffer)
- {
-@@ -289,9 +302,20 @@
- #if defined(CONFIG_ARCH_S390)
- buffer = task_show_regs(task, buffer);
- #endif
-+
-+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
-+ buffer = task_pax(task, buffer);
-+#endif
-+
- return buffer - orig;
- }
-
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
-+ task->flags & PF_PAX_SEGMEXEC || \
-+ task->flags & PF_PAX_RANDEXEC)
-+#endif
-+
- extern unsigned long task_vsize(struct mm_struct *);
- int proc_pid_stat(struct task_struct *task, char * buffer)
- {
-@@ -326,6 +350,19 @@
-
- wchan = get_wchan(task);
-
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ if (PAX_RAND_FLAGS) {
-+ eip = 0;
-+ esp = 0;
-+ wchan = 0;
-+ }
-+#endif
-+#ifdef CONFIG_GRKERNSEC_HIDESYM
-+ wchan = 0;
-+ eip =0;
-+ esp =0;
-+#endif
-+
- sigemptyset(&sigign);
- sigemptyset(&sigcatch);
- read_lock(&tasklist_lock);
-@@ -374,9 +411,15 @@
- vsize,
- mm ? mm->rss : 0, /* you might want to shift this left 3 */
- task->rlim[RLIMIT_RSS].rlim_cur,
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0),
-+ PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0),
-+ PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0),
-+#else
- mm ? mm->start_code : 0,
- mm ? mm->end_code : 0,
- mm ? mm->start_stack : 0,
-+#endif
- esp,
- eip,
- /* The signal information here is obsolete.
-@@ -416,3 +459,14 @@
- return sprintf(buffer,"%d %d %d %d %d %d %d\n",
- size, resident, shared, text, lib, data, 0);
- }
-+
-+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
-+int proc_pid_ipaddr(struct task_struct *task, char * buffer)
-+{
-+ int len;
-+
-+ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));
-+ return len;
-+}
-+#endif
-+
-diff -urN linux-2.6.5/fs/proc/base.c linux-2.6.5/fs/proc/base.c
---- linux-2.6.5/fs/proc/base.c 2004-04-03 22:37:25.000000000 -0500
-+++ linux-2.6.5/fs/proc/base.c 2004-04-18 11:05:50.000000000 -0400
-@@ -32,6 +32,7 @@
- #include <linux/mount.h>
- #include <linux/security.h>
- #include <linux/ptrace.h>
-+#include <linux/grsecurity.h>
-
- /*
- * For hysterical raisins we keep the same inumbers as in the old procfs.
-@@ -67,6 +68,9 @@
- PROC_TGID_ATTR_EXEC,
- PROC_TGID_ATTR_FSCREATE,
- #endif
-+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
-+ PROC_TGID_IPADDR,
-+#endif
- PROC_TGID_FD_DIR,
- PROC_TID_INO,
- PROC_TID_STATUS,
-@@ -117,6 +121,9 @@
- E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
- E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
- E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
-+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
-+ E(PROC_TGID_IPADDR, "ipaddr", S_IFREG|S_IRUSR),
-+#endif
- #ifdef CONFIG_SECURITY
- E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
- #endif
-@@ -181,6 +188,9 @@
- int proc_pid_status(struct task_struct*,char*);
- int proc_pid_statm(struct task_struct*,char*);
- int proc_pid_cpu(struct task_struct*,char*);
-+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
-+int proc_pid_ipaddr(struct task_struct*,char*);
-+#endif
-
- static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
- {
-@@ -281,7 +291,7 @@
- (task == current || \
- (task->parent == current && \
- (task->ptrace & PT_PTRACED) && task->state == TASK_STOPPED && \
-- security_ptrace(current,task) == 0))
-+ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
-
- static int may_ptrace_attach(struct task_struct *task)
- {
-@@ -296,13 +306,15 @@
- (current->uid != task->uid) ||
- (current->gid != task->egid) ||
- (current->gid != task->sgid) ||
-- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
-+ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
- goto out;
- rmb();
-- if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
-+ if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
- goto out;
- if (security_ptrace(current, task))
- goto out;
-+ if (gr_handle_proc_ptrace(task))
-+ goto out;
-
- retval = 1;
- out:
-@@ -449,9 +461,22 @@
-
- static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
- {
-+ int ret;
-+ struct task_struct *task;
-+
- if (vfs_permission(inode, mask) != 0)
- return -EACCES;
-- return proc_check_root(inode);
-+ ret = proc_check_root(inode);
-+
-+ if (ret)
-+ return ret;
-+
-+ task = proc_task(inode);
-+
-+ if (!task)
-+ return 0;
-+
-+ return gr_acl_handle_procpidmem(task);
- }
-
- extern struct seq_operations proc_pid_maps_op;
-@@ -962,6 +987,9 @@
- inode->i_uid = task->euid;
- inode->i_gid = task->egid;
- }
-+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
-+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
-+#endif
- security_task_to_inode(task, inode);
-
- out:
-@@ -990,7 +1018,9 @@
- if (pid_alive(task)) {
- if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
- inode->i_uid = task->euid;
-+#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
- inode->i_gid = task->egid;
-+#endif
- } else {
- inode->i_uid = 0;
- inode->i_gid = 0;
-@@ -1334,6 +1364,12 @@
- inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_pid_status;
- break;
-+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
-+ case PROC_TGID_IPADDR:
-+ inode->i_fop = &proc_info_file_operations;
-+ ei->op.proc_read = proc_pid_ipaddr;
-+ break;
-+#endif
- case PROC_TID_STAT:
- case PROC_TGID_STAT:
- inode->i_fop = &proc_info_file_operations;
-@@ -1583,6 +1619,22 @@
- if (!task)
- goto out;
-
-+ if (gr_check_hidden_task(task)) {
-+ put_task_struct(task);
-+ goto out;
-+ }
-+
-+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
-+ if (current->uid && (task->uid != current->uid)
-+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
-+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
-+#endif
-+ ) {
-+ put_task_struct(task);
-+ goto out;
-+ }
-+#endif
-+
- inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
-
-
-@@ -1590,7 +1642,15 @@
- put_task_struct(task);
- goto out;
- }
-+
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
-+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
-+#else
- inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
-+#endif
- inode->i_op = &proc_tgid_base_inode_operations;
- inode->i_fop = &proc_tgid_base_operations;
- inode->i_nlink = 3;
-@@ -1674,6 +1734,9 @@
- static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
- {
- struct task_struct *p;
-+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
-+ struct task_struct *tmp = current;
-+#endif
- int nr_tgids = 0;
-
- index--;
-@@ -1694,6 +1757,18 @@
- int tgid = p->pid;
- if (!pid_alive(p))
- continue;
-+ if (gr_pid_is_chrooted(p))
-+ continue;
-+ if (gr_check_hidden_task(p))
-+ continue;
-+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
-+ if (tmp->uid && (p->uid != tmp->uid)
-+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
-+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
-+#endif
-+ )
-+ continue;
-+#endif
- if (--index >= 0)
- continue;
- tgids[nr_tgids] = tgid;
-diff -urN linux-2.6.5/fs/proc/inode.c linux-2.6.5/fs/proc/inode.c
---- linux-2.6.5/fs/proc/inode.c 2004-04-03 22:38:14.000000000 -0500
-+++ linux-2.6.5/fs/proc/inode.c 2004-04-18 11:05:50.000000000 -0400
-@@ -205,7 +205,11 @@
- if (de->mode) {
- inode->i_mode = de->mode;
- inode->i_uid = de->uid;
-+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
-+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
-+#else
- inode->i_gid = de->gid;
-+#endif
- }
- if (de->size)
- inode->i_size = de->size;
-diff -urN linux-2.6.5/fs/proc/proc_misc.c linux-2.6.5/fs/proc/proc_misc.c
---- linux-2.6.5/fs/proc/proc_misc.c 2004-04-03 22:36:24.000000000 -0500
-+++ linux-2.6.5/fs/proc/proc_misc.c 2004-04-18 11:05:50.000000000 -0400
-@@ -654,6 +654,8 @@
- void __init proc_misc_init(void)
- {
- struct proc_dir_entry *entry;
-+ int gr_mode = 0;
-+
- static struct {
- char *name;
- int (*read_proc)(char*,char**,off_t,int,int*,void*);
-@@ -668,9 +670,13 @@
- #ifdef CONFIG_STRAM_PROC
- {"stram", stram_read_proc},
- #endif
-+#ifndef CONFIG_GRKERNSEC_PROC_ADD
- {"devices", devices_read_proc},
-+#endif
- {"filesystems", filesystems_read_proc},
-+#ifndef CONFIG_GRKERNSEC_PROC_ADD
- {"cmdline", cmdline_read_proc},
-+#endif
- #ifdef CONFIG_SGI_DS1286
- {"rtc", ds1286_read_proc},
- #endif
-@@ -681,24 +687,39 @@
- for (p = simple_ones; p->name; p++)
- create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
-
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ gr_mode = S_IRUSR;
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ gr_mode = S_IRUSR | S_IRGRP;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+ create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
-+ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
-+#endif
-+
- proc_symlink("mounts", NULL, "self/mounts");
-
- /* And now for trickier ones */
- entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
- if (entry)
- entry->proc_fops = &proc_kmsg_operations;
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+ create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
-+ create_seq_entry("slabinfo",gr_mode,&proc_slabinfo_operations);
-+#else
- create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
-+ create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
-+#endif
- create_seq_entry("partitions", 0, &proc_partitions_operations);
- create_seq_entry("stat", 0, &proc_stat_operations);
- create_seq_entry("interrupts", 0, &proc_interrupts_operations);
-- create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
- create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
- create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
- create_seq_entry("diskstats", 0, &proc_diskstats_operations);
- #ifdef CONFIG_MODULES
-- create_seq_entry("modules", 0, &proc_modules_operations);
-+ create_seq_entry("modules", gr_mode, &proc_modules_operations);
- #endif
--#ifdef CONFIG_PROC_KCORE
-+#if defined(CONFIG_PROC_KCORE)
- proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
- if (proc_root_kcore) {
- proc_root_kcore->proc_fops = &proc_kcore_operations;
-diff -urN linux-2.6.5/fs/proc/root.c linux-2.6.5/fs/proc/root.c
---- linux-2.6.5/fs/proc/root.c 2004-04-03 22:37:40.000000000 -0500
-+++ linux-2.6.5/fs/proc/root.c 2004-04-18 11:05:50.000000000 -0400
-@@ -52,13 +52,26 @@
- return;
- }
- proc_misc_init();
-+
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, 0);
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
-+#else
- proc_net = proc_mkdir("net", 0);
-+#endif
- #ifdef CONFIG_SYSVIPC
- proc_mkdir("sysvipc", 0);
- #endif
- #ifdef CONFIG_SYSCTL
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR, 0);
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
-+#else
- proc_sys_root = proc_mkdir("sys", 0);
- #endif
-+#endif
- #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
- proc_mkdir("sys/fs", 0);
- proc_mkdir("sys/fs/binfmt_misc", 0);
-@@ -74,7 +87,15 @@
- #ifdef CONFIG_PROC_DEVICETREE
- proc_device_tree_init();
- #endif
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, 0);
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
-+#endif
-+#else
- proc_bus = proc_mkdir("bus", 0);
-+#endif
- }
-
- static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
-diff -urN linux-2.6.5/fs/proc/task_mmu.c linux-2.6.5/fs/proc/task_mmu.c
---- linux-2.6.5/fs/proc/task_mmu.c 2004-04-03 22:36:24.000000000 -0500
-+++ linux-2.6.5/fs/proc/task_mmu.c 2004-04-18 11:05:51.000000000 -0400
-@@ -76,8 +76,17 @@
- return size;
- }
-
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
-+ task->flags & PF_PAX_SEGMEXEC || \
-+ task->flags & PF_PAX_RANDEXEC)
-+#endif
-+
- static int show_map(struct seq_file *m, void *v)
- {
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ struct task_struct *task = m->private;
-+#endif
- struct vm_area_struct *map = v;
- struct file *file = map->vm_file;
- int flags = map->vm_flags;
-@@ -92,8 +101,14 @@
- }
-
- seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+ PAX_RAND_FLAGS ? 0UL : map->vm_start,
-+ PAX_RAND_FLAGS ? 0UL : map->vm_end,
-+#else
- map->vm_start,
- map->vm_end,
-+#endif
-+
- flags & VM_READ ? 'r' : '-',
- flags & VM_WRITE ? 'w' : '-',
- flags & VM_EXEC ? 'x' : '-',
-diff -urN linux-2.6.5/fs/readdir.c linux-2.6.5/fs/readdir.c
---- linux-2.6.5/fs/readdir.c 2004-04-03 22:37:06.000000000 -0500
-+++ linux-2.6.5/fs/readdir.c 2004-04-18 11:05:50.000000000 -0400
-@@ -14,6 +14,8 @@
- #include <linux/fs.h>
- #include <linux/dirent.h>
- #include <linux/security.h>
-+#include <linux/namei.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
-
-@@ -64,6 +66,7 @@
- struct readdir_callback {
- struct old_linux_dirent __user * dirent;
- int result;
-+ struct nameidata nd;
- };
-
- static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
-@@ -74,6 +77,10 @@
-
- if (buf->result)
- return -EINVAL;
-+
-+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
-+ return 0;
-+
- buf->result++;
- dirent = buf->dirent;
- if (!access_ok(VERIFY_WRITE, (unsigned long)dirent,
-@@ -106,6 +113,9 @@
- buf.result = 0;
- buf.dirent = dirent;
-
-+ buf.nd.dentry = file->f_dentry;
-+ buf.nd.mnt = file->f_vfsmnt;
-+
- error = vfs_readdir(file, fillonedir, &buf);
- if (error >= 0)
- error = buf.result;
-@@ -133,6 +143,7 @@
- struct linux_dirent __user * previous;
- int count;
- int error;
-+ struct nameidata nd;
- };
-
- static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
-@@ -145,6 +156,10 @@
- buf->error = -EINVAL; /* only used if we fail.. */
- if (reclen > buf->count)
- return -EINVAL;
-+
-+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
-+ return 0;
-+
- dirent = buf->previous;
- if (dirent) {
- if (__put_user(offset, &dirent->d_off))
-@@ -192,6 +207,9 @@
- buf.count = count;
- buf.error = 0;
-
-+ buf.nd.dentry = file->f_dentry;
-+ buf.nd.mnt = file->f_vfsmnt;
-+
- error = vfs_readdir(file, filldir, &buf);
- if (error < 0)
- goto out_putf;
-@@ -217,6 +235,7 @@
- struct linux_dirent64 __user * previous;
- int count;
- int error;
-+ struct nameidata nd;
- };
-
- static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
-@@ -229,6 +248,10 @@
- buf->error = -EINVAL; /* only used if we fail.. */
- if (reclen > buf->count)
- return -EINVAL;
-+
-+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
-+ return 0;
-+
- dirent = buf->previous;
- if (dirent) {
- if (__put_user(offset, &dirent->d_off))
-@@ -278,6 +301,9 @@
- buf.count = count;
- buf.error = 0;
-
-+ buf.nd.mnt = file->f_vfsmnt;
-+ buf.nd.dentry = file->f_dentry;
-+
- error = vfs_readdir(file, filldir64, &buf);
- if (error < 0)
- goto out_putf;
-diff -urN linux-2.6.5/grsecurity/Kconfig linux-2.6.5/grsecurity/Kconfig
---- linux-2.6.5/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/Kconfig 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,864 @@
-+#
-+# grecurity configuration
-+#
-+
-+menu "Grsecurity"
-+
-+config GRKERNSEC
-+ bool "Grsecurity"
-+ select CRYPTO
-+ select CRYPTO_SHA256
-+ help
-+ If you say Y here, you will be able to configure many features
-+ that will enhance the security of your system. It is highly
-+ recommended that you say Y here and read through the help
-+ for each option so that you fully understand the features and
-+ can evaluate their usefulness for your machine.
-+
-+choice
-+ prompt "Security Level"
-+ depends GRKERNSEC
-+ default GRKERNSEC_CUSTOM
-+
-+config GRKERNSEC_LOW
-+ bool "Low"
-+ select GRKERNSEC_LINK
-+ select GRKERNSEC_FIFO
-+ select GRKERNSEC_RANDPID
-+ select GRKERNSEC_EXECVE
-+ select GRKERNSEC_RANDNET
-+ select GRKERNSEC_RANDISN
-+ select GRKERNSEC_DMESG
-+ select GRKERNSEC_RANDID
-+ select GRKERNSEC_CHROOT_CHDIR
-+ help
-+ If you choose this option, several of the grsecurity options will
-+ be enabled that will give you greater protection against a number
-+ of attacks, while assuring that none of your software will have any
-+ conflicts with the additional security measures. If you run a lot
-+ of unusual software, or you are having problems with the higher
-+ security levels, you should say Y here. With this option, the
-+ following features are enabled:
-+
-+ - Linking Restrictions
-+ - FIFO Restrictions
-+ - Randomized PIDs
-+ - Enforcing RLIMIT_NPROC on execve
-+ - Restricted dmesg
-+ - Randomized IP IDs
-+ - Enforced chdir("/") on chroot
-+
-+config GRKERNSEC_MEDIUM
-+ bool "Medium"
-+ select PAX_EI_PAX
-+ select PAX_PT_PAX_FLAGS
-+ select PAX_HAVE_ACL_FLAGS
-+ select GRKERNSEC_PROC_MEMMAP
-+ select GRKERNSEC_CHROOT_SYSCTL
-+ select GRKERNSEC_LINK
-+ select GRKERNSEC_FIFO
-+ select GRKERNSEC_RANDPID
-+ select GRKERNSEC_EXECVE
-+ select GRKERNSEC_DMESG
-+ select GRKERNSEC_RANDID
-+ select GRKERNSEC_RANDNET
-+ select GRKERNSEC_RANDISN
-+ select GRKERNSEC_RANDSRC
-+ select GRKERNSEC_RANDRPC
-+ select GRKERNSEC_FORKFAIL
-+ select GRKERNSEC_TIME
-+ select GRKERNSEC_SIGNAL
-+ select GRKERNSEC_CHROOT
-+ select GRKERNSEC_CHROOT_UNIX
-+ select GRKERNSEC_CHROOT_MOUNT
-+ select GRKERNSEC_CHROOT_PIVOT
-+ select GRKERNSEC_CHROOT_DOUBLE
-+ select GRKERNSEC_CHROOT_CHDIR
-+ select GRKERNSEC_CHROOT_MKNOD
-+ select GRKERNSEC_PROC
-+ select GRKERNSEC_PROC_USERGROUP
-+ select PAX_RANDUSTACK
-+ select PAX_ASLR
-+ select PAX_RANDMMAP
-+
-+ help
-+ If you say Y here, several features in addition to those included
-+ in the low additional security level will be enabled. These
-+ features provide even more security to your system, though in rare
-+ cases they may be incompatible with very old or poorly written
-+ software. If you enable this option, make sure that your auth
-+ service (identd) is running as gid 1001. With this option,
-+ the following features (in addition to those provided in the
-+ low additional security level) will be enabled:
-+
-+ - Randomized TCP Source Ports
-+ - Failed Fork Logging
-+ - Time Change Logging
-+ - Signal Logging
-+ - Deny Mounts in chroot
-+ - Deny Double chrooting
-+ - Deny Sysctl Writes in chroot
-+ - Deny Mknod in chroot
-+ - Deny Access to Abstract AF_UNIX Sockets out of chroot
-+ - Deny pivot_root in chroot
-+ - Denied Writes of /dev/kmem, /dev/mem, and /dev/port
-+ - /proc restrictions with special GID set to 10 (usually wheel)
-+ - Address Space Layout Randomization (ASLR)
-+
-+config GRKERNSEC_HIGH
-+ bool "High"
-+ select GRKERNSEC_LINK
-+ select GRKERNSEC_FIFO
-+ select GRKERNSEC_RANDPID
-+ select GRKERNSEC_EXECVE
-+ select GRKERNSEC_DMESG
-+ select GRKERNSEC_RANDID
-+ select GRKERNSEC_RANDSRC
-+ select GRKERNSEC_RANDRPC
-+ select GRKERNSEC_FORKFAIL
-+ select GRKERNSEC_TIME
-+ select GRKERNSEC_SIGNAL
-+ select GRKERNSEC_CHROOT_SHMAT
-+ select GRKERNSEC_CHROOT_UNIX
-+ select GRKERNSEC_CHROOT_MOUNT
-+ select GRKERNSEC_CHROOT_FCHDIR
-+ select GRKERNSEC_CHROOT_PIVOT
-+ select GRKERNSEC_CHROOT_DOUBLE
-+ select GRKERNSEC_CHROOT_CHDIR
-+ select GRKERNSEC_CHROOT_MKNOD
-+ select GRKERNSEC_CHROOT_CAPS
-+ select GRKERNSEC_CHROOT_SYSCTL
-+ select GRKERNSEC_CHROOT_FINDTASK
-+ select GRKERNSEC_PROC
-+ select GRKERNSEC_PROC_MEMMAP
-+ select GRKERNSEC_HIDESYM
-+ select GRKERNSEC_PROC_USERGROUP
-+ select GRKERNSEC_KMEM
-+ select GRKERNSEC_RESLOG
-+ select GRKERNSEC_RANDNET
-+ select GRKERNSEC_RANDISN
-+ select GRKERNSEC_PROC_ADD
-+ select GRKERNSEC_CHROOT_CHMOD
-+ select GRKERNSEC_CHROOT_NICE
-+ select GRKERNSEC_AUDIT_MOUNT
-+ select PAX_RANDUSTACK
-+ select PAX_ASLR
-+ select PAX_RANDMMAP
-+ select PAX_NOEXEC
-+ select PAX_MPROTECT
-+ select PAX_EI_PAX
-+ select PAX_PT_PAX_FLAGS
-+ select PAX_HAVE_ACL_FLAGS
-+ select PAX_KERNEXEC
-+ select PAX_RANDKSTACK
-+ select PAX_RANDEXEC
-+ select PAX_SEGMEXEC
-+ select PAX_EMUTRAMP
-+ select PAX_NOVSYSCALL
-+ help
-+ If you say Y here, many of the features of grsecurity will be
-+ enabled, which will protect you against many kinds of attacks
-+ against your system. The heightened security comes at a cost
-+ of an increased chance of incompatibilities with rare software
-+ on your machine. Since this security level enables PaX, you should
-+ view <http://pax.grsecurity.net> and read about the PaX
-+ project. While you are there, download chpax and run it on
-+ binaries that cause problems with PaX. Also remember that
-+ since the /proc restrictions are enabled, you must run your
-+ identd as gid 1001. This security level enables the following
-+ features in addition to those listed in the low and medium
-+ security levels:
-+
-+ - Additional /proc Restrictions
-+ - Chmod Restrictions in chroot
-+ - No Signals, Ptrace, or Viewing of Processes Outside of chroot
-+ - Capability Restrictions in chroot
-+ - Deny fchdir out of chroot
-+ - Priority Restrictions in chroot
-+ - Segmentation-based Implementation of PaX
-+ - Mprotect Restrictions
-+ - Removal of Addresses from /proc/<pid>/[maps|stat]
-+ - Kernel Stack Randomization
-+ - Mount/Unmount/Remount Logging
-+ - Kernel Symbol Hiding
-+
-+config GRKERNSEC_CUSTOM
-+ bool "Custom"
-+ help
-+ If you say Y here, you will be able to configure every grsecurity
-+ option, which allows you to enable many more features that aren't
-+ covered in the basic security levels. These additional features
-+ include TPE, socket restrictions, and the sysctl system for
-+ grsecurity. It is advised that you read through the help for
-+ each option to determine its usefulness in your situation.
-+
-+endchoice
-+
-+menu "Address Space Protection"
-+depends on GRKERNSEC
-+
-+config GRKERNSEC_KMEM
-+ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
-+ help
-+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
-+ be written to via mmap or otherwise to modify the running kernel.
-+ /dev/port will also not be allowed to be opened. If you have module
-+ support disabled, enabling this will close up four ways that are
-+ currently used to insert malicious code into the running kernel.
-+ Even with all these features enabled, we still highly recommend that
-+ you use the ACL system, as it is still possible for an attacker to
-+ modify the running kernel through privileged I/O granted by ioperm/iopl.
-+ If you are not using XFree86, you may be able to stop this additional
-+ case by enabling the 'Disable privileged I/O' option. Though nothing
-+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
-+ but only to video memory, which is the only writing we allow in this
-+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
-+ not be allowed to mprotect it with PROT_WRITE later.
-+ Enabling this feature could make certain apps like VMWare stop working,
-+ as they need to write to other locations in /dev/mem.
-+ It is highly recommended that you say Y here if you meet all the
-+ conditions above.
-+
-+config GRKERNSEC_IO
-+ bool "Disable privileged I/O"
-+ depends on X86
-+ select RTC
-+ help
-+ If you say Y here, all ioperm and iopl calls will return an error.
-+ Ioperm and iopl can be used to modify the running kernel.
-+ Unfortunately, some programs need this access to operate properly,
-+ the most notable of which are XFree86 and hwclock. hwclock can be
-+ remedied by having RTC support in the kernel, so CONFIG_RTC is
-+ enabled if this option is enabled, to ensure that hwclock operates
-+ correctly. XFree86 still will not operate correctly with this option
-+ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
-+ and you still want to protect your kernel against modification,
-+ use the ACL system.
-+
-+config GRKERNSEC_PROC_MEMMAP
-+ bool "Remove addresses from /proc/<pid>/[maps|stat]"
-+ help
-+ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
-+ give no information about the addresses of its mappings if
-+ PaX features that rely on random addresses are enabled on the task.
-+ If you use PaX it is greatly recommended that you say Y here as it
-+ closes up a hole that makes the full ASLR useless for suid
-+ binaries.
-+
-+config GRKERNSEC_HIDESYM
-+ bool "Hide kernel symbols"
-+ help
-+ If you say Y here, getting information on loaded modules, and
-+ displaying all kernel symbols through a syscall will be restricted
-+ to users with CAP_SYS_MODULE. This option is only effective
-+ provided the following conditions are met:
-+ 1) The kernel using grsecurity is not precompiled by some distribution
-+ 2) You are using the ACL system and hiding other files such as your
-+ kernel image and System.map
-+ 3) You have the additional /proc restrictions enabled, which removes
-+ /proc/kcore
-+ If the above conditions are met, this option will aid to provide a
-+ useful protection against local and remote kernel exploitation of
-+ overflows and arbitrary read/write vulnerabilities.
-+
-+endmenu
-+menu "Role Based Access Control Options"
-+depends on GRKERNSEC
-+
-+config GRKERNSEC_ACL_HIDEKERN
-+ bool "Hide kernel processes"
-+ help
-+ If you say Y here, when the RBAC system is enabled via gradm -E,
-+ an additional ACL will be passed to the kernel that hides all kernel
-+ processes. These processes will only be viewable by the authenticated
-+ admin, or processes that have viewing access set.
-+
-+config GRKERNSEC_ACL_MAXTRIES
-+ int "Maximum tries before password lockout"
-+ default 3
-+ help
-+ This option enforces the maximum number of times a user can attempt
-+ to authorize themselves with the grsecurity ACL system before being
-+ denied the ability to attempt authorization again for a specified time.
-+ The lower the number, the harder it will be to brute-force a password.
-+
-+config GRKERNSEC_ACL_TIMEOUT
-+ int "Time to wait after max password tries, in seconds"
-+ default 30
-+ help
-+ This option specifies the time the user must wait after attempting to
-+ authorize to the ACL system with the maximum number of invalid
-+ passwords. The higher the number, the harder it will be to brute-force
-+ a password.
-+
-+endmenu
-+menu "Filesystem Protections"
-+depends on GRKERNSEC
-+
-+config GRKERNSEC_PROC
-+ bool "Proc restrictions"
-+ help
-+ If you say Y here, the permissions of the /proc filesystem
-+ will be altered to enhance system security and privacy. Depending
-+ upon the options you choose, you can either restrict users to see
-+ only the processes they themselves run, or choose a group that can
-+ view all processes and files normally restricted to root if you choose
-+ the "restrict to user only" option. NOTE: If you're running identd as
-+ a non-root user, you will have to run it as the group you specify here.
-+
-+config GRKERNSEC_PROC_USER
-+ bool "Restrict /proc to user only"
-+ depends on GRKERNSEC_PROC
-+ help
-+ If you say Y here, non-root users will only be able to view their own
-+ processes, and restricts them from viewing network-related information,
-+ and viewing kernel symbol and module information.
-+
-+config GRKERNSEC_PROC_USERGROUP
-+ bool "Allow special group"
-+ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
-+ help
-+ If you say Y here, you will be able to select a group that will be
-+ able to view all processes, network-related information, and
-+ kernel and symbol information. This option is useful if you want
-+ to run identd as a non-root user.
-+
-+config GRKERNSEC_PROC_GID
-+ int "GID for special group"
-+ depends on GRKERNSEC_PROC_USERGROUP
-+ default 1001
-+
-+config GRKERNSEC_PROC_ADD
-+ bool "Additional restrictions"
-+ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
-+ help
-+ If you say Y here, additional restrictions will be placed on
-+ /proc that keep normal users from viewing cpu and device information.
-+
-+config GRKERNSEC_LINK
-+ bool "Linking restrictions"
-+ help
-+ If you say Y here, /tmp race exploits will be prevented, since users
-+ will no longer be able to follow symlinks owned by other users in
-+ world-writable +t directories (i.e. /tmp), unless the owner of the
-+ symlink is the owner of the directory. users will also not be
-+ able to hardlink to files they do not own. If the sysctl option is
-+ enabled, a sysctl option with name "linking_restrictions" is created.
-+
-+config GRKERNSEC_FIFO
-+ bool "FIFO restrictions"
-+ help
-+ If you say Y here, users will not be able to write to FIFOs they don't
-+ own in world-writable +t directories (i.e. /tmp), unless the owner of
-+ the FIFO is the same owner of the directory it's held in. If the sysctl
-+ option is enabled, a sysctl option with name "fifo_restrictions" is
-+ created.
-+
-+config GRKERNSEC_CHROOT
-+ bool "Chroot jail restrictions"
-+ help
-+ If you say Y here, you will be able to choose several options that will
-+ make breaking out of a chrooted jail much more difficult. If you
-+ encounter no software incompatibilities with the following options, it
-+ is recommended that you enable each one.
-+
-+config GRKERNSEC_CHROOT_MOUNT
-+ bool "Deny mounts"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, processes inside a chroot will not be able to
-+ mount or remount filesystems. If the sysctl option is enabled, a
-+ sysctl option with name "chroot_deny_mount" is created.
-+
-+config GRKERNSEC_CHROOT_DOUBLE
-+ bool "Deny double-chroots"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, processes inside a chroot will not be able to chroot
-+ again outside the chroot. This is a widely used method of breaking
-+ out of a chroot jail and should not be allowed. If the sysctl
-+ option is enabled, a sysctl option with name
-+ "chroot_deny_chroot" is created.
-+
-+config GRKERNSEC_CHROOT_PIVOT
-+ bool "Deny pivot_root in chroot"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, processes inside a chroot will not be able to use
-+ a function called pivot_root() that was introduced in Linux 2.3.41. It
-+ works similar to chroot in that it changes the root filesystem. This
-+ function could be misused in a chrooted process to attempt to break out
-+ of the chroot, and therefore should not be allowed. If the sysctl
-+ option is enabled, a sysctl option with name "chroot_deny_pivot" is
-+ created.
-+
-+config GRKERNSEC_CHROOT_CHDIR
-+ bool "Enforce chdir(\"/\") on all chroots"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, the current working directory of all newly-chrooted
-+ applications will be set to the the root directory of the chroot.
-+ The man page on chroot(2) states:
-+ Note that this call does not change the current working
-+ directory, so that `.' can be outside the tree rooted at
-+ `/'. In particular, the super-user can escape from a
-+ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
-+
-+ It is recommended that you say Y here, since it's not known to break
-+ any software. If the sysctl option is enabled, a sysctl option with
-+ name "chroot_enforce_chdir" is created.
-+
-+config GRKERNSEC_CHROOT_CHMOD
-+ bool "Deny (f)chmod +s"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, processes inside a chroot will not be able to chmod
-+ or fchmod files to make them have suid or sgid bits. This protects
-+ against another published method of breaking a chroot. If the sysctl
-+ option is enabled, a sysctl option with name "chroot_deny_chmod" is
-+ created.
-+
-+config GRKERNSEC_CHROOT_FCHDIR
-+ bool "Deny fchdir out of chroot"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
-+ to a file descriptor of the chrooting process that points to a directory
-+ outside the filesystem will be stopped. If the sysctl option
-+ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
-+
-+config GRKERNSEC_CHROOT_MKNOD
-+ bool "Deny mknod"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, processes inside a chroot will not be allowed to
-+ mknod. The problem with using mknod inside a chroot is that it
-+ would allow an attacker to create a device entry that is the same
-+ as one on the physical root of your system, which could range from
-+ anything from the console device to a device for your harddrive (which
-+ they could then use to wipe the drive or steal data). It is recommended
-+ that you say Y here, unless you run into software incompatibilities.
-+ If the sysctl option is enabled, a sysctl option with name
-+ "chroot_deny_mknod" is created.
-+
-+config GRKERNSEC_CHROOT_SHMAT
-+ bool "Deny shmat() out of chroot"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, processes inside a chroot will not be able to attach
-+ to shared memory segments that were created outside of the chroot jail.
-+ It is recommended that you say Y here. If the sysctl option is enabled,
-+ a sysctl option with name "chroot_deny_shmat" is created.
-+
-+config GRKERNSEC_CHROOT_UNIX
-+ bool "Deny access to abstract AF_UNIX sockets out of chroot"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, processes inside a chroot will not be able to
-+ connect to abstract (meaning not belonging to a filesystem) Unix
-+ domain sockets that were bound outside of a chroot. It is recommended
-+ that you say Y here. If the sysctl option is enabled, a sysctl option
-+ with name "chroot_deny_unix" is created.
-+
-+config GRKERNSEC_CHROOT_FINDTASK
-+ bool "Protect outside processes"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, processes inside a chroot will not be able to
-+ kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
-+ getsid, or view any process outside of the chroot. If the sysctl
-+ option is enabled, a sysctl option with name "chroot_findtask" is
-+ created.
-+
-+config GRKERNSEC_CHROOT_NICE
-+ bool "Restrict priority changes"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, processes inside a chroot will not be able to raise
-+ the priority of processes in the chroot, or alter the priority of
-+ processes outside the chroot. This provides more security than simply
-+ removing CAP_SYS_NICE from the process' capability set. If the
-+ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
-+ is created.
-+
-+config GRKERNSEC_CHROOT_SYSCTL
-+ bool "Deny sysctl writes"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, an attacker in a chroot will not be able to
-+ write to sysctl entries, either by sysctl(2) or through a /proc
-+ interface. It is strongly recommended that you say Y here. If the
-+ sysctl option is enabled, a sysctl option with name
-+ "chroot_deny_sysctl" is created.
-+
-+config GRKERNSEC_CHROOT_CAPS
-+ bool "Capability restrictions"
-+ depends on GRKERNSEC_CHROOT
-+ help
-+ If you say Y here, the capabilities on all root processes within a
-+ chroot jail will be lowered to stop module insertion, raw i/o,
-+ system and net admin tasks, rebooting the system, modifying immutable
-+ files, modifying IPC owned by another, and changing the system time.
-+ This is left an option because it can break some apps. Disable this
-+ if your chrooted apps are having problems performing those kinds of
-+ tasks. If the sysctl option is enabled, a sysctl option with
-+ name "chroot_caps" is created.
-+
-+endmenu
-+menu "Kernel Auditing"
-+depends on GRKERNSEC
-+
-+config GRKERNSEC_AUDIT_GROUP
-+ bool "Single group for auditing"
-+ help
-+ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
-+ will only operate on a group you specify. This option is recommended
-+ if you only want to watch certain users instead of having a large
-+ amount of logs from the entire system. If the sysctl option is enabled,
-+ a sysctl option with name "audit_group" is created.
-+
-+config GRKERNSEC_AUDIT_GID
-+ int "GID for auditing"
-+ depends on GRKERNSEC_AUDIT_GROUP
-+ default 1007
-+
-+config GRKERNSEC_EXECLOG
-+ bool "Exec logging"
-+ help
-+ If you say Y here, all execve() calls will be logged (since the
-+ other exec*() calls are frontends to execve(), all execution
-+ will be logged). Useful for shell-servers that like to keep track
-+ of their users. If the sysctl option is enabled, a sysctl option with
-+ name "exec_logging" is created.
-+ WARNING: This option when enabled will produce a LOT of logs, especially
-+ on an active system.
-+
-+config GRKERNSEC_RESLOG
-+ bool "Resource logging"
-+ help
-+ If you say Y here, all attempts to overstep resource limits will
-+ be logged with the resource name, the requested size, and the current
-+ limit. It is highly recommended that you say Y here.
-+
-+config GRKERNSEC_CHROOT_EXECLOG
-+ bool "Log execs within chroot"
-+ help
-+ If you say Y here, all executions inside a chroot jail will be logged
-+ to syslog. This can cause a large amount of logs if certain
-+ applications (eg. djb's daemontools) are installed on the system, and
-+ is therefore left as an option. If the sysctl option is enabled, a
-+ sysctl option with name "chroot_execlog" is created.
-+
-+config GRKERNSEC_AUDIT_CHDIR
-+ bool "Chdir logging"
-+ help
-+ If you say Y here, all chdir() calls will be logged. If the sysctl
-+ option is enabled, a sysctl option with name "audit_chdir" is created.
-+
-+config GRKERNSEC_AUDIT_MOUNT
-+ bool "(Un)Mount logging"
-+ help
-+ If you say Y here, all mounts and unmounts will be logged. If the
-+ sysctl option is enabled, a sysctl option with name "audit_mount" is
-+ created.
-+
-+config GRKERNSEC_AUDIT_IPC
-+ bool "IPC logging"
-+ help
-+ If you say Y here, creation and removal of message queues, semaphores,
-+ and shared memory will be logged. If the sysctl option is enabled, a
-+ sysctl option with name "audit_ipc" is created.
-+
-+config GRKERNSEC_SIGNAL
-+ bool "Signal logging"
-+ help
-+ If you say Y here, certain important signals will be logged, such as
-+ SIGSEGV, which will as a result inform you of when a error in a program
-+ occurred, which in some cases could mean a possible exploit attempt.
-+ If the sysctl option is enabled, a sysctl option with name
-+ "signal_logging" is created.
-+
-+config GRKERNSEC_FORKFAIL
-+ bool "Fork failure logging"
-+ help
-+ If you say Y here, all failed fork() attempts will be logged.
-+ This could suggest a fork bomb, or someone attempting to overstep
-+ their process limit. If the sysctl option is enabled, a sysctl option
-+ with name "forkfail_logging" is created.
-+
-+config GRKERNSEC_TIME
-+ bool "Time change logging"
-+ help
-+ If you say Y here, any changes of the system clock will be logged.
-+ If the sysctl option is enabled, a sysctl option with name
-+ "timechange_logging" is created.
-+
-+config GRKERNSEC_PROC_IPADDR
-+ bool "/proc/<pid>/ipaddr support"
-+ help
-+ If you say Y here, a new entry will be added to each /proc/<pid>
-+ directory that contains the IP address of the person using the task.
-+ The IP is carried across local TCP and AF_UNIX stream sockets.
-+ This information can be useful for IDS/IPSes to perform remote response
-+ to a local attack. The entry is readable by only the owner of the
-+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
-+ the RBAC system), and thus does not create privacy concerns.
-+
-+config GRKERNSEC_AUDIT_TEXTREL
-+ bool 'ELF text relocations logging (READ HELP)'
-+ depends on PAX_MPROTECT
-+ help
-+ If you say Y here, text relocations will be logged with the filename
-+ of the offending library or binary. The purpose of the feature is
-+ to help Linux distribution developers get rid of libraries and
-+ binaries that need text relocations which hinder the future progress
-+ of PaX. Only Linux distribution developers should say Y here, and
-+ never on a production machine, as this option creates an information
-+ leak that could aid an attacker in defeating the randomization of
-+ a single memory region. If the sysctl option is enabled, a sysctl
-+ option with name "audit_textrel" is created.
-+
-+endmenu
-+
-+menu "Executable Protections"
-+depends on GRKERNSEC
-+
-+config GRKERNSEC_EXECVE
-+ bool "Enforce RLIMIT_NPROC on execs"
-+ help
-+ If you say Y here, users with a resource limit on processes will
-+ have the value checked during execve() calls. The current system
-+ only checks the system limit during fork() calls. If the sysctl option
-+ is enabled, a sysctl option with name "execve_limiting" is created.
-+
-+config GRKERNSEC_DMESG
-+ bool "Dmesg(8) restriction"
-+ help
-+ If you say Y here, non-root users will not be able to use dmesg(8)
-+ to view up to the last 4kb of messages in the kernel's log buffer.
-+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
-+ created.
-+
-+config GRKERNSEC_RANDPID
-+ bool "Randomized PIDs"
-+ help
-+ If you say Y here, all PIDs created on the system will be
-+ pseudo-randomly generated. This is extremely effective along
-+ with the /proc restrictions to disallow an attacker from guessing
-+ pids of daemons, etc. PIDs are also used in some cases as part
-+ of a naming system for temporary files, so this option would keep
-+ those filenames from being predicted as well. We also use code
-+ to make sure that PID numbers aren't reused too soon. If the sysctl
-+ option is enabled, a sysctl option with name "rand_pids" is created.
-+
-+config GRKERNSEC_TPE
-+ bool "Trusted Path Execution (TPE)"
-+ help
-+ If you say Y here, you will be able to choose a gid to add to the
-+ supplementary groups of users you want to mark as "untrusted."
-+ These users will not be able to execute any files that are not in
-+ root-owned directories writable only by root. If the sysctl option
-+ is enabled, a sysctl option with name "tpe" is created.
-+
-+config GRKERNSEC_TPE_ALL
-+ bool "Partially restrict non-root users"
-+ depends on GRKERNSEC_TPE
-+ help
-+ If you say Y here, All non-root users other than the ones in the
-+ group specified in the main TPE option will only be allowed to
-+ execute files in directories they own that are not group or
-+ world-writable, or in directories owned by root and writable only by
-+ root. If the sysctl option is enabled, a sysctl option with name
-+ "tpe_restrict_all" is created.
-+
-+config GRKERNSEC_TPE_GID
-+ int "GID for untrusted users"
-+ depends on GRKERNSEC_TPE
-+ default 1005
-+ help
-+ Here you can choose the GID to enable trusted path protection for.
-+ Remember to add the users you want protection enabled for to the GID
-+ specified here. If the sysctl option is enabled, whatever you choose
-+ here won't matter. You'll have to specify the GID in your bootup
-+ script by echoing the GID to the proper /proc entry. View the help
-+ on the sysctl option for more information. If the sysctl option is
-+ enabled, a sysctl option with name "tpe_gid" is created.
-+
-+endmenu
-+menu "Network Protections"
-+depends on GRKERNSEC
-+
-+config GRKERNSEC_RANDNET
-+ bool "Larger entropy pools"
-+ help
-+ If you say Y here, the entropy pools used for many features of Linux
-+ and grsecurity will be doubled in size. Since several grsecurity
-+ features use additional randomness, it is recommended that you say Y
-+ here. Saying Y here has a similar effect as modifying
-+ /proc/sys/kernel/random/poolsize.
-+
-+config GRKERNSEC_RANDISN
-+ bool "Truly random TCP ISN selection"
-+ help
-+ If you say Y here, Linux's default selection of TCP Initial Sequence
-+ Numbers (ISNs) will be replaced with that of OpenBSD. Linux uses
-+ an MD4 hash based on the connection plus a time value to create the
-+ ISN, while OpenBSD's selection is random. If the sysctl option is
-+ enabled, a sysctl option with name "rand_isns" is created.
-+
-+config GRKERNSEC_RANDID
-+ bool "Randomized IP IDs"
-+ help
-+ If you say Y here, all the id field on all outgoing packets
-+ will be randomized. This hinders os fingerprinters and
-+ keeps your machine from being used as a bounce for an untraceable
-+ portscan. Ids are used for fragmented packets, fragments belonging
-+ to the same packet have the same id. By default linux only
-+ increments the id value on each packet sent to an individual host.
-+ We use a port of the OpenBSD random ip id code to achieve the
-+ randomness, while keeping the possibility of id duplicates to
-+ near none. If the sysctl option is enabled, a sysctl option with name
-+ "rand_ip_ids" is created.
-+
-+config GRKERNSEC_RANDSRC
-+ bool "Randomized TCP source ports"
-+ default n if GRKERNSEC_LOW || GRKERNSEC_MID
-+ default y if GRKERNSEC_HIGH
-+ help
-+ If you say Y here, situations where a source port is generated on the
-+ fly for the TCP protocol (ie. with connect() ) will be altered so that
-+ the source port is generated at random, instead of a simple incrementing
-+ algorithm. If the sysctl option is enabled, a sysctl option with name
-+ "rand_tcp_src_ports" is created.
-+
-+config GRKERNSEC_RANDRPC
-+ bool "Randomized RPC XIDs"
-+ help
-+ If you say Y here, the method of determining XIDs for RPC requests will
-+ be randomized, instead of using linux's default behavior of simply
-+ incrementing the XID. If you want your RPC connections to be more
-+ secure, say Y here. If the sysctl option is enabled, a sysctl option
-+ with name "rand_rpc" is created.
-+
-+config GRKERNSEC_SOCKET
-+ bool "Socket restrictions"
-+ help
-+ If you say Y here, you will be able to choose from several options.
-+ If you assign a GID on your system and add it to the supplementary
-+ groups of users you want to restrict socket access to, this patch
-+ will perform up to three things, based on the option(s) you choose.
-+
-+config GRKERNSEC_SOCKET_ALL
-+ bool "Deny any sockets to group"
-+ depends on GRKERNSEC_SOCKET
-+ help
-+ If you say Y here, you will be able to choose a GID of whose users will
-+ be unable to connect to other hosts from your machine or run server
-+ applications from your machine. If the sysctl option is enabled, a
-+ sysctl option with name "socket_all" is created.
-+
-+config GRKERNSEC_SOCKET_ALL_GID
-+ int "GID to deny all sockets for"
-+ depends on GRKERNSEC_SOCKET_ALL
-+ default 1004
-+ help
-+ Here you can choose the GID to disable socket access for. Remember to
-+ add the users you want socket access disabled for to the GID
-+ specified here. If the sysctl option is enabled, whatever you choose
-+ here won't matter. You'll have to specify the GID in your bootup
-+ script by echoing the GID to the proper /proc entry. View the help
-+ on the sysctl option for more information. If the sysctl option is
-+ enabled, a sysctl option with name "socket_all_gid" is created.
-+
-+config GRKERNSEC_SOCKET_CLIENT
-+ bool "Deny client sockets to group"
-+ depends on GRKERNSEC_SOCKET
-+ help
-+ If you say Y here, you will be able to choose a GID of whose users will
-+ be unable to connect to other hosts from your machine, but will be
-+ able to run servers. If this option is enabled, all users in the group
-+ you specify will have to use passive mode when initiating ftp transfers
-+ from the shell on your machine. If the sysctl option is enabled, a
-+ sysctl option with name "socket_client" is created.
-+
-+config GRKERNSEC_SOCKET_CLIENT_GID
-+ int "GID to deny client sockets for"
-+ depends on GRKERNSEC_SOCKET_CLIENT
-+ default 1003
-+ help
-+ Here you can choose the GID to disable client socket access for.
-+ Remember to add the users you want client socket access disabled for to
-+ the GID specified here. If the sysctl option is enabled, whatever you
-+ choose here won't matter. You'll have to specify the GID in your bootup
-+ script by echoing the GID to the proper /proc entry. View the help
-+ on the sysctl option for more information. If the sysctl option is
-+ enabled, a sysctl option with name "socket_client_gid" is created.
-+
-+config GRKERNSEC_SOCKET_SERVER
-+ bool "Deny server sockets to group"
-+ depends on GRKERNSEC_SOCKET
-+ help
-+ If you say Y here, you will be able to choose a GID of whose users will
-+ be unable to run server applications from your machine. If the sysctl
-+ option is enabled, a sysctl option with name "socket_server" is created.
-+
-+config GRKERNSEC_SOCKET_SERVER_GID
-+ int "GID to deny server sockets for"
-+ depends on GRKERNSEC_SOCKET_SERVER
-+ default 1002
-+ help
-+ Here you can choose the GID to disable server socket access for.
-+ Remember to add the users you want server socket access disabled for to
-+ the GID specified here. If the sysctl option is enabled, whatever you
-+ choose here won't matter. You'll have to specify the GID in your bootup
-+ script by echoing the GID to the proper /proc entry. View the help
-+ on the sysctl option for more information. If the sysctl option is
-+ enabled, a sysctl option with name "socket_server_gid" is created.
-+
-+endmenu
-+menu "Sysctl support"
-+depends on GRKERNSEC && SYSCTL
-+
-+config GRKERNSEC_SYSCTL
-+ bool "Sysctl support"
-+ help
-+ If you say Y here, you will be able to change the options that
-+ grsecurity runs with at bootup, without having to recompile your
-+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
-+ to enable (1) or disable (0) various features. All the sysctl entries
-+ are mutable until the "grsec_lock" entry is set to a non-zero value.
-+ All features are disabled by default. Please note that this option could
-+ reduce the effectiveness of the added security of this patch if an ACL
-+ system is not put in place. Your init scripts should be read-only, and
-+ root should not have access to adding modules or performing raw i/o
-+ operations. All options should be set at startup, and the grsec_lock
-+ entry should be set to a non-zero value after all the options are set.
-+ *THIS IS EXTREMELY IMPORTANT*
-+
-+endmenu
-+menu "Logging Options"
-+depends on GRKERNSEC
-+
-+config GRKERNSEC_FLOODTIME
-+ int "Seconds in between log messages (minimum)"
-+ default 10
-+ help
-+ This option allows you to enforce the number of seconds between
-+ grsecurity log messages. The default should be suitable for most
-+ people, however, if you choose to change it, choose a value small enough
-+ to allow informative logs to be produced, but large enough to
-+ prevent flooding.
-+
-+config GRKERNSEC_FLOODBURST
-+ int "Number of messages in a burst (maximum)"
-+ default 4
-+ help
-+ This option allows you to choose the maximum number of messages allowed
-+ within the flood time interval you chose in a separate option. The
-+ default should be suitable for most people, however if you find that
-+ many of your logs are being interpreted as flooding, you may want to
-+ raise this value.
-+
-+endmenu
-+
-+endmenu
-diff -urN linux-2.6.5/grsecurity/Makefile linux-2.6.5/grsecurity/Makefile
---- linux-2.6.5/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/Makefile 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,21 @@
-+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
-+# during 2001, 2002, and 2003 it has been completely redesigned by
-+# Brad Spengler
-+#
-+# All code in this directory and various hooks inserted throughout the kernel
-+# are copyright Brad Spengler, and released under the GPL, unless otherwise
-+# noted (as in obsd_rand.c)
-+
-+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
-+ grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
-+ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
-+
-+obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
-+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
-+ gracl_learn.o
-+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
-+
-+ifndef CONFIG_GRKERNSEC
-+obj-y += grsec_disabled.o
-+endif
-+
-diff -urN linux-2.6.5/grsecurity/gracl.c linux-2.6.5/grsecurity/gracl.c
---- linux-2.6.5/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/gracl.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,3340 @@
-+/*
-+ * grsecurity/gracl.c
-+ * Copyright Brad Spengler 2001, 2002, 2003
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
-+#include <linux/namei.h>
-+#include <linux/mount.h>
-+#include <linux/tty.h>
-+#include <linux/proc_fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/types.h>
-+#include <linux/capability.h>
-+#include <linux/sysctl.h>
-+#include <linux/ptrace.h>
-+#include <linux/gracl.h>
-+#include <linux/gralloc.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+#include <linux/percpu.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/errno.h>
-+#include <asm/mman.h>
-+
-+static struct acl_role_db acl_role_set;
-+static struct acl_role_label *role_list_head;
-+static struct name_db name_set;
-+static struct name_db inodev_set;
-+
-+/* for keeping track of userspace pointers used for subjects, so we
-+ can share references in the kernel as well
-+*/
-+static struct acl_subj_map_db subj_map_set;
-+
-+static struct acl_role_label *default_role;
-+
-+static u16 acl_sp_role_value;
-+
-+extern char *gr_shared_page[4];
-+static DECLARE_MUTEX(gr_dev_sem);
-+rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
-+
-+struct gr_arg *gr_usermode;
-+
-+static unsigned long gr_status = GR_STATUS_INIT;
-+
-+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
-+extern void gr_clear_learn_entries(void);
-+
-+#ifdef CONFIG_GRKERNSEC_RESLOG
-+extern void gr_log_resource(const struct task_struct *task,
-+ const int res, const unsigned long wanted, const int gt);
-+#endif
-+
-+extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
-+ struct dentry *root, struct vfsmount *rootmnt,
-+ char *buffer, int buflen);
-+
-+unsigned char *gr_system_salt;
-+unsigned char *gr_system_sum;
-+
-+static struct sprole_pw **acl_special_roles = NULL;
-+static __u16 num_sprole_pws = 0;
-+
-+static struct acl_role_label *kernel_role = NULL;
-+
-+/* The following are used to keep a place held in the hash table when we move
-+ entries around. They can be replaced during insert. */
-+
-+static struct acl_subject_label *deleted_subject;
-+static struct acl_object_label *deleted_object;
-+static struct name_entry *deleted_inodev;
-+
-+/* for keeping track of the last and final allocated subjects, since
-+ nested subject parsing is tricky
-+*/
-+static struct acl_subject_label *s_last = NULL;
-+static struct acl_subject_label *s_final = NULL;
-+
-+static unsigned int gr_auth_attempts = 0;
-+static unsigned long gr_auth_expires = 0UL;
-+
-+extern int gr_init_uidset(void);
-+extern void gr_free_uidset(void);
-+extern void gr_remove_uid(uid_t uid);
-+extern int gr_find_uid(uid_t uid);
-+
-+__inline__ int
-+gr_acl_is_enabled(void)
-+{
-+ return (gr_status & GR_READY);
-+}
-+
-+__inline__ int
-+gr_acl_tpe_check(void)
-+{
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return 0;
-+ if (current->role->roletype & GR_ROLE_TPE)
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+int
-+gr_handle_rawio(const struct inode *inode)
-+{
-+ if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
-+ ((gr_status & GR_READY)
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
-+ || (grsec_enable_chroot_caps && proc_is_chrooted(current))
-+#endif
-+ ))
-+ return 1;
-+ return 0;
-+}
-+
-+
-+static __inline__ int
-+gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
-+{
-+ int i;
-+ unsigned long *l1;
-+ unsigned long *l2;
-+ unsigned char *c1;
-+ unsigned char *c2;
-+ int num_longs;
-+
-+ if (likely(lena != lenb))
-+ return 0;
-+
-+ l1 = (unsigned long *)a;
-+ l2 = (unsigned long *)b;
-+
-+ num_longs = lena / sizeof(unsigned long);
-+
-+ for (i = num_longs; i--; l1++, l2++) {
-+ if (unlikely(*l1 != *l2))
-+ return 0;
-+ }
-+
-+ c1 = (unsigned char *) l1;
-+ c2 = (unsigned char *) l2;
-+
-+ i = lena - (num_longs * sizeof(unsigned long));
-+
-+ for (; i--; c1++, c2++) {
-+ if (unlikely(*c1 != *c2))
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static __inline__ char *
-+__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
-+ char *buf, int buflen)
-+{
-+ char *res;
-+ struct dentry *our_dentry;
-+ struct vfsmount *our_mount;
-+ struct vfsmount *rootmnt;
-+ struct dentry *root;
-+
-+ our_dentry = (struct dentry *) dentry;
-+ our_mount = (struct vfsmount *) vfsmnt;
-+
-+ read_lock(&child_reaper->fs->lock);
-+ rootmnt = mntget(child_reaper->fs->rootmnt);
-+ root = dget(child_reaper->fs->root);
-+ read_unlock(&child_reaper->fs->lock);
-+
-+ res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
-+ if (unlikely(IS_ERR(res)))
-+ res = strcpy(buf, "<path too long>");
-+ dput(root);
-+ mntput(rootmnt);
-+ return res;
-+}
-+
-+char *
-+gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
-+ PAGE_SIZE);
-+}
-+
-+static __inline__ char *
-+d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
-+ char *buf, int buflen)
-+{
-+ char *res;
-+ struct dentry *our_dentry;
-+ struct vfsmount *our_mount;
-+ struct vfsmount *rootmnt;
-+ struct dentry *root;
-+
-+ our_dentry = (struct dentry *) dentry;
-+ our_mount = (struct vfsmount *) vfsmnt;
-+
-+ read_lock(&child_reaper->fs->lock);
-+ rootmnt = mntget(child_reaper->fs->rootmnt);
-+ root = dget(child_reaper->fs->root);
-+ read_unlock(&child_reaper->fs->lock);
-+
-+ spin_lock(&dcache_lock);
-+ res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
-+ spin_unlock(&dcache_lock);
-+ if (unlikely(IS_ERR(res)))
-+ res = strcpy(buf, "<path too long>");
-+ dput(root);
-+ mntput(rootmnt);
-+ return res;
-+}
-+
-+char *
-+gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
-+ PAGE_SIZE);
-+}
-+
-+char *
-+gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
-+ PAGE_SIZE);
-+}
-+
-+char *
-+gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
-+ PAGE_SIZE);
-+}
-+
-+char *
-+gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
-+ PAGE_SIZE);
-+}
-+
-+__inline__ __u32
-+to_gr_audit(const __u32 reqmode)
-+{
-+ __u32 retmode = 0;
-+
-+ retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
-+ retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
-+ retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
-+ retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
-+ retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
-+ retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
-+ retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
-+ retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
-+ retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
-+
-+ return retmode;
-+}
-+
-+__inline__ struct acl_subject_label *
-+lookup_subject_map(const struct acl_subject_label *userp)
-+{
-+ unsigned long index = shash(userp, subj_map_set.s_size);
-+ struct subject_map *match;
-+ __u8 i = 0;
-+
-+ match = subj_map_set.s_hash[index];
-+
-+ while (match && match->user != userp) {
-+ index = (index + (1 << i)) % subj_map_set.s_size;
-+ match = subj_map_set.s_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (match)
-+ return match->kernel;
-+ else
-+ return NULL;
-+}
-+
-+static void
-+insert_subj_map_entry(struct subject_map *subjmap)
-+{
-+ unsigned long index = shash(subjmap->user, subj_map_set.s_size);
-+ struct subject_map **curr;
-+ __u8 i = 0;
-+
-+ curr = &subj_map_set.s_hash[index];
-+
-+ while (*curr) {
-+ index = (index + (1 << i)) % subj_map_set.s_size;
-+ curr = &subj_map_set.s_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ *curr = subjmap;
-+
-+ return;
-+}
-+
-+__inline__ struct acl_role_label *
-+lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
-+ const gid_t gid)
-+{
-+ unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
-+ struct acl_role_label *match;
-+ struct role_allowed_ip *ipp;
-+ __u8 i = 0;
-+
-+ match = acl_role_set.r_hash[index];
-+
-+ while (match
-+ && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) {
-+ index = (index + (1 << i)) % acl_role_set.r_size;
-+ match = acl_role_set.r_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (match == NULL) {
-+ try_group:
-+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
-+ match = acl_role_set.r_hash[index];
-+ i = 0;
-+
-+ while (match && (match->uidgid != gid
-+ || !(match->roletype & GR_ROLE_GROUP))) {
-+ index = (index + (1 << i)) % acl_role_set.r_size;
-+ match = acl_role_set.r_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (match == NULL)
-+ match = default_role;
-+ if (match->allowed_ips == NULL)
-+ return match;
-+ else {
-+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
-+ if (likely
-+ ((task->curr_ip & ipp->netmask) ==
-+ (ipp->addr & ipp->netmask)))
-+ return match;
-+ }
-+ match = default_role;
-+ }
-+ } else if (match->allowed_ips == NULL) {
-+ return match;
-+ } else {
-+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
-+ if (likely
-+ ((task->curr_ip & ipp->netmask) ==
-+ (ipp->addr & ipp->netmask)))
-+ return match;
-+ }
-+ goto try_group;
-+ }
-+
-+ return match;
-+}
-+
-+__inline__ struct acl_subject_label *
-+lookup_acl_subj_label(const ino_t ino, const dev_t dev,
-+ const struct acl_role_label *role)
-+{
-+ unsigned long subj_size = role->subj_hash_size;
-+ struct acl_subject_label **s_hash = role->subj_hash;
-+ unsigned long index = fhash(ino, dev, subj_size);
-+ struct acl_subject_label *match;
-+ __u8 i = 0;
-+
-+ match = s_hash[index];
-+
-+ while (match && (match->inode != ino || match->device != dev ||
-+ (match->mode & GR_DELETED))) {
-+ index = (index + (1 << i)) % subj_size;
-+ match = s_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (match && (match != deleted_subject) && !(match->mode & GR_DELETED))
-+ return match;
-+ else
-+ return NULL;
-+}
-+
-+static __inline__ struct acl_object_label *
-+lookup_acl_obj_label(const ino_t ino, const dev_t dev,
-+ const struct acl_subject_label *subj)
-+{
-+ unsigned long obj_size = subj->obj_hash_size;
-+ struct acl_object_label **o_hash = subj->obj_hash;
-+ unsigned long index = fhash(ino, dev, obj_size);
-+ struct acl_object_label *match;
-+ __u8 i = 0;
-+
-+ match = o_hash[index];
-+
-+ while (match && (match->inode != ino || match->device != dev ||
-+ (match->mode & GR_DELETED))) {
-+ index = (index + (1 << i)) % obj_size;
-+ match = o_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
-+ return match;
-+ else
-+ return NULL;
-+}
-+
-+static __inline__ struct acl_object_label *
-+lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
-+ const struct acl_subject_label *subj)
-+{
-+ unsigned long obj_size = subj->obj_hash_size;
-+ struct acl_object_label **o_hash = subj->obj_hash;
-+ unsigned long index = fhash(ino, dev, obj_size);
-+ struct acl_object_label *match;
-+ __u8 i = 0;
-+
-+ match = o_hash[index];
-+
-+ while (match && (match->inode != ino || match->device != dev ||
-+ !(match->mode & GR_DELETED))) {
-+ index = (index + (1 << i)) % obj_size;
-+ match = o_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (match && (match != deleted_object) && (match->mode & GR_DELETED))
-+ return match;
-+
-+ i = 0;
-+ index = fhash(ino, dev, obj_size);
-+ match = o_hash[index];
-+
-+ while (match && (match->inode != ino || match->device != dev ||
-+ (match->mode & GR_DELETED))) {
-+ index = (index + (1 << i)) % obj_size;
-+ match = o_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
-+ return match;
-+ else
-+ return NULL;
-+}
-+
-+static __inline__ struct name_entry *
-+lookup_name_entry(const char *name)
-+{
-+ __u16 len = strlen(name);
-+ unsigned long index = nhash(name, len, name_set.n_size);
-+ struct name_entry *match;
-+ __u8 i = 0;
-+
-+ match = name_set.n_hash[index];
-+
-+ while (match && !gr_streq(match->name, name, match->len, len)) {
-+ index = (index + (1 << i)) % name_set.n_size;
-+ match = name_set.n_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ return match;
-+}
-+
-+static __inline__ struct name_entry *
-+lookup_inodev_entry(const ino_t ino, const dev_t dev)
-+{
-+ unsigned long index = fhash(ino, dev, inodev_set.n_size);
-+ struct name_entry *match;
-+ __u8 i = 0;
-+
-+ match = inodev_set.n_hash[index];
-+
-+ while (match && (match->inode != ino || match->device != dev)) {
-+ index = (index + (1 << i)) % inodev_set.n_size;
-+ match = inodev_set.n_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (match && (match != deleted_inodev))
-+ return match;
-+ else
-+ return NULL;
-+}
-+
-+static void
-+insert_inodev_entry(struct name_entry *nentry)
-+{
-+ unsigned long index = fhash(nentry->inode, nentry->device,
-+ inodev_set.n_size);
-+ struct name_entry **curr;
-+ __u8 i = 0;
-+
-+ curr = &inodev_set.n_hash[index];
-+
-+ while (*curr && *curr != deleted_inodev) {
-+ index = (index + (1 << i)) % inodev_set.n_size;
-+ curr = &inodev_set.n_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ *curr = nentry;
-+
-+ return;
-+}
-+
-+static void
-+insert_acl_role_label(struct acl_role_label *role)
-+{
-+ unsigned long index =
-+ rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
-+ struct acl_role_label **curr;
-+ __u8 i = 0;
-+
-+ curr = &acl_role_set.r_hash[index];
-+
-+ while (*curr) {
-+ index = (index + (1 << i)) % acl_role_set.r_size;
-+ curr = &acl_role_set.r_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ *curr = role;
-+
-+ return;
-+}
-+
-+static int
-+insert_name_entry(char *name, const ino_t inode, const dev_t device)
-+{
-+ struct name_entry **curr;
-+ __u8 i = 0;
-+ __u16 len = strlen(name);
-+ unsigned long index = nhash(name, len, name_set.n_size);
-+
-+ curr = &name_set.n_hash[index];
-+
-+ while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
-+ index = (index + (1 << i)) % name_set.n_size;
-+ curr = &name_set.n_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (!(*curr)) {
-+ struct name_entry *nentry =
-+ acl_alloc(sizeof (struct name_entry));
-+ if (!nentry)
-+ return 0;
-+ nentry->name = name;
-+ nentry->inode = inode;
-+ nentry->device = device;
-+ nentry->len = len;
-+ *curr = nentry;
-+ /* insert us into the table searchable by inode/dev */
-+ insert_inodev_entry(nentry);
-+ }
-+
-+ return 1;
-+}
-+
-+static void
-+insert_acl_obj_label(struct acl_object_label *obj,
-+ struct acl_subject_label *subj)
-+{
-+ unsigned long index =
-+ fhash(obj->inode, obj->device, subj->obj_hash_size);
-+ struct acl_object_label **curr;
-+ __u8 i = 0;
-+
-+ curr = &subj->obj_hash[index];
-+
-+ while (*curr && *curr != deleted_object) {
-+ index = (index + (1 << i)) % subj->obj_hash_size;
-+ curr = &subj->obj_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ *curr = obj;
-+
-+ return;
-+}
-+
-+static void
-+insert_acl_subj_label(struct acl_subject_label *obj,
-+ struct acl_role_label *role)
-+{
-+ unsigned long subj_size = role->subj_hash_size;
-+ struct acl_subject_label **s_hash = role->subj_hash;
-+ unsigned long index = fhash(obj->inode, obj->device, subj_size);
-+ struct acl_subject_label **curr;
-+ __u8 i = 0;
-+
-+ curr = &s_hash[index];
-+
-+ while (*curr && *curr != deleted_subject) {
-+ index = (index + (1 << i)) % subj_size;
-+ curr = &s_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ *curr = obj;
-+
-+ return;
-+}
-+
-+static void **
-+create_table(__u32 * len)
-+{
-+ unsigned long table_sizes[] = {
-+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
-+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
-+ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
-+ 268435399, 536870909, 1073741789, 2147483647
-+ };
-+ void *newtable = NULL;
-+ unsigned int pwr = 0;
-+
-+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
-+ table_sizes[pwr] <= (2 * (*len)))
-+ pwr++;
-+
-+ if (table_sizes[pwr] <= (2 * (*len)))
-+ return newtable;
-+
-+ if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
-+ newtable =
-+ kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
-+ else
-+ newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
-+
-+ *len = table_sizes[pwr];
-+
-+ return newtable;
-+}
-+
-+static int
-+init_variables(const unsigned long acl_obj_size,
-+ const unsigned long acl_glob_size,
-+ const unsigned long acl_subj_size,
-+ const unsigned long acl_ip_size,
-+ const unsigned long acl_role_size,
-+ const unsigned long allowed_ip_size,
-+ const unsigned long acl_trans_size,
-+ const __u16 num_sprole_pws)
-+{
-+ unsigned long stacksize;
-+
-+ subj_map_set.s_size = acl_subj_size;
-+ acl_role_set.r_size = acl_role_size;
-+ name_set.n_size = (acl_obj_size + acl_subj_size);
-+ inodev_set.n_size = (acl_obj_size + acl_subj_size);
-+
-+ if (!gr_init_uidset())
-+ return 1;
-+
-+ /* set up the stack that holds allocation info */
-+
-+ stacksize = (3 * acl_obj_size) + (3 * acl_role_size) +
-+ (6 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) +
-+ allowed_ip_size + (2 * num_sprole_pws) + (2 * acl_glob_size) + 5;
-+
-+ if (!acl_alloc_stack_init(stacksize))
-+ return 1;
-+
-+ /* create our empty, fake deleted acls */
-+ deleted_subject =
-+ (struct acl_subject_label *)
-+ acl_alloc(sizeof (struct acl_subject_label));
-+ deleted_object =
-+ (struct acl_object_label *)
-+ acl_alloc(sizeof (struct acl_object_label));
-+ deleted_inodev =
-+ (struct name_entry *) acl_alloc(sizeof (struct name_entry));
-+
-+ if (!deleted_subject || !deleted_object || !deleted_inodev)
-+ return 1;
-+
-+ memset(deleted_subject, 0, sizeof (struct acl_subject_label));
-+ memset(deleted_object, 0, sizeof (struct acl_object_label));
-+ memset(deleted_inodev, 0, sizeof (struct name_entry));
-+
-+ /* We only want 50% full tables for now */
-+
-+ subj_map_set.s_hash =
-+ (struct subject_map **) create_table(&subj_map_set.s_size);
-+ acl_role_set.r_hash =
-+ (struct acl_role_label **) create_table(&acl_role_set.r_size);
-+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
-+ inodev_set.n_hash =
-+ (struct name_entry **) create_table(&inodev_set.n_size);
-+
-+ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
-+ !name_set.n_hash || !inodev_set.n_hash)
-+ return 1;
-+
-+ memset(subj_map_set.s_hash, 0,
-+ sizeof(struct subject_map *) * subj_map_set.s_size);
-+ memset(acl_role_set.r_hash, 0,
-+ sizeof (struct acl_role_label *) * acl_role_set.r_size);
-+ memset(name_set.n_hash, 0,
-+ sizeof (struct name_entry *) * name_set.n_size);
-+ memset(inodev_set.n_hash, 0,
-+ sizeof (struct name_entry *) * inodev_set.n_size);
-+
-+ return 0;
-+}
-+
-+/* free information not needed after startup
-+ currently contains user->kernel pointer mappings for subjects
-+*/
-+
-+static void
-+free_init_variables(void)
-+{
-+ __u32 i;
-+
-+ if (subj_map_set.s_hash) {
-+ for (i = 0; i < subj_map_set.s_size; i++) {
-+ if (subj_map_set.s_hash[i]) {
-+ kfree(subj_map_set.s_hash[i]);
-+ subj_map_set.s_hash[i] = NULL;
-+ }
-+ }
-+
-+ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
-+ PAGE_SIZE)
-+ kfree(subj_map_set.s_hash);
-+ else
-+ vfree(subj_map_set.s_hash);
-+ }
-+
-+ return;
-+}
-+
-+static void
-+free_variables(void)
-+{
-+ struct acl_subject_label *s;
-+ struct acl_role_label *r;
-+ struct task_struct *task, *task2;
-+
-+ gr_clear_learn_entries();
-+
-+ read_lock(&tasklist_lock);
-+ for_each_process(task) {
-+ task2 = task;
-+ do {
-+ task2->acl_sp_role = 0;
-+ task2->acl_role_id = 0;
-+ task2->acl = NULL;
-+ task2->role = NULL;
-+ } while ((task2 = next_thread(task2)) != task);
-+ }
-+ read_unlock(&tasklist_lock);
-+
-+ /* free all object hash tables */
-+
-+ if (role_list_head) {
-+ for (r = role_list_head; r; r = r->next) {
-+ if (!r->subj_hash)
-+ break;
-+ for (s = r->hash->first; s; s = s->next) {
-+ if (!s->obj_hash)
-+ break;
-+ if ((s->obj_hash_size *
-+ sizeof (struct acl_object_label *)) <=
-+ PAGE_SIZE)
-+ kfree(s->obj_hash);
-+ else
-+ vfree(s->obj_hash);
-+ }
-+ if ((r->subj_hash_size *
-+ sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
-+ kfree(r->subj_hash);
-+ else
-+ vfree(r->subj_hash);
-+ }
-+ }
-+
-+ acl_free_all();
-+
-+ if (acl_role_set.r_hash) {
-+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
-+ PAGE_SIZE)
-+ kfree(acl_role_set.r_hash);
-+ else
-+ vfree(acl_role_set.r_hash);
-+ }
-+ if (name_set.n_hash) {
-+ if ((name_set.n_size * sizeof (struct name_entry *)) <=
-+ PAGE_SIZE)
-+ kfree(name_set.n_hash);
-+ else
-+ vfree(name_set.n_hash);
-+ }
-+
-+ if (inodev_set.n_hash) {
-+ if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
-+ PAGE_SIZE)
-+ kfree(inodev_set.n_hash);
-+ else
-+ vfree(inodev_set.n_hash);
-+ }
-+
-+ gr_free_uidset();
-+
-+ memset(&name_set, 0, sizeof (struct name_db));
-+ memset(&inodev_set, 0, sizeof (struct name_db));
-+ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
-+ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
-+
-+ role_list_head = NULL;
-+ default_role = NULL;
-+
-+ return;
-+}
-+
-+static __u32
-+count_user_objs(struct acl_object_label *userp)
-+{
-+ struct acl_object_label o_tmp;
-+ __u32 num = 0;
-+
-+ while (userp) {
-+ if (copy_from_user(&o_tmp, userp,
-+ sizeof (struct acl_object_label)))
-+ break;
-+
-+ userp = o_tmp.prev;
-+ num++;
-+ }
-+
-+ return num;
-+}
-+
-+static struct acl_subject_label *
-+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
-+
-+static int
-+copy_user_glob(struct acl_object_label *obj)
-+{
-+ struct acl_object_label *g_tmp, **guser, *glast = NULL;
-+ unsigned int len;
-+ char *tmp;
-+
-+ if (obj->globbed == NULL)
-+ return 0;
-+
-+ guser = &obj->globbed;
-+ while (*guser) {
-+ g_tmp = (struct acl_object_label *)
-+ acl_alloc(sizeof (struct acl_object_label));
-+ if (g_tmp == NULL)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(g_tmp, *guser,
-+ sizeof (struct acl_object_label)))
-+ return -EFAULT;
-+
-+ len = strnlen_user(g_tmp->filename, PATH_MAX);
-+
-+ if (!len || len >= PATH_MAX)
-+ return -EINVAL;
-+
-+ if ((tmp = (char *) acl_alloc(len)) == NULL)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(tmp, g_tmp->filename, len))
-+ return -EFAULT;
-+
-+ g_tmp->filename = tmp;
-+
-+ if (glast)
-+ glast->next = g_tmp;
-+ g_tmp->prev = glast;
-+ *guser = g_tmp;
-+ glast = g_tmp;
-+ guser = &((*guser)->next);
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
-+ struct acl_role_label *role)
-+{
-+ struct acl_object_label *o_tmp;
-+ unsigned int len;
-+ int ret;
-+ char *tmp;
-+
-+ while (userp) {
-+ if ((o_tmp = (struct acl_object_label *)
-+ acl_alloc(sizeof (struct acl_object_label))) == NULL)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(o_tmp, userp,
-+ sizeof (struct acl_object_label)))
-+ return -EFAULT;
-+
-+ userp = o_tmp->prev;
-+
-+ len = strnlen_user(o_tmp->filename, PATH_MAX);
-+
-+ if (!len || len >= PATH_MAX)
-+ return -EINVAL;
-+
-+ if ((tmp = (char *) acl_alloc(len)) == NULL)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(tmp, o_tmp->filename, len))
-+ return -EFAULT;
-+
-+ o_tmp->filename = tmp;
-+
-+ insert_acl_obj_label(o_tmp, subj);
-+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
-+ o_tmp->device))
-+ return -ENOMEM;
-+
-+ ret = copy_user_glob(o_tmp);
-+ if (ret)
-+ return ret;
-+
-+ if (o_tmp->nested) {
-+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
-+ if (IS_ERR(o_tmp->nested))
-+ return PTR_ERR(o_tmp->nested);
-+
-+ s_final = o_tmp->nested;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static __u32
-+count_user_subjs(struct acl_subject_label *userp)
-+{
-+ struct acl_subject_label s_tmp;
-+ __u32 num = 0;
-+
-+ while (userp) {
-+ if (copy_from_user(&s_tmp, userp,
-+ sizeof (struct acl_subject_label)))
-+ break;
-+
-+ userp = s_tmp.prev;
-+ /* do not count nested subjects against this count, since
-+ they are not included in the hash table, but are
-+ attached to objects. We have already counted
-+ the subjects in userspace for the allocation
-+ stack
-+ */
-+ if (!(s_tmp.mode & GR_NESTED))
-+ num++;
-+ }
-+
-+ return num;
-+}
-+
-+static int
-+copy_user_allowedips(struct acl_role_label *rolep)
-+{
-+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
-+
-+ ruserip = rolep->allowed_ips;
-+
-+ while (ruserip) {
-+ rlast = rtmp;
-+
-+ if ((rtmp = (struct role_allowed_ip *)
-+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(rtmp, ruserip,
-+ sizeof (struct role_allowed_ip)))
-+ return -EFAULT;
-+
-+ ruserip = rtmp->prev;
-+
-+ if (!rlast) {
-+ rtmp->prev = NULL;
-+ rolep->allowed_ips = rtmp;
-+ } else {
-+ rlast->next = rtmp;
-+ rtmp->prev = rlast;
-+ }
-+
-+ if (!ruserip)
-+ rtmp->next = NULL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+copy_user_transitions(struct acl_role_label *rolep)
-+{
-+ struct role_transition *rusertp, *rtmp = NULL, *rlast;
-+ unsigned int len;
-+ char *tmp;
-+
-+ rusertp = rolep->transitions;
-+
-+ while (rusertp) {
-+ rlast = rtmp;
-+
-+ if ((rtmp = (struct role_transition *)
-+ acl_alloc(sizeof (struct role_transition))) == NULL)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(rtmp, rusertp,
-+ sizeof (struct role_transition)))
-+ return -EFAULT;
-+
-+ rusertp = rtmp->prev;
-+
-+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
-+
-+ if (!len || len >= GR_SPROLE_LEN)
-+ return -EINVAL;
-+
-+ if ((tmp = (char *) acl_alloc(len)) == NULL)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(tmp, rtmp->rolename, len))
-+ return -EFAULT;
-+
-+ rtmp->rolename = tmp;
-+
-+ if (!rlast) {
-+ rtmp->prev = NULL;
-+ rolep->transitions = rtmp;
-+ } else {
-+ rlast->next = rtmp;
-+ rtmp->prev = rlast;
-+ }
-+
-+ if (!rusertp)
-+ rtmp->next = NULL;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct acl_subject_label *
-+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
-+{
-+ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
-+ unsigned int len;
-+ char *tmp;
-+ __u32 num_objs;
-+ struct acl_ip_label **i_tmp, *i_utmp2;
-+ struct gr_hash_struct ghash;
-+ struct subject_map *subjmap;
-+ unsigned long i_num;
-+ int err;
-+
-+ s_tmp = lookup_subject_map(userp);
-+
-+ /* we've already copied this subject into the kernel, just return
-+ the reference to it, and don't copy it over again
-+ */
-+ if (s_tmp)
-+ return(s_tmp);
-+
-+
-+ if ((s_tmp = (struct acl_subject_label *)
-+ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
-+ return ERR_PTR(-ENOMEM);
-+
-+ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
-+ if (subjmap == NULL)
-+ return ERR_PTR(-ENOMEM);
-+
-+ subjmap->user = userp;
-+ subjmap->kernel = s_tmp;
-+ insert_subj_map_entry(subjmap);
-+
-+ if (copy_from_user(s_tmp, userp,
-+ sizeof (struct acl_subject_label)))
-+ return ERR_PTR(-EFAULT);
-+
-+ if (!s_last) {
-+ s_tmp->prev = NULL;
-+ role->hash->first = s_tmp;
-+ } else {
-+ s_last->next = s_tmp;
-+ s_tmp->prev = s_last;
-+ }
-+
-+ s_last = s_tmp;
-+
-+ len = strnlen_user(s_tmp->filename, PATH_MAX);
-+
-+ if (!len || len >= PATH_MAX)
-+ return ERR_PTR(-EINVAL);
-+
-+ if ((tmp = (char *) acl_alloc(len)) == NULL)
-+ return ERR_PTR(-ENOMEM);
-+
-+ if (copy_from_user(tmp, s_tmp->filename, len))
-+ return ERR_PTR(-EFAULT);
-+
-+ s_tmp->filename = tmp;
-+
-+ if (!strcmp(s_tmp->filename, "/"))
-+ role->root_label = s_tmp;
-+
-+ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
-+ return ERR_PTR(-EFAULT);
-+
-+ /* copy user and group transition tables */
-+
-+ if (s_tmp->user_trans_num) {
-+ uid_t *uidlist;
-+
-+ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
-+ if (uidlist == NULL)
-+ return ERR_PTR(-ENOMEM);
-+ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
-+ return ERR_PTR(-EFAULT);
-+
-+ s_tmp->user_transitions = uidlist;
-+ }
-+
-+ if (s_tmp->group_trans_num) {
-+ gid_t *gidlist;
-+
-+ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
-+ if (gidlist == NULL)
-+ return ERR_PTR(-ENOMEM);
-+ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
-+ return ERR_PTR(-EFAULT);
-+
-+ s_tmp->group_transitions = gidlist;
-+ }
-+
-+ /* set up object hash table */
-+ num_objs = count_user_objs(ghash.first);
-+
-+ s_tmp->obj_hash_size = num_objs;
-+ s_tmp->obj_hash =
-+ (struct acl_object_label **)
-+ create_table(&(s_tmp->obj_hash_size));
-+
-+ if (!s_tmp->obj_hash)
-+ return ERR_PTR(-ENOMEM);
-+
-+ memset(s_tmp->obj_hash, 0,
-+ s_tmp->obj_hash_size *
-+ sizeof (struct acl_object_label *));
-+
-+ /* copy before adding in objects, since a nested
-+ acl could be found and be the final subject
-+ copied
-+ */
-+
-+ s_final = s_tmp;
-+
-+ /* add in objects */
-+ err = copy_user_objs(ghash.first, s_tmp, role);
-+
-+ if (err)
-+ return ERR_PTR(err);
-+
-+ /* set pointer for parent subject */
-+ if (s_tmp->parent_subject) {
-+ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
-+
-+ if (IS_ERR(s_tmp2))
-+ return s_tmp2;
-+
-+ s_tmp->parent_subject = s_tmp2;
-+ }
-+
-+ /* add in ip acls */
-+
-+ if (!s_tmp->ip_num) {
-+ s_tmp->ips = NULL;
-+ goto insert;
-+ }
-+
-+ i_tmp =
-+ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
-+ sizeof (struct
-+ acl_ip_label *));
-+
-+ if (!i_tmp)
-+ return ERR_PTR(-ENOMEM);
-+
-+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
-+ *(i_tmp + i_num) =
-+ (struct acl_ip_label *)
-+ acl_alloc(sizeof (struct acl_ip_label));
-+ if (!*(i_tmp + i_num))
-+ return ERR_PTR(-ENOMEM);
-+
-+ if (copy_from_user
-+ (&i_utmp2, s_tmp->ips + i_num,
-+ sizeof (struct acl_ip_label *)))
-+ return ERR_PTR(-EFAULT);
-+
-+ if (copy_from_user
-+ (*(i_tmp + i_num), i_utmp2,
-+ sizeof (struct acl_ip_label)))
-+ return ERR_PTR(-EFAULT);
-+ }
-+
-+ s_tmp->ips = i_tmp;
-+
-+insert:
-+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
-+ s_tmp->device))
-+ return ERR_PTR(-ENOMEM);
-+
-+ return s_tmp;
-+}
-+
-+static int
-+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
-+{
-+ struct acl_subject_label s_pre;
-+ struct acl_subject_label * ret;
-+ int err;
-+
-+ while (userp) {
-+ if (copy_from_user(&s_pre, userp,
-+ sizeof (struct acl_subject_label)))
-+ return -EFAULT;
-+
-+ /* do not add nested subjects here, add
-+ while parsing objects
-+ */
-+
-+ if (s_pre.mode & GR_NESTED) {
-+ userp = s_pre.prev;
-+ continue;
-+ }
-+
-+ ret = do_copy_user_subj(userp, role);
-+
-+ err = PTR_ERR(ret);
-+ if (IS_ERR(ret))
-+ return err;
-+
-+ insert_acl_subj_label(ret, role);
-+
-+ userp = s_pre.prev;
-+ }
-+
-+ s_final->next = NULL;
-+
-+ return 0;
-+}
-+
-+static int
-+copy_user_acl(struct gr_arg *arg)
-+{
-+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
-+ struct sprole_pw *sptmp;
-+ struct gr_hash_struct *ghash;
-+ unsigned long r_num;
-+ unsigned int len;
-+ char *tmp;
-+ int err = 0;
-+ __u16 i;
-+ __u32 num_subjs;
-+
-+ /* we need a default and kernel role */
-+ if (arg->role_db.r_entries < 2)
-+ return -EINVAL;
-+
-+ /* copy special role authentication info from userspace */
-+
-+ num_sprole_pws = arg->num_sprole_pws;
-+ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
-+
-+ if (!acl_special_roles) {
-+ err = -ENOMEM;
-+ goto cleanup;
-+ }
-+
-+ for (i = 0; i < num_sprole_pws; i++) {
-+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
-+ if (!sptmp) {
-+ err = -ENOMEM;
-+ goto cleanup;
-+ }
-+ if (copy_from_user(sptmp, arg->sprole_pws + i,
-+ sizeof (struct sprole_pw))) {
-+ err = -EFAULT;
-+ goto cleanup;
-+ }
-+
-+ len =
-+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
-+
-+ if (!len || len >= GR_SPROLE_LEN) {
-+ err = -EINVAL;
-+ goto cleanup;
-+ }
-+
-+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
-+ err = -ENOMEM;
-+ goto cleanup;
-+ }
-+
-+ if (copy_from_user(tmp, sptmp->rolename, len)) {
-+ err = -EFAULT;
-+ goto cleanup;
-+ }
-+
-+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
-+ printk(KERN_ALERT "Copying special role %s\n", tmp);
-+#endif
-+ sptmp->rolename = tmp;
-+ acl_special_roles[i] = sptmp;
-+ }
-+
-+ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
-+
-+ for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) {
-+ r_last = r_tmp;
-+
-+ r_tmp = acl_alloc(sizeof (struct acl_role_label));
-+
-+ if (!r_tmp) {
-+ err = -ENOMEM;
-+ goto cleanup;
-+ }
-+
-+ if (copy_from_user(&r_utmp2, r_utmp + r_num,
-+ sizeof (struct acl_role_label *))) {
-+ err = -EFAULT;
-+ goto cleanup;
-+ }
-+
-+ if (copy_from_user(r_tmp, r_utmp2,
-+ sizeof (struct acl_role_label))) {
-+ err = -EFAULT;
-+ goto cleanup;
-+ }
-+
-+ if (!r_last) {
-+ r_tmp->prev = NULL;
-+ role_list_head = r_tmp;
-+ } else {
-+ r_last->next = r_tmp;
-+ r_tmp->prev = r_last;
-+ }
-+
-+ if (r_num == (arg->role_db.r_entries - 1))
-+ r_tmp->next = NULL;
-+
-+ len = strnlen_user(r_tmp->rolename, PATH_MAX);
-+
-+ if (!len || len >= PATH_MAX) {
-+ err = -EINVAL;
-+ goto cleanup;
-+ }
-+
-+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
-+ err = -ENOMEM;
-+ goto cleanup;
-+ }
-+ if (copy_from_user(tmp, r_tmp->rolename, len)) {
-+ err = -EFAULT;
-+ goto cleanup;
-+ }
-+ r_tmp->rolename = tmp;
-+
-+ if (!strcmp(r_tmp->rolename, "default")
-+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
-+ default_role = r_tmp;
-+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
-+ kernel_role = r_tmp;
-+ }
-+
-+ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
-+ err = -ENOMEM;
-+ goto cleanup;
-+ }
-+ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
-+ err = -EFAULT;
-+ goto cleanup;
-+ }
-+
-+ r_tmp->hash = ghash;
-+
-+ num_subjs = count_user_subjs(r_tmp->hash->first);
-+
-+ r_tmp->subj_hash_size = num_subjs;
-+ r_tmp->subj_hash =
-+ (struct acl_subject_label **)
-+ create_table(&(r_tmp->subj_hash_size));
-+
-+ if (!r_tmp->subj_hash) {
-+ err = -ENOMEM;
-+ goto cleanup;
-+ }
-+
-+ err = copy_user_allowedips(r_tmp);
-+ if (err)
-+ goto cleanup;
-+
-+ err = copy_user_transitions(r_tmp);
-+ if (err)
-+ goto cleanup;
-+
-+ memset(r_tmp->subj_hash, 0,
-+ r_tmp->subj_hash_size *
-+ sizeof (struct acl_subject_label *));
-+
-+ s_last = NULL;
-+
-+ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
-+
-+ if (err)
-+ goto cleanup;
-+
-+ insert_acl_role_label(r_tmp);
-+ }
-+
-+ goto return_err;
-+ cleanup:
-+ free_variables();
-+ return_err:
-+ return err;
-+
-+}
-+
-+static int
-+gracl_init(struct gr_arg *args)
-+{
-+ int error = 0;
-+
-+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
-+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
-+
-+ if (init_variables(args->role_db.o_entries, args->role_db.g_entries,
-+ args->role_db.s_entries, args->role_db.i_entries,
-+ args->role_db.r_entries, args->role_db.a_entries,
-+ args->role_db.t_entries, args->num_sprole_pws)) {
-+ security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
-+ error = -ENOMEM;
-+ free_variables();
-+ goto out;
-+ }
-+
-+ error = copy_user_acl(args);
-+ free_init_variables();
-+ if (error) {
-+ free_variables();
-+ goto out;
-+ }
-+
-+ if ((error = gr_set_acls(0))) {
-+ free_variables();
-+ goto out;
-+ }
-+
-+ gr_status |= GR_READY;
-+ out:
-+ return error;
-+}
-+
-+static int
-+glob_match(char *pattern, char *string)
-+{
-+ char *p1, *p2;
-+
-+ p1 = pattern;
-+ p2 = string;
-+
-+ while (*p1 != '\0' && *p2 != '\0' && *p1 != '*') {
-+ if (*p1 == *p2 || *p1 == '?') {
-+ p1++;
-+ p2++;
-+ } else
-+ break;
-+ }
-+ if (*p1 == '*') {
-+ p1++;
-+ while (*p2 != '\0') {
-+ if (!glob_match(p1, p2))
-+ return 0;
-+ else
-+ p2++;
-+ }
-+ }
-+
-+ if (*p2 == '\0' && *p1 == '*')
-+ while (*p1 == '*')
-+ p1++;
-+
-+ if (*p1 == '\0' && *p2 == '\0')
-+ return 0;
-+ else
-+ return 1;
-+}
-+
-+static struct acl_object_label *
-+chk_glob_label(struct acl_object_label *globbed,
-+ struct dentry *dentry, struct vfsmount *mnt, char **path)
-+{
-+ struct acl_object_label *tmp;
-+
-+ if (*path == NULL)
-+ *path = gr_to_filename_nolock(dentry, mnt);
-+
-+ tmp = globbed;
-+
-+ while (tmp) {
-+ if (!glob_match(tmp->filename, *path))
-+ return tmp;
-+ tmp = tmp->next;
-+ }
-+
-+ return NULL;
-+}
-+
-+static __inline__ struct acl_object_label *
-+full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
-+ struct dentry *curr_dentry,
-+ const struct acl_subject_label *subj, char **path)
-+{
-+ struct acl_subject_label *tmpsubj;
-+ struct acl_object_label *retval;
-+ struct acl_object_label *retval2;
-+
-+ tmpsubj = (struct acl_subject_label *) subj;
-+ read_lock(&gr_inode_lock);
-+ do {
-+ retval = lookup_acl_obj_label(curr_dentry->d_inode->i_ino,
-+ curr_dentry->d_inode->i_sb->s_dev, tmpsubj);
-+ if (retval) {
-+ if (retval->globbed) {
-+ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
-+ (struct vfsmount *)orig_mnt, path);
-+ if (retval2)
-+ retval = retval2;
-+ }
-+ break;
-+ }
-+ } while ((tmpsubj = tmpsubj->parent_subject));
-+ read_unlock(&gr_inode_lock);
-+
-+ return retval;
-+}
-+
-+static struct acl_object_label *
-+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
-+ const struct acl_subject_label *subj)
-+{
-+ struct dentry *dentry = (struct dentry *) l_dentry;
-+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
-+ struct dentry *root;
-+ struct vfsmount *rootmnt;
-+ struct acl_object_label *retval;
-+ char *path = NULL;
-+
-+ read_lock(&child_reaper->fs->lock);
-+ rootmnt = mntget(child_reaper->fs->rootmnt);
-+ root = dget(child_reaper->fs->root);
-+ read_unlock(&child_reaper->fs->lock);
-+ spin_lock(&dcache_lock);
-+
-+ for (;;) {
-+ if (dentry == root && mnt == rootmnt)
-+ break;
-+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
-+ if (mnt->mnt_parent == mnt)
-+ break;
-+
-+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
-+ if (retval != NULL)
-+ goto out;
-+
-+ dentry = mnt->mnt_mountpoint;
-+ mnt = mnt->mnt_parent;
-+ continue;
-+ }
-+
-+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
-+ if (retval != NULL)
-+ goto out;
-+
-+ dentry = dentry->d_parent;
-+ }
-+
-+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
-+
-+ if (retval == NULL)
-+ retval = full_lookup(l_dentry, l_mnt, root, subj, &path);
-+out:
-+ spin_unlock(&dcache_lock);
-+ dput(root);
-+ mntput(rootmnt);
-+
-+ return retval;
-+}
-+
-+static struct acl_object_label *
-+chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
-+ const struct acl_subject_label *subj, char *path)
-+{
-+ struct dentry *dentry = (struct dentry *) l_dentry;
-+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
-+ struct dentry *root;
-+ struct vfsmount *rootmnt;
-+ struct acl_object_label *retval;
-+
-+ read_lock(&child_reaper->fs->lock);
-+ rootmnt = mntget(child_reaper->fs->rootmnt);
-+ root = dget(child_reaper->fs->root);
-+ read_unlock(&child_reaper->fs->lock);
-+ spin_lock(&dcache_lock);
-+
-+ for (;;) {
-+ if (dentry == root && mnt == rootmnt)
-+ break;
-+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
-+ if (mnt->mnt_parent == mnt)
-+ break;
-+
-+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
-+ if (retval != NULL)
-+ goto out;
-+
-+ dentry = mnt->mnt_mountpoint;
-+ mnt = mnt->mnt_parent;
-+ continue;
-+ }
-+
-+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
-+ if (retval != NULL)
-+ goto out;
-+
-+ dentry = dentry->d_parent;
-+ }
-+
-+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
-+
-+ if (retval == NULL)
-+ retval = full_lookup(l_dentry, l_mnt, root, subj, &path);
-+out:
-+ spin_unlock(&dcache_lock);
-+ dput(root);
-+ mntput(rootmnt);
-+
-+ return retval;
-+}
-+
-+static struct acl_subject_label *
-+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
-+ const struct acl_role_label *role)
-+{
-+ struct dentry *dentry = (struct dentry *) l_dentry;
-+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
-+ struct dentry *root;
-+ struct vfsmount *rootmnt;
-+ struct acl_subject_label *retval;
-+
-+ read_lock(&child_reaper->fs->lock);
-+ rootmnt = mntget(child_reaper->fs->rootmnt);
-+ root = dget(child_reaper->fs->root);
-+ read_unlock(&child_reaper->fs->lock);
-+ spin_lock(&dcache_lock);
-+
-+ for (;;) {
-+ if (unlikely(dentry == root && mnt == rootmnt))
-+ break;
-+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
-+ if (mnt->mnt_parent == mnt)
-+ break;
-+
-+ read_lock(&gr_inode_lock);
-+ retval =
-+ lookup_acl_subj_label(dentry->d_inode->i_ino,
-+ dentry->d_inode->i_sb->s_dev, role);
-+ read_unlock(&gr_inode_lock);
-+ if (unlikely(retval != NULL))
-+ goto out;
-+
-+ dentry = mnt->mnt_mountpoint;
-+ mnt = mnt->mnt_parent;
-+ continue;
-+ }
-+
-+ read_lock(&gr_inode_lock);
-+ retval =
-+ lookup_acl_subj_label(dentry->d_inode->i_ino,
-+ dentry->d_inode->i_sb->s_dev, role);
-+ read_unlock(&gr_inode_lock);
-+ if (unlikely(retval != NULL))
-+ goto out;
-+
-+ dentry = dentry->d_parent;
-+ }
-+
-+ read_lock(&gr_inode_lock);
-+ retval =
-+ lookup_acl_subj_label(dentry->d_inode->i_ino,
-+ dentry->d_inode->i_sb->s_dev, role);
-+ read_unlock(&gr_inode_lock);
-+
-+ if (unlikely(retval == NULL)) {
-+ read_lock(&gr_inode_lock);
-+ retval =
-+ lookup_acl_subj_label(root->d_inode->i_ino,
-+ root->d_inode->i_sb->s_dev, role);
-+ read_unlock(&gr_inode_lock);
-+ }
-+ out:
-+ spin_unlock(&dcache_lock);
-+ dput(root);
-+ mntput(rootmnt);
-+
-+ return retval;
-+}
-+
-+static __inline__ void
-+gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
-+ const struct task_struct *task, const char *pathname,
-+ const __u32 mode)
-+{
-+ security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
-+ uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
-+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
-+ 1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
-+
-+ return;
-+}
-+
-+__u32
-+gr_check_link(const struct dentry * new_dentry,
-+ const struct dentry * parent_dentry,
-+ const struct vfsmount * parent_mnt,
-+ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
-+{
-+ struct acl_object_label *obj;
-+ __u32 oldmode, newmode;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return (GR_WRITE | GR_CREATE);
-+
-+ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
-+ oldmode = obj->mode;
-+
-+ if (current->acl->mode & GR_LEARN)
-+ oldmode |= (GR_WRITE | GR_CREATE);
-+ newmode =
-+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
-+ oldmode | GR_CREATE | GR_AUDIT_CREATE |
-+ GR_AUDIT_WRITE | GR_SUPPRESS);
-+
-+ if ((newmode & oldmode) == oldmode)
-+ return newmode;
-+ else if (current->acl->mode & GR_LEARN) {
-+ gr_log_learn(current->role, current->uid, current->gid,
-+ current, gr_to_filename(old_dentry, old_mnt), oldmode);
-+ return (GR_WRITE | GR_CREATE);
-+ } else if (newmode & GR_SUPPRESS)
-+ return GR_SUPPRESS;
-+ else
-+ return 0;
-+}
-+
-+__u32
-+gr_search_file(const struct dentry * dentry, const __u32 mode,
-+ const struct vfsmount * mnt)
-+{
-+ __u32 retval = mode;
-+ struct acl_subject_label *curracl;
-+ struct acl_object_label *currobj;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return (mode & ~GR_AUDITS);
-+
-+ curracl = current->acl;
-+
-+ currobj = chk_obj_label(dentry, mnt, curracl);
-+ retval = currobj->mode & mode;
-+
-+ if (unlikely
-+ ((curracl->mode & GR_LEARN) && !(mode & GR_NOPTRACE)
-+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
-+ __u32 new_mode = mode;
-+
-+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
-+
-+ retval = new_mode;
-+
-+ if (!(mode & GR_NOLEARN))
-+ gr_log_learn(current->role, current->uid, current->gid,
-+ current, gr_to_filename(dentry, mnt), new_mode);
-+ }
-+
-+ return retval;
-+}
-+
-+__u32
-+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
-+ const struct vfsmount * mnt, const __u32 mode)
-+{
-+ struct name_entry *match;
-+ struct acl_object_label *matchpo;
-+ struct acl_subject_label *curracl;
-+ char *path;
-+ __u32 retval;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return (mode & ~GR_AUDITS);
-+
-+ preempt_disable();
-+ path = gr_to_filename(new_dentry, mnt);
-+ match = lookup_name_entry(path);
-+
-+ if (!match)
-+ goto check_parent;
-+
-+ curracl = current->acl;
-+
-+ read_lock(&gr_inode_lock);
-+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
-+ read_unlock(&gr_inode_lock);
-+
-+ if (matchpo) {
-+ if ((matchpo->mode & mode) !=
-+ (mode & ~(GR_AUDITS | GR_SUPPRESS))
-+ && curracl->mode & GR_LEARN) {
-+ __u32 new_mode = mode;
-+
-+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
-+
-+ gr_log_learn(current->role, current->uid, current->gid,
-+ current, gr_to_filename(new_dentry, mnt), new_mode);
-+
-+ preempt_enable();
-+ return new_mode;
-+ }
-+ preempt_enable();
-+ return (matchpo->mode & mode);
-+ }
-+
-+ check_parent:
-+ curracl = current->acl;
-+
-+ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
-+ retval = matchpo->mode & mode;
-+
-+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
-+ && (curracl->mode & GR_LEARN)) {
-+ __u32 new_mode = mode;
-+
-+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
-+
-+ gr_log_learn(current->role, current->uid, current->gid,
-+ current, gr_to_filename(new_dentry, mnt), new_mode);
-+ preempt_enable();
-+ return new_mode;
-+ }
-+
-+ preempt_enable();
-+ return retval;
-+}
-+
-+int
-+gr_check_hidden_task(const struct task_struct *task)
-+{
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return 0;
-+
-+ if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+int
-+gr_check_protected_task(const struct task_struct *task)
-+{
-+ if (unlikely(!(gr_status & GR_READY) || !task))
-+ return 0;
-+
-+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+__inline__ void
-+gr_copy_label(struct task_struct *tsk)
-+{
-+ tsk->used_accept = 0;
-+ tsk->acl_sp_role = 0;
-+ tsk->acl_role_id = current->acl_role_id;
-+ tsk->acl = current->acl;
-+ tsk->role = current->role;
-+ tsk->curr_ip = current->curr_ip;
-+ if (current->exec_file)
-+ get_file(current->exec_file);
-+ tsk->exec_file = current->exec_file;
-+ tsk->is_writable = current->is_writable;
-+ if (unlikely(current->used_accept))
-+ current->curr_ip = 0;
-+
-+ return;
-+}
-+
-+static __inline__ void
-+gr_set_proc_res(void)
-+{
-+ struct acl_subject_label *proc;
-+ unsigned short i;
-+
-+ proc = current->acl;
-+
-+ if (proc->mode & GR_LEARN)
-+ return;
-+
-+ for (i = 0; i < RLIM_NLIMITS; i++) {
-+ if (!(proc->resmask & (1 << i)))
-+ continue;
-+
-+ current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
-+ current->rlim[i].rlim_max = proc->res[i].rlim_max;
-+ }
-+
-+ return;
-+}
-+
-+static __inline__ void
-+do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
-+{
-+ task->role = lookup_acl_role_label(task, uid, gid);
-+
-+ return;
-+}
-+
-+int
-+gr_check_user_change(int real, int effective, int fs)
-+{
-+ unsigned int i;
-+ __u16 num;
-+ uid_t *uidlist;
-+ int curuid;
-+ int realok = 0;
-+ int effectiveok = 0;
-+ int fsok = 0;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return 0;
-+
-+ num = current->acl->user_trans_num;
-+ uidlist = current->acl->user_transitions;
-+
-+ if (uidlist == NULL)
-+ return 0;
-+
-+ if (real == -1)
-+ realok = 1;
-+ if (effective == -1)
-+ effectiveok = 1;
-+ if (fs == -1)
-+ fsok = 1;
-+
-+ if (current->acl->user_trans_type & GR_ID_ALLOW) {
-+ for (i = 0; i < num; i++) {
-+ curuid = (int)uidlist[i];
-+ if (real == curuid)
-+ realok = 1;
-+ if (effective == curuid)
-+ effectiveok = 1;
-+ if (fs == curuid)
-+ fsok = 1;
-+ }
-+ } else if (current->acl->user_trans_type & GR_ID_DENY) {
-+ for (i = 0; i < num; i++) {
-+ curuid = (int)uidlist[i];
-+ if (real == curuid)
-+ break;
-+ if (effective == curuid)
-+ break;
-+ if (fs == curuid)
-+ break;
-+ }
-+ /* not in deny list */
-+ if (i == num) {
-+ realok = 1;
-+ effectiveok = 1;
-+ fsok = 1;
-+ }
-+ }
-+
-+ if (realok && effectiveok && fsok)
-+ return 0;
-+ else {
-+ security_alert(GR_USRCHANGE_ACL_MSG,
-+ realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real, DEFAULTSECARGS);
-+ return 1;
-+ }
-+}
-+
-+int
-+gr_check_group_change(int real, int effective, int fs)
-+{
-+ unsigned int i;
-+ __u16 num;
-+ gid_t *gidlist;
-+ int curgid;
-+ int realok = 0;
-+ int effectiveok = 0;
-+ int fsok = 0;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return 0;
-+
-+ num = current->acl->group_trans_num;
-+ gidlist = current->acl->group_transitions;
-+
-+ if (gidlist == NULL)
-+ return 0;
-+
-+ if (real == -1)
-+ realok = 1;
-+ if (effective == -1)
-+ effectiveok = 1;
-+ if (fs == -1)
-+ fsok = 1;
-+
-+ if (current->acl->group_trans_type & GR_ID_ALLOW) {
-+ for (i = 0; i < num; i++) {
-+ curgid = (int)gidlist[i];
-+ if (real == curgid)
-+ realok = 1;
-+ if (effective == curgid)
-+ effectiveok = 1;
-+ if (fs == curgid)
-+ fsok = 1;
-+ }
-+ } else if (current->acl->group_trans_type & GR_ID_DENY) {
-+ for (i = 0; i < num; i++) {
-+ curgid = (int)gidlist[i];
-+ if (real == curgid)
-+ break;
-+ if (effective == curgid)
-+ break;
-+ if (fs == curgid)
-+ break;
-+ }
-+ /* not in deny list */
-+ if (i == num) {
-+ realok = 1;
-+ effectiveok = 1;
-+ fsok = 1;
-+ }
-+ }
-+
-+ if (realok && effectiveok && fsok)
-+ return 0;
-+ else {
-+ security_alert(GR_GRPCHANGE_ACL_MSG,
-+ realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real, DEFAULTSECARGS);
-+ return 1;
-+ }
-+}
-+
-+void
-+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
-+{
-+ struct acl_object_label *obj;
-+ struct file *filp;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return;
-+
-+ filp = task->exec_file;
-+
-+ /* kernel process, we'll give them the kernel role */
-+ if (unlikely(!filp)) {
-+ task->role = kernel_role;
-+ task->acl = kernel_role->root_label;
-+ return;
-+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
-+ do_set_role_label(task, uid, gid);
-+
-+ task->acl =
-+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
-+
-+ task->is_writable = 0;
-+
-+ /* ignore additional mmap checks for processes that are writable
-+ by the default ACL */
-+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
-+ if (unlikely(obj->mode & GR_WRITE))
-+ task->is_writable = 1;
-+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
-+ if (unlikely(obj->mode & GR_WRITE))
-+ task->is_writable = 1;
-+
-+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
-+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
-+#endif
-+
-+ gr_set_proc_res();
-+
-+ return;
-+}
-+
-+void
-+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ struct acl_subject_label *newacl;
-+ struct acl_object_label *obj;
-+ __u32 retmode;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return;
-+
-+ newacl = chk_subj_label(dentry, mnt, current->role);
-+
-+ obj = chk_obj_label(dentry, mnt, current->acl);
-+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
-+
-+ if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
-+ if (obj->nested)
-+ current->acl = obj->nested;
-+ else
-+ current->acl = newacl;
-+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
-+ security_audit(GR_INHERIT_ACL_MSG, current->acl->filename,
-+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
-+
-+ current->is_writable = 0;
-+
-+ /* ignore additional mmap checks for processes that are writable
-+ by the default ACL */
-+ obj = chk_obj_label(dentry, mnt, default_role->root_label);
-+ if (unlikely(obj->mode & GR_WRITE))
-+ current->is_writable = 1;
-+ obj = chk_obj_label(dentry, mnt, current->role->root_label);
-+ if (unlikely(obj->mode & GR_WRITE))
-+ current->is_writable = 1;
-+
-+ gr_set_proc_res();
-+
-+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
-+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename);
-+#endif
-+ return;
-+}
-+
-+static __inline__ void
-+do_handle_delete(const ino_t ino, const dev_t dev)
-+{
-+ struct acl_object_label *matchpo;
-+ struct acl_subject_label *matchps;
-+ struct acl_subject_label *i;
-+ struct acl_role_label *role;
-+
-+ for (role = role_list_head; role; role = role->next) {
-+ for (i = role->hash->first; i; i = i->next) {
-+ if (unlikely((i->mode & GR_NESTED) &&
-+ (i->inode == ino) &&
-+ (i->device == dev)))
-+ i->mode |= GR_DELETED;
-+ if (unlikely((matchpo =
-+ lookup_acl_obj_label(ino, dev, i)) != NULL))
-+ matchpo->mode |= GR_DELETED;
-+ }
-+
-+ if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
-+ matchps->mode |= GR_DELETED;
-+ }
-+
-+ return;
-+}
-+
-+void
-+gr_handle_delete(const ino_t ino, const dev_t dev)
-+{
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return;
-+
-+ write_lock(&gr_inode_lock);
-+ if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
-+ do_handle_delete(ino, dev);
-+ write_unlock(&gr_inode_lock);
-+
-+ return;
-+}
-+
-+static __inline__ void
-+update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
-+ const ino_t newinode, const dev_t newdevice,
-+ struct acl_subject_label *subj)
-+{
-+ unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
-+ struct acl_object_label **match;
-+ struct acl_object_label *tmp;
-+ __u8 i = 0;
-+
-+ match = &subj->obj_hash[index];
-+
-+ while (*match && ((*match)->inode != oldinode ||
-+ (*match)->device != olddevice ||
-+ !((*match)->mode & GR_DELETED))) {
-+ index = (index + (1 << i)) % subj->obj_hash_size;
-+ match = &subj->obj_hash[index];
-+ i = (i + 1) % 32;
-+ }
-+
-+ if (*match && ((*match) != deleted_object)
-+ && ((*match)->inode == oldinode)
-+ && ((*match)->device == olddevice)
-+ && ((*match)->mode & GR_DELETED)) {
-+ tmp = *match;
-+ tmp->inode = newinode;
-+ tmp->device = newdevice;
-+ tmp->mode &= ~GR_DELETED;
-+
-+ *match = deleted_object;
-+
-+ insert_acl_obj_label(tmp, subj);
-+ }
-+
-+ return;
-+}
-+
-+static __inline__ void
-+update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
-+ const ino_t newinode, const dev_t newdevice,
-+ struct acl_role_label *role)
-+{
-+ struct acl_subject_label **s_hash = role->subj_hash;
-+ unsigned long subj_size = role->subj_hash_size;
-+ unsigned long index = fhash(oldinode, olddevice, subj_size);
-+ struct acl_subject_label **match;
-+ struct acl_subject_label *tmp;
-+ __u8 i = 0;
-+
-+ match = &s_hash[index];
-+
-+ while (*match && ((*match)->inode != oldinode ||
-+ (*match)->device != olddevice ||
-+ !((*match)->mode & GR_DELETED))) {
-+ index = (index + (1 << i)) % subj_size;
-+ i = (i + 1) % 32;
-+ match = &s_hash[index];
-+ }
-+
-+ if (*match && (*match != deleted_subject)
-+ && ((*match)->inode == oldinode)
-+ && ((*match)->device == olddevice)
-+ && ((*match)->mode & GR_DELETED)) {
-+ tmp = *match;
-+
-+ tmp->inode = newinode;
-+ tmp->device = newdevice;
-+ tmp->mode &= ~GR_DELETED;
-+
-+ *match = deleted_subject;
-+
-+ insert_acl_subj_label(tmp, role);
-+ }
-+
-+ return;
-+}
-+
-+static __inline__ void
-+update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
-+ const ino_t newinode, const dev_t newdevice)
-+{
-+ unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
-+ struct name_entry **match;
-+ struct name_entry *tmp;
-+ __u8 i = 0;
-+
-+ match = &inodev_set.n_hash[index];
-+
-+ while (*match
-+ && ((*match)->inode != oldinode
-+ || (*match)->device != olddevice)) {
-+ index = (index + (1 << i)) % inodev_set.n_size;
-+ i = (i + 1) % 32;
-+ match = &inodev_set.n_hash[index];
-+ }
-+
-+ if (*match && (*match != deleted_inodev)
-+ && ((*match)->inode == oldinode)
-+ && ((*match)->device == olddevice)) {
-+ tmp = *match;
-+
-+ tmp->inode = newinode;
-+ tmp->device = newdevice;
-+
-+ *match = deleted_inodev;
-+
-+ insert_inodev_entry(tmp);
-+ }
-+
-+ return;
-+}
-+
-+static __inline__ void
-+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
-+ const struct vfsmount *mnt)
-+{
-+ struct acl_subject_label *i;
-+ struct acl_role_label *role;
-+
-+ for (role = role_list_head; role; role = role->next) {
-+ update_acl_subj_label(matchn->inode, matchn->device,
-+ dentry->d_inode->i_ino,
-+ dentry->d_inode->i_sb->s_dev, role);
-+
-+ for (i = role->hash->first; i; i = i->next) {
-+ if (unlikely((i->mode & GR_NESTED) &&
-+ (i->inode == dentry->d_inode->i_ino) &&
-+ (i->device == dentry->d_inode->i_sb->s_dev))) {
-+ i->inode = dentry->d_inode->i_ino;
-+ i->device = dentry->d_inode->i_sb->s_dev;
-+ }
-+ update_acl_obj_label(matchn->inode, matchn->device,
-+ dentry->d_inode->i_ino,
-+ dentry->d_inode->i_sb->s_dev, i);
-+ }
-+ }
-+
-+ update_inodev_entry(matchn->inode, matchn->device,
-+ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
-+
-+ return;
-+}
-+
-+void
-+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ struct name_entry *matchn;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return;
-+
-+ preempt_disable();
-+ matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
-+ preempt_enable();
-+
-+ if (unlikely((unsigned long)matchn)) {
-+ write_lock(&gr_inode_lock);
-+ do_handle_create(matchn, dentry, mnt);
-+ write_unlock(&gr_inode_lock);
-+ }
-+
-+ return;
-+}
-+
-+void
-+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
-+ struct dentry *old_dentry,
-+ struct dentry *new_dentry,
-+ struct vfsmount *mnt, const __u8 replace)
-+{
-+ struct name_entry *matchn;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return;
-+
-+ preempt_disable();
-+ matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
-+ preempt_enable();
-+
-+ /* we wouldn't have to check d_inode if it weren't for
-+ NFS silly-renaming
-+ */
-+
-+ write_lock(&gr_inode_lock);
-+ if (unlikely(replace && new_dentry->d_inode)) {
-+ if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
-+ new_dentry->d_inode->i_sb->s_dev) &&
-+ (old_dentry->d_inode->i_nlink <= 1)))
-+ do_handle_delete(new_dentry->d_inode->i_ino,
-+ new_dentry->d_inode->i_sb->s_dev);
-+ }
-+
-+ if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
-+ old_dentry->d_inode->i_sb->s_dev) &&
-+ (old_dentry->d_inode->i_nlink <= 1)))
-+ do_handle_delete(old_dentry->d_inode->i_ino,
-+ old_dentry->d_inode->i_sb->s_dev);
-+
-+ if (unlikely((unsigned long)matchn))
-+ do_handle_create(matchn, old_dentry, mnt);
-+ write_unlock(&gr_inode_lock);
-+
-+ return;
-+}
-+
-+static int
-+lookup_special_role_auth(const char *rolename, unsigned char **salt,
-+ unsigned char **sum)
-+{
-+ struct acl_role_label *r;
-+ struct role_transition *trans;
-+ __u16 i;
-+ int found = 0;
-+
-+ /* check transition table */
-+
-+ for (trans = current->role->transitions; trans; trans = trans->next) {
-+ if (!strcmp(rolename, trans->rolename)) {
-+ found = 1;
-+ break;
-+ }
-+ }
-+
-+ if (!found)
-+ return 0;
-+
-+ /* handle special roles that do not require authentication */
-+
-+ for (r = role_list_head; r; r = r->next) {
-+ if (!strcmp(rolename, r->rolename)
-+ && (r->roletype & GR_ROLE_NOPW)) {
-+ *salt = NULL;
-+ *sum = NULL;
-+ return 1;
-+ }
-+ }
-+
-+ for (i = 0; i < num_sprole_pws; i++) {
-+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
-+ *salt = acl_special_roles[i]->salt;
-+ *sum = acl_special_roles[i]->sum;
-+ return 1;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static void
-+assign_special_role(char *rolename)
-+{
-+ struct acl_object_label *obj;
-+ struct acl_role_label *r;
-+ struct acl_role_label *assigned = NULL;
-+ struct task_struct *tsk;
-+ struct file *filp;
-+
-+ for (r = role_list_head; r; r = r->next)
-+ if (!strcmp(rolename, r->rolename) &&
-+ (r->roletype & GR_ROLE_SPECIAL))
-+ assigned = r;
-+
-+ if (!assigned)
-+ return;
-+
-+ tsk = current->parent;
-+ filp = tsk->exec_file;
-+
-+ if (tsk && filp) {
-+ tsk->is_writable = 0;
-+
-+ acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
-+ tsk->acl_sp_role = 1;
-+ tsk->acl_role_id = acl_sp_role_value;
-+ tsk->role = assigned;
-+ tsk->acl =
-+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
-+
-+ /* ignore additional mmap checks for processes that are writable
-+ by the default ACL */
-+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
-+ if (unlikely(obj->mode & GR_WRITE))
-+ tsk->is_writable = 1;
-+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
-+ if (unlikely(obj->mode & GR_WRITE))
-+ tsk->is_writable = 1;
-+
-+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
-+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
-+#endif
-+ }
-+
-+ return;
-+}
-+
-+ssize_t
-+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
-+{
-+ struct gr_arg *arg;
-+ unsigned char *sprole_salt;
-+ unsigned char *sprole_sum;
-+ int error = sizeof (struct gr_arg);
-+ int error2 = 0;
-+
-+ down(&gr_dev_sem);
-+
-+ arg = (struct gr_arg *) buf;
-+
-+ if (count != sizeof (struct gr_arg)) {
-+ security_alert_good(GR_DEV_ACL_MSG, count,
-+ (int) sizeof (struct gr_arg));
-+ error = -EINVAL;
-+ goto out;
-+ }
-+
-+ if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
-+ && time_before_eq(gr_auth_expires, get_seconds())) {
-+ gr_auth_expires = 0;
-+ gr_auth_attempts = 0;
-+ }
-+
-+ if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) {
-+ error = -EFAULT;
-+ goto out;
-+ }
-+
-+ if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, get_seconds())) {
-+ error = -EBUSY;
-+ goto out;
-+ }
-+
-+ /* if non-root trying to do anything other than use a special role,
-+ do not attempt authentication, do not count towards authentication
-+ locking
-+ */
-+
-+ if (gr_usermode->mode != SPROLE && current->uid) {
-+ error = -EPERM;
-+ goto out;
-+ }
-+
-+ /* ensure pw and special role name are null terminated */
-+
-+ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
-+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
-+
-+ /* Okay.
-+ * We have our enough of the argument structure..(we have yet
-+ * to copy_from_user the tables themselves) . Copy the tables
-+ * only if we need them, i.e. for loading operations. */
-+
-+ switch (gr_usermode->mode) {
-+ case STATUS:
-+ if (gr_status & GR_READY)
-+ error = 1;
-+ else
-+ error = 2;
-+ goto out;
-+ case SHUTDOWN:
-+ if ((gr_status & GR_READY)
-+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
-+ gr_status &= ~GR_READY;
-+ security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
-+ free_variables();
-+ memset(gr_usermode, 0, sizeof (struct gr_arg));
-+ memset(gr_system_salt, 0, GR_SALT_LEN);
-+ memset(gr_system_sum, 0, GR_SHA_LEN);
-+ } else if (gr_status & GR_READY) {
-+ security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
-+ error = -EPERM;
-+ } else {
-+ security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
-+ error = -EAGAIN;
-+ }
-+ break;
-+ case ENABLE:
-+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
-+ security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
-+ else {
-+ if (gr_status & GR_READY)
-+ error = -EAGAIN;
-+ else
-+ error = error2;
-+ security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
-+ DEFAULTSECARGS);
-+ }
-+ break;
-+ case RELOAD:
-+ if (!(gr_status & GR_READY)) {
-+ security_alert_good(GR_RELOADI_ACL_MSG);
-+ error = -EAGAIN;
-+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
-+ lock_kernel();
-+ gr_status &= ~GR_READY;
-+ free_variables();
-+ if (!(error2 = gracl_init(gr_usermode))) {
-+ unlock_kernel();
-+ security_alert_good(GR_RELOAD_ACL_MSG,
-+ GR_VERSION);
-+ } else {
-+ unlock_kernel();
-+ error = error2;
-+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
-+ DEFAULTSECARGS);
-+ }
-+ } else {
-+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
-+ DEFAULTSECARGS);
-+ error = -EPERM;
-+ }
-+ break;
-+ case SEGVMOD:
-+ if (unlikely(!(gr_status & GR_READY))) {
-+ security_alert_good(GR_SEGVMODI_ACL_MSG,
-+ DEFAULTSECARGS);
-+ error = -EAGAIN;
-+ break;
-+ }
-+
-+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
-+ security_alert_good(GR_SEGVMODS_ACL_MSG,
-+ DEFAULTSECARGS);
-+ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
-+ struct acl_subject_label *segvacl;
-+ segvacl =
-+ lookup_acl_subj_label(gr_usermode->segv_inode,
-+ gr_usermode->segv_device,
-+ current->role);
-+ if (segvacl) {
-+ segvacl->crashes = 0;
-+ segvacl->expires = 0;
-+ }
-+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
-+ gr_remove_uid(gr_usermode->segv_uid);
-+ }
-+ } else {
-+ security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
-+ error = -EPERM;
-+ }
-+ break;
-+ case SPROLE:
-+ if (unlikely(!(gr_status & GR_READY))) {
-+ security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
-+ error = -EAGAIN;
-+ break;
-+ }
-+
-+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
-+ && time_before_eq(current->role->expires, get_seconds())) {
-+ current->role->expires = 0;
-+ current->role->auth_attempts = 0;
-+ }
-+
-+ if (time_after(current->role->expires, get_seconds())) {
-+ error = -EBUSY;
-+ goto out;
-+ }
-+
-+ if (lookup_special_role_auth
-+ (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
-+ && ((!sprole_salt && !sprole_sum)
-+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
-+ assign_special_role(gr_usermode->sp_role);
-+ security_alert_good(GR_SPROLES_ACL_MSG,
-+ (current->parent) ? current->
-+ parent->role->rolename : "",
-+ acl_sp_role_value, DEFAULTSECARGS);
-+ } else {
-+ security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
-+ DEFAULTSECARGS);
-+ error = -EPERM;
-+ current->role->auth_attempts++;
-+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
-+ current->role->expires =
-+ get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
-+ security_alert(GR_MAXROLEPW_ACL_MSG,
-+ CONFIG_GRKERNSEC_ACL_MAXTRIES,
-+ gr_usermode->sp_role, DEFAULTSECARGS);
-+ }
-+
-+ goto out;
-+ }
-+ break;
-+ case UNSPROLE:
-+ if (unlikely(!(gr_status & GR_READY))) {
-+ security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
-+ error = -EAGAIN;
-+ break;
-+ }
-+
-+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
-+ && time_before_eq(current->role->expires, get_seconds())) {
-+ current->role->expires = 0;
-+ current->role->auth_attempts = 0;
-+ }
-+
-+ if (time_after(current->role->expires, get_seconds())) {
-+ error = -EBUSY;
-+ goto out;
-+ }
-+
-+ if ((current->role->roletype & GR_ROLE_SPECIAL) &&
-+ lookup_special_role_auth
-+ (current->role->rolename, &sprole_salt, &sprole_sum)
-+ && ((!sprole_salt && !sprole_sum)
-+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
-+ security_alert_good(GR_UNSPROLES_ACL_MSG,
-+ (current->parent) ? current->
-+ parent->role->rolename : "",
-+ (current->parent) ? current->
-+ parent->acl_role_id : 0, DEFAULTSECARGS);
-+ gr_set_acls(1);
-+ if (current->parent)
-+ current->parent->acl_sp_role = 0;
-+ } else {
-+ security_alert(GR_UNSPROLEF_ACL_MSG, current->role->rolename,
-+ DEFAULTSECARGS);
-+ error = -EPERM;
-+ current->role->auth_attempts++;
-+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
-+ current->role->expires =
-+ get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
-+ security_alert(GR_MAXROLEPW_ACL_MSG,
-+ CONFIG_GRKERNSEC_ACL_MAXTRIES,
-+ current->role->rolename, DEFAULTSECARGS);
-+ }
-+
-+ goto out;
-+ }
-+ break;
-+ default:
-+ security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
-+ DEFAULTSECARGS);
-+ error = -EINVAL;
-+ break;
-+ }
-+
-+ if (error != -EPERM)
-+ goto out;
-+
-+ gr_auth_attempts++;
-+
-+ if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
-+ security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
-+ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
-+ }
-+
-+ out:
-+ up(&gr_dev_sem);
-+ return error;
-+}
-+
-+int
-+gr_set_acls(const int type)
-+{
-+ struct acl_object_label *obj;
-+ struct task_struct *task, *task2;
-+ struct file *filp;
-+ unsigned short i;
-+
-+ read_lock(&tasklist_lock);
-+ for_each_process(task2) {
-+ task = task2;
-+ do {
-+ /* check to see if we're called from the exit handler,
-+ if so, only replace ACLs that have inherited the admin
-+ ACL */
-+
-+ if (type && (task->role != current->role ||
-+ task->acl_role_id != current->acl_role_id))
-+ continue;
-+
-+ task->acl_role_id = 0;
-+
-+ if ((filp = task->exec_file)) {
-+ do_set_role_label(task, task->uid, task->gid);
-+
-+ task->acl =
-+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
-+ task->role);
-+ if (task->acl) {
-+ struct acl_subject_label *curr;
-+ curr = task->acl;
-+
-+ task->is_writable = 0;
-+ /* ignore additional mmap checks for processes that are writable
-+ by the default ACL */
-+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
-+ if (unlikely(obj->mode & GR_WRITE))
-+ task->is_writable = 1;
-+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
-+ if (unlikely(obj->mode & GR_WRITE))
-+ task->is_writable = 1;
-+
-+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
-+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
-+#endif
-+ if (!(curr->mode & GR_LEARN))
-+ for (i = 0; i < RLIM_NLIMITS; i++) {
-+ if (!(curr->resmask & (1 << i)))
-+ continue;
-+
-+ task->rlim[i].rlim_cur =
-+ curr->res[i].rlim_cur;
-+ task->rlim[i].rlim_max =
-+ curr->res[i].rlim_max;
-+ }
-+ } else {
-+ read_unlock(&tasklist_lock);
-+ security_alert_good(GR_DEFACL_MSG, task->comm,
-+ task->pid);
-+ return 1;
-+ }
-+ } else {
-+ // it's a kernel process
-+ task->role = kernel_role;
-+ task->acl = kernel_role->root_label;
-+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
-+ task->acl->mode &= ~GR_FIND;
-+#endif
-+ }
-+ } while ((task = next_thread(task)) != task2);
-+ }
-+ read_unlock(&tasklist_lock);
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(gr_learn_resource);
-+
-+void
-+gr_learn_resource(const struct task_struct *task,
-+ const int res, const unsigned long wanted, const int gt)
-+{
-+ struct acl_subject_label *acl;
-+
-+ if (unlikely((gr_status & GR_READY) &&
-+ task->acl && (task->acl->mode & GR_LEARN)))
-+ goto skip_reslog;
-+
-+#ifdef CONFIG_GRKERNSEC_RESLOG
-+ gr_log_resource(task, res, wanted, gt);
-+#endif
-+ skip_reslog:
-+
-+ if (unlikely(!(gr_status & GR_READY) || !wanted))
-+ return;
-+
-+ acl = task->acl;
-+
-+ if (likely(!acl || !(acl->mode & GR_LEARN) ||
-+ !(acl->resmask & (1 << (unsigned short) res))))
-+ return;
-+
-+ if (wanted >= acl->res[res].rlim_cur) {
-+ unsigned long res_add;
-+
-+ res_add = wanted;
-+ switch (res) {
-+ case RLIMIT_CPU:
-+ res_add += GR_RLIM_CPU_BUMP;
-+ break;
-+ case RLIMIT_FSIZE:
-+ res_add += GR_RLIM_FSIZE_BUMP;
-+ break;
-+ case RLIMIT_DATA:
-+ res_add += GR_RLIM_DATA_BUMP;
-+ break;
-+ case RLIMIT_STACK:
-+ res_add += GR_RLIM_STACK_BUMP;
-+ break;
-+ case RLIMIT_CORE:
-+ res_add += GR_RLIM_CORE_BUMP;
-+ break;
-+ case RLIMIT_RSS:
-+ res_add += GR_RLIM_RSS_BUMP;
-+ break;
-+ case RLIMIT_NPROC:
-+ res_add += GR_RLIM_NPROC_BUMP;
-+ break;
-+ case RLIMIT_NOFILE:
-+ res_add += GR_RLIM_NOFILE_BUMP;
-+ break;
-+ case RLIMIT_MEMLOCK:
-+ res_add += GR_RLIM_MEMLOCK_BUMP;
-+ break;
-+ case RLIMIT_AS:
-+ res_add += GR_RLIM_AS_BUMP;
-+ break;
-+ case RLIMIT_LOCKS:
-+ res_add += GR_RLIM_LOCKS_BUMP;
-+ break;
-+ }
-+
-+ acl->res[res].rlim_cur = res_add;
-+
-+ if (wanted > acl->res[res].rlim_max)
-+ acl->res[res].rlim_max = res_add;
-+
-+ security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
-+ current->role->roletype, acl->filename,
-+ acl->res[res].rlim_cur, acl->res[res].rlim_max,
-+ "", (unsigned long) res);
-+ }
-+
-+ return;
-+}
-+
-+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
-+void
-+pax_set_flags(struct linux_binprm *bprm)
-+{
-+ struct task_struct *task = current;
-+ struct acl_subject_label *proc;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return;
-+
-+ proc = task->acl;
-+
-+ if (proc->mode & GR_PAXPAGE)
-+ task->flags &= ~PF_PAX_PAGEEXEC;
-+ if (proc->mode & GR_PAXSEGM)
-+ task->flags &= ~PF_PAX_SEGMEXEC;
-+ if (proc->mode & GR_PAXGCC)
-+ task->flags |= PF_PAX_EMUTRAMP;
-+ if (proc->mode & GR_PAXMPROTECT)
-+ task->flags &= ~PF_PAX_MPROTECT;
-+ if (proc->mode & GR_PAXRANDMMAP)
-+ task->flags &= ~PF_PAX_RANDMMAP;
-+ if (proc->mode & GR_PAXRANDEXEC)
-+ task->flags |= PF_PAX_RANDEXEC;
-+
-+ return;
-+}
-+#endif
-+
-+#ifdef CONFIG_SYSCTL
-+extern struct proc_dir_entry *proc_sys_root;
-+
-+
-+/* the following function is called under the BKL */
-+
-+__u32
-+gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
-+ const void *newval)
-+{
-+ struct proc_dir_entry *tmp;
-+ struct nameidata nd;
-+ const char *proc_sys = "/proc/sys";
-+ char *path;
-+ struct acl_object_label *obj;
-+ unsigned short len = 0, pos = 0, depth = 0, i;
-+ __u32 err = 0;
-+ __u32 mode = 0;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return 1;
-+
-+ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
-+
-+ if (oldval)
-+ mode |= GR_READ;
-+ if (newval)
-+ mode |= GR_WRITE;
-+
-+ /* convert the requested sysctl entry into a pathname */
-+
-+ for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
-+ len += strlen(tmp->name);
-+ len++;
-+ depth++;
-+ }
-+
-+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
-+ return 0; /* deny */
-+
-+ memset(path, 0, PAGE_SIZE);
-+
-+ memcpy(path, proc_sys, strlen(proc_sys));
-+
-+ pos += strlen(proc_sys);
-+
-+ for (; depth > 0; depth--) {
-+ path[pos] = '/';
-+ pos++;
-+ for (i = 1, tmp = table->de; tmp != proc_sys_root;
-+ tmp = tmp->parent) {
-+ if (depth == i) {
-+ memcpy(path + pos, tmp->name,
-+ strlen(tmp->name));
-+ pos += strlen(tmp->name);
-+ }
-+ i++;
-+ }
-+ }
-+
-+ err = path_lookup(path, LOOKUP_FOLLOW, &nd);
-+
-+ if (err)
-+ goto out;
-+
-+ obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
-+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
-+
-+ if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
-+ __u32 new_mode = mode;
-+
-+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
-+
-+ err = new_mode;
-+ gr_log_learn(current->role, current->uid, current->gid,
-+ current, path, new_mode);
-+ } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
-+ security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
-+ (mode & GR_READ) ? " reading" : "",
-+ (mode & GR_WRITE) ? " writing" : "",
-+ DEFAULTSECARGS);
-+ err = 0;
-+ } else if ((err & mode) != mode) {
-+ err = 0;
-+ } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
-+ security_audit(GR_SYSCTL_ACL_MSG, "successful",
-+ path, (mode & GR_READ) ? " reading" : "",
-+ (mode & GR_WRITE) ? " writing" : "",
-+ DEFAULTSECARGS);
-+ }
-+
-+ path_release(&nd);
-+
-+ out:
-+ return err;
-+}
-+#endif
-+
-+int
-+gr_handle_proc_ptrace(struct task_struct *task)
-+{
-+ struct file *filp;
-+ struct task_struct *tmp = task;
-+ struct task_struct *curtemp = current;
-+ __u32 retmode;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return 0;
-+
-+ filp = task->exec_file;
-+
-+ read_lock(&tasklist_lock);
-+ while (tmp->pid > 0) {
-+ if (tmp == curtemp)
-+ break;
-+ tmp = tmp->parent;
-+ }
-+ read_unlock(&tasklist_lock);
-+
-+ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))
-+ return 1;
-+
-+ retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
-+
-+ if (retmode & GR_NOPTRACE)
-+ return 1;
-+
-+ if (!(current->acl->mode & GR_OVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
-+ && (current->acl != task->acl || (current->acl != current->role->root_label
-+ && current->pid != task->pid)))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+int
-+gr_handle_ptrace(struct task_struct *task, const long request)
-+{
-+ struct file *filp;
-+ struct task_struct *tmp = task;
-+ struct task_struct *curtemp = current;
-+ __u32 retmode;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return 0;
-+
-+ filp = task->exec_file;
-+
-+ if (task->acl->mode & GR_NOPTRACE) {
-+ security_alert(GR_PTRACE_ACL_MSG, filp ?
-+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt)
-+ : "(none)", task->comm, task->pid,
-+ DEFAULTSECARGS);
-+ return 1;
-+ }
-+
-+ read_lock(&tasklist_lock);
-+ while (tmp->pid > 0) {
-+ if (tmp == curtemp)
-+ break;
-+ tmp = tmp->parent;
-+ }
-+ read_unlock(&tasklist_lock);
-+
-+ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
-+ security_alert(GR_PTRACE_ACL_MSG, filp ?
-+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt)
-+ : "(none)", task->comm, task->pid,
-+ DEFAULTSECARGS);
-+ return 1;
-+ }
-+
-+ if (unlikely(!filp))
-+ return 0;
-+
-+ retmode = gr_search_file(filp->f_dentry, GR_PTRACERD | GR_NOPTRACE, filp->f_vfsmnt);
-+
-+ if (retmode & GR_NOPTRACE) {
-+ security_alert(GR_PTRACE_ACL_MSG, gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
-+ task->comm, task->pid, DEFAULTSECARGS);
-+ return 1;
-+ }
-+
-+ if (retmode & GR_PTRACERD) {
-+ switch (request) {
-+ case PTRACE_POKETEXT:
-+ case PTRACE_POKEDATA:
-+ case PTRACE_POKEUSR:
-+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
-+ case PTRACE_SETREGS:
-+ case PTRACE_SETFPREGS:
-+#endif
-+#ifdef CONFIG_X86
-+ case PTRACE_SETFPXREGS:
-+#endif
-+#ifdef CONFIG_ALTIVEC
-+ case PTRACE_SETVRREGS:
-+#endif
-+ return 1;
-+ default:
-+ return 0;
-+ }
-+ } else if (!(current->acl->mode & GR_OVERRIDE) &&
-+ !(current->role->roletype & GR_ROLE_GOD)
-+ && (current->acl != task->acl
-+ || (current->acl != current->role->root_label
-+ && current->pid != task->pid))) {
-+ security_alert(GR_PTRACE_ACL_MSG,
-+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
-+ task->comm, task->pid, DEFAULTSECARGS);
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ __u32 retmode;
-+ struct acl_subject_label *subj;
-+
-+ if (unlikely(!(gr_status & GR_READY)))
-+ return 0;
-+
-+ if (unlikely
-+ ((current->ptrace & PT_PTRACED)
-+ && !(current->acl->mode & GR_OVERRIDE)))
-+ retmode = gr_search_file(dentry, GR_PTRACERD, mnt);
-+ else
-+ return 0;
-+
-+ subj = chk_subj_label(dentry, mnt, current->role);
-+
-+ if (!(retmode & GR_PTRACERD) &&
-+ !(current->role->roletype & GR_ROLE_GOD) &&
-+ (current->acl != subj)) {
-+ security_alert(GR_PTRACE_EXEC_ACL_MSG,
-+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+gr_handle_mmap(const struct file *filp, const unsigned long prot)
-+{
-+ struct acl_object_label *obj, *obj2;
-+
-+ if (unlikely(!(gr_status & GR_READY) ||
-+ (current->acl->mode & GR_OVERRIDE) || !filp ||
-+ !(prot & PROT_EXEC)))
-+ return 0;
-+
-+ if (unlikely(current->is_writable))
-+ return 0;
-+
-+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
-+ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
-+ current->role->root_label);
-+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
-+ security_alert(GR_WRITLIB_ACL_MSG,
-+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
-+ DEFAULTSECARGS);
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
-+{
-+ __u32 mode;
-+
-+ if (unlikely(!file || !(prot & PROT_EXEC)))
-+ return 1;
-+
-+ mode =
-+ gr_search_file(file->f_dentry,
-+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
-+ file->f_vfsmnt);
-+
-+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
-+ security_alert(GR_MMAP_ACL_MSG, "denied",
-+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
-+ DEFAULTSECARGS);
-+ return 0;
-+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
-+ return 0;
-+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
-+ security_audit(GR_MMAP_ACL_MSG, "successful",
-+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
-+ DEFAULTSECARGS);
-+ return 1;
-+ }
-+
-+ return 1;
-+}
-+
-+int
-+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
-+{
-+ __u32 mode;
-+
-+ if (unlikely(!file || !(prot & PROT_EXEC)))
-+ return 1;
-+
-+ mode =
-+ gr_search_file(file->f_dentry,
-+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
-+ file->f_vfsmnt);
-+
-+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
-+ security_alert(GR_MPROTECT_ACL_MSG, "denied",
-+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
-+ DEFAULTSECARGS);
-+ return 0;
-+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
-+ return 0;
-+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
-+ security_audit(GR_MPROTECT_ACL_MSG, "successful",
-+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
-+ DEFAULTSECARGS);
-+ return 1;
-+ }
-+
-+ return 1;
-+}
-+
-+void
-+gr_acl_handle_psacct(struct task_struct *task, const long code)
-+{
-+ u64 runtime64;
-+ unsigned long runtime;
-+ unsigned long cputime;
-+ unsigned int wday, cday;
-+ __u8 whr, chr;
-+ __u8 wmin, cmin;
-+ __u8 wsec, csec;
-+ char cur_tty[64] = { 0 };
-+ char parent_tty[64] = { 0 };
-+
-+ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
-+ !(task->acl->mode & GR_PROCACCT)))
-+ return;
-+
-+ runtime64 = get_jiffies_64() - task->start_time;
-+ do_div(runtime64, HZ);
-+ runtime = (unsigned long)runtime64;
-+ wday = runtime / (3600 * 24);
-+ runtime -= wday * (3600 * 24);
-+ whr = runtime / 3600;
-+ runtime -= whr * 3600;
-+ wmin = runtime / 60;
-+ runtime -= wmin * 60;
-+ wsec = runtime;
-+
-+ cputime = (task->utime + task->stime) / HZ;
-+ cday = cputime / (3600 * 24);
-+ cputime -= cday * (3600 * 24);
-+ chr = cputime / 3600;
-+ cputime -= chr * 3600;
-+ cmin = cputime / 60;
-+ cputime -= cmin * 60;
-+ csec = cputime;
-+
-+ security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
-+ task->pid, NIPQUAD(task->curr_ip), tty_name(task->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",
-+ code, gr_parent_task_fullpath(task),
-+ task->parent->comm, task->parent->pid,
-+ NIPQUAD(task->parent->curr_ip),
-+ tty_name(task->parent->tty, parent_tty),
-+ task->parent->uid, task->parent->euid, task->parent->gid,
-+ task->parent->egid);
-+
-+ return;
-+}
-+
-+EXPORT_SYMBOL(gr_set_kernel_label);
-+
-+void gr_set_kernel_label(struct task_struct *task)
-+{
-+ if (gr_status & GR_READY) {
-+ task->role = kernel_role;
-+ task->acl = kernel_role->root_label;
-+ }
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/gracl_alloc.c linux-2.6.5/grsecurity/gracl_alloc.c
---- linux-2.6.5/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/gracl_alloc.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,93 @@
-+/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
-+
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/gracl.h>
-+#include <linux/grsecurity.h>
-+
-+static unsigned long alloc_stack_next = 1;
-+static unsigned long alloc_stack_size = 1;
-+static void **alloc_stack;
-+
-+static __inline__ int
-+alloc_pop(void)
-+{
-+ if (alloc_stack_next == 1)
-+ return 0;
-+
-+ kfree(alloc_stack[alloc_stack_next - 2]);
-+
-+ alloc_stack_next--;
-+
-+ return 1;
-+}
-+
-+static __inline__ void
-+alloc_push(void *buf)
-+{
-+ if (alloc_stack_next >= alloc_stack_size)
-+ BUG();
-+
-+ alloc_stack[alloc_stack_next - 1] = buf;
-+
-+ alloc_stack_next++;
-+
-+ return;
-+}
-+
-+void *
-+acl_alloc(unsigned long len)
-+{
-+ void *ret;
-+
-+ if (len > PAGE_SIZE)
-+ BUG();
-+
-+ ret = kmalloc(len, GFP_KERNEL);
-+
-+ if (ret)
-+ alloc_push(ret);
-+
-+ return ret;
-+}
-+
-+void
-+acl_free_all(void)
-+{
-+ if (gr_acl_is_enabled() || !alloc_stack)
-+ return;
-+
-+ while (alloc_pop()) ;
-+
-+ if (alloc_stack) {
-+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
-+ kfree(alloc_stack);
-+ else
-+ vfree(alloc_stack);
-+ }
-+
-+ alloc_stack = NULL;
-+ alloc_stack_size = 1;
-+ alloc_stack_next = 1;
-+
-+ return;
-+}
-+
-+int
-+acl_alloc_stack_init(unsigned long size)
-+{
-+ if ((size * sizeof (void *)) <= PAGE_SIZE)
-+ alloc_stack =
-+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
-+ else
-+ alloc_stack = (void **) vmalloc(size * sizeof (void *));
-+
-+ alloc_stack_size = size;
-+
-+ if (!alloc_stack)
-+ return 0;
-+ else
-+ return 1;
-+}
-diff -urN linux-2.6.5/grsecurity/gracl_cap.c linux-2.6.5/grsecurity/gracl_cap.c
---- linux-2.6.5/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/gracl_cap.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,115 @@
-+/* capability handling routines, (c) Brad Spengler 2002,2003 */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/capability.h>
-+#include <linux/gracl.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+static const char *captab_log[29] = {
-+ "CAP_CHOWN",
-+ "CAP_DAC_OVERRIDE",
-+ "CAP_DAC_READ_SEARCH",
-+ "CAP_FOWNER",
-+ "CAP_FSETID",
-+ "CAP_KILL",
-+ "CAP_SETGID",
-+ "CAP_SETUID",
-+ "CAP_SETPCAP",
-+ "CAP_LINUX_IMMUTABLE",
-+ "CAP_NET_BIND_SERVICE",
-+ "CAP_NET_BROADCAST",
-+ "CAP_NET_ADMIN",
-+ "CAP_NET_RAW",
-+ "CAP_IPC_LOCK",
-+ "CAP_IPC_OWNER",
-+ "CAP_SYS_MODULE",
-+ "CAP_SYS_RAWIO",
-+ "CAP_SYS_CHROOT",
-+ "CAP_SYS_PTRACE",
-+ "CAP_SYS_PACCT",
-+ "CAP_SYS_ADMIN",
-+ "CAP_SYS_BOOT",
-+ "CAP_SYS_NICE",
-+ "CAP_SYS_RESOURCE",
-+ "CAP_SYS_TIME",
-+ "CAP_SYS_TTY_CONFIG",
-+ "CAP_MKNOD",
-+ "CAP_LEASE"
-+};
-+
-+EXPORT_SYMBOL(gr_task_is_capable);
-+
-+int
-+gr_task_is_capable(struct task_struct *task, const int cap)
-+{
-+ struct acl_subject_label *curracl;
-+ __u32 cap_drop = 0, cap_mask = 0;
-+
-+ if (!gr_acl_is_enabled())
-+ return 1;
-+
-+ curracl = task->acl;
-+
-+ cap_drop = curracl->cap_lower;
-+ cap_mask = curracl->cap_mask;
-+
-+ while ((curracl = curracl->parent_subject)) {
-+ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
-+ cap_mask |= curracl->cap_mask;
-+ }
-+
-+ if (!cap_raised(cap_drop, cap))
-+ return 1;
-+
-+ curracl = task->acl;
-+
-+ if ((curracl->mode & GR_LEARN)
-+ && cap_raised(task->cap_effective, cap)) {
-+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
-+ task->role->roletype, task->uid,
-+ task->gid, task->exec_file ?
-+ gr_to_filename(task->exec_file->f_dentry,
-+ task->exec_file->f_vfsmnt) : curracl->filename,
-+ curracl->filename, 0UL,
-+ 0UL, "", (unsigned long) cap, NIPQUAD(task->curr_ip));
-+ return 1;
-+ }
-+
-+ if ((cap >= 0) && (cap < 29) && cap_raised(task->cap_effective, cap))
-+ security_alert(GR_CAP_ACL_MSG, captab_log[cap],
-+ 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);
-+
-+ return 0;
-+}
-+
-+int
-+gr_is_capable_nolog(const int cap)
-+{
-+ struct acl_subject_label *curracl;
-+ __u32 cap_drop = 0, cap_mask = 0;
-+
-+ if (!gr_acl_is_enabled())
-+ return 1;
-+
-+ curracl = current->acl;
-+
-+ cap_drop = curracl->cap_lower;
-+ cap_mask = curracl->cap_mask;
-+
-+ while ((curracl = curracl->parent_subject)) {
-+ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
-+ cap_mask |= curracl->cap_mask;
-+ }
-+
-+ if (!cap_raised(cap_drop, cap))
-+ return 1;
-+
-+ return 0;
-+}
-+
-diff -urN linux-2.6.5/grsecurity/gracl_fs.c linux-2.6.5/grsecurity/gracl_fs.c
---- linux-2.6.5/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/gracl_fs.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,460 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/file.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+#include <linux/gracl.h>
-+
-+__u32
-+gr_acl_handle_hidden_file(const struct dentry * dentry,
-+ const struct vfsmount * mnt)
-+{
-+ __u32 mode;
-+
-+ if (unlikely(!dentry->d_inode))
-+ return GR_FIND;
-+
-+ mode =
-+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
-+
-+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
-+ security_audit(GR_HIDDEN_ACL_MSG, "successful",
-+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
-+ return mode;
-+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
-+ security_alert(GR_HIDDEN_ACL_MSG, "denied",
-+ gr_to_filename(dentry, mnt),
-+ DEFAULTSECARGS);
-+ return 0;
-+ } else if (unlikely(!(mode & GR_FIND)))
-+ return 0;
-+
-+ return GR_FIND;
-+}
-+
-+__u32
-+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
-+ const int fmode)
-+{
-+ __u32 reqmode = GR_FIND;
-+ __u32 mode;
-+
-+ if (unlikely(!dentry->d_inode))
-+ return reqmode;
-+
-+ if (unlikely(fmode & O_APPEND))
-+ reqmode |= GR_APPEND;
-+ else if (unlikely(fmode & FMODE_WRITE))
-+ reqmode |= GR_WRITE;
-+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
-+ reqmode |= GR_READ;
-+
-+ mode =
-+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
-+ mnt);
-+
-+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
-+ security_audit(GR_OPEN_ACL_MSG, "successful",
-+ gr_to_filename(dentry, mnt),
-+ reqmode & GR_READ ? " reading" : "",
-+ reqmode & GR_WRITE ? " writing" :
-+ reqmode & GR_APPEND ? " appending" : "",
-+ DEFAULTSECARGS);
-+ return reqmode;
-+ } else
-+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
-+ {
-+ security_alert(GR_OPEN_ACL_MSG, "denied",
-+ gr_to_filename(dentry, mnt),
-+ reqmode & GR_READ ? " reading" : "",
-+ reqmode & GR_WRITE ? " writing" : reqmode &
-+ GR_APPEND ? " appending" : "", DEFAULTSECARGS);
-+ return 0;
-+ } else if (unlikely((mode & reqmode) != reqmode))
-+ return 0;
-+
-+ return reqmode;
-+}
-+
-+__u32
-+gr_acl_handle_creat(const struct dentry * dentry,
-+ const struct dentry * p_dentry,
-+ const struct vfsmount * p_mnt, const int fmode,
-+ const int imode)
-+{
-+ __u32 reqmode = GR_WRITE | GR_CREATE;
-+ __u32 mode;
-+
-+ if (unlikely(fmode & O_APPEND))
-+ reqmode |= GR_APPEND;
-+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
-+ reqmode |= GR_READ;
-+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
-+ reqmode |= GR_SETID;
-+
-+ mode =
-+ gr_check_create(dentry, p_dentry, p_mnt,
-+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
-+
-+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
-+ security_audit(GR_CREATE_ACL_MSG, "successful",
-+ gr_to_filename(dentry, p_mnt),
-+ reqmode & GR_READ ? " reading" : "",
-+ reqmode & GR_WRITE ? " writing" :
-+ reqmode & GR_APPEND ? " appending" : "",
-+ DEFAULTSECARGS);
-+ return reqmode;
-+ } else
-+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
-+ {
-+ security_alert(GR_CREATE_ACL_MSG, "denied",
-+ gr_to_filename(dentry, p_mnt),
-+ reqmode & GR_READ ? " reading" : "",
-+ reqmode & GR_WRITE ? " writing" : reqmode &
-+ GR_APPEND ? " appending" : "", DEFAULTSECARGS);
-+ return 0;
-+ } else if (unlikely((mode & reqmode) != reqmode))
-+ return 0;
-+
-+ return reqmode;
-+}
-+
-+__u32
-+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
-+ const int fmode)
-+{
-+ __u32 mode, reqmode = GR_FIND;
-+
-+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
-+ reqmode |= GR_EXEC;
-+ if (fmode & S_IWOTH)
-+ reqmode |= GR_WRITE;
-+ if (fmode & S_IROTH)
-+ reqmode |= GR_READ;
-+
-+ mode =
-+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
-+ mnt);
-+
-+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
-+ security_audit(GR_ACCESS_ACL_MSG, "successful",
-+ gr_to_filename(dentry, mnt),
-+ reqmode & GR_READ ? " reading" : "",
-+ reqmode & GR_WRITE ? " writing" : "",
-+ reqmode & GR_EXEC ? " executing" : "",
-+ DEFAULTSECARGS);
-+ return reqmode;
-+ } else
-+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
-+ {
-+ security_alert(GR_ACCESS_ACL_MSG, "denied",
-+ gr_to_filename(dentry, mnt),
-+ reqmode & GR_READ ? " reading" : "",
-+ reqmode & GR_WRITE ? " writing" : "",
-+ reqmode & GR_EXEC ? " executing" : "",
-+ DEFAULTSECARGS);
-+ return 0;
-+ } else if (unlikely((mode & reqmode) != reqmode))
-+ return 0;
-+
-+ return reqmode;
-+}
-+
-+#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
-+{ \
-+ __u32 mode; \
-+ \
-+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
-+ \
-+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
-+ security_audit(fmt, "successful", \
-+ gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
-+ return mode; \
-+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
-+ security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
-+ DEFAULTSECARGS); \
-+ return 0; \
-+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \
-+ return 0; \
-+ \
-+ return (reqmode); \
-+}
-+
-+__u32
-+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
-+{
-+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
-+}
-+
-+__u32
-+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
-+}
-+
-+__u32
-+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
-+}
-+
-+__u32
-+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
-+}
-+
-+__u32
-+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
-+ mode_t mode)
-+{
-+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
-+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
-+ GR_FCHMOD_ACL_MSG);
-+ } else {
-+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
-+ }
-+}
-+
-+__u32
-+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
-+ mode_t mode)
-+{
-+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
-+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
-+ GR_CHMOD_ACL_MSG);
-+ } else {
-+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
-+ }
-+}
-+
-+__u32
-+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
-+}
-+
-+__u32
-+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
-+}
-+
-+__u32
-+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
-+ GR_UNIXCONNECT_ACL_MSG);
-+}
-+
-+__u32
-+gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
-+ const ino_t ino)
-+{
-+ if (likely((unsigned long)(dentry->d_inode))) {
-+ struct dentry d = *dentry;
-+ struct inode inode = *(dentry->d_inode);
-+
-+ inode.i_ino = ino;
-+ d.d_inode = &inode;
-+
-+ if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+__u32
-+gr_acl_handle_link(const struct dentry * new_dentry,
-+ const struct dentry * parent_dentry,
-+ const struct vfsmount * parent_mnt,
-+ const struct dentry * old_dentry,
-+ const struct vfsmount * old_mnt, const char *to)
-+{
-+ __u32 needmode = GR_WRITE | GR_CREATE;
-+ __u32 mode;
-+
-+ mode =
-+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
-+ old_mnt);
-+
-+ if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
-+ security_audit(GR_LINK_ACL_MSG, "successful",
-+ gr_to_filename(old_dentry, old_mnt), to,
-+ DEFAULTSECARGS);
-+ return mode;
-+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
-+ security_alert(GR_LINK_ACL_MSG, "denied",
-+ gr_to_filename(old_dentry, old_mnt), to,
-+ DEFAULTSECARGS);
-+ return 0;
-+ } else if (unlikely((mode & needmode) != needmode))
-+ return 0;
-+
-+ return (GR_WRITE | GR_CREATE);
-+}
-+
-+__u32
-+gr_acl_handle_symlink(const struct dentry * new_dentry,
-+ const struct dentry * parent_dentry,
-+ const struct vfsmount * parent_mnt, const char *from)
-+{
-+ __u32 needmode = GR_WRITE | GR_CREATE;
-+ __u32 mode;
-+
-+ mode =
-+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
-+ GR_CREATE | GR_AUDIT_CREATE |
-+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
-+
-+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
-+ security_audit(GR_SYMLINK_ACL_MSG, "successful",
-+ from, gr_to_filename(new_dentry, parent_mnt),
-+ DEFAULTSECARGS);
-+ return mode;
-+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
-+ security_alert(GR_SYMLINK_ACL_MSG, "denied",
-+ from, gr_to_filename(new_dentry, parent_mnt),
-+ DEFAULTSECARGS);
-+ return 0;
-+ } else if (unlikely((mode & needmode) != needmode))
-+ return 0;
-+
-+ return (GR_WRITE | GR_CREATE);
-+}
-+
-+#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
-+{ \
-+ __u32 mode; \
-+ \
-+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
-+ \
-+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
-+ security_audit(fmt, "successful", \
-+ gr_to_filename(new_dentry, parent_mnt), \
-+ DEFAULTSECARGS); \
-+ return mode; \
-+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
-+ security_alert(fmt, "denied", \
-+ gr_to_filename(new_dentry, parent_mnt), \
-+ DEFAULTSECARGS); \
-+ return 0; \
-+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \
-+ return 0; \
-+ \
-+ return (reqmode); \
-+}
-+
-+__u32
-+gr_acl_handle_mknod(const struct dentry * new_dentry,
-+ const struct dentry * parent_dentry,
-+ const struct vfsmount * parent_mnt,
-+ const int mode)
-+{
-+ __u32 reqmode = GR_WRITE | GR_CREATE;
-+ if (unlikely(mode & (S_ISUID | S_ISGID)))
-+ reqmode |= GR_SETID;
-+
-+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
-+ reqmode, GR_MKNOD_ACL_MSG);
-+}
-+
-+__u32
-+gr_acl_handle_mkdir(const struct dentry *new_dentry,
-+ const struct dentry *parent_dentry,
-+ const struct vfsmount *parent_mnt)
-+{
-+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
-+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
-+}
-+
-+#define RENAME_CHECK_SUCCESS(old, new) \
-+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
-+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
-+
-+int
-+gr_acl_handle_rename(struct dentry *new_dentry,
-+ struct dentry *parent_dentry,
-+ const struct vfsmount *parent_mnt,
-+ struct dentry *old_dentry,
-+ struct inode *old_parent_inode,
-+ struct vfsmount *old_mnt, const char *newname)
-+{
-+ __u32 comp1, comp2;
-+ int error = 0;
-+
-+ if (unlikely(!gr_acl_is_enabled()))
-+ return 0;
-+
-+ if (!new_dentry->d_inode) {
-+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
-+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
-+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
-+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
-+ GR_DELETE | GR_AUDIT_DELETE |
-+ GR_AUDIT_READ | GR_AUDIT_WRITE |
-+ GR_SUPPRESS, old_mnt);
-+ } else {
-+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
-+ GR_CREATE | GR_DELETE |
-+ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
-+ GR_AUDIT_READ | GR_AUDIT_WRITE |
-+ GR_SUPPRESS, parent_mnt);
-+ comp2 =
-+ gr_search_file(old_dentry,
-+ GR_READ | GR_WRITE | GR_AUDIT_READ |
-+ GR_DELETE | GR_AUDIT_DELETE |
-+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
-+ }
-+
-+ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
-+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
-+ security_audit(GR_RENAME_ACL_MSG, "successful",
-+ gr_to_filename(old_dentry, old_mnt),
-+ newname, DEFAULTSECARGS);
-+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
-+ && !(comp2 & GR_SUPPRESS)) {
-+ security_alert(GR_RENAME_ACL_MSG, "denied",
-+ gr_to_filename(old_dentry, old_mnt), newname,
-+ DEFAULTSECARGS);
-+ error = -EACCES;
-+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
-+ error = -EACCES;
-+
-+ return error;
-+}
-+
-+void
-+gr_acl_handle_exit(void)
-+{
-+ u16 id;
-+ char *rolename;
-+
-+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
-+ id = current->acl_role_id;
-+ rolename = current->role->rolename;
-+ gr_set_acls(1);
-+ security_alert_good(GR_SPROLEL_ACL_MSG,
-+ rolename, id, DEFAULTSECARGS);
-+ }
-+
-+ if (current->exec_file) {
-+ fput(current->exec_file);
-+ current->exec_file = NULL;
-+ }
-+}
-+
-+int
-+gr_acl_handle_procpidmem(const struct task_struct *task)
-+{
-+ if (unlikely(!gr_acl_is_enabled()))
-+ return 0;
-+
-+ if (task->acl->mode & GR_PROTPROCFD)
-+ return -EACCES;
-+
-+ return 0;
-+}
-diff -urN linux-2.6.5/grsecurity/gracl_ip.c linux-2.6.5/grsecurity/gracl_ip.c
---- linux-2.6.5/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/gracl_ip.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,236 @@
-+/*
-+ * grsecurity/gracl_ip.c
-+ * Copyright Brad Spengler 2002, 2003
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <asm/uaccess.h>
-+#include <asm/errno.h>
-+#include <net/sock.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
-+#include <linux/net.h>
-+#include <linux/in.h>
-+#include <linux/skbuff.h>
-+#include <linux/ip.h>
-+#include <linux/udp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/gracl.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+#define GR_BIND 0x01
-+#define GR_CONNECT 0x02
-+
-+static const char * gr_protocols[256] = {
-+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
-+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
-+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
-+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
-+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
-+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
-+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
-+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
-+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
-+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
-+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
-+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
-+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
-+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
-+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
-+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
-+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
-+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
-+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
-+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
-+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
-+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
-+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
-+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
-+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
-+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
-+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
-+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
-+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
-+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
-+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
-+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
-+ };
-+
-+static const char * gr_socktypes[11] = {
-+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
-+ "unknown:7", "unknown:8", "unknown:9", "packet"
-+ };
-+
-+__inline__ const char *
-+gr_proto_to_name(unsigned char proto)
-+{
-+ return gr_protocols[proto];
-+}
-+
-+__inline__ const char *
-+gr_socktype_to_name(unsigned char type)
-+{
-+ return gr_socktypes[type];
-+}
-+
-+int
-+gr_search_socket(const int domain, const int type, const int protocol)
-+{
-+ struct acl_subject_label *curr;
-+
-+ if (unlikely(!gr_acl_is_enabled()))
-+ goto exit;
-+
-+ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
-+ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
-+ goto exit; // let the kernel handle it
-+
-+ curr = current->acl;
-+
-+ if (!curr->ips)
-+ goto exit;
-+
-+ if ((curr->ip_type & (1 << type)) &&
-+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
-+ goto exit;
-+
-+ if (curr->mode & GR_LEARN) {
-+ /* we don't place acls on raw sockets , and sometimes
-+ dgram/ip sockets are opened for ioctl and not
-+ bind/connect, so we'll fake a bind learn log */
-+ if (type == SOCK_RAW || type == SOCK_PACKET) {
-+ __u32 fakeip = 0;
-+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
-+ current->role->roletype, current->uid,
-+ current->gid, current->exec_file ?
-+ gr_to_filename(current->exec_file->f_dentry,
-+ current->exec_file->f_vfsmnt) :
-+ curr->filename, curr->filename,
-+ NIPQUAD(fakeip), 0, type,
-+ protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
-+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
-+ __u32 fakeip = 0;
-+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
-+ current->role->roletype, current->uid,
-+ current->gid, current->exec_file ?
-+ gr_to_filename(current->exec_file->f_dentry,
-+ current->exec_file->f_vfsmnt) :
-+ curr->filename, curr->filename,
-+ NIPQUAD(fakeip), 0, type,
-+ protocol, GR_BIND, NIPQUAD(current->curr_ip));
-+ }
-+ /* we'll log when they use connect or bind */
-+ goto exit;
-+ }
-+
-+ security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
-+ gr_proto_to_name(protocol), DEFAULTSECARGS);
-+
-+ return 0;
-+ exit:
-+ return 1;
-+}
-+
-+static __inline__ int
-+gr_search_connectbind(const int mode, const struct sock *sk,
-+ const struct sockaddr_in *addr, const int type)
-+{
-+ struct acl_subject_label *curr;
-+ struct acl_ip_label *ip;
-+ unsigned long i;
-+ __u32 ip_addr = 0;
-+ __u16 ip_port = 0;
-+
-+ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
-+ return 1;
-+
-+ curr = current->acl;
-+
-+ if (!curr->ips)
-+ return 1;
-+
-+ ip_addr = addr->sin_addr.s_addr;
-+ ip_port = ntohs(addr->sin_port);
-+
-+ for (i = 0; i < curr->ip_num; i++) {
-+ ip = *(curr->ips + i);
-+ if ((ip->mode & mode) &&
-+ (ip_port >= ip->low) &&
-+ (ip_port <= ip->high) &&
-+ ((ntohl(ip_addr) & ip->netmask) ==
-+ (ntohl(ip->addr) & ip->netmask))
-+ && (ip->
-+ proto[sk->sk_protocol / 32] & (1 << (sk->sk_protocol % 32)))
-+ && (ip->type & (1 << type)))
-+ return 1;
-+ }
-+
-+ if (curr->mode & GR_LEARN) {
-+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
-+ current->role->roletype, current->uid,
-+ current->gid, current->exec_file ?
-+ gr_to_filename(current->exec_file->f_dentry,
-+ current->exec_file->f_vfsmnt) :
-+ curr->filename, curr->filename,
-+ NIPQUAD(ip_addr), ip_port, type,
-+ sk->sk_protocol, mode, NIPQUAD(current->curr_ip));
-+ return 1;
-+ }
-+
-+ if (mode == GR_BIND)
-+ security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
-+ gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol),
-+ DEFAULTSECARGS);
-+ else if (mode == GR_CONNECT)
-+ security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
-+ gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol),
-+ DEFAULTSECARGS);
-+
-+ return 0;
-+}
-+
-+int
-+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
-+{
-+ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
-+}
-+
-+int
-+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
-+{
-+ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
-+}
-+
-+int
-+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
-+{
-+ if (addr)
-+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
-+ else {
-+ struct sockaddr_in sin;
-+ const struct inet_opt *inet = inet_sk(sk);
-+
-+ sin.sin_addr.s_addr = inet->daddr;
-+ sin.sin_port = inet->dport;
-+
-+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
-+ }
-+}
-+
-+int
-+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
-+{
-+ struct sockaddr_in sin;
-+
-+ if (unlikely(skb->len < sizeof (struct udphdr)))
-+ return 1; // skip this packet
-+
-+ sin.sin_addr.s_addr = skb->nh.iph->saddr;
-+ sin.sin_port = skb->h.uh->source;
-+
-+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
-+}
-diff -urN linux-2.6.5/grsecurity/gracl_learn.c linux-2.6.5/grsecurity/gracl_learn.c
---- linux-2.6.5/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/gracl_learn.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,204 @@
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/sched.h>
-+#include <linux/poll.h>
-+#include <linux/smp_lock.h>
-+#include <linux/string.h>
-+#include <linux/file.h>
-+#include <linux/types.h>
-+#include <linux/vmalloc.h>
-+#include <linux/grinternal.h>
-+
-+extern ssize_t write_grsec_handler(struct file * file, const char * buf,
-+ size_t count, loff_t *ppos);
-+extern int gr_acl_is_enabled(void);
-+
-+static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
-+static int gr_learn_attached;
-+
-+/* use a 512k buffer */
-+#define LEARN_BUFFER_SIZE (512 * 1024)
-+
-+static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
-+static DECLARE_MUTEX(gr_learn_user_sem);
-+
-+/* we need to maintain two buffers, so that the kernel context of grlearn
-+ uses a semaphore around the userspace copying, and the other kernel contexts
-+ use a spinlock when copying into the buffer, since they cannot sleep
-+*/
-+static char *learn_buffer;
-+static char *learn_buffer_user;
-+static int learn_buffer_len;
-+static int learn_buffer_user_len;
-+
-+static ssize_t
-+read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ ssize_t retval = 0;
-+
-+ add_wait_queue(&learn_wait, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ do {
-+ down(&gr_learn_user_sem);
-+ spin_lock(&gr_learn_lock);
-+ if (learn_buffer_len)
-+ break;
-+ spin_unlock(&gr_learn_lock);
-+ up(&gr_learn_user_sem);
-+ if (file->f_flags & O_NONBLOCK) {
-+ retval = -EAGAIN;
-+ goto out;
-+ }
-+ if (signal_pending(current)) {
-+ retval = -ERESTARTSYS;
-+ goto out;
-+ }
-+
-+ schedule();
-+ } while (1);
-+
-+ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
-+ learn_buffer_user_len = learn_buffer_len;
-+ retval = learn_buffer_len;
-+ learn_buffer_len = 0;
-+
-+ spin_unlock(&gr_learn_lock);
-+
-+ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
-+ retval = -EFAULT;
-+
-+ up(&gr_learn_user_sem);
-+out:
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&learn_wait, &wait);
-+ return retval;
-+}
-+
-+static unsigned int
-+poll_learn(struct file * file, poll_table * wait)
-+{
-+ poll_wait(file, &learn_wait, wait);
-+
-+ if (learn_buffer_len)
-+ return (POLLIN | POLLRDNORM);
-+
-+ return 0;
-+}
-+
-+void
-+gr_clear_learn_entries(void)
-+{
-+ char *tmp;
-+
-+ down(&gr_learn_user_sem);
-+ if (learn_buffer != NULL) {
-+ spin_lock(&gr_learn_lock);
-+ tmp = learn_buffer;
-+ learn_buffer = NULL;
-+ spin_unlock(&gr_learn_lock);
-+ vfree(learn_buffer);
-+ }
-+ if (learn_buffer_user != NULL) {
-+ vfree(learn_buffer_user);
-+ learn_buffer_user = NULL;
-+ }
-+ learn_buffer_len = 0;
-+ up(&gr_learn_user_sem);
-+
-+ return;
-+}
-+
-+void
-+gr_add_learn_entry(const char *fmt, ...)
-+{
-+ va_list args;
-+ unsigned int len;
-+
-+ if (!gr_learn_attached)
-+ return;
-+
-+ spin_lock(&gr_learn_lock);
-+
-+ /* leave a gap at the end so we know when it's "full" but don't have to
-+ compute the exact length of the string we're trying to append
-+ */
-+ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
-+ spin_unlock(&gr_learn_lock);
-+ wake_up_interruptible(&learn_wait);
-+ return;
-+ }
-+ if (learn_buffer == NULL) {
-+ spin_unlock(&gr_learn_lock);
-+ return;
-+ }
-+
-+ va_start(args, fmt);
-+ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
-+ va_end(args);
-+
-+ learn_buffer_len += len + 1;
-+
-+ spin_unlock(&gr_learn_lock);
-+ wake_up_interruptible(&learn_wait);
-+
-+ return;
-+}
-+
-+static int
-+open_learn(struct inode *inode, struct file *file)
-+{
-+ if (file->f_mode & FMODE_READ && gr_learn_attached)
-+ return -EBUSY;
-+ if (file->f_mode & FMODE_READ) {
-+ down(&gr_learn_user_sem);
-+ if (learn_buffer == NULL)
-+ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
-+ if (learn_buffer_user == NULL)
-+ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
-+ if (learn_buffer == NULL)
-+ return -ENOMEM;
-+ if (learn_buffer_user == NULL)
-+ return -ENOMEM;
-+ learn_buffer_len = 0;
-+ learn_buffer_user_len = 0;
-+ gr_learn_attached = 1;
-+ up(&gr_learn_user_sem);
-+ }
-+ return 0;
-+}
-+
-+static int
-+close_learn(struct inode *inode, struct file *file)
-+{
-+ char *tmp;
-+
-+ if (file->f_mode & FMODE_READ) {
-+ down(&gr_learn_user_sem);
-+ if (learn_buffer != NULL) {
-+ spin_lock(&gr_learn_lock);
-+ tmp = learn_buffer;
-+ learn_buffer = NULL;
-+ spin_unlock(&gr_learn_lock);
-+ vfree(tmp);
-+ }
-+ if (learn_buffer_user != NULL) {
-+ vfree(learn_buffer_user);
-+ learn_buffer_user = NULL;
-+ }
-+ learn_buffer_len = 0;
-+ learn_buffer_user_len = 0;
-+ gr_learn_attached = 0;
-+ up(&gr_learn_user_sem);
-+ }
-+
-+ return 0;
-+}
-+
-+struct file_operations grsec_fops = {
-+ read: read_learn,
-+ write: write_grsec_handler,
-+ open: open_learn,
-+ release: close_learn,
-+ poll: poll_learn,
-+};
-diff -urN linux-2.6.5/grsecurity/gracl_res.c linux-2.6.5/grsecurity/gracl_res.c
---- linux-2.6.5/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/gracl_res.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,50 @@
-+/* resource handling routines (c) Brad Spengler 2002, 2003 */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/gracl.h>
-+#include <linux/grinternal.h>
-+
-+static const char *restab_log[11] = {
-+ "RLIMIT_CPU",
-+ "RLIMIT_FSIZE",
-+ "RLIMIT_DATA",
-+ "RLIMIT_STACK",
-+ "RLIMIT_CORE",
-+ "RLIMIT_RSS",
-+ "RLIMIT_NPROC",
-+ "RLIMIT_NOFILE",
-+ "RLIMIT_MEMLOCK",
-+ "RLIMIT_AS",
-+ "RLIMIT_LOCKS"
-+};
-+
-+__inline__ void
-+gr_log_resource(const struct task_struct *task,
-+ const int res, const unsigned long wanted, const int gt)
-+{
-+ if (unlikely(res == RLIMIT_NPROC &&
-+ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
-+ cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
-+ return;
-+
-+ preempt_disable();
-+
-+ if (unlikely(((gt && wanted > task->rlim[res].rlim_cur) ||
-+ (!gt && wanted >= task->rlim[res].rlim_cur)) &&
-+ task->rlim[res].rlim_cur != RLIM_INFINITY))
-+ security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
-+ task->rlim[res].rlim_cur,
-+ 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);
-+
-+ preempt_enable_no_resched();
-+
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/gracl_segv.c linux-2.6.5/grsecurity/gracl_segv.c
---- linux-2.6.5/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/gracl_segv.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,330 @@
-+/*
-+ * grsecurity/gracl_segv.c
-+ * Copyright Brad Spengler 2002, 2003
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <asm/uaccess.h>
-+#include <asm/errno.h>
-+#include <asm/mman.h>
-+#include <net/sock.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
-+#include <linux/net.h>
-+#include <linux/in.h>
-+#include <linux/smp_lock.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/gracl.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+static struct crash_uid *uid_set;
-+static unsigned short uid_used;
-+static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
-+extern rwlock_t gr_inode_lock;
-+extern struct acl_subject_label *
-+ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
-+ struct acl_role_label *role);
-+extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
-+
-+int
-+gr_init_uidset(void)
-+{
-+ uid_set =
-+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
-+ uid_used = 0;
-+
-+ return uid_set ? 1 : 0;
-+}
-+
-+void
-+gr_free_uidset(void)
-+{
-+ if (uid_set)
-+ kfree(uid_set);
-+
-+ return;
-+}
-+
-+int
-+gr_find_uid(const uid_t uid)
-+{
-+ struct crash_uid *tmp = uid_set;
-+ uid_t buid;
-+ int low = 0, high = uid_used - 1, mid;
-+
-+ while (high >= low) {
-+ mid = (low + high) >> 1;
-+ buid = tmp[mid].uid;
-+ if (buid == uid)
-+ return mid;
-+ if (buid > uid)
-+ high = mid - 1;
-+ if (buid < uid)
-+ low = mid + 1;
-+ }
-+
-+ return -1;
-+}
-+
-+static __inline__ void
-+gr_insertsort(void)
-+{
-+ unsigned short i, j;
-+ struct crash_uid index;
-+
-+ for (i = 1; i < uid_used; i++) {
-+ index = uid_set[i];
-+ j = i;
-+ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
-+ uid_set[j] = uid_set[j - 1];
-+ j--;
-+ }
-+ uid_set[j] = index;
-+ }
-+
-+ return;
-+}
-+
-+static __inline__ void
-+gr_insert_uid(const uid_t uid, const unsigned long expires)
-+{
-+ int loc;
-+
-+ if (uid_used == GR_UIDTABLE_MAX)
-+ return;
-+
-+ loc = gr_find_uid(uid);
-+
-+ if (loc >= 0) {
-+ uid_set[loc].expires = expires;
-+ return;
-+ }
-+
-+ uid_set[uid_used].uid = uid;
-+ uid_set[uid_used].expires = expires;
-+ uid_used++;
-+
-+ gr_insertsort();
-+
-+ return;
-+}
-+
-+void
-+gr_remove_uid(const unsigned short loc)
-+{
-+ unsigned short i;
-+
-+ for (i = loc + 1; i < uid_used; i++)
-+ uid_set[i - i] = uid_set[i];
-+
-+ uid_used--;
-+
-+ return;
-+}
-+
-+int
-+gr_check_crash_uid(const uid_t uid)
-+{
-+ int loc;
-+
-+ if (unlikely(!gr_acl_is_enabled()))
-+ return 0;
-+
-+ read_lock(&gr_uid_lock);
-+ loc = gr_find_uid(uid);
-+ read_unlock(&gr_uid_lock);
-+
-+ if (loc < 0)
-+ return 0;
-+
-+ write_lock(&gr_uid_lock);
-+ if (time_before_eq(uid_set[loc].expires, get_seconds()))
-+ gr_remove_uid(loc);
-+ else {
-+ write_unlock(&gr_uid_lock);
-+ return 1;
-+ }
-+
-+ write_unlock(&gr_uid_lock);
-+ return 0;
-+}
-+
-+static __inline__ int
-+proc_is_setxid(const struct task_struct *task)
-+{
-+ if (task->uid != task->euid || task->uid != task->suid ||
-+ task->uid != task->fsuid)
-+ return 1;
-+ if (task->gid != task->egid || task->gid != task->sgid ||
-+ task->gid != task->fsgid)
-+ return 1;
-+
-+ return 0;
-+}
-+static __inline__ int
-+gr_fake_force_sig(int sig, struct task_struct *t)
-+{
-+ unsigned long int flags;
-+ int ret;
-+
-+ spin_lock_irqsave(&t->sighand->siglock, flags);
-+ if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
-+ t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
-+ sigdelset(&t->blocked, sig);
-+ recalc_sigpending_tsk(t);
-+ }
-+ ret = specific_send_sig_info(sig, (void*)1L, t);
-+ spin_unlock_irqrestore(&t->sighand->siglock, flags);
-+
-+ return ret;
-+}
-+
-+void
-+gr_handle_crash(struct task_struct *task, const int sig)
-+{
-+ struct acl_subject_label *curr;
-+ struct acl_subject_label *curr2;
-+ struct task_struct *tsk, *tsk2;
-+
-+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
-+ return;
-+
-+ if (unlikely(!gr_acl_is_enabled()))
-+ return;
-+
-+ curr = task->acl;
-+
-+ if (!(curr->resmask & (1 << GR_CRASH_RES)))
-+ return;
-+
-+ if (time_before_eq(curr->expires, get_seconds())) {
-+ curr->expires = 0;
-+ curr->crashes = 0;
-+ }
-+
-+ curr->crashes++;
-+
-+ if (!curr->expires)
-+ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
-+
-+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
-+ time_after(curr->expires, get_seconds())) {
-+ if (task->uid && proc_is_setxid(task)) {
-+ security_alert(GR_SEGVSTART_ACL_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,
-+ curr->res[GR_CRASH_RES].rlim_max);
-+ write_lock(&gr_uid_lock);
-+ gr_insert_uid(task->uid, curr->expires);
-+ write_unlock(&gr_uid_lock);
-+ curr->expires = 0;
-+ curr->crashes = 0;
-+ read_lock(&tasklist_lock);
-+ for_each_process(tsk) {
-+ tsk2 = tsk;
-+ do {
-+ if (tsk2 != task && tsk2->uid == task->uid)
-+ gr_fake_force_sig(SIGKILL, tsk2);
-+ } while ((tsk2 = next_thread(tsk2)) != tsk);
-+ }
-+ read_unlock(&tasklist_lock);
-+ } else {
-+ security_alert(GR_SEGVNOSUID_ACL_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,
-+ curr->res[GR_CRASH_RES].rlim_max);
-+ read_lock(&tasklist_lock);
-+ for_each_process(tsk) {
-+ tsk2 = tsk;
-+ do {
-+ if (likely(tsk2 != task)) {
-+ curr2 = tsk2->acl;
-+
-+ if (curr2->device == curr->device &&
-+ curr2->inode == curr->inode)
-+ gr_fake_force_sig(SIGKILL, tsk2);
-+ }
-+ } while ((tsk2 = next_thread(tsk2)) != tsk);
-+ }
-+ read_unlock(&tasklist_lock);
-+ }
-+ }
-+
-+ return;
-+}
-+
-+int
-+gr_check_crash_exec(const struct file *filp)
-+{
-+ struct acl_subject_label *curr;
-+
-+ if (unlikely(!gr_acl_is_enabled()))
-+ return 0;
-+
-+ read_lock(&gr_inode_lock);
-+ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
-+ filp->f_dentry->d_inode->i_sb->s_dev,
-+ current->role);
-+ read_unlock(&gr_inode_lock);
-+
-+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
-+ (!curr->crashes && !curr->expires))
-+ return 0;
-+
-+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
-+ time_after(curr->expires, get_seconds()))
-+ return 1;
-+ else if (time_before_eq(curr->expires, get_seconds())) {
-+ curr->crashes = 0;
-+ curr->expires = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+void
-+gr_handle_alertkill(void)
-+{
-+ struct acl_subject_label *curracl;
-+ __u32 curr_ip;
-+ struct task_struct *task, *task2;
-+
-+ if (unlikely(!gr_acl_is_enabled()))
-+ return;
-+
-+ curracl = current->acl;
-+ curr_ip = current->curr_ip;
-+
-+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
-+ (curr_ip != 0xffffffff)) {
-+ read_lock(&tasklist_lock);
-+ for_each_process(task) {
-+ task2 = task;
-+ do {
-+ if (task2->curr_ip == curr_ip)
-+ gr_fake_force_sig(SIGKILL, task2);
-+ } while ((task2 = next_thread(task2)) != task);
-+ }
-+ read_unlock(&tasklist_lock);
-+ } else if (curracl->mode & GR_KILLPROC)
-+ gr_fake_force_sig(SIGKILL, current);
-+
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/gracl_shm.c linux-2.6.5/grsecurity/gracl_shm.c
---- linux-2.6.5/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/gracl_shm.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,36 @@
-+/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
-+
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/sched.h>
-+#include <linux/file.h>
-+#include <linux/ipc.h>
-+#include <linux/gracl.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+int
-+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
-+ const time_t shm_createtime, const uid_t cuid, const int shmid)
-+{
-+ struct task_struct *task;
-+
-+ if (!gr_acl_is_enabled())
-+ return 1;
-+
-+ task = find_task_by_pid(shm_cprid);
-+
-+ if (unlikely(!task))
-+ task = find_task_by_pid(shm_lapid);
-+
-+ if (unlikely(task && ((task->start_time < shm_createtime) ||
-+ (task->pid == shm_lapid)) &&
-+ (task->acl->mode & GR_PROTSHM) &&
-+ (task->acl != current->acl))) {
-+ security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
-+ DEFAULTSECARGS);
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_chdir.c linux-2.6.5/grsecurity/grsec_chdir.c
---- linux-2.6.5/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_chdir.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,20 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/file.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+void
-+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
-+ if ((grsec_enable_chdir && grsec_enable_group &&
-+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
-+ !grsec_enable_group)) {
-+ security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
-+ DEFAULTSECARGS);
-+ }
-+#endif
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_chroot.c linux-2.6.5/grsecurity/grsec_chroot.c
---- linux-2.6.5/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_chroot.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,348 @@
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
-+#include <linux/mount.h>
-+#include <linux/types.h>
-+#include <linux/grinternal.h>
-+
-+int
-+gr_handle_chroot_unix(const pid_t pid)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
-+ struct pid *spid = NULL;
-+
-+ if (unlikely(!grsec_enable_chroot_unix))
-+ return 1;
-+
-+ if (likely(!proc_is_chrooted(current)))
-+ return 1;
-+
-+ read_lock(&tasklist_lock);
-+
-+ spid = find_pid(PIDTYPE_PID, pid);
-+ if (spid) {
-+ struct task_struct *p;
-+ p = pid_task(spid->task_list.next, PIDTYPE_PID);
-+ if (unlikely(!have_same_root(current, p))) {
-+ read_unlock(&tasklist_lock);
-+ security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
-+ return 0;
-+ }
-+ }
-+ read_unlock(&tasklist_lock);
-+#endif
-+ return 1;
-+}
-+
-+int
-+gr_handle_chroot_nice(void)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
-+ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
-+ security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
-+ return -EPERM;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
-+ if (grsec_enable_chroot_nice && (!have_same_root(p, current)
-+ || (have_same_root(p, current)
-+ && (niceval < task_nice(p))
-+ && proc_is_chrooted(current)))) {
-+ security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
-+ DEFAULTSECARGS);
-+ return -ESRCH;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_handle_chroot_capset(const struct task_struct *target)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
-+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
-+ !have_same_root(current, target)) {
-+ security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
-+ DEFAULTSECARGS);
-+ return 1;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_handle_chroot_rawio(const struct inode *inode)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
-+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
-+ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
-+ return 1;
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_pid_is_chrooted(const struct task_struct *p)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
-+ if (!grsec_enable_chroot_findtask || (current->pid <= 1))
-+ return 0;
-+
-+ if (p && p->fs && p->fs->root && p->fs->root->d_inode &&
-+ child_reaper && child_reaper->fs && child_reaper->fs->root &&
-+ child_reaper->fs->root->d_inode && current && current->fs &&
-+ current->fs->root && current->fs->root->d_inode) {
-+ if (proc_is_chrooted(current) && !have_same_root(current, p))
-+ return 1;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(gr_pid_is_chrooted);
-+
-+#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
-+int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
-+{
-+ struct dentry *dentry = (struct dentry *)u_dentry;
-+ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
-+ struct dentry *realroot;
-+ struct vfsmount *realrootmnt;
-+ struct dentry *currentroot;
-+ struct vfsmount *currentmnt;
-+
-+ read_lock(&child_reaper->fs->lock);
-+ realrootmnt = mntget(child_reaper->fs->rootmnt);
-+ realroot = dget(child_reaper->fs->root);
-+ read_unlock(&child_reaper->fs->lock);
-+
-+ read_lock(&current->fs->lock);
-+ currentmnt = mntget(current->fs->rootmnt);
-+ currentroot = dget(current->fs->root);
-+ read_unlock(&current->fs->lock);
-+
-+ spin_lock(&dcache_lock);
-+ for (;;) {
-+ if (unlikely((dentry == realroot && mnt == realrootmnt)
-+ || (dentry == currentroot && mnt == currentmnt)))
-+ break;
-+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
-+ if (mnt->mnt_parent == mnt)
-+ break;
-+ dentry = mnt->mnt_mountpoint;
-+ mnt = mnt->mnt_parent;
-+ continue;
-+ }
-+ dentry = dentry->d_parent;
-+ }
-+ spin_unlock(&dcache_lock);
-+
-+ dput(currentroot);
-+ mntput(currentmnt);
-+
-+ if (dentry == realroot && mnt == realrootmnt) {
-+ /* access is outside of chroot */
-+ dput(realroot);
-+ mntput(realrootmnt);
-+ return 0;
-+ }
-+
-+ dput(realroot);
-+ mntput(realrootmnt);
-+ return 1;
-+}
-+#endif
-+
-+int
-+gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
-+ if (!grsec_enable_chroot_fchdir)
-+ return 1;
-+
-+ if (!proc_is_chrooted(current))
-+ return 1;
-+ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
-+ security_alert(GR_CHROOT_FCHDIR_MSG,
-+ gr_to_filename(u_dentry, u_mnt),
-+ DEFAULTSECARGS);
-+ return 0;
-+ }
-+#endif
-+ return 1;
-+}
-+
-+int
-+gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
-+ const time_t shm_createtime)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
-+ struct pid *pid = NULL;
-+ u64 starttime64;
-+ time_t starttime;
-+
-+ if (unlikely(!grsec_enable_chroot_shmat))
-+ return 1;
-+
-+ if (likely(!proc_is_chrooted(current)))
-+ return 1;
-+
-+ read_lock(&tasklist_lock);
-+
-+ pid = find_pid(PIDTYPE_PID, shm_cprid);
-+ if (pid) {
-+ struct task_struct *p;
-+ p = pid_task(pid->task_list.next, PIDTYPE_PID);
-+ starttime64 = p->start_time;
-+ do_div(starttime64, HZ);
-+ starttime = (time_t) starttime64;
-+ if (unlikely(!have_same_root(current, p) &&
-+ time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
-+ read_unlock(&tasklist_lock);
-+ security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
-+ return 0;
-+ }
-+ } else {
-+ pid = find_pid(PIDTYPE_PID, shm_lapid);
-+ if (pid) {
-+ struct task_struct *p;
-+ p = pid_task(pid->task_list.next, PIDTYPE_PID);
-+ if (unlikely(!have_same_root(current, p))) {
-+ read_unlock(&tasklist_lock);
-+ security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
-+ return 0;
-+ }
-+ }
-+ }
-+
-+ read_unlock(&tasklist_lock);
-+#endif
-+ return 1;
-+}
-+
-+void
-+gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
-+ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
-+ security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
-+ DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-+
-+int
-+gr_handle_chroot_mknod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, const int mode)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
-+ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
-+ proc_is_chrooted(current)) {
-+ security_alert(GR_MKNOD_CHROOT_MSG,
-+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
-+ return -EPERM;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_handle_chroot_mount(const struct dentry *dentry,
-+ const struct vfsmount *mnt, const char *dev_name)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
-+ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
-+ security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
-+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
-+ return -EPERM;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_handle_chroot_pivot(void)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
-+ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
-+ security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
-+ return -EPERM;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
-+ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
-+ !gr_is_outside_chroot(dentry, mnt)) {
-+ security_alert(GR_CHROOT_CHROOT_MSG,
-+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
-+ return -EPERM;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+void
-+gr_handle_chroot_caps(struct task_struct *task)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
-+ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
-+ task->cap_permitted =
-+ cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
-+ task->cap_inheritable =
-+ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
-+ task->cap_effective =
-+ cap_drop(task->cap_effective, GR_CHROOT_CAPS);
-+ }
-+#endif
-+ return;
-+}
-+
-+int
-+gr_handle_chroot_sysctl(const int op)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
-+ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
-+ && (op & 002))
-+ return -EACCES;
-+#endif
-+ return 0;
-+}
-+
-+void
-+gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
-+ if (grsec_enable_chroot_chdir)
-+ set_fs_pwd(current->fs, mnt, dentry);
-+#endif
-+ return;
-+}
-+
-+int
-+gr_handle_chroot_chmod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, const int mode)
-+{
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
-+ if (grsec_enable_chroot_chmod &&
-+ ((mode & S_ISUID) || (mode & S_ISGID)) &&
-+ proc_is_chrooted(current)) {
-+ security_alert(GR_CHMOD_CHROOT_MSG,
-+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
-+ return -EPERM;
-+ }
-+#endif
-+ return 0;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_disabled.c linux-2.6.5/grsecurity/grsec_disabled.c
---- linux-2.6.5/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_disabled.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,406 @@
-+/*
-+ * when grsecurity is disabled, compile all external functions into nothing
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
-+#include <linux/kdev_t.h>
-+#include <linux/net.h>
-+#include <linux/in.h>
-+#include <linux/ip.h>
-+#include <linux/skbuff.h>
-+#include <linux/sysctl.h>
-+
-+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
-+__inline__ void
-+pax_set_flags(struct linux_binprm *bprm)
-+{
-+ return;
-+}
-+#endif
-+
-+#ifdef CONFIG_SYSCTL
-+__inline__ __u32
-+gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
-+{
-+ return mode;
-+}
-+#endif
-+
-+__inline__ int
-+gr_acl_is_enabled(void)
-+{
-+ return 0;
-+}
-+
-+__inline__ int
-+gr_handle_rawio(const struct inode *inode)
-+{
-+ return 0;
-+}
-+
-+__inline__ void
-+gr_acl_handle_psacct(struct task_struct *task, const long code)
-+{
-+ return;
-+}
-+
-+__inline__ int
-+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ return 0;
-+}
-+
-+__inline__ int
-+gr_handle_mmap(const struct file *filp, const unsigned long prot)
-+{
-+ return 0;
-+}
-+
-+__inline__ int
-+gr_handle_ptrace(struct task_struct *task, const long request)
-+{
-+ return 0;
-+}
-+
-+__inline__ int
-+gr_handle_proc_ptrace(struct task_struct *task)
-+{
-+ return 0;
-+}
-+
-+__inline__ void
-+gr_learn_resource(const struct task_struct *task,
-+ const int res, const unsigned long wanted, const int gt)
-+{
-+ return;
-+}
-+
-+__inline__ int
-+gr_set_acls(const int type)
-+{
-+ return 0;
-+}
-+
-+__inline__ int
-+gr_check_hidden_task(const struct task_struct *tsk)
-+{
-+ return 0;
-+}
-+
-+__inline__ int
-+gr_check_protected_task(const struct task_struct *task)
-+{
-+ return 0;
-+}
-+
-+__inline__ void
-+gr_copy_label(struct task_struct *tsk)
-+{
-+ return;
-+}
-+
-+__inline__ void
-+gr_set_pax_flags(struct task_struct *task)
-+{
-+ return;
-+}
-+
-+__inline__ void
-+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ return;
-+}
-+
-+__inline__ void
-+gr_handle_delete(const ino_t ino, const dev_t dev)
-+{
-+ return;
-+}
-+
-+__inline__ void
-+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+ return;
-+}
-+
-+__inline__ void
-+gr_handle_crash(struct task_struct *task, const int sig)
-+{
-+ return;
-+}
-+
-+__inline__ int
-+gr_check_crash_exec(const struct file *filp)
-+{
-+ return 0;
-+}
-+
-+__inline__ int
-+gr_check_crash_uid(const uid_t uid)
-+{
-+ return 0;
-+}
-+
-+__inline__ void
-+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
-+ struct dentry *old_dentry,
-+ struct dentry *new_dentry,
-+ struct vfsmount *mnt, const __u8 replace)
-+{
-+ return;
-+}
-+
-+__inline__ int
-+gr_search_socket(const int family, const int type, const int protocol)
-+{
-+ return 1;
-+}
-+
-+__inline__ int
-+gr_search_connectbind(const int mode, const struct socket *sock,
-+ const struct sockaddr_in *addr)
-+{
-+ return 1;
-+}
-+
-+__inline__ int
-+gr_task_is_capable(struct task_struct *task, const int cap)
-+{
-+ return 1;
-+}
-+
-+__inline__ int
-+gr_is_capable_nolog(const int cap)
-+{
-+ return 1;
-+}
-+
-+__inline__ void
-+gr_handle_alertkill(void)
-+{
-+ return;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_hidden_file(const struct dentry * dentry,
-+ const struct vfsmount * mnt)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
-+ const int fmode)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
-+{
-+ return 1;
-+}
-+
-+__inline__ int
-+gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
-+ unsigned int *vm_flags)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_truncate(const struct dentry * dentry,
-+ const struct vfsmount * mnt)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_access(const struct dentry * dentry,
-+ const struct vfsmount * mnt, const int fmode)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
-+ mode_t mode)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
-+ mode_t mode)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
-+{
-+ return 1;
-+}
-+
-+__inline__ void
-+grsecurity_init(void)
-+{
-+ return;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_mknod(const struct dentry * new_dentry,
-+ const struct dentry * parent_dentry,
-+ const struct vfsmount * parent_mnt,
-+ const int mode)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_mkdir(const struct dentry * new_dentry,
-+ const struct dentry * parent_dentry,
-+ const struct vfsmount * parent_mnt)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_symlink(const struct dentry * new_dentry,
-+ const struct dentry * parent_dentry,
-+ const struct vfsmount * parent_mnt, const char *from)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_link(const struct dentry * new_dentry,
-+ const struct dentry * parent_dentry,
-+ const struct vfsmount * parent_mnt,
-+ const struct dentry * old_dentry,
-+ const struct vfsmount * old_mnt, const char *to)
-+{
-+ return 1;
-+}
-+
-+__inline__ int
-+gr_acl_handle_rename(const struct dentry *new_dentry,
-+ const struct dentry *parent_dentry,
-+ const struct vfsmount *parent_mnt,
-+ const struct dentry *old_dentry,
-+ const struct inode *old_parent_inode,
-+ const struct vfsmount *old_mnt, const char *newname)
-+{
-+ return 0;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_filldir(const struct dentry * dentry,
-+ const struct vfsmount * mnt, const ino_t ino)
-+{
-+ return 1;
-+}
-+
-+__inline__ int
-+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
-+ const time_t shm_createtime, const uid_t cuid, const int shmid)
-+{
-+ return 1;
-+}
-+
-+__inline__ int
-+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
-+{
-+ return 1;
-+}
-+
-+__inline__ int
-+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
-+{
-+ return 1;
-+}
-+
-+__inline__ __u32
-+gr_acl_handle_creat(const struct dentry * dentry,
-+ const struct dentry * p_dentry,
-+ const struct vfsmount * p_mnt, const int fmode,
-+ const int imode)
-+{
-+ return 1;
-+}
-+
-+__inline__ void
-+gr_acl_handle_exit(void)
-+{
-+ return;
-+}
-+
-+__inline__ int
-+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
-+{
-+ return 1;
-+}
-+
-+__inline__ void
-+gr_set_role_label(const uid_t uid, const gid_t gid)
-+{
-+ return;
-+}
-+
-+__inline__ int
-+gr_acl_handle_procpidmem(const struct task_struct *task)
-+{
-+ return 0;
-+}
-+
-+__inline__ int
-+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
-+{
-+ return 1;
-+}
-+
-+__inline__ int
-+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
-+{
-+ return 1;
-+}
-+
-+__inline__ void
-+gr_set_kernel_label(struct task_struct *task)
-+{
-+ return;
-+}
-+
-+EXPORT_SYMBOL(gr_task_is_capable);
-+EXPORT_SYMBOL(gr_learn_resource);
-+EXPORT_SYMBOL(gr_set_kernel_label);
-+
-diff -urN linux-2.6.5/grsecurity/grsec_exec.c linux-2.6.5/grsecurity/grsec_exec.c
---- linux-2.6.5/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_exec.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,71 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/file.h>
-+#include <linux/binfmts.h>
-+#include <linux/fs.h>
-+#include <linux/types.h>
-+#include <linux/grdefs.h>
-+#include <linux/grinternal.h>
-+#include <linux/capability.h>
-+
-+#include <asm/uaccess.h>
-+
-+int
-+gr_handle_nproc(void)
-+{
-+#ifdef CONFIG_GRKERNSEC_EXECVE
-+ if (grsec_enable_execve && current->user &&
-+ (atomic_read(&current->user->processes) >
-+ current->rlim[RLIMIT_NPROC].rlim_cur) &&
-+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
-+ security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
-+ return -EAGAIN;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+void
-+gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
-+{
-+#ifdef CONFIG_GRKERNSEC_EXECLOG
-+ char grarg[64] = { 0 };
-+ __u8 execlen = 0;
-+ unsigned int i;
-+
-+ if (!((grsec_enable_execlog && grsec_enable_group &&
-+ in_group_p(grsec_audit_gid))
-+ || (grsec_enable_execlog && !grsec_enable_group)))
-+ return;
-+
-+ if (unlikely(!argv))
-+ goto log;
-+
-+ for (i = 0; i < bprm->argc && execlen < 62; i++) {
-+ char *p;
-+ __u8 len;
-+
-+ if (get_user(p, argv + i))
-+ goto log;
-+ if (!p)
-+ goto log;
-+ len = strnlen_user(p, 62 - execlen);
-+ if (len > 62 - execlen)
-+ len = 62 - execlen;
-+ else if (len > 0)
-+ len--;
-+ if (copy_from_user(grarg + execlen, p, len))
-+ goto log;
-+ execlen += len;
-+ *(grarg + execlen) = ' ';
-+ *(grarg + execlen + 1) = '\0';
-+ execlen++;
-+ }
-+
-+ log:
-+ security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
-+ bprm->file->f_vfsmnt),
-+ grarg, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_fifo.c linux-2.6.5/grsecurity/grsec_fifo.c
---- linux-2.6.5/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_fifo.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,24 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/file.h>
-+#include <linux/grinternal.h>
-+
-+int
-+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
-+ const struct dentry *dir, const int flag, const int acc_mode)
-+{
-+#ifdef CONFIG_GRKERNSEC_FIFO
-+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
-+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
-+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
-+ (current->fsuid != dentry->d_inode->i_uid)) {
-+ if (!vfs_permission(dentry->d_inode, acc_mode))
-+ security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
-+ dentry->d_inode->i_uid,
-+ dentry->d_inode->i_gid, DEFAULTSECARGS);
-+ return -EACCES;
-+ }
-+#endif
-+ return 0;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_fork.c linux-2.6.5/grsecurity/grsec_fork.c
---- linux-2.6.5/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_fork.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,14 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+void
-+gr_log_forkfail(const int retval)
-+{
-+#ifdef CONFIG_GRKERNSEC_FORKFAIL
-+ if (grsec_enable_forkfail)
-+ security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_init.c linux-2.6.5/grsecurity/grsec_init.c
---- linux-2.6.5/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_init.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,227 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/smp_lock.h>
-+#include <linux/gracl.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/percpu.h>
-+
-+int grsec_enable_link;
-+int grsec_enable_dmesg;
-+int grsec_enable_fifo;
-+int grsec_enable_execve;
-+int grsec_enable_execlog;
-+int grsec_enable_signal;
-+int grsec_enable_forkfail;
-+int grsec_enable_time;
-+int grsec_enable_audit_textrel;
-+int grsec_enable_group;
-+int grsec_audit_gid;
-+int grsec_enable_chdir;
-+int grsec_enable_audit_ipc;
-+int grsec_enable_mount;
-+int grsec_enable_chroot_findtask;
-+int grsec_enable_chroot_mount;
-+int grsec_enable_chroot_shmat;
-+int grsec_enable_chroot_fchdir;
-+int grsec_enable_chroot_double;
-+int grsec_enable_chroot_pivot;
-+int grsec_enable_chroot_chdir;
-+int grsec_enable_chroot_chmod;
-+int grsec_enable_chroot_mknod;
-+int grsec_enable_chroot_nice;
-+int grsec_enable_chroot_execlog;
-+int grsec_enable_chroot_caps;
-+int grsec_enable_chroot_sysctl;
-+int grsec_enable_chroot_unix;
-+int grsec_enable_tpe;
-+int grsec_tpe_gid;
-+int grsec_enable_tpe_all;
-+int grsec_enable_randpid;
-+int grsec_enable_randid;
-+int grsec_enable_randisn;
-+int grsec_enable_randsrc;
-+int grsec_enable_randrpc;
-+int grsec_enable_socket_all;
-+int grsec_socket_all_gid;
-+int grsec_enable_socket_client;
-+int grsec_socket_client_gid;
-+int grsec_enable_socket_server;
-+int grsec_socket_server_gid;
-+int grsec_lock;
-+
-+spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
-+unsigned long grsec_alert_wtime = 0;
-+unsigned long grsec_alert_fyet = 0;
-+
-+spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED;
-+unsigned long grsec_alertgood_wtime = 0;
-+unsigned long grsec_alertgood_fyet = 0;
-+
-+spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
-+
-+char *gr_shared_page[4];
-+extern struct gr_arg *gr_usermode;
-+extern unsigned char *gr_system_salt;
-+extern unsigned char *gr_system_sum;
-+extern struct task_struct **gr_conn_table;
-+extern const unsigned int gr_conn_table_size;
-+
-+void
-+grsecurity_init(void)
-+{
-+ int j;
-+ /* create the per-cpu shared pages */
-+
-+ preempt_disable();
-+ for (j = 0; j < 4; j++) {
-+ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(char *));
-+ if (gr_shared_page[j] == NULL) {
-+ panic("Unable to allocate grsecurity shared page");
-+ return;
-+ }
-+ }
-+ preempt_enable();
-+
-+ /* create hash tables for ip tagging */
-+
-+ gr_conn_table = (struct task_struct **) vmalloc(gr_conn_table_size * sizeof(struct task_struct *));
-+ if (gr_conn_table == NULL) {
-+ panic("Unable to allocate grsecurity IP tagging table");
-+ return;
-+ }
-+ memset(gr_conn_table, 0, gr_conn_table_size * sizeof(struct task_struct *));
-+
-+ /* allocate memory for authentication structure */
-+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
-+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
-+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
-+
-+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
-+ panic("Unable to allocate grsecurity authentication structure");
-+ return;
-+ }
-+
-+#ifndef CONFIG_GRKERNSEC_SYSCTL
-+ grsec_lock = 1;
-+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
-+ grsec_enable_audit_textrel = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
-+ grsec_enable_group = 1;
-+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
-+ grsec_enable_chdir = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
-+ grsec_enable_audit_ipc = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
-+ grsec_enable_mount = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_LINK
-+ grsec_enable_link = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_DMESG
-+ grsec_enable_dmesg = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_FIFO
-+ grsec_enable_fifo = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_EXECVE
-+ grsec_enable_execve = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_EXECLOG
-+ grsec_enable_execlog = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_SIGNAL
-+ grsec_enable_signal = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_FORKFAIL
-+ grsec_enable_forkfail = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_TIME
-+ grsec_enable_time = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
-+ grsec_enable_chroot_findtask = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
-+ grsec_enable_chroot_unix = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
-+ grsec_enable_chroot_mount = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
-+ grsec_enable_chroot_fchdir = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
-+ grsec_enable_chroot_shmat = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
-+ grsec_enable_chroot_double = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
-+ grsec_enable_chroot_pivot = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
-+ grsec_enable_chroot_chdir = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
-+ grsec_enable_chroot_chmod = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
-+ grsec_enable_chroot_mknod = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
-+ grsec_enable_chroot_nice = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
-+ grsec_enable_chroot_execlog = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
-+ grsec_enable_chroot_caps = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
-+ grsec_enable_chroot_sysctl = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_TPE
-+ grsec_enable_tpe = 1;
-+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
-+#ifdef CONFIG_GRKERNSEC_TPE_ALL
-+ grsec_enable_tpe_all = 1;
-+#endif
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDPID
-+ grsec_enable_randpid = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+ grsec_enable_randid = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDISN
-+ grsec_enable_randisn = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDSRC
-+ grsec_enable_randsrc = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDRPC
-+ grsec_enable_randrpc = 1;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
-+ grsec_enable_socket_all = 1;
-+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
-+ grsec_enable_socket_client = 1;
-+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
-+#endif
-+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
-+ grsec_enable_socket_server = 1;
-+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
-+#endif
-+#endif
-+
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_ipc.c linux-2.6.5/grsecurity/grsec_ipc.c
---- linux-2.6.5/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_ipc.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,81 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/ipc.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+void
-+gr_log_msgget(const int ret, const int msgflg)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
-+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
-+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
-+ !grsec_enable_group)) && (ret >= 0)
-+ && (msgflg & IPC_CREAT))
-+ security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-+
-+void
-+gr_log_msgrm(const uid_t uid, const uid_t cuid)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
-+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
-+ grsec_enable_audit_ipc) ||
-+ (grsec_enable_audit_ipc && !grsec_enable_group))
-+ security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-+
-+void
-+gr_log_semget(const int err, const int semflg)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
-+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
-+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
-+ !grsec_enable_group)) && (err >= 0)
-+ && (semflg & IPC_CREAT))
-+ security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-+
-+void
-+gr_log_semrm(const uid_t uid, const uid_t cuid)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
-+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
-+ grsec_enable_audit_ipc) ||
-+ (grsec_enable_audit_ipc && !grsec_enable_group))
-+ security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-+
-+void
-+gr_log_shmget(const int err, const int shmflg, const size_t size)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
-+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
-+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
-+ !grsec_enable_group)) && (err >= 0)
-+ && (shmflg & IPC_CREAT))
-+ security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-+
-+void
-+gr_log_shmrm(const uid_t uid, const uid_t cuid)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
-+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
-+ grsec_enable_audit_ipc) ||
-+ (grsec_enable_audit_ipc && !grsec_enable_group))
-+ security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_link.c linux-2.6.5/grsecurity/grsec_link.c
---- linux-2.6.5/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_link.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,41 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/file.h>
-+#include <linux/grinternal.h>
-+
-+int
-+gr_handle_follow_link(const struct inode *parent,
-+ const struct inode *inode,
-+ const struct dentry *dentry, const struct vfsmount *mnt)
-+{
-+#ifdef CONFIG_GRKERNSEC_LINK
-+ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
-+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
-+ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
-+ security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
-+ inode->i_uid, inode->i_gid, DEFAULTSECARGS);
-+ return -EACCES;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_handle_hardlink(const struct dentry *dentry,
-+ const struct vfsmount *mnt,
-+ struct inode *inode, const int mode, const char *to)
-+{
-+#ifdef CONFIG_GRKERNSEC_LINK
-+ if (grsec_enable_link && current->fsuid != inode->i_uid &&
-+ (!S_ISREG(mode) || (mode & S_ISUID) ||
-+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
-+ (vfs_permission(inode, MAY_READ | MAY_WRITE))) &&
-+ !capable(CAP_FOWNER) && current->uid) {
-+ security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
-+ inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
-+ return -EPERM;
-+ }
-+#endif
-+ return 0;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_mem.c linux-2.6.5/grsecurity/grsec_mem.c
---- linux-2.6.5/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_mem.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,54 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/mman.h>
-+#include <linux/grinternal.h>
-+
-+void
-+gr_handle_ioperm(void)
-+{
-+ security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
-+ return;
-+}
-+
-+void
-+gr_handle_iopl(void)
-+{
-+ security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
-+ return;
-+}
-+
-+void
-+gr_handle_mem_write(void)
-+{
-+ security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
-+ return;
-+}
-+
-+void
-+gr_handle_kmem_write(void)
-+{
-+ security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
-+ return;
-+}
-+
-+void
-+gr_handle_open_port(void)
-+{
-+ security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
-+ return;
-+}
-+
-+int
-+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
-+{
-+ if (offset < __pa(high_memory) && (vma->vm_flags & VM_WRITE) &&
-+ !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) &&
-+ !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) {
-+ security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
-+ return -EPERM;
-+ } else if (offset < __pa(high_memory))
-+ vma->vm_flags &= ~VM_MAYWRITE;
-+
-+ return 0;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_mount.c linux-2.6.5/grsecurity/grsec_mount.c
---- linux-2.6.5/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_mount.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,34 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+void
-+gr_log_remount(const char *devname, const int retval)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
-+ if (grsec_enable_mount && (retval >= 0))
-+ security_audit(GR_REMOUNT_AUDIT_MSG, devname ? devname : "none", DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-+
-+void
-+gr_log_unmount(const char *devname, const int retval)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
-+ if (grsec_enable_mount && (retval >= 0))
-+ security_audit(GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none", DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-+
-+void
-+gr_log_mount(const char *from, const char *to, const int retval)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
-+ if (grsec_enable_mount && (retval >= 0))
-+ security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_rand.c linux-2.6.5/grsecurity/grsec_rand.c
---- linux-2.6.5/grsecurity/grsec_rand.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_rand.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,22 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/smp_lock.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+extern int pid_max;
-+
-+int
-+gr_random_pid(void)
-+{
-+#ifdef CONFIG_GRKERNSEC_RANDPID
-+ int pid;
-+
-+ if (grsec_enable_randpid && current->fs->root) {
-+
-+ pid = 1 + (get_random_long() % pid_max);
-+ return pid;
-+ }
-+#endif
-+ return 0;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_sig.c linux-2.6.5/grsecurity/grsec_sig.c
---- linux-2.6.5/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_sig.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,48 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+void
-+gr_log_signal(const int sig, const struct task_struct *t)
-+{
-+#ifdef CONFIG_GRKERNSEC_SIGNAL
-+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
-+ (sig == SIGABRT) || (sig == SIGBUS))) {
-+ if (t->pid == current->pid) {
-+ security_alert_good(GR_UNISIGLOG_MSG, sig,
-+ DEFAULTSECARGS);
-+ } else {
-+ security_alert_good(GR_DUALSIGLOG_MSG, sig,
-+ gr_task_fullpath0(t), t->comm,
-+ t->pid, t->uid, t->euid, t->gid,
-+ t->egid, gr_parent_task_fullpath0(t),
-+ t->parent->comm,
-+ t->parent->pid, t->parent->uid,
-+ t->parent->euid, t->parent->gid,
-+ t->parent->egid, DEFAULTSECARGS);
-+ }
-+ }
-+#endif
-+ return;
-+}
-+
-+int
-+gr_handle_signal(const struct task_struct *p, const int sig)
-+{
-+#ifdef CONFIG_GRKERNSEC
-+ if (current->pid > 1 && gr_check_protected_task(p)) {
-+ security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath0(p),
-+ p->comm, p->pid, p->uid,
-+ p->euid, p->gid, p->egid,
-+ gr_parent_task_fullpath0(p), p->parent->comm,
-+ p->parent->pid, p->parent->uid,
-+ p->parent->euid, p->parent->gid,
-+ p->parent->egid, DEFAULTSECARGS);
-+ return -EPERM;
-+ } else if (gr_pid_is_chrooted(p)) {
-+ return -EPERM;
-+ }
-+#endif
-+ return 0;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_sock.c linux-2.6.5/grsecurity/grsec_sock.c
---- linux-2.6.5/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_sock.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,256 @@
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/file.h>
-+#include <linux/net.h>
-+#include <linux/in.h>
-+#include <linux/ip.h>
-+#include <net/sock.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+#include <linux/gracl.h>
-+
-+#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
-+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
-+EXPORT_SYMBOL(udp_v4_lookup);
-+#endif
-+#if defined(CONFIG_GRKERNSEC_RANDID)
-+EXPORT_SYMBOL(ip_randomid);
-+#endif
-+#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
-+EXPORT_SYMBOL(get_random_long);
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDISN
-+EXPORT_SYMBOL(ip_randomisn);
-+EXPORT_SYMBOL(grsec_enable_randisn);
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+EXPORT_SYMBOL(grsec_enable_randid);
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDSRC
-+EXPORT_SYMBOL(grsec_enable_randsrc);
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDRPC
-+EXPORT_SYMBOL(grsec_enable_randrpc);
-+#endif
-+
-+EXPORT_SYMBOL(gr_cap_rtnetlink);
-+
-+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
-+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
-+
-+EXPORT_SYMBOL(gr_search_udp_recvmsg);
-+EXPORT_SYMBOL(gr_search_udp_sendmsg);
-+
-+#ifdef CONFIG_UNIX_MODULE
-+EXPORT_SYMBOL(gr_acl_handle_unix);
-+EXPORT_SYMBOL(gr_acl_handle_mknod);
-+EXPORT_SYMBOL(gr_handle_chroot_unix);
-+EXPORT_SYMBOL(gr_handle_create);
-+#endif
-+
-+#ifdef CONFIG_GRKERNSEC
-+struct task_struct **gr_conn_table;
-+const unsigned int gr_conn_table_size = 65521;
-+struct task_struct *deleted_conn = (struct task_struct *)~0;
-+spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
-+
-+extern __inline__ const char * gr_socktype_to_name(unsigned char type);
-+extern __inline__ const char * gr_proto_to_name(unsigned char proto);
-+
-+static __inline__ int
-+conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
-+{
-+ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
-+}
-+
-+static __inline__ int
-+conn_match(const struct task_struct *task, __u32 saddr, __u32 daddr,
-+ __u16 sport, __u16 dport)
-+{
-+ if (unlikely(task != deleted_conn && task->gr_saddr == saddr &&
-+ task->gr_daddr == daddr && task->gr_sport == sport &&
-+ task->gr_dport == dport))
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+void gr_add_to_task_ip_table(struct task_struct *task)
-+{
-+ unsigned int index;
-+
-+ if (unlikely(gr_conn_table == NULL))
-+ return;
-+
-+ if (!thread_group_leader(task))
-+ task = task->group_leader;
-+
-+ index = conn_hash(task->gr_saddr, task->gr_daddr,
-+ task->gr_sport, task->gr_dport,
-+ gr_conn_table_size);
-+
-+ spin_lock(&gr_conn_table_lock);
-+
-+ while (gr_conn_table[index] && gr_conn_table[index] != deleted_conn) {
-+ index = (index + 1) % gr_conn_table_size;
-+ }
-+
-+ gr_conn_table[index] = task;
-+
-+ spin_unlock(&gr_conn_table_lock);
-+
-+ return;
-+}
-+
-+void gr_del_task_from_ip_table_nolock(struct task_struct *task)
-+{
-+ unsigned int index;
-+
-+ if (unlikely(gr_conn_table == NULL))
-+ return;
-+
-+ if (!thread_group_leader(task))
-+ task = task->group_leader;
-+
-+ index = conn_hash(task->gr_saddr, task->gr_daddr,
-+ task->gr_sport, task->gr_dport,
-+ gr_conn_table_size);
-+
-+ while (gr_conn_table[index] && !conn_match(gr_conn_table[index],
-+ task->gr_saddr, task->gr_daddr, task->gr_sport,
-+ task->gr_dport)) {
-+ index = (index + 1) % gr_conn_table_size;
-+ }
-+
-+ if (gr_conn_table[index]) {
-+ if (gr_conn_table[(index + 1) % gr_conn_table_size])
-+ gr_conn_table[index] = deleted_conn;
-+ else
-+ gr_conn_table[index] = NULL;
-+ }
-+
-+ return;
-+}
-+
-+struct task_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
-+ __u16 sport, __u16 dport)
-+{
-+ unsigned int index;
-+
-+ if (unlikely(gr_conn_table == NULL))
-+ return NULL;
-+
-+ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
-+
-+ while (gr_conn_table[index] && !conn_match(gr_conn_table[index],
-+ saddr, daddr, sport, dport)) {
-+ index = (index + 1) % gr_conn_table_size;
-+ }
-+
-+ return gr_conn_table[index];
-+}
-+
-+#endif
-+
-+void gr_del_task_from_ip_table(struct task_struct *task)
-+{
-+#ifdef CONFIG_GRKERNSEC
-+ spin_lock(&gr_conn_table_lock);
-+ if (!thread_group_leader(task))
-+ gr_del_task_from_ip_table_nolock(task->group_leader);
-+ else
-+ gr_del_task_from_ip_table_nolock(task);
-+ spin_unlock(&gr_conn_table_lock);
-+#endif
-+ return;
-+}
-+
-+void
-+gr_attach_curr_ip(const struct sock *sk)
-+{
-+#ifdef CONFIG_GRKERNSEC
-+ struct task_struct *p;
-+ struct task_struct *set;
-+ const struct inet_opt *inet = inet_sk(sk);
-+
-+ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
-+ return;
-+
-+ set = current;
-+ if (!thread_group_leader(set))
-+ set = set->group_leader;
-+
-+ spin_lock(&gr_conn_table_lock);
-+ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
-+ inet->dport, inet->sport);
-+ if (unlikely(p != NULL)) {
-+ set->curr_ip = p->curr_ip;
-+ set->used_accept = 1;
-+ gr_del_task_from_ip_table_nolock(p);
-+ spin_unlock(&gr_conn_table_lock);
-+ return;
-+ }
-+ spin_unlock(&gr_conn_table_lock);
-+
-+ set->curr_ip = inet->daddr;
-+ set->used_accept = 1;
-+#endif
-+ return;
-+}
-+
-+int
-+gr_handle_sock_all(const int family, const int type, const int protocol)
-+{
-+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
-+ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
-+ (family != AF_UNIX) && (family != AF_LOCAL)) {
-+ security_alert(GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol),
-+ DEFAULTSECARGS);
-+ return -EACCES;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_handle_sock_server(const struct sockaddr *sck)
-+{
-+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
-+ if (grsec_enable_socket_server &&
-+ in_group_p(grsec_socket_server_gid) &&
-+ sck && (sck->sa_family != AF_UNIX) &&
-+ (sck->sa_family != AF_LOCAL)) {
-+ security_alert(GR_BIND_MSG, DEFAULTSECARGS);
-+ return -EACCES;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int
-+gr_handle_sock_client(const struct sockaddr *sck)
-+{
-+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
-+ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
-+ sck && (sck->sa_family != AF_UNIX) &&
-+ (sck->sa_family != AF_LOCAL)) {
-+ security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
-+ return -EACCES;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+__u32
-+gr_cap_rtnetlink(void)
-+{
-+#ifdef CONFIG_GRKERNSEC
-+ if (!gr_acl_is_enabled())
-+ return current->cap_effective;
-+ else
-+ return (current->cap_effective & ~(current->acl->cap_lower));
-+#else
-+ return current->cap_effective;
-+#endif
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_sysctl.c linux-2.6.5/grsecurity/grsec_sysctl.c
---- linux-2.6.5/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_sysctl.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,453 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/sysctl.h>
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+int
-+gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
-+{
-+#ifdef CONFIG_GRKERNSEC_SYSCTL
-+ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
-+ security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
-+ return -EACCES;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+#ifdef CONFIG_GRKERNSEC_SYSCTL
-+enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
-+GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
-+GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
-+GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
-+GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
-+GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
-+GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
-+GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_TTY, GS_TTYS,
-+GS_PTY, GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
-+GS_TEXTREL, GS_FINDTASK, GS_LOCK};
-+
-+
-+ctl_table grsecurity_table[] = {
-+#ifdef CONFIG_GRKERNSEC_LINK
-+ {
-+ .ctl_name = GS_LINK,
-+ .procname = "linking_restrictions",
-+ .data = &grsec_enable_link,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_FIFO
-+ {
-+ .ctl_name = GS_FIFO,
-+ .procname = "fifo_restrictions",
-+ .data = &grsec_enable_fifo,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_EXECVE
-+ {
-+ .ctl_name = GS_EXECVE,
-+ .procname = "execve_limiting",
-+ .data = &grsec_enable_execve,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_EXECLOG
-+ {
-+ .ctl_name = GS_EXECLOG,
-+ .procname = "exec_logging",
-+ .data = &grsec_enable_execlog,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_SIGNAL
-+ {
-+ .ctl_name = GS_SIGNAL,
-+ .procname = "signal_logging",
-+ .data = &grsec_enable_signal,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_FORKFAIL
-+ {
-+ .ctl_name = GS_FORKFAIL,
-+ .procname = "forkfail_logging",
-+ .data = &grsec_enable_forkfail,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_TIME
-+ {
-+ .ctl_name = GS_TIME,
-+ .procname = "timechange_logging",
-+ .data = &grsec_enable_time,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
-+ {
-+ .ctl_name = GS_CHROOT_SHMAT,
-+ .procname = "chroot_deny_shmat",
-+ .data = &grsec_enable_chroot_shmat,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
-+ {
-+ .ctl_name = GS_CHROOT_UNIX,
-+ .procname = "chroot_deny_unix",
-+ .data = &grsec_enable_chroot_unix,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
-+ {
-+ .ctl_name = GS_CHROOT_MNT,
-+ .procname = "chroot_deny_mount",
-+ .data = &grsec_enable_chroot_mount,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
-+ {
-+ .ctl_name = GS_CHROOT_FCHDIR,
-+ .procname = "chroot_deny_fchdir",
-+ .data = &grsec_enable_chroot_fchdir,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
-+ {
-+ .ctl_name = GS_CHROOT_DBL,
-+ .procname = "chroot_deny_chroot",
-+ .data = &grsec_enable_chroot_double,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
-+ {
-+ .ctl_name = GS_CHROOT_PVT,
-+ .procname = "chroot_deny_pivot",
-+ .data = &grsec_enable_chroot_pivot,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
-+ {
-+ .ctl_name = GS_CHROOT_CD,
-+ .procname = "chroot_enforce_chdir",
-+ .data = &grsec_enable_chroot_chdir,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
-+ {
-+ .ctl_name = GS_CHROOT_CM,
-+ .procname = "chroot_deny_chmod",
-+ .data = &grsec_enable_chroot_chmod,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
-+ {
-+ .ctl_name = GS_CHROOT_MK,
-+ .procname = "chroot_deny_mknod",
-+ .data = &grsec_enable_chroot_mknod,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
-+ {
-+ .ctl_name = GS_CHROOT_NI,
-+ .procname = "chroot_restrict_nice",
-+ .data = &grsec_enable_chroot_nice,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
-+ {
-+ .ctl_name = GS_CHROOT_EXECLOG,
-+ .procname = "chroot_execlog",
-+ .data = &grsec_enable_chroot_execlog,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
-+ {
-+ .ctl_name = GS_CHROOT_CAPS,
-+ .procname = "chroot_caps",
-+ .data = &grsec_enable_chroot_caps,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
-+ {
-+ .ctl_name = GS_CHROOT_SYSCTL,
-+ .procname = "chroot_deny_sysctl",
-+ .data = &grsec_enable_chroot_sysctl,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_TPE
-+ {
-+ .ctl_name = GS_TPE,
-+ .procname = "tpe",
-+ .data = &grsec_enable_tpe,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
-+ .ctl_name = GS_TPE_GID,
-+ .procname = "tpe_gid",
-+ .data = &grsec_tpe_gid,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_TPE_ALL
-+ {
-+ .ctl_name = GS_TPE_ALL,
-+ .procname = "tpe_restrict_all",
-+ .data = &grsec_enable_tpe_all,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDPID
-+ {
-+ .ctl_name = GS_RANDPID,
-+ .procname = "rand_pids",
-+ .data = &grsec_enable_randpid,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+ {
-+ .ctl_name = GS_RANDID,
-+ .procname = "rand_ip_ids",
-+ .data = &grsec_enable_randid,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDSRC
-+ {
-+ .ctl_name = GS_RANDSRC,
-+ .procname = "rand_tcp_src_ports",
-+ .data = &grsec_enable_randsrc,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDISN
-+ {
-+ .ctl_name = GS_RANDISN,
-+ .procname = "rand_isns",
-+ .data = &grsec_enable_randisn,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
-+ {
-+ .ctl_name = GS_SOCKET_ALL,
-+ .procname = "socket_all",
-+ .data = &grsec_enable_socket_all,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
-+ .ctl_name = GS_SOCKET_ALL_GID,
-+ .procname = "socket_all_gid",
-+ .data = &grsec_socket_all_gid,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
-+ {
-+ .ctl_name = GS_SOCKET_CLIENT,
-+ .procname = "socket_client",
-+ .data = &grsec_enable_socket_client,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
-+ .ctl_name = GS_SOCKET_CLIENT_GID,
-+ .procname = "socket_client_gid",
-+ .data = &grsec_socket_client_gid,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
-+ {
-+ .ctl_name = GS_SOCKET_SERVER,
-+ .procname = "socket_server",
-+ .data = &grsec_enable_socket_server,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
-+ .ctl_name = GS_SOCKET_SERVER_GID,
-+ .procname = "socket_server_gid",
-+ .data = &grsec_socket_server_gid,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
-+ {
-+ .ctl_name = GS_GROUP,
-+ .procname = "audit_group",
-+ .data = &grsec_enable_group,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
-+ .ctl_name = GS_GID,
-+ .procname = "audit_gid",
-+ .data = &grsec_audit_gid,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
-+ {
-+ .ctl_name = GS_ACHDIR,
-+ .procname = "audit_chdir",
-+ .data = &grsec_enable_chdir,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
-+ {
-+ .ctl_name = GS_AMOUNT,
-+ .procname = "audit_mount",
-+ .data = &grsec_enable_mount,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
-+ {
-+ .ctl_name = GS_AIPC,
-+ .procname = "audit_ipc",
-+ .data = &grsec_enable_audit_ipc,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
-+ {
-+ .ctl_name = GS_TEXTREL,
-+ .procname = "audit_textrel",
-+ .data = &grsec_enable_audit_textrel,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_DMESG
-+ {
-+ .ctl_name = GS_DMSG,
-+ .procname = "dmesg",
-+ .data = &grsec_enable_dmesg,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_RANDRPC
-+ {
-+ .ctl_name = GS_RANDRPC,
-+ .procname = "rand_rpc",
-+ .data = &grsec_enable_randrpc,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
-+ {
-+ .ctl_name = GS_FINDTASK,
-+ .procname = "chroot_findtask",
-+ .data = &grsec_enable_chroot_findtask,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+ {
-+ .ctl_name = GS_LOCK,
-+ .procname = "grsec_lock",
-+ .data = &grsec_lock,
-+ .maxlen = sizeof(int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ { .ctl_name = 0 }
-+};
-+#endif
-diff -urN linux-2.6.5/grsecurity/grsec_textrel.c linux-2.6.5/grsecurity/grsec_textrel.c
---- linux-2.6.5/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_textrel.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,19 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/file.h>
-+#include <linux/grinternal.h>
-+#include <linux/grsecurity.h>
-+
-+void
-+gr_log_textrel(struct vm_area_struct * vma)
-+{
-+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
-+ if (grsec_enable_audit_textrel)
-+ security_audit(GR_TEXTREL_AUDIT_MSG, vma->vm_file ?
-+ gr_to_filename(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt)
-+ : "<anonymous mapping>", vma->vm_start,
-+ vma->vm_pgoff, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_time.c linux-2.6.5/grsecurity/grsec_time.c
---- linux-2.6.5/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_time.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,13 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/grinternal.h>
-+
-+void
-+gr_log_timechange(void)
-+{
-+#ifdef CONFIG_GRKERNSEC_TIME
-+ if (grsec_enable_time)
-+ security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
-+#endif
-+ return;
-+}
-diff -urN linux-2.6.5/grsecurity/grsec_tpe.c linux-2.6.5/grsecurity/grsec_tpe.c
---- linux-2.6.5/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsec_tpe.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,35 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
-+#include <linux/grinternal.h>
-+
-+extern int gr_acl_tpe_check(void);
-+
-+int
-+gr_tpe_allow(const struct file *file)
-+{
-+#ifdef CONFIG_GRKERNSEC
-+ struct inode *inode = file->f_dentry->d_parent->d_inode;
-+
-+ if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
-+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
-+ (inode->i_mode & S_IWOTH))))) {
-+ security_alert(GR_EXEC_TPE_MSG,
-+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
-+ DEFAULTSECARGS);
-+ return 0;
-+ }
-+#ifdef CONFIG_GRKERNSEC_TPE_ALL
-+ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
-+ ((inode->i_uid && (inode->i_uid != current->uid)) ||
-+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
-+ security_alert(GR_EXEC_TPE_MSG,
-+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
-+ DEFAULTSECARGS);
-+ return 0;
-+ }
-+#endif
-+#endif
-+ return 1;
-+}
-diff -urN linux-2.6.5/grsecurity/grsum.c linux-2.6.5/grsecurity/grsum.c
---- linux-2.6.5/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/grsum.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,59 @@
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <asm/scatterlist.h>
-+#include <linux/crypto.h>
-+#include <linux/gracl.h>
-+
-+
-+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
-+#error "crypto and sha256 must be built into the kernel"
-+#endif
-+
-+int
-+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
-+{
-+ char *p;
-+ struct crypto_tfm *tfm;
-+ unsigned char temp_sum[GR_SHA_LEN];
-+ struct scatterlist sg[2];
-+ volatile int retval = 0;
-+ volatile int dummy = 0;
-+ unsigned int i;
-+
-+ tfm = crypto_alloc_tfm("sha256", 0);
-+ if (tfm == NULL) {
-+ /* should never happen, since sha256 should be built in */
-+ return 1;
-+ }
-+
-+ crypto_digest_init(tfm);
-+
-+ p = salt;
-+ sg[0].page = virt_to_page(p);
-+ sg[0].offset = ((long) p & ~PAGE_MASK);
-+ sg[0].length = GR_SALT_LEN;
-+
-+ crypto_digest_update(tfm, sg, 1);
-+
-+ p = entry->pw;
-+ sg[0].page = virt_to_page(p);
-+ sg[0].offset = ((long) p & ~PAGE_MASK);
-+ sg[0].length = strlen(entry->pw);
-+
-+ crypto_digest_update(tfm, sg, 1);
-+
-+ crypto_digest_final(tfm, temp_sum);
-+
-+ memset(entry->pw, 0, GR_PW_LEN);
-+
-+ for (i = 0; i < GR_SHA_LEN; i++)
-+ if (sum[i] != temp_sum[i])
-+ retval = 1;
-+ else
-+ dummy = 1; // waste a cycle
-+
-+ crypto_free_tfm(tfm);
-+
-+ return retval;
-+}
-diff -urN linux-2.6.5/grsecurity/obsd_rand.c linux-2.6.5/grsecurity/obsd_rand.c
---- linux-2.6.5/grsecurity/obsd_rand.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/grsecurity/obsd_rand.c 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,186 @@
-+
-+/*
-+ * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
-+ *
-+ * Version 1.89, last modified 19-Sep-99
-+ *
-+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
-+ * All rights reserved.
-+ *
-+ * Copyright 1998 Niels Provos <provos@citi.umich.edu>
-+ * All rights reserved.
-+ * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
-+ * such a mathematical system to generate more random (yet non-repeating)
-+ * ids to solve the resolver/named problem. But Niels designed the
-+ * actual system based on the constraints.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer,
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/time.h>
-+#include <linux/timer.h>
-+#include <linux/smp_lock.h>
-+#include <linux/random.h>
-+#include <linux/grsecurity.h>
-+
-+#define RU_OUT 180
-+#define RU_MAX 30000
-+#define RU_GEN 2
-+#define RU_N 32749
-+#define RU_AGEN 7
-+#define RU_M 31104
-+#define PFAC_N 3
-+const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
-+
-+static __u16 ru_x;
-+static __u16 ru_seed, ru_seed2;
-+static __u16 ru_a, ru_b;
-+static __u16 ru_g;
-+static __u16 ru_counter = 0;
-+static __u16 ru_msb = 0;
-+static unsigned long ru_reseed = 0;
-+static __u32 tmp;
-+
-+#define TCP_RNDISS_ROUNDS 15
-+#define TCP_RNDISS_OUT 7200
-+#define TCP_RNDISS_MAX 30000
-+
-+static __u8 tcp_rndiss_sbox[128];
-+static __u16 tcp_rndiss_msb;
-+static __u16 tcp_rndiss_cnt;
-+static unsigned long tcp_rndiss_reseed;
-+
-+static __u16 pmod(__u16, __u16, __u16);
-+static void ip_initid(void);
-+__u16 ip_randomid(void);
-+
-+static __u16
-+pmod(__u16 gen, __u16 exp, __u16 mod)
-+{
-+ __u16 s, t, u;
-+
-+ s = 1;
-+ t = gen;
-+ u = exp;
-+
-+ while (u) {
-+ if (u & 1)
-+ s = (s * t) % mod;
-+ u >>= 1;
-+ t = (t * t) % mod;
-+ }
-+ return (s);
-+}
-+
-+static void
-+ip_initid(void)
-+{
-+ __u16 j, i;
-+ int noprime = 1;
-+
-+ ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
-+
-+ ru_seed = (tmp >> 16) & 0x7FFF;
-+ ru_seed2 = get_random_long() & 0x7FFF;
-+
-+ ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
-+ ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
-+ while (ru_b % 3 == 0)
-+ ru_b += 2;
-+
-+ j = (tmp = get_random_long()) % RU_N;
-+ tmp = tmp >> 16;
-+
-+ while (noprime) {
-+ for (i = 0; i < PFAC_N; i++)
-+ if (j % pfacts[i] == 0)
-+ break;
-+
-+ if (i >= PFAC_N)
-+ noprime = 0;
-+ else
-+ j = (j + 1) % RU_N;
-+ }
-+
-+ ru_g = pmod(RU_GEN, j, RU_N);
-+ ru_counter = 0;
-+
-+ ru_reseed = xtime.tv_sec + RU_OUT;
-+ ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
-+}
-+
-+__u16
-+ip_randomid(void)
-+{
-+ int i, n;
-+
-+ if (ru_counter >= RU_MAX || time_after(get_seconds(), ru_reseed))
-+ ip_initid();
-+
-+ if (!tmp)
-+ tmp = get_random_long();
-+
-+ n = tmp & 0x3;
-+ tmp = tmp >> 2;
-+ if (ru_counter + n >= RU_MAX)
-+ ip_initid();
-+ for (i = 0; i <= n; i++)
-+ ru_x = (ru_a * ru_x + ru_b) % RU_M;
-+ ru_counter += i;
-+
-+ return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
-+}
-+
-+__u16
-+tcp_rndiss_encrypt(__u16 val)
-+{
-+ __u16 sum = 0, i;
-+
-+ for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
-+ sum += 0x79b9;
-+ val ^= ((__u16) tcp_rndiss_sbox[(val ^ sum) & 0x7f]) << 7;
-+ val = ((val & 0xff) << 7) | (val >> 8);
-+ }
-+
-+ return val;
-+}
-+
-+static void
-+tcp_rndiss_init(void)
-+{
-+ get_random_bytes(tcp_rndiss_sbox, sizeof (tcp_rndiss_sbox));
-+ tcp_rndiss_reseed = get_seconds() + TCP_RNDISS_OUT;
-+ tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000;
-+ tcp_rndiss_cnt = 0;
-+}
-+
-+__u32
-+ip_randomisn(void)
-+{
-+ if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
-+ time_after(get_seconds(), tcp_rndiss_reseed))
-+ tcp_rndiss_init();
-+
-+ return (((tcp_rndiss_encrypt(tcp_rndiss_cnt++) |
-+ tcp_rndiss_msb) << 16) | (get_random_long() & 0x7fff));
-+}
-diff -urN linux-2.6.5/include/asm-alpha/a.out.h linux-2.6.5/include/asm-alpha/a.out.h
---- linux-2.6.5/include/asm-alpha/a.out.h 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/include/asm-alpha/a.out.h 2004-04-18 11:05:51.000000000 -0400
-@@ -98,7 +98,7 @@
- set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
- ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
-
--#define STACK_TOP \
-+#define __STACK_TOP \
- (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
-
- #endif
-diff -urN linux-2.6.5/include/asm-alpha/elf.h linux-2.6.5/include/asm-alpha/elf.h
---- linux-2.6.5/include/asm-alpha/elf.h 2004-04-03 22:37:07.000000000 -0500
-+++ linux-2.6.5/include/asm-alpha/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -84,6 +84,17 @@
-
- #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
-+#endif
-+
- /* $0 is set by ld.so to a pointer to a function which might be
- registered using atexit. This provides a mean for the dynamic
- linker to call DT_FINI functions for shared libraries that have
-diff -urN linux-2.6.5/include/asm-alpha/mman.h linux-2.6.5/include/asm-alpha/mman.h
---- linux-2.6.5/include/asm-alpha/mman.h 2004-04-03 22:36:14.000000000 -0500
-+++ linux-2.6.5/include/asm-alpha/mman.h 2004-04-18 11:05:51.000000000 -0400
-@@ -29,6 +29,10 @@
- #define MAP_POPULATE 0x20000 /* populate (prefault) pagetables */
- #define MAP_NONBLOCK 0x40000 /* do not block on IO */
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+#define MAP_MIRROR 0x20000
-+#endif
-+
- #define MS_ASYNC 1 /* sync memory asynchronously */
- #define MS_SYNC 2 /* synchronous memory sync */
- #define MS_INVALIDATE 4 /* invalidate the caches */
-diff -urN linux-2.6.5/include/asm-alpha/page.h linux-2.6.5/include/asm-alpha/page.h
---- linux-2.6.5/include/asm-alpha/page.h 2004-04-03 22:37:40.000000000 -0500
-+++ linux-2.6.5/include/asm-alpha/page.h 2004-04-18 11:05:51.000000000 -0400
-@@ -98,6 +98,15 @@
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
-
- #endif /* _ALPHA_PAGE_H */
-diff -urN linux-2.6.5/include/asm-alpha/pgtable.h linux-2.6.5/include/asm-alpha/pgtable.h
---- linux-2.6.5/include/asm-alpha/pgtable.h 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/include/asm-alpha/pgtable.h 2004-04-18 11:05:51.000000000 -0400
-@@ -96,6 +96,17 @@
- #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
- #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
- #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
-+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
-+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
-+#else
-+# define PAGE_SHARED_NOEXEC PAGE_SHARED
-+# define PAGE_COPY_NOEXEC PAGE_COPY
-+# define PAGE_READONLY_NOEXEC PAGE_READONLY
-+#endif
-+
- #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
-
- #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
-diff -urN linux-2.6.5/include/asm-i386/a.out.h linux-2.6.5/include/asm-i386/a.out.h
---- linux-2.6.5/include/asm-i386/a.out.h 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/a.out.h 2004-04-18 11:05:51.000000000 -0400
-@@ -19,7 +19,11 @@
-
- #ifdef __KERNEL__
-
--#define STACK_TOP TASK_SIZE
-+#ifdef CONFIG_PAX_SEGMEXEC
-+#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
-+#else
-+#define __STACK_TOP TASK_SIZE
-+#endif
-
- #endif
-
-diff -urN linux-2.6.5/include/asm-i386/desc.h linux-2.6.5/include/asm-i386/desc.h
---- linux-2.6.5/include/asm-i386/desc.h 2004-04-03 22:36:12.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/desc.h 2004-04-18 11:05:51.000000000 -0400
-@@ -8,11 +8,19 @@
-
- #include <linux/preempt.h>
- #include <linux/smp.h>
-+#include <linux/sched.h>
-
- #include <asm/mmu.h>
-+#include <asm/pgtable.h>
-+#include <asm/tlbflush.h>
-
- extern struct desc_struct cpu_gdt_table[NR_CPUS][GDT_ENTRIES];
-
-+static inline void pax_switch_segments(struct task_struct * tsk, int cpu)
-+{
-+ cpu_gdt_table[cpu][GDT_ENTRY_DEFAULT_USER_CS].b = tsk->flags & PF_PAX_SEGMEXEC ? 0x60c9fb00U : 0x00cffb00U;
-+}
-+
- struct Xgt_desc_struct {
- unsigned short size;
- unsigned long address __attribute__((packed));
-@@ -28,7 +36,7 @@
- * This is the ldt that every process will get unless we need
- * something other than this.
- */
--extern struct desc_struct default_ldt[];
-+extern const struct desc_struct default_ldt[];
- extern void set_intr_gate(unsigned int irq, void * addr);
-
- #define _set_tssldt_desc(n,addr,limit,type) \
-@@ -42,16 +50,50 @@
- "rorl $16,%%eax" \
- : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
-
--static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
-+static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
- {
- _set_tssldt_desc(&cpu_gdt_table[cpu][entry], (int)addr, 235, 0x89);
- }
-
- #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
-
--static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
-+static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
-+{
-+ _set_tssldt_desc(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
-+}
-+
-+#define pax_open_kernel(flags, cr3) \
-+do { \
-+ typecheck(unsigned long,flags); \
-+ typecheck(unsigned long,cr3); \
-+ local_irq_save(flags); \
-+ asm("movl %%cr3,%0":"=r" (cr3)); \
-+ load_cr3(kernexec_pg_dir); \
-+} while(0)
-+
-+#define pax_close_kernel(flags, cr3) \
-+do { \
-+ typecheck(unsigned long,flags); \
-+ typecheck(unsigned long,cr3); \
-+ asm("movl %0,%%cr3": :"r" (cr3)); \
-+ local_irq_restore(flags); \
-+} while(0)
-+
-+static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
- {
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ unsigned long flags, cr3;
-+
-+ pax_open_kernel(flags, cr3);
-+#endif
-+
- _set_tssldt_desc(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ pax_close_kernel(flags, cr3);
-+#endif
-+
- }
-
- #define LDT_entry_a(info) \
-@@ -67,7 +109,7 @@
- ((info)->seg_32bit << 22) | \
- ((info)->limit_in_pages << 23) | \
- ((info)->useable << 20) | \
-- 0x7000)
-+ 0x7100)
-
- #define LDT_empty(info) (\
- (info)->base_addr == 0 && \
-@@ -104,7 +146,7 @@
- */
- static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
- {
-- void *segments = pc->ldt;
-+ const void *segments = pc->ldt;
- int count = pc->size;
-
- if (likely(!count)) {
-@@ -123,6 +165,22 @@
- put_cpu();
- }
-
-+static inline void _load_LDT(mm_context_t *pc)
-+{
-+ int cpu = get_cpu();
-+ const void *segments = pc->ldt;
-+ int count = pc->size;
-+
-+ if (likely(!count)) {
-+ segments = &default_ldt[0];
-+ count = 5;
-+ }
-+
-+ __set_ldt_desc(cpu, segments, count);
-+ load_LDT_desc();
-+ put_cpu();
-+}
-+
- #endif /* !__ASSEMBLY__ */
-
- #endif
-diff -urN linux-2.6.5/include/asm-i386/elf.h linux-2.6.5/include/asm-i386/elf.h
---- linux-2.6.5/include/asm-i386/elf.h 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -70,7 +70,22 @@
- the loader. We need to make sure that it is out of the way of the program
- that it will "exec", and that there is sufficient room for the brk. */
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+#define ELF_ET_DYN_BASE ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3*2:TASK_SIZE/3*2)
-+#else
- #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
-+#endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) 0x08048000UL
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) 16
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) 16
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->flags & PF_PAX_SEGMEXEC ? 15 : 16)
-+#endif
-
- /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
- now struct_user_regs, they are different) */
-@@ -113,8 +128,11 @@
- * Architecture-neutral AT_ values in 0-17, leave some room
- * for more of them, start the x86-specific ones at 32.
- */
-+
-+#ifndef CONFIG_PAX_NOVSYSCALL
- #define AT_SYSINFO 32
- #define AT_SYSINFO_EHDR 33
-+#endif
-
- #ifdef __KERNEL__
- #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
-@@ -129,7 +147,14 @@
-
- #define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
- #define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
-+
-+#ifndef CONFIG_PAX_NOVSYSCALL
-+#ifdef CONFIG_PAX_SEGMEXEC
-+#define VSYSCALL_ENTRY ((current->flags & PF_PAX_SEGMEXEC) ? (unsigned long) &__kernel_vsyscall - SEGMEXEC_TASK_SIZE : (unsigned long) &__kernel_vsyscall)
-+#else
- #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
-+#endif
-+
- extern void __kernel_vsyscall;
-
- #define ARCH_DLINFO \
-@@ -185,3 +210,5 @@
- #endif
-
- #endif
-+
-+#endif
-diff -urN linux-2.6.5/include/asm-i386/mach-default/apm.h linux-2.6.5/include/asm-i386/mach-default/apm.h
---- linux-2.6.5/include/asm-i386/mach-default/apm.h 2004-04-03 22:36:26.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/mach-default/apm.h 2004-04-18 11:05:51.000000000 -0400
-@@ -36,7 +36,7 @@
- __asm__ __volatile__(APM_DO_ZERO_SEGS
- "pushl %%edi\n\t"
- "pushl %%ebp\n\t"
-- "lcall *%%cs:apm_bios_entry\n\t"
-+ "lcall *%%ss:apm_bios_entry\n\t"
- "setc %%al\n\t"
- "popl %%ebp\n\t"
- "popl %%edi\n\t"
-@@ -60,7 +60,7 @@
- __asm__ __volatile__(APM_DO_ZERO_SEGS
- "pushl %%edi\n\t"
- "pushl %%ebp\n\t"
-- "lcall *%%cs:apm_bios_entry\n\t"
-+ "lcall *%%ss:apm_bios_entry\n\t"
- "setc %%bl\n\t"
- "popl %%ebp\n\t"
- "popl %%edi\n\t"
-diff -urN linux-2.6.5/include/asm-i386/mach-pc9800/apm.h linux-2.6.5/include/asm-i386/mach-pc9800/apm.h
---- linux-2.6.5/include/asm-i386/mach-pc9800/apm.h 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/mach-pc9800/apm.h 2004-04-18 11:05:51.000000000 -0400
-@@ -39,7 +39,7 @@
- "pushl %%edi\n\t"
- "pushl %%ebp\n\t"
- "pushfl\n\t"
-- "lcall *%%cs:apm_bios_entry\n\t"
-+ "lcall *%%ss:apm_bios_entry\n\t"
- "setc %%al\n\t"
- "popl %%ebp\n\t"
- "popl %%edi\n\t"
-@@ -64,7 +64,7 @@
- "pushl %%edi\n\t"
- "pushl %%ebp\n\t"
- "pushfl\n\t"
-- "lcall *%%cs:apm_bios_entry\n\t"
-+ "lcall *%%ss:apm_bios_entry\n\t"
- "setc %%bl\n\t"
- "popl %%ebp\n\t"
- "popl %%edi\n\t"
-diff -urN linux-2.6.5/include/asm-i386/mman.h linux-2.6.5/include/asm-i386/mman.h
---- linux-2.6.5/include/asm-i386/mman.h 2004-04-03 22:36:24.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/mman.h 2004-04-18 11:05:51.000000000 -0400
-@@ -23,6 +23,10 @@
- #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
- #define MAP_NONBLOCK 0x10000 /* do not block on IO */
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+#define MAP_MIRROR 0x20000
-+#endif
-+
- #define MS_ASYNC 1 /* sync memory asynchronously */
- #define MS_INVALIDATE 2 /* invalidate the caches */
- #define MS_SYNC 4 /* synchronous memory sync */
-diff -urN linux-2.6.5/include/asm-i386/module.h linux-2.6.5/include/asm-i386/module.h
---- linux-2.6.5/include/asm-i386/module.h 2004-04-03 22:36:24.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/module.h 2004-04-18 11:05:51.000000000 -0400
-@@ -60,6 +60,12 @@
- #define MODULE_REGPARM ""
- #endif
-
--#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM
-+#ifdef CONFIG_GRKERNSEC
-+#define MODULE_GRSEC "GRSECURITY "
-+#else
-+#define MODULE_GRSEC ""
-+#endif
-+
-+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_GRSEC
-
- #endif /* _ASM_I386_MODULE_H */
-diff -urN linux-2.6.5/include/asm-i386/page.h linux-2.6.5/include/asm-i386/page.h
---- linux-2.6.5/include/asm-i386/page.h 2004-04-03 22:36:25.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/page.h 2004-04-18 11:05:51.000000000 -0400
-@@ -120,6 +120,19 @@
- #define __PAGE_OFFSET (0xC0000000UL)
- #endif
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+#ifdef __ASSEMBLY__
-+#define __KERNEL_TEXT_OFFSET (0xC0400000)
-+#else
-+#define __KERNEL_TEXT_OFFSET (0xC0400000UL)
-+#endif
-+#else
-+#ifdef __ASSEMBLY__
-+#define __KERNEL_TEXT_OFFSET (0)
-+#else
-+#define __KERNEL_TEXT_OFFSET (0x0UL)
-+#endif
-+#endif
-
- #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
- #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
-@@ -139,6 +152,15 @@
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
-
- #endif /* _I386_PAGE_H */
-diff -urN linux-2.6.5/include/asm-i386/pgalloc.h linux-2.6.5/include/asm-i386/pgalloc.h
---- linux-2.6.5/include/asm-i386/pgalloc.h 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/pgalloc.h 2004-04-18 11:05:51.000000000 -0400
-@@ -8,7 +8,7 @@
- #include <linux/mm.h> /* for struct page */
-
- #define pmd_populate_kernel(mm, pmd, pte) \
-- set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
-+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
-
- static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
- {
-diff -urN linux-2.6.5/include/asm-i386/pgtable.h linux-2.6.5/include/asm-i386/pgtable.h
---- linux-2.6.5/include/asm-i386/pgtable.h 2004-04-03 22:37:38.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/pgtable.h 2004-04-18 11:05:51.000000000 -0400
-@@ -32,6 +32,11 @@
- #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
- extern unsigned long empty_zero_page[1024];
- extern pgd_t swapper_pg_dir[1024];
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+extern pgd_t kernexec_pg_dir[1024];
-+#endif
-+
- extern kmem_cache_t *pgd_cache;
- extern kmem_cache_t *pmd_cache;
- extern spinlock_t pgd_lock;
-@@ -130,6 +135,16 @@
- #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
- #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
-+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-+#else
-+# define PAGE_SHARED_NOEXEC PAGE_SHARED
-+# define PAGE_COPY_NOEXEC PAGE_COPY
-+# define PAGE_READONLY_NOEXEC PAGE_READONLY
-+#endif
-+
- #define _PAGE_KERNEL \
- (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
-
-@@ -149,18 +164,18 @@
- * This is the closest we can get..
- */
- #define __P000 PAGE_NONE
--#define __P001 PAGE_READONLY
--#define __P010 PAGE_COPY
--#define __P011 PAGE_COPY
-+#define __P001 PAGE_READONLY_NOEXEC
-+#define __P010 PAGE_COPY_NOEXEC
-+#define __P011 PAGE_COPY_NOEXEC
- #define __P100 PAGE_READONLY
- #define __P101 PAGE_READONLY
- #define __P110 PAGE_COPY
- #define __P111 PAGE_COPY
-
- #define __S000 PAGE_NONE
--#define __S001 PAGE_READONLY
--#define __S010 PAGE_SHARED
--#define __S011 PAGE_SHARED
-+#define __S001 PAGE_READONLY_NOEXEC
-+#define __S010 PAGE_SHARED_NOEXEC
-+#define __S011 PAGE_SHARED_NOEXEC
- #define __S100 PAGE_READONLY
- #define __S101 PAGE_READONLY
- #define __S110 PAGE_SHARED
-diff -urN linux-2.6.5/include/asm-i386/processor.h linux-2.6.5/include/asm-i386/processor.h
---- linux-2.6.5/include/asm-i386/processor.h 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/processor.h 2004-04-18 11:05:51.000000000 -0400
-@@ -296,10 +296,19 @@
- */
- #define TASK_SIZE (PAGE_OFFSET)
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+#define SEGMEXEC_TASK_SIZE ((PAGE_OFFSET) / 2)
-+#endif
-+
- /* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+#define TASK_UNMAPPED_BASE (PAGE_ALIGN((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3:TASK_SIZE/3))
-+#else
- #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
-+#endif
-
- /*
- * Size of io_bitmap, covering ports 0 to 0x3ff.
-@@ -624,7 +633,7 @@
- extern inline void prefetch(const void *x)
- {
- alternative_input(ASM_NOP4,
-- "prefetchnta (%1)",
-+ "prefetchnta (%2)",
- X86_FEATURE_XMM,
- "r" (x));
- }
-@@ -638,7 +647,7 @@
- extern inline void prefetchw(const void *x)
- {
- alternative_input(ASM_NOP4,
-- "prefetchw (%1)",
-+ "prefetchw (%2)",
- X86_FEATURE_3DNOW,
- "r" (x));
- }
-diff -urN linux-2.6.5/include/asm-i386/system.h linux-2.6.5/include/asm-i386/system.h
---- linux-2.6.5/include/asm-i386/system.h 2004-04-03 22:36:13.000000000 -0500
-+++ linux-2.6.5/include/asm-i386/system.h 2004-04-18 11:05:51.000000000 -0400
-@@ -5,6 +5,7 @@
- #include <linux/kernel.h>
- #include <asm/segment.h>
- #include <asm/cpufeature.h>
-+#include <asm/page.h>
- #include <linux/bitops.h> /* for LOCK_PREFIX */
-
- #ifdef __KERNEL__
-@@ -301,7 +302,7 @@
- asm volatile ("661:\n\t" oldinstr "\n662:\n" \
- ".section .altinstructions,\"a\"\n" \
- " .align 4\n" \
-- " .long 661b\n" /* label */ \
-+ " .long 661b + %c1\n" /* label */ \
- " .long 663f\n" /* new instruction */ \
- " .byte %c0\n" /* feature bit */ \
- " .byte 662b-661b\n" /* sourcelen */ \
-@@ -309,7 +310,7 @@
- ".previous\n" \
- ".section .altinstr_replacement,\"ax\"\n" \
- "663:\n\t" newinstr "\n664:\n" /* replacement */ \
-- ".previous" :: "i" (feature) : "memory")
-+ ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET) : "memory")
-
- /*
- * Alternative inline assembly with input.
-@@ -325,7 +326,7 @@
- asm volatile ("661:\n\t" oldinstr "\n662:\n" \
- ".section .altinstructions,\"a\"\n" \
- " .align 4\n" \
-- " .long 661b\n" /* label */ \
-+ " .long 661b + %c1\n" /* label */ \
- " .long 663f\n" /* new instruction */ \
- " .byte %c0\n" /* feature bit */ \
- " .byte 662b-661b\n" /* sourcelen */ \
-@@ -333,7 +334,7 @@
- ".previous\n" \
- ".section .altinstr_replacement,\"ax\"\n" \
- "663:\n\t" newinstr "\n664:\n" /* replacement */ \
-- ".previous" :: "i" (feature), input)
-+ ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET), input)
-
- /*
- * Force strict CPU ordering.
-diff -urN linux-2.6.5/include/asm-ia64/elf.h linux-2.6.5/include/asm-ia64/elf.h
---- linux-2.6.5/include/asm-ia64/elf.h 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/include/asm-ia64/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -162,6 +162,16 @@
- typedef struct ia64_fpreg elf_fpreg_t;
- typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
-+#endif
-
-
- struct pt_regs; /* forward declaration... */
-diff -urN linux-2.6.5/include/asm-ia64/mman.h linux-2.6.5/include/asm-ia64/mman.h
---- linux-2.6.5/include/asm-ia64/mman.h 2004-04-03 22:37:07.000000000 -0500
-+++ linux-2.6.5/include/asm-ia64/mman.h 2004-04-18 11:05:51.000000000 -0400
-@@ -31,6 +31,10 @@
- #define MAP_POPULATE 0x08000 /* populate (prefault) pagetables */
- #define MAP_NONBLOCK 0x10000 /* do not block on IO */
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+#define MAP_MIRROR 0x40000
-+#endif
-+
- #define MS_ASYNC 1 /* sync memory asynchronously */
- #define MS_INVALIDATE 2 /* invalidate the caches */
- #define MS_SYNC 4 /* synchronous memory sync */
-diff -urN linux-2.6.5/include/asm-ia64/page.h linux-2.6.5/include/asm-ia64/page.h
---- linux-2.6.5/include/asm-ia64/page.h 2004-04-03 22:36:19.000000000 -0500
-+++ linux-2.6.5/include/asm-ia64/page.h 2004-04-18 11:05:51.000000000 -0400
-@@ -187,4 +187,13 @@
- (((current->thread.flags & IA64_THREAD_XSTACK) != 0) \
- ? VM_EXEC : 0))
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* _ASM_IA64_PAGE_H */
-diff -urN linux-2.6.5/include/asm-ia64/pgtable.h linux-2.6.5/include/asm-ia64/pgtable.h
---- linux-2.6.5/include/asm-ia64/pgtable.h 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/include/asm-ia64/pgtable.h 2004-04-18 11:05:51.000000000 -0400
-@@ -120,6 +120,17 @@
- #define PAGE_SHARED __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
- #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
- #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
-+# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
-+# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
-+#else
-+# define PAGE_SHARED_NOEXEC PAGE_SHARED
-+# define PAGE_READONLY_NOEXEC PAGE_READONLY
-+# define PAGE_COPY_NOEXEC PAGE_COPY
-+#endif
-+
- #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
- #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
- #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
-diff -urN linux-2.6.5/include/asm-ia64/ustack.h linux-2.6.5/include/asm-ia64/ustack.h
---- linux-2.6.5/include/asm-ia64/ustack.h 2004-04-03 22:38:21.000000000 -0500
-+++ linux-2.6.5/include/asm-ia64/ustack.h 2004-04-18 11:05:51.000000000 -0400
-@@ -11,6 +11,6 @@
- #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
- /* Make a default stack size of 2GB */
- #define DEFAULT_USER_STACK_SIZE (1UL << 31)
--#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
-+#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
-
- #endif /* _ASM_IA64_USTACK_H */
-diff -urN linux-2.6.5/include/asm-mips/a.out.h linux-2.6.5/include/asm-mips/a.out.h
---- linux-2.6.5/include/asm-mips/a.out.h 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/include/asm-mips/a.out.h 2004-04-18 11:05:51.000000000 -0400
-@@ -36,10 +36,10 @@
- #ifdef __KERNEL__
-
- #ifdef CONFIG_MIPS32
--#define STACK_TOP TASK_SIZE
-+#define __STACK_TOP TASK_SIZE
- #endif
- #ifdef CONFIG_MIPS64
--#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
-+#define __STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
- #endif
-
- #endif
-diff -urN linux-2.6.5/include/asm-mips/elf.h linux-2.6.5/include/asm-mips/elf.h
---- linux-2.6.5/include/asm-mips/elf.h 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/include/asm-mips/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -273,4 +273,15 @@
- #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
- #endif
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#endif
-+
- #endif /* _ASM_ELF_H */
-diff -urN linux-2.6.5/include/asm-mips/page.h linux-2.6.5/include/asm-mips/page.h
---- linux-2.6.5/include/asm-mips/page.h 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/include/asm-mips/page.h 2004-04-18 11:05:51.000000000 -0400
-@@ -130,6 +130,15 @@
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
- #define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
-
-diff -urN linux-2.6.5/include/asm-parisc/a.out.h linux-2.6.5/include/asm-parisc/a.out.h
---- linux-2.6.5/include/asm-parisc/a.out.h 2004-04-03 22:38:18.000000000 -0500
-+++ linux-2.6.5/include/asm-parisc/a.out.h 2004-04-18 11:05:51.000000000 -0400
-@@ -22,7 +22,7 @@
- /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
- * prumpf */
-
--#define STACK_TOP TASK_SIZE
-+#define __STACK_TOP TASK_SIZE
-
- #endif
-
-diff -urN linux-2.6.5/include/asm-parisc/elf.h linux-2.6.5/include/asm-parisc/elf.h
---- linux-2.6.5/include/asm-parisc/elf.h 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/include/asm-parisc/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -337,6 +337,17 @@
-
- #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) 16
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) 16
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) 16
-+#endif
-+
- /* This yields a mask that user programs can use to figure out what
- instruction set this CPU supports. This could be done in user space,
- but it's not easy, and we've already done it here. */
-diff -urN linux-2.6.5/include/asm-parisc/mman.h linux-2.6.5/include/asm-parisc/mman.h
---- linux-2.6.5/include/asm-parisc/mman.h 2004-04-03 22:37:24.000000000 -0500
-+++ linux-2.6.5/include/asm-parisc/mman.h 2004-04-18 11:05:51.000000000 -0400
-@@ -23,6 +23,10 @@
- #define MAP_POPULATE 0x10000 /* populate (prefault) pagetables */
- #define MAP_NONBLOCK 0x20000 /* do not block on IO */
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+#define MAP_MIRROR 0x0400
-+#endif
-+
- #define MS_SYNC 1 /* synchronous memory sync */
- #define MS_ASYNC 2 /* sync memory asynchronously */
- #define MS_INVALIDATE 4 /* invalidate the caches */
-diff -urN linux-2.6.5/include/asm-parisc/page.h linux-2.6.5/include/asm-parisc/page.h
---- linux-2.6.5/include/asm-parisc/page.h 2004-04-03 22:36:26.000000000 -0500
-+++ linux-2.6.5/include/asm-parisc/page.h 2004-04-18 11:05:51.000000000 -0400
-@@ -113,6 +113,15 @@
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
-
- #endif /* _PARISC_PAGE_H */
-diff -urN linux-2.6.5/include/asm-parisc/pgtable.h linux-2.6.5/include/asm-parisc/pgtable.h
---- linux-2.6.5/include/asm-parisc/pgtable.h 2004-04-03 22:38:13.000000000 -0500
-+++ linux-2.6.5/include/asm-parisc/pgtable.h 2004-04-18 11:05:51.000000000 -0400
-@@ -179,6 +179,17 @@
- #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
- #define PAGE_COPY PAGE_EXECREAD
- #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
-+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
-+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
-+#else
-+# define PAGE_SHARED_NOEXEC PAGE_SHARED
-+# define PAGE_COPY_NOEXEC PAGE_COPY
-+# define PAGE_READONLY_NOEXEC PAGE_READONLY
-+#endif
-+
- #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
- #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
- #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
-diff -urN linux-2.6.5/include/asm-ppc/a.out.h linux-2.6.5/include/asm-ppc/a.out.h
---- linux-2.6.5/include/asm-ppc/a.out.h 2004-04-03 22:37:07.000000000 -0500
-+++ linux-2.6.5/include/asm-ppc/a.out.h 2004-04-18 11:05:51.000000000 -0400
-@@ -2,7 +2,7 @@
- #define __PPC_A_OUT_H__
-
- /* grabbed from the intel stuff */
--#define STACK_TOP TASK_SIZE
-+#define __STACK_TOP TASK_SIZE
-
-
- struct exec
-diff -urN linux-2.6.5/include/asm-ppc/elf.h linux-2.6.5/include/asm-ppc/elf.h
---- linux-2.6.5/include/asm-ppc/elf.h 2004-04-03 22:36:13.000000000 -0500
-+++ linux-2.6.5/include/asm-ppc/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -87,6 +87,17 @@
-
- #define ELF_ET_DYN_BASE (0x08000000)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000000UL
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) 15
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) 15
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) 15
-+#endif
-+
- #define USE_ELF_CORE_DUMP
- #define ELF_EXEC_PAGESIZE 4096
-
-diff -urN linux-2.6.5/include/asm-ppc/mman.h linux-2.6.5/include/asm-ppc/mman.h
---- linux-2.6.5/include/asm-ppc/mman.h 2004-04-03 22:38:28.000000000 -0500
-+++ linux-2.6.5/include/asm-ppc/mman.h 2004-04-18 11:05:51.000000000 -0400
-@@ -24,6 +24,10 @@
- #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
- #define MAP_NONBLOCK 0x10000 /* do not block on IO */
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+#define MAP_MIRROR 0x0200
-+#endif
-+
- #define MS_ASYNC 1 /* sync memory asynchronously */
- #define MS_INVALIDATE 2 /* invalidate the caches */
- #define MS_SYNC 4 /* synchronous memory sync */
-diff -urN linux-2.6.5/include/asm-ppc/page.h linux-2.6.5/include/asm-ppc/page.h
---- linux-2.6.5/include/asm-ppc/page.h 2004-04-03 22:36:53.000000000 -0500
-+++ linux-2.6.5/include/asm-ppc/page.h 2004-04-18 11:05:51.000000000 -0400
-@@ -162,5 +162,14 @@
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
- #endif /* _PPC_PAGE_H */
-diff -urN linux-2.6.5/include/asm-ppc/pgtable.h linux-2.6.5/include/asm-ppc/pgtable.h
---- linux-2.6.5/include/asm-ppc/pgtable.h 2004-04-03 22:36:26.000000000 -0500
-+++ linux-2.6.5/include/asm-ppc/pgtable.h 2004-04-18 11:05:51.000000000 -0400
-@@ -349,11 +349,21 @@
-
- #define PAGE_NONE __pgprot(_PAGE_BASE)
- #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
--#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
- #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
--#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
-+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
- #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
--#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
-+
-+#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
-+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
-+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
-+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
-+#else
-+# define PAGE_SHARED_NOEXEC PAGE_SHARED
-+# define PAGE_COPY_NOEXEC PAGE_COPY
-+# define PAGE_READONLY_NOEXEC PAGE_READONLY
-+#endif
-
- #define PAGE_KERNEL __pgprot(_PAGE_RAM)
- #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
-@@ -365,21 +375,21 @@
- * This is the closest we can get..
- */
- #define __P000 PAGE_NONE
--#define __P001 PAGE_READONLY_X
--#define __P010 PAGE_COPY
--#define __P011 PAGE_COPY_X
--#define __P100 PAGE_READONLY
-+#define __P001 PAGE_READONLY_NOEXEC
-+#define __P010 PAGE_COPY_NOEXEC
-+#define __P011 PAGE_COPY_NOEXEC
-+#define __P100 PAGE_READONLY_X
- #define __P101 PAGE_READONLY_X
--#define __P110 PAGE_COPY
-+#define __P110 PAGE_COPY_X
- #define __P111 PAGE_COPY_X
-
- #define __S000 PAGE_NONE
--#define __S001 PAGE_READONLY_X
--#define __S010 PAGE_SHARED
--#define __S011 PAGE_SHARED_X
--#define __S100 PAGE_READONLY
-+#define __S001 PAGE_READONLY_NOEXEC
-+#define __S010 PAGE_SHARED_NOEXEC
-+#define __S011 PAGE_SHARED_NOEXEC
-+#define __S100 PAGE_READONLY_X
- #define __S101 PAGE_READONLY_X
--#define __S110 PAGE_SHARED
-+#define __S110 PAGE_SHARED_X
- #define __S111 PAGE_SHARED_X
-
- #ifndef __ASSEMBLY__
-diff -urN linux-2.6.5/include/asm-sparc/a.out.h linux-2.6.5/include/asm-sparc/a.out.h
---- linux-2.6.5/include/asm-sparc/a.out.h 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc/a.out.h 2004-04-18 11:05:51.000000000 -0400
-@@ -91,7 +91,7 @@
-
- #include <asm/page.h>
-
--#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
-+#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
-
- #endif /* __KERNEL__ */
-
-diff -urN linux-2.6.5/include/asm-sparc/elf.h linux-2.6.5/include/asm-sparc/elf.h
---- linux-2.6.5/include/asm-sparc/elf.h 2004-04-03 22:37:43.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -145,6 +145,17 @@
-
- #define ELF_ET_DYN_BASE (0x08000000)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) 16
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) 16
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) 16
-+#endif
-+
- /* This yields a mask that user programs can use to figure out what
- instruction set this cpu supports. This can NOT be done in userspace
- on Sparc. */
-diff -urN linux-2.6.5/include/asm-sparc/mman.h linux-2.6.5/include/asm-sparc/mman.h
---- linux-2.6.5/include/asm-sparc/mman.h 2004-04-03 22:38:20.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc/mman.h 2004-04-18 11:05:51.000000000 -0400
-@@ -27,6 +27,10 @@
- #define MAP_DENYWRITE 0x0800 /* ETXTBSY */
- #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+#define MAP_MIRROR 0x0400
-+#endif
-+
- #define MS_ASYNC 1 /* sync memory asynchronously */
- #define MS_INVALIDATE 2 /* invalidate the caches */
- #define MS_SYNC 4 /* synchronous memory sync */
-diff -urN linux-2.6.5/include/asm-sparc/page.h linux-2.6.5/include/asm-sparc/page.h
---- linux-2.6.5/include/asm-sparc/page.h 2004-04-03 22:36:53.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc/page.h 2004-04-18 11:05:51.000000000 -0400
-@@ -176,6 +176,15 @@
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
-
- #endif /* _SPARC_PAGE_H */
-diff -urN linux-2.6.5/include/asm-sparc/pgtable.h linux-2.6.5/include/asm-sparc/pgtable.h
---- linux-2.6.5/include/asm-sparc/pgtable.h 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc/pgtable.h 2004-04-18 11:05:51.000000000 -0400
-@@ -109,6 +109,13 @@
- BTFIXUPDEF_INT(page_shared)
- BTFIXUPDEF_INT(page_copy)
- BTFIXUPDEF_INT(page_readonly)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+BTFIXUPDEF_INT(page_shared_noexec)
-+BTFIXUPDEF_INT(page_copy_noexec)
-+BTFIXUPDEF_INT(page_readonly_noexec)
-+#endif
-+
- BTFIXUPDEF_INT(page_kernel)
-
- #define PMD_SHIFT BTFIXUP_SIMM13(pmd_shift)
-@@ -130,6 +137,16 @@
- #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
- #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+# define PAGE_SHARED_NOEXEC __pgprot(BTFIXUP_INT(page_shared_noexec))
-+# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
-+# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
-+#else
-+# define PAGE_SHARED_NOEXEC PAGE_SHARED
-+# define PAGE_COPY_NOEXEC PAGE_COPY
-+# define PAGE_READONLY_NOEXEC PAGE_READONLY
-+#endif
-+
- extern unsigned long page_kernel;
-
- #ifdef MODULE
-diff -urN linux-2.6.5/include/asm-sparc/pgtsrmmu.h linux-2.6.5/include/asm-sparc/pgtsrmmu.h
---- linux-2.6.5/include/asm-sparc/pgtsrmmu.h 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc/pgtsrmmu.h 2004-04-18 11:05:51.000000000 -0400
-@@ -103,6 +103,16 @@
- SRMMU_EXEC | SRMMU_REF)
- #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
- SRMMU_EXEC | SRMMU_REF)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
-+ SRMMU_WRITE | SRMMU_REF)
-+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
-+ SRMMU_REF)
-+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
-+ SRMMU_REF)
-+#endif
-+
- #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
- SRMMU_DIRTY | SRMMU_REF)
-
-diff -urN linux-2.6.5/include/asm-sparc/uaccess.h linux-2.6.5/include/asm-sparc/uaccess.h
---- linux-2.6.5/include/asm-sparc/uaccess.h 2004-04-03 22:38:14.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc/uaccess.h 2004-04-18 11:05:51.000000000 -0400
-@@ -41,7 +41,7 @@
- * No one can read/write anything from userland in the kernel space by setting
- * large size and address near to PAGE_OFFSET - a fault will break his intentions.
- */
--#define __user_ok(addr,size) ((addr) < STACK_TOP)
-+#define __user_ok(addr,size) ((addr) < __STACK_TOP)
- #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
- #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
- #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
-diff -urN linux-2.6.5/include/asm-sparc64/a.out.h linux-2.6.5/include/asm-sparc64/a.out.h
---- linux-2.6.5/include/asm-sparc64/a.out.h 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc64/a.out.h 2004-04-18 11:05:51.000000000 -0400
-@@ -95,7 +95,7 @@
-
- #ifdef __KERNEL__
-
--#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
-+#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
-
- #endif
-
-diff -urN linux-2.6.5/include/asm-sparc64/elf.h linux-2.6.5/include/asm-sparc64/elf.h
---- linux-2.6.5/include/asm-sparc64/elf.h 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc64/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -140,6 +140,16 @@
- #define ELF_ET_DYN_BASE 0x0000010000000000UL
- #endif
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) (PAGE_SHIFT + 1)
-+#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 14 : 28 )
-+#define PAX_DELTA_EXEC_LSB(tsk) (PAGE_SHIFT + 1)
-+#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 14 : 28 )
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 15 : 29 )
-+#endif
-
- /* This yields a mask that user programs can use to figure out what
- instruction set this cpu supports. */
-diff -urN linux-2.6.5/include/asm-sparc64/mman.h linux-2.6.5/include/asm-sparc64/mman.h
---- linux-2.6.5/include/asm-sparc64/mman.h 2004-04-03 22:37:06.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc64/mman.h 2004-04-18 11:05:51.000000000 -0400
-@@ -27,6 +27,10 @@
- #define MAP_DENYWRITE 0x0800 /* ETXTBSY */
- #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+#define MAP_MIRROR 0x0400
-+#endif
-+
- #define MS_ASYNC 1 /* sync memory asynchronously */
- #define MS_INVALIDATE 2 /* invalidate the caches */
- #define MS_SYNC 4 /* synchronous memory sync */
-diff -urN linux-2.6.5/include/asm-sparc64/page.h linux-2.6.5/include/asm-sparc64/page.h
---- linux-2.6.5/include/asm-sparc64/page.h 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc64/page.h 2004-04-18 11:05:51.000000000 -0400
-@@ -174,6 +174,15 @@
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* !(__KERNEL__) */
-
- #endif /* !(_SPARC64_PAGE_H) */
-diff -urN linux-2.6.5/include/asm-sparc64/pgtable.h linux-2.6.5/include/asm-sparc64/pgtable.h
---- linux-2.6.5/include/asm-sparc64/pgtable.h 2004-04-03 22:36:14.000000000 -0500
-+++ linux-2.6.5/include/asm-sparc64/pgtable.h 2004-04-18 11:05:51.000000000 -0400
-@@ -124,7 +124,8 @@
-
- /* Here are the SpitFire software bits we use in the TTE's. */
- #define _PAGE_FILE 0x0000000000001000 /* Pagecache page */
--#define _PAGE_MODIFIED 0x0000000000000800 /* Modified Page (ie. dirty) */
-+#define _PAGE_MODIFIED 0x0000000000001000 /* Modified Page (ie. dirty) */
-+#define _PAGE_EXEC 0x0000000000000800 /* Executable SW Bit */
- #define _PAGE_ACCESSED 0x0000000000000400 /* Accessed Page (ie. referenced) */
- #define _PAGE_READ 0x0000000000000200 /* Readable SW Bit */
- #define _PAGE_WRITE 0x0000000000000100 /* Writable SW Bit */
-@@ -160,34 +161,48 @@
-
- /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
- #define PAGE_SHARED __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
-- __ACCESS_BITS | _PAGE_WRITE)
-+ __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
-
- #define PAGE_COPY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
-- __ACCESS_BITS)
-+ __ACCESS_BITS | _PAGE_EXEC)
-
- #define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
-- __ACCESS_BITS)
-+ __ACCESS_BITS | _PAGE_EXEC)
-
- #define PAGE_KERNEL __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
-- __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS)
-+ __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS | \
-+ _PAGE_EXEC)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+# define PAGE_SHARED_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
-+ __ACCESS_BITS | _PAGE_WRITE)
-+# define PAGE_COPY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
-+ __ACCESS_BITS)
-+# define PAGE_READONLY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
-+ __ACCESS_BITS)
-+#else
-+# define PAGE_SHARED_NOEXEC PAGE_SHARED
-+# define PAGE_COPY_NOEXEC PAGE_COPY
-+# define PAGE_READONLY_NOEXEC PAGE_READONLY
-+#endif
-
- #define _PFN_MASK _PAGE_PADDR
-
- #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
-
- #define __P000 PAGE_NONE
--#define __P001 PAGE_READONLY
--#define __P010 PAGE_COPY
--#define __P011 PAGE_COPY
-+#define __P001 PAGE_READONLY_NOEXEC
-+#define __P010 PAGE_COPY_NOEXEC
-+#define __P011 PAGE_COPY_NOEXEC
- #define __P100 PAGE_READONLY
- #define __P101 PAGE_READONLY
- #define __P110 PAGE_COPY
- #define __P111 PAGE_COPY
-
- #define __S000 PAGE_NONE
--#define __S001 PAGE_READONLY
--#define __S010 PAGE_SHARED
--#define __S011 PAGE_SHARED
-+#define __S001 PAGE_READONLY_NOEXEC
-+#define __S010 PAGE_SHARED_NOEXEC
-+#define __S011 PAGE_SHARED_NOEXEC
- #define __S100 PAGE_READONLY
- #define __S101 PAGE_READONLY
- #define __S110 PAGE_SHARED
-diff -urN linux-2.6.5/include/asm-x86_64/a.out.h linux-2.6.5/include/asm-x86_64/a.out.h
---- linux-2.6.5/include/asm-x86_64/a.out.h 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/include/asm-x86_64/a.out.h 2004-04-18 11:05:51.000000000 -0400
-@@ -21,7 +21,7 @@
-
- #ifdef __KERNEL__
- #include <linux/thread_info.h>
--#define STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE)
-+#define __STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE)
- #endif
-
- #endif /* __A_OUT_GNU_H__ */
-diff -urN linux-2.6.5/include/asm-x86_64/elf.h linux-2.6.5/include/asm-x86_64/elf.h
---- linux-2.6.5/include/asm-x86_64/elf.h 2004-04-03 22:37:44.000000000 -0500
-+++ linux-2.6.5/include/asm-x86_64/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -89,6 +89,17 @@
-
- #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 24)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 24)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 24)
-+#endif
-+
- /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
- now struct_user_regs, they are different). Assumes current is the process
- getting dumped. */
-diff -urN linux-2.6.5/include/asm-x86_64/mman.h linux-2.6.5/include/asm-x86_64/mman.h
---- linux-2.6.5/include/asm-x86_64/mman.h 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/include/asm-x86_64/mman.h 2004-04-18 11:05:51.000000000 -0400
-@@ -24,6 +24,10 @@
- #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
- #define MAP_NONBLOCK 0x10000 /* do not block on IO */
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+#define MAP_MIRROR 0x8000
-+#endif
-+
- #define MS_ASYNC 1 /* sync memory asynchronously */
- #define MS_INVALIDATE 2 /* invalidate the caches */
- #define MS_SYNC 4 /* synchronous memory sync */
-diff -urN linux-2.6.5/include/asm-x86_64/page.h linux-2.6.5/include/asm-x86_64/page.h
---- linux-2.6.5/include/asm-x86_64/page.h 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/include/asm-x86_64/page.h 2004-04-18 11:05:51.000000000 -0400
-@@ -127,6 +127,16 @@
-
- #define __VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#define VM_DATA_DEFAULT_FLAGS __VM_DATA_DEFAULT_FLAGS
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#else
- #define __VM_STACK_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-@@ -137,6 +147,8 @@
- #define VM_STACK_DEFAULT_FLAGS \
- (test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags)
-
-+#endif
-+
- #define CONFIG_ARCH_GATE_AREA 1
-
- #ifndef __ASSEMBLY__
-diff -urN linux-2.6.5/include/asm-x86_64/pgalloc.h linux-2.6.5/include/asm-x86_64/pgalloc.h
---- linux-2.6.5/include/asm-x86_64/pgalloc.h 2004-04-03 22:37:07.000000000 -0500
-+++ linux-2.6.5/include/asm-x86_64/pgalloc.h 2004-04-18 11:05:51.000000000 -0400
-@@ -8,7 +8,7 @@
- #include <linux/mm.h>
-
- #define pmd_populate_kernel(mm, pmd, pte) \
-- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
-+ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
- #define pgd_populate(mm, pgd, pmd) \
- set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pmd)))
-
-diff -urN linux-2.6.5/include/asm-x86_64/pgtable.h linux-2.6.5/include/asm-x86_64/pgtable.h
---- linux-2.6.5/include/asm-x86_64/pgtable.h 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/include/asm-x86_64/pgtable.h 2004-04-18 11:05:51.000000000 -0400
-@@ -170,6 +170,10 @@
- #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
- #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
- #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-+
-+#define PAGE_READONLY_NOEXEC PAGE_READONLY
-+#define PAGE_SHARED_NOEXEC PAGE_SHARED
-+
- #define __PAGE_KERNEL \
- (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
- #define __PAGE_KERNEL_EXECUTABLE \
-diff -urN linux-2.6.5/include/linux/a.out.h linux-2.6.5/include/linux/a.out.h
---- linux-2.6.5/include/linux/a.out.h 2004-04-03 22:37:24.000000000 -0500
-+++ linux-2.6.5/include/linux/a.out.h 2004-04-18 11:05:51.000000000 -0400
-@@ -7,6 +7,16 @@
-
- #include <asm/a.out.h>
-
-+#ifdef CONFIG_PAX_RANDUSTACK
-+#define __DELTA_STACK (current->mm->delta_stack)
-+#else
-+#define __DELTA_STACK 0UL
-+#endif
-+
-+#ifndef STACK_TOP
-+#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
-+#endif
-+
- #endif /* __STRUCT_EXEC_OVERRIDE__ */
-
- /* these go in the N_MACHTYPE field */
-@@ -37,6 +47,14 @@
- M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
- };
-
-+/* Constants for the N_FLAGS field */
-+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
-+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
-+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
-+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
-+#define F_PAX_RANDEXEC 16 /* Randomize ET_EXEC base */
-+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
-+
- #if !defined (N_MAGIC)
- #define N_MAGIC(exec) ((exec).a_info & 0xffff)
- #endif
-diff -urN linux-2.6.5/include/linux/binfmts.h linux-2.6.5/include/linux/binfmts.h
---- linux-2.6.5/include/linux/binfmts.h 2004-04-03 22:37:07.000000000 -0500
-+++ linux-2.6.5/include/linux/binfmts.h 2004-04-18 11:05:51.000000000 -0400
-@@ -36,6 +36,7 @@
- of the time same as filename, but could be
- different for binfmt_{misc,script} */
- unsigned long loader, exec;
-+ int misc;
- };
-
- /*
-@@ -65,5 +66,8 @@
- extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
- extern int set_binfmt(struct linux_binfmt *new);
-
-+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
-+void pax_report_insns(void *pc, void *sp);
-+
- #endif /* __KERNEL__ */
- #endif /* _LINUX_BINFMTS_H */
-diff -urN linux-2.6.5/include/linux/elf.h linux-2.6.5/include/linux/elf.h
---- linux-2.6.5/include/linux/elf.h 2004-04-03 22:36:25.000000000 -0500
-+++ linux-2.6.5/include/linux/elf.h 2004-04-18 11:05:51.000000000 -0400
-@@ -35,6 +35,17 @@
- #define PT_HIPROC 0x7fffffff
- #define PT_GNU_EH_FRAME 0x6474e550
-
-+#define PT_GNU_STACK (PT_LOOS + 0x474e551)
-+#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
-+
-+/* Constants for the e_flags field */
-+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
-+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
-+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
-+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
-+#define EF_PAX_RANDEXEC 16 /* Randomize ET_EXEC base */
-+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
-+
- /* These constants define the different elf file types */
- #define ET_NONE 0
- #define ET_REL 1
-@@ -121,6 +132,8 @@
- #define DT_DEBUG 21
- #define DT_TEXTREL 22
- #define DT_JMPREL 23
-+#define DT_FLAGS 30
-+ #define DF_TEXTREL 0x00000004
- #define DT_LOPROC 0x70000000
- #define DT_HIPROC 0x7fffffff
-
-@@ -271,6 +284,19 @@
- #define PF_W 0x2
- #define PF_X 0x1
-
-+#define PF_PAGEEXEC (1 << 4) /* Enable PAGEEXEC */
-+#define PF_NOPAGEEXEC (1 << 5) /* Disable PAGEEXEC */
-+#define PF_SEGMEXEC (1 << 6) /* Enable SEGMEXEC */
-+#define PF_NOSEGMEXEC (1 << 7) /* Disable SEGMEXEC */
-+#define PF_MPROTECT (1 << 8) /* Enable MPROTECT */
-+#define PF_NOMPROTECT (1 << 9) /* Disable MPROTECT */
-+#define PF_RANDEXEC (1 << 10) /* Enable RANDEXEC */
-+#define PF_NORANDEXEC (1 << 11) /* Disable RANDEXEC */
-+#define PF_EMUTRAMP (1 << 12) /* Enable EMUTRAMP */
-+#define PF_NOEMUTRAMP (1 << 13) /* Disable EMUTRAMP */
-+#define PF_RANDMMAP (1 << 14) /* Enable RANDMMAP */
-+#define PF_NORANDMMAP (1 << 15) /* Disable RANDMMAP */
-+
- typedef struct elf32_phdr{
- Elf32_Word p_type;
- Elf32_Off p_offset;
-@@ -363,6 +389,8 @@
- #define EI_OSABI 7
- #define EI_PAD 8
-
-+#define EI_PAX 14
-+
- #define ELFMAG0 0x7f /* EI_MAG */
- #define ELFMAG1 'E'
- #define ELFMAG2 'L'
-@@ -419,6 +447,7 @@
- #define elfhdr elf32_hdr
- #define elf_phdr elf32_phdr
- #define elf_note elf32_note
-+#define elf_dyn Elf32_Dyn
-
- #else
-
-@@ -426,6 +455,7 @@
- #define elfhdr elf64_hdr
- #define elf_phdr elf64_phdr
- #define elf_note elf64_note
-+#define elf_dyn Elf64_Dyn
-
- #endif
-
-diff -urN linux-2.6.5/include/linux/fs.h linux-2.6.5/include/linux/fs.h
---- linux-2.6.5/include/linux/fs.h 2004-04-03 22:36:52.000000000 -0500
-+++ linux-2.6.5/include/linux/fs.h 2004-04-18 11:05:51.000000000 -0400
-@@ -1134,7 +1134,7 @@
-
- /* fs/open.c */
-
--extern int do_truncate(struct dentry *, loff_t start);
-+extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
- extern struct file *filp_open(const char *, int, int);
- extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
- extern int filp_close(struct file *, fl_owner_t id);
-diff -urN linux-2.6.5/include/linux/gracl.h linux-2.6.5/include/linux/gracl.h
---- linux-2.6.5/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/include/linux/gracl.h 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,246 @@
-+#ifndef GR_ACL_H
-+#define GR_ACL_H
-+#endif
-+#include <linux/grdefs.h>
-+#include <linux/resource.h>
-+#include <linux/dcache.h>
-+#include <asm/resource.h>
-+
-+/* * * * * * * * * * * * * * * * * * * * *
-+ * grsecurity ACL System
-+ * Main header file
-+ * Purpose: define most gracl data structures
-+ * * * * * * * * * * * * * * * * * * * * */
-+
-+/* Major status information */
-+
-+#define GR_VERSION "grsecurity 2.0"
-+
-+enum {
-+
-+ SHUTDOWN = 0,
-+ ENABLE = 1,
-+ SPROLE = 2,
-+ RELOAD = 3,
-+ SEGVMOD = 4,
-+ STATUS = 5,
-+ UNSPROLE = 6
-+};
-+
-+/* Password setup definitions
-+ * kernel/grhash.c */
-+enum {
-+ GR_PW_LEN = 128,
-+ GR_SALT_LEN = 16,
-+ GR_SHA_LEN = 32,
-+};
-+
-+enum {
-+ GR_SPROLE_LEN = 64,
-+};
-+
-+/* Begin Data Structures */
-+
-+struct sprole_pw {
-+ unsigned char *rolename;
-+ unsigned char salt[GR_SALT_LEN];
-+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
-+};
-+
-+struct name_entry {
-+ ino_t inode;
-+ dev_t device;
-+ char *name;
-+ __u16 len;
-+};
-+
-+struct acl_role_db {
-+ struct acl_role_label **r_hash;
-+ __u32 r_size;
-+};
-+
-+struct name_db {
-+ struct name_entry **n_hash;
-+ __u32 n_size;
-+};
-+
-+struct crash_uid {
-+ uid_t uid;
-+ unsigned long expires;
-+};
-+
-+struct gr_hash_struct {
-+ void **table;
-+ void **nametable;
-+ void *first;
-+ __u32 table_size;
-+ __u32 used_size;
-+ int type;
-+};
-+
-+/* Userspace Grsecurity ACL data structures */
-+struct acl_subject_label {
-+ char *filename;
-+ ino_t inode;
-+ dev_t device;
-+ __u32 mode;
-+ __u32 cap_mask;
-+ __u32 cap_lower;
-+
-+ struct rlimit res[RLIM_NLIMITS + 1];
-+ __u16 resmask;
-+
-+ __u8 user_trans_type;
-+ __u8 group_trans_type;
-+ uid_t *user_transitions;
-+ gid_t *group_transitions;
-+ __u16 user_trans_num;
-+ __u16 group_trans_num;
-+
-+ __u32 ip_proto[8];
-+ __u32 ip_type;
-+ struct acl_ip_label **ips;
-+ __u32 ip_num;
-+
-+ __u32 crashes;
-+ unsigned long expires;
-+
-+ struct acl_subject_label *parent_subject;
-+ struct gr_hash_struct *hash;
-+ struct acl_ip_label *ip_object;
-+ struct acl_subject_label *prev;
-+ struct acl_subject_label *next;
-+
-+ struct acl_object_label **obj_hash;
-+ __u32 obj_hash_size;
-+};
-+
-+struct role_allowed_ip {
-+ __u32 addr;
-+ __u32 netmask;
-+
-+ struct role_allowed_ip *prev;
-+ struct role_allowed_ip *next;
-+};
-+
-+struct role_transition {
-+ char *rolename;
-+
-+ struct role_transition *prev;
-+ struct role_transition *next;
-+};
-+
-+struct acl_role_label {
-+ char *rolename;
-+ uid_t uidgid;
-+ __u16 roletype;
-+
-+ __u16 auth_attempts;
-+ unsigned long expires;
-+
-+ struct acl_subject_label *root_label;
-+ struct gr_hash_struct *hash;
-+
-+ struct acl_role_label *prev;
-+ struct acl_role_label *next;
-+
-+ struct role_transition *transitions;
-+ struct role_allowed_ip *allowed_ips;
-+ struct acl_subject_label **subj_hash;
-+ __u32 subj_hash_size;
-+};
-+
-+struct user_acl_role_db {
-+ struct acl_role_label **r_table;
-+ __u32 r_entries; /* number of entries in table */
-+ __u32 s_entries; /* total number of subject acls */
-+ __u32 i_entries; /* total number of ip acls */
-+ __u32 o_entries; /* Total number of object acls */
-+ __u32 g_entries; /* total number of globbed objects */
-+ __u32 a_entries; /* total number of allowed ips */
-+ __u32 t_entries; /* total number of transitions */
-+};
-+
-+struct acl_object_label {
-+ char *filename;
-+ ino_t inode;
-+ dev_t device;
-+ __u32 mode;
-+
-+ struct acl_subject_label *nested;
-+ struct acl_object_label *globbed;
-+
-+ /* next two structures not used */
-+
-+ struct acl_object_label *prev;
-+ struct acl_object_label *next;
-+};
-+
-+struct acl_ip_label {
-+ __u32 addr;
-+ __u32 netmask;
-+ __u16 low, high;
-+ __u8 mode;
-+ __u32 type;
-+ __u32 proto[8];
-+
-+ /* next two structures not used */
-+
-+ struct acl_ip_label *prev;
-+ struct acl_ip_label *next;
-+};
-+
-+struct gr_arg {
-+ struct user_acl_role_db role_db;
-+ unsigned char pw[GR_PW_LEN];
-+ unsigned char salt[GR_SALT_LEN];
-+ unsigned char sum[GR_SHA_LEN];
-+ unsigned char sp_role[GR_SPROLE_LEN];
-+ struct sprole_pw *sprole_pws;
-+ dev_t segv_device;
-+ ino_t segv_inode;
-+ uid_t segv_uid;
-+ __u16 num_sprole_pws;
-+ __u16 mode;
-+};
-+
-+struct subject_map {
-+ struct acl_subject_label *user;
-+ struct acl_subject_label *kernel;
-+};
-+
-+struct acl_subj_map_db {
-+ struct subject_map **s_hash;
-+ __u32 s_size;
-+};
-+
-+/* End Data Structures Section */
-+
-+/* Hash functions generated by empirical testing by Brad Spengler
-+ Makes good use of the low bits of the inode. Generally 0-1 times
-+ in loop for successful match. 0-3 for unsuccessful match.
-+ Shift/add algorithm with modulus of table size and an XOR*/
-+
-+static __inline__ unsigned long
-+rhash(const uid_t uid, const __u16 type, const unsigned long sz)
-+{
-+ return (((uid << type) + (uid ^ type)) % sz);
-+}
-+
-+ static __inline__ unsigned long
-+shash(const struct acl_subject_label *userp, const unsigned long sz)
-+{
-+ return ((const unsigned long)userp % sz);
-+}
-+
-+static __inline__ unsigned long
-+fhash(const ino_t ino, const dev_t dev, const unsigned long sz)
-+{
-+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
-+}
-+
-+static __inline__ unsigned long
-+nhash(const char *name, const __u16 len, const unsigned long sz)
-+{
-+ return full_name_hash(name, len) % sz;
-+}
-diff -urN linux-2.6.5/include/linux/gralloc.h linux-2.6.5/include/linux/gralloc.h
---- linux-2.6.5/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/include/linux/gralloc.h 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,8 @@
-+#ifndef __GRALLOC_H
-+#define __GRALLOC_H
-+
-+void acl_free_all(void);
-+int acl_alloc_stack_init(unsigned long size);
-+void *acl_alloc(unsigned long len);
-+
-+#endif
-diff -urN linux-2.6.5/include/linux/grdefs.h linux-2.6.5/include/linux/grdefs.h
---- linux-2.6.5/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/include/linux/grdefs.h 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,116 @@
-+#ifndef GRDEFS_H
-+#define GRDEFS_H
-+
-+/* Begin grsecurity status declarations */
-+
-+enum {
-+ GR_READY = 0x01,
-+ GR_STATUS_INIT = 0x00 // disabled state
-+};
-+
-+/* Begin ACL declarations */
-+
-+/* Role flags */
-+
-+enum {
-+ GR_ROLE_USER = 0x0001,
-+ GR_ROLE_GROUP = 0x0002,
-+ GR_ROLE_DEFAULT = 0x0004,
-+ GR_ROLE_SPECIAL = 0x0008,
-+ GR_ROLE_AUTH = 0x0010,
-+ GR_ROLE_NOPW = 0x0020,
-+ GR_ROLE_GOD = 0x0040,
-+ GR_ROLE_LEARN = 0x0080,
-+ GR_ROLE_TPE = 0x0100
-+};
-+
-+/* ACL Subject and Object mode flags */
-+enum {
-+ GR_DELETED = 0x00000080
-+};
-+
-+/* ACL Object-only mode flags */
-+enum {
-+ GR_READ = 0x00000001,
-+ GR_APPEND = 0x00000002,
-+ GR_WRITE = 0x00000004,
-+ GR_EXEC = 0x00000008,
-+ GR_FIND = 0x00000010,
-+ GR_INHERIT = 0x00000040,
-+ GR_PTRACERD = 0x00000100,
-+ GR_SETID = 0x00000200,
-+ GR_CREATE = 0x00000400,
-+ GR_DELETE = 0x00000800,
-+ GR_NOPTRACE = 0x00001000,
-+ GR_AUDIT_READ = 0x00002000,
-+ GR_AUDIT_APPEND = 0x00004000,
-+ GR_AUDIT_WRITE = 0x00008000,
-+ GR_AUDIT_EXEC = 0x00010000,
-+ GR_AUDIT_FIND = 0x00020000,
-+ GR_AUDIT_INHERIT= 0x00040000,
-+ GR_AUDIT_SETID = 0x00080000,
-+ GR_AUDIT_CREATE = 0x00100000,
-+ GR_AUDIT_DELETE = 0x00200000,
-+ GR_SUPPRESS = 0x00400000,
-+ GR_NOLEARN = 0x00800000
-+};
-+
-+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
-+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
-+ GR_AUDIT_CREATE | GR_AUDIT_DELETE)
-+
-+/* ACL subject-only mode flags */
-+enum {
-+ GR_KILL = 0x00000001,
-+ GR_VIEW = 0x00000002,
-+ GR_PROTECTED = 0x00000100,
-+ GR_LEARN = 0x00000200,
-+ GR_OVERRIDE = 0x00000400,
-+ /* just a placeholder, this mode is only used in userspace */
-+ GR_DUMMY = 0x00000800,
-+ GR_PAXPAGE = 0x00001000,
-+ GR_PAXSEGM = 0x00002000,
-+ GR_PAXGCC = 0x00004000,
-+ GR_PAXRANDMMAP = 0x00008000,
-+ GR_PAXRANDEXEC = 0x00010000,
-+ GR_PAXMPROTECT = 0x00020000,
-+ GR_PROTSHM = 0x00040000,
-+ GR_KILLPROC = 0x00080000,
-+ GR_KILLIPPROC = 0x00100000,
-+ /* just a placeholder, this mode is only used in userspace */
-+ GR_NOTROJAN = 0x00200000,
-+ GR_PROTPROCFD = 0x00400000,
-+ GR_PROCACCT = 0x00800000,
-+ GR_RELAXPTRACE = 0x01000000,
-+ GR_NESTED = 0x02000000
-+};
-+
-+enum {
-+ GR_ID_USER = 0x01,
-+ GR_ID_GROUP = 0x02,
-+};
-+
-+enum {
-+ GR_ID_ALLOW = 0x01,
-+ GR_ID_DENY = 0x02,
-+};
-+
-+#define GR_CRASH_RES 11
-+#define GR_UIDTABLE_MAX 500
-+
-+/* begin resource learning section */
-+enum {
-+ GR_RLIM_CPU_BUMP = 60,
-+ GR_RLIM_FSIZE_BUMP = 50000,
-+ GR_RLIM_DATA_BUMP = 10000,
-+ GR_RLIM_STACK_BUMP = 1000,
-+ GR_RLIM_CORE_BUMP = 10000,
-+ GR_RLIM_RSS_BUMP = 500000,
-+ GR_RLIM_NPROC_BUMP = 1,
-+ GR_RLIM_NOFILE_BUMP = 5,
-+ GR_RLIM_MEMLOCK_BUMP = 50000,
-+ GR_RLIM_AS_BUMP = 500000,
-+ GR_RLIM_LOCKS_BUMP = 2
-+};
-+
-+#endif
-diff -urN linux-2.6.5/include/linux/grinternal.h linux-2.6.5/include/linux/grinternal.h
---- linux-2.6.5/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/include/linux/grinternal.h 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,201 @@
-+#ifndef __GRINTERNAL_H
-+#define __GRINTERNAL_H
-+
-+#ifdef CONFIG_GRKERNSEC
-+
-+#include <linux/fs.h>
-+#include <linux/grdefs.h>
-+#include <linux/grmsg.h>
-+
-+extern void gr_add_learn_entry(const char *fmt, ...);
-+extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
-+ const struct vfsmount *mnt);
-+extern __u32 gr_check_create(const struct dentry *new_dentry,
-+ const struct dentry *parent,
-+ const struct vfsmount *mnt, const __u32 mode);
-+extern int gr_check_protected_task(const struct task_struct *task);
-+extern __u32 to_gr_audit(const __u32 reqmode);
-+extern int gr_set_acls(const int type);
-+
-+extern void gr_handle_alertkill(void);
-+extern char *gr_to_filename(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern char *gr_to_filename1(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern char *gr_to_filename2(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern char *gr_to_filename3(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+
-+extern int grsec_enable_link;
-+extern int grsec_enable_fifo;
-+extern int grsec_enable_execve;
-+extern int grsec_enable_forkbomb;
-+extern int grsec_forkbomb_gid;
-+extern int grsec_forkbomb_sec;
-+extern int grsec_forkbomb_max;
-+extern int grsec_enable_execlog;
-+extern int grsec_enable_signal;
-+extern int grsec_enable_forkfail;
-+extern int grsec_enable_time;
-+extern int grsec_enable_chroot_shmat;
-+extern int grsec_enable_chroot_findtask;
-+extern int grsec_enable_chroot_mount;
-+extern int grsec_enable_chroot_double;
-+extern int grsec_enable_chroot_pivot;
-+extern int grsec_enable_chroot_chdir;
-+extern int grsec_enable_chroot_chmod;
-+extern int grsec_enable_chroot_mknod;
-+extern int grsec_enable_chroot_fchdir;
-+extern int grsec_enable_chroot_nice;
-+extern int grsec_enable_chroot_execlog;
-+extern int grsec_enable_chroot_caps;
-+extern int grsec_enable_chroot_sysctl;
-+extern int grsec_enable_chroot_unix;
-+extern int grsec_enable_tpe;
-+extern int grsec_tpe_gid;
-+extern int grsec_enable_tpe_all;
-+extern int grsec_enable_sidcaps;
-+extern int grsec_enable_randpid;
-+extern int grsec_enable_socket_all;
-+extern int grsec_socket_all_gid;
-+extern int grsec_enable_socket_client;
-+extern int grsec_socket_client_gid;
-+extern int grsec_enable_socket_server;
-+extern int grsec_socket_server_gid;
-+extern int grsec_audit_gid;
-+extern int grsec_enable_group;
-+extern int grsec_enable_audit_ipc;
-+extern int grsec_enable_audit_textrel;
-+extern int grsec_enable_mount;
-+extern int grsec_enable_chdir;
-+extern int grsec_lock;
-+
-+extern struct task_struct *child_reaper;
-+
-+extern spinlock_t grsec_alert_lock;
-+extern unsigned long grsec_alert_wtime;
-+extern unsigned long grsec_alert_fyet;
-+
-+extern spinlock_t grsec_alertgood_lock;
-+extern unsigned long grsec_alertgood_wtime;
-+extern unsigned long grsec_alertgood_fyet;
-+
-+extern spinlock_t grsec_audit_lock;
-+
-+#define gr_task_fullpath(tsk) (tsk->exec_file ? \
-+ gr_to_filename2(tsk->exec_file->f_dentry, \
-+ tsk->exec_file->f_vfsmnt) : "/")
-+
-+#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
-+ gr_to_filename3(tsk->parent->exec_file->f_dentry, \
-+ tsk->parent->exec_file->f_vfsmnt) : "/")
-+
-+#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
-+ gr_to_filename(tsk->exec_file->f_dentry, \
-+ tsk->exec_file->f_vfsmnt) : "/")
-+
-+#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
-+ gr_to_filename1(tsk->parent->exec_file->f_dentry, \
-+ tsk->parent->exec_file->f_vfsmnt) : "/")
-+
-+#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && \
-+ ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
-+ child_reaper->fs->root->d_inode->i_sb->s_dev) || \
-+ (tsk_a->fs->root->d_inode->i_ino != \
-+ child_reaper->fs->root->d_inode->i_ino)))
-+
-+#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_sb->s_dev == \
-+ tsk_b->fs->root->d_inode->i_sb->s_dev) && \
-+ (tsk_a->fs->root->d_inode->i_ino == \
-+ tsk_b->fs->root->d_inode->i_ino))
-+
-+#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
-+ current->pid, current->uid, \
-+ current->euid, current->gid, current->egid, \
-+ gr_parent_task_fullpath(current), \
-+ current->parent->comm, current->parent->pid, \
-+ current->parent->uid, current->parent->euid, \
-+ current->parent->gid, current->parent->egid
-+
-+#define GR_CHROOT_CAPS ( \
-+ CAP_TO_MASK(CAP_FOWNER) | \
-+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
-+ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
-+ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
-+ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
-+ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
-+ CAP_TO_MASK(CAP_IPC_OWNER))
-+
-+#define security_alert_good(normal_msg,args...) \
-+({ \
-+ spin_lock(&grsec_alertgood_lock); \
-+ \
-+ if (!grsec_alertgood_wtime || get_seconds() - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME) { \
-+ grsec_alertgood_wtime = get_seconds(); grsec_alertgood_fyet = 0; \
-+ if (current->curr_ip) \
-+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
-+ else \
-+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
-+ } else if((get_seconds() - grsec_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
-+ grsec_alertgood_fyet++; \
-+ if (current->curr_ip) \
-+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
-+ else \
-+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
-+ } else if (grsec_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
-+ grsec_alertgood_wtime = get_seconds(); grsec_alertgood_fyet++; \
-+ printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
-+ "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
-+ } \
-+ \
-+ spin_unlock(&grsec_alertgood_lock); \
-+})
-+
-+#define security_alert(normal_msg,args...) \
-+({ \
-+ spin_lock(&grsec_alert_lock); \
-+ \
-+ if (!grsec_alert_wtime || get_seconds() - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME) { \
-+ grsec_alert_wtime = get_seconds(); grsec_alert_fyet = 0; \
-+ if (current->curr_ip) \
-+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
-+ else \
-+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
-+ } else if((get_seconds() - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
-+ grsec_alert_fyet++; \
-+ if (current->curr_ip) \
-+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
-+ else \
-+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
-+ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
-+ grsec_alert_wtime = get_seconds(); grsec_alert_fyet++; \
-+ printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
-+ "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
-+ } \
-+ \
-+ gr_handle_alertkill(); \
-+ spin_unlock(&grsec_alert_lock); \
-+})
-+
-+#define security_audit(normal_msg,args...) \
-+({ \
-+ spin_lock(&grsec_audit_lock); \
-+ if (current->curr_ip) \
-+ printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \
-+ NIPQUAD(current->curr_ip) , ## args); \
-+ else \
-+ printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \
-+ spin_unlock(&grsec_audit_lock); \
-+})
-+
-+#define security_learn(normal_msg,args...) \
-+({ \
-+ preempt_disable(); \
-+ gr_add_learn_entry(normal_msg "\n", ## args); \
-+ preempt_enable(); \
-+})
-+
-+#endif
-+
-+#endif
-diff -urN linux-2.6.5/include/linux/grmsg.h linux-2.6.5/include/linux/grmsg.h
---- linux-2.6.5/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/include/linux/grmsg.h 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,108 @@
-+#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d, parent %.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d"
-+#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%d/%d gid/egid:%d/%d 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:%d/%d gid/egid:%d/%d"
-+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
-+#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
-+#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
-+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
-+#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
-+#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
-+#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
-+#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
-+#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
-+#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
-+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
-+#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"
-+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
-+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
-+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
-+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
-+#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
-+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
-+#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
-+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
-+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
-+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
-+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
-+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
-+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
-+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
-+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
-+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
-+#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
-+#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
-+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
-+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
-+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution for %lu seconds"
-+#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
-+#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
-+#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
-+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
-+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
-+#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
-+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
-+#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
-+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
-+#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
-+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
-+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
-+#define GR_INITF_ACL_MSG "init_variables() failed %s"
-+#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"
-+#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
-+#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
-+#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
-+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
-+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
-+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
-+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
-+#define GR_ENABLE_ACL_MSG "Loaded %s"
-+#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
-+#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
-+#define GR_RELOAD_ACL_MSG "Reloaded %s"
-+#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
-+#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
-+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
-+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
-+#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
-+#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
-+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
-+#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
-+#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
-+#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
-+#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
-+#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
-+#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
-+#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
-+#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
-+#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
-+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
-+#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
-+#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
-+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
-+#define GR_TIME_MSG "time set by " DEFAULTSECMSG
-+#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
-+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
-+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
-+#define GR_SOCK_MSG "attempted socket(%.16s,%.16s,%.16s) by " DEFAULTSECMSG
-+#define GR_SOCK2_MSG "attempted socket(%d,%.16s,%.16s) by " DEFAULTSECMSG
-+#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
-+#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
-+#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
-+#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
-+#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"
-+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
-+#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
-+#define GR_USRCHANGE_ACL_MSG "change to uid %d denied for " DEFAULTSECMSG
-+#define GR_GRPCHANGE_ACL_MSG "change to gid %d denied for " DEFAULTSECMSG
-+#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
-+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
-+#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
-+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
-+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
-+#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
-+#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
-+#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
-+#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
-+#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
-+#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
-+#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
-+#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " DEFAULTSECMSG
-diff -urN linux-2.6.5/include/linux/grsecurity.h linux-2.6.5/include/linux/grsecurity.h
---- linux-2.6.5/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/include/linux/grsecurity.h 2004-04-18 11:05:51.000000000 -0400
-@@ -0,0 +1,188 @@
-+#ifndef GR_SECURITY_H
-+#define GR_SECURITY_H
-+#include <linux/fs.h>
-+#include <linux/binfmts.h>
-+
-+extern int gr_check_user_change(int real, int effective, int fs);
-+extern int gr_check_group_change(int real, int effective, int fs);
-+
-+extern void gr_add_to_task_ip_table(struct task_struct *p);
-+extern void gr_del_task_from_ip_table(struct task_struct *p);
-+
-+extern int gr_pid_is_chrooted(const struct task_struct *p);
-+extern int gr_handle_chroot_nice(void);
-+extern int gr_handle_chroot_sysctl(const int op);
-+extern int gr_handle_chroot_capset(const struct task_struct *target);
-+extern int gr_handle_chroot_setpriority(struct task_struct *p,
-+ const int niceval);
-+extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
-+extern int gr_handle_chroot_chroot(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern void gr_handle_chroot_caps(struct task_struct *task);
-+extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
-+extern int gr_handle_chroot_chmod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, const int mode);
-+extern int gr_handle_chroot_mknod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, const int mode);
-+extern int gr_handle_chroot_mount(const struct dentry *dentry,
-+ const struct vfsmount *mnt,
-+ const char *dev_name);
-+extern int gr_handle_chroot_pivot(void);
-+extern int gr_handle_chroot_unix(const pid_t pid);
-+
-+extern int gr_handle_rawio(const struct inode *inode);
-+extern int gr_handle_nproc(void);
-+
-+extern void gr_handle_ioperm(void);
-+extern void gr_handle_iopl(void);
-+
-+extern int gr_tpe_allow(const struct file *file);
-+
-+extern int gr_random_pid(void);
-+
-+extern void gr_log_forkfail(const int retval);
-+extern void gr_log_timechange(void);
-+extern void gr_log_signal(const int sig, const struct task_struct *t);
-+extern void gr_log_chdir(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern void gr_log_chroot_exec(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
-+extern void gr_log_remount(const char *devname, const int retval);
-+extern void gr_log_unmount(const char *devname, const int retval);
-+extern void gr_log_mount(const char *from, const char *to, const int retval);
-+extern void gr_log_msgget(const int ret, const int msgflg);
-+extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
-+extern void gr_log_semget(const int err, const int semflg);
-+extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
-+extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
-+extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
-+extern void gr_log_textrel(struct vm_area_struct *vma);
-+
-+extern int gr_handle_follow_link(const struct inode *parent,
-+ const struct inode *inode,
-+ const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern int gr_handle_fifo(const struct dentry *dentry,
-+ const struct vfsmount *mnt,
-+ const struct dentry *dir, const int flag,
-+ const int acc_mode);
-+extern int gr_handle_hardlink(const struct dentry *dentry,
-+ const struct vfsmount *mnt,
-+ struct inode *inode,
-+ const int mode, const char *to);
-+
-+extern int gr_task_is_capable(struct task_struct *task, const int cap);
-+extern int gr_is_capable_nolog(const int cap);
-+extern void gr_learn_resource(const struct task_struct *task, const int limit,
-+ const unsigned long wanted, const int gt);
-+extern void gr_copy_label(struct task_struct *tsk);
-+extern void gr_handle_crash(struct task_struct *task, const int sig);
-+extern int gr_handle_signal(const struct task_struct *p, const int sig);
-+extern int gr_check_crash_uid(const uid_t uid);
-+extern int gr_check_protected_task(const struct task_struct *task);
-+extern int gr_acl_handle_mmap(const struct file *file,
-+ const unsigned long prot);
-+extern int gr_acl_handle_mprotect(const struct file *file,
-+ const unsigned long prot);
-+extern int gr_check_hidden_task(const struct task_struct *tsk);
-+extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern __u32 gr_acl_handle_access(const struct dentry *dentry,
-+ const struct vfsmount *mnt, const int fmode);
-+extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, mode_t mode);
-+extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
-+ const struct vfsmount *mnt, mode_t mode);
-+extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern int gr_handle_ptrace_exec(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern int gr_handle_ptrace(struct task_struct *task, const long request);
-+extern int gr_handle_proc_ptrace(struct task_struct *task);
-+extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
-+extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern int gr_check_crash_exec(const struct file *filp);
-+extern int gr_acl_is_enabled(void);
-+extern void gr_set_kernel_label(struct task_struct *task);
-+extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
-+ const gid_t gid);
-+extern void gr_set_proc_label(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern __u32 gr_acl_handle_open(const struct dentry *dentry,
-+ const struct vfsmount *mnt, const int fmode);
-+extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
-+ const struct dentry *p_dentry,
-+ const struct vfsmount *p_mnt, const int fmode,
-+ const int imode);
-+extern void gr_handle_create(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
-+ const struct dentry *parent_dentry,
-+ const struct vfsmount *parent_mnt,
-+ const int mode);
-+extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
-+ const struct dentry *parent_dentry,
-+ const struct vfsmount *parent_mnt);
-+extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern void gr_handle_delete(const ino_t ino, const dev_t dev);
-+extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
-+ const struct dentry *parent_dentry,
-+ const struct vfsmount *parent_mnt,
-+ const char *from);
-+extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
-+ const struct dentry *parent_dentry,
-+ const struct vfsmount *parent_mnt,
-+ const struct dentry *old_dentry,
-+ const struct vfsmount *old_mnt, const char *to);
-+extern int gr_acl_handle_rename(struct dentry *new_dentry,
-+ struct dentry *parent_dentry,
-+ const struct vfsmount *parent_mnt,
-+ struct dentry *old_dentry,
-+ struct inode *old_parent_inode,
-+ struct vfsmount *old_mnt, const char *newname);
-+extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
-+ struct dentry *old_dentry,
-+ struct dentry *new_dentry,
-+ struct vfsmount *mnt, const __u8 replace);
-+extern __u32 gr_check_link(const struct dentry *new_dentry,
-+ const struct dentry *parent_dentry,
-+ const struct vfsmount *parent_mnt,
-+ const struct dentry *old_dentry,
-+ const struct vfsmount *old_mnt);
-+extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
-+ const struct vfsmount *mnt, const ino_t ino);
-+extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
-+ const struct vfsmount *mnt);
-+extern void gr_acl_handle_exit(void);
-+extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
-+extern int gr_acl_handle_procpidmem(const struct task_struct *task);
-+extern __u32 gr_cap_rtnetlink(void);
-+
-+#ifdef CONFIG_GRKERNSEC
-+extern void gr_handle_mem_write(void);
-+extern void gr_handle_kmem_write(void);
-+extern void gr_handle_open_port(void);
-+extern int gr_handle_mem_mmap(const unsigned long offset,
-+ struct vm_area_struct *vma);
-+
-+extern __u16 ip_randomid(void);
-+extern __u32 ip_randomisn(void);
-+extern unsigned long get_random_long(void);
-+
-+extern int grsec_enable_dmesg;
-+extern int grsec_enable_randid;
-+extern int grsec_enable_randisn;
-+extern int grsec_enable_randsrc;
-+extern int grsec_enable_randrpc;
-+#endif
-+
-+#endif
-diff -urN linux-2.6.5/include/linux/mm.h linux-2.6.5/include/linux/mm.h
---- linux-2.6.5/include/linux/mm.h 2004-04-03 22:36:15.000000000 -0500
-+++ linux-2.6.5/include/linux/mm.h 2004-04-18 11:05:51.000000000 -0400
-@@ -25,6 +25,7 @@
- #include <asm/pgtable.h>
- #include <asm/processor.h>
- #include <asm/atomic.h>
-+#include <asm/mman.h>
-
- #ifndef MM_VM_SIZE
- #define MM_VM_SIZE(mm) TASK_SIZE
-@@ -115,6 +116,18 @@
- /* It makes sense to apply VM_ACCOUNT to this vma. */
- #define VM_MAYACCT(vma) (!!((vma)->vm_flags & VM_HUGETLB))
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+#define VM_MIRROR 0x01000000 /* vma is mirroring another */
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+#define VM_MAYNOTWRITE 0x02000000 /* vma cannot be granted VM_WRITE any more */
-+#endif
-+
-+#ifdef __VM_STACK_FLAGS
-+#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
-+#endif
-+
- #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
- #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
- #endif
-@@ -549,21 +562,48 @@
- unsigned long len, unsigned long prot,
- unsigned long flag, unsigned long pgoff);
-
-+extern int do_munmap(struct mm_struct *, unsigned long, size_t);
-+
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- unsigned long len, unsigned long prot,
- unsigned long flag, unsigned long offset)
- {
- unsigned long ret = -EINVAL;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if ((current->flags & PF_PAX_SEGMEXEC) &&
-+ (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len)))
-+ goto out;
-+#endif
-+
- if ((offset + PAGE_ALIGN(len)) < offset)
- goto out;
- if (!(offset & ~PAGE_MASK))
- ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if ((current->flags & PF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flag & MAP_TYPE) == MAP_PRIVATE)
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ && (!(current->flags & PF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
-+#endif
-+
-+ )
-+ {
-+ unsigned long ret_m;
-+ prot = prot & PROT_EXEC ? prot : PROT_NONE;
-+ ret_m = do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flag | MAP_MIRROR | MAP_FIXED, ret);
-+ if (ret_m >= TASK_SIZE) {
-+ do_munmap(current->mm, ret, len);
-+ ret = ret_m;
-+ }
-+ }
-+#endif
-+
- out:
- return ret;
- }
-
--extern int do_munmap(struct mm_struct *, unsigned long, size_t);
--
- extern unsigned long do_brk(unsigned long, unsigned long);
-
- static inline void
-@@ -579,6 +619,12 @@
- static inline int
- can_vma_merge(struct vm_area_struct *vma, unsigned long vm_flags)
- {
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if ((vma->vm_flags | vm_flags) & VM_MIRROR)
-+ return 0;
-+#endif
-+
- #ifdef CONFIG_MMU
- if (!vma->vm_file && vma->vm_flags == vm_flags)
- return 1;
-diff -urN linux-2.6.5/include/linux/mman.h linux-2.6.5/include/linux/mman.h
---- linux-2.6.5/include/linux/mman.h 2004-04-03 22:36:19.000000000 -0500
-+++ linux-2.6.5/include/linux/mman.h 2004-04-18 11:05:51.000000000 -0400
-@@ -56,6 +56,11 @@
- calc_vm_flag_bits(unsigned long flags)
- {
- return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
-+#endif
-+
- _calc_vm_trans(flags, MAP_DENYWRITE, VM_DENYWRITE ) |
- _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
- _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED );
-diff -urN linux-2.6.5/include/linux/proc_fs.h linux-2.6.5/include/linux/proc_fs.h
---- linux-2.6.5/include/linux/proc_fs.h 2004-04-03 22:38:28.000000000 -0500
-+++ linux-2.6.5/include/linux/proc_fs.h 2004-04-18 11:05:51.000000000 -0400
-@@ -226,7 +226,7 @@
-
- #endif /* CONFIG_PROC_FS */
-
--#if !defined(CONFIG_PROC_FS)
-+#if !defined(CONFIG_PROC_FS) || !defined(CONFIG_PROC_KCORE)
- static inline void kclist_add(struct kcore_list *new, void *addr, size_t size)
- {
- }
-diff -urN linux-2.6.5/include/linux/random.h linux-2.6.5/include/linux/random.h
---- linux-2.6.5/include/linux/random.h 2004-04-03 22:38:24.000000000 -0500
-+++ linux-2.6.5/include/linux/random.h 2004-04-18 11:05:51.000000000 -0400
-@@ -69,6 +69,8 @@
-
- extern __u32 secure_ipv6_id(__u32 *daddr);
-
-+extern unsigned long pax_get_random_long(void);
-+
- #ifndef MODULE
- extern struct file_operations random_fops, urandom_fops;
- #endif
-diff -urN linux-2.6.5/include/linux/sched.h linux-2.6.5/include/linux/sched.h
---- linux-2.6.5/include/linux/sched.h 2004-04-03 22:36:18.000000000 -0500
-+++ linux-2.6.5/include/linux/sched.h 2004-04-18 11:05:51.000000000 -0400
-@@ -31,6 +31,7 @@
- #include <linux/percpu.h>
-
- struct exec_domain;
-+struct linux_binprm;
-
- /*
- * cloning flags:
-@@ -228,6 +229,21 @@
- struct kioctx *ioctx_list;
-
- struct kioctx default_kioctx;
-+
-+#ifdef CONFIG_PAX_DLRESOLVE
-+ unsigned long call_dl_resolve;
-+#endif
-+
-+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
-+ unsigned long call_syscall;
-+#endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+ unsigned long delta_mmap; /* randomized offset */
-+ unsigned long delta_exec; /* randomized offset */
-+ unsigned long delta_stack; /* randomized offset */
-+#endif
-+
- };
-
- extern int mmlist_nr;
-@@ -493,6 +509,22 @@
-
- unsigned long ptrace_message;
- siginfo_t *last_siginfo; /* For ptrace use. */
-+
-+#ifdef CONFIG_GRKERNSEC
-+ /* grsecurity */
-+ struct acl_subject_label *acl;
-+ struct acl_role_label *role;
-+ struct file *exec_file;
-+ u32 curr_ip;
-+ u32 gr_saddr;
-+ u32 gr_daddr;
-+ u16 gr_sport;
-+ u16 gr_dport;
-+ u16 acl_role_id;
-+ u8 acl_sp_role:1;
-+ u8 used_accept:1;
-+ u8 is_writable:1;
-+#endif
- };
-
- static inline pid_t process_group(struct task_struct *tsk)
-@@ -530,6 +562,29 @@
- #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */
- #define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */
-
-+#define PF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
-+#define PF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
-+#define PF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
-+#define PF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
-+#define PF_PAX_RANDEXEC 0x10000000 /* Randomize ET_EXEC base */
-+#define PF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
-+extern unsigned int pax_aslr;
-+#endif
-+
-+extern unsigned int pax_softmode;
-+#endif
-+
-+extern int pax_check_flags(unsigned long *);
-+
-+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
-+extern void pax_set_flags(struct linux_binprm * bprm);
-+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
-+extern void (*pax_set_flags_func)(struct linux_binprm * bprm);
-+#endif
-+
- #ifdef CONFIG_SMP
- extern int set_cpus_allowed(task_t *p, cpumask_t new_mask);
- #else
-@@ -675,14 +730,29 @@
- : on_sig_stack(sp) ? SS_ONSTACK : 0);
- }
-
-+extern int gr_task_is_capable(struct task_struct *task, const int cap);
-+extern int gr_is_capable_nolog(const int cap);
-
- #ifdef CONFIG_SECURITY
- /* code is in security.c */
- extern int capable(int cap);
-+static inline int capable_nolog(int cap)
-+{
-+ return capable(cap);
-+}
- #else
- static inline int capable(int cap)
- {
-- if (cap_raised(current->cap_effective, cap)) {
-+ if (cap_raised(current->cap_effective, cap) && gr_task_is_capable(current, cap)) {
-+ current->flags |= PF_SUPERPRIV;
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static inline int capable_nolog(int cap)
-+{
-+ if (cap_raised(current->cap_effective, cap) && gr_is_capable_nolog(cap)) {
- current->flags |= PF_SUPERPRIV;
- return 1;
- }
-diff -urN linux-2.6.5/include/linux/shm.h linux-2.6.5/include/linux/shm.h
---- linux-2.6.5/include/linux/shm.h 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/include/linux/shm.h 2004-04-18 11:05:51.000000000 -0400
-@@ -84,6 +84,10 @@
- time_t shm_ctim;
- pid_t shm_cprid;
- pid_t shm_lprid;
-+#ifdef CONFIG_GRKERNSEC
-+ time_t shm_createtime;
-+ pid_t shm_lapid;
-+#endif
- };
-
- /* shm_mode upper byte flags */
-diff -urN linux-2.6.5/include/linux/sysctl.h linux-2.6.5/include/linux/sysctl.h
---- linux-2.6.5/include/linux/sysctl.h 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/include/linux/sysctl.h 2004-04-18 11:05:51.000000000 -0400
-@@ -131,8 +131,21 @@
- KERN_PRINTK_RATELIMIT_BURST=61, /* int: tune printk ratelimiting */
- KERN_PTY=62, /* dir: pty driver */
- KERN_NGROUPS_MAX=63, /* int: NGROUPS_MAX */
-+ KERN_GRSECURITY=68, /* grsecurity */
-+
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ KERN_PAX=69, /* PaX control */
-+#endif
-+
- };
-
-+#ifdef CONFIG_PAX_SOFTMODE
-+enum {
-+ PAX_ASLR=1, /* PaX: disable/enable all randomization features */
-+ PAX_SOFTMODE=2 /* PaX: disable/enable soft mode */
-+};
-+#endif
-
- /* CTL_VM names: */
- enum
-diff -urN linux-2.6.5/include/net/ip.h linux-2.6.5/include/net/ip.h
---- linux-2.6.5/include/net/ip.h 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/include/net/ip.h 2004-04-18 11:05:51.000000000 -0400
-@@ -33,6 +33,11 @@
- #include <net/route.h>
- #include <net/arp.h>
-
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+extern int grsec_enable_randid;
-+extern __u16 ip_randomid(void);
-+#endif
-+
- #ifndef _SNMP_H
- #include <net/snmp.h>
- #endif
-@@ -188,6 +193,13 @@
-
- static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk)
- {
-+
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+ if (grsec_enable_randid)
-+ iph->id = htons(ip_randomid());
-+ else
-+#endif
-+
- if (iph->frag_off & htons(IP_DF)) {
- /* This is only to work around buggy Windows95/2000
- * VJ compression implementations. If the ID field
-diff -urN linux-2.6.5/init/Kconfig linux-2.6.5/init/Kconfig
---- linux-2.6.5/init/Kconfig 2004-04-03 22:37:44.000000000 -0500
-+++ linux-2.6.5/init/Kconfig 2004-04-18 11:05:51.000000000 -0400
-@@ -193,6 +193,7 @@
- config KALLSYMS
- bool "Load all symbols for debugging/kksymoops" if EMBEDDED
- default y
-+ depends on !GRKERNSEC_HIDESYM
- help
- Say Y here to let the kernel print out symbolic crash information and
- symbolic stack backtraces. This increases the size of the kernel
-diff -urN linux-2.6.5/init/do_mounts.c linux-2.6.5/init/do_mounts.c
---- linux-2.6.5/init/do_mounts.c 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/init/do_mounts.c 2004-04-18 11:05:51.000000000 -0400
-@@ -287,6 +287,7 @@
- case -EINVAL:
- continue;
- }
-+
- /*
- * Allow the user to distinguish between failed sys_open
- * and bad superblock on root device.
-diff -urN linux-2.6.5/init/main.c linux-2.6.5/init/main.c
---- linux-2.6.5/init/main.c 2004-04-03 22:36:25.000000000 -0500
-+++ linux-2.6.5/init/main.c 2004-04-18 11:05:51.000000000 -0400
-@@ -89,6 +89,7 @@
- extern void free_initmem(void);
- extern void populate_rootfs(void);
- extern void driver_init(void);
-+extern void grsecurity_init(void);
-
- #ifdef CONFIG_TC
- extern void tc_init(void);
-@@ -605,7 +606,7 @@
- do_basic_setup();
-
- prepare_namespace();
--
-+ grsecurity_init();
- /*
- * Ok, we have completed the initial bootup, and
- * we're essentially up and running. Get rid of the
-diff -urN linux-2.6.5/ipc/msg.c linux-2.6.5/ipc/msg.c
---- linux-2.6.5/ipc/msg.c 2004-04-03 22:36:13.000000000 -0500
-+++ linux-2.6.5/ipc/msg.c 2004-04-18 11:05:51.000000000 -0400
-@@ -24,6 +24,7 @@
- #include <linux/list.h>
- #include <linux/security.h>
- #include <linux/sched.h>
-+#include <linux/grsecurity.h>
- #include <asm/current.h>
- #include <asm/uaccess.h>
- #include "util.h"
-@@ -331,6 +332,9 @@
- msg_unlock(msq);
- }
- up(&msg_ids.sem);
-+
-+ gr_log_msgget(ret, msgflg);
-+
- return ret;
- }
-
-@@ -580,6 +584,8 @@
- break;
- }
- case IPC_RMID:
-+ gr_log_msgrm(ipcp->uid, ipcp->cuid);
-+
- freeque (msq, msqid);
- break;
- }
-diff -urN linux-2.6.5/ipc/sem.c linux-2.6.5/ipc/sem.c
---- linux-2.6.5/ipc/sem.c 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/ipc/sem.c 2004-04-18 11:05:51.000000000 -0400
-@@ -71,6 +71,7 @@
- #include <linux/time.h>
- #include <linux/smp_lock.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
- #include <asm/uaccess.h>
- #include "util.h"
-
-@@ -238,6 +239,9 @@
- }
-
- up(&sem_ids.sem);
-+
-+ gr_log_semget(err, semflg);
-+
- return err;
- }
-
-@@ -804,6 +808,8 @@
-
- switch(cmd){
- case IPC_RMID:
-+ gr_log_semrm(ipcp->uid, ipcp->cuid);
-+
- freeary(sma, semid);
- err = 0;
- break;
-diff -urN linux-2.6.5/ipc/shm.c linux-2.6.5/ipc/shm.c
---- linux-2.6.5/ipc/shm.c 2004-04-03 22:37:07.000000000 -0500
-+++ linux-2.6.5/ipc/shm.c 2004-04-18 11:05:51.000000000 -0400
-@@ -26,6 +26,7 @@
- #include <linux/proc_fs.h>
- #include <linux/shmem_fs.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
- #include <asm/uaccess.h>
-
- #include "util.h"
-@@ -50,6 +51,14 @@
- static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
- #endif
-
-+#ifdef CONFIG_GRKERNSEC
-+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
-+ const time_t shm_createtime, const uid_t cuid,
-+ const int shmid);
-+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
-+ const time_t shm_createtime);
-+#endif
-+
- size_t shm_ctlmax = SHMMAX;
- size_t shm_ctlall = SHMALL;
- int shm_ctlmni = SHMMNI;
-@@ -213,6 +222,9 @@
- shp->shm_lprid = 0;
- shp->shm_atim = shp->shm_dtim = 0;
- shp->shm_ctim = get_seconds();
-+#ifdef CONFIG_GRKERNSEC
-+ shp->shm_createtime = get_seconds();
-+#endif
- shp->shm_segsz = size;
- shp->shm_nattch = 0;
- shp->id = shm_buildid(id,shp->shm_perm.seq);
-@@ -267,6 +279,8 @@
- }
- up(&shm_ids.sem);
-
-+ gr_log_shmget(err, shmflg, size);
-+
- return err;
- }
-
-@@ -567,6 +581,8 @@
- if (err)
- goto out_unlock_up;
-
-+ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
-+
- if (shp->shm_nattch){
- shp->shm_flags |= SHM_DEST;
- /* Do not find it any more */
-@@ -705,9 +721,27 @@
- return err;
- }
-
-+#ifdef CONFIG_GRKERNSEC
-+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
-+ shp->shm_perm.cuid, shmid)) {
-+ shm_unlock(shp);
-+ return -EACCES;
-+ }
-+
-+ if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
-+ shm_unlock(shp);
-+ return -EACCES;
-+ }
-+#endif
-+
- file = shp->shm_file;
- size = i_size_read(file->f_dentry->d_inode);
- shp->shm_nattch++;
-+
-+#ifdef CONFIG_GRKERNSEC
-+ shp->shm_lapid = current->pid;
-+#endif
-+
- shm_unlock(shp);
-
- down_write(&current->mm->mmap_sem);
-diff -urN linux-2.6.5/kernel/capability.c linux-2.6.5/kernel/capability.c
---- linux-2.6.5/kernel/capability.c 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/kernel/capability.c 2004-04-18 11:05:51.000000000 -0400
-@@ -10,6 +10,7 @@
- #include <linux/mm.h>
- #include <linux/module.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
- #include <asm/uaccess.h>
-
- unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
-@@ -168,6 +169,11 @@
- } else
- target = current;
-
-+ if (gr_handle_chroot_capset(target)) {
-+ ret = -ESRCH;
-+ goto out;
-+ }
-+
- ret = -EPERM;
-
- if (security_capset_check(target, &effective, &inheritable, &permitted))
-diff -urN linux-2.6.5/kernel/configs.c linux-2.6.5/kernel/configs.c
---- linux-2.6.5/kernel/configs.c 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/kernel/configs.c 2004-04-18 11:05:51.000000000 -0400
-@@ -81,8 +81,16 @@
- IKCONFIG_VERSION);
-
- /* create the current config file */
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
-+#endif
-+#else
- entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
- &proc_root);
-+#endif
- if (!entry)
- return -ENOMEM;
-
-diff -urN linux-2.6.5/kernel/exit.c linux-2.6.5/kernel/exit.c
---- linux-2.6.5/kernel/exit.c 2004-04-03 22:38:13.000000000 -0500
-+++ linux-2.6.5/kernel/exit.c 2004-04-18 11:05:51.000000000 -0400
-@@ -22,6 +22,7 @@
- #include <linux/profile.h>
- #include <linux/mount.h>
- #include <linux/proc_fs.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -232,6 +233,13 @@
- {
- write_lock_irq(&tasklist_lock);
-
-+#ifdef CONFIG_GRKERNSEC
-+ if (current->exec_file) {
-+ fput(current->exec_file);
-+ current->exec_file = NULL;
-+ }
-+#endif
-+
- ptrace_unlink(current);
- /* Reparent to init */
- REMOVE_LINKS(current);
-@@ -239,6 +247,8 @@
- current->real_parent = child_reaper;
- SET_LINKS(current);
-
-+ gr_set_kernel_label(current);
-+
- /* Set the exit signal to SIGCHLD so we signal init on exit */
- current->exit_signal = SIGCHLD;
-
-@@ -333,6 +343,15 @@
- vsnprintf(current->comm, sizeof(current->comm), name, args);
- va_end(args);
-
-+#ifdef CONFIG_GRKERNSEC
-+ if (current->exec_file) {
-+ fput(current->exec_file);
-+ current->exec_file = NULL;
-+ }
-+#endif
-+
-+ gr_set_kernel_label(current);
-+
- /*
- * If we were started as result of loading a module, close all of the
- * user space pages. We don't need them, and if we didn't close them
-@@ -771,6 +790,11 @@
- }
-
- acct_process(code);
-+
-+ gr_acl_handle_psacct(tsk, code);
-+ gr_acl_handle_exit();
-+ gr_del_task_from_ip_table(tsk);
-+
- __exit_mm(tsk);
-
- exit_sem(tsk);
-diff -urN linux-2.6.5/kernel/fork.c linux-2.6.5/kernel/fork.c
---- linux-2.6.5/kernel/fork.c 2004-04-03 22:36:18.000000000 -0500
-+++ linux-2.6.5/kernel/fork.c 2004-04-18 11:05:51.000000000 -0400
-@@ -31,6 +31,7 @@
- #include <linux/futex.h>
- #include <linux/ptrace.h>
- #include <linux/mount.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/pgtable.h>
- #include <asm/pgalloc.h>
-@@ -274,7 +275,7 @@
- mm->locked_vm = 0;
- mm->mmap = NULL;
- mm->mmap_cache = NULL;
-- mm->free_area_cache = TASK_UNMAPPED_BASE;
-+ mm->free_area_cache = oldmm->free_area_cache;
- mm->map_count = 0;
- mm->rss = 0;
- cpus_clear(mm->cpu_vm_mask);
-@@ -880,6 +881,9 @@
- goto fork_out;
-
- retval = -EAGAIN;
-+
-+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
-+
- if (atomic_read(&p->user->processes) >=
- p->rlim[RLIMIT_NPROC].rlim_cur) {
- if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
-@@ -968,6 +972,8 @@
- if (retval)
- goto bad_fork_cleanup_namespace;
-
-+ gr_copy_label(p);
-+
- p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
- /*
- * Clear TID on mm_release()?
-@@ -1101,6 +1107,9 @@
- free_uid(p->user);
- bad_fork_free:
- free_task(p);
-+
-+ gr_log_forkfail(retval);
-+
- goto fork_out;
- }
-
-diff -urN linux-2.6.5/kernel/kallsyms.c linux-2.6.5/kernel/kallsyms.c
---- linux-2.6.5/kernel/kallsyms.c 2004-04-03 22:38:21.000000000 -0500
-+++ linux-2.6.5/kernel/kallsyms.c 2004-04-18 11:05:51.000000000 -0400
-@@ -301,7 +301,15 @@
- {
- struct proc_dir_entry *entry;
-
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
-+#endif
-+#else
- entry = create_proc_entry("kallsyms", 0444, NULL);
-+#endif
- if (entry)
- entry->proc_fops = &kallsyms_operations;
- return 0;
-diff -urN linux-2.6.5/kernel/pid.c linux-2.6.5/kernel/pid.c
---- linux-2.6.5/kernel/pid.c 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/kernel/pid.c 2004-04-18 11:05:51.000000000 -0400
-@@ -25,6 +25,7 @@
- #include <linux/init.h>
- #include <linux/bootmem.h>
- #include <linux/hash.h>
-+#include <linux/grsecurity.h>
-
- #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
- static struct list_head *pid_hash[PIDTYPE_MAX];
-@@ -99,10 +100,12 @@
-
- int alloc_pidmap(void)
- {
-- int pid, offset, max_steps = PIDMAP_ENTRIES + 1;
-+ int pid = 0, offset, max_steps = PIDMAP_ENTRIES + 1;
- pidmap_t *map;
-
-- pid = last_pid + 1;
-+ pid = gr_random_pid();
-+ if (!pid)
-+ pid = last_pid + 1;
- if (pid >= pid_max)
- pid = RESERVED_PIDS;
-
-@@ -225,10 +228,16 @@
- task_t *find_task_by_pid(int nr)
- {
- struct pid *pid = find_pid(PIDTYPE_PID, nr);
-+ struct task_struct *task = NULL;
-
- if (!pid)
- return NULL;
-- return pid_task(pid->task_list.next, PIDTYPE_PID);
-+ task = pid_task(pid->task_list.next, PIDTYPE_PID);
-+
-+ if (gr_pid_is_chrooted(task))
-+ return NULL;
-+
-+ return task;
- }
-
- EXPORT_SYMBOL(find_task_by_pid);
-diff -urN linux-2.6.5/kernel/printk.c linux-2.6.5/kernel/printk.c
---- linux-2.6.5/kernel/printk.c 2004-04-03 22:38:24.000000000 -0500
-+++ linux-2.6.5/kernel/printk.c 2004-04-18 11:05:51.000000000 -0400
-@@ -30,6 +30,7 @@
- #include <linux/smp.h>
- #include <linux/security.h>
- #include <linux/bootmem.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
-
-@@ -248,6 +249,11 @@
- char c;
- int error = 0;
-
-+#ifdef CONFIG_GRKERNSEC_DMESG
-+ if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
-+ return -EPERM;
-+#endif
-+
- error = security_syslog(type);
- if (error)
- return error;
-diff -urN linux-2.6.5/kernel/resource.c linux-2.6.5/kernel/resource.c
---- linux-2.6.5/kernel/resource.c 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/kernel/resource.c 2004-04-18 11:05:51.000000000 -0400
-@@ -134,10 +134,27 @@
- {
- struct proc_dir_entry *entry;
-
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ entry = create_proc_entry("ioports", S_IRUSR, NULL);
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
-+#endif
-+#else
- entry = create_proc_entry("ioports", 0, NULL);
-+#endif
- if (entry)
- entry->proc_fops = &proc_ioports_operations;
-+
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ entry = create_proc_entry("iomem", S_IRUSR, NULL);
-+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
-+ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
-+#endif
-+#else
- entry = create_proc_entry("iomem", 0, NULL);
-+#endif
- if (entry)
- entry->proc_fops = &proc_iomem_operations;
- return 0;
-diff -urN linux-2.6.5/kernel/sched.c linux-2.6.5/kernel/sched.c
---- linux-2.6.5/kernel/sched.c 2004-04-03 22:37:42.000000000 -0500
-+++ linux-2.6.5/kernel/sched.c 2004-04-18 11:05:51.000000000 -0400
-@@ -39,6 +39,7 @@
- #include <linux/cpu.h>
- #include <linux/percpu.h>
- #include <linux/kthread.h>
-+#include <linux/grsecurity.h>
-
- #ifdef CONFIG_NUMA
- #define cpu_to_node_mask(cpu) node_to_cpumask(cpu_to_node(cpu))
-@@ -2038,6 +2039,8 @@
- return -EPERM;
- if (increment < -40)
- increment = -40;
-+ if (gr_handle_chroot_nice())
-+ return -EPERM;
- }
- if (increment > 40)
- increment = 40;
-diff -urN linux-2.6.5/kernel/signal.c linux-2.6.5/kernel/signal.c
---- linux-2.6.5/kernel/signal.c 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/kernel/signal.c 2004-04-18 11:05:51.000000000 -0400
-@@ -21,6 +21,7 @@
- #include <linux/binfmts.h>
- #include <linux/security.h>
- #include <linux/ptrace.h>
-+#include <linux/grsecurity.h>
- #include <asm/param.h>
- #include <asm/uaccess.h>
- #include <asm/siginfo.h>
-@@ -750,11 +751,13 @@
- (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
-
-
--static int
-+int
- specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
- {
- int ret = 0;
-
-+ gr_log_signal(sig, t);
-+
- if (!irqs_disabled())
- BUG();
- #ifdef CONFIG_SMP
-@@ -805,6 +808,8 @@
- ret = specific_send_sig_info(sig, info, t);
- spin_unlock_irqrestore(&t->sighand->siglock, flags);
-
-+ gr_handle_crash(t, sig);
-+
- return ret;
- }
-
-@@ -1063,9 +1068,14 @@
- int err;
-
- found = 1;
-- err = group_send_sig_info(sig, info, p);
-- if (!retval)
-- retval = err;
-+
-+ if (gr_handle_signal(p, sig))
-+ retval = -EPERM;
-+ else {
-+ err = group_send_sig_info(sig, info, p);
-+ if (!retval)
-+ retval = err;
-+ }
- }
- return found ? retval : -ESRCH;
- }
-@@ -1123,8 +1133,12 @@
- read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
- error = -ESRCH;
-- if (p)
-- error = group_send_sig_info(sig, info, p);
-+ if (p) {
-+ if (gr_handle_signal(p, sig))
-+ error = -EPERM;
-+ else
-+ error = group_send_sig_info(sig, info, p);
-+ }
- read_unlock(&tasklist_lock);
- return error;
- }
-@@ -1148,10 +1162,14 @@
- read_lock(&tasklist_lock);
- for_each_process(p) {
- if (p->pid > 1 && p->tgid != current->tgid) {
-- int err = group_send_sig_info(sig, info, p);
-- ++count;
-- if (err != -EPERM)
-- retval = err;
-+ if (gr_handle_signal(p, sig))
-+ retval = -EPERM;
-+ else {
-+ int err = group_send_sig_info(sig, info, p);
-+ ++count;
-+ if (err != -EPERM)
-+ retval = err;
-+ }
- }
- }
- read_unlock(&tasklist_lock);
-diff -urN linux-2.6.5/kernel/sys.c linux-2.6.5/kernel/sys.c
---- linux-2.6.5/kernel/sys.c 2004-04-03 22:36:18.000000000 -0500
-+++ linux-2.6.5/kernel/sys.c 2004-04-18 11:05:51.000000000 -0400
-@@ -23,6 +23,7 @@
- #include <linux/security.h>
- #include <linux/dcookies.h>
- #include <linux/suspend.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/io.h>
-@@ -279,6 +280,12 @@
- error = -EACCES;
- goto out;
- }
-+
-+ if (gr_handle_chroot_setpriority(p, niceval)) {
-+ error = -ESRCH;
-+ goto out;
-+ }
-+
- no_nice = security_task_setnice(p, niceval);
- if (no_nice) {
- error = no_nice;
-@@ -579,6 +586,9 @@
- if (rgid != (gid_t) -1 ||
- (egid != (gid_t) -1 && egid != old_rgid))
- current->sgid = new_egid;
-+
-+ gr_set_role_label(current, current->uid, new_rgid);
-+
- current->fsgid = new_egid;
- current->egid = new_egid;
- current->gid = new_rgid;
-@@ -606,6 +616,9 @@
- current->mm->dumpable=0;
- wmb();
- }
-+
-+ gr_set_role_label(current, current->uid, gid);
-+
- current->gid = current->egid = current->sgid = current->fsgid = gid;
- }
- else if ((gid == current->gid) || (gid == current->sgid))
-@@ -644,6 +657,9 @@
- current->mm->dumpable = 0;
- wmb();
- }
-+
-+ gr_set_role_label(current, new_ruid, current->gid);
-+
- current->uid = new_ruid;
- return 0;
- }
-@@ -744,6 +760,9 @@
- } else if ((uid != current->uid) && (uid != new_suid))
- return -EPERM;
-
-+ if (gr_check_crash_uid(uid))
-+ return -EPERM;
-+
- if (old_euid != uid)
- {
- current->mm->dumpable = 0;
-@@ -843,8 +862,10 @@
- current->egid = egid;
- }
- current->fsgid = current->egid;
-- if (rgid != (gid_t) -1)
-+ if (rgid != (gid_t) -1) {
-+ gr_set_role_label(current, current->uid, rgid);
- current->gid = rgid;
-+ }
- if (sgid != (gid_t) -1)
- current->sgid = sgid;
- return 0;
-diff -urN linux-2.6.5/kernel/sysctl.c linux-2.6.5/kernel/sysctl.c
---- linux-2.6.5/kernel/sysctl.c 2004-04-03 22:36:18.000000000 -0500
-+++ linux-2.6.5/kernel/sysctl.c 2004-04-18 11:05:51.000000000 -0400
-@@ -46,6 +46,14 @@
- #endif
-
- #if defined(CONFIG_SYSCTL)
-+#include <linux/grsecurity.h>
-+#include <linux/grinternal.h>
-+
-+extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
-+ const void *newval);
-+extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
-+ const int op);
-+extern int gr_handle_chroot_sysctl(const int op);
-
- /* External variables not in a header file. */
- extern int panic_timeout;
-@@ -139,6 +147,32 @@
- #ifdef CONFIG_UNIX98_PTYS
- extern ctl_table pty_table[];
- #endif
-+extern ctl_table grsecurity_table[];
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+static ctl_table pax_table[] = {
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
-+ {
-+ .ctl_name = PAX_ASLR,
-+ .procname = "aslr",
-+ .data = &pax_aslr,
-+ .maxlen = sizeof(unsigned int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ },
-+#endif
-+
-+ {
-+ .ctl_name = PAX_SOFTMODE,
-+ .procname = "softmode",
-+ .data = &pax_softmode,
-+ .maxlen = sizeof(unsigned int),
-+ .mode = 0600,
-+ .proc_handler = &proc_dointvec,
-+ }
-+};
-+#endif
-
- /* /proc declarations: */
-
-@@ -615,6 +649,14 @@
- .mode = 0444,
- .proc_handler = &proc_dointvec,
- },
-+#ifdef CONFIG_GRKERNSEC_SYSCTL
-+ {
-+ .ctl_name = KERN_GRSECURITY,
-+ .procname = "grsecurity",
-+ .mode = 0500,
-+ .child = grsecurity_table,
-+ },
-+#endif
- { .ctl_name = 0 }
- };
-
-@@ -854,6 +896,16 @@
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ {
-+ .ctl_name = KERN_PAX,
-+ .procname = "pax",
-+ .mode = 0500,
-+ .child = pax_table,
-+ },
-+#endif
-+
- { .ctl_name = 0 }
- };
-
-@@ -938,6 +990,10 @@
- static inline int ctl_perm(ctl_table *table, int op)
- {
- int error;
-+ if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
-+ return -EACCES;
-+ if (gr_handle_chroot_sysctl(op))
-+ return -EACCES;
- error = security_sysctl(table, op);
- if (error)
- return error;
-@@ -974,6 +1030,10 @@
- table = table->child;
- goto repeat;
- }
-+
-+ if (!gr_handle_sysctl(table, oldval, newval))
-+ return -EACCES;
-+
- error = do_sysctl_strategy(table, name, nlen,
- oldval, oldlenp,
- newval, newlen, context);
-diff -urN linux-2.6.5/kernel/time.c linux-2.6.5/kernel/time.c
---- linux-2.6.5/kernel/time.c 2004-04-03 22:36:27.000000000 -0500
-+++ linux-2.6.5/kernel/time.c 2004-04-18 11:05:51.000000000 -0400
-@@ -28,6 +28,7 @@
- #include <linux/timex.h>
- #include <linux/errno.h>
- #include <linux/smp_lock.h>
-+#include <linux/grsecurity.h>
- #include <asm/uaccess.h>
-
- /*
-@@ -80,6 +81,9 @@
-
- tv.tv_nsec = 0;
- do_settimeofday(&tv);
-+
-+ gr_log_timechange();
-+
- return 0;
- }
-
-@@ -181,6 +185,8 @@
- return -EFAULT;
- }
-
-+ gr_log_timechange();
-+
- return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
- }
-
-diff -urN linux-2.6.5/kernel/timer.c linux-2.6.5/kernel/timer.c
---- linux-2.6.5/kernel/timer.c 2004-04-03 22:37:59.000000000 -0500
-+++ linux-2.6.5/kernel/timer.c 2004-04-18 11:05:51.000000000 -0400
-@@ -31,6 +31,7 @@
- #include <linux/time.h>
- #include <linux/jiffies.h>
- #include <linux/cpu.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/div64.h>
-@@ -688,6 +689,9 @@
-
- psecs = (p->utime += user);
- psecs += (p->stime += system);
-+
-+ gr_learn_resource(p, RLIMIT_CPU, psecs / HZ, 1);
-+
- if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
- /* Send SIGXCPU every second.. */
- if (!(psecs % HZ))
-diff -urN linux-2.6.5/mm/filemap.c linux-2.6.5/mm/filemap.c
---- linux-2.6.5/mm/filemap.c 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/mm/filemap.c 2004-04-18 11:05:51.000000000 -0400
-@@ -27,6 +27,8 @@
- #include <linux/pagevec.h>
- #include <linux/blkdev.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-+
- /*
- * This is needed for the following functions:
- * - try_to_release_page
-@@ -1356,6 +1358,12 @@
-
- if (!mapping->a_ops->readpage)
- return -ENOEXEC;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (current->flags & PF_PAX_PAGEEXEC)
-+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
-+#endif
-+
- file_accessed(file);
- vma->vm_ops = &generic_file_vm_ops;
- return 0;
-@@ -1654,6 +1662,7 @@
- *pos = i_size_read(inode);
-
- if (limit != RLIM_INFINITY) {
-+ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
- if (*pos >= limit) {
- send_sig(SIGXFSZ, current, 0);
- return -EFBIG;
-diff -urN linux-2.6.5/mm/madvise.c linux-2.6.5/mm/madvise.c
---- linux-2.6.5/mm/madvise.c 2004-04-03 22:36:52.000000000 -0500
-+++ linux-2.6.5/mm/madvise.c 2004-04-18 11:05:51.000000000 -0400
-@@ -13,8 +13,42 @@
- * We can potentially split a vm area into separate
- * areas, each area with its own behavior.
- */
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+static long __madvise_behavior(struct vm_area_struct * vma, unsigned long start,
-+ unsigned long end, int behavior);
-+
-+static long madvise_behavior(struct vm_area_struct * vma, unsigned long start,
-+ unsigned long end, int behavior)
-+{
-+ if (vma->vm_flags & VM_MIRROR) {
-+ struct vm_area_struct * vma_m, * prev_m;
-+ unsigned long start_m, end_m;
-+ int error;
-+
-+ start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
-+ vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
-+ if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
-+ start_m = start + (unsigned long)vma->vm_private_data;
-+ end_m = end + (unsigned long)vma->vm_private_data;
-+ error = __madvise_behavior(vma_m, start_m, end_m, behavior);
-+ if (error)
-+ return error;
-+ } else {
-+ printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
-+ return -ENOMEM;
-+ }
-+ }
-+
-+ return __madvise_behavior(vma, start, end, behavior);
-+}
-+
-+static long __madvise_behavior(struct vm_area_struct * vma, unsigned long start,
-+ unsigned long end, int behavior)
-+#else
- static long madvise_behavior(struct vm_area_struct * vma, unsigned long start,
- unsigned long end, int behavior)
-+#endif
- {
- struct mm_struct * mm = vma->vm_mm;
- int error;
-diff -urN linux-2.6.5/mm/memory.c linux-2.6.5/mm/memory.c
---- linux-2.6.5/mm/memory.c 2004-04-03 22:36:58.000000000 -0500
-+++ linux-2.6.5/mm/memory.c 2004-04-18 11:05:51.000000000 -0400
-@@ -46,6 +46,7 @@
- #include <linux/rmap-locking.h>
- #include <linux/module.h>
- #include <linux/init.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/pgalloc.h>
- #include <asm/rmap.h>
-@@ -989,6 +990,69 @@
- update_mmu_cache(vma, address, entry);
- }
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+/* PaX: if vma is mirrored, synchronize the mirror's PTE
-+ *
-+ * mm->page_table_lock is held on entry and is not released on exit or inside
-+ * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
-+ */
-+struct pte_chain * pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
-+ unsigned long address, pte_t *pte, struct pte_chain *pte_chain)
-+{
-+ unsigned long address_m;
-+ struct vm_area_struct * vma_m = NULL;
-+ pte_t * pte_m, entry_m;
-+ struct page * page_m;
-+
-+ address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
-+ vma_m = find_vma(mm, address_m);
-+ BUG_ON(!vma_m || vma_m->vm_start != address_m);
-+
-+ address_m = address + (unsigned long)vma->vm_private_data;
-+
-+ {
-+ pgd_t *pgd_m;
-+ pmd_t *pmd_m;
-+
-+ pgd_m = pgd_offset(mm, address_m);
-+ pmd_m = pmd_offset(pgd_m, address_m);
-+ pte_m = pte_offset_map_nested(pmd_m, address_m);
-+ }
-+
-+ if (pte_present(*pte_m)) {
-+ flush_cache_page(vma_m, address_m);
-+ flush_icache_page(vma_m, pte_page(*pte_m));
-+ }
-+ entry_m = ptep_get_and_clear(pte_m);
-+ if (pte_present(entry_m))
-+ flush_tlb_page(vma_m, address_m);
-+
-+ if (pte_none(entry_m)) {
-+ ++mm->rss;
-+ } else if (pte_present(entry_m)) {
-+ page_remove_rmap(pte_page(entry_m), pte_m);
-+ page_cache_release(pte_page(entry_m));
-+ } else if (!pte_file(entry_m)) {
-+ free_swap_and_cache(pte_to_swp_entry(entry_m));
-+ ++mm->rss;
-+ } else {
-+ printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
-+ address, vma->vm_start, address_m, vma_m->vm_start);
-+ }
-+
-+ page_m = pte_page(*pte);
-+ page_cache_get(page_m);
-+ entry_m = mk_pte(page_m, vma_m->vm_page_prot);
-+ if (pte_write(*pte))
-+ entry_m = pte_mkdirty(pte_mkwrite(entry_m));
-+ pte_chain = page_add_rmap(page_m, pte_m, pte_chain);
-+ ptep_establish(vma_m, address_m, pte_m, entry_m);
-+ update_mmu_cache(vma_m, address_m, entry_m);
-+ pte_unmap_nested(pte_m);
-+ return pte_chain;
-+}
-+#endif
-+
- /*
- * This routine handles present pages, when users try to write
- * to a shared page. It is done by copying the page to a new address
-@@ -1017,6 +1081,10 @@
- struct pte_chain *pte_chain;
- pte_t entry;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ struct pte_chain *pte_chain_m = NULL;
-+#endif
-+
- if (unlikely(!pfn_valid(pfn))) {
- /*
- * This should really halt the system so it can be debugged or
-@@ -1056,6 +1124,13 @@
- pte_chain = pte_chain_alloc(GFP_KERNEL);
- if (!pte_chain)
- goto no_pte_chain;
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_m = pte_chain_alloc(GFP_KERNEL);
-+ if (!pte_chain_m)
-+ goto no_new_page;
-+#endif
-+
- new_page = alloc_page(GFP_HIGHUSER);
- if (!new_page)
- goto no_new_page;
-@@ -1076,16 +1151,32 @@
-
- /* Free the old page.. */
- new_page = old_page;
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (vma->vm_flags & VM_MIRROR)
-+ pte_chain_m = pax_mirror_fault(mm, vma, address, page_table, pte_chain_m);
-+#endif
-+
- }
- pte_unmap(page_table);
- page_cache_release(new_page);
- page_cache_release(old_page);
- spin_unlock(&mm->page_table_lock);
- pte_chain_free(pte_chain);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_free(pte_chain_m);
-+#endif
-+
- return VM_FAULT_MINOR;
-
- no_new_page:
- pte_chain_free(pte_chain);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_free(pte_chain_m);
-+#endif
-+
- no_pte_chain:
- page_cache_release(old_page);
- return VM_FAULT_OOM;
-@@ -1187,6 +1278,7 @@
-
- do_expand:
- limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-+ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
- if (limit != RLIM_INFINITY && offset > limit)
- goto out_sig;
- if (offset > inode->i_sb->s_maxbytes)
-@@ -1246,6 +1338,10 @@
- int ret = VM_FAULT_MINOR;
- struct pte_chain *pte_chain = NULL;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ struct pte_chain *pte_chain_m = NULL;
-+#endif
-+
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
- page = lookup_swap_cache(entry);
-@@ -1279,6 +1375,15 @@
- ret = VM_FAULT_OOM;
- goto out;
- }
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_m = pte_chain_alloc(GFP_KERNEL);
-+ if (!pte_chain_m) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+#endif
-+
- lock_page(page);
-
- /*
-@@ -1314,10 +1419,21 @@
-
- /* No need to invalidate - it was non-present before */
- update_mmu_cache(vma, address, pte);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (vma->vm_flags & VM_MIRROR)
-+ pte_chain_m = pax_mirror_fault(mm, vma, address, page_table, pte_chain_m);
-+#endif
-+
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
- out:
- pte_chain_free(pte_chain);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_free(pte_chain_m);
-+#endif
-+
- return ret;
- }
-
-@@ -1336,13 +1452,38 @@
- struct pte_chain *pte_chain;
- int ret;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ struct pte_chain *pte_chain_m = NULL;
-+#endif
-+
- pte_chain = pte_chain_alloc(GFP_ATOMIC | __GFP_NOWARN);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_m = pte_chain_alloc(GFP_ATOMIC | __GFP_NOWARN);
-+#endif
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (!pte_chain || !pte_chain_m) {
-+#else
- if (!pte_chain) {
-+#endif
-+
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (!pte_chain)
-+ pte_chain = pte_chain_alloc(GFP_KERNEL);
-+ if (!pte_chain_m)
-+ pte_chain_m = pte_chain_alloc(GFP_KERNEL);
-+ if (!pte_chain || !pte_chain_m)
-+ goto no_mem;
-+#else
- pte_chain = pte_chain_alloc(GFP_KERNEL);
- if (!pte_chain)
- goto no_mem;
-+#endif
-+
- spin_lock(&mm->page_table_lock);
- page_table = pte_offset_map(pmd, addr);
- }
-@@ -1382,10 +1523,16 @@
- set_pte(page_table, entry);
- /* ignores ZERO_PAGE */
- pte_chain = page_add_rmap(page, page_table, pte_chain);
-- pte_unmap(page_table);
-
- /* No need to invalidate - it was non-present before */
- update_mmu_cache(vma, addr, entry);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (vma->vm_flags & VM_MIRROR)
-+ pte_chain_m = pax_mirror_fault(mm, vma, addr, page_table, pte_chain_m);
-+#endif
-+
-+ pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
- ret = VM_FAULT_MINOR;
- goto out;
-@@ -1394,6 +1541,11 @@
- ret = VM_FAULT_OOM;
- out:
- pte_chain_free(pte_chain);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_free(pte_chain_m);
-+#endif
-+
- return ret;
- }
-
-@@ -1420,6 +1572,10 @@
- int sequence = 0;
- int ret = VM_FAULT_MINOR;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ struct pte_chain *pte_chain_m = NULL;
-+#endif
-+
- if (!vma->vm_ops || !vma->vm_ops->nopage)
- return do_anonymous_page(mm, vma, page_table,
- pmd, write_access, address);
-@@ -1444,6 +1600,12 @@
- if (!pte_chain)
- goto oom;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_m = pte_chain_alloc(GFP_KERNEL);
-+ if (!pte_chain_m)
-+ goto oom;
-+#endif
-+
- /*
- * Should we do an early C-O-W break?
- */
-@@ -1469,6 +1631,11 @@
- spin_unlock(&mm->page_table_lock);
- page_cache_release(new_page);
- pte_chain_free(pte_chain);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_free(pte_chain_m);
-+#endif
-+
- goto retry;
- }
- page_table = pte_offset_map(pmd, address);
-@@ -1493,6 +1660,15 @@
- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
- set_pte(page_table, entry);
- pte_chain = page_add_rmap(new_page, page_table, pte_chain);
-+
-+ /* no need to invalidate: a not-present page shouldn't be cached */
-+ update_mmu_cache(vma, address, entry);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (vma->vm_flags & VM_MIRROR)
-+ pte_chain_m = pax_mirror_fault(mm, vma, address, page_table, pte_chain_m);
-+#endif
-+
- pte_unmap(page_table);
- } else {
- /* One of our sibling threads was faster, back out. */
-@@ -1502,8 +1678,6 @@
- goto out;
- }
-
-- /* no need to invalidate: a not-present page shouldn't be cached */
-- update_mmu_cache(vma, address, entry);
- spin_unlock(&mm->page_table_lock);
- goto out;
- oom:
-@@ -1511,6 +1685,11 @@
- ret = VM_FAULT_OOM;
- out:
- pte_chain_free(pte_chain);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pte_chain_free(pte_chain_m);
-+#endif
-+
- return ret;
- }
-
-@@ -1613,6 +1792,11 @@
- pgd_t *pgd;
- pmd_t *pmd;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ unsigned long address_m = 0UL;
-+ struct vm_area_struct * vma_m = NULL;
-+#endif
-+
- __set_current_state(TASK_RUNNING);
- pgd = pgd_offset(mm, address);
-
-@@ -1626,6 +1810,48 @@
- * and the SMP-safe atomic PTE updates.
- */
- spin_lock(&mm->page_table_lock);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (vma->vm_flags & VM_MIRROR) {
-+ pgd_t *pgd_m;
-+ pmd_t *pmd_m;
-+ pte_t *pte_m;
-+
-+ address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
-+ vma_m = find_vma(mm, address_m);
-+
-+ /* PaX: sanity checks */
-+ if (!vma_m) {
-+ spin_unlock(&mm->page_table_lock);
-+ printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
-+ address, vma, address_m, vma_m);
-+ return VM_FAULT_SIGBUS;
-+ } else if (!(vma_m->vm_flags & VM_MIRROR) ||
-+ vma_m->vm_start != address_m ||
-+ vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
-+ {
-+ spin_unlock(&mm->page_table_lock);
-+ printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
-+ address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
-+ return VM_FAULT_SIGBUS;
-+ }
-+
-+ address_m = address + (unsigned long)vma->vm_private_data;
-+ pgd_m = pgd_offset(mm, address_m);
-+ pmd_m = pmd_alloc(mm, pgd_m, address_m);
-+ if (!pmd_m) {
-+ spin_unlock(&mm->page_table_lock);
-+ return VM_FAULT_OOM;
-+ }
-+ pte_m = pte_alloc_map(mm, pmd_m, address_m);
-+ if (!pte_m) {
-+ spin_unlock(&mm->page_table_lock);
-+ return VM_FAULT_OOM;
-+ }
-+ pte_unmap(pte_m);
-+ }
-+#endif
-+
- pmd = pmd_alloc(mm, pgd, address);
-
- if (pmd) {
-diff -urN linux-2.6.5/mm/mlock.c linux-2.6.5/mm/mlock.c
---- linux-2.6.5/mm/mlock.c 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/mm/mlock.c 2004-04-18 11:05:51.000000000 -0400
-@@ -7,11 +7,43 @@
-
- #include <linux/mman.h>
- #include <linux/mm.h>
-+#include <linux/grsecurity.h>
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+static int __mlock_fixup(struct vm_area_struct * vma,
-+ unsigned long start, unsigned long end, unsigned int newflags);
-
- static int mlock_fixup(struct vm_area_struct * vma,
- unsigned long start, unsigned long end, unsigned int newflags)
- {
-+ if (vma->vm_flags & VM_MIRROR) {
-+ struct vm_area_struct * vma_m;
-+ unsigned long start_m, end_m;
-+ int error;
-+
-+ start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
-+ vma_m = find_vma(vma->vm_mm, start_m);
-+ if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
-+ start_m = start + (unsigned long)vma->vm_private_data;
-+ end_m = end + (unsigned long)vma->vm_private_data;
-+ error = __mlock_fixup(vma_m, start_m, end_m, newflags);
-+ if (error)
-+ return error;
-+ } else {
-+ printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
-+ return -ENOMEM;
-+ }
-+ }
-+ return __mlock_fixup(vma, start, end, newflags);
-+}
-+
-+static int __mlock_fixup(struct vm_area_struct * vma,
-+ unsigned long start, unsigned long end, unsigned int newflags)
-+#else
-+static int mlock_fixup(struct vm_area_struct * vma,
-+ unsigned long start, unsigned long end, unsigned int newflags)
-+#endif
-+{
- struct mm_struct * mm = vma->vm_mm;
- int pages;
- int ret = 0;
-@@ -65,6 +97,17 @@
- return -EINVAL;
- if (end == start)
- return 0;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (end > SEGMEXEC_TASK_SIZE)
-+ return -EINVAL;
-+ } else
-+#endif
-+
-+ if (end > TASK_SIZE)
-+ return -EINVAL;
-+
- vma = find_vma(current->mm, start);
- if (!vma || vma->vm_start > start)
- return -ENOMEM;
-@@ -115,6 +158,7 @@
- lock_limit >>= PAGE_SHIFT;
-
- /* check against resource limits */
-+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
- if (locked <= lock_limit)
- error = do_mlock(start, len, 1);
- up_write(&current->mm->mmap_sem);
-@@ -151,6 +195,16 @@
- for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
- unsigned int newflags;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (vma->vm_end > SEGMEXEC_TASK_SIZE)
-+ break;
-+ } else
-+#endif
-+
-+ if (vma->vm_end > TASK_SIZE)
-+ break;
-+
- newflags = vma->vm_flags | VM_LOCKED;
- if (!(flags & MCL_CURRENT))
- newflags &= ~VM_LOCKED;
-@@ -174,6 +228,7 @@
- lock_limit >>= PAGE_SHIFT;
-
- ret = -ENOMEM;
-+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
- if (current->mm->total_vm <= lock_limit)
- ret = do_mlockall(flags);
- out:
-diff -urN linux-2.6.5/mm/mmap.c linux-2.6.5/mm/mmap.c
---- linux-2.6.5/mm/mmap.c 2004-04-03 22:37:25.000000000 -0500
-+++ linux-2.6.5/mm/mmap.c 2004-04-18 11:05:51.000000000 -0400
-@@ -21,6 +21,7 @@
- #include <linux/profile.h>
- #include <linux/module.h>
- #include <linux/mount.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgalloc.h>
-@@ -121,6 +122,7 @@
-
- /* Check against rlimit.. */
- rlim = current->rlim[RLIMIT_DATA].rlim_cur;
-+ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
- if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
- goto out;
-
-@@ -327,6 +329,12 @@
- static inline int is_mergeable_vma(struct vm_area_struct *vma,
- struct file *file, unsigned long vm_flags)
- {
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if ((vma->vm_flags | vm_flags) & VM_MIRROR)
-+ return 0;
-+#endif
-+
- if (vma->vm_ops && vma->vm_ops->close)
- return 0;
- if (vma->vm_file != file)
-@@ -494,6 +502,28 @@
- int accountable = 1;
- unsigned long charged = 0;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ struct vm_area_struct * vma_m = NULL;
-+
-+ if (flags & MAP_MIRROR) {
-+ /* PaX: sanity checks, to be removed when proved to be stable */
-+ if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
-+ return -EINVAL;
-+
-+ vma_m = find_vma(mm, pgoff);
-+
-+ if (!vma_m || is_vm_hugetlb_page(vma_m) ||
-+ vma_m->vm_start != pgoff ||
-+ (vma_m->vm_flags & VM_MIRROR) ||
-+ (!(vma_m->vm_flags & VM_WRITE) && (prot & PROT_WRITE)))
-+ return -EINVAL;
-+
-+ file = vma_m->vm_file;
-+ pgoff = vma_m->vm_pgoff;
-+ len = vma_m->vm_end - vma_m->vm_start;
-+ }
-+#endif
-+
- if (file) {
- if (is_file_hugepages(file))
- accountable = 0;
-@@ -535,6 +565,30 @@
- vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
- mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
-
-+ if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
-+ vm_flags &= ~VM_MAYEXEC;
-+
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+ if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if (current->flags & PF_PAX_MPROTECT) {
-+ if (!file || (prot & PROT_WRITE))
-+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
-+ else
-+ vm_flags &= ~VM_MAYWRITE;
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (file && (flags & MAP_MIRROR) && (vm_flags & VM_EXEC))
-+ vma_m->vm_flags &= ~VM_MAYWRITE;
-+#endif
-+
-+ }
-+#endif
-+
-+ }
-+#endif
-+
- if (flags & MAP_LOCKED) {
- if (!capable(CAP_IPC_LOCK))
- return -EPERM;
-@@ -544,6 +598,7 @@
- if (vm_flags & VM_LOCKED) {
- unsigned long locked = mm->locked_vm << PAGE_SHIFT;
- locked += len;
-+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
- if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
- return -EAGAIN;
- }
-@@ -599,6 +654,9 @@
- if (error)
- return error;
-
-+ if (!gr_acl_handle_mmap(file, prot))
-+ return -EACCES;
-+
- /* Clear old maps */
- error = -ENOMEM;
- munmap_back:
-@@ -610,6 +668,7 @@
- }
-
- /* Check against address space limit. */
-+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
- if ((mm->total_vm << PAGE_SHIFT) + len
- > current->rlim[RLIMIT_AS].rlim_cur)
- return -ENOMEM;
-@@ -650,6 +709,13 @@
- vma->vm_start = addr;
- vma->vm_end = addr + len;
- vma->vm_flags = vm_flags;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if ((file || !(current->flags & PF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
-+ vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
-+ else
-+#endif
-+
- vma->vm_page_prot = protection_map[vm_flags & 0x0f];
- vma->vm_ops = NULL;
- vma->vm_pgoff = pgoff;
-@@ -679,6 +745,14 @@
- goto free_vma;
- }
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (flags & MAP_MIRROR) {
-+ vma_m->vm_flags |= VM_MIRROR;
-+ vma_m->vm_private_data = (void *)(vma->vm_start - vma_m->vm_start);
-+ vma->vm_private_data = (void *)(vma_m->vm_start - vma->vm_start);
-+ }
-+#endif
-+
- /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
- * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
- * that memory reservation must be checked; but that reservation
-@@ -759,12 +833,28 @@
- struct vm_area_struct *vma;
- unsigned long start_addr;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if ((current->flags & PF_PAX_SEGMEXEC) && len > SEGMEXEC_TASK_SIZE)
-+ return -ENOMEM;
-+ else
-+#endif
-+
- if (len > TASK_SIZE)
- return -ENOMEM;
-
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
-+#endif
-+
- if (addr) {
- addr = PAGE_ALIGN(addr);
- vma = find_vma(mm, addr);
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)
-+ return -ENOMEM;
-+#endif
-+
- if (TASK_SIZE - len >= addr &&
- (!vma || addr + len <= vma->vm_start))
- return addr;
-@@ -780,6 +870,13 @@
- * some holes.
- */
- if (start_addr != TASK_UNMAPPED_BASE) {
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (current->flags & PF_PAX_RANDMMAP)
-+ start_addr = addr = TASK_UNMAPPED_BASE + mm->delta_mmap;
-+ else
-+#endif
-+
- start_addr = addr = TASK_UNMAPPED_BASE;
- goto full_search;
- }
-@@ -939,10 +1036,18 @@
- spin_unlock(&vma->vm_mm->page_table_lock);
- return -ENOMEM;
- }
--
-+
-+ gr_learn_resource(current, RLIMIT_STACK, address - vma->vm_start, 1);
-+ gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
-+ if (vma->vm_flags & VM_LOCKED)
-+ gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);
-+
- if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur ||
- ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
-- current->rlim[RLIMIT_AS].rlim_cur) {
-+ current->rlim[RLIMIT_AS].rlim_cur ||
-+ ((vma->vm_flags & VM_LOCKED) &&
-+ ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
-+ current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
- spin_unlock(&vma->vm_mm->page_table_lock);
- vm_unacct_memory(grow);
- return -ENOMEM;
-@@ -993,10 +1098,62 @@
- spin_unlock(&vma->vm_mm->page_table_lock);
- return -ENOMEM;
- }
--
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (vma->vm_flags & VM_MIRROR) {
-+ struct vm_area_struct * vma_m;
-+ unsigned long address_m;
-+
-+ address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
-+ vma_m = find_vma(vma->vm_mm, address_m);
-+ if (!vma_m || vma_m->vm_start != address_m ||
-+ !(vma_m->vm_flags & VM_MIRROR) ||
-+ vma->vm_end - vma->vm_start !=
-+ vma_m->vm_end - vma_m->vm_start) {
-+ spin_unlock(&vma->vm_mm->page_table_lock);
-+ vm_unacct_memory(grow);
-+ printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
-+ address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
-+ return -ENOMEM;
-+ }
-+
-+ address_m = address + (unsigned long)vma->vm_private_data;
-+
-+ gr_learn_resource(current, RLIMIT_STACK, vma_m->vm_end - address_m, 1);
-+ gr_learn_resource(current, RLIMIT_AS, (vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT, 1);
-+ if (vma_m->vm_flags & VM_LOCKED)
-+ gr_learn_resource(current, RLIMIT_MEMLOCK, (vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT, 1);
-+
-+ if (vma_m->vm_end - address_m > current->rlim[RLIMIT_STACK].rlim_cur ||
-+ ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) >
-+ current->rlim[RLIMIT_AS].rlim_cur ||
-+ ((vma_m->vm_flags & VM_LOCKED) &&
-+ ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) >
-+ current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
-+ spin_unlock(&vma->vm_mm->page_table_lock);
-+ vm_unacct_memory(grow);
-+ return -ENOMEM;
-+ }
-+
-+ vma_m->vm_start = address_m;
-+ vma_m->vm_pgoff -= grow;
-+ vma_m->vm_mm->total_vm += grow;
-+ if (vma_m->vm_flags & VM_LOCKED)
-+ vma_m->vm_mm->locked_vm += grow;
-+ } else
-+#endif
-+
-+ gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address, 1);
-+ gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
-+ if (vma->vm_flags & VM_LOCKED)
-+ gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);
-+
- if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
- ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
-- current->rlim[RLIMIT_AS].rlim_cur) {
-+ current->rlim[RLIMIT_AS].rlim_cur ||
-+ ((vma->vm_flags & VM_LOCKED) &&
-+ ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
-+ current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
- spin_unlock(&vma->vm_mm->page_table_lock);
- vm_unacct_memory(grow);
- return -ENOMEM;
-@@ -1108,15 +1265,15 @@
- {
- size_t len = area->vm_end - area->vm_start;
-
-- area->vm_mm->total_vm -= len >> PAGE_SHIFT;
-+ mm->total_vm -= len >> PAGE_SHIFT;
- if (area->vm_flags & VM_LOCKED)
-- area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
-+ mm->locked_vm -= len >> PAGE_SHIFT;
- /*
- * Is this a new hole at the lowest possible address?
- */
- if (area->vm_start >= TASK_UNMAPPED_BASE &&
-- area->vm_start < area->vm_mm->free_area_cache)
-- area->vm_mm->free_area_cache = area->vm_start;
-+ area->vm_start < mm->free_area_cache)
-+ mm->free_area_cache = area->vm_start;
-
- remove_shared_vm_struct(area);
-
-@@ -1178,21 +1335,73 @@
- */
- static void
- detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
-- struct vm_area_struct *prev, unsigned long end)
-+ struct vm_area_struct *prev, unsigned long *start, unsigned long *end)
- {
- struct vm_area_struct **insertion_point;
- struct vm_area_struct *tail_vma = NULL;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ unsigned long start_m;
-+ struct vm_area_struct *vma_m, *head_vma = vma, *mirrors = NULL, *head_vma_m = NULL;
-+#endif
-+
- insertion_point = (prev ? &prev->vm_next : &mm->mmap);
- do {
- rb_erase(&vma->vm_rb, &mm->mm_rb);
- mm->map_count--;
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if ((vma->vm_flags & VM_MIRROR) &&
-+ vma->vm_start + (unsigned long)vma->vm_private_data >= *start &&
-+ vma->vm_start + (unsigned long)vma->vm_private_data < *end)
-+ {
-+ mm->mmap_cache = NULL; /* Kill the cache. */
-+ start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
-+ vma_m = find_vma(mm, start_m);
-+ if (vma_m && (vma_m->vm_flags & VM_MIRROR) && vma_m->vm_start == start_m) {
-+ vma->vm_flags &= ~VM_MIRROR;
-+ vma_m->vm_flags &= ~VM_MIRROR;
-+ } else
-+ printk("PAX: VMMIRROR: munmap bug in %s, %08lx\n", current->comm, vma->vm_start);
-+ }
-+#endif
-+
- tail_vma = vma;
- vma = vma->vm_next;
-- } while (vma && vma->vm_start < end);
-+ } while (vma && vma->vm_start < *end);
- *insertion_point = vma;
- tail_vma->vm_next = NULL;
- mm->mmap_cache = NULL; /* Kill the cache. */
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ for (; head_vma; head_vma = head_vma->vm_next) {
-+ struct vm_area_struct *prev_m;
-+
-+ if (!(head_vma->vm_flags & VM_MIRROR))
-+ continue;
-+
-+ start_m = head_vma->vm_start + (unsigned long)head_vma->vm_private_data;
-+ vma_m = find_vma_prev(mm, start_m, &prev_m);
-+ rb_erase(&vma_m->vm_rb, &mm->mm_rb);
-+ mm->map_count--;
-+ insertion_point = prev_m ? &prev_m->vm_next : &mm->mmap;
-+ *insertion_point = vma_m->vm_next;
-+ if (head_vma_m) {
-+ mirrors->vm_next = vma_m;
-+ mirrors = vma_m;
-+ } else
-+ head_vma_m = mirrors = vma_m;
-+ mirrors->vm_next = NULL;
-+ if (vma_m->vm_start < *start)
-+ *start = vma_m->vm_start;
-+ if (vma_m->vm_end > *end)
-+ *end = vma_m->vm_end;
-+ mm->mmap_cache = NULL; /* Kill the cache. */
-+ }
-+ if (head_vma_m)
-+ tail_vma->vm_next = head_vma_m;
-+#endif
-+
- }
-
- /*
-@@ -1262,6 +1471,10 @@
- unsigned long end;
- struct vm_area_struct *mpnt, *prev, *last;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ struct vm_area_struct *mpnt_m = NULL, *last_m;
-+#endif
-+
- if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
- return -EINVAL;
-
-@@ -1298,6 +1511,20 @@
- * places tmp vma above, and higher split_vma places tmp vma below.
- */
- if (start > mpnt->vm_start) {
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (mpnt->vm_flags & VM_MIRROR) {
-+ unsigned long start_m = mpnt->vm_start + (unsigned long)mpnt->vm_private_data;
-+
-+ mpnt_m = find_vma(mm, start_m);
-+ if (!mpnt_m || (!mpnt_m->vm_flags & VM_MIRROR) || mpnt_m->vm_start != start_m)
-+ return -EINVAL;
-+ start_m = start + (unsigned long)mpnt->vm_private_data;
-+ if (split_vma(mm, mpnt_m, start_m, 0))
-+ return -ENOMEM;
-+ }
-+#endif
-+
- if (split_vma(mm, mpnt, start, 0))
- return -ENOMEM;
- prev = mpnt;
-@@ -1306,6 +1533,20 @@
- /* Does it split the last one? */
- last = find_vma(mm, end);
- if (last && end > last->vm_start) {
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (last->vm_flags & VM_MIRROR) {
-+ unsigned long end_m = last->vm_start + (unsigned long)last->vm_private_data;
-+
-+ last_m = find_vma(mm, end_m);
-+ if (!last_m || (!last_m->vm_flags & VM_MIRROR) || last_m->vm_start != end_m)
-+ return -EINVAL;
-+ end_m = end + (unsigned long)last->vm_private_data;
-+ if (split_vma(mm, last_m, end_m, 1))
-+ return -ENOMEM;
-+ }
-+#endif
-+
- if (split_vma(mm, last, end, 1))
- return -ENOMEM;
- }
-@@ -1315,7 +1556,7 @@
- * Remove the vma's, and unmap the actual pages
- */
- spin_lock(&mm->page_table_lock);
-- detach_vmas_to_be_unmapped(mm, mpnt, prev, end);
-+ detach_vmas_to_be_unmapped(mm, mpnt, prev, &start, &end);
- unmap_region(mm, mpnt, prev, start, end);
- spin_unlock(&mm->page_table_lock);
-
-@@ -1332,6 +1573,12 @@
- int ret;
- struct mm_struct *mm = current->mm;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if ((current->flags & PF_PAX_SEGMEXEC) &&
-+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
-+ return -EINVAL;
-+#endif
-+
- down_write(&mm->mmap_sem);
- ret = do_munmap(mm, addr, len);
- up_write(&mm->mmap_sem);
-@@ -1343,7 +1590,31 @@
- * anonymous maps. eventually we may be able to do some
- * brk-specific accounting here.
- */
-+#if defined(CONFIG_PAX_SEGMEXEC) && defined(CONFIG_PAX_MPROTECT)
-+unsigned long __do_brk(unsigned long addr, unsigned long len);
-+
-+unsigned long do_brk(unsigned long addr, unsigned long len)
-+{
-+ unsigned long ret;
-+
-+ ret = __do_brk(addr, len);
-+ if (ret == addr && (current->flags & (PF_PAX_SEGMEXEC | PF_PAX_MPROTECT)) == PF_PAX_SEGMEXEC) {
-+ unsigned long ret_m;
-+
-+ ret_m = do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
-+ if (ret_m > TASK_SIZE) {
-+ do_munmap(current->mm, addr, len);
-+ ret = ret_m;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+unsigned long __do_brk(unsigned long addr, unsigned long len)
-+#else
- unsigned long do_brk(unsigned long addr, unsigned long len)
-+#endif
- {
- struct mm_struct * mm = current->mm;
- struct vm_area_struct * vma, * prev;
-@@ -1354,6 +1625,13 @@
- if (!len)
- return addr;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if ((addr + len) > SEGMEXEC_TASK_SIZE || (addr + len) < addr)
-+ return -EINVAL;
-+ } else
-+#endif
-+
- if ((addr + len) > TASK_SIZE || (addr + len) < addr)
- return -EINVAL;
-
-@@ -1363,6 +1641,7 @@
- if (mm->def_flags & VM_LOCKED) {
- unsigned long locked = mm->locked_vm << PAGE_SHIFT;
- locked += len;
-+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
- if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
- return -EAGAIN;
- }
-@@ -1379,6 +1658,7 @@
- }
-
- /* Check against address space limits *after* clearing old maps... */
-+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
- if ((mm->total_vm << PAGE_SHIFT) + len
- > current->rlim[RLIMIT_AS].rlim_cur)
- return -ENOMEM;
-@@ -1391,6 +1671,18 @@
-
- flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
-
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+ if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
-+ flags &= ~VM_EXEC;
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if (current->flags & PF_PAX_MPROTECT)
-+ flags &= ~VM_MAYEXEC;
-+#endif
-+
-+ }
-+#endif
-+
- /* Can we just expand an old anonymous mapping? */
- if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len,
- flags, NULL, 0))
-@@ -1409,6 +1701,13 @@
- vma->vm_start = addr;
- vma->vm_end = addr + len;
- vma->vm_flags = flags;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(current->flags & PF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
-+ vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
-+ else
-+#endif
-+
- vma->vm_page_prot = protection_map[flags & 0x0f];
- vma->vm_ops = NULL;
- vma->vm_pgoff = 0;
-diff -urN linux-2.6.5/mm/mprotect.c linux-2.6.5/mm/mprotect.c
---- linux-2.6.5/mm/mprotect.c 2004-04-03 22:38:28.000000000 -0500
-+++ linux-2.6.5/mm/mprotect.c 2004-04-18 11:05:51.000000000 -0400
-@@ -16,6 +16,12 @@
- #include <linux/fs.h>
- #include <linux/highmem.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+#include <linux/elf.h>
-+#include <linux/fs.h>
-+#endif
-
- #include <asm/uaccess.h>
- #include <asm/pgalloc.h>
-@@ -150,6 +156,46 @@
- return 1;
- }
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
-+ unsigned long start, unsigned long end, unsigned int newflags);
-+
-+static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
-+ unsigned long start, unsigned long end, unsigned int newflags)
-+{
-+ if (vma->vm_flags & VM_MIRROR) {
-+ struct vm_area_struct * vma_m, * prev_m;
-+ unsigned long start_m, end_m;
-+ int error;
-+
-+ start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
-+ vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
-+ if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
-+ start_m = start + (unsigned long)vma->vm_private_data;
-+ end_m = end + (unsigned long)vma->vm_private_data;
-+ if ((current->flags & PF_PAX_SEGMEXEC) && !(newflags & VM_EXEC))
-+ error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
-+ else
-+ error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
-+ if (error)
-+ return error;
-+ } else {
-+ printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
-+ return -ENOMEM;
-+ }
-+ }
-+
-+ return __mprotect_fixup(vma, pprev, start, end, newflags);
-+}
-+
-+static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
-+ unsigned long start, unsigned long end, unsigned int newflags)
-+{
-+ struct mm_struct * mm = vma->vm_mm;
-+ unsigned long charged = 0;
-+ pgprot_t newprot;
-+ int error;
-+#else
- static int
- mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
- unsigned long start, unsigned long end, unsigned int newflags)
-@@ -163,6 +209,7 @@
- *pprev = vma;
- return 0;
- }
-+#endif
-
- /*
- * If we make a private mapping writable we increase our commit;
-@@ -182,6 +229,12 @@
- }
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(current->flags & PF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
-+ newprot = protection_map[(newflags | VM_EXEC) & 0xf];
-+ else
-+#endif
-+
- newprot = protection_map[newflags & 0xf];
-
- if (start == vma->vm_start) {
-@@ -222,6 +275,69 @@
- return error;
- }
-
-+#ifdef CONFIG_PAX_MPROTECT
-+/* PaX: non-PIC ELF libraries need relocations on their executable segments
-+ * therefore we'll grant them VM_MAYWRITE once during their life.
-+ *
-+ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
-+ * basis because we want to allow the common case and not the special ones.
-+ */
-+static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
-+{
-+ struct elfhdr elf_h;
-+ struct elf_phdr elf_p, p_dyn;
-+ elf_dyn dyn;
-+ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
-+
-+#ifndef CONFIG_PAX_NOELFRELOCS
-+ if ((vma->vm_start != start) ||
-+ !vma->vm_file ||
-+ !(vma->vm_flags & VM_MAYEXEC) ||
-+ (vma->vm_flags & VM_MAYNOTWRITE))
-+#endif
-+
-+ return;
-+
-+ if (0 > kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
-+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
-+
-+#ifdef CONFIG_PAX_ETEXECRELOCS
-+ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
-+#else
-+ elf_h.e_type != ET_DYN ||
-+#endif
-+
-+ !elf_check_arch(&elf_h) ||
-+ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
-+ elf_h.e_phnum > j)
-+ return;
-+
-+ for (i = 0UL; i < elf_h.e_phnum; i++) {
-+ if (0 > kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
-+ return;
-+ if (elf_p.p_type == PT_DYNAMIC) {
-+ p_dyn = elf_p;
-+ j = i;
-+ }
-+ }
-+ if (elf_h.e_phnum <= j)
-+ return;
-+
-+ i = 0UL;
-+ do {
-+ if (0 > kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
-+ return;
-+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
-+ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
-+ gr_log_textrel(vma);
-+ return;
-+ }
-+ i++;
-+ } while (dyn.d_tag != DT_NULL);
-+ return;
-+}
-+#endif
-+
- asmlinkage long
- sys_mprotect(unsigned long start, size_t len, unsigned long prot)
- {
-@@ -239,6 +355,17 @@
- end = start + len;
- if (end < start)
- return -ENOMEM;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (end > SEGMEXEC_TASK_SIZE)
-+ return -EINVAL;
-+ } else
-+#endif
-+
-+ if (end > TASK_SIZE)
-+ return -EINVAL;
-+
- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
- return -EINVAL;
- if (end == start)
-@@ -271,6 +398,16 @@
- }
- }
-
-+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
-+ error = -EACCES;
-+ goto out;
-+ }
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE))
-+ pax_handle_maywrite(vma, start);
-+#endif
-+
- for (nstart = start ; ; ) {
- unsigned int newflags;
- int last = 0;
-@@ -289,6 +426,12 @@
- goto out;
- }
-
-+#ifdef CONFIG_PAX_MPROTECT
-+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
-+ if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
-+ newflags &= ~VM_MAYWRITE;
-+#endif
-+
- error = security_file_mprotect(vma, prot);
- if (error)
- goto out;
-diff -urN linux-2.6.5/mm/mremap.c linux-2.6.5/mm/mremap.c
---- linux-2.6.5/mm/mremap.c 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/mm/mremap.c 2004-04-18 11:05:51.000000000 -0400
-@@ -329,6 +329,18 @@
- if (!new_len)
- goto out;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
-+ old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len)
-+ goto out;
-+ } else
-+#endif
-+
-+ if (new_len > TASK_SIZE || addr > TASK_SIZE-new_len ||
-+ old_len > TASK_SIZE || addr > TASK_SIZE-old_len)
-+ goto out;
-+
- /* new_addr is only valid if MREMAP_FIXED is specified */
- if (flags & MREMAP_FIXED) {
- if (new_addr & ~PAGE_MASK)
-@@ -336,6 +348,13 @@
- if (!(flags & MREMAP_MAYMOVE))
- goto out;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len)
-+ goto out;
-+ } else
-+#endif
-+
- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
- goto out;
-
-@@ -379,6 +398,16 @@
- ret = -EINVAL;
- goto out;
- }
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) &&
-+ (vma->vm_flags & VM_MIRROR))
-+ {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+#endif
-+
- /* We can't remap across vm area boundaries */
- if (old_len > vma->vm_end - addr)
- goto out;
-diff -urN linux-2.6.5/net/ipv4/af_inet.c linux-2.6.5/net/ipv4/af_inet.c
---- linux-2.6.5/net/ipv4/af_inet.c 2004-04-03 22:36:24.000000000 -0500
-+++ linux-2.6.5/net/ipv4/af_inet.c 2004-04-18 11:05:52.000000000 -0400
-@@ -87,6 +87,7 @@
- #include <linux/init.h>
- #include <linux/poll.h>
- #include <linux/netfilter_ipv4.h>
-+#include <linux/grsecurity.h>
-
- #include <asm/uaccess.h>
- #include <asm/system.h>
-@@ -387,7 +388,12 @@
- else
- inet->pmtudisc = IP_PMTUDISC_WANT;
-
-- inet->id = 0;
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+ if (grsec_enable_randid)
-+ inet->id = htons(ip_randomid());
-+ else
-+#endif
-+ inet->id = 0;
-
- sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
-diff -urN linux-2.6.5/net/ipv4/ip_output.c linux-2.6.5/net/ipv4/ip_output.c
---- linux-2.6.5/net/ipv4/ip_output.c 2004-04-03 22:38:22.000000000 -0500
-+++ linux-2.6.5/net/ipv4/ip_output.c 2004-04-18 11:05:52.000000000 -0400
-@@ -64,6 +64,7 @@
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/init.h>
-+#include <linux/grsecurity.h>
-
- #include <net/snmp.h>
- #include <net/ip.h>
-@@ -1161,6 +1162,12 @@
- iph->tos = inet->tos;
- iph->tot_len = htons(skb->len);
- iph->frag_off = df;
-+
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+ if (grsec_enable_randid)
-+ iph->id = htons(ip_randomid());
-+ else
-+#endif
- if (!df) {
- __ip_select_ident(iph, &rt->u.dst, 0);
- } else {
-diff -urN linux-2.6.5/net/ipv4/netfilter/Kconfig linux-2.6.5/net/ipv4/netfilter/Kconfig
---- linux-2.6.5/net/ipv4/netfilter/Kconfig 2004-04-03 22:37:45.000000000 -0500
-+++ linux-2.6.5/net/ipv4/netfilter/Kconfig 2004-04-18 11:05:52.000000000 -0400
-@@ -225,6 +225,21 @@
-
- To compile it as a module, choose M here. If unsure, say N.
-
-+config IP_NF_MATCH_STEALTH
-+ tristate "stealth match support"
-+ depends on IP_NF_IPTABLES
-+ help
-+ Enabling this option will drop all syn packets coming to unserved tcp
-+ ports as well as all packets coming to unserved udp ports. If you
-+ are using your system to route any type of packets (ie. via NAT)
-+ you should put this module at the end of your ruleset, since it will
-+ drop packets that aren't going to ports that are listening on your
-+ machine itself, it doesn't take into account that the packet might be
-+ destined for someone on your internal network if you're using NAT for
-+ instance.
-+
-+ To compile it as a module, choose M here. If unsure, say N.
-+
- config IP_NF_MATCH_HELPER
- tristate "Helper match support"
- depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
-diff -urN linux-2.6.5/net/ipv4/netfilter/Makefile linux-2.6.5/net/ipv4/netfilter/Makefile
---- linux-2.6.5/net/ipv4/netfilter/Makefile 2004-04-03 22:36:27.000000000 -0500
-+++ linux-2.6.5/net/ipv4/netfilter/Makefile 2004-04-18 11:05:52.000000000 -0400
-@@ -64,6 +64,8 @@
- obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
- obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
-
-+obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
-+
- obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
-
- # targets
-diff -urN linux-2.6.5/net/ipv4/netfilter/ipt_stealth.c linux-2.6.5/net/ipv4/netfilter/ipt_stealth.c
---- linux-2.6.5/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.5/net/ipv4/netfilter/ipt_stealth.c 2004-04-18 11:05:52.000000000 -0400
-@@ -0,0 +1,112 @@
-+/* Kernel module to add stealth support.
-+ *
-+ * Copyright (C) 2002 Brad Spengler <spender@grsecurity.net>
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/net.h>
-+#include <linux/sched.h>
-+#include <linux/inet.h>
-+#include <linux/stddef.h>
-+
-+#include <net/ip.h>
-+#include <net/sock.h>
-+#include <net/tcp.h>
-+#include <net/udp.h>
-+#include <net/route.h>
-+#include <net/inet_common.h>
-+
-+#include <linux/netfilter_ipv4/ip_tables.h>
-+
-+MODULE_LICENSE("GPL");
-+
-+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
-+
-+static int
-+match(const struct sk_buff *skb,
-+ const struct net_device *in,
-+ const struct net_device *out,
-+ const void *matchinfo,
-+ int offset,
-+ int *hotdrop)
-+{
-+ struct iphdr *ip = skb->nh.iph;
-+ struct tcphdr th;
-+ struct udphdr uh;
-+ struct sock *sk = NULL;
-+
-+ if (!ip || offset) return 0;
-+
-+ switch(ip->protocol) {
-+ case IPPROTO_TCP:
-+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
-+ *hotdrop = 1;
-+ return 0;
-+ }
-+ if (!(th.syn && !th.ack)) return 0;
-+ sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);
-+ break;
-+ case IPPROTO_UDP:
-+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
-+ *hotdrop = 1;
-+ return 0;
-+ }
-+ sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ if(!sk) // port is being listened on, match this
-+ return 1;
-+ else {
-+ sock_put(sk);
-+ return 0;
-+ }
-+}
-+
-+/* Called when user tries to insert an entry of this type. */
-+static int
-+checkentry(const char *tablename,
-+ const struct ipt_ip *ip,
-+ void *matchinfo,
-+ unsigned int matchsize,
-+ unsigned int hook_mask)
-+{
-+ if (matchsize != IPT_ALIGN(0))
-+ return 0;
-+
-+ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
-+ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
-+ && (hook_mask & (1 << NF_IP_LOCAL_IN)))
-+ return 1;
-+
-+ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
-+
-+ return 0;
-+}
-+
-+
-+static struct ipt_match stealth_match = {
-+ .name = "stealth",
-+ .match = &match,
-+ .checkentry = &checkentry,
-+ .destroy = NULL,
-+ .me = THIS_MODULE
-+};
-+
-+static int __init init(void)
-+{
-+ return ipt_register_match(&stealth_match);
-+}
-+
-+static void __exit fini(void)
-+{
-+ ipt_unregister_match(&stealth_match);
-+}
-+
-+module_init(init);
-+module_exit(fini);
-diff -urN linux-2.6.5/net/ipv4/tcp_ipv4.c linux-2.6.5/net/ipv4/tcp_ipv4.c
---- linux-2.6.5/net/ipv4/tcp_ipv4.c 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/net/ipv4/tcp_ipv4.c 2004-04-18 11:05:52.000000000 -0400
-@@ -62,6 +62,7 @@
- #include <linux/jhash.h>
- #include <linux/init.h>
- #include <linux/times.h>
-+#include <linux/grsecurity.h>
-
- #include <net/icmp.h>
- #include <net/tcp.h>
-@@ -224,9 +225,16 @@
- spin_lock(&tcp_portalloc_lock);
- rover = tcp_port_rover;
- do {
-- rover++;
-- if (rover < low || rover > high)
-- rover = low;
-+#ifdef CONFIG_GRKERNSEC_RANDSRC
-+ if (grsec_enable_randsrc && (high > low)) {
-+ rover = low + (get_random_long() % (high - low));
-+ } else
-+#endif
-+ {
-+ rover++;
-+ if (rover < low || rover > high)
-+ rover = low;
-+ }
- head = &tcp_bhash[tcp_bhashfn(rover)];
- spin_lock(&head->lock);
- tb_for_each(tb, node, &head->chain)
-@@ -537,6 +545,11 @@
-
- static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
- {
-+#ifdef CONFIG_GRKERNSEC_RANDISN
-+ if (likely(grsec_enable_randisn))
-+ return ip_randomisn();
-+ else
-+#endif
- return secure_tcp_sequence_number(skb->nh.iph->daddr,
- skb->nh.iph->saddr,
- skb->h.th->dest,
-@@ -671,10 +684,17 @@
- rover = tcp_port_rover;
-
- do {
-- rover++;
-- if ((rover < low) || (rover > high))
-- rover = low;
-- head = &tcp_bhash[tcp_bhashfn(rover)];
-+#ifdef CONFIG_GRKERNSEC_RANDSRC
-+ if (grsec_enable_randsrc && (high > low)) {
-+ rover = low + (get_random_long() % (high - low));
-+ } else
-+#endif
-+ {
-+ rover++;
-+ if ((rover < low) || (rover > high))
-+ rover = low;
-+ }
-+ head = &tcp_bhash[tcp_bhashfn(rover)];
- spin_lock(&head->lock);
-
- /* Does not bother with rcv_saddr checks,
-@@ -724,6 +744,15 @@
- }
- spin_unlock(&head->lock);
-
-+#ifdef CONFIG_GRKERNSEC
-+ gr_del_task_from_ip_table(current);
-+ current->gr_saddr = inet_sk(sk)->rcv_saddr;
-+ current->gr_daddr = inet_sk(sk)->daddr;
-+ current->gr_sport = inet_sk(sk)->sport;
-+ current->gr_dport = inet_sk(sk)->dport;
-+ gr_add_to_task_ip_table(current);
-+#endif
-+
- if (tw) {
- tcp_tw_deschedule(tw);
- tcp_tw_put(tw);
-@@ -843,13 +872,24 @@
- tcp_v4_setup_caps(sk, &rt->u.dst);
- tp->ext2_header_len = rt->u.dst.header_len;
-
-- if (!tp->write_seq)
-+ if (!tp->write_seq) {
-+#ifdef CONFIG_GRKERNSEC_RANDISN
-+ if (likely(grsec_enable_randisn))
-+ tp->write_seq = ip_randomisn();
-+ else
-+#endif
- tp->write_seq = secure_tcp_sequence_number(inet->saddr,
- inet->daddr,
- inet->sport,
- usin->sin_port);
-+ }
-
-- inet->id = tp->write_seq ^ jiffies;
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+ if (grsec_enable_randid)
-+ inet->id = htons(ip_randomid());
-+ else
-+#endif
-+ inet->id = tp->write_seq ^ jiffies;
-
- err = tcp_connect(sk);
- rt = NULL;
-@@ -1593,7 +1633,13 @@
- if (newinet->opt)
- newtp->ext_header_len = newinet->opt->optlen;
- newtp->ext2_header_len = dst->header_len;
-- newinet->id = newtp->write_seq ^ jiffies;
-+
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+ if (grsec_enable_randid)
-+ newinet->id = htons(ip_randomid());
-+ else
-+#endif
-+ newinet->id = newtp->write_seq ^ jiffies;
-
- tcp_sync_mss(newsk, dst_pmtu(dst));
- newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
-diff -urN linux-2.6.5/net/ipv4/udp.c linux-2.6.5/net/ipv4/udp.c
---- linux-2.6.5/net/ipv4/udp.c 2004-04-03 22:36:25.000000000 -0500
-+++ linux-2.6.5/net/ipv4/udp.c 2004-04-18 11:05:52.000000000 -0400
-@@ -100,6 +100,7 @@
- #include <linux/skbuff.h>
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
-+#include <linux/grsecurity.h>
- #include <net/sock.h>
- #include <net/udp.h>
- #include <net/icmp.h>
-@@ -108,6 +109,12 @@
- #include <net/checksum.h>
- #include <net/xfrm.h>
-
-+extern int gr_search_udp_recvmsg(const struct sock *sk,
-+ const struct sk_buff *skb);
-+extern int gr_search_udp_sendmsg(const struct sock *sk,
-+ const struct sockaddr_in *addr);
-+
-+
- /*
- * Snmp MIB for the UDP layer
- */
-@@ -538,9 +545,16 @@
- dport = usin->sin_port;
- if (dport == 0)
- return -EINVAL;
-+
-+ if (!gr_search_udp_sendmsg(sk, usin))
-+ return -EPERM;
- } else {
- if (sk->sk_state != TCP_ESTABLISHED)
- return -EDESTADDRREQ;
-+
-+ if (!gr_search_udp_sendmsg(sk, NULL))
-+ return -EPERM;
-+
- daddr = inet->daddr;
- dport = inet->dport;
- /* Open fast path for connected socket.
-@@ -792,7 +806,12 @@
- if (!skb)
- goto out;
-
-- copied = skb->len - sizeof(struct udphdr);
-+ if (!gr_search_udp_recvmsg(sk, skb)) {
-+ err = -EPERM;
-+ goto out_free;
-+ }
-+
-+ copied = skb->len - sizeof(struct udphdr);
- if (copied > len) {
- copied = len;
- msg->msg_flags |= MSG_TRUNC;
-@@ -901,7 +920,12 @@
- inet->daddr = rt->rt_dst;
- inet->dport = usin->sin_port;
- sk->sk_state = TCP_ESTABLISHED;
-- inet->id = jiffies;
-+#ifdef CONFIG_GRKERNSEC_RANDID
-+ if (grsec_enable_randid)
-+ inet->id = htons(ip_randomid());
-+ else
-+#endif
-+ inet->id = jiffies;
-
- sk_dst_set(sk, &rt->u.dst);
- return(0);
-diff -urN linux-2.6.5/net/socket.c linux-2.6.5/net/socket.c
---- linux-2.6.5/net/socket.c 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/net/socket.c 2004-04-18 11:05:51.000000000 -0400
-@@ -81,6 +81,7 @@
- #include <linux/syscalls.h>
- #include <linux/compat.h>
- #include <linux/kmod.h>
-+#include <linux/in.h>
-
- #ifdef CONFIG_NET_RADIO
- #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
-@@ -92,6 +93,18 @@
- #include <net/sock.h>
- #include <linux/netfilter.h>
-
-+extern void gr_attach_curr_ip(const struct sock *sk);
-+extern int gr_handle_sock_all(const int family, const int type,
-+ const int protocol);
-+extern int gr_handle_sock_server(const struct sockaddr *sck);
-+extern int gr_handle_sock_client(const struct sockaddr *sck);
-+extern int gr_search_connect(const struct socket * sock,
-+ const struct sockaddr_in * addr);
-+extern int gr_search_bind(const struct socket * sock,
-+ const struct sockaddr_in * addr);
-+extern int gr_search_socket(const int domain, const int type,
-+ const int protocol);
-+
- static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
- static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
- size_t size, loff_t pos);
-@@ -872,6 +885,7 @@
- printk(KERN_DEBUG "sock_close: NULL inode\n");
- return 0;
- }
-+
- sock_fasync(-1, filp, 0);
- sock_release(SOCKET_I(inode));
- return 0;
-@@ -1092,6 +1106,16 @@
- int retval;
- struct socket *sock;
-
-+ if(!gr_search_socket(family, type, protocol)) {
-+ retval = -EACCES;
-+ goto out;
-+ }
-+
-+ if (gr_handle_sock_all(family, type, protocol)) {
-+ retval = -EACCES;
-+ goto out;
-+ }
-+
- retval = sock_create(family, type, protocol, &sock);
- if (retval < 0)
- goto out;
-@@ -1187,11 +1211,23 @@
- {
- struct socket *sock;
- char address[MAX_SOCK_ADDR];
-+ struct sockaddr *sck;
- int err;
-
- if((sock = sockfd_lookup(fd,&err))!=NULL)
- {
- if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
-+ sck = (struct sockaddr *)address;
-+ if (!gr_search_bind(sock, (struct sockaddr_in *)sck)) {
-+ sockfd_put(sock);
-+ return -EACCES;
-+ }
-+
-+ if (gr_handle_sock_server(sck)) {
-+ sockfd_put(sock);
-+ return -EACCES;
-+ }
-+
- err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
- if (err) {
- sockfd_put(sock);
-@@ -1294,6 +1330,7 @@
- goto out_release;
-
- security_socket_post_accept(sock, newsock);
-+ gr_attach_curr_ip(newsock->sk);
-
- out_put:
- sockfd_put(sock);
-@@ -1321,6 +1358,7 @@
- {
- struct socket *sock;
- char address[MAX_SOCK_ADDR];
-+ struct sockaddr *sck;
- int err;
-
- sock = sockfd_lookup(fd, &err);
-@@ -1330,6 +1368,18 @@
- if (err < 0)
- goto out_put;
-
-+ sck = (struct sockaddr *)address;
-+
-+ if (!gr_search_connect(sock, (struct sockaddr_in *)sck)) {
-+ err = -EACCES;
-+ goto out_put;
-+ }
-+
-+ if (gr_handle_sock_client(sck)) {
-+ err = -EACCES;
-+ goto out_put;
-+ }
-+
- err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
- if (err)
- goto out_put;
-@@ -1583,6 +1633,7 @@
- err=sock->ops->shutdown(sock, how);
- sockfd_put(sock);
- }
-+
- return err;
- }
-
-diff -urN linux-2.6.5/net/sunrpc/xprt.c linux-2.6.5/net/sunrpc/xprt.c
---- linux-2.6.5/net/sunrpc/xprt.c 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/net/sunrpc/xprt.c 2004-04-18 11:05:52.000000000 -0400
-@@ -58,6 +58,7 @@
- #include <linux/file.h>
- #include <linux/workqueue.h>
- #include <linux/random.h>
-+#include <linux/grsecurity.h>
-
- #include <net/sock.h>
- #include <net/checksum.h>
-@@ -1322,6 +1323,12 @@
- */
- static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
- {
-+
-+#ifdef CONFIG_GRKERNSEC_RANDRPC
-+ if (grsec_enable_randrpc)
-+ return (u32) get_random_long();
-+#endif
-+
- return xprt->xid++;
- }
-
-diff -urN linux-2.6.5/net/unix/af_unix.c linux-2.6.5/net/unix/af_unix.c
---- linux-2.6.5/net/unix/af_unix.c 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/net/unix/af_unix.c 2004-04-18 11:05:52.000000000 -0400
-@@ -120,6 +120,7 @@
- #include <linux/mount.h>
- #include <net/checksum.h>
- #include <linux/security.h>
-+#include <linux/grsecurity.h>
-
- int sysctl_unix_max_dgram_qlen = 10;
-
-@@ -683,6 +684,11 @@
- if (err)
- goto put_fail;
-
-+ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
-+ err = -EACCES;
-+ goto put_fail;
-+ }
-+
- err = -ECONNREFUSED;
- if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
- goto put_fail;
-@@ -706,6 +712,13 @@
- if (u) {
- struct dentry *dentry;
- dentry = unix_sk(u)->dentry;
-+
-+ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
-+ err = -EPERM;
-+ sock_put(u);
-+ goto fail;
-+ }
-+
- if (dentry)
- touch_atime(unix_sk(u)->mnt, dentry);
- } else
-@@ -805,9 +818,18 @@
- */
- mode = S_IFSOCK |
- (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
-+
-+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
-+ err = -EACCES;
-+ goto out_mknod_dput;
-+ }
-+
- err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
- if (err)
- goto out_mknod_dput;
-+
-+ gr_handle_create(dentry, nd.mnt);
-+
- up(&nd.dentry->d_inode->i_sem);
- dput(nd.dentry);
- nd.dentry = dentry;
-@@ -825,6 +847,10 @@
- goto out_unlock;
- }
-
-+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
-+ sk->sk_peercred.pid = current->pid;
-+#endif
-+
- list = &unix_socket_table[addr->hash];
- } else {
- list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
-diff -urN linux-2.6.5/security/Kconfig linux-2.6.5/security/Kconfig
---- linux-2.6.5/security/Kconfig 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/security/Kconfig 2004-04-18 11:05:52.000000000 -0400
-@@ -4,6 +4,407 @@
-
- menu "Security options"
-
-+source grsecurity/Kconfig
-+
-+menu "PaX"
-+
-+config PAX
-+ bool "Enable various PaX features"
-+ depends on ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || SPARC32 || SPARC64 || X86 || X86_64
-+ help
-+ This allows you to enable various PaX features. PaX adds
-+ intrusion prevention mechanisms to the kernel that reduce
-+ the risks posed by exploitable memory corruption bugs.
-+
-+menu "PaX Control"
-+ depends on PAX
-+
-+config PAX_SOFTMODE
-+ bool 'Support soft mode'
-+ help
-+ Enabling this option will allow you to run PaX in soft mode, that
-+ is, PaX features will not be enforced by default, only on executables
-+ marked explicitly. You must also enable PT_PAX_FLAGS support as it
-+ is the only way to mark executables for soft mode use.
-+
-+ Soft mode can be activated by using the "pax_softmode=1" kernel command
-+ line option on boot. Furthermore you can control various PaX features
-+ at runtime via the entries in /proc/sys/kernel/pax.
-+
-+config PAX_EI_PAX
-+ bool 'Use legacy ELF header marking'
-+ help
-+ Enabling this option will allow you to control PaX features on
-+ a per executable basis via the 'chpax' utility available at
-+ http://pax.grsecurity.net/. The control flags will be read from
-+ an otherwise reserved part of the ELF header. This marking has
-+ numerous drawbacks (no support for soft-mode, toolchain does not
-+ know about the non-standard use of the ELF header) therefore it
-+ has been deprecated in favour of PT_PAX_FLAGS support.
-+
-+ You should enable this option only if your toolchain does not yet
-+ support the new control flag location (PT_PAX_FLAGS) or you still
-+ have applications not marked by PT_PAX_FLAGS.
-+
-+ Note that if you enable PT_PAX_FLAGS marking support as well,
-+ it will override the legacy EI_PAX marks.
-+
-+config PAX_PT_PAX_FLAGS
-+ bool 'Use ELF program header marking'
-+ help
-+ Enabling this option will allow you to control PaX features on
-+ a per executable basis via the 'paxctl' utility available at
-+ http://pax.grsecurity.net/. The control flags will be read from
-+ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
-+ has the benefits of supporting both soft mode and being fully
-+ integrated into the toolchain (the binutils patch is available
-+ from http://pax.grsecurity.net).
-+
-+ Note that if you enable the legacy EI_PAX marking support as well,
-+ it will be overridden by the PT_PAX_FLAGS marking.
-+
-+choice
-+ prompt 'MAC system integration'
-+ default PAX_NO_ACL_FLAGS
-+ help
-+ Mandatory Access Control systems have the option of controlling
-+ PaX flags on a per executable basis, choose the method supported
-+ by your particular system.
-+
-+ - "none": if your MAC system does not interact with PaX,
-+ - "direct": if your MAC system defines pax_set_flags() itself,
-+ - "hook": if your MAC system uses the pax_set_flags_func callback.
-+
-+ NOTE: this option is for developers/integrators only.
-+
-+config PAX_NO_ACL_FLAGS
-+ bool 'none'
-+
-+config PAX_HAVE_ACL_FLAGS
-+ bool 'direct'
-+
-+config PAX_HOOK_ACL_FLAGS
-+ bool 'hook'
-+endchoice
-+
-+endmenu
-+
-+menu "Non-executable pages"
-+ depends on PAX
-+
-+config PAX_NOEXEC
-+ bool "Enforce non-executable pages"
-+ depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || SPARC32 || SPARC64 || X86 || X86_64)
-+ help
-+ By design some architectures do not allow for protecting memory
-+ pages against execution or even if they do, Linux does not make
-+ use of this feature. In practice this means that if a page is
-+ readable (such as the stack or heap) it is also executable.
-+
-+ There is a well known exploit technique that makes use of this
-+ fact and a common programming mistake where an attacker can
-+ introduce code of his choice somewhere in the attacked program's
-+ memory (typically the stack or the heap) and then execute it.
-+
-+ If the attacked program was running with different (typically
-+ higher) privileges than that of the attacker, then he can elevate
-+ his own privilege level (e.g. get a root shell, write to files for
-+ which he does not have write access to, etc).
-+
-+ Enabling this option will let you choose from various features
-+ that prevent the injection and execution of 'foreign' code in
-+ a program.
-+
-+ This will also break programs that rely on the old behaviour and
-+ expect that dynamically allocated memory via the malloc() family
-+ of functions is executable (which it is not). Notable examples
-+ are the XFree86 4.x server, the java runtime and wine.
-+
-+config PAX_PAGEEXEC
-+ bool "Paging based non-executable pages"
-+ depends on PAX_NOEXEC && !HIGHPTE && (!X86 || X86_64 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUM4 || MK7 || MK8)
-+ help
-+ This implementation is based on the paging feature of the CPU.
-+ On i386 it has a variable performance impact on applications
-+ depending on their memory usage pattern. You should carefully
-+ test your applications before using this feature in production.
-+ On alpha, ia64, parisc, sparc, sparc64 and x86_64 there is no
-+ performance impact. On ppc there is a slight performance impact.
-+
-+config PAX_SEGMEXEC
-+ bool "Segmentation based non-executable pages"
-+ depends on PAX_NOEXEC && X86 && !X86_64
-+ help
-+ This implementation is based on the segmentation feature of the
-+ CPU and has little performance impact, however applications will
-+ be limited to a 1.5 GB address space instead of the normal 3 GB.
-+
-+config PAX_EMUTRAMP
-+ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC || X86) && !X86_64
-+ default y if PARISC || PPC
-+ help
-+ There are some programs and libraries that for one reason or
-+ another attempt to execute special small code snippets from
-+ non-executable memory pages. Most notable examples are the
-+ signal handler return code generated by the kernel itself and
-+ the GCC trampolines.
-+
-+ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
-+ such programs will no longer work under your kernel.
-+
-+ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
-+ utilities to enable trampoline emulation for the affected programs
-+ yet still have the protection provided by the non-executable pages.
-+
-+ On parisc and ppc you MUST enable this option and EMUSIGRT as
-+ well, otherwise your system will not even boot.
-+
-+ Alternatively you can say N here and use the 'chpax' or 'paxctl'
-+ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
-+ for the affected files.
-+
-+ NOTE: enabling this feature *may* open up a loophole in the
-+ protection provided by non-executable pages that an attacker
-+ could abuse. Therefore the best solution is to not have any
-+ files on your system that would require this option. This can
-+ be achieved by not using libc5 (which relies on the kernel
-+ signal handler return code) and not using or rewriting programs
-+ that make use of the nested function implementation of GCC.
-+ Skilled users can just fix GCC itself so that it implements
-+ nested function calls in a way that does not interfere with PaX.
-+
-+config PAX_EMUSIGRT
-+ bool "Automatically emulate sigreturn trampolines"
-+ depends on PAX_EMUTRAMP && (PARISC || PPC)
-+ default y
-+ help
-+ Enabling this option will have the kernel automatically detect
-+ and emulate signal return trampolines executing on the stack
-+ that would otherwise lead to task termination.
-+
-+ This solution is intended as a temporary one for users with
-+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
-+ Modula-3 runtime, etc) or executables linked to such, basically
-+ everything that does not specify its own SA_RESTORER function in
-+ normal executable memory like glibc 2.1+ does.
-+
-+ On parisc and ppc you MUST enable this option, otherwise your
-+ system will not even boot.
-+
-+ NOTE: this feature cannot be disabled on a per executable basis
-+ and since it *does* open up a loophole in the protection provided
-+ by non-executable pages, the best solution is to not have any
-+ files on your system that would require this option.
-+
-+config PAX_MPROTECT
-+ bool "Restrict mprotect()"
-+ depends on PAX_PAGEEXEC || PAX_SEGMEXEC
-+ help
-+ Enabling this option will prevent programs from
-+ - changing the executable status of memory pages that were
-+ not originally created as executable,
-+ - making read-only executable pages writable again,
-+ - creating executable pages from anonymous memory.
-+
-+ You should say Y here to complete the protection provided by
-+ the enforcement of non-executable pages.
-+
-+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
-+ this feature on a per file basis.
-+
-+config PAX_NOELFRELOCS
-+ bool "Disallow ELF text relocations"
-+ depends on PAX_MPROTECT && (IA64 || X86 || X86_64)
-+ help
-+ Non-executable pages and mprotect() restrictions are effective
-+ in preventing the introduction of new executable code into an
-+ attacked task's address space. There remain only two venues
-+ for this kind of attack: if the attacker can execute already
-+ existing code in the attacked task then he can either have it
-+ create and mmap() a file containing his code or have it mmap()
-+ an already existing ELF library that does not have position
-+ independent code in it and use mprotect() on it to make it
-+ writable and copy his code there. While protecting against
-+ the former approach is beyond PaX, the latter can be prevented
-+ by having only PIC ELF libraries on one's system (which do not
-+ need to relocate their code). If you are sure this is your case,
-+ then enable this option otherwise be careful as you may not even
-+ be able to boot or log on your system (for example, some PAM
-+ modules are erroneously compiled as non-PIC by default).
-+
-+ NOTE: if you are using dynamic ELF executables (as suggested
-+ when using ASLR) then you must have made sure that you linked
-+ your files using the PIC version of crt1 (the et_dyn.tar.gz package
-+ referenced there has already been updated to support this).
-+
-+config PAX_ETEXECRELOCS
-+ bool "Allow ELF ET_EXEC text relocations"
-+ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
-+ default y
-+ help
-+ On some architectures there are incorrectly created applications
-+ that require text relocations and would not work without enabling
-+ this option. If you are an alpha, ia64 or parisc user, you should
-+ enable this option and disable it once you have made sure that
-+ none of your applications need it.
-+
-+config PAX_EMUPLT
-+ bool "Automatically emulate ELF PLT"
-+ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC || SPARC32 || SPARC64)
-+ default y
-+ help
-+ Enabling this option will have the kernel automatically detect
-+ and emulate the Procedure Linkage Table entries in ELF files.
-+ On some architectures such entries are in writable memory, and
-+ become non-executable leading to task termination. Therefore
-+ it is mandatory that you enable this option on alpha, parisc, ppc,
-+ sparc and sparc64, otherwise your system would not even boot.
-+
-+ NOTE: this feature *does* open up a loophole in the protection
-+ provided by the non-executable pages, therefore the proper
-+ solution is to modify the toolchain to produce a PLT that does
-+ not need to be writable.
-+
-+config PAX_DLRESOLVE
-+ bool
-+ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
-+ default y
-+
-+config PAX_SYSCALL
-+ bool
-+ depends on PAX_PAGEEXEC && PPC
-+ default y
-+
-+config PAX_KERNEXEC
-+ bool "Enforce non-executable kernel pages"
-+ depends on PAX_NOEXEC && X86 && !X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM
-+ help
-+ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
-+ that is, enabling this option will make it harder to inject
-+ and execute 'foreign' code in kernel memory itself.
-+
-+endmenu
-+
-+menu "Address Space Layout Randomization"
-+ depends on PAX
-+
-+config PAX_ASLR
-+ bool "Address Space Layout Randomization"
-+ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
-+ help
-+ Many if not most exploit techniques rely on the knowledge of
-+ certain addresses in the attacked program. The following options
-+ will allow the kernel to apply a certain amount of randomization
-+ to specific parts of the program thereby forcing an attacker to
-+ guess them in most cases. Any failed guess will most likely crash
-+ the attacked program which allows the kernel to detect such attempts
-+ and react on them. PaX itself provides no reaction mechanisms,
-+ instead it is strongly encouraged that you make use of Nergal's
-+ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
-+ (http://www.grsecurity.net/) built-in crash detection features or
-+ develop one yourself.
-+
-+ By saying Y here you can choose to randomize the following areas:
-+ - top of the task's kernel stack
-+ - top of the task's userland stack
-+ - base address for mmap() requests that do not specify one
-+ (this includes all libraries)
-+ - base address of the main executable
-+
-+ It is strongly recommended to say Y here as address space layout
-+ randomization has negligible impact on performance yet it provides
-+ a very effective protection.
-+
-+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
-+ this feature on a per file basis.
-+
-+config PAX_RANDKSTACK
-+ bool "Randomize kernel stack base"
-+ depends on PAX_ASLR && X86_TSC && !X86_64
-+ help
-+ By saying Y here the kernel will randomize every task's kernel
-+ stack on every system call. This will not only force an attacker
-+ to guess it but also prevent him from making use of possible
-+ leaked information about it.
-+
-+ Since the kernel stack is a rather scarce resource, randomization
-+ may cause unexpected stack overflows, therefore you should very
-+ carefully test your system. Note that once enabled in the kernel
-+ configuration, this feature cannot be disabled on a per file basis.
-+
-+config PAX_RANDUSTACK
-+ bool "Randomize user stack base"
-+ depends on PAX_ASLR
-+ help
-+ By saying Y here the kernel will randomize every task's userland
-+ stack. The randomization is done in two steps where the second
-+ one may apply a big amount of shift to the top of the stack and
-+ cause problems for programs that want to use lots of memory (more
-+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
-+ For this reason the second step can be controlled by 'chpax' or
-+ 'paxctl' on a per file basis.
-+
-+config PAX_RANDMMAP
-+ bool "Randomize mmap() base"
-+ depends on PAX_ASLR
-+ help
-+ By saying Y here the kernel will use a randomized base address for
-+ mmap() requests that do not specify one themselves. As a result
-+ all dynamically loaded libraries will appear at random addresses
-+ and therefore be harder to exploit by a technique where an attacker
-+ attempts to execute library code for his purposes (e.g. spawn a
-+ shell from an exploited program that is running at an elevated
-+ privilege level).
-+
-+ Furthermore, if a program is relinked as a dynamic ELF file, its
-+ base address will be randomized as well, completing the full
-+ randomization of the address space layout. Attacking such programs
-+ becomes a guess game. You can find an example of doing this at
-+ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
-+ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
-+
-+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
-+ feature on a per file basis.
-+
-+config PAX_RANDEXEC
-+ bool "Randomize ET_EXEC base"
-+ depends on PAX_MPROTECT && PAX_RANDMMAP
-+ help
-+ By saying Y here the kernel will randomize the base address of normal
-+ ET_EXEC ELF executables as well. This is accomplished by mapping the
-+ executable in memory in a special way which also allows for detecting
-+ attackers who attempt to execute its code for their purposes. Since
-+ this special mapping causes performance degradation and the attack
-+ detection may create false alarms as well, you should carefully test
-+ your executables when this feature is enabled.
-+
-+ This solution is intended only as a temporary one until you relink
-+ your programs as a dynamic ELF file.
-+
-+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
-+ feature on a per file basis.
-+
-+config PAX_NOVSYSCALL
-+ bool "Disable the vsyscall page"
-+ depends on PAX_ASLR && X86 && !X86_64
-+ help
-+ The Linux 2.6 kernel introduced a new feature that speeds up or
-+ simplifies certain operations, such as system calls or returns
-+ from signal handlers.
-+
-+ Unfortunately the implementation also gives a powerful instrument
-+ into the hands of exploit writers: the so-called vsyscall page exists
-+ in every task at the same fixed address and it contains machine code
-+ that is very useful in performing the return-to-libc style attack.
-+
-+ Since this exploit technique cannot in general be protected against
-+ via kernel solutions, this option will allow you to disable the use
-+ of the vsyscall page and revert back to the old behaviour.
-+
-+endmenu
-+
-+endmenu
-+
- config SECURITY
- bool "Enable different security models"
- help
-diff -urN linux-2.6.5/security/commoncap.c linux-2.6.5/security/commoncap.c
---- linux-2.6.5/security/commoncap.c 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/security/commoncap.c 2004-04-18 11:05:52.000000000 -0400
-@@ -27,7 +27,7 @@
- int cap_capable (struct task_struct *tsk, int cap)
- {
- /* Derived from include/linux/sched.h:capable. */
-- if (cap_raised (tsk->cap_effective, cap))
-+ if (cap_raised (tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
- return 0;
- else
- return -EPERM;
-@@ -37,7 +37,7 @@
- {
- /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
- if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
-- !capable (CAP_SYS_PTRACE))
-+ !capable_nolog (CAP_SYS_PTRACE))
- return -EPERM;
- else
- return 0;
-@@ -338,7 +338,7 @@
- /*
- * Leave the last 3% for root
- */
-- if (!capable(CAP_SYS_ADMIN))
-+ if (!capable_nolog(CAP_SYS_ADMIN))
- free -= free / 32;
-
- if (free > pages)
-@@ -349,7 +349,7 @@
- * only call if we're about to fail.
- */
- n = nr_free_pages();
-- if (!capable(CAP_SYS_ADMIN))
-+ if (!capable_nolog(CAP_SYS_ADMIN))
- n -= n / 32;
- free += n;
-
-diff -urN linux-2.6.5/security/security.c linux-2.6.5/security/security.c
---- linux-2.6.5/security/security.c 2004-04-03 22:36:13.000000000 -0500
-+++ linux-2.6.5/security/security.c 2004-04-18 11:05:52.000000000 -0400
-@@ -206,4 +206,5 @@
- EXPORT_SYMBOL_GPL(mod_reg_security);
- EXPORT_SYMBOL_GPL(mod_unreg_security);
- EXPORT_SYMBOL(capable);
-+EXPORT_SYMBOL(capable_nolog);
- EXPORT_SYMBOL(security_ops);