1 diff -urNp linux-2.6.20.3/arch/alpha/kernel/module.c linux-2.6.20.3/arch/alpha/kernel/module.c
2 --- linux-2.6.20.3/arch/alpha/kernel/module.c 2007-03-13 14:27:08.000000000 -0400
3 +++ linux-2.6.20.3/arch/alpha/kernel/module.c 2007-03-23 08:10:05.000000000 -0400
4 @@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
6 /* The small sections were sorted to the end of the segment.
7 The following should definitely cover them. */
8 - gp = (u64)me->module_core + me->core_size - 0x8000;
9 + gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
10 got = sechdrs[me->arch.gotsecindex].sh_addr;
12 for (i = 0; i < n; i++) {
13 diff -urNp linux-2.6.20.3/arch/alpha/kernel/osf_sys.c linux-2.6.20.3/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.20.3/arch/alpha/kernel/osf_sys.c 2007-03-13 14:27:08.000000000 -0400
15 +++ linux-2.6.20.3/arch/alpha/kernel/osf_sys.c 2007-03-23 08:10:05.000000000 -0400
16 @@ -1277,6 +1277,10 @@ arch_get_unmapped_area(struct file *filp
17 merely specific addresses, but regions of memory -- perhaps
18 this feature should be incorporated into all ports? */
20 +#ifdef CONFIG_PAX_RANDMMAP
21 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
25 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
26 if (addr != (unsigned long) -ENOMEM)
27 @@ -1284,8 +1288,8 @@ arch_get_unmapped_area(struct file *filp
30 /* Next, try allocating at TASK_UNMAPPED_BASE. */
31 - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
33 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
35 if (addr != (unsigned long) -ENOMEM)
38 diff -urNp linux-2.6.20.3/arch/alpha/kernel/ptrace.c linux-2.6.20.3/arch/alpha/kernel/ptrace.c
39 --- linux-2.6.20.3/arch/alpha/kernel/ptrace.c 2007-03-13 14:27:08.000000000 -0400
40 +++ linux-2.6.20.3/arch/alpha/kernel/ptrace.c 2007-03-23 08:11:18.000000000 -0400
42 #include <linux/security.h>
43 #include <linux/signal.h>
44 #include <linux/vs_base.h>
45 +#include <linux/grsecurity.h>
47 #include <asm/uaccess.h>
48 #include <asm/pgtable.h>
49 @@ -289,6 +290,9 @@ do_sys_ptrace(long request, long pid, lo
53 + if (gr_handle_ptrace(child, request))
56 if (request == PTRACE_ATTACH) {
57 ret = ptrace_attach(child);
59 diff -urNp linux-2.6.20.3/arch/alpha/mm/fault.c linux-2.6.20.3/arch/alpha/mm/fault.c
60 --- linux-2.6.20.3/arch/alpha/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
61 +++ linux-2.6.20.3/arch/alpha/mm/fault.c 2007-03-23 08:10:05.000000000 -0400
63 #include <linux/smp_lock.h>
64 #include <linux/interrupt.h>
65 #include <linux/module.h>
66 +#include <linux/binfmts.h>
68 #include <asm/system.h>
69 #include <asm/uaccess.h>
70 @@ -55,6 +56,124 @@ __load_new_mm_context(struct mm_struct *
74 +#ifdef CONFIG_PAX_PAGEEXEC
76 + * PaX: decide what to do with offenders (regs->pc = fault address)
78 + * returns 1 when task should be killed
79 + * 2 when patched PLT trampoline was detected
80 + * 3 when unpatched PLT trampoline was detected
82 +static int pax_handle_fetch_fault(struct pt_regs *regs)
85 +#ifdef CONFIG_PAX_EMUPLT
88 + do { /* PaX: patched PLT emulation #1 */
89 + unsigned int ldah, ldq, jmp;
91 + err = get_user(ldah, (unsigned int *)regs->pc);
92 + err |= get_user(ldq, (unsigned int *)(regs->pc+4));
93 + err |= get_user(jmp, (unsigned int *)(regs->pc+8));
98 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
99 + (ldq & 0xFFFF0000U) == 0xA77B0000U &&
100 + jmp == 0x6BFB0000U)
102 + unsigned long r27, addr;
103 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
104 + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
106 + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
107 + err = get_user(r27, (unsigned long*)addr);
117 + do { /* PaX: patched PLT emulation #2 */
118 + unsigned int ldah, lda, br;
120 + err = get_user(ldah, (unsigned int *)regs->pc);
121 + err |= get_user(lda, (unsigned int *)(regs->pc+4));
122 + err |= get_user(br, (unsigned int *)(regs->pc+8));
127 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
128 + (lda & 0xFFFF0000U) == 0xA77B0000U &&
129 + (br & 0xFFE00000U) == 0xC3E00000U)
131 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
132 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
133 + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
135 + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
136 + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
141 + do { /* PaX: unpatched PLT emulation */
144 + err = get_user(br, (unsigned int *)regs->pc);
146 + if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
147 + unsigned int br2, ldq, nop, jmp;
148 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
150 + addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
151 + err = get_user(br2, (unsigned int *)addr);
152 + err |= get_user(ldq, (unsigned int *)(addr+4));
153 + err |= get_user(nop, (unsigned int *)(addr+8));
154 + err |= get_user(jmp, (unsigned int *)(addr+12));
155 + err |= get_user(resolver, (unsigned long *)(addr+16));
160 + if (br2 == 0xC3600000U &&
161 + ldq == 0xA77B000CU &&
162 + nop == 0x47FF041FU &&
163 + jmp == 0x6B7B0000U)
165 + regs->r28 = regs->pc+4;
166 + regs->r27 = addr+16;
167 + regs->pc = resolver;
177 +void pax_report_insns(void *pc, void *sp)
181 + printk(KERN_ERR "PAX: bytes at PC: ");
182 + for (i = 0; i < 5; i++) {
184 + if (get_user(c, (unsigned int*)pc+i))
185 + printk("???????? ");
187 + printk("%08x ", c);
194 * This routine handles page faults. It determines the address,
195 @@ -132,8 +251,29 @@ do_page_fault(unsigned long address, uns
197 si_code = SEGV_ACCERR;
199 - if (!(vma->vm_flags & VM_EXEC))
200 + if (!(vma->vm_flags & VM_EXEC)) {
202 +#ifdef CONFIG_PAX_PAGEEXEC
203 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
206 + up_read(&mm->mmap_sem);
207 + switch(pax_handle_fetch_fault(regs)) {
209 +#ifdef CONFIG_PAX_EMUPLT
216 + pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
224 /* Allow reads even for write-only mappings */
225 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
226 diff -urNp linux-2.6.20.3/arch/arm/mm/mmap.c linux-2.6.20.3/arch/arm/mm/mmap.c
227 --- linux-2.6.20.3/arch/arm/mm/mmap.c 2007-03-13 14:27:08.000000000 -0400
228 +++ linux-2.6.20.3/arch/arm/mm/mmap.c 2007-03-23 08:10:05.000000000 -0400
229 @@ -61,6 +61,10 @@ arch_get_unmapped_area(struct file *filp
233 +#ifdef CONFIG_PAX_RANDMMAP
234 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
239 addr = COLOUR_ALIGN(addr, pgoff);
240 @@ -75,7 +79,7 @@ arch_get_unmapped_area(struct file *filp
241 if (len > mm->cached_hole_size) {
242 start_addr = addr = mm->free_area_cache;
244 - start_addr = addr = TASK_UNMAPPED_BASE;
245 + start_addr = addr = mm->mmap_base;
246 mm->cached_hole_size = 0;
249 @@ -92,8 +96,8 @@ full_search:
250 * Start a new search - just in case we missed
253 - if (start_addr != TASK_UNMAPPED_BASE) {
254 - start_addr = addr = TASK_UNMAPPED_BASE;
255 + if (start_addr != mm->mmap_base) {
256 + start_addr = addr = mm->mmap_base;
257 mm->cached_hole_size = 0;
260 diff -urNp linux-2.6.20.3/arch/i386/boot/setup.S linux-2.6.20.3/arch/i386/boot/setup.S
261 --- linux-2.6.20.3/arch/i386/boot/setup.S 2007-03-13 14:27:08.000000000 -0400
262 +++ linux-2.6.20.3/arch/i386/boot/setup.S 2007-03-23 08:10:05.000000000 -0400
263 @@ -869,11 +869,13 @@ startup_32:
267 + movl 0x00000000, %ecx
269 1: incl %eax # check that A20 really IS enabled
270 movl %eax, 0x00000000 # loop forever if it isn't
271 cmpl %eax, 0x00100000
273 + movl %ecx, 0x00000000
275 # Jump to the 32bit entry point
276 jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
277 diff -urNp linux-2.6.20.3/arch/i386/Kconfig linux-2.6.20.3/arch/i386/Kconfig
278 --- linux-2.6.20.3/arch/i386/Kconfig 2007-03-13 14:27:08.000000000 -0400
279 +++ linux-2.6.20.3/arch/i386/Kconfig 2007-03-23 08:11:18.000000000 -0400
280 @@ -864,7 +864,7 @@ config HOTPLUG_CPU
283 bool "Compat VDSO support"
288 Map the VDSO to the predictable old-style address too.
289 @@ -1060,7 +1060,7 @@ config PCI
291 prompt "PCI access mode"
292 depends on PCI && !X86_VISWS
294 + default PCI_GODIRECT
296 On PCI systems, the BIOS can be used to detect the PCI devices and
297 determine their configuration. However, some old PCI motherboards
298 @@ -1092,7 +1092,7 @@ endchoice
302 - depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
303 + depends on !X86_VISWS && PCI && PCI_GOBIOS
307 diff -urNp linux-2.6.20.3/arch/i386/Kconfig.cpu linux-2.6.20.3/arch/i386/Kconfig.cpu
308 --- linux-2.6.20.3/arch/i386/Kconfig.cpu 2007-03-13 14:27:08.000000000 -0400
309 +++ linux-2.6.20.3/arch/i386/Kconfig.cpu 2007-03-23 08:10:05.000000000 -0400
310 @@ -267,7 +267,7 @@ config X86_PPRO_FENCE
314 - depends on M586MMX || M586TSC || M586 || M486 || M386
315 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
318 config X86_WP_WORKS_OK
319 @@ -297,7 +297,7 @@ config X86_CMPXCHG64
321 config X86_ALIGNMENT_16
323 - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
324 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
328 diff -urNp linux-2.6.20.3/arch/i386/Kconfig.debug linux-2.6.20.3/arch/i386/Kconfig.debug
329 --- linux-2.6.20.3/arch/i386/Kconfig.debug 2007-03-13 14:27:08.000000000 -0400
330 +++ linux-2.6.20.3/arch/i386/Kconfig.debug 2007-03-23 08:10:05.000000000 -0400
331 @@ -48,7 +48,7 @@ config DEBUG_PAGEALLOC
334 bool "Write protect kernel read-only data structures"
335 - depends on DEBUG_KERNEL
336 + depends on DEBUG_KERNEL && !PAX_KERNEXEC
338 Mark the kernel read-only data as write-protected in the pagetables,
339 in order to catch accidental (and incorrect) writes to such const
340 diff -urNp linux-2.6.20.3/arch/i386/kernel/acpi/boot.c linux-2.6.20.3/arch/i386/kernel/acpi/boot.c
341 --- linux-2.6.20.3/arch/i386/kernel/acpi/boot.c 2007-03-13 14:27:08.000000000 -0400
342 +++ linux-2.6.20.3/arch/i386/kernel/acpi/boot.c 2007-03-23 08:10:05.000000000 -0400
343 @@ -1152,7 +1152,7 @@ static struct dmi_system_id __initdata a
344 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
348 + { NULL, NULL, {{0, NULL}}, NULL}
351 #endif /* __i386__ */
352 diff -urNp linux-2.6.20.3/arch/i386/kernel/acpi/sleep.c linux-2.6.20.3/arch/i386/kernel/acpi/sleep.c
353 --- linux-2.6.20.3/arch/i386/kernel/acpi/sleep.c 2007-03-13 14:27:08.000000000 -0400
354 +++ linux-2.6.20.3/arch/i386/kernel/acpi/sleep.c 2007-03-23 08:10:05.000000000 -0400
355 @@ -94,7 +94,7 @@ static __initdata struct dmi_system_id a
356 DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
360 + { NULL, NULL, {{0, NULL}}, NULL}
363 static int __init acpisleep_dmi_init(void)
364 diff -urNp linux-2.6.20.3/arch/i386/kernel/acpi/wakeup.S linux-2.6.20.3/arch/i386/kernel/acpi/wakeup.S
365 --- linux-2.6.20.3/arch/i386/kernel/acpi/wakeup.S 2007-03-13 14:27:08.000000000 -0400
366 +++ linux-2.6.20.3/arch/i386/kernel/acpi/wakeup.S 2007-03-23 08:10:05.000000000 -0400
367 @@ -205,13 +205,11 @@ wakeup_pmode_return:
368 # and restore the stack ... but you need gdt for this to work
369 movl saved_context_esp, %esp
371 - movl %cs:saved_magic, %eax
372 - cmpl $0x12345678, %eax
373 + cmpl $0x12345678, saved_magic
376 # jump to place where we left off
377 - movl saved_eip,%eax
382 movw $0x0e00 + 'B', 0xb8018
383 diff -urNp linux-2.6.20.3/arch/i386/kernel/alternative.c linux-2.6.20.3/arch/i386/kernel/alternative.c
384 --- linux-2.6.20.3/arch/i386/kernel/alternative.c 2007-03-13 14:27:08.000000000 -0400
385 +++ linux-2.6.20.3/arch/i386/kernel/alternative.c 2007-03-23 08:10:05.000000000 -0400
387 #include <linux/list.h>
388 #include <asm/alternative.h>
389 #include <asm/sections.h>
390 +#include <asm/desc.h>
392 static int no_replacement = 0;
393 static int smp_alt_once = 0;
394 @@ -156,12 +157,18 @@ void apply_alternatives(struct alt_instr
398 +#ifdef CONFIG_PAX_KERNEXEC
401 + pax_open_kernel(cr0);
404 DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
405 for (a = start; a < end; a++) {
406 BUG_ON(a->replacementlen > a->instrlen);
407 if (!boot_cpu_has(a->cpuid))
410 + instr = a->instr + __KERNEL_TEXT_OFFSET;
412 /* vsyscall code is not mapped yet. resolve it manually. */
413 if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) {
414 @@ -174,6 +181,11 @@ void apply_alternatives(struct alt_instr
415 diff = a->instrlen - a->replacementlen;
416 nop_out(instr + a->replacementlen, diff);
419 +#ifdef CONFIG_PAX_KERNEXEC
420 + pax_close_kernel(cr0);
426 @@ -182,49 +194,95 @@ static void alternatives_smp_save(struct
430 +#ifdef CONFIG_PAX_KERNEXEC
433 + pax_open_kernel(cr0);
436 DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end);
437 for (a = start; a < end; a++) {
438 memcpy(a->replacement + a->replacementlen,
440 + a->instr + __KERNEL_TEXT_OFFSET,
444 +#ifdef CONFIG_PAX_KERNEXEC
445 + pax_close_kernel(cr0);
450 static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end)
454 +#ifdef CONFIG_PAX_KERNEXEC
457 + pax_open_kernel(cr0);
460 for (a = start; a < end; a++) {
462 + memcpy(a->instr + __KERNEL_TEXT_OFFSET,
463 a->replacement + a->replacementlen,
467 +#ifdef CONFIG_PAX_KERNEXEC
468 + pax_close_kernel(cr0);
473 static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
478 - for (ptr = start; ptr < end; ptr++) {
480 +#ifdef CONFIG_PAX_KERNEXEC
483 + pax_open_kernel(cr0);
486 + for (; start < end; start++) {
487 + ptr = *start + __KERNEL_TEXT_OFFSET;
490 - if (*ptr > text_end)
491 + if (ptr > text_end)
493 - **ptr = 0xf0; /* lock prefix */
494 + *ptr = 0xf0; /* lock prefix */
497 +#ifdef CONFIG_PAX_KERNEXEC
498 + pax_close_kernel(cr0);
503 static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
508 +#ifdef CONFIG_PAX_KERNEXEC
511 + pax_open_kernel(cr0);
514 - for (ptr = start; ptr < end; ptr++) {
516 + for (; start < end; start++) {
517 + ptr = *start + __KERNEL_TEXT_OFFSET;
520 - if (*ptr > text_end)
521 + if (ptr > text_end)
527 +#ifdef CONFIG_PAX_KERNEXEC
528 + pax_close_kernel(cr0);
533 struct smp_alt_module {
534 @@ -354,10 +412,17 @@ void apply_paravirt(struct paravirt_patc
536 struct paravirt_patch *p;
538 +#ifdef CONFIG_PAX_KERNEXEC
541 + pax_open_kernel(cr0);
544 for (p = start; p < end; p++) {
546 + u8 *instr = p->instr + __KERNEL_TEXT_OFFSET;
548 - used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr,
549 + used = paravirt_ops.patch(p->instrtype, p->clobbers, instr,
551 #ifdef CONFIG_DEBUG_PARAVIRT
553 @@ -365,17 +430,20 @@ void apply_paravirt(struct paravirt_patc
554 /* Deliberately clobber regs using "not %reg" to find bugs. */
555 for (i = 0; i < 3; i++) {
556 if (p->len - used >= 2 && (p->clobbers & (1 << i))) {
557 - memcpy(p->instr + used, "\xf7\xd0", 2);
558 - p->instr[used+1] |= i;
560 + instr[used++] = 0xf7;
561 + instr[used++] = 0xd0 | i;
566 /* Pad the rest with nops */
567 - nop_out(p->instr + used, p->len - used);
568 + nop_out(instr + used, p->len - used);
571 +#ifdef CONFIG_PAX_KERNEXEC
572 + pax_close_kernel(cr0);
575 /* Sync to be conservative, in case we patched following instructions */
578 diff -urNp linux-2.6.20.3/arch/i386/kernel/apic.c linux-2.6.20.3/arch/i386/kernel/apic.c
579 --- linux-2.6.20.3/arch/i386/kernel/apic.c 2007-03-13 14:27:08.000000000 -0400
580 +++ linux-2.6.20.3/arch/i386/kernel/apic.c 2007-03-23 08:10:05.000000000 -0400
581 @@ -1211,7 +1211,7 @@ inline void smp_local_timer_interrupt(vo
583 profile_tick(CPU_PROFILING);
585 - update_process_times(user_mode_vm(get_irq_regs()));
586 + update_process_times(user_mode(get_irq_regs()));
590 diff -urNp linux-2.6.20.3/arch/i386/kernel/apm.c linux-2.6.20.3/arch/i386/kernel/apm.c
591 --- linux-2.6.20.3/arch/i386/kernel/apm.c 2007-03-13 14:27:08.000000000 -0400
592 +++ linux-2.6.20.3/arch/i386/kernel/apm.c 2007-03-23 08:10:05.000000000 -0400
594 #include "io_ports.h"
596 extern unsigned long get_cmos_time(void);
597 -extern void machine_real_restart(unsigned char *, int);
598 +extern void machine_real_restart(const unsigned char *, unsigned int);
600 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
601 extern int (*console_blank_hook)(int);
602 @@ -609,9 +609,18 @@ static u8 apm_bios_call(u32 func, u32 eb
603 struct desc_struct save_desc_40;
604 struct desc_struct *gdt;
606 +#ifdef CONFIG_PAX_KERNEXEC
610 cpus = apm_save_cpus();
614 +#ifdef CONFIG_PAX_KERNEXEC
615 + pax_open_kernel(cr0);
618 gdt = get_cpu_gdt_table(cpu);
619 save_desc_40 = gdt[0x40 / 8];
620 gdt[0x40 / 8] = bad_bios_desc;
621 @@ -622,6 +631,11 @@ static u8 apm_bios_call(u32 func, u32 eb
623 apm_irq_restore(flags);
624 gdt[0x40 / 8] = save_desc_40;
626 +#ifdef CONFIG_PAX_KERNEXEC
627 + pax_close_kernel(cr0);
631 apm_restore_cpus(cpus);
633 @@ -652,9 +666,18 @@ static u8 apm_bios_call_simple(u32 func,
634 struct desc_struct save_desc_40;
635 struct desc_struct *gdt;
637 +#ifdef CONFIG_PAX_KERNEXEC
641 cpus = apm_save_cpus();
645 +#ifdef CONFIG_PAX_KERNEXEC
646 + pax_open_kernel(cr0);
649 gdt = get_cpu_gdt_table(cpu);
650 save_desc_40 = gdt[0x40 / 8];
651 gdt[0x40 / 8] = bad_bios_desc;
652 @@ -665,6 +688,11 @@ static u8 apm_bios_call_simple(u32 func,
654 apm_irq_restore(flags);
655 gdt[0x40 / 8] = save_desc_40;
657 +#ifdef CONFIG_PAX_KERNEXEC
658 + pax_close_kernel(cr0);
662 apm_restore_cpus(cpus);
664 @@ -932,7 +960,7 @@ recalc:
666 static void apm_power_off(void)
668 - unsigned char po_bios_call[] = {
669 + const unsigned char po_bios_call[] = {
670 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
671 0x8e, 0xd0, /* movw ax,ss */
672 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
673 @@ -1906,7 +1934,10 @@ static struct file_operations apm_bios_f
674 static struct miscdevice apm_device = {
685 @@ -2016,210 +2047,210 @@ static struct dmi_system_id __initdata a
687 KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.",
688 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
689 - DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), },
690 + DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), }, NULL
692 { /* Handle problems with APM on the C600 */
693 broken_ps2_resume, "Dell Latitude C600",
694 { DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
695 - DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), },
696 + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), }, NULL
698 { /* Allow interrupts during suspend on Dell Latitude laptops*/
699 set_apm_ints, "Dell Latitude",
700 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
701 - DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }
702 + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }, NULL
705 apm_is_horked, "Dell Inspiron 2500",
706 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
707 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
708 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
709 - DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
710 + DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
712 { /* Allow interrupts during suspend on Dell Inspiron laptops*/
713 set_apm_ints, "Dell Inspiron", {
714 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
715 - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), },
716 + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), }, NULL
718 { /* Handle problems with APM on Inspiron 5000e */
719 broken_apm_power, "Dell Inspiron 5000e",
720 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
721 DMI_MATCH(DMI_BIOS_VERSION, "A04"),
722 - DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), },
723 + DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), }, NULL
725 { /* Handle problems with APM on Inspiron 2500 */
726 broken_apm_power, "Dell Inspiron 2500",
727 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
728 DMI_MATCH(DMI_BIOS_VERSION, "A12"),
729 - DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), },
730 + DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), }, NULL
733 apm_is_horked, "Dell Dimension 4100",
734 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
735 DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
736 DMI_MATCH(DMI_BIOS_VENDOR,"Intel Corp."),
737 - DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
738 + DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
740 { /* Allow interrupts during suspend on Compaq Laptops*/
741 set_apm_ints, "Compaq 12XL125",
742 { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
743 DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
744 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
745 - DMI_MATCH(DMI_BIOS_VERSION,"4.06"), },
746 + DMI_MATCH(DMI_BIOS_VERSION,"4.06"), }, NULL
748 { /* Allow interrupts during APM or the clock goes slow */
749 set_apm_ints, "ASUSTeK",
750 { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
751 - DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), },
752 + DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), }, NULL
754 { /* APM blows on shutdown */
755 apm_is_horked, "ABIT KX7-333[R]",
756 { DMI_MATCH(DMI_BOARD_VENDOR, "ABIT"),
757 - DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), },
758 + DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), }, NULL
761 apm_is_horked, "Trigem Delhi3",
762 { DMI_MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
763 - DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), },
764 + DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), }, NULL
767 apm_is_horked, "Fujitsu-Siemens",
768 { DMI_MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
769 - DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), },
770 + DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), }, NULL
773 apm_is_horked_d850md, "Intel D850MD",
774 { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
775 - DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), },
776 + DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), }, NULL
779 apm_is_horked, "Intel D810EMO",
780 { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
781 - DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), },
782 + DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), }, NULL
785 apm_is_horked, "Dell XPS-Z",
786 { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
787 DMI_MATCH(DMI_BIOS_VERSION, "A11"),
788 - DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), },
789 + DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), }, NULL
792 apm_is_horked, "Sharp PC-PJ/AX",
793 { DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
794 DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
795 DMI_MATCH(DMI_BIOS_VENDOR,"SystemSoft"),
796 - DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), },
797 + DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), }, NULL
800 apm_is_horked, "Dell Inspiron 2500",
801 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
802 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
803 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
804 - DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
805 + DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
807 { /* APM idle hangs */
808 apm_likes_to_melt, "Jabil AMD",
809 { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
810 - DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
811 + DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), }, NULL
813 { /* APM idle hangs */
814 apm_likes_to_melt, "AMI Bios",
815 { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
816 - DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
817 + DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), }, NULL
819 { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
820 swab_apm_power_in_minutes, "Sony VAIO",
821 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
822 DMI_MATCH(DMI_BIOS_VERSION, "R0206H"),
823 - DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), },
824 + DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), }, NULL
826 { /* Handle problems with APM on Sony Vaio PCG-N505VX */
827 swab_apm_power_in_minutes, "Sony VAIO",
828 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
829 DMI_MATCH(DMI_BIOS_VERSION, "W2K06H0"),
830 - DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), },
831 + DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), }, NULL
833 { /* Handle problems with APM on Sony Vaio PCG-XG29 */
834 swab_apm_power_in_minutes, "Sony VAIO",
835 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
836 DMI_MATCH(DMI_BIOS_VERSION, "R0117A0"),
837 - DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), },
838 + DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), }, NULL
840 { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
841 swab_apm_power_in_minutes, "Sony VAIO",
842 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
843 DMI_MATCH(DMI_BIOS_VERSION, "R0121Z1"),
844 - DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), },
845 + DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), }, NULL
847 { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
848 swab_apm_power_in_minutes, "Sony VAIO",
849 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
850 DMI_MATCH(DMI_BIOS_VERSION, "WME01Z1"),
851 - DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), },
852 + DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), }, NULL
854 { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
855 swab_apm_power_in_minutes, "Sony VAIO",
856 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
857 DMI_MATCH(DMI_BIOS_VERSION, "R0206Z3"),
858 - DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), },
859 + DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), }, NULL
861 { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
862 swab_apm_power_in_minutes, "Sony VAIO",
863 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
864 DMI_MATCH(DMI_BIOS_VERSION, "R0203D0"),
865 - DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), },
866 + DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), }, NULL
868 { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
869 swab_apm_power_in_minutes, "Sony VAIO",
870 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
871 DMI_MATCH(DMI_BIOS_VERSION, "R0203Z3"),
872 - DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), },
873 + DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), }, NULL
875 { /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
876 swab_apm_power_in_minutes, "Sony VAIO",
877 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
878 DMI_MATCH(DMI_BIOS_VERSION, "R0209Z3"),
879 - DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), },
880 + DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), }, NULL
882 { /* Handle problems with APM on Sony Vaio PCG-F104K */
883 swab_apm_power_in_minutes, "Sony VAIO",
884 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
885 DMI_MATCH(DMI_BIOS_VERSION, "R0204K2"),
886 - DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), },
887 + DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), }, NULL
890 { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
891 swab_apm_power_in_minutes, "Sony VAIO",
892 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
893 DMI_MATCH(DMI_BIOS_VERSION, "R0208P1"),
894 - DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), },
895 + DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), }, NULL
897 { /* Handle problems with APM on Sony Vaio PCG-C1VE */
898 swab_apm_power_in_minutes, "Sony VAIO",
899 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
900 DMI_MATCH(DMI_BIOS_VERSION, "R0204P1"),
901 - DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), },
902 + DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), }, NULL
904 { /* Handle problems with APM on Sony Vaio PCG-C1VE */
905 swab_apm_power_in_minutes, "Sony VAIO",
906 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
907 DMI_MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
908 - DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), },
909 + DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), }, NULL
911 { /* broken PM poweroff bios */
912 set_realmode_power_off, "Award Software v4.60 PGMA",
913 { DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
914 DMI_MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
915 - DMI_MATCH(DMI_BIOS_DATE, "134526184"), },
916 + DMI_MATCH(DMI_BIOS_DATE, "134526184"), }, NULL
919 /* Generic per vendor APM settings */
921 { /* Allow interrupts during suspend on IBM laptops */
923 - { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
924 + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, NULL
928 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
932 diff -urNp linux-2.6.20.3/arch/i386/kernel/asm-offsets.c linux-2.6.20.3/arch/i386/kernel/asm-offsets.c
933 --- linux-2.6.20.3/arch/i386/kernel/asm-offsets.c 2007-03-13 14:27:08.000000000 -0400
934 +++ linux-2.6.20.3/arch/i386/kernel/asm-offsets.c 2007-03-23 08:10:05.000000000 -0400
936 #include <asm/thread_info.h>
939 +#include <asm/pgtable.h>
941 #define DEFINE(sym, val) \
942 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
943 @@ -52,6 +53,7 @@ void foo(void)
944 OFFSET(TI_exec_domain, thread_info, exec_domain);
945 OFFSET(TI_flags, thread_info, flags);
946 OFFSET(TI_status, thread_info, status);
947 + OFFSET(TI_cpu, thread_info, cpu);
948 OFFSET(TI_preempt_count, thread_info, preempt_count);
949 OFFSET(TI_addr_limit, thread_info, addr_limit);
950 OFFSET(TI_restart_block, thread_info, restart_block);
951 @@ -94,12 +96,14 @@ void foo(void)
952 sizeof(struct tss_struct));
954 DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
955 + DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
956 DEFINE(VDSO_PRELINK, VDSO_PRELINK);
958 OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
961 - OFFSET(PDA_cpu, i386_pda, cpu_number);
962 + DEFINE(PDA_size, sizeof __cpu_pda[0]);
963 + OFFSET(PDA_cpu, i386_pda, cpu_number);
964 OFFSET(PDA_pcurrent, i386_pda, pcurrent);
966 #ifdef CONFIG_PARAVIRT
967 @@ -110,5 +114,6 @@ void foo(void)
968 OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
969 OFFSET(PARAVIRT_iret, paravirt_ops, iret);
970 OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
971 + OFFSET(PARAVIRT_write_cr0, paravirt_ops, write_cr0);
974 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/common.c linux-2.6.20.3/arch/i386/kernel/cpu/common.c
975 --- linux-2.6.20.3/arch/i386/kernel/cpu/common.c 2007-03-13 14:27:08.000000000 -0400
976 +++ linux-2.6.20.3/arch/i386/kernel/cpu/common.c 2007-03-23 08:10:05.000000000 -0400
978 #include <linux/smp.h>
979 #include <linux/module.h>
980 #include <linux/percpu.h>
981 -#include <linux/bootmem.h>
982 #include <asm/semaphore.h>
983 #include <asm/processor.h>
984 #include <asm/i387.h>
989 -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
990 -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
992 -struct i386_pda *_cpu_pda[NR_CPUS] __read_mostly;
993 EXPORT_SYMBOL(_cpu_pda);
995 static int cachesize_override __cpuinitdata = -1;
996 static int disable_x86_fxsr __cpuinitdata;
997 static int disable_x86_serial_nr __cpuinitdata = 1;
999 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC)
1000 +static int disable_x86_sep __cpuinitdata = 1;
1002 static int disable_x86_sep __cpuinitdata;
1005 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
1007 @@ -609,52 +609,6 @@ struct pt_regs * __devinit idle_regs(str
1011 -static __cpuinit int alloc_gdt(int cpu)
1013 - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
1014 - struct desc_struct *gdt;
1015 - struct i386_pda *pda;
1017 - gdt = (struct desc_struct *)cpu_gdt_descr->address;
1018 - pda = cpu_pda(cpu);
1021 - * This is a horrible hack to allocate the GDT. The problem
1022 - * is that cpu_init() is called really early for the boot CPU
1023 - * (and hence needs bootmem) but much later for the secondary
1024 - * CPUs, when bootmem will have gone away
1026 - if (NODE_DATA(0)->bdata->node_bootmem_map) {
1027 - BUG_ON(gdt != NULL || pda != NULL);
1029 - gdt = alloc_bootmem_pages(PAGE_SIZE);
1030 - pda = alloc_bootmem(sizeof(*pda));
1031 - /* alloc_bootmem(_pages) panics on failure, so no check */
1033 - memset(gdt, 0, PAGE_SIZE);
1034 - memset(pda, 0, sizeof(*pda));
1036 - /* GDT and PDA might already have been allocated if
1037 - this is a CPU hotplug re-insertion. */
1039 - gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
1042 - pda = kmalloc_node(sizeof(*pda), GFP_KERNEL, cpu_to_node(cpu));
1044 - if (unlikely(!gdt || !pda)) {
1045 - free_pages((unsigned long)gdt, 0);
1051 - cpu_gdt_descr->address = (unsigned long)gdt;
1052 - cpu_pda(cpu) = pda;
1057 /* Initial PDA used by boot CPU */
1058 struct i386_pda boot_pda = {
1060 @@ -672,59 +626,43 @@ static inline void set_kernel_gs(void)
1062 /* Initialize the CPU's GDT and PDA. The boot CPU does this for
1063 itself, but secondaries find this done for them. */
1064 -__cpuinit int init_gdt(int cpu, struct task_struct *idle)
1065 +__cpuinit void init_gdt(int cpu, struct task_struct *idle)
1067 - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
1068 - struct desc_struct *gdt;
1069 - struct i386_pda *pda;
1071 - /* For non-boot CPUs, the GDT and PDA should already have been
1073 - if (!alloc_gdt(cpu)) {
1074 - printk(KERN_CRIT "CPU%d failed to allocate GDT or PDA\n", cpu);
1077 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
1078 + struct i386_pda *pda = __cpu_pda + cpu;
1080 - gdt = (struct desc_struct *)cpu_gdt_descr->address;
1081 - pda = cpu_pda(cpu);
1083 - BUG_ON(gdt == NULL || pda == NULL);
1084 + cpu_gdt_descr[cpu].address = gdt;
1087 * Initialize the per-CPU GDT with the boot GDT,
1088 * and set up the GDT descriptor:
1090 - memcpy(gdt, cpu_gdt_table, GDT_SIZE);
1091 - cpu_gdt_descr->size = GDT_SIZE - 1;
1093 + memcpy(gdt, cpu_gdt_table, GDT_SIZE);
1094 + cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
1096 pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a,
1097 (u32 *)&gdt[GDT_ENTRY_PDA].b,
1098 (unsigned long)pda, sizeof(*pda) - 1,
1099 - 0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */
1100 + 0x80 | DESCTYPE_S | 0x3, 0); /* present read-write data segment */
1102 - memset(pda, 0, sizeof(*pda));
1104 - pda->cpu_number = cpu;
1105 pda->pcurrent = idle;
1108 + pda->irq_regs = NULL;
1111 void __cpuinit cpu_set_gdt(int cpu)
1113 - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
1115 /* Reinit these anyway, even if they've already been done (on
1116 the boot CPU, this will transition from the boot gdt+pda to
1118 - load_gdt(cpu_gdt_descr);
1119 + load_gdt(&cpu_gdt_descr[cpu]);
1123 /* Common CPU init for both boot and secondary CPUs */
1124 static void __cpuinit _cpu_init(int cpu, struct task_struct *curr)
1126 - struct tss_struct * t = &per_cpu(init_tss, cpu);
1127 + struct tss_struct * t = init_tss + cpu;
1128 struct thread_struct *thread = &curr->thread;
1130 if (cpu_test_and_set(cpu, cpu_initialized)) {
1131 @@ -805,12 +743,7 @@ void __cpuinit cpu_init(void)
1133 /* Set up the real GDT and PDA, so we can transition from the
1135 - if (!init_gdt(cpu, curr)) {
1136 - /* failed to allocate something; not much we can do... */
1138 - local_irq_enable();
1141 + init_gdt(cpu, curr);
1143 _cpu_init(cpu, curr);
1145 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
1146 --- linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-03-13 14:27:08.000000000 -0400
1147 +++ linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-03-23 08:10:05.000000000 -0400
1148 @@ -563,7 +563,7 @@ static struct dmi_system_id sw_any_bug_d
1149 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
1153 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
1157 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
1158 --- linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-03-13 14:27:08.000000000 -0400
1159 +++ linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-03-23 08:10:05.000000000 -0400
1160 @@ -229,7 +229,7 @@ static struct cpu_model models[] =
1161 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
1162 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
1165 + { NULL, NULL, 0, NULL}
1169 @@ -404,7 +404,7 @@ static struct dmi_system_id sw_any_bug_d
1170 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
1174 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
1178 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/cyrix.c linux-2.6.20.3/arch/i386/kernel/cpu/cyrix.c
1179 --- linux-2.6.20.3/arch/i386/kernel/cpu/cyrix.c 2007-03-13 14:27:08.000000000 -0400
1180 +++ linux-2.6.20.3/arch/i386/kernel/cpu/cyrix.c 2007-03-23 08:10:05.000000000 -0400
1181 @@ -187,7 +187,7 @@ static void __cpuinit geode_configure(vo
1182 static struct pci_device_id __cpuinitdata cyrix_55x0[] = {
1183 { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) },
1184 { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) },
1186 + { PCI_DEVICE(0, 0) },
1190 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/mcheck/therm_throt.c linux-2.6.20.3/arch/i386/kernel/cpu/mcheck/therm_throt.c
1191 --- linux-2.6.20.3/arch/i386/kernel/cpu/mcheck/therm_throt.c 2007-03-13 14:27:08.000000000 -0400
1192 +++ linux-2.6.20.3/arch/i386/kernel/cpu/mcheck/therm_throt.c 2007-03-23 08:10:05.000000000 -0400
1193 @@ -148,7 +148,7 @@ static __cpuinit int thermal_throttle_cp
1197 -static struct notifier_block thermal_throttle_cpu_notifier =
1198 +static __cpuinitdata struct notifier_block thermal_throttle_cpu_notifier =
1200 .notifier_call = thermal_throttle_cpu_callback,
1202 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/mtrr/generic.c linux-2.6.20.3/arch/i386/kernel/cpu/mtrr/generic.c
1203 --- linux-2.6.20.3/arch/i386/kernel/cpu/mtrr/generic.c 2007-03-13 14:27:08.000000000 -0400
1204 +++ linux-2.6.20.3/arch/i386/kernel/cpu/mtrr/generic.c 2007-03-23 08:10:05.000000000 -0400
1205 @@ -21,7 +21,7 @@ struct mtrr_state {
1208 static unsigned long smp_changes_mask;
1209 -static struct mtrr_state mtrr_state = {};
1210 +static struct mtrr_state mtrr_state;
1212 #undef MODULE_PARAM_PREFIX
1213 #define MODULE_PARAM_PREFIX "mtrr."
1214 diff -urNp linux-2.6.20.3/arch/i386/kernel/crash.c linux-2.6.20.3/arch/i386/kernel/crash.c
1215 --- linux-2.6.20.3/arch/i386/kernel/crash.c 2007-03-13 14:27:08.000000000 -0400
1216 +++ linux-2.6.20.3/arch/i386/kernel/crash.c 2007-03-23 08:10:05.000000000 -0400
1217 @@ -55,7 +55,7 @@ static int crash_nmi_callback(struct not
1219 local_irq_disable();
1221 - if (!user_mode_vm(regs)) {
1222 + if (!user_mode(regs)) {
1223 crash_fixup_ss_esp(&fixed_regs, regs);
1226 diff -urNp linux-2.6.20.3/arch/i386/kernel/doublefault.c linux-2.6.20.3/arch/i386/kernel/doublefault.c
1227 --- linux-2.6.20.3/arch/i386/kernel/doublefault.c 2007-03-13 14:27:08.000000000 -0400
1228 +++ linux-2.6.20.3/arch/i386/kernel/doublefault.c 2007-03-23 08:10:05.000000000 -0400
1231 #define DOUBLEFAULT_STACKSIZE (1024)
1232 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
1233 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
1234 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
1236 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
1238 static void doublefault_fn(void)
1240 - struct Xgt_desc_struct gdt_desc = {0, 0};
1241 + struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
1242 unsigned long gdt, tss;
1244 store_gdt(&gdt_desc);
1245 - gdt = gdt_desc.address;
1246 + gdt = (unsigned long)gdt_desc.address;
1248 printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
1250 @@ -57,10 +57,10 @@ struct tss_struct doublefault_tss __cach
1251 .eip = (unsigned long) doublefault_fn,
1252 .eflags = X86_EFLAGS_SF | 0x2, /* 0x2 bit is always set */
1255 + .es = __KERNEL_DS,
1259 + .ds = __KERNEL_DS,
1261 .__cr3 = __pa(swapper_pg_dir)
1263 diff -urNp linux-2.6.20.3/arch/i386/kernel/efi.c linux-2.6.20.3/arch/i386/kernel/efi.c
1264 --- linux-2.6.20.3/arch/i386/kernel/efi.c 2007-03-13 14:27:08.000000000 -0400
1265 +++ linux-2.6.20.3/arch/i386/kernel/efi.c 2007-03-23 08:10:05.000000000 -0400
1266 @@ -63,82 +63,43 @@ extern void * boot_ioremap(unsigned long
1268 static unsigned long efi_rt_eflags;
1269 static DEFINE_SPINLOCK(efi_rt_lock);
1270 -static pgd_t efi_bak_pg_dir_pointer[2];
1271 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
1273 static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
1275 - unsigned long cr4;
1276 - unsigned long temp;
1277 - struct Xgt_desc_struct *cpu_gdt_descr;
1279 spin_lock(&efi_rt_lock);
1280 local_irq_save(efi_rt_eflags);
1282 - cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
1285 - * If I don't have PSE, I should just duplicate two entries in page
1286 - * directory. If I have PSE, I just need to duplicate one entry in
1291 - if (cr4 & X86_CR4_PSE) {
1292 - efi_bak_pg_dir_pointer[0].pgd =
1293 - swapper_pg_dir[pgd_index(0)].pgd;
1294 - swapper_pg_dir[0].pgd =
1295 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1297 - efi_bak_pg_dir_pointer[0].pgd =
1298 - swapper_pg_dir[pgd_index(0)].pgd;
1299 - efi_bak_pg_dir_pointer[1].pgd =
1300 - swapper_pg_dir[pgd_index(0x400000)].pgd;
1301 - swapper_pg_dir[pgd_index(0)].pgd =
1302 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1303 - temp = PAGE_OFFSET + 0x400000;
1304 - swapper_pg_dir[pgd_index(0x400000)].pgd =
1305 - swapper_pg_dir[pgd_index(temp)].pgd;
1307 + clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
1308 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
1309 + min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
1312 * After the lock is released, the original page table is restored.
1314 - local_flush_tlb();
1315 + __flush_tlb_all();
1317 - cpu_gdt_descr->address = __pa(cpu_gdt_descr->address);
1318 - load_gdt(cpu_gdt_descr);
1319 + cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
1320 + load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
1323 static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
1325 - unsigned long cr4;
1326 - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
1328 - cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address);
1329 - load_gdt(cpu_gdt_descr);
1332 + cpu_gdt_descr[0].address = (unsigned long) __va(cpu_gdt_descr[0].address);
1333 + load_gdt(&cpu_gdt_descr[0]);
1335 - if (cr4 & X86_CR4_PSE) {
1336 - swapper_pg_dir[pgd_index(0)].pgd =
1337 - efi_bak_pg_dir_pointer[0].pgd;
1339 - swapper_pg_dir[pgd_index(0)].pgd =
1340 - efi_bak_pg_dir_pointer[0].pgd;
1341 - swapper_pg_dir[pgd_index(0x400000)].pgd =
1342 - efi_bak_pg_dir_pointer[1].pgd;
1344 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
1347 * After the lock is released, the original page table is restored.
1349 - local_flush_tlb();
1350 + __flush_tlb_all();
1352 local_irq_restore(efi_rt_eflags);
1353 spin_unlock(&efi_rt_lock);
1356 -static efi_status_t
1357 +static efi_status_t __init
1358 phys_efi_set_virtual_address_map(unsigned long memory_map_size,
1359 unsigned long descriptor_size,
1360 u32 descriptor_version,
1361 @@ -154,7 +115,7 @@ phys_efi_set_virtual_address_map(unsigne
1365 -static efi_status_t
1366 +static efi_status_t __init
1367 phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
1369 efi_status_t status;
1370 diff -urNp linux-2.6.20.3/arch/i386/kernel/efi_stub.S linux-2.6.20.3/arch/i386/kernel/efi_stub.S
1371 --- linux-2.6.20.3/arch/i386/kernel/efi_stub.S 2007-03-13 14:27:08.000000000 -0400
1372 +++ linux-2.6.20.3/arch/i386/kernel/efi_stub.S 2007-03-23 08:10:05.000000000 -0400
1376 #include <linux/linkage.h>
1377 +#include <linux/init.h>
1378 #include <asm/page.h>
1382 * service functions will comply with gcc calling convention, too.
1387 ENTRY(efi_call_phys)
1389 * 0. The function can only be called in Linux kernel. So CS has been
1390 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
1391 * The mapping of lower virtual memory has been created in prelog and
1395 - subl $__PAGE_OFFSET, %edx
1397 + jmp 1f-__PAGE_OFFSET
1401 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
1402 * parameter 2, ..., param n. To make things easy, we save the return
1403 * address of efi_call_phys in a global variable.
1406 - movl %edx, saved_return_addr
1407 - /* get the function pointer into ECX*/
1409 - movl %ecx, efi_rt_function_ptr
1411 - subl $__PAGE_OFFSET, %edx
1413 + popl (saved_return_addr)
1414 + popl (efi_rt_function_ptr)
1417 * 3. Clear PG bit in %CR0.
1418 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
1420 * 5. Call the physical function.
1423 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
1427 * 6. After EFI runtime service returns, control will return to
1428 * following instruction. We'd better readjust stack pointer first.
1429 @@ -85,37 +77,29 @@ ENTRY(efi_call_phys)
1434 - orl $0x80000000, %edx
1439 * 8. Now restore the virtual mode from flat mode by
1440 * adding EIP with PAGE_OFFSET.
1445 + orl $0x80000000, %edx
1447 + jmp 1f+__PAGE_OFFSET
1451 * 9. Balance the stack. And because EAX contain the return value,
1452 * we'd better not clobber it.
1454 - leal efi_rt_function_ptr, %edx
1457 + pushl (efi_rt_function_ptr)
1460 - * 10. Push the saved return address onto the stack and return.
1461 + * 10. Return to the saved return address.
1463 - leal saved_return_addr, %edx
1467 + jmpl *(saved_return_addr)
1474 efi_rt_function_ptr:
1475 diff -urNp linux-2.6.20.3/arch/i386/kernel/entry.S linux-2.6.20.3/arch/i386/kernel/entry.S
1476 --- linux-2.6.20.3/arch/i386/kernel/entry.S 2007-03-13 14:27:08.000000000 -0400
1477 +++ linux-2.6.20.3/arch/i386/kernel/entry.S 2007-03-23 08:10:05.000000000 -0400
1479 #include <asm/smp.h>
1480 #include <asm/page.h>
1481 #include <asm/desc.h>
1482 -#include <asm/percpu.h>
1483 #include <asm/dwarf2.h>
1484 #include "irq_vectors.h"
1486 @@ -97,7 +96,7 @@ VM_MASK = 0x00020000
1487 #define resume_userspace_sig resume_userspace
1491 +#define __SAVE_ALL(_DS) \
1494 CFI_ADJUST_CFA_OFFSET 4;\
1495 @@ -129,12 +128,26 @@ VM_MASK = 0x00020000
1497 CFI_ADJUST_CFA_OFFSET 4;\
1498 CFI_REL_OFFSET ebx, 0;\
1499 - movl $(__USER_DS), %edx; \
1500 + movl $(_DS), %edx; \
1503 movl $(__KERNEL_PDA), %edx; \
1506 +#ifdef CONFIG_PAX_KERNEXEC
1508 + __SAVE_ALL(__KERNEL_DS); \
1509 + GET_CR0_INTO_EDX; \
1510 + movl %edx, %esi; \
1511 + orl $0x10000, %edx; \
1512 + xorl %edx, %esi; \
1514 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
1515 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
1517 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
1520 #define RESTORE_INT_REGS \
1522 CFI_ADJUST_CFA_OFFSET -4;\
1523 @@ -247,7 +260,17 @@ check_userspace:
1524 movb PT_CS(%esp), %al
1525 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
1526 cmpl $USER_RPL, %eax
1528 +#ifdef CONFIG_PAX_KERNEXEC
1529 + jae resume_userspace
1536 jb resume_kernel # not returning to v8086 or userspace
1539 ENTRY(resume_userspace)
1540 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
1541 @@ -305,10 +328,9 @@ sysenter_past_esp:
1542 #ifndef CONFIG_COMPAT_VDSO
1544 * Push current_thread_info()->sysenter_return to the stack.
1545 - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
1546 - * pushed above; +8 corresponds to copy_thread's esp0 setting.
1548 - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
1549 + GET_THREAD_INFO(%ebp)
1550 + pushl TI_sysenter_return(%ebp)
1552 pushl $SYSENTER_RETURN
1554 @@ -319,9 +341,20 @@ sysenter_past_esp:
1555 * Load the potential sixth argument from user stack.
1556 * Careful about security.
1558 + movl 12(%esp),%ebp
1560 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1561 + pushl $(__USER_DS)
1562 + CFI_ADJUST_CFA_OFFSET 4
1564 + CFI_ADJUST_CFA_OFFSET -4
1565 +1: movl %ds:(%ebp),%ebp
1567 cmpl $__PAGE_OFFSET-3,%ebp
1572 .section __ex_table,"a"
1574 .long 1b,syscall_fault
1575 @@ -344,20 +377,37 @@ sysenter_past_esp:
1576 movl TI_flags(%ebp), %ecx
1577 testw $_TIF_ALLWORK_MASK, %cx
1578 jne syscall_exit_work
1580 +#ifdef CONFIG_PAX_RANDKSTACK
1582 + CFI_ADJUST_CFA_OFFSET 4
1583 + call pax_randomize_kstack
1585 + CFI_ADJUST_CFA_OFFSET -4
1588 /* if something modifies registers it must also disable sysexit */
1589 movl PT_EIP(%esp), %edx
1590 movl PT_OLDESP(%esp), %ecx
1593 1: mov PT_GS(%esp), %gs
1594 +2: mov PT_DS(%esp), %ds
1595 +3: mov PT_ES(%esp), %es
1596 ENABLE_INTERRUPTS_SYSEXIT
1598 .pushsection .fixup,"ax"
1599 -2: movl $0,PT_GS(%esp)
1600 +4: movl $0,PT_GS(%esp)
1602 +5: movl $0,PT_DS(%esp)
1604 +6: movl $0,PT_ES(%esp)
1606 .section __ex_table,"a"
1614 # system call handler stub
1615 @@ -389,6 +439,10 @@ syscall_exit:
1616 testw $_TIF_ALLWORK_MASK, %cx # current->work
1617 jne syscall_exit_work
1619 +#ifdef CONFIG_PAX_RANDKSTACK
1620 + call pax_randomize_kstack
1624 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
1625 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
1626 @@ -551,8 +605,7 @@ syscall_badsys:
1627 #define FIXUP_ESPFIX_STACK \
1628 /* since we are on a wrong stack, we cant make it a C code :( */ \
1629 movl %gs:PDA_cpu, %ebx; \
1630 - PER_CPU(cpu_gdt_descr, %ebx); \
1631 - movl GDS_address(%ebx), %ebx; \
1632 + movl GDS_address+cpu_gdt_descr(,%ebx,8), %ebx; \
1633 GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
1635 pushl $__KERNEL_DS; \
1636 @@ -577,7 +630,7 @@ syscall_badsys:
1637 * Build the entry stubs and pointer table with
1638 * some assembler magic.
1641 +.section .rodata,"a",@progbits
1645 @@ -592,7 +645,7 @@ ENTRY(irq_entries_start)
1647 CFI_ADJUST_CFA_OFFSET 4
1648 jmp common_interrupt
1650 +.section .rodata,"a",@progbits
1654 @@ -670,12 +723,21 @@ error_code:
1656 CFI_ADJUST_CFA_OFFSET -4
1657 /*CFI_REGISTER es, ecx*/
1659 +#ifdef CONFIG_PAX_KERNEXEC
1662 + orl $0x10000, %edx
1667 movl PT_GS(%esp), %edi # get the function address
1668 movl PT_ORIG_EAX(%esp), %edx # get the error code
1669 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
1670 mov %ecx, PT_GS(%esp)
1671 /*CFI_REL_OFFSET gs, ES*/
1672 - movl $(__USER_DS), %ecx
1673 + movl $(__KERNEL_DS), %ecx
1676 movl %esp,%eax # pt_regs pointer
1677 @@ -806,6 +868,13 @@ nmi_stack_correct:
1678 xorl %edx,%edx # zero error code
1679 movl %esp,%eax # pt_regs pointer
1682 +#ifdef CONFIG_PAX_KERNEXEC
1688 jmp restore_nocheck_notrace
1691 @@ -846,6 +915,13 @@ nmi_espfix_stack:
1692 FIXUP_ESPFIX_STACK # %eax == %esp
1693 xorl %edx,%edx # zero error code
1696 +#ifdef CONFIG_PAX_KERNEXEC
1703 lss 12+4(%esp), %esp # back to espfix stack
1704 CFI_ADJUST_CFA_OFFSET -24
1705 @@ -996,7 +1072,6 @@ ENTRY(kernel_thread_helper)
1707 ENDPROC(kernel_thread_helper)
1709 -.section .rodata,"a"
1710 #include "syscall_table.S"
1712 syscall_table_size=(.-sys_call_table)
1713 diff -urNp linux-2.6.20.3/arch/i386/kernel/head.S linux-2.6.20.3/arch/i386/kernel/head.S
1714 --- linux-2.6.20.3/arch/i386/kernel/head.S 2007-03-13 14:27:08.000000000 -0400
1715 +++ linux-2.6.20.3/arch/i386/kernel/head.S 2007-03-23 08:10:05.000000000 -0400
1718 #define INIT_MAP_BEYOND_END (128*1024)
1720 +#ifdef CONFIG_PAX_KERNEXEC
1721 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
1726 + * Real beginning of normal "text" segment
1732 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
1733 @@ -72,6 +82,45 @@ ENTRY(startup_32)
1737 + /* get the PDA pointer */
1738 + movl $boot_pda, %eax
1740 + /* slot the PDA address into the GDT */
1741 + mov %ax, (cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PDA+0+2) /* base & 0x0000ffff */
1743 + mov %al, (cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PDA+4+0) /* base & 0x00ff0000 */
1744 + mov %ah, (cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PDA+4+3) /* base & 0xff000000 */
1746 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1747 + /* check for VMware */
1748 + movl $0x564d5868,%eax
1753 + cmpl $0x564d5868,%ebx
1756 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
1757 + movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
1758 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c0f300),%eax
1759 + movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_DEFAULT_USER_DS * 8 + 4)
1763 +#ifdef CONFIG_PAX_KERNEXEC
1764 + movl $ __KERNEL_TEXT_OFFSET,%eax
1765 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
1767 + movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
1768 + movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1770 + movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
1771 + movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
1773 + movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
1777 * Clear BSS first so that there are no surprises...
1778 * No need to cld as DF is already clear from cld above...
1779 @@ -119,24 +168,42 @@ ENTRY(startup_32)
1780 * Warning: don't use %esi or the stack in this code. However, %esp
1781 * can be used as a GPR if you really need it...
1783 -page_pde_offset = (__PAGE_OFFSET >> 20);
1785 +#ifdef CONFIG_X86_PAE
1786 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE_asm));
1788 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE_asm));
1790 movl $(pg0 - __PAGE_OFFSET), %edi
1791 +#ifdef CONFIG_X86_PAE
1792 + movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1794 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1795 - movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
1797 + movl $0x063, %eax /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1799 - leal 0x007(%edi),%ecx /* Create PDE entry */
1800 + leal 0x063(%edi),%ecx /* Create PDE entry */
1801 movl %ecx,(%edx) /* Store identity PDE entry */
1802 movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
1803 +#ifdef CONFIG_X86_PAE
1805 + movl $0,page_pde_offset+4(%edx)
1814 +#ifdef CONFIG_X86_PAE
1820 /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1821 - /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1822 - leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1823 + /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1824 + leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1827 movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1828 @@ -159,6 +226,11 @@ ENTRY(startup_32_smp)
1832 + /* This is a secondary processor (AP) */
1835 +#endif /* CONFIG_SMP */
1838 * New page tables may be in 4Mbyte page mode and may
1839 * be using the global pages.
1840 @@ -174,26 +246,27 @@ ENTRY(startup_32_smp)
1841 * not yet offset PAGE_OFFSET..
1843 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1849 movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
1853 - btl $5, %eax # check if PAE is enabled
1855 +#ifdef CONFIG_X86_PAE
1858 /* Check if extended functions are implemented */
1859 movl $0x80000000, %eax
1861 cmpl $0x80000000, %eax
1864 mov $0x80000001, %eax
1866 /* Execute Disable bit supported? */
1871 /* Setup EFER (Extended Feature Enable Register) */
1872 movl $0xc0000080, %ecx
1873 @@ -202,14 +275,13 @@ ENTRY(startup_32_smp)
1875 /* Make changes effective */
1877 + btsl $63,__supported_pte_mask-__PAGE_OFFSET
1878 + movl $1,nx_enabled-__PAGE_OFFSET
1881 - /* This is a secondary processor (AP) */
1886 -#endif /* CONFIG_SMP */
1894 @@ -234,9 +306,7 @@ ENTRY(startup_32_smp)
1898 - jz 1f /* Initial CPU cleans BSS */
1901 + jnz checkCPUtype /* Initial CPU cleans BSS */
1902 #endif /* CONFIG_SMP */
1905 @@ -308,14 +378,13 @@ is386: movl $2,%ecx # set MP
1910 - lgdt cpu_gdt_descr
1911 + GET_THREAD_INFO(%ecx)
1912 + movl TI_cpu(%ecx),%ecx
1913 + lgdt cpu_gdt_descr(,%ecx,8)
1915 ljmp $(__KERNEL_CS),$1f
1916 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
1917 movl %eax,%ss # after changing gdt.
1919 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
1923 @@ -356,23 +425,6 @@ check_x87:
1927 - * Point the GDT at this CPU's PDA. On boot this will be
1928 - * cpu_gdt_table and boot_pda; for secondary CPUs, these will be
1929 - * that CPU's GDT and PDA.
1932 - /* get the PDA pointer */
1933 - movl start_pda, %eax
1935 - /* slot the PDA address into the GDT */
1936 - mov cpu_gdt_descr+2, %ecx
1937 - mov %ax, (__KERNEL_PDA+0+2)(%ecx) /* base & 0x0000ffff */
1939 - mov %al, (__KERNEL_PDA+4+0)(%ecx) /* base & 0x00ff0000 */
1940 - mov %ah, (__KERNEL_PDA+4+3)(%ecx) /* base & 0xff000000 */
1946 * sets up a idt with 256 entries pointing to
1947 @@ -460,8 +512,8 @@ hlt_loop:
1948 /* This is the default interrupt "handler" :-) */
1952 #ifdef CONFIG_PRINTK
1957 @@ -495,7 +547,7 @@ ignore_int:
1958 #ifdef CONFIG_PARAVIRT
1961 - movl $(init_thread_union+THREAD_SIZE),%esp
1962 + movl $(init_thread_union+THREAD_SIZE-8),%esp
1964 /* We take pains to preserve all the regs. */
1966 @@ -519,30 +571,63 @@ startup_paravirt:
1971 - * Real beginning of normal "text" segment
1979 -.section ".bss.page_aligned","w"
1980 +.section .swapper_pg_dir,"a",@progbits
1981 ENTRY(swapper_pg_dir)
1982 +#ifdef CONFIG_X86_PAE
1983 + .long swapper_pm_dir-__PAGE_OFFSET+1
1985 + .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1987 + .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
1989 + .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
1995 +#ifdef CONFIG_X86_PAE
1996 +.section .swapper_pm_dir,"a",@progbits
1997 +ENTRY(swapper_pm_dir)
2004 +.section .empty_zero_page,"a",@progbits
2005 ENTRY(empty_zero_page)
2009 - * This starts the data section.
2014 + * The IDT has to be page-aligned to simplify the Pentium
2015 + * F0 0F bug workaround.. We have a special link segment
2018 +.section .idt,"a",@progbits
2022 +.section .rodata,"a",@progbits
2026 + .long __cpu_pda + cpu*PDA_size
2041 - .long init_thread_union+THREAD_SIZE
2042 + .long init_thread_union+THREAD_SIZE-8
2046 @@ -585,6 +670,8 @@ ENTRY(cpu_gdt_descr)
2047 .word GDT_ENTRIES*8-1
2050 + .fill NR_CPUS*8-6,1,0 # space for the other GDT descriptors
2053 * The boot_gdt_table must mirror the equivalent in setup.S and is
2054 * used only for booting.
2055 @@ -592,13 +679,13 @@ ENTRY(cpu_gdt_descr)
2056 .align L1_CACHE_BYTES
2057 ENTRY(boot_gdt_table)
2058 .fill GDT_ENTRY_BOOT_CS,8,0
2059 - .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
2060 - .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
2061 + .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
2062 + .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
2065 * The Global Descriptor Table contains 28 quadwords, per-CPU.
2067 - .align L1_CACHE_BYTES
2068 + .align PAGE_SIZE_asm
2069 ENTRY(cpu_gdt_table)
2070 .quad 0x0000000000000000 /* NULL descriptor */
2071 .quad 0x0000000000000000 /* 0x0b reserved */
2072 @@ -613,10 +700,10 @@ ENTRY(cpu_gdt_table)
2073 .quad 0x0000000000000000 /* 0x53 reserved */
2074 .quad 0x0000000000000000 /* 0x5b reserved */
2076 - .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
2077 - .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
2078 - .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */
2079 - .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */
2080 + .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
2081 + .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
2082 + .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
2083 + .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
2085 .quad 0x0000000000000000 /* 0x80 TSS descriptor */
2086 .quad 0x0000000000000000 /* 0x88 LDT descriptor */
2087 @@ -626,24 +713,30 @@ ENTRY(cpu_gdt_table)
2088 * They code segments and data segments have fixed 64k limits,
2089 * the transfer segment sizes are set at run time.
2091 - .quad 0x00409a000000ffff /* 0x90 32-bit code */
2092 - .quad 0x00009a000000ffff /* 0x98 16-bit code */
2093 - .quad 0x000092000000ffff /* 0xa0 16-bit data */
2094 - .quad 0x0000920000000000 /* 0xa8 16-bit data */
2095 - .quad 0x0000920000000000 /* 0xb0 16-bit data */
2096 + .quad 0x00409b000000ffff /* 0x90 32-bit code */
2097 + .quad 0x00009b000000ffff /* 0x98 16-bit code */
2098 + .quad 0x000093000000ffff /* 0xa0 16-bit data */
2099 + .quad 0x0000930000000000 /* 0xa8 16-bit data */
2100 + .quad 0x0000930000000000 /* 0xb0 16-bit data */
2103 * The APM segments have byte granularity and their bases
2104 * are set at run time. All have 64k limits.
2106 - .quad 0x00409a000000ffff /* 0xb8 APM CS code */
2107 - .quad 0x00009a000000ffff /* 0xc0 APM CS 16 code (16 bit) */
2108 - .quad 0x004092000000ffff /* 0xc8 APM DS data */
2109 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
2110 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
2111 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
2113 - .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */
2114 - .quad 0x00cf92000000ffff /* 0xd8 - PDA */
2115 + .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
2116 + .quad 0x00c093000000ffff /* 0xd8 - PDA */
2117 .quad 0x0000000000000000 /* 0xe0 - unused */
2118 .quad 0x0000000000000000 /* 0xe8 - unused */
2119 .quad 0x0000000000000000 /* 0xf0 - unused */
2120 .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
2122 + /* Be sure this is zeroed to avoid false validations in Xen */
2123 + .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
2126 + .fill (NR_CPUS-1) * (PAGE_SIZE_asm / 8),8,0 /* other CPU's GDT */
2128 diff -urNp linux-2.6.20.3/arch/i386/kernel/i386_ksyms.c linux-2.6.20.3/arch/i386/kernel/i386_ksyms.c
2129 --- linux-2.6.20.3/arch/i386/kernel/i386_ksyms.c 2007-03-13 14:27:08.000000000 -0400
2130 +++ linux-2.6.20.3/arch/i386/kernel/i386_ksyms.c 2007-03-23 08:10:05.000000000 -0400
2132 #include <asm/checksum.h>
2133 #include <asm/desc.h>
2135 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
2137 EXPORT_SYMBOL(__down_failed);
2138 EXPORT_SYMBOL(__down_failed_interruptible);
2139 EXPORT_SYMBOL(__down_failed_trylock);
2140 EXPORT_SYMBOL(__up_wakeup);
2141 /* Networking helper routines. */
2142 EXPORT_SYMBOL(csum_partial_copy_generic);
2143 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
2144 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
2146 EXPORT_SYMBOL(__get_user_1);
2147 EXPORT_SYMBOL(__get_user_2);
2148 diff -urNp linux-2.6.20.3/arch/i386/kernel/i8259.c linux-2.6.20.3/arch/i386/kernel/i8259.c
2149 --- linux-2.6.20.3/arch/i386/kernel/i8259.c 2007-03-13 14:27:08.000000000 -0400
2150 +++ linux-2.6.20.3/arch/i386/kernel/i8259.c 2007-03-23 08:10:06.000000000 -0400
2151 @@ -350,7 +350,7 @@ static irqreturn_t math_error_irq(int cp
2152 * New motherboards sometimes make IRQ 13 be a PCI interrupt,
2153 * so allow interrupt sharing.
2155 -static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL };
2156 +static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL, 0, NULL };
2158 void __init init_ISA_irqs (void)
2160 diff -urNp linux-2.6.20.3/arch/i386/kernel/init_task.c linux-2.6.20.3/arch/i386/kernel/init_task.c
2161 --- linux-2.6.20.3/arch/i386/kernel/init_task.c 2007-03-13 14:27:08.000000000 -0400
2162 +++ linux-2.6.20.3/arch/i386/kernel/init_task.c 2007-03-23 08:10:06.000000000 -0400
2163 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
2164 * per-CPU TSS segments. Threads are completely 'soft' on Linux,
2165 * no more per-task TSS's.
2167 -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
2168 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
2170 diff -urNp linux-2.6.20.3/arch/i386/kernel/io_apic.c linux-2.6.20.3/arch/i386/kernel/io_apic.c
2171 --- linux-2.6.20.3/arch/i386/kernel/io_apic.c 2007-03-13 14:27:08.000000000 -0400
2172 +++ linux-2.6.20.3/arch/i386/kernel/io_apic.c 2007-03-23 08:10:06.000000000 -0400
2173 @@ -357,8 +357,8 @@ static void set_ioapic_affinity_irq(unsi
2174 # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0)
2175 # define Dprintk(x...) do { TDprintk(x); } while (0)
2177 -# define TDprintk(x...)
2178 -# define Dprintk(x...)
2179 +# define TDprintk(x...) do {} while (0)
2180 +# define Dprintk(x...) do {} while (0)
2183 #define IRQBALANCE_CHECK_ARCH -999
2184 diff -urNp linux-2.6.20.3/arch/i386/kernel/ioport.c linux-2.6.20.3/arch/i386/kernel/ioport.c
2185 --- linux-2.6.20.3/arch/i386/kernel/ioport.c 2007-03-13 14:27:08.000000000 -0400
2186 +++ linux-2.6.20.3/arch/i386/kernel/ioport.c 2007-03-23 08:11:18.000000000 -0400
2188 #include <linux/stddef.h>
2189 #include <linux/slab.h>
2190 #include <linux/thread_info.h>
2191 +#include <linux/grsecurity.h>
2193 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
2194 static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
2195 @@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
2197 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
2199 +#ifdef CONFIG_GRKERNSEC_IO
2201 + gr_handle_ioperm();
2203 if (turn_on && !capable(CAP_SYS_RAWIO))
2207 +#ifdef CONFIG_GRKERNSEC_IO
2211 * If it's the first ioperm() call in this thread's lifetime, set the
2212 * IO bitmap up. ioperm() is much less timing critical than clone(),
2213 @@ -89,7 +97,7 @@ asmlinkage long sys_ioperm(unsigned long
2214 * because the ->io_bitmap_max value must match the bitmap
2217 - tss = &per_cpu(init_tss, get_cpu());
2218 + tss = init_tss + get_cpu();
2220 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
2222 @@ -143,8 +151,13 @@ asmlinkage long sys_iopl(unsigned long u
2224 /* Trying to gain more privileges? */
2226 +#ifdef CONFIG_GRKERNSEC_IO
2230 if (!capable(CAP_SYS_RAWIO))
2234 t->iopl = level << 12;
2235 regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
2236 diff -urNp linux-2.6.20.3/arch/i386/kernel/irq.c linux-2.6.20.3/arch/i386/kernel/irq.c
2237 --- linux-2.6.20.3/arch/i386/kernel/irq.c 2007-03-13 14:27:08.000000000 -0400
2238 +++ linux-2.6.20.3/arch/i386/kernel/irq.c 2007-03-23 08:10:06.000000000 -0400
2239 @@ -100,7 +100,7 @@ fastcall unsigned int do_IRQ(struct pt_r
2240 int arg1, arg2, ebx;
2242 /* build the stack frame on the IRQ stack */
2243 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2244 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2245 irqctx->tinfo.task = curctx->tinfo.task;
2246 irqctx->tinfo.previous_esp = current_stack_pointer;
2248 @@ -137,10 +137,10 @@ fastcall unsigned int do_IRQ(struct pt_r
2249 * gcc's 3.0 and earlier don't handle that correctly.
2251 static char softirq_stack[NR_CPUS * THREAD_SIZE]
2252 - __attribute__((__aligned__(THREAD_SIZE)));
2253 + __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
2255 static char hardirq_stack[NR_CPUS * THREAD_SIZE]
2256 - __attribute__((__aligned__(THREAD_SIZE)));
2257 + __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
2260 * allocate per-cpu stacks for hardirq and for softirq processing
2261 @@ -200,7 +200,7 @@ asmlinkage void do_softirq(void)
2262 irqctx->tinfo.previous_esp = current_stack_pointer;
2264 /* build the stack frame on the softirq stack */
2265 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2266 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2269 " xchgl %%ebx,%%esp \n"
2270 diff -urNp linux-2.6.20.3/arch/i386/kernel/kprobes.c linux-2.6.20.3/arch/i386/kernel/kprobes.c
2271 --- linux-2.6.20.3/arch/i386/kernel/kprobes.c 2007-03-13 14:27:08.000000000 -0400
2272 +++ linux-2.6.20.3/arch/i386/kernel/kprobes.c 2007-03-23 08:10:06.000000000 -0400
2273 @@ -661,7 +661,7 @@ int __kprobes kprobe_exceptions_notify(s
2274 struct die_args *args = (struct die_args *)data;
2275 int ret = NOTIFY_DONE;
2277 - if (args->regs && user_mode_vm(args->regs))
2278 + if (args->regs && user_mode(args->regs))
2282 diff -urNp linux-2.6.20.3/arch/i386/kernel/ldt.c linux-2.6.20.3/arch/i386/kernel/ldt.c
2283 --- linux-2.6.20.3/arch/i386/kernel/ldt.c 2007-03-13 14:27:08.000000000 -0400
2284 +++ linux-2.6.20.3/arch/i386/kernel/ldt.c 2007-03-23 08:10:06.000000000 -0400
2285 @@ -103,6 +103,22 @@ int init_new_context(struct task_struct
2286 retval = copy_ldt(&mm->context, &old_mm->context);
2287 up(&old_mm->context.sem);
2290 + if (tsk == current) {
2291 + mm->context.vdso = ~0UL;
2293 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2294 + mm->context.user_cs_base = 0UL;
2295 + mm->context.user_cs_limit = ~0UL;
2297 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
2298 + cpus_clear(mm->context.cpu_user_cs_mask);
2308 @@ -213,6 +229,13 @@ static int write_ldt(void __user * ptr,
2312 +#ifdef CONFIG_PAX_SEGMEXEC
2313 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
2319 entry_1 = LDT_entry_a(&ldt_info);
2320 entry_2 = LDT_entry_b(&ldt_info);
2322 diff -urNp linux-2.6.20.3/arch/i386/kernel/machine_kexec.c linux-2.6.20.3/arch/i386/kernel/machine_kexec.c
2323 --- linux-2.6.20.3/arch/i386/kernel/machine_kexec.c 2007-03-13 14:27:08.000000000 -0400
2324 +++ linux-2.6.20.3/arch/i386/kernel/machine_kexec.c 2007-03-23 08:10:06.000000000 -0400
2325 @@ -29,25 +29,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
2326 static u32 kexec_pte0[1024] PAGE_ALIGNED;
2327 static u32 kexec_pte1[1024] PAGE_ALIGNED;
2329 -static void set_idt(void *newidt, __u16 limit)
2330 +static void set_idt(struct desc_struct *newidt, __u16 limit)
2332 struct Xgt_desc_struct curidt;
2334 /* ia32 supports unaliged loads & stores */
2335 curidt.size = limit;
2336 - curidt.address = (unsigned long)newidt;
2337 + curidt.address = newidt;
2343 -static void set_gdt(void *newgdt, __u16 limit)
2344 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
2346 struct Xgt_desc_struct curgdt;
2348 /* ia32 supports unaligned loads & stores */
2349 curgdt.size = limit;
2350 - curgdt.address = (unsigned long)newgdt;
2351 + curgdt.address = newgdt;
2355 diff -urNp linux-2.6.20.3/arch/i386/kernel/module.c linux-2.6.20.3/arch/i386/kernel/module.c
2356 --- linux-2.6.20.3/arch/i386/kernel/module.c 2007-03-13 14:27:08.000000000 -0400
2357 +++ linux-2.6.20.3/arch/i386/kernel/module.c 2007-03-23 08:10:06.000000000 -0400
2359 #include <linux/kernel.h>
2360 #include <linux/bug.h>
2362 +#include <asm/desc.h>
2365 #define DEBUGP printk
2367 @@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
2372 +#ifdef CONFIG_PAX_KERNEXEC
2373 + return vmalloc(size);
2375 return vmalloc_exec(size);
2380 +#ifdef CONFIG_PAX_KERNEXEC
2381 +void *module_alloc_exec(unsigned long size)
2383 + struct vm_struct *area;
2388 + area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
2390 + return area->addr;
2396 /* Free memory returned from module_alloc */
2397 void module_free(struct module *mod, void *module_region)
2398 @@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
2402 +#ifdef CONFIG_PAX_KERNEXEC
2403 +void module_free_exec(struct module *mod, void *module_region)
2405 + struct vm_struct **p, *tmp;
2407 + if (!module_region)
2410 + if ((PAGE_SIZE-1) & (unsigned long)module_region) {
2411 + printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
2416 + write_lock(&vmlist_lock);
2417 + for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next)
2418 + if (tmp->addr == module_region)
2422 + unsigned long cr0;
2424 + pax_open_kernel(cr0);
2425 + memset(tmp->addr, 0xCC, tmp->size);
2426 + pax_close_kernel(cr0);
2431 + write_unlock(&vmlist_lock);
2434 + printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
2441 /* We don't need anything special. */
2442 int module_frob_arch_sections(Elf_Ehdr *hdr,
2444 @@ -63,14 +125,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
2446 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
2448 - uint32_t *location;
2449 + uint32_t *plocation, location;
2451 DEBUGP("Applying relocate section %u to %u\n", relsec,
2452 sechdrs[relsec].sh_info);
2453 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
2454 /* This is where to make the change */
2455 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
2456 - + rel[i].r_offset;
2457 + plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
2458 + location = (uint32_t)plocation;
2459 + if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
2460 + plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
2461 /* This is the symbol it is referring to. Note that all
2462 undefined symbols have been resolved. */
2463 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
2464 @@ -79,11 +143,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
2465 switch (ELF32_R_TYPE(rel[i].r_info)) {
2467 /* We add the value into the location given */
2468 - *location += sym->st_value;
2469 + *plocation += sym->st_value;
2472 /* Add the value, subtract its postition */
2473 - *location += sym->st_value - (uint32_t)location;
2474 + *plocation += sym->st_value - location;
2477 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
2478 diff -urNp linux-2.6.20.3/arch/i386/kernel/paravirt.c linux-2.6.20.3/arch/i386/kernel/paravirt.c
2479 --- linux-2.6.20.3/arch/i386/kernel/paravirt.c 2007-03-13 14:27:08.000000000 -0400
2480 +++ linux-2.6.20.3/arch/i386/kernel/paravirt.c 2007-03-23 08:10:06.000000000 -0400
2481 @@ -88,7 +88,7 @@ static unsigned native_patch(u8 type, u1
2485 - memcpy(insns, native_insns[type].start, insn_len);
2486 + memcpy(insns, native_insns[type].start + __KERNEL_TEXT_OFFSET, insn_len);
2490 @@ -336,16 +336,40 @@ static fastcall unsigned long native_sto
2492 static fastcall void native_load_tls(struct thread_struct *t, unsigned int cpu)
2495 +#ifdef CONFIG_PAX_KERNEXEC
2496 + unsigned long cr0;
2498 + pax_open_kernel(cr0);
2501 #define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
2505 +#ifdef CONFIG_PAX_KERNEXEC
2506 + pax_close_kernel(cr0);
2511 static inline void native_write_dt_entry(void *dt, int entry, u32 entry_low, u32 entry_high)
2513 u32 *lp = (u32 *)((char *)dt + entry*8);
2515 +#ifdef CONFIG_PAX_KERNEXEC
2516 + unsigned long cr0;
2518 + pax_open_kernel(cr0);
2524 +#ifdef CONFIG_PAX_KERNEXEC
2525 + pax_close_kernel(cr0);
2530 static fastcall void native_write_ldt_entry(void *dt, int entrynum, u32 low, u32 high)
2531 @@ -485,7 +509,7 @@ core_initcall(print_banner);
2532 /* We simply declare start_kernel to be the paravirt probe of last resort. */
2533 paravirt_probe(start_kernel);
2535 -struct paravirt_ops paravirt_ops = {
2536 +const struct paravirt_ops paravirt_ops = {
2537 .name = "bare hardware",
2538 .paravirt_enabled = 0,
2540 diff -urNp linux-2.6.20.3/arch/i386/kernel/process.c linux-2.6.20.3/arch/i386/kernel/process.c
2541 --- linux-2.6.20.3/arch/i386/kernel/process.c 2007-03-13 14:27:08.000000000 -0400
2542 +++ linux-2.6.20.3/arch/i386/kernel/process.c 2007-03-23 08:10:06.000000000 -0400
2543 @@ -70,7 +70,7 @@ EXPORT_SYMBOL(boot_option_idle_override)
2545 unsigned long thread_saved_pc(struct task_struct *tsk)
2547 - return ((unsigned long *)tsk->thread.esp)[3];
2548 + return tsk->thread.eip;
2552 @@ -298,7 +298,7 @@ void show_regs(struct pt_regs * regs)
2553 0xffff & regs->xcs,regs->eip, smp_processor_id());
2554 print_symbol("EIP is at %s\n", regs->eip);
2556 - if (user_mode_vm(regs))
2557 + if (user_mode(regs))
2558 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
2559 printk(" EFLAGS: %08lx %s (%s %.*s)\n",
2560 regs->eflags, print_tainted(), init_utsname()->release,
2561 @@ -338,8 +338,8 @@ int kernel_thread(int (*fn)(void *), voi
2562 regs.ebx = (unsigned long) fn;
2563 regs.edx = (unsigned long) arg;
2565 - regs.xds = __USER_DS;
2566 - regs.xes = __USER_DS;
2567 + regs.xds = __KERNEL_DS;
2568 + regs.xes = __KERNEL_DS;
2569 regs.xgs = __KERNEL_PDA;
2571 regs.eip = (unsigned long) kernel_thread_helper;
2572 @@ -361,7 +361,7 @@ void exit_thread(void)
2573 struct task_struct *tsk = current;
2574 struct thread_struct *t = &tsk->thread;
2575 int cpu = get_cpu();
2576 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
2577 + struct tss_struct *tss = init_tss + cpu;
2579 kfree(t->io_bitmap_ptr);
2580 t->io_bitmap_ptr = NULL;
2581 @@ -382,6 +382,7 @@ void flush_thread(void)
2583 struct task_struct *tsk = current;
2585 + __asm__("mov %0,%%fs\n" : : "r" (0) : "memory");
2586 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
2587 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
2588 clear_tsk_thread_flag(tsk, TIF_DEBUG);
2589 @@ -415,7 +416,7 @@ int copy_thread(int nr, unsigned long cl
2590 struct task_struct *tsk;
2593 - childregs = task_pt_regs(p);
2594 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
2597 childregs->esp = esp;
2598 @@ -457,6 +458,11 @@ int copy_thread(int nr, unsigned long cl
2599 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2602 +#ifdef CONFIG_PAX_SEGMEXEC
2603 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2607 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
2608 desc->a = LDT_entry_a(&info);
2609 desc->b = LDT_entry_b(&info);
2610 @@ -636,7 +642,7 @@ struct task_struct fastcall * __switch_t
2611 struct thread_struct *prev = &prev_p->thread,
2612 *next = &next_p->thread;
2613 int cpu = smp_processor_id();
2614 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
2615 + struct tss_struct *tss = init_tss + cpu;
2617 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
2619 @@ -664,6 +670,11 @@ struct task_struct fastcall * __switch_t
2621 savesegment(fs, prev->fs);
2623 +#ifdef CONFIG_PAX_MEMORY_UDEREF
2624 + if (!segment_eq(prev_p->thread_info->addr_limit, next_p->thread_info->addr_limit))
2625 + __set_fs(next_p->thread_info->addr_limit, cpu);
2629 * Load the per-thread Thread-Local Storage descriptor.
2631 @@ -814,6 +825,12 @@ asmlinkage int sys_set_thread_area(struc
2633 if (copy_from_user(&info, u_info, sizeof(info)))
2636 +#ifdef CONFIG_PAX_SEGMEXEC
2637 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2641 idx = info.entry_number;
2644 @@ -902,9 +919,28 @@ asmlinkage int sys_get_thread_area(struc
2648 -unsigned long arch_align_stack(unsigned long sp)
2649 +#ifdef CONFIG_PAX_RANDKSTACK
2650 +asmlinkage void pax_randomize_kstack(void)
2652 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
2653 - sp -= get_random_int() % 8192;
2655 + struct tss_struct *tss;
2656 + unsigned long time;
2658 + if (!randomize_va_space)
2661 + tss = init_tss + smp_processor_id();
2664 + /* P4 seems to return a 0 LSB, ignore it */
2665 +#ifdef CONFIG_MPENTIUM4
2673 + tss->esp0 ^= time;
2674 + current->thread.esp0 = tss->esp0;
2677 diff -urNp linux-2.6.20.3/arch/i386/kernel/ptrace.c linux-2.6.20.3/arch/i386/kernel/ptrace.c
2678 --- linux-2.6.20.3/arch/i386/kernel/ptrace.c 2007-03-13 14:27:08.000000000 -0400
2679 +++ linux-2.6.20.3/arch/i386/kernel/ptrace.c 2007-03-23 08:11:18.000000000 -0400
2681 #include <linux/audit.h>
2682 #include <linux/seccomp.h>
2683 #include <linux/signal.h>
2684 +#include <linux/grsecurity.h>
2686 #include <asm/uaccess.h>
2687 #include <asm/pgtable.h>
2688 @@ -162,15 +163,15 @@ static unsigned long convert_eip_to_line
2689 * and APM bios ones we just ignore here.
2691 if (seg & LDT_SEGMENT) {
2693 + struct desc_struct *desc;
2696 down(&child->mm->context.sem);
2697 - desc = child->mm->context.ldt + (seg & ~7);
2698 - base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 0xff000000);
2699 + desc = &child->mm->context.ldt[seg >> 3];
2700 + base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
2702 /* 16-bit code segment? */
2703 - if (!((desc[1] >> 22) & 1))
2704 + if (!((desc->b >> 22) & 1))
2707 up(&child->mm->context.sem);
2708 @@ -335,6 +336,11 @@ ptrace_set_thread_area(struct task_struc
2709 if (copy_from_user(&info, user_desc, sizeof(info)))
2712 +#ifdef CONFIG_PAX_SEGMEXEC
2713 + if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2717 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2720 @@ -425,6 +431,17 @@ long arch_ptrace(struct task_struct *chi
2721 if(addr == (long) &dummy->u_debugreg[5]) break;
2722 if(addr < (long) &dummy->u_debugreg[4] &&
2723 ((unsigned long) data) >= TASK_SIZE-3) break;
2725 +#ifdef CONFIG_GRKERNSEC
2726 + if(addr >= (long) &dummy->u_debugreg[0] &&
2727 + addr <= (long) &dummy->u_debugreg[3]){
2728 + long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
2729 + long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
2730 + long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
2731 + if((type & 1) && (data & align))
2736 /* Sanity-check data. Take one half-byte at once with
2737 * check = (val >> (16 + 4*i)) & 0xf. It contains the
2738 @@ -641,7 +658,7 @@ void send_sigtrap(struct task_struct *ts
2739 info.si_code = TRAP_BRKPT;
2741 /* User-mode eip? */
2742 - info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
2743 + info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
2745 /* Send us the fakey SIGTRAP */
2746 force_sig_info(SIGTRAP, &info, tsk);
2747 diff -urNp linux-2.6.20.3/arch/i386/kernel/reboot.c linux-2.6.20.3/arch/i386/kernel/reboot.c
2748 --- linux-2.6.20.3/arch/i386/kernel/reboot.c 2007-03-13 14:27:08.000000000 -0400
2749 +++ linux-2.6.20.3/arch/i386/kernel/reboot.c 2007-03-23 08:10:06.000000000 -0400
2751 void (*pm_power_off)(void);
2752 EXPORT_SYMBOL(pm_power_off);
2754 -static int reboot_mode;
2755 +static unsigned short reboot_mode;
2756 static int reboot_thru_bios;
2759 @@ -120,7 +120,7 @@ static struct dmi_system_id __initdata r
2760 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
2764 + { NULL, NULL, {{0, NULL}}, NULL}
2767 static int __init reboot_init(void)
2768 @@ -138,18 +138,18 @@ core_initcall(reboot_init);
2769 doesn't work with at least one type of 486 motherboard. It is easy
2770 to stop this code working; hence the copious comments. */
2772 -static unsigned long long
2773 +static const struct desc_struct
2774 real_mode_gdt_entries [3] =
2776 - 0x0000000000000000ULL, /* Null descriptor */
2777 - 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
2778 - 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
2779 + {0x00000000, 0x00000000}, /* Null descriptor */
2780 + {0x0000ffff, 0x00009b00}, /* 16-bit real-mode 64k code at 0x00000000 */
2781 + {0x0100ffff, 0x00009300} /* 16-bit real-mode 64k data at 0x00000100 */
2784 -static struct Xgt_desc_struct
2785 -real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
2786 -real_mode_idt = { 0x3ff, 0 },
2788 +static const struct Xgt_desc_struct
2789 +real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries, 0 },
2790 +real_mode_idt = { 0x3ff, NULL, 0 },
2791 +no_idt = { 0, NULL, 0 };
2794 /* This is 16-bit protected mode code to disable paging and the cache,
2795 @@ -171,7 +171,7 @@ no_idt = { 0, 0 };
2796 More could be done here to set up the registers as if a CPU reset had
2797 occurred; hopefully real BIOSs don't assume much. */
2799 -static unsigned char real_mode_switch [] =
2800 +static const unsigned char real_mode_switch [] =
2802 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
2803 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
2804 @@ -185,7 +185,7 @@ static unsigned char real_mode_switch []
2805 0x24, 0x10, /* f: andb $0x10,al */
2806 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
2808 -static unsigned char jump_to_bios [] =
2809 +static const unsigned char jump_to_bios [] =
2811 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
2813 @@ -195,10 +195,14 @@ static unsigned char jump_to_bios [] =
2814 * specified by the code and length parameters.
2815 * We assume that length will aways be less that 100!
2817 -void machine_real_restart(unsigned char *code, int length)
2818 +void machine_real_restart(const unsigned char *code, unsigned int length)
2820 unsigned long flags;
2822 +#ifdef CONFIG_PAX_KERNEXEC
2823 + unsigned long cr0;
2826 local_irq_disable();
2828 /* Write zero to CMOS register number 0x0f, which the BIOS POST
2829 @@ -219,8 +223,16 @@ void machine_real_restart(unsigned char
2830 from the kernel segment. This assumes the kernel segment starts at
2831 virtual address PAGE_OFFSET. */
2833 - memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2834 - sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
2835 +#ifdef CONFIG_PAX_KERNEXEC
2836 + pax_open_kernel(cr0);
2839 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2840 + min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
2842 +#ifdef CONFIG_PAX_KERNEXEC
2843 + pax_close_kernel(cr0);
2847 * Use `swapper_pg_dir' as our page directory.
2848 @@ -233,7 +245,7 @@ void machine_real_restart(unsigned char
2849 REBOOT.COM programs, and the previous reset routine did this
2852 - *((unsigned short *)0x472) = reboot_mode;
2853 + __put_user(reboot_mode, (unsigned short __user *)0x472);
2855 /* For the switch to real mode, copy some code to low memory. It has
2856 to be in the first 64k because it is running in 16-bit mode, and it
2857 @@ -241,9 +253,9 @@ void machine_real_restart(unsigned char
2858 off paging. Copy it near the end of the first page, out of the way
2859 of BIOS variables. */
2861 - memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
2862 + flags = __copy_to_user_inatomic((void __user *) (0x1000 - sizeof (real_mode_switch) - 100),
2863 real_mode_switch, sizeof (real_mode_switch));
2864 - memcpy ((void *) (0x1000 - 100), code, length);
2865 + flags = __copy_to_user_inatomic((void __user *) (0x1000 - 100), code, length);
2867 /* Set up the IDT for real mode. */
2869 @@ -325,7 +337,7 @@ void machine_emergency_restart(void)
2870 __asm__ __volatile__("int3");
2872 /* rebooting needs to touch the page at absolute addr 0 */
2873 - *((unsigned short *)__va(0x472)) = reboot_mode;
2874 + __put_user(reboot_mode, (unsigned short __user *)0x472);
2876 mach_reboot_fixups(); /* for board specific fixups */
2878 diff -urNp linux-2.6.20.3/arch/i386/kernel/setup.c linux-2.6.20.3/arch/i386/kernel/setup.c
2879 --- linux-2.6.20.3/arch/i386/kernel/setup.c 2007-03-13 14:27:08.000000000 -0400
2880 +++ linux-2.6.20.3/arch/i386/kernel/setup.c 2007-03-23 08:10:06.000000000 -0400
2881 @@ -82,7 +82,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini
2882 struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
2883 EXPORT_SYMBOL(boot_cpu_data);
2885 +#ifdef CONFIG_X86_PAE
2886 +unsigned long mmu_cr4_features = X86_CR4_PAE;
2888 unsigned long mmu_cr4_features;
2891 /* for MCA, but anyone else can use it if they want */
2892 unsigned int machine_id;
2893 @@ -404,8 +408,8 @@ void __init setup_bootmem_allocator(void
2894 * the (very unlikely) case of us accidentally initializing the
2895 * bootmem allocator with an invalid RAM area.
2897 - reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
2898 - bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
2899 + reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
2900 + bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR);
2903 * reserve physical page 0 - it's a special BIOS page on many boxes,
2904 @@ -559,14 +563,14 @@ void __init setup_arch(char **cmdline_p)
2906 if (!MOUNT_ROOT_RDONLY)
2907 root_mountflags &= ~MS_RDONLY;
2908 - init_mm.start_code = (unsigned long) _text;
2909 - init_mm.end_code = (unsigned long) _etext;
2910 + init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
2911 + init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
2912 init_mm.end_data = (unsigned long) _edata;
2913 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
2915 - code_resource.start = virt_to_phys(_text);
2916 - code_resource.end = virt_to_phys(_etext)-1;
2917 - data_resource.start = virt_to_phys(_etext);
2918 + code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
2919 + code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
2920 + data_resource.start = virt_to_phys(_data);
2921 data_resource.end = virt_to_phys(_edata)-1;
2923 parse_early_param();
2924 diff -urNp linux-2.6.20.3/arch/i386/kernel/signal.c linux-2.6.20.3/arch/i386/kernel/signal.c
2925 --- linux-2.6.20.3/arch/i386/kernel/signal.c 2007-03-13 14:27:08.000000000 -0400
2926 +++ linux-2.6.20.3/arch/i386/kernel/signal.c 2007-03-23 08:10:06.000000000 -0400
2927 @@ -351,9 +351,9 @@ static int setup_frame(int sig, struct k
2930 if (current->binfmt->hasvdso)
2931 - restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
2932 + restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
2934 - restorer = (void *)&frame->retcode;
2935 + restorer = (void __user *)&frame->retcode;
2936 if (ka->sa.sa_flags & SA_RESTORER)
2937 restorer = ka->sa.sa_restorer;
2939 @@ -449,7 +449,8 @@ static int setup_rt_frame(int sig, struc
2942 /* Set up to return from userspace. */
2943 - restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
2945 + restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
2946 if (ka->sa.sa_flags & SA_RESTORER)
2947 restorer = ka->sa.sa_restorer;
2948 err |= __put_user(restorer, &frame->pretcode);
2949 @@ -582,7 +583,7 @@ static void fastcall do_signal(struct pt
2950 * before reaching here, so testing against kernel
2953 - if (!user_mode(regs))
2954 + if (!user_mode_novm(regs))
2957 if (test_thread_flag(TIF_RESTORE_SIGMASK))
2958 diff -urNp linux-2.6.20.3/arch/i386/kernel/smpboot.c linux-2.6.20.3/arch/i386/kernel/smpboot.c
2959 --- linux-2.6.20.3/arch/i386/kernel/smpboot.c 2007-03-13 14:27:08.000000000 -0400
2960 +++ linux-2.6.20.3/arch/i386/kernel/smpboot.c 2007-03-23 08:10:06.000000000 -0400
2962 #include <asm/desc.h>
2963 #include <asm/arch_hooks.h>
2964 #include <asm/nmi.h>
2965 -#include <asm/pda.h>
2966 #include <asm/genapic.h>
2968 #include <mach_apic.h>
2969 @@ -618,8 +617,6 @@ extern struct {
2973 -extern struct i386_pda *start_pda;
2974 -extern struct Xgt_desc_struct cpu_gdt_descr;
2978 @@ -961,10 +958,7 @@ static int __cpuinit do_boot_cpu(int api
2979 /* Pre-allocate and initialize the CPU's GDT and PDA so it
2980 doesn't have to do any memory allocation during the
2981 delicate CPU-bringup phase. */
2982 - if (!init_gdt(cpu, idle)) {
2983 - printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu);
2984 - return -1; /* ? */
2986 + init_gdt(cpu, idle);
2988 idle->thread.eip = (unsigned long) start_secondary;
2989 /* start_eip had better be page-aligned! */
2990 @@ -1090,7 +1084,6 @@ static int __cpuinit __smp_prepare_cpu(i
2991 DECLARE_COMPLETION_ONSTACK(done);
2992 struct warm_boot_cpu_info info;
2994 - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
2996 apicid = x86_cpu_to_apicid[cpu];
2997 if (apicid == BAD_APICID) {
2998 @@ -1098,18 +1091,6 @@ static int __cpuinit __smp_prepare_cpu(i
3003 - * the CPU isn't initialized at boot time, allocate gdt table here.
3004 - * cpu_init will initialize it
3006 - if (!cpu_gdt_descr->address) {
3007 - cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL);
3008 - if (!cpu_gdt_descr->address)
3009 - printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
3014 info.complete = &done;
3015 info.apicid = apicid;
3017 diff -urNp linux-2.6.20.3/arch/i386/kernel/smp.c linux-2.6.20.3/arch/i386/kernel/smp.c
3018 --- linux-2.6.20.3/arch/i386/kernel/smp.c 2007-03-13 14:27:08.000000000 -0400
3019 +++ linux-2.6.20.3/arch/i386/kernel/smp.c 2007-03-23 08:10:06.000000000 -0400
3021 * about nothing of note with C stepping upwards.
3024 -DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
3025 +DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
3028 * the following functions deal with sending IPIs between CPUs.
3029 diff -urNp linux-2.6.20.3/arch/i386/kernel/syscall_table.S linux-2.6.20.3/arch/i386/kernel/syscall_table.S
3030 --- linux-2.6.20.3/arch/i386/kernel/syscall_table.S 2007-03-13 14:27:08.000000000 -0400
3031 +++ linux-2.6.20.3/arch/i386/kernel/syscall_table.S 2007-03-23 08:10:06.000000000 -0400
3033 +.section .rodata,"a",@progbits
3034 ENTRY(sys_call_table)
3035 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
3037 diff -urNp linux-2.6.20.3/arch/i386/kernel/sysenter.c linux-2.6.20.3/arch/i386/kernel/sysenter.c
3038 --- linux-2.6.20.3/arch/i386/kernel/sysenter.c 2007-03-13 14:27:08.000000000 -0400
3039 +++ linux-2.6.20.3/arch/i386/kernel/sysenter.c 2007-03-23 08:10:06.000000000 -0400
3040 @@ -49,7 +49,7 @@ extern asmlinkage void sysenter_entry(vo
3041 void enable_sep_cpu(void)
3043 int cpu = get_cpu();
3044 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
3045 + struct tss_struct *tss = init_tss + cpu;
3047 if (!boot_cpu_has(X86_FEATURE_SEP)) {
3049 @@ -125,16 +125,36 @@ int arch_setup_additional_pages(struct l
3053 +#ifdef CONFIG_PAX_SEGMEXEC
3054 + struct vm_area_struct *vma_m = NULL;
3057 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3061 +#ifdef CONFIG_PAX_SEGMEXEC
3062 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
3063 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3065 + kmem_cache_free(vm_area_cachep, vma);
3071 down_write(&mm->mmap_sem);
3072 - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
3073 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
3074 if (IS_ERR_VALUE(addr)) {
3079 - vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3082 + kmem_cache_free(vm_area_cachep, vma);
3084 +#ifdef CONFIG_PAX_SEGMEXEC
3086 + kmem_cache_free(vm_area_cachep, vma_m);
3092 @@ -142,6 +162,12 @@ int arch_setup_additional_pages(struct l
3093 vma->vm_end = addr + PAGE_SIZE;
3094 /* MAYWRITE to allow gdb to COW and set breakpoints */
3095 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
3097 +#ifdef CONFIG_PAX_MPROTECT
3098 + if (mm->pax_flags & MF_PAX_MPROTECT)
3099 + vma->vm_flags &= ~VM_MAYWRITE;
3103 * Make sure the vDSO gets into every core dump.
3104 * Dumping its contents makes post-mortem fully interpretable later
3105 @@ -151,17 +177,42 @@ int arch_setup_additional_pages(struct l
3107 vma->vm_flags |= VM_ALWAYSDUMP;
3108 vma->vm_flags |= mm->def_flags;
3109 - vma->vm_page_prot = protection_map[vma->vm_flags & 7];
3110 + vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
3111 vma->vm_ops = &syscall_vm_ops;
3114 ret = insert_vm_struct(mm, vma);
3115 if (unlikely(ret)) {
3116 kmem_cache_free(vm_area_cachep, vma);
3118 +#ifdef CONFIG_PAX_SEGMEXEC
3120 + kmem_cache_free(vm_area_cachep, vma_m);
3126 - current->mm->context.vdso = (void *)addr;
3127 +#ifdef CONFIG_PAX_SEGMEXEC
3130 + vma_m->vm_start += SEGMEXEC_TASK_SIZE;
3131 + vma_m->vm_end += SEGMEXEC_TASK_SIZE;
3132 + ret = insert_vm_struct(mm, vma_m);
3133 + if (unlikely(ret)) {
3134 + kmem_cache_free(vm_area_cachep, vma_m);
3137 + vma_m->vm_flags |= VM_MIRROR;
3138 + vma->vm_flags |= VM_MIRROR;
3139 + vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
3140 + vma->vm_mirror = vma_m->vm_start - vma->vm_start;
3141 + vma_m->vm_pgoff = vma->vm_pgoff;
3146 + current->mm->context.vdso = addr;
3147 current_thread_info()->sysenter_return =
3148 (void *)VDSO_SYM(&SYSENTER_RETURN);
3150 @@ -171,8 +222,17 @@ up_fail:
3152 const char *arch_vma_name(struct vm_area_struct *vma)
3154 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
3155 + if (vma->vm_start == vma->vm_mm->context.vdso)
3158 +#ifdef CONFIG_PAX_SEGMEXEC
3159 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_MIRROR))
3162 + if (vma->vm_start + vma->vm_mirror == vma->vm_mm->context.vdso)
3169 diff -urNp linux-2.6.20.3/arch/i386/kernel/sys_i386.c linux-2.6.20.3/arch/i386/kernel/sys_i386.c
3170 --- linux-2.6.20.3/arch/i386/kernel/sys_i386.c 2007-03-13 14:27:08.000000000 -0400
3171 +++ linux-2.6.20.3/arch/i386/kernel/sys_i386.c 2007-03-23 08:10:06.000000000 -0400
3172 @@ -100,6 +100,191 @@ out:
3177 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
3178 + unsigned long len, unsigned long pgoff, unsigned long flags)
3180 + struct mm_struct *mm = current->mm;
3181 + struct vm_area_struct *vma;
3182 + unsigned long start_addr, task_size = TASK_SIZE;
3184 +#ifdef CONFIG_PAX_SEGMEXEC
3185 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
3186 + task_size = SEGMEXEC_TASK_SIZE;
3189 + if (len > task_size)
3192 +#ifdef CONFIG_PAX_RANDMMAP
3193 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3197 + addr = PAGE_ALIGN(addr);
3198 + vma = find_vma(mm, addr);
3199 + if (task_size - len >= addr &&
3200 + (!vma || addr + len <= vma->vm_start))
3203 + if (len > mm->cached_hole_size) {
3204 + start_addr = addr = mm->free_area_cache;
3206 + start_addr = addr = mm->mmap_base;
3207 + mm->cached_hole_size = 0;
3210 +#ifdef CONFIG_PAX_PAGEEXEC
3211 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
3212 + start_addr = 0x00110000UL;
3214 +#ifdef CONFIG_PAX_RANDMMAP
3215 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3216 + start_addr += mm->delta_mmap & 0x03FFF000UL;
3219 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
3220 + start_addr = addr = mm->mmap_base;
3222 + addr = start_addr;
3227 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
3228 + /* At this point: (!vma || addr < vma->vm_end). */
3229 + if (task_size - len < addr) {
3231 + * Start a new search - just in case we missed
3234 + if (start_addr != mm->mmap_base) {
3235 + start_addr = addr = mm->mmap_base;
3236 + mm->cached_hole_size = 0;
3241 + if (!vma || addr + len <= vma->vm_start) {
3243 + * Remember the place where we stopped the search:
3245 + mm->free_area_cache = addr + len;
3248 + if (addr + mm->cached_hole_size < vma->vm_start)
3249 + mm->cached_hole_size = vma->vm_start - addr;
3250 + addr = vma->vm_end;
3251 + if (mm->start_brk <= addr && addr < mm->mmap_base) {
3252 + start_addr = addr = mm->mmap_base;
3259 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
3260 + const unsigned long len, const unsigned long pgoff,
3261 + const unsigned long flags)
3263 + struct vm_area_struct *vma;
3264 + struct mm_struct *mm = current->mm;
3265 + unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
3267 +#ifdef CONFIG_PAX_SEGMEXEC
3268 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
3269 + task_size = SEGMEXEC_TASK_SIZE;
3272 + /* requested length too big for entire address space */
3273 + if (len > task_size)
3276 +#ifdef CONFIG_PAX_PAGEEXEC
3277 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
3281 +#ifdef CONFIG_PAX_RANDMMAP
3282 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3285 + /* requesting a specific address */
3287 + addr = PAGE_ALIGN(addr);
3288 + vma = find_vma(mm, addr);
3289 + if (task_size - len >= addr &&
3290 + (!vma || addr + len <= vma->vm_start))
3294 + /* check if free_area_cache is useful for us */
3295 + if (len <= mm->cached_hole_size) {
3296 + mm->cached_hole_size = 0;
3297 + mm->free_area_cache = mm->mmap_base;
3300 + /* either no address requested or can't fit in requested address hole */
3301 + addr = mm->free_area_cache;
3303 + /* make sure it can fit in the remaining address space */
3305 + vma = find_vma(mm, addr-len);
3306 + if (!vma || addr <= vma->vm_start)
3307 + /* remember the address as a hint for next time */
3308 + return (mm->free_area_cache = addr-len);
3311 + if (mm->mmap_base < len)
3314 + addr = mm->mmap_base-len;
3318 + * Lookup failure means no vma is above this address,
3319 + * else if new region fits below vma->vm_start,
3320 + * return with success:
3322 + vma = find_vma(mm, addr);
3323 + if (!vma || addr+len <= vma->vm_start)
3324 + /* remember the address as a hint for next time */
3325 + return (mm->free_area_cache = addr);
3327 + /* remember the largest hole we saw so far */
3328 + if (addr + mm->cached_hole_size < vma->vm_start)
3329 + mm->cached_hole_size = vma->vm_start - addr;
3331 + /* try just below the current vma->vm_start */
3332 + addr = vma->vm_start-len;
3333 + } while (len < vma->vm_start);
3337 + * A failed mmap() very likely causes application failure,
3338 + * so fall back to the bottom-up function here. This scenario
3339 + * can happen with large stack limits and large mmap()
3342 + mm->mmap_base = TASK_UNMAPPED_BASE;
3344 +#ifdef CONFIG_PAX_RANDMMAP
3345 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3346 + mm->mmap_base += mm->delta_mmap;
3349 + mm->free_area_cache = mm->mmap_base;
3350 + mm->cached_hole_size = ~0UL;
3351 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
3353 + * Restore the topdown base:
3355 + mm->mmap_base = base;
3356 + mm->free_area_cache = base;
3357 + mm->cached_hole_size = ~0UL;
3362 struct sel_arg_struct {
3364 diff -urNp linux-2.6.20.3/arch/i386/kernel/time.c linux-2.6.20.3/arch/i386/kernel/time.c
3365 --- linux-2.6.20.3/arch/i386/kernel/time.c 2007-03-13 14:27:08.000000000 -0400
3366 +++ linux-2.6.20.3/arch/i386/kernel/time.c 2007-03-23 08:10:06.000000000 -0400
3367 @@ -131,7 +131,7 @@ unsigned long profile_pc(struct pt_regs
3368 unsigned long pc = instruction_pointer(regs);
3371 - if (!user_mode_vm(regs) && in_lock_functions(pc)) {
3372 + if (!user_mode(regs) && in_lock_functions(pc)) {
3373 #ifdef CONFIG_FRAME_POINTER
3374 return *(unsigned long *)(regs->ebp + 4);
3376 @@ -340,7 +340,7 @@ static struct sys_device device_timer =
3377 .cls = &timer_sysclass,
3380 -static int time_init_device(void)
3381 +static int __init time_init_device(void)
3383 int error = sysdev_class_register(&timer_sysclass);
3385 diff -urNp linux-2.6.20.3/arch/i386/kernel/traps.c linux-2.6.20.3/arch/i386/kernel/traps.c
3386 --- linux-2.6.20.3/arch/i386/kernel/traps.c 2007-03-13 14:27:08.000000000 -0400
3387 +++ linux-2.6.20.3/arch/i386/kernel/traps.c 2007-03-23 08:10:06.000000000 -0400
3389 #include <linux/uaccess.h>
3390 #include <linux/nmi.h>
3391 #include <linux/bug.h>
3392 +#include <linux/binfmts.h>
3395 #include <linux/ioport.h>
3396 @@ -68,12 +69,7 @@ asmlinkage int system_call(void);
3397 /* Do we ignore FPU interrupts ? */
3398 char ignore_fpu_irq = 0;
3401 - * The IDT has to be page-aligned to simplify the Pentium
3402 - * F0 0F bug workaround.. We have a special link segment
3405 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
3406 +extern struct desc_struct idt_table[256];
3408 asmlinkage void divide_error(void);
3409 asmlinkage void debug(void);
3410 @@ -140,7 +136,7 @@ static inline unsigned long print_contex
3412 while (valid_stack_ptr(tinfo, stack)) {
3414 - if (__kernel_text_address(addr))
3415 + if (__kernel_text_address(addr + __KERNEL_TEXT_OFFSET))
3416 ops->address(data, addr);
3419 @@ -297,7 +293,7 @@ void show_registers(struct pt_regs *regs
3421 esp = (unsigned long) (®s->esp);
3422 savesegment(ss, ss);
3423 - if (user_mode_vm(regs)) {
3424 + if (user_mode(regs)) {
3427 ss = regs->xss & 0xffff;
3428 @@ -313,8 +309,8 @@ void show_registers(struct pt_regs *regs
3429 regs->eax, regs->ebx, regs->ecx, regs->edx);
3430 printk(KERN_EMERG "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
3431 regs->esi, regs->edi, regs->ebp, esp);
3432 - printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n",
3433 - regs->xds & 0xffff, regs->xes & 0xffff, ss);
3434 + printk(KERN_EMERG "ds: %04x es: %04x gs: %04x ss: %04x\n",
3435 + regs->xds & 0xffff, regs->xes & 0xffff, regs->xgs & 0xffff, ss);
3436 printk(KERN_EMERG "Process %.*s (pid: %d[#%u], ti=%p task=%p task.ti=%p)",
3437 TASK_COMM_LEN, current->comm, current->pid, current->xid,
3438 current_thread_info(), current, current->thread_info);
3439 @@ -332,11 +328,11 @@ void show_registers(struct pt_regs *regs
3441 printk(KERN_EMERG "Code: ");
3443 - eip = (u8 *)regs->eip - 43;
3444 + eip = (u8 *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
3445 if (eip < (u8 *)PAGE_OFFSET ||
3446 probe_kernel_address(eip, c)) {
3447 /* try starting at EIP */
3448 - eip = (u8 *)regs->eip;
3449 + eip = (u8 *)regs->eip + __KERNEL_TEXT_OFFSET;
3452 for (i = 0; i < code_bytes; i++, eip++) {
3453 @@ -345,7 +341,7 @@ void show_registers(struct pt_regs *regs
3454 printk(" Bad EIP value.");
3457 - if (eip == (u8 *)regs->eip)
3458 + if (eip == (u8 *)regs->eip + __KERNEL_TEXT_OFFSET)
3459 printk("<%02x> ", c);
3462 @@ -358,6 +354,7 @@ int is_valid_bugaddr(unsigned long eip)
3466 + eip += __KERNEL_TEXT_OFFSET;
3467 if (eip < PAGE_OFFSET)
3469 if (probe_kernel_address((unsigned short *)eip, ud2))
3470 @@ -464,7 +461,7 @@ void die(const char * str, struct pt_reg
3472 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
3474 - if (!user_mode_vm(regs))
3475 + if (!user_mode(regs))
3476 die(str, regs, err);
3479 @@ -482,7 +479,7 @@ static void __kprobes do_trap(int trapnr
3483 - if (!user_mode(regs))
3484 + if (!user_mode_novm(regs))
3488 @@ -570,7 +567,7 @@ fastcall void __kprobes do_general_prote
3491 int cpu = get_cpu();
3492 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
3493 + struct tss_struct *tss = &init_tss[cpu];
3494 struct thread_struct *thread = ¤t->thread;
3497 @@ -606,9 +603,25 @@ fastcall void __kprobes do_general_prote
3498 if (regs->eflags & VM_MASK)
3501 - if (!user_mode(regs))
3502 + if (!user_mode_novm(regs))
3505 +#ifdef CONFIG_PAX_PAGEEXEC
3506 + if (current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
3507 + struct mm_struct *mm = current->mm;
3508 + unsigned long limit;
3510 + down_write(&mm->mmap_sem);
3511 + limit = mm->context.user_cs_limit;
3512 + if (limit < TASK_SIZE) {
3513 + track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
3514 + up_write(&mm->mmap_sem);
3517 + up_write(&mm->mmap_sem);
3521 current->thread.error_code = error_code;
3522 current->thread.trap_no = 13;
3523 force_sig(SIGSEGV, current);
3524 @@ -624,6 +637,13 @@ gp_in_kernel:
3525 if (notify_die(DIE_GPF, "general protection fault", regs,
3526 error_code, 13, SIGSEGV) == NOTIFY_STOP)
3529 +#ifdef CONFIG_PAX_KERNEXEC
3530 + if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
3531 + die("PAX: suspicious general protection fault", regs, error_code);
3535 die("general protection fault", regs, error_code);
3538 @@ -705,7 +725,7 @@ void __kprobes die_nmi(struct pt_regs *r
3539 /* If we are in kernel we are probably nested up pretty bad
3540 * and might aswell get out now while we still can.
3542 - if (!user_mode_vm(regs)) {
3543 + if (!user_mode(regs)) {
3544 current->thread.trap_no = 2;
3547 @@ -837,7 +857,7 @@ fastcall void __kprobes do_debug(struct
3548 * check for kernel mode by just checking the CPL
3551 - if (!user_mode(regs))
3552 + if (!user_mode_novm(regs))
3553 goto clear_TF_reenable;
3556 @@ -1016,8 +1036,7 @@ fastcall unsigned long patch_espfix_desc
3559 int cpu = smp_processor_id();
3560 - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
3561 - struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr->address;
3562 + struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr[cpu].address;
3563 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
3564 unsigned long new_kesp = kesp - base;
3565 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
3566 @@ -1076,7 +1095,7 @@ void __init trap_init_f00f_bug(void)
3567 * Update the IDT descriptor and reload the IDT so that
3568 * it uses the read-only mapped virtual address.
3570 - idt_descr.address = fix_to_virt(FIX_F00F_IDT);
3571 + idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
3572 load_idt(&idt_descr);
3575 diff -urNp linux-2.6.20.3/arch/i386/kernel/tsc.c linux-2.6.20.3/arch/i386/kernel/tsc.c
3576 --- linux-2.6.20.3/arch/i386/kernel/tsc.c 2007-03-13 14:27:08.000000000 -0400
3577 +++ linux-2.6.20.3/arch/i386/kernel/tsc.c 2007-03-23 08:10:06.000000000 -0400
3578 @@ -383,7 +383,7 @@ static struct dmi_system_id __initdata b
3579 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
3583 + { NULL, NULL, {{0, NULL}}, NULL}
3586 #define TSC_FREQ_CHECK_INTERVAL (10*MSEC_PER_SEC) /* 10sec in MS */
3587 diff -urNp linux-2.6.20.3/arch/i386/kernel/vm86.c linux-2.6.20.3/arch/i386/kernel/vm86.c
3588 --- linux-2.6.20.3/arch/i386/kernel/vm86.c 2007-03-13 14:27:08.000000000 -0400
3589 +++ linux-2.6.20.3/arch/i386/kernel/vm86.c 2007-03-23 08:10:06.000000000 -0400
3590 @@ -148,7 +148,7 @@ struct pt_regs * fastcall save_v86_state
3594 - tss = &per_cpu(init_tss, get_cpu());
3595 + tss = init_tss + get_cpu();
3596 current->thread.esp0 = current->thread.saved_esp0;
3597 current->thread.sysenter_cs = __KERNEL_CS;
3598 load_esp0(tss, ¤t->thread);
3599 @@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
3600 savesegment(fs, tsk->thread.saved_fs);
3601 tsk->thread.saved_gs = info->regs32->xgs;
3603 - tss = &per_cpu(init_tss, get_cpu());
3604 + tss = init_tss + get_cpu();
3605 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
3607 tsk->thread.sysenter_cs = 0;
3608 diff -urNp linux-2.6.20.3/arch/i386/kernel/vmlinux.lds.S linux-2.6.20.3/arch/i386/kernel/vmlinux.lds.S
3609 --- linux-2.6.20.3/arch/i386/kernel/vmlinux.lds.S 2007-03-13 14:27:08.000000000 -0400
3610 +++ linux-2.6.20.3/arch/i386/kernel/vmlinux.lds.S 2007-03-23 08:10:06.000000000 -0400
3612 #include <asm/page.h>
3613 #include <asm/cache.h>
3614 #include <asm/boot.h>
3615 +#include <asm/segment.h>
3617 +#ifdef CONFIG_X86_PAE
3618 +#define PMD_SHIFT 21
3620 +#define PMD_SHIFT 22
3623 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
3625 @@ -30,85 +37,19 @@ _proxy_pda = 0;
3628 text PT_LOAD FLAGS(5); /* R_E */
3629 - data PT_LOAD FLAGS(7); /* RWE */
3630 + data PT_LOAD FLAGS(6); /* RW_ */
3631 note PT_NOTE FLAGS(4); /* R__ */
3635 . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
3636 - phys_startup_32 = startup_32 - LOAD_OFFSET;
3638 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
3639 - _text = .; /* Text and read-only data */
3646 - _etext = .; /* End of text section */
3649 - . = ALIGN(16); /* Exception table */
3650 - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
3651 - __start___ex_table = .;
3653 - __stop___ex_table = .;
3655 + phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
3662 - .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
3663 - __tracedata_start = .;
3665 - __tracedata_end = .;
3670 - .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
3675 - .paravirtprobe : AT(ADDR(.paravirtprobe) - LOAD_OFFSET) {
3676 - __start_paravirtprobe = .;
3678 - __stop_paravirtprobe = .;
3682 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
3683 - __nosave_begin = .;
3690 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
3695 - .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
3696 - *(.data.cacheline_aligned)
3699 - /* rarely changed data like cpu maps */
3701 - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
3702 - *(.data.read_mostly)
3703 - _edata = .; /* End of data section */
3706 - . = ALIGN(THREAD_SIZE); /* init_task */
3707 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
3708 - *(.data.init_task)
3710 + .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
3711 + BYTE(0xEA) /* jmp far */
3712 + LONG(phys_startup_32)
3716 /* might get freed after init */
3718 @@ -137,14 +78,10 @@ SECTIONS
3721 /* will be freed after init */
3722 - . = ALIGN(4096); /* Init code and data */
3723 - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
3729 - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
3730 + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
3735 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
3737 @@ -177,9 +114,6 @@ SECTIONS
3738 *(.parainstructions)
3739 __stop_parainstructions = .;
3741 - /* .exit.text is discard at runtime, not link time, to deal with references
3742 - from .altinstructions and .eh_frame */
3743 - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
3744 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
3746 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
3747 @@ -193,11 +127,131 @@ SECTIONS
3754 + . = ALIGN(4096); /* Init code and data */
3755 + .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3761 + /* .exit.text is discard at runtime, not link time, to deal with references
3762 + from .altinstructions and .eh_frame */
3763 + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
3765 +#ifdef CONFIG_PAX_KERNEXEC
3766 + .text.align : AT(ADDR(.text.align) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3767 + . = ALIGN(__KERNEL_TEXT_OFFSET - LOAD_OFFSET) - 1;
3774 /* freed after init ends here */
3777 + .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3778 + __init_end = . + __KERNEL_TEXT_OFFSET;
3779 + _text = .; /* Text and read-only data */
3786 + _etext = .; /* End of text section */
3789 + . += __KERNEL_TEXT_OFFSET;
3790 + . = ALIGN(16); /* Exception table */
3791 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
3792 + __start___ex_table = .;
3794 + __stop___ex_table = .;
3798 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
3799 + *(.empty_zero_page)
3801 +#ifdef CONFIG_X86_PAE
3802 + *(.swapper_pm_dir)
3805 + *(.swapper_pg_dir)
3814 + .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
3815 + __tracedata_start = .;
3817 + __tracedata_end = .;
3820 +#ifdef CONFIG_PAX_KERNEXEC
3823 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
3824 + MODULES_VADDR = .;
3825 + . += (4 * 1024 * 1024);
3826 + . = ALIGN(1 << PMD_SHIFT) - 1;
3837 + .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
3843 + .paravirtprobe : AT(ADDR(.paravirtprobe) - LOAD_OFFSET) {
3844 + __start_paravirtprobe = .;
3846 + __stop_paravirtprobe = .;
3850 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
3851 + __nosave_begin = .;
3858 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
3859 + *(.data.cacheline_aligned)
3862 + /* rarely changed data like cpu maps */
3864 + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
3865 + *(.data.read_mostly)
3866 + _edata = .; /* End of data section */
3869 + . = ALIGN(THREAD_SIZE); /* init_task */
3870 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
3871 + *(.data.init_task)
3876 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
3878 __bss_start = .; /* BSS */
3879 *(.bss.page_aligned)
3881 diff -urNp linux-2.6.20.3/arch/i386/lib/checksum.S linux-2.6.20.3/arch/i386/lib/checksum.S
3882 --- linux-2.6.20.3/arch/i386/lib/checksum.S 2007-03-13 14:27:08.000000000 -0400
3883 +++ linux-2.6.20.3/arch/i386/lib/checksum.S 2007-03-23 08:10:06.000000000 -0400
3887 #include <asm/errno.h>
3889 +#include <asm/segment.h>
3892 * computes a partial checksum, e.g. for TCP/UDP fragments
3894 @@ -280,12 +281,23 @@ unsigned int csum_partial_copy_generic (
3897 .globl csum_partial_copy_generic
3899 +.globl csum_partial_copy_generic_to_user
3900 +.globl csum_partial_copy_generic_from_user
3902 #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
3908 +csum_partial_copy_generic_to_user:
3909 + pushl $(__USER_DS)
3911 + jmp csum_partial_copy_generic
3913 +csum_partial_copy_generic_from_user:
3914 + pushl $(__USER_DS)
3917 csum_partial_copy_generic:
3920 @@ -304,7 +316,7 @@ csum_partial_copy_generic:
3922 SRC(1: movw (%esi), %bx )
3924 -DST( movw %bx, (%edi) )
3925 +DST( movw %bx, %es:(%edi) )
3929 @@ -316,30 +328,30 @@ DST( movw %bx, (%edi) )
3930 SRC(1: movl (%esi), %ebx )
3931 SRC( movl 4(%esi), %edx )
3933 -DST( movl %ebx, (%edi) )
3934 +DST( movl %ebx, %es:(%edi) )
3936 -DST( movl %edx, 4(%edi) )
3937 +DST( movl %edx, %es:4(%edi) )
3939 SRC( movl 8(%esi), %ebx )
3940 SRC( movl 12(%esi), %edx )
3942 -DST( movl %ebx, 8(%edi) )
3943 +DST( movl %ebx, %es:8(%edi) )
3945 -DST( movl %edx, 12(%edi) )
3946 +DST( movl %edx, %es:12(%edi) )
3948 SRC( movl 16(%esi), %ebx )
3949 SRC( movl 20(%esi), %edx )
3951 -DST( movl %ebx, 16(%edi) )
3952 +DST( movl %ebx, %es:16(%edi) )
3954 -DST( movl %edx, 20(%edi) )
3955 +DST( movl %edx, %es:20(%edi) )
3957 SRC( movl 24(%esi), %ebx )
3958 SRC( movl 28(%esi), %edx )
3960 -DST( movl %ebx, 24(%edi) )
3961 +DST( movl %ebx, %es:24(%edi) )
3963 -DST( movl %edx, 28(%edi) )
3964 +DST( movl %edx, %es:28(%edi) )
3968 @@ -353,7 +365,7 @@ DST( movl %edx, 28(%edi) )
3969 shrl $2, %edx # This clears CF
3970 SRC(3: movl (%esi), %ebx )
3972 -DST( movl %ebx, (%edi) )
3973 +DST( movl %ebx, %es:(%edi) )
3977 @@ -365,12 +377,12 @@ DST( movl %ebx, (%edi) )
3979 SRC( movw (%esi), %cx )
3981 -DST( movw %cx, (%edi) )
3982 +DST( movw %cx, %es:(%edi) )
3986 SRC(5: movb (%esi), %cl )
3987 -DST( movb %cl, (%edi) )
3988 +DST( movb %cl, %es:(%edi) )
3992 @@ -381,7 +393,7 @@ DST( movb %cl, (%edi) )
3995 movl ARGBASE+20(%esp), %ebx # src_err_ptr
3996 - movl $-EFAULT, (%ebx)
3997 + movl $-EFAULT, %ss:(%ebx)
3999 # zero the complete destination - computing the rest
4001 @@ -394,11 +406,15 @@ DST( movb %cl, (%edi) )
4004 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
4005 - movl $-EFAULT,(%ebx)
4006 + movl $-EFAULT,%ss:(%ebx)
4018 @@ -410,17 +426,28 @@ DST( movb %cl, (%edi) )
4019 /* Version for PentiumII/PPro */
4023 SRC(movl x(%esi), %ebx ) ; \
4025 - DST(movl %ebx, x(%edi) ) ;
4026 + DST(movl %ebx, %es:x(%edi));
4030 SRC(movl x(%esi), %ebx ) ; \
4032 - DST(movl %ebx, x(%edi) ) ;
4033 + DST(movl %ebx, %es:x(%edi));
4038 +csum_partial_copy_generic_to_user:
4039 + pushl $(__USER_DS)
4041 + jmp csum_partial_copy_generic
4043 +csum_partial_copy_generic_from_user:
4044 + pushl $(__USER_DS)
4047 csum_partial_copy_generic:
4050 @@ -439,7 +466,7 @@ csum_partial_copy_generic:
4054 - lea 3f(%ebx,%ebx), %ebx
4055 + lea 3f(%ebx,%ebx,2), %ebx
4059 @@ -460,19 +487,19 @@ csum_partial_copy_generic:
4061 SRC( movw (%esi), %dx )
4063 -DST( movw %dx, (%edi) )
4064 +DST( movw %dx, %es:(%edi) )
4069 SRC( movb (%esi), %dl )
4070 -DST( movb %dl, (%edi) )
4071 +DST( movb %dl, %es:(%edi) )
4075 .section .fixup, "ax"
4076 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
4077 - movl $-EFAULT, (%ebx)
4078 + movl $-EFAULT, %ss:(%ebx)
4079 # zero the complete destination (computing the rest is too much work)
4080 movl ARGBASE+8(%esp),%edi # dst
4081 movl ARGBASE+12(%esp),%ecx # len
4082 @@ -480,10 +507,14 @@ DST( movb %dl, (%edi) )
4085 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
4086 - movl $-EFAULT, (%ebx)
4087 + movl $-EFAULT, %ss:(%ebx)
4098 diff -urNp linux-2.6.20.3/arch/i386/lib/getuser.S linux-2.6.20.3/arch/i386/lib/getuser.S
4099 --- linux-2.6.20.3/arch/i386/lib/getuser.S 2007-03-13 14:27:08.000000000 -0400
4100 +++ linux-2.6.20.3/arch/i386/lib/getuser.S 2007-03-23 08:10:06.000000000 -0400
4104 #include <asm/thread_info.h>
4105 +#include <asm/segment.h>
4109 @@ -30,8 +31,12 @@ __get_user_1:
4110 GET_THREAD_INFO(%edx)
4111 cmpl TI_addr_limit(%edx),%eax
4113 + pushl $(__USER_DS)
4115 1: movzbl (%eax),%edx
4122 @@ -42,7 +47,11 @@ __get_user_2:
4123 GET_THREAD_INFO(%edx)
4124 cmpl TI_addr_limit(%edx),%eax
4126 + pushl $(__USER_DS)
4128 2: movzwl -1(%eax),%edx
4134 @@ -54,11 +63,17 @@ __get_user_4:
4135 GET_THREAD_INFO(%edx)
4136 cmpl TI_addr_limit(%edx),%eax
4138 + pushl $(__USER_DS)
4140 3: movl -3(%eax),%edx
4152 diff -urNp linux-2.6.20.3/arch/i386/lib/mmx.c linux-2.6.20.3/arch/i386/lib/mmx.c
4153 --- linux-2.6.20.3/arch/i386/lib/mmx.c 2007-03-13 14:27:08.000000000 -0400
4154 +++ linux-2.6.20.3/arch/i386/lib/mmx.c 2007-03-23 09:32:49.000000000 -0400
4155 @@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void *
4159 + unsigned long cr0;
4161 if (unlikely(in_interrupt()))
4162 return __memcpy(to, from, len);
4163 @@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
4166 __asm__ __volatile__ (
4167 - "1: prefetch (%0)\n" /* This set is 28 bytes */
4168 - " prefetch 64(%0)\n"
4169 - " prefetch 128(%0)\n"
4170 - " prefetch 192(%0)\n"
4171 - " prefetch 256(%0)\n"
4172 + "1: prefetch (%1)\n" /* This set is 28 bytes */
4173 + " prefetch 64(%1)\n"
4174 + " prefetch 128(%1)\n"
4175 + " prefetch 192(%1)\n"
4176 + " prefetch 256(%1)\n"
4178 ".section .fixup, \"ax\"\n"
4179 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4182 +#ifdef CONFIG_PAX_KERNEXEC
4183 + " movl %%cr0, %0\n"
4184 + " movl %0, %%eax\n"
4185 + " andl $0xFFFEFFFF, %%eax\n"
4186 + " movl %%eax, %%cr0\n"
4189 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4191 +#ifdef CONFIG_PAX_KERNEXEC
4192 + " movl %0, %%cr0\n"
4197 ".section __ex_table,\"a\"\n"
4202 + : "=&r" (cr0) : "r" (from) : "ax");
4207 __asm__ __volatile__ (
4208 - "1: prefetch 320(%0)\n"
4209 - "2: movq (%0), %%mm0\n"
4210 - " movq 8(%0), %%mm1\n"
4211 - " movq 16(%0), %%mm2\n"
4212 - " movq 24(%0), %%mm3\n"
4213 - " movq %%mm0, (%1)\n"
4214 - " movq %%mm1, 8(%1)\n"
4215 - " movq %%mm2, 16(%1)\n"
4216 - " movq %%mm3, 24(%1)\n"
4217 - " movq 32(%0), %%mm0\n"
4218 - " movq 40(%0), %%mm1\n"
4219 - " movq 48(%0), %%mm2\n"
4220 - " movq 56(%0), %%mm3\n"
4221 - " movq %%mm0, 32(%1)\n"
4222 - " movq %%mm1, 40(%1)\n"
4223 - " movq %%mm2, 48(%1)\n"
4224 - " movq %%mm3, 56(%1)\n"
4225 + "1: prefetch 320(%1)\n"
4226 + "2: movq (%1), %%mm0\n"
4227 + " movq 8(%1), %%mm1\n"
4228 + " movq 16(%1), %%mm2\n"
4229 + " movq 24(%1), %%mm3\n"
4230 + " movq %%mm0, (%2)\n"
4231 + " movq %%mm1, 8(%2)\n"
4232 + " movq %%mm2, 16(%2)\n"
4233 + " movq %%mm3, 24(%2)\n"
4234 + " movq 32(%1), %%mm0\n"
4235 + " movq 40(%1), %%mm1\n"
4236 + " movq 48(%1), %%mm2\n"
4237 + " movq 56(%1), %%mm3\n"
4238 + " movq %%mm0, 32(%2)\n"
4239 + " movq %%mm1, 40(%2)\n"
4240 + " movq %%mm2, 48(%2)\n"
4241 + " movq %%mm3, 56(%2)\n"
4242 ".section .fixup, \"ax\"\n"
4243 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4246 +#ifdef CONFIG_PAX_KERNEXEC
4247 + " movl %%cr0, %0\n"
4248 + " movl %0, %%eax\n"
4249 + " andl $0xFFFEFFFF, %%eax\n"
4250 + " movl %%eax, %%cr0\n"
4253 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4255 +#ifdef CONFIG_PAX_KERNEXEC
4256 + " movl %0, %%cr0\n"
4261 ".section __ex_table,\"a\"\n"
4265 - : : "r" (from), "r" (to) : "memory");
4266 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4270 @@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
4271 static void fast_copy_page(void *to, void *from)
4274 + unsigned long cr0;
4278 @@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
4279 * but that is for later. -AV
4281 __asm__ __volatile__ (
4282 - "1: prefetch (%0)\n"
4283 - " prefetch 64(%0)\n"
4284 - " prefetch 128(%0)\n"
4285 - " prefetch 192(%0)\n"
4286 - " prefetch 256(%0)\n"
4287 + "1: prefetch (%1)\n"
4288 + " prefetch 64(%1)\n"
4289 + " prefetch 128(%1)\n"
4290 + " prefetch 192(%1)\n"
4291 + " prefetch 256(%1)\n"
4293 ".section .fixup, \"ax\"\n"
4294 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4297 +#ifdef CONFIG_PAX_KERNEXEC
4298 + " movl %%cr0, %0\n"
4299 + " movl %0, %%eax\n"
4300 + " andl $0xFFFEFFFF, %%eax\n"
4301 + " movl %%eax, %%cr0\n"
4304 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4306 +#ifdef CONFIG_PAX_KERNEXEC
4307 + " movl %0, %%cr0\n"
4312 ".section __ex_table,\"a\"\n"
4317 + : "=&r" (cr0) : "r" (from) : "ax");
4319 for(i=0; i<(4096-320)/64; i++)
4321 __asm__ __volatile__ (
4322 - "1: prefetch 320(%0)\n"
4323 - "2: movq (%0), %%mm0\n"
4324 - " movntq %%mm0, (%1)\n"
4325 - " movq 8(%0), %%mm1\n"
4326 - " movntq %%mm1, 8(%1)\n"
4327 - " movq 16(%0), %%mm2\n"
4328 - " movntq %%mm2, 16(%1)\n"
4329 - " movq 24(%0), %%mm3\n"
4330 - " movntq %%mm3, 24(%1)\n"
4331 - " movq 32(%0), %%mm4\n"
4332 - " movntq %%mm4, 32(%1)\n"
4333 - " movq 40(%0), %%mm5\n"
4334 - " movntq %%mm5, 40(%1)\n"
4335 - " movq 48(%0), %%mm6\n"
4336 - " movntq %%mm6, 48(%1)\n"
4337 - " movq 56(%0), %%mm7\n"
4338 - " movntq %%mm7, 56(%1)\n"
4339 + "1: prefetch 320(%1)\n"
4340 + "2: movq (%1), %%mm0\n"
4341 + " movntq %%mm0, (%2)\n"
4342 + " movq 8(%1), %%mm1\n"
4343 + " movntq %%mm1, 8(%2)\n"
4344 + " movq 16(%1), %%mm2\n"
4345 + " movntq %%mm2, 16(%2)\n"
4346 + " movq 24(%1), %%mm3\n"
4347 + " movntq %%mm3, 24(%2)\n"
4348 + " movq 32(%1), %%mm4\n"
4349 + " movntq %%mm4, 32(%2)\n"
4350 + " movq 40(%1), %%mm5\n"
4351 + " movntq %%mm5, 40(%2)\n"
4352 + " movq 48(%1), %%mm6\n"
4353 + " movntq %%mm6, 48(%2)\n"
4354 + " movq 56(%1), %%mm7\n"
4355 + " movntq %%mm7, 56(%2)\n"
4356 ".section .fixup, \"ax\"\n"
4357 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4360 +#ifdef CONFIG_PAX_KERNEXEC
4361 + " movl %%cr0, %0\n"
4362 + " movl %0, %%eax\n"
4363 + " andl $0xFFFEFFFF, %%eax\n"
4364 + " movl %%eax, %%cr0\n"
4367 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4369 +#ifdef CONFIG_PAX_KERNEXEC
4370 + " movl %0, %%cr0\n"
4375 ".section __ex_table,\"a\"\n"
4379 - : : "r" (from), "r" (to) : "memory");
4380 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4384 @@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
4385 static void fast_copy_page(void *to, void *from)
4390 + unsigned long cr0;
4394 __asm__ __volatile__ (
4395 - "1: prefetch (%0)\n"
4396 - " prefetch 64(%0)\n"
4397 - " prefetch 128(%0)\n"
4398 - " prefetch 192(%0)\n"
4399 - " prefetch 256(%0)\n"
4400 + "1: prefetch (%1)\n"
4401 + " prefetch 64(%1)\n"
4402 + " prefetch 128(%1)\n"
4403 + " prefetch 192(%1)\n"
4404 + " prefetch 256(%1)\n"
4406 ".section .fixup, \"ax\"\n"
4407 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4410 +#ifdef CONFIG_PAX_KERNEXEC
4411 + " movl %%cr0, %0\n"
4412 + " movl %0, %%eax\n"
4413 + " andl $0xFFFEFFFF, %%eax\n"
4414 + " movl %%eax, %%cr0\n"
4417 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4419 +#ifdef CONFIG_PAX_KERNEXEC
4420 + " movl %0, %%cr0\n"
4425 ".section __ex_table,\"a\"\n"
4430 + : "=&r" (cr0) : "r" (from) : "ax");
4432 for(i=0; i<4096/64; i++)
4434 __asm__ __volatile__ (
4435 - "1: prefetch 320(%0)\n"
4436 - "2: movq (%0), %%mm0\n"
4437 - " movq 8(%0), %%mm1\n"
4438 - " movq 16(%0), %%mm2\n"
4439 - " movq 24(%0), %%mm3\n"
4440 - " movq %%mm0, (%1)\n"
4441 - " movq %%mm1, 8(%1)\n"
4442 - " movq %%mm2, 16(%1)\n"
4443 - " movq %%mm3, 24(%1)\n"
4444 - " movq 32(%0), %%mm0\n"
4445 - " movq 40(%0), %%mm1\n"
4446 - " movq 48(%0), %%mm2\n"
4447 - " movq 56(%0), %%mm3\n"
4448 - " movq %%mm0, 32(%1)\n"
4449 - " movq %%mm1, 40(%1)\n"
4450 - " movq %%mm2, 48(%1)\n"
4451 - " movq %%mm3, 56(%1)\n"
4452 + "1: prefetch 320(%1)\n"
4453 + "2: movq (%1), %%mm0\n"
4454 + " movq 8(%1), %%mm1\n"
4455 + " movq 16(%1), %%mm2\n"
4456 + " movq 24(%1), %%mm3\n"
4457 + " movq %%mm0, (%2)\n"
4458 + " movq %%mm1, 8(%2)\n"
4459 + " movq %%mm2, 16(%2)\n"
4460 + " movq %%mm3, 24(%2)\n"
4461 + " movq 32(%1), %%mm0\n"
4462 + " movq 40(%1), %%mm1\n"
4463 + " movq 48(%1), %%mm2\n"
4464 + " movq 56(%1), %%mm3\n"
4465 + " movq %%mm0, 32(%2)\n"
4466 + " movq %%mm1, 40(%2)\n"
4467 + " movq %%mm2, 48(%2)\n"
4468 + " movq %%mm3, 56(%2)\n"
4469 ".section .fixup, \"ax\"\n"
4470 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4473 +#ifdef CONFIG_PAX_KERNEXEC
4474 + " movl %%cr0, %0\n"
4475 + " movl %0, %%eax\n"
4476 + " andl $0xFFFEFFFF, %%eax\n"
4477 + " movl %%eax, %%cr0\n"
4480 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4482 +#ifdef CONFIG_PAX_KERNEXEC
4483 + " movl %0, %%cr0\n"
4488 ".section __ex_table,\"a\"\n"
4492 - : : "r" (from), "r" (to) : "memory");
4493 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4497 diff -urNp linux-2.6.20.3/arch/i386/lib/putuser.S linux-2.6.20.3/arch/i386/lib/putuser.S
4498 --- linux-2.6.20.3/arch/i386/lib/putuser.S 2007-03-13 14:27:08.000000000 -0400
4499 +++ linux-2.6.20.3/arch/i386/lib/putuser.S 2007-03-23 08:10:06.000000000 -0400
4503 #include <asm/thread_info.h>
4504 +#include <asm/segment.h>
4508 @@ -33,7 +34,11 @@ __put_user_1:
4510 cmpl TI_addr_limit(%ebx),%ecx
4512 + pushl $(__USER_DS)
4520 @@ -45,7 +50,11 @@ __put_user_2:
4524 + pushl $(__USER_DS)
4532 @@ -57,7 +66,11 @@ __put_user_4:
4536 + pushl $(__USER_DS)
4544 @@ -69,12 +82,18 @@ __put_user_8:
4548 + pushl $(__USER_DS)
4551 5: movl %edx,4(%ecx)
4563 diff -urNp linux-2.6.20.3/arch/i386/lib/usercopy.c linux-2.6.20.3/arch/i386/lib/usercopy.c
4564 --- linux-2.6.20.3/arch/i386/lib/usercopy.c 2007-03-13 14:27:08.000000000 -0400
4565 +++ linux-2.6.20.3/arch/i386/lib/usercopy.c 2007-03-23 08:10:06.000000000 -0400
4566 @@ -28,34 +28,41 @@ static inline int __movsl_is_ok(unsigned
4567 * Copy a null terminated string from userspace.
4570 -#define __do_strncpy_from_user(dst,src,count,res) \
4572 - int __d0, __d1, __d2; \
4574 - __asm__ __volatile__( \
4575 - " testl %1,%1\n" \
4579 - " testb %%al,%%al\n" \
4583 - "1: subl %1,%0\n" \
4585 - ".section .fixup,\"ax\"\n" \
4586 - "3: movl %5,%0\n" \
4589 - ".section __ex_table,\"a\"\n" \
4591 - " .long 0b,3b\n" \
4593 - : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
4595 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
4598 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
4600 + int __d0, __d1, __d2;
4601 + long res = -EFAULT;
4604 + __asm__ __volatile__(
4605 + " movw %w10,%%ds\n"
4610 + " testb %%al,%%al\n"
4618 + ".section .fixup,\"ax\"\n"
4622 + ".section __ex_table,\"a\"\n"
4626 + : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
4628 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
4635 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
4636 @@ -80,9 +87,7 @@ do { \
4638 __strncpy_from_user(char *dst, const char __user *src, long count)
4641 - __do_strncpy_from_user(dst, src, count, res);
4643 + return __do_strncpy_from_user(dst, src, count);
4645 EXPORT_SYMBOL(__strncpy_from_user);
4647 @@ -109,7 +114,7 @@ strncpy_from_user(char *dst, const char
4650 if (access_ok(VERIFY_READ, src, 1))
4651 - __do_strncpy_from_user(dst, src, count, res);
4652 + res = __do_strncpy_from_user(dst, src, count);
4655 EXPORT_SYMBOL(strncpy_from_user);
4656 @@ -118,27 +123,33 @@ EXPORT_SYMBOL(strncpy_from_user);
4660 -#define __do_clear_user(addr,size) \
4664 - __asm__ __volatile__( \
4665 - "0: rep; stosl\n" \
4667 - "1: rep; stosb\n" \
4669 - ".section .fixup,\"ax\"\n" \
4670 - "3: lea 0(%2,%0,4),%0\n" \
4673 - ".section __ex_table,\"a\"\n" \
4675 - " .long 0b,3b\n" \
4676 - " .long 1b,2b\n" \
4678 - : "=&c"(size), "=&D" (__d0) \
4679 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
4681 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
4686 + __asm__ __volatile__(
4687 + " movw %w6,%%es\n"
4694 + ".section .fixup,\"ax\"\n"
4695 + "3: lea 0(%2,%0,4),%0\n"
4698 + ".section __ex_table,\"a\"\n"
4703 + : "=&c"(size), "=&D" (__d0)
4704 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
4710 * clear_user: - Zero a block of memory in user space.
4711 @@ -155,7 +166,7 @@ clear_user(void __user *to, unsigned lon
4714 if (access_ok(VERIFY_WRITE, to, n))
4715 - __do_clear_user(to, n);
4716 + n = __do_clear_user(to, n);
4719 EXPORT_SYMBOL(clear_user);
4720 @@ -174,8 +185,7 @@ EXPORT_SYMBOL(clear_user);
4722 __clear_user(void __user *to, unsigned long n)
4724 - __do_clear_user(to, n);
4726 + return __do_clear_user(to, n);
4728 EXPORT_SYMBOL(__clear_user);
4730 @@ -198,14 +208,17 @@ long strnlen_user(const char __user *s,
4733 __asm__ __volatile__(
4734 + " movw %w8,%%es\n"
4737 - " andl %0,%%ecx\n"
4738 + " movl %0,%%ecx\n"
4746 ".section .fixup,\"ax\"\n"
4747 "2: xorl %%eax,%%eax\n"
4749 @@ -217,7 +230,7 @@ long strnlen_user(const char __user *s,
4752 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
4753 - :"0" (n), "1" (s), "2" (0), "3" (mask)
4754 + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
4758 @@ -225,10 +238,11 @@ EXPORT_SYMBOL(strnlen_user);
4760 #ifdef CONFIG_X86_INTEL_USERCOPY
4761 static unsigned long
4762 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
4763 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
4766 __asm__ __volatile__(
4767 + " movw %w6, %%es\n"
4769 "1: movl 32(%4), %%eax\n"
4771 @@ -237,36 +251,36 @@ __copy_user_intel(void __user *to, const
4773 "3: movl 0(%4), %%eax\n"
4774 "4: movl 4(%4), %%edx\n"
4775 - "5: movl %%eax, 0(%3)\n"
4776 - "6: movl %%edx, 4(%3)\n"
4777 + "5: movl %%eax, %%es:0(%3)\n"
4778 + "6: movl %%edx, %%es:4(%3)\n"
4779 "7: movl 8(%4), %%eax\n"
4780 "8: movl 12(%4),%%edx\n"
4781 - "9: movl %%eax, 8(%3)\n"
4782 - "10: movl %%edx, 12(%3)\n"
4783 + "9: movl %%eax, %%es:8(%3)\n"
4784 + "10: movl %%edx, %%es:12(%3)\n"
4785 "11: movl 16(%4), %%eax\n"
4786 "12: movl 20(%4), %%edx\n"
4787 - "13: movl %%eax, 16(%3)\n"
4788 - "14: movl %%edx, 20(%3)\n"
4789 + "13: movl %%eax, %%es:16(%3)\n"
4790 + "14: movl %%edx, %%es:20(%3)\n"
4791 "15: movl 24(%4), %%eax\n"
4792 "16: movl 28(%4), %%edx\n"
4793 - "17: movl %%eax, 24(%3)\n"
4794 - "18: movl %%edx, 28(%3)\n"
4795 + "17: movl %%eax, %%es:24(%3)\n"
4796 + "18: movl %%edx, %%es:28(%3)\n"
4797 "19: movl 32(%4), %%eax\n"
4798 "20: movl 36(%4), %%edx\n"
4799 - "21: movl %%eax, 32(%3)\n"
4800 - "22: movl %%edx, 36(%3)\n"
4801 + "21: movl %%eax, %%es:32(%3)\n"
4802 + "22: movl %%edx, %%es:36(%3)\n"
4803 "23: movl 40(%4), %%eax\n"
4804 "24: movl 44(%4), %%edx\n"
4805 - "25: movl %%eax, 40(%3)\n"
4806 - "26: movl %%edx, 44(%3)\n"
4807 + "25: movl %%eax, %%es:40(%3)\n"
4808 + "26: movl %%edx, %%es:44(%3)\n"
4809 "27: movl 48(%4), %%eax\n"
4810 "28: movl 52(%4), %%edx\n"
4811 - "29: movl %%eax, 48(%3)\n"
4812 - "30: movl %%edx, 52(%3)\n"
4813 + "29: movl %%eax, %%es:48(%3)\n"
4814 + "30: movl %%edx, %%es:52(%3)\n"
4815 "31: movl 56(%4), %%eax\n"
4816 "32: movl 60(%4), %%edx\n"
4817 - "33: movl %%eax, 56(%3)\n"
4818 - "34: movl %%edx, 60(%3)\n"
4819 + "33: movl %%eax, %%es:56(%3)\n"
4820 + "34: movl %%edx, %%es:60(%3)\n"
4824 @@ -280,6 +294,8 @@ __copy_user_intel(void __user *to, const
4825 "36: movl %%eax, %0\n"
4830 ".section .fixup,\"ax\"\n"
4831 "101: lea 0(%%eax,%0,4),%0\n"
4833 @@ -326,7 +342,117 @@ __copy_user_intel(void __user *to, const
4836 : "=&c"(size), "=&D" (d0), "=&S" (d1)
4837 - : "1"(to), "2"(from), "0"(size)
4838 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4839 + : "eax", "edx", "memory");
4843 +static unsigned long
4844 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
4847 + __asm__ __volatile__(
4848 + " movw %w6, %%ds\n"
4849 + " .align 2,0x90\n"
4850 + "1: movl 32(%4), %%eax\n"
4853 + "2: movl 64(%4), %%eax\n"
4854 + " .align 2,0x90\n"
4855 + "3: movl 0(%4), %%eax\n"
4856 + "4: movl 4(%4), %%edx\n"
4857 + "5: movl %%eax, %%es:0(%3)\n"
4858 + "6: movl %%edx, %%es:4(%3)\n"
4859 + "7: movl 8(%4), %%eax\n"
4860 + "8: movl 12(%4),%%edx\n"
4861 + "9: movl %%eax, %%es:8(%3)\n"
4862 + "10: movl %%edx, %%es:12(%3)\n"
4863 + "11: movl 16(%4), %%eax\n"
4864 + "12: movl 20(%4), %%edx\n"
4865 + "13: movl %%eax, %%es:16(%3)\n"
4866 + "14: movl %%edx, %%es:20(%3)\n"
4867 + "15: movl 24(%4), %%eax\n"
4868 + "16: movl 28(%4), %%edx\n"
4869 + "17: movl %%eax, %%es:24(%3)\n"
4870 + "18: movl %%edx, %%es:28(%3)\n"
4871 + "19: movl 32(%4), %%eax\n"
4872 + "20: movl 36(%4), %%edx\n"
4873 + "21: movl %%eax, %%es:32(%3)\n"
4874 + "22: movl %%edx, %%es:36(%3)\n"
4875 + "23: movl 40(%4), %%eax\n"
4876 + "24: movl 44(%4), %%edx\n"
4877 + "25: movl %%eax, %%es:40(%3)\n"
4878 + "26: movl %%edx, %%es:44(%3)\n"
4879 + "27: movl 48(%4), %%eax\n"
4880 + "28: movl 52(%4), %%edx\n"
4881 + "29: movl %%eax, %%es:48(%3)\n"
4882 + "30: movl %%edx, %%es:52(%3)\n"
4883 + "31: movl 56(%4), %%eax\n"
4884 + "32: movl 60(%4), %%edx\n"
4885 + "33: movl %%eax, %%es:56(%3)\n"
4886 + "34: movl %%edx, %%es:60(%3)\n"
4887 + " addl $-64, %0\n"
4892 + "35: movl %0, %%eax\n"
4894 + " andl $3, %%eax\n"
4896 + "99: rep; movsl\n"
4897 + "36: movl %%eax, %0\n"
4898 + "37: rep; movsb\n"
4902 + ".section .fixup,\"ax\"\n"
4903 + "101: lea 0(%%eax,%0,4),%0\n"
4906 + ".section __ex_table,\"a\"\n"
4908 + " .long 1b,100b\n"
4909 + " .long 2b,100b\n"
4910 + " .long 3b,100b\n"
4911 + " .long 4b,100b\n"
4912 + " .long 5b,100b\n"
4913 + " .long 6b,100b\n"
4914 + " .long 7b,100b\n"
4915 + " .long 8b,100b\n"
4916 + " .long 9b,100b\n"
4917 + " .long 10b,100b\n"
4918 + " .long 11b,100b\n"
4919 + " .long 12b,100b\n"
4920 + " .long 13b,100b\n"
4921 + " .long 14b,100b\n"
4922 + " .long 15b,100b\n"
4923 + " .long 16b,100b\n"
4924 + " .long 17b,100b\n"
4925 + " .long 18b,100b\n"
4926 + " .long 19b,100b\n"
4927 + " .long 20b,100b\n"
4928 + " .long 21b,100b\n"
4929 + " .long 22b,100b\n"
4930 + " .long 23b,100b\n"
4931 + " .long 24b,100b\n"
4932 + " .long 25b,100b\n"
4933 + " .long 26b,100b\n"
4934 + " .long 27b,100b\n"
4935 + " .long 28b,100b\n"
4936 + " .long 29b,100b\n"
4937 + " .long 30b,100b\n"
4938 + " .long 31b,100b\n"
4939 + " .long 32b,100b\n"
4940 + " .long 33b,100b\n"
4941 + " .long 34b,100b\n"
4942 + " .long 35b,100b\n"
4943 + " .long 36b,100b\n"
4944 + " .long 37b,100b\n"
4945 + " .long 99b,101b\n"
4947 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
4948 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4949 : "eax", "edx", "memory");
4952 @@ -336,6 +462,7 @@ __copy_user_zeroing_intel(void *to, cons
4955 __asm__ __volatile__(
4956 + " movw %w6, %%ds\n"
4958 "0: movl 32(%4), %%eax\n"
4960 @@ -344,36 +471,36 @@ __copy_user_zeroing_intel(void *to, cons
4962 "2: movl 0(%4), %%eax\n"
4963 "21: movl 4(%4), %%edx\n"
4964 - " movl %%eax, 0(%3)\n"
4965 - " movl %%edx, 4(%3)\n"
4966 + " movl %%eax, %%es:0(%3)\n"
4967 + " movl %%edx, %%es:4(%3)\n"
4968 "3: movl 8(%4), %%eax\n"
4969 "31: movl 12(%4),%%edx\n"
4970 - " movl %%eax, 8(%3)\n"
4971 - " movl %%edx, 12(%3)\n"
4972 + " movl %%eax, %%es:8(%3)\n"
4973 + " movl %%edx, %%es:12(%3)\n"
4974 "4: movl 16(%4), %%eax\n"
4975 "41: movl 20(%4), %%edx\n"
4976 - " movl %%eax, 16(%3)\n"
4977 - " movl %%edx, 20(%3)\n"
4978 + " movl %%eax, %%es:16(%3)\n"
4979 + " movl %%edx, %%es:20(%3)\n"
4980 "10: movl 24(%4), %%eax\n"
4981 "51: movl 28(%4), %%edx\n"
4982 - " movl %%eax, 24(%3)\n"
4983 - " movl %%edx, 28(%3)\n"
4984 + " movl %%eax, %%es:24(%3)\n"
4985 + " movl %%edx, %%es:28(%3)\n"
4986 "11: movl 32(%4), %%eax\n"
4987 "61: movl 36(%4), %%edx\n"
4988 - " movl %%eax, 32(%3)\n"
4989 - " movl %%edx, 36(%3)\n"
4990 + " movl %%eax, %%es:32(%3)\n"
4991 + " movl %%edx, %%es:36(%3)\n"
4992 "12: movl 40(%4), %%eax\n"
4993 "71: movl 44(%4), %%edx\n"
4994 - " movl %%eax, 40(%3)\n"
4995 - " movl %%edx, 44(%3)\n"
4996 + " movl %%eax, %%es:40(%3)\n"
4997 + " movl %%edx, %%es:44(%3)\n"
4998 "13: movl 48(%4), %%eax\n"
4999 "81: movl 52(%4), %%edx\n"
5000 - " movl %%eax, 48(%3)\n"
5001 - " movl %%edx, 52(%3)\n"
5002 + " movl %%eax, %%es:48(%3)\n"
5003 + " movl %%edx, %%es:52(%3)\n"
5004 "14: movl 56(%4), %%eax\n"
5005 "91: movl 60(%4), %%edx\n"
5006 - " movl %%eax, 56(%3)\n"
5007 - " movl %%edx, 60(%3)\n"
5008 + " movl %%eax, %%es:56(%3)\n"
5009 + " movl %%edx, %%es:60(%3)\n"
5013 @@ -387,6 +514,8 @@ __copy_user_zeroing_intel(void *to, cons
5019 ".section .fixup,\"ax\"\n"
5020 "9: lea 0(%%eax,%0,4),%0\n"
5022 @@ -421,7 +550,7 @@ __copy_user_zeroing_intel(void *to, cons
5025 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5026 - : "1"(to), "2"(from), "0"(size)
5027 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5028 : "eax", "edx", "memory");
5031 @@ -437,6 +566,7 @@ static unsigned long __copy_user_zeroing
5034 __asm__ __volatile__(
5035 + " movw %w6, %%ds\n"
5037 "0: movl 32(%4), %%eax\n"
5039 @@ -445,36 +575,36 @@ static unsigned long __copy_user_zeroing
5041 "2: movl 0(%4), %%eax\n"
5042 "21: movl 4(%4), %%edx\n"
5043 - " movnti %%eax, 0(%3)\n"
5044 - " movnti %%edx, 4(%3)\n"
5045 + " movnti %%eax, %%es:0(%3)\n"
5046 + " movnti %%edx, %%es:4(%3)\n"
5047 "3: movl 8(%4), %%eax\n"
5048 "31: movl 12(%4),%%edx\n"
5049 - " movnti %%eax, 8(%3)\n"
5050 - " movnti %%edx, 12(%3)\n"
5051 + " movnti %%eax, %%es:8(%3)\n"
5052 + " movnti %%edx, %%es:12(%3)\n"
5053 "4: movl 16(%4), %%eax\n"
5054 "41: movl 20(%4), %%edx\n"
5055 - " movnti %%eax, 16(%3)\n"
5056 - " movnti %%edx, 20(%3)\n"
5057 + " movnti %%eax, %%es:16(%3)\n"
5058 + " movnti %%edx, %%es:20(%3)\n"
5059 "10: movl 24(%4), %%eax\n"
5060 "51: movl 28(%4), %%edx\n"
5061 - " movnti %%eax, 24(%3)\n"
5062 - " movnti %%edx, 28(%3)\n"
5063 + " movnti %%eax, %%es:24(%3)\n"
5064 + " movnti %%edx, %%es:28(%3)\n"
5065 "11: movl 32(%4), %%eax\n"
5066 "61: movl 36(%4), %%edx\n"
5067 - " movnti %%eax, 32(%3)\n"
5068 - " movnti %%edx, 36(%3)\n"
5069 + " movnti %%eax, %%es:32(%3)\n"
5070 + " movnti %%edx, %%es:36(%3)\n"
5071 "12: movl 40(%4), %%eax\n"
5072 "71: movl 44(%4), %%edx\n"
5073 - " movnti %%eax, 40(%3)\n"
5074 - " movnti %%edx, 44(%3)\n"
5075 + " movnti %%eax, %%es:40(%3)\n"
5076 + " movnti %%edx, %%es:44(%3)\n"
5077 "13: movl 48(%4), %%eax\n"
5078 "81: movl 52(%4), %%edx\n"
5079 - " movnti %%eax, 48(%3)\n"
5080 - " movnti %%edx, 52(%3)\n"
5081 + " movnti %%eax, %%es:48(%3)\n"
5082 + " movnti %%edx, %%es:52(%3)\n"
5083 "14: movl 56(%4), %%eax\n"
5084 "91: movl 60(%4), %%edx\n"
5085 - " movnti %%eax, 56(%3)\n"
5086 - " movnti %%edx, 60(%3)\n"
5087 + " movnti %%eax, %%es:56(%3)\n"
5088 + " movnti %%edx, %%es:60(%3)\n"
5092 @@ -489,6 +619,8 @@ static unsigned long __copy_user_zeroing
5098 ".section .fixup,\"ax\"\n"
5099 "9: lea 0(%%eax,%0,4),%0\n"
5101 @@ -523,7 +655,7 @@ static unsigned long __copy_user_zeroing
5104 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5105 - : "1"(to), "2"(from), "0"(size)
5106 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5107 : "eax", "edx", "memory");
5110 @@ -534,6 +666,7 @@ static unsigned long __copy_user_intel_n
5113 __asm__ __volatile__(
5114 + " movw %w6, %%ds\n"
5116 "0: movl 32(%4), %%eax\n"
5118 @@ -542,36 +675,36 @@ static unsigned long __copy_user_intel_n
5120 "2: movl 0(%4), %%eax\n"
5121 "21: movl 4(%4), %%edx\n"
5122 - " movnti %%eax, 0(%3)\n"
5123 - " movnti %%edx, 4(%3)\n"
5124 + " movnti %%eax, %%es:0(%3)\n"
5125 + " movnti %%edx, %%es:4(%3)\n"
5126 "3: movl 8(%4), %%eax\n"
5127 "31: movl 12(%4),%%edx\n"
5128 - " movnti %%eax, 8(%3)\n"
5129 - " movnti %%edx, 12(%3)\n"
5130 + " movnti %%eax, %%es:8(%3)\n"
5131 + " movnti %%edx, %%es:12(%3)\n"
5132 "4: movl 16(%4), %%eax\n"
5133 "41: movl 20(%4), %%edx\n"
5134 - " movnti %%eax, 16(%3)\n"
5135 - " movnti %%edx, 20(%3)\n"
5136 + " movnti %%eax, %%es:16(%3)\n"
5137 + " movnti %%edx, %%es:20(%3)\n"
5138 "10: movl 24(%4), %%eax\n"
5139 "51: movl 28(%4), %%edx\n"
5140 - " movnti %%eax, 24(%3)\n"
5141 - " movnti %%edx, 28(%3)\n"
5142 + " movnti %%eax, %%es:24(%3)\n"
5143 + " movnti %%edx, %%es:28(%3)\n"
5144 "11: movl 32(%4), %%eax\n"
5145 "61: movl 36(%4), %%edx\n"
5146 - " movnti %%eax, 32(%3)\n"
5147 - " movnti %%edx, 36(%3)\n"
5148 + " movnti %%eax, %%es:32(%3)\n"
5149 + " movnti %%edx, %%es:36(%3)\n"
5150 "12: movl 40(%4), %%eax\n"
5151 "71: movl 44(%4), %%edx\n"
5152 - " movnti %%eax, 40(%3)\n"
5153 - " movnti %%edx, 44(%3)\n"
5154 + " movnti %%eax, %%es:40(%3)\n"
5155 + " movnti %%edx, %%es:44(%3)\n"
5156 "13: movl 48(%4), %%eax\n"
5157 "81: movl 52(%4), %%edx\n"
5158 - " movnti %%eax, 48(%3)\n"
5159 - " movnti %%edx, 52(%3)\n"
5160 + " movnti %%eax, %%es:48(%3)\n"
5161 + " movnti %%edx, %%es:52(%3)\n"
5162 "14: movl 56(%4), %%eax\n"
5163 "91: movl 60(%4), %%edx\n"
5164 - " movnti %%eax, 56(%3)\n"
5165 - " movnti %%edx, 60(%3)\n"
5166 + " movnti %%eax, %%es:56(%3)\n"
5167 + " movnti %%edx, %%es:60(%3)\n"
5171 @@ -586,6 +719,8 @@ static unsigned long __copy_user_intel_n
5177 ".section .fixup,\"ax\"\n"
5178 "9: lea 0(%%eax,%0,4),%0\n"
5180 @@ -614,7 +749,7 @@ static unsigned long __copy_user_intel_n
5183 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5184 - : "1"(to), "2"(from), "0"(size)
5185 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5186 : "eax", "edx", "memory");
5189 @@ -627,90 +762,146 @@ static unsigned long __copy_user_intel_n
5191 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
5192 unsigned long size);
5193 -unsigned long __copy_user_intel(void __user *to, const void *from,
5194 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
5195 + unsigned long size);
5196 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
5197 unsigned long size);
5198 unsigned long __copy_user_zeroing_intel_nocache(void *to,
5199 const void __user *from, unsigned long size);
5200 #endif /* CONFIG_X86_INTEL_USERCOPY */
5202 /* Generic arbitrary sized copy. */
5203 -#define __copy_user(to,from,size) \
5205 - int __d0, __d1, __d2; \
5206 - __asm__ __volatile__( \
5213 - "4: rep; movsb\n" \
5217 - " .align 2,0x90\n" \
5218 - "0: rep; movsl\n" \
5220 - "1: rep; movsb\n" \
5222 - ".section .fixup,\"ax\"\n" \
5223 - "5: addl %3,%0\n" \
5225 - "3: lea 0(%3,%0,4),%0\n" \
5228 - ".section __ex_table,\"a\"\n" \
5230 - " .long 4b,5b\n" \
5231 - " .long 0b,3b\n" \
5232 - " .long 1b,2b\n" \
5234 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
5235 - : "3"(size), "0"(size), "1"(to), "2"(from) \
5239 -#define __copy_user_zeroing(to,from,size) \
5241 - int __d0, __d1, __d2; \
5242 - __asm__ __volatile__( \
5249 - "4: rep; movsb\n" \
5253 - " .align 2,0x90\n" \
5254 - "0: rep; movsl\n" \
5256 - "1: rep; movsb\n" \
5258 - ".section .fixup,\"ax\"\n" \
5259 - "5: addl %3,%0\n" \
5261 - "3: lea 0(%3,%0,4),%0\n" \
5263 - " pushl %%eax\n" \
5264 - " xorl %%eax,%%eax\n" \
5270 - ".section __ex_table,\"a\"\n" \
5272 - " .long 4b,5b\n" \
5273 - " .long 0b,3b\n" \
5274 - " .long 1b,6b\n" \
5276 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
5277 - : "3"(size), "0"(size), "1"(to), "2"(from) \
5280 +static unsigned long
5281 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
5283 + int __d0, __d1, __d2;
5285 + __asm__ __volatile__(
5286 + " movw %w8,%%es\n"
5297 + " .align 2,0x90\n"
5304 + ".section .fixup,\"ax\"\n"
5307 + "3: lea 0(%3,%0,4),%0\n"
5310 + ".section __ex_table,\"a\"\n"
5316 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5317 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5322 +static unsigned long
5323 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
5325 + int __d0, __d1, __d2;
5327 + __asm__ __volatile__(
5328 + " movw %w8,%%ds\n"
5339 + " .align 2,0x90\n"
5346 + ".section .fixup,\"ax\"\n"
5349 + "3: lea 0(%3,%0,4),%0\n"
5352 + ".section __ex_table,\"a\"\n"
5358 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5359 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5364 +static unsigned long
5365 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
5367 + int __d0, __d1, __d2;
5369 + __asm__ __volatile__(
5370 + " movw %w8,%%ds\n"
5381 + " .align 2,0x90\n"
5388 + ".section .fixup,\"ax\"\n"
5391 + "3: lea 0(%3,%0,4),%0\n"
5394 + " xorl %%eax,%%eax\n"
5400 + ".section __ex_table,\"a\"\n"
5406 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5407 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5412 unsigned long __copy_to_user_ll(void __user *to, const void *from,
5414 @@ -766,9 +957,9 @@ survive:
5417 if (movsl_is_ok(to, from, n))
5418 - __copy_user(to, from, n);
5419 + n = __generic_copy_to_user(to, from, n);
5421 - n = __copy_user_intel(to, from, n);
5422 + n = __generic_copy_to_user_intel(to, from, n);
5425 EXPORT_SYMBOL(__copy_to_user_ll);
5426 @@ -778,7 +969,7 @@ unsigned long __copy_from_user_ll(void *
5428 BUG_ON((long)n < 0);
5429 if (movsl_is_ok(to, from, n))
5430 - __copy_user_zeroing(to, from, n);
5431 + n = __copy_user_zeroing(to, from, n);
5433 n = __copy_user_zeroing_intel(to, from, n);
5435 @@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
5437 BUG_ON((long)n < 0);
5438 if (movsl_is_ok(to, from, n))
5439 - __copy_user(to, from, n);
5440 + n = __generic_copy_from_user(to, from, n);
5442 - n = __copy_user_intel((void __user *)to,
5443 - (const void *)from, n);
5444 + n = __generic_copy_from_user_intel(to, from, n);
5447 EXPORT_SYMBOL(__copy_from_user_ll_nozero);
5448 @@ -804,11 +994,11 @@ unsigned long __copy_from_user_ll_nocach
5449 BUG_ON((long)n < 0);
5450 #ifdef CONFIG_X86_INTEL_USERCOPY
5451 if ( n > 64 && cpu_has_xmm2)
5452 - n = __copy_user_zeroing_intel_nocache(to, from, n);
5453 + n = __copy_user_zeroing_intel_nocache(to, from, n);
5455 - __copy_user_zeroing(to, from, n);
5456 + n = __copy_user_zeroing(to, from, n);
5458 - __copy_user_zeroing(to, from, n);
5459 + n = __copy_user_zeroing(to, from, n);
5463 @@ -819,11 +1009,11 @@ unsigned long __copy_from_user_ll_nocach
5464 BUG_ON((long)n < 0);
5465 #ifdef CONFIG_X86_INTEL_USERCOPY
5466 if ( n > 64 && cpu_has_xmm2)
5467 - n = __copy_user_intel_nocache(to, from, n);
5468 + n = __copy_user_intel_nocache(to, from, n);
5470 - __copy_user(to, from, n);
5471 + n = __generic_copy_from_user(to, from, n);
5473 - __copy_user(to, from, n);
5474 + n = __generic_copy_from_user(to, from, n);
5478 @@ -878,3 +1068,31 @@ copy_from_user(void *to, const void __us
5481 EXPORT_SYMBOL(copy_from_user);
5483 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5484 +void __set_fs(mm_segment_t x, int cpu)
5486 + unsigned long limit = x.seg;
5489 + current_thread_info()->addr_limit = x;
5490 + if (likely(limit))
5493 + pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
5494 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
5497 +void set_fs(mm_segment_t x)
5499 + __set_fs(x, get_cpu());
5500 + put_cpu_no_resched();
5503 +void set_fs(mm_segment_t x)
5505 + current_thread_info()->addr_limit = x;
5509 +EXPORT_SYMBOL(set_fs);
5510 diff -urNp linux-2.6.20.3/arch/i386/mach-default/setup.c linux-2.6.20.3/arch/i386/mach-default/setup.c
5511 --- linux-2.6.20.3/arch/i386/mach-default/setup.c 2007-03-13 14:27:08.000000000 -0400
5512 +++ linux-2.6.20.3/arch/i386/mach-default/setup.c 2007-03-23 08:10:06.000000000 -0400
5513 @@ -35,7 +35,7 @@ void __init pre_intr_init_hook(void)
5515 * IRQ2 is cascade interrupt to second interrupt controller
5517 -static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
5518 +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL};
5521 * intr_init_hook - post gate setup interrupt initialisation
5522 @@ -79,7 +79,7 @@ void __init trap_init_hook(void)
5526 -static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL};
5527 +static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL, 0, NULL};
5530 * time_init_hook - do any specific initialisations for the system timer.
5531 diff -urNp linux-2.6.20.3/arch/i386/mach-voyager/voyager_smp.c linux-2.6.20.3/arch/i386/mach-voyager/voyager_smp.c
5532 --- linux-2.6.20.3/arch/i386/mach-voyager/voyager_smp.c 2007-03-13 14:27:08.000000000 -0400
5533 +++ linux-2.6.20.3/arch/i386/mach-voyager/voyager_smp.c 2007-03-23 08:10:06.000000000 -0400
5534 @@ -583,11 +583,7 @@ do_boot_cpu(__u8 cpu)
5535 /* Pre-allocate and initialize the CPU's GDT and PDA so it
5536 doesn't have to do any memory allocation during the
5537 delicate CPU-bringup phase. */
5538 - if (!init_gdt(cpu, idle)) {
5539 - printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu);
5543 + init_gdt(cpu, idle);
5547 @@ -1322,7 +1318,7 @@ smp_local_timer_interrupt(void)
5548 per_cpu(prof_counter, cpu);
5551 - update_process_times(user_mode_vm(get_irq_regs()));
5552 + update_process_times(user_mode(get_irq_regs()));
5555 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
5556 diff -urNp linux-2.6.20.3/arch/i386/mm/boot_ioremap.c linux-2.6.20.3/arch/i386/mm/boot_ioremap.c
5557 --- linux-2.6.20.3/arch/i386/mm/boot_ioremap.c 2007-03-13 14:27:08.000000000 -0400
5558 +++ linux-2.6.20.3/arch/i386/mm/boot_ioremap.c 2007-03-23 08:10:06.000000000 -0400
5560 * Written by Dave Hansen <haveblue@us.ibm.com>
5565 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
5566 - * keeps that from happenning. If anyone has a better way, I'm listening.
5568 - * boot_pte_t is defined only if this all works correctly
5571 -#undef CONFIG_X86_PAE
5572 #undef CONFIG_PARAVIRT
5573 #include <asm/page.h>
5574 #include <asm/pgtable.h>
5576 #include <linux/init.h>
5577 #include <linux/stddef.h>
5580 - * I'm cheating here. It is known that the two boot PTE pages are
5581 - * allocated next to each other. I'm pretending that they're just
5585 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
5587 -static unsigned long boot_pte_index(unsigned long vaddr)
5589 - return __pa(vaddr) >> PAGE_SHIFT;
5592 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
5594 - boot_pte_t* boot_pg = (boot_pte_t*)pg0;
5595 - return &boot_pg[boot_pte_index((unsigned long)address)];
5599 * This is only for a caller who is clever enough to page-align
5600 * phys_addr and virtual_source, and who also has a preference
5601 * about which virtual address from which to steal ptes
5603 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
5604 - void* virtual_source)
5605 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
5606 + char* virtual_source)
5610 - char *vaddr = virtual_source;
5616 + unsigned long vaddr = (unsigned long)virtual_source;
5618 + pgd = pgd_offset_k(vaddr);
5619 + pud = pud_offset(pgd, vaddr);
5620 + pmd = pmd_offset(pud, vaddr);
5621 + pte = pte_offset_kernel(pmd, vaddr);
5623 - pte = boot_vaddr_to_pte(virtual_source);
5624 for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
5625 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
5626 - __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
5627 + __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
5631 diff -urNp linux-2.6.20.3/arch/i386/mm/extable.c linux-2.6.20.3/arch/i386/mm/extable.c
5632 --- linux-2.6.20.3/arch/i386/mm/extable.c 2007-03-13 14:27:08.000000000 -0400
5633 +++ linux-2.6.20.3/arch/i386/mm/extable.c 2007-03-23 08:10:06.000000000 -0400
5634 @@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs
5635 const struct exception_table_entry *fixup;
5637 #ifdef CONFIG_PNPBIOS
5638 - if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
5639 + if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
5641 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
5642 extern u32 pnp_bios_is_utter_crap;
5643 diff -urNp linux-2.6.20.3/arch/i386/mm/fault.c linux-2.6.20.3/arch/i386/mm/fault.c
5644 --- linux-2.6.20.3/arch/i386/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
5645 +++ linux-2.6.20.3/arch/i386/mm/fault.c 2007-03-23 08:32:22.000000000 -0400
5647 #include <linux/kprobes.h>
5648 #include <linux/uaccess.h>
5649 #include <linux/suspend.h>
5650 +#include <linux/unistd.h>
5651 +#include <linux/compiler.h>
5652 +#include <linux/binfmts.h>
5654 #include <asm/system.h>
5655 #include <asm/desc.h>
5656 #include <asm/kdebug.h>
5657 #include <asm/segment.h>
5658 +#include <asm/tlbflush.h>
5660 extern void die(const char *,struct pt_regs *,long);
5662 @@ -104,7 +108,8 @@ static inline unsigned long get_segment_
5664 unsigned long eip = regs->eip;
5665 unsigned seg = regs->xcs & 0xffff;
5666 - u32 seg_ar, seg_limit, base, *desc;
5667 + u32 seg_ar, seg_limit, base;
5668 + struct desc_struct *desc;
5670 /* Unlikely, but must come before segment checks. */
5671 if (unlikely(regs->eflags & VM_MASK)) {
5672 @@ -118,7 +123,7 @@ static inline unsigned long get_segment_
5674 /* By far the most common cases. */
5675 if (likely(SEGMENT_IS_FLAT_CODE(seg)))
5677 + return eip + (seg == __KERNEL_CS ? __KERNEL_TEXT_OFFSET : 0);
5679 /* Check the segment exists, is within the current LDT/GDT size,
5680 that kernel/user (ring 0..3) has the appropriate privilege,
5681 @@ -136,16 +140,14 @@ static inline unsigned long get_segment_
5683 /* Must lock the LDT while reading it. */
5684 down(¤t->mm->context.sem);
5685 - desc = current->mm->context.ldt;
5686 - desc = (void *)desc + (seg & ~7);
5687 + desc = ¤t->mm->context.ldt[seg >> 3];
5689 /* Must disable preemption while reading the GDT. */
5690 - desc = (u32 *)get_cpu_gdt_table(get_cpu());
5691 - desc = (void *)desc + (seg & ~7);
5692 + desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
5695 /* Decode the code segment base from the descriptor */
5696 - base = get_desc_base((unsigned long *)desc);
5697 + base = get_desc_base(desc);
5700 up(¤t->mm->context.sem);
5701 @@ -246,6 +248,30 @@ static noinline void force_sig_info_faul
5703 fastcall void do_invalid_op(struct pt_regs *, unsigned long);
5705 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5706 +static int pax_handle_fetch_fault(struct pt_regs *regs);
5709 +#ifdef CONFIG_PAX_PAGEEXEC
5710 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
5716 + pgd = pgd_offset(mm, address);
5717 + if (!pgd_present(*pgd))
5719 + pud = pud_offset(pgd, address);
5720 + if (!pud_present(*pud))
5722 + pmd = pmd_offset(pud, address);
5723 + if (!pmd_present(*pmd))
5729 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
5731 unsigned index = pgd_index(address);
5732 @@ -326,14 +352,20 @@ fastcall void __kprobes do_page_fault(st
5733 struct task_struct *tsk;
5734 struct mm_struct *mm;
5735 struct vm_area_struct * vma;
5736 - unsigned long address;
5737 - unsigned long page;
5740 +#ifdef CONFIG_PAX_PAGEEXEC
5744 + unsigned char pte_mask;
5747 /* get the address */
5748 - address = read_cr2();
5749 + const unsigned long address = read_cr2();
5754 si_code = SEGV_MAPERR;
5756 @@ -372,14 +404,12 @@ fastcall void __kprobes do_page_fault(st
5757 if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
5763 * If we're in an interrupt, have no user context or are running in an
5764 * atomic region then we must not take the fault..
5766 if (in_atomic() || !mm)
5767 - goto bad_area_nosemaphore;
5768 + goto bad_area_nopax;
5770 /* When running in the kernel we expect faults to occur only to
5771 * addresses in user space. All other faults represent errors in the
5772 @@ -399,10 +429,101 @@ fastcall void __kprobes do_page_fault(st
5773 if (!down_read_trylock(&mm->mmap_sem)) {
5774 if ((error_code & 4) == 0 &&
5775 !search_exception_tables(regs->eip))
5776 - goto bad_area_nosemaphore;
5777 + goto bad_area_nopax;
5778 down_read(&mm->mmap_sem);
5781 +#ifdef CONFIG_PAX_PAGEEXEC
5782 + if (unlikely((error_code & 5) != 5 ||
5783 + (regs->eflags & X86_EFLAGS_VM) ||
5784 + !(mm->pax_flags & MF_PAX_PAGEEXEC)))
5785 + goto not_pax_fault;
5787 + /* PaX: it's our fault, let's handle it if we can */
5789 + /* PaX: take a look at read faults before acquiring any locks */
5790 + if (unlikely(!(error_code & 2) && (regs->eip == address))) {
5791 + /* instruction fetch attempt from a protected page in user mode */
5792 + up_read(&mm->mmap_sem);
5794 +#ifdef CONFIG_PAX_EMUTRAMP
5795 + switch (pax_handle_fetch_fault(regs)) {
5801 + pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
5805 + pmd = pax_get_pmd(mm, address);
5806 + if (unlikely(!pmd))
5807 + goto not_pax_fault;
5809 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
5810 + if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
5811 + pte_unmap_unlock(pte, ptl);
5812 + goto not_pax_fault;
5815 + if (unlikely((error_code & 2) && !pte_write(*pte))) {
5816 + /* write attempt to a protected page in user mode */
5817 + pte_unmap_unlock(pte, ptl);
5818 + goto not_pax_fault;
5822 + if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
5824 + if (likely(address > get_limit(regs->xcs)))
5827 + set_pte(pte, pte_mkread(*pte));
5828 + __flush_tlb_one(address);
5829 + pte_unmap_unlock(pte, ptl);
5830 + up_read(&mm->mmap_sem);
5834 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
5837 + * PaX: fill DTLB with user rights and retry
5839 + __asm__ __volatile__ (
5841 + "orb %2,%%ss:(%1)\n"
5842 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
5844 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
5845 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
5846 + * page fault when examined during a TLB load attempt. this is true not only
5847 + * for PTEs holding a non-present entry but also present entries that will
5848 + * raise a page fault (such as those set up by PaX, or the copy-on-write
5849 + * mechanism). in effect it means that we do *not* need to flush the TLBs
5850 + * for our target pages since their PTEs are simply not in the TLBs at all.
5852 + * the best thing in omitting it is that we gain around 15-20% speed in the
5853 + * fast path of the page fault handler and can get rid of tracing since we
5854 + * can no longer flush unintended entries.
5859 + "xorb %3,%%ss:(%1)\n"
5863 + : "q" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
5864 + : "memory", "cc");
5865 + pte_unmap_unlock(pte, ptl);
5866 + up_read(&mm->mmap_sem);
5872 vma = find_vma(mm, address);
5875 @@ -420,6 +541,12 @@ fastcall void __kprobes do_page_fault(st
5876 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
5880 +#ifdef CONFIG_PAX_SEGMEXEC
5881 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
5885 if (expand_stack(vma, address))
5888 @@ -484,6 +611,36 @@ bad_area:
5889 up_read(&mm->mmap_sem);
5891 bad_area_nosemaphore:
5893 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5894 + if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
5896 +#ifdef CONFIG_PAX_PAGEEXEC
5897 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
5898 + pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
5903 +#ifdef CONFIG_PAX_SEGMEXEC
5904 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
5906 +#ifdef CONFIG_PAX_EMUTRAMP
5907 + switch (pax_handle_fetch_fault(regs)) {
5913 + pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
5922 /* User mode accesses just cause a SIGSEGV */
5923 if (error_code & 4) {
5925 @@ -508,7 +666,7 @@ bad_area_nosemaphore:
5926 if (boot_cpu_data.f00f_bug) {
5929 - nr = (address - idt_descr.address) >> 3;
5930 + nr = (address - (unsigned long)idt_descr.address) >> 3;
5933 do_invalid_op(regs, 0);
5934 @@ -551,6 +709,22 @@ no_context:
5935 if (address < PAGE_SIZE)
5936 printk(KERN_ALERT "BUG: unable to handle kernel NULL "
5937 "pointer dereference");
5939 +#ifdef CONFIG_PAX_KERNEXEC
5940 +#ifdef CONFIG_MODULES
5941 + else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END) {
5943 + else if (init_mm.start_code <= address && address < init_mm.end_code) {
5945 + if (tsk->signal->curr_ip)
5946 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
5947 + NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
5949 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
5950 + tsk->comm, tsk->pid, tsk->uid, tsk->euid);
5955 printk(KERN_ALERT "BUG: unable to handle kernel paging"
5957 @@ -558,24 +732,34 @@ no_context:
5958 printk(KERN_ALERT " printing eip:\n");
5959 printk("%08lx\n", regs->eip);
5961 - page = read_cr3();
5962 - page = ((unsigned long *) __va(page))[address >> 22];
5963 - if (oops_may_print())
5964 - printk(KERN_ALERT "*pde = %08lx\n", page);
5966 - * We must not directly access the pte in the highpte
5967 - * case, the page table might be allocated in highmem.
5968 - * And lets rather not kmap-atomic the pte, just in case
5969 - * it's allocated already.
5972 + if (oops_may_print()) {
5973 + unsigned long index = pgd_index(address);
5979 + pgd = index + (pgd_t *)__va(read_cr3());
5980 + printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
5981 + if (pgd_present(*pgd)) {
5982 + pud = pud_offset(pgd, address);
5983 + pmd = pmd_offset(pud, address);
5984 + printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
5986 + * We must not directly access the pte in the highpte
5987 + * case, the page table might be allocated in highmem.
5988 + * And lets rather not kmap-atomic the pte, just in case
5989 + * it's allocated already.
5991 #ifndef CONFIG_HIGHPTE
5992 - if ((page & 1) && oops_may_print()) {
5993 - page &= PAGE_MASK;
5994 - address &= 0x003ff000;
5995 - page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
5996 - printk(KERN_ALERT "*pte = %08lx\n", page);
5998 + if (pmd_present(*pmd) && !pmd_large(*pmd)) {
5999 + pte = pte_offset_kernel(pmd, address);
6000 + printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
6005 tsk->thread.cr2 = address;
6006 tsk->thread.trap_no = 14;
6007 tsk->thread.error_code = error_code;
6008 @@ -653,3 +837,101 @@ void vmalloc_sync_all(void)
6013 +#ifdef CONFIG_PAX_EMUTRAMP
6015 + * PaX: decide what to do with offenders (regs->eip = fault address)
6017 + * returns 1 when task should be killed
6018 + * 2 when gcc trampoline was detected
6020 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6023 + static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
6026 + if (regs->eflags & X86_EFLAGS_VM)
6029 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
6032 + do { /* PaX: gcc trampoline emulation #1 */
6033 + unsigned char mov1, mov2;
6034 + unsigned short jmp;
6035 + unsigned long addr1, addr2;
6037 + err = get_user(mov1, (unsigned char __user *)regs->eip);
6038 + err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
6039 + err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
6040 + err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
6041 + err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
6046 + if ((mov1 & 0xF8) == 0xB8 &&
6047 + (mov2 & 0xF8) == 0xB8 &&
6048 + (mov1 & 0x07) != (mov2 & 0x07) &&
6049 + (jmp & 0xF8FF) == 0xE0FF &&
6050 + (mov2 & 0x07) == ((jmp>>8) & 0x07))
6052 + ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
6053 + ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
6054 + regs->eip = addr2;
6059 + do { /* PaX: gcc trampoline emulation #2 */
6060 + unsigned char mov, jmp;
6061 + unsigned long addr1, addr2;
6063 + err = get_user(mov, (unsigned char __user *)regs->eip);
6064 + err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
6065 + err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
6066 + err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
6071 + if ((mov & 0xF8) == 0xB8 &&
6074 + ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
6075 + regs->eip += addr2 + 10;
6080 + return 1; /* PaX in action */
6084 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6085 +void pax_report_insns(void *pc, void *sp)
6089 + printk(KERN_ERR "PAX: bytes at PC: ");
6090 + for (i = 0; i < 20; i++) {
6092 + if (get_user(c, (unsigned char __user *)pc+i))
6095 + printk("%02x ", c);
6099 + printk(KERN_ERR "PAX: bytes at SP-4: ");
6100 + for (i = -1; i < 20; i++) {
6102 + if (get_user(c, (unsigned long __user *)sp+i))
6103 + printk("???????? ");
6105 + printk("%08lx ", c);
6110 diff -urNp linux-2.6.20.3/arch/i386/mm/hugetlbpage.c linux-2.6.20.3/arch/i386/mm/hugetlbpage.c
6111 --- linux-2.6.20.3/arch/i386/mm/hugetlbpage.c 2007-03-13 14:27:08.000000000 -0400
6112 +++ linux-2.6.20.3/arch/i386/mm/hugetlbpage.c 2007-03-23 08:10:06.000000000 -0400
6113 @@ -230,7 +230,12 @@ static unsigned long hugetlb_get_unmappe
6115 struct mm_struct *mm = current->mm;
6116 struct vm_area_struct *vma;
6117 - unsigned long start_addr;
6118 + unsigned long start_addr, task_size = TASK_SIZE;
6120 +#ifdef CONFIG_PAX_SEGMEXEC
6121 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6122 + task_size = SEGMEXEC_TASK_SIZE;
6125 if (len > mm->cached_hole_size) {
6126 start_addr = mm->free_area_cache;
6127 @@ -244,7 +249,7 @@ full_search:
6129 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6130 /* At this point: (!vma || addr < vma->vm_end). */
6131 - if (TASK_SIZE - len < addr) {
6132 + if (task_size - len < addr) {
6134 * Start a new search - just in case we missed
6136 @@ -272,9 +277,8 @@ static unsigned long hugetlb_get_unmappe
6138 struct mm_struct *mm = current->mm;
6139 struct vm_area_struct *vma, *prev_vma;
6140 - unsigned long base = mm->mmap_base, addr = addr0;
6141 + unsigned long base = mm->mmap_base, addr;
6142 unsigned long largest_hole = mm->cached_hole_size;
6143 - int first_time = 1;
6145 /* don't allow allocations above current base */
6146 if (mm->free_area_cache > base)
6147 @@ -284,7 +288,7 @@ static unsigned long hugetlb_get_unmappe
6149 mm->free_area_cache = base;
6153 /* make sure it can fit in the remaining address space */
6154 if (mm->free_area_cache < len)
6156 @@ -326,16 +330,6 @@ try_again:
6160 - * if hint left us with no space for the requested
6161 - * mapping then try again:
6164 - mm->free_area_cache = base;
6170 * A failed mmap() very likely causes application failure,
6171 * so fall back to the bottom-up function here. This scenario
6172 * can happen with large stack limits and large mmap()
6173 @@ -361,16 +355,23 @@ hugetlb_get_unmapped_area(struct file *f
6175 struct mm_struct *mm = current->mm;
6176 struct vm_area_struct *vma;
6177 + unsigned long task_size = TASK_SIZE;
6179 if (len & ~HPAGE_MASK)
6181 - if (len > TASK_SIZE)
6183 +#ifdef CONFIG_PAX_SEGMEXEC
6184 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6185 + task_size = SEGMEXEC_TASK_SIZE;
6188 + if (len > task_size || addr > task_size - len)
6192 addr = ALIGN(addr, HPAGE_SIZE);
6193 vma = find_vma(mm, addr);
6194 - if (TASK_SIZE - len >= addr &&
6195 + if (task_size - len >= addr &&
6196 (!vma || addr + len <= vma->vm_start))
6199 diff -urNp linux-2.6.20.3/arch/i386/mm/init.c linux-2.6.20.3/arch/i386/mm/init.c
6200 --- linux-2.6.20.3/arch/i386/mm/init.c 2007-03-13 14:27:08.000000000 -0400
6201 +++ linux-2.6.20.3/arch/i386/mm/init.c 2007-03-23 08:10:06.000000000 -0400
6203 #include <asm/tlb.h>
6204 #include <asm/tlbflush.h>
6205 #include <asm/sections.h>
6206 +#include <asm/desc.h>
6208 unsigned int __VMALLOC_RESERVE = 128 << 20;
6210 @@ -51,30 +52,6 @@ unsigned long highstart_pfn, highend_pfn
6211 static int noinline do_test_wp_bit(void);
6214 - * Creates a middle page table and puts a pointer to it in the
6215 - * given global directory entry. This only returns the gd entry
6216 - * in non-PAE compilation mode, since the middle layer is folded.
6218 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
6223 -#ifdef CONFIG_X86_PAE
6224 - pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
6225 - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
6226 - pud = pud_offset(pgd, 0);
6227 - if (pmd_table != pmd_offset(pud, 0))
6230 - pud = pud_offset(pgd, 0);
6231 - pmd_table = pmd_offset(pud, 0);
6238 * Create a page table and place a pointer to it in a middle page
6241 @@ -82,7 +59,11 @@ static pte_t * __init one_page_table_ini
6243 if (pmd_none(*pmd)) {
6244 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
6245 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6246 + set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
6248 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
6250 if (page_table != pte_offset_kernel(pmd, 0))
6253 @@ -117,8 +98,6 @@ static void __init page_table_range_init
6254 pgd = pgd_base + pgd_idx;
6256 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
6257 - if (pgd_none(*pgd))
6258 - one_md_table_init(pgd);
6259 pud = pud_offset(pgd, vaddr);
6260 pmd = pmd_offset(pud, vaddr);
6261 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
6262 @@ -131,11 +110,22 @@ static void __init page_table_range_init
6266 -static inline int is_kernel_text(unsigned long addr)
6267 +static inline int is_kernel_text(unsigned long start, unsigned long end)
6269 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
6272 + unsigned long etext;
6274 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
6275 + etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
6277 + etext = (unsigned long)&_etext;
6280 + if ((start > etext + __KERNEL_TEXT_OFFSET ||
6281 + end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
6282 + (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
6283 + end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
6289 @@ -147,26 +137,24 @@ static void __init kernel_physical_mappi
6296 - int pgd_idx, pmd_idx, pte_ofs;
6297 + unsigned int pgd_idx, pmd_idx, pte_ofs;
6299 pgd_idx = pgd_index(PAGE_OFFSET);
6300 pgd = pgd_base + pgd_idx;
6303 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
6304 - pmd = one_md_table_init(pgd);
6305 - if (pfn >= max_low_pfn)
6307 + for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
6308 + pud = pud_offset(pgd, 0);
6309 + pmd = pmd_offset(pud, 0);
6310 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
6311 - unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
6312 + unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
6314 /* Map with big pages if possible, otherwise create normal page tables. */
6316 - unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
6318 - if (is_kernel_text(address) || is_kernel_text(address2))
6319 + if (is_kernel_text(address, address + PMD_SIZE))
6320 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
6322 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
6323 @@ -175,7 +163,7 @@ static void __init kernel_physical_mappi
6324 pte = one_page_table_init(pmd);
6326 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
6327 - if (is_kernel_text(address))
6328 + if (is_kernel_text(address, address + PAGE_SIZE))
6329 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
6331 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
6332 @@ -340,13 +328,6 @@ static void __init pagetable_init (void)
6333 unsigned long vaddr;
6334 pgd_t *pgd_base = swapper_pg_dir;
6336 -#ifdef CONFIG_X86_PAE
6338 - /* Init entries of the first-level page table to the zero page */
6339 - for (i = 0; i < PTRS_PER_PGD; i++)
6340 - set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
6343 /* Enable PSE if available */
6345 set_in_cr4(X86_CR4_PSE);
6346 @@ -370,17 +351,6 @@ static void __init pagetable_init (void)
6347 page_table_range_init(vaddr, 0, pgd_base);
6349 permanent_kmaps_init(pgd_base);
6351 -#ifdef CONFIG_X86_PAE
6353 - * Add low memory identity-mappings - SMP needs it when
6354 - * starting up on an AP from real-mode. In the non-PAE
6355 - * case we already have these mappings through head.S.
6356 - * All user-space mappings are explicitly cleared after
6359 - set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
6363 #if defined(CONFIG_SUSPEND_SHARED) || defined(CONFIG_ACPI_SLEEP)
6364 @@ -388,12 +358,12 @@ static void __init pagetable_init (void)
6365 * Swap suspend & friends need this for resume because things like the intel-agp
6366 * driver might have split up a kernel 4MB mapping.
6368 -char __nosavedata swsusp_pg_dir[PAGE_SIZE]
6369 +pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
6370 __attribute__ ((aligned (PAGE_SIZE)));
6372 static inline void save_pg_dir(void)
6374 - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
6375 + clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
6378 static inline void save_pg_dir(void)
6379 @@ -422,7 +392,6 @@ void zap_low_mappings (void)
6383 -static int disable_nx __initdata = 0;
6384 u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
6387 @@ -436,13 +405,10 @@ u64 __supported_pte_mask __read_mostly =
6388 static int __init noexec_setup(char *str)
6390 if (!str || !strcmp(str, "on")) {
6392 - __supported_pte_mask |= _PAGE_NX;
6397 } else if (!strcmp(str,"off")) {
6399 - __supported_pte_mask &= ~_PAGE_NX;
6404 @@ -455,17 +421,13 @@ int nx_enabled = 0;
6406 static void __init set_nx(void)
6408 - unsigned int v[4], l, h;
6409 + if (!nx_enabled && cpu_has_nx) {
6412 - if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
6413 - cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
6414 - if ((v[3] & (1 << 20)) && !disable_nx) {
6415 - rdmsr(MSR_EFER, l, h);
6417 - wrmsr(MSR_EFER, l, h);
6419 - __supported_pte_mask |= _PAGE_NX;
6421 + __supported_pte_mask &= ~_PAGE_NX;
6422 + rdmsr(MSR_EFER, l, h);
6424 + wrmsr(MSR_EFER, l, h);
6428 @@ -518,14 +480,6 @@ void __init paging_init(void)
6430 load_cr3(swapper_pg_dir);
6432 -#ifdef CONFIG_X86_PAE
6434 - * We will bail out later - printk doesn't work right now so
6435 - * the user would just see a hanging kernel.
6438 - set_in_cr4(X86_CR4_PAE);
6443 @@ -596,7 +550,7 @@ void __init mem_init(void)
6444 set_highmem_pages_init(bad_ppro);
6446 codesize = (unsigned long) &_etext - (unsigned long) &_text;
6447 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
6448 + datasize = (unsigned long) &_edata - (unsigned long) &_data;
6449 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
6451 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
6452 @@ -641,10 +595,10 @@ void __init mem_init(void)
6453 (unsigned long)&__init_begin, (unsigned long)&__init_end,
6454 ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
6456 - (unsigned long)&_etext, (unsigned long)&_edata,
6457 - ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
6458 + (unsigned long)&_data, (unsigned long)&_edata,
6459 + ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
6461 - (unsigned long)&_text, (unsigned long)&_etext,
6462 + (unsigned long)&_text + __KERNEL_TEXT_OFFSET, (unsigned long)&_etext + __KERNEL_TEXT_OFFSET,
6463 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
6465 #ifdef CONFIG_HIGHMEM
6466 @@ -655,10 +609,6 @@ void __init mem_init(void)
6467 BUG_ON((unsigned long)high_memory > VMALLOC_START);
6468 #endif /* double-sanity-check paranoia */
6470 -#ifdef CONFIG_X86_PAE
6472 - panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
6474 if (boot_cpu_data.wp_works_ok < 0)
6477 @@ -781,6 +731,38 @@ void free_init_pages(char *what, unsigne
6479 void free_initmem(void)
6482 +#ifdef CONFIG_PAX_KERNEXEC
6483 + /* PaX: limit KERNEL_CS to actual size */
6484 + unsigned long addr, limit;
6491 +#ifdef CONFIG_MODULES
6492 + limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
6494 + limit = (unsigned long)&_etext;
6496 + limit = (limit - 1UL) >> PAGE_SHIFT;
6498 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
6499 + pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
6500 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b);
6503 + /* PaX: make KERNEL_CS read-only */
6504 + for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
6505 + pgd = pgd_offset_k(addr);
6506 + pud = pud_offset(pgd, addr);
6507 + pmd = pmd_offset(pud, addr);
6508 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
6513 free_init_pages("unused kernel memory",
6514 (unsigned long)(&__init_begin),
6515 (unsigned long)(&__init_end));
6516 diff -urNp linux-2.6.20.3/arch/i386/mm/mmap.c linux-2.6.20.3/arch/i386/mm/mmap.c
6517 --- linux-2.6.20.3/arch/i386/mm/mmap.c 2007-03-13 14:27:08.000000000 -0400
6518 +++ linux-2.6.20.3/arch/i386/mm/mmap.c 2007-03-23 08:10:06.000000000 -0400
6520 * Leave an at least ~128 MB hole.
6522 #define MIN_GAP (128*1024*1024)
6523 -#define MAX_GAP (TASK_SIZE/6*5)
6524 +#define MAX_GAP (task_size/6*5)
6526 static inline unsigned long mmap_base(struct mm_struct *mm)
6528 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
6529 unsigned long random_factor = 0;
6530 + unsigned long task_size = TASK_SIZE;
6532 +#ifdef CONFIG_PAX_SEGMEXEC
6533 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6534 + task_size = SEGMEXEC_TASK_SIZE;
6537 if (current->flags & PF_RANDOMIZE)
6538 random_factor = get_random_int() % (1024*1024);
6539 @@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
6540 else if (gap > MAX_GAP)
6543 - return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
6544 + return PAGE_ALIGN(task_size - gap - random_factor);
6548 @@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
6549 (current->personality & ADDR_COMPAT_LAYOUT) ||
6550 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
6551 mm->mmap_base = TASK_UNMAPPED_BASE;
6553 +#ifdef CONFIG_PAX_RANDMMAP
6554 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6555 + mm->mmap_base += mm->delta_mmap;
6558 mm->get_unmapped_area = arch_get_unmapped_area;
6559 mm->unmap_area = arch_unmap_area;
6561 mm->mmap_base = mmap_base(mm);
6563 +#ifdef CONFIG_PAX_RANDMMAP
6564 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6565 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
6568 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
6569 mm->unmap_area = arch_unmap_area_topdown;
6571 diff -urNp linux-2.6.20.3/arch/i386/mm/pageattr.c linux-2.6.20.3/arch/i386/mm/pageattr.c
6572 --- linux-2.6.20.3/arch/i386/mm/pageattr.c 2007-03-13 14:27:08.000000000 -0400
6573 +++ linux-2.6.20.3/arch/i386/mm/pageattr.c 2007-03-23 08:10:06.000000000 -0400
6575 #include <asm/tlbflush.h>
6576 #include <asm/pgalloc.h>
6577 #include <asm/sections.h>
6578 +#include <asm/desc.h>
6580 static DEFINE_SPINLOCK(cpa_lock);
6581 static struct list_head df_list = LIST_HEAD_INIT(df_list);
6582 @@ -89,7 +90,18 @@ static void set_pmd_pte(pte_t *kpte, uns
6584 unsigned long flags;
6586 +#ifdef CONFIG_PAX_KERNEXEC
6587 + unsigned long cr0;
6589 + pax_open_kernel(cr0);
6592 set_pte_atomic(kpte, pte); /* change init_mm */
6594 +#ifdef CONFIG_PAX_KERNEXEC
6595 + pax_close_kernel(cr0);
6598 if (PTRS_PER_PMD > 1)
6601 @@ -116,7 +128,7 @@ static inline void revert_page(struct pa
6605 - ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
6606 + ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
6607 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
6610 @@ -148,7 +160,7 @@ __change_page_attr(struct page *page, pg
6614 - ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
6615 + ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
6616 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
6617 split = split_large_page(address, prot, ref_prot);
6619 diff -urNp linux-2.6.20.3/arch/i386/oprofile/backtrace.c linux-2.6.20.3/arch/i386/oprofile/backtrace.c
6620 --- linux-2.6.20.3/arch/i386/oprofile/backtrace.c 2007-03-13 14:27:08.000000000 -0400
6621 +++ linux-2.6.20.3/arch/i386/oprofile/backtrace.c 2007-03-23 08:10:06.000000000 -0400
6622 @@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
6623 head = (struct frame_head *)regs->ebp;
6626 - if (!user_mode_vm(regs)) {
6627 + if (!user_mode(regs)) {
6628 while (depth-- && valid_kernel_stack(head, regs))
6629 head = dump_kernel_backtrace(head);
6631 diff -urNp linux-2.6.20.3/arch/i386/oprofile/op_model_p4.c linux-2.6.20.3/arch/i386/oprofile/op_model_p4.c
6632 --- linux-2.6.20.3/arch/i386/oprofile/op_model_p4.c 2007-03-13 14:27:08.000000000 -0400
6633 +++ linux-2.6.20.3/arch/i386/oprofile/op_model_p4.c 2007-03-23 08:10:06.000000000 -0400
6634 @@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
6638 -static int inline addr_increment(void)
6639 +static inline int addr_increment(void)
6642 return smp_num_siblings == 2 ? 2 : 1;
6643 diff -urNp linux-2.6.20.3/arch/i386/pci/common.c linux-2.6.20.3/arch/i386/pci/common.c
6644 --- linux-2.6.20.3/arch/i386/pci/common.c 2007-03-13 14:27:08.000000000 -0400
6645 +++ linux-2.6.20.3/arch/i386/pci/common.c 2007-03-23 08:10:06.000000000 -0400
6646 @@ -191,7 +191,7 @@ static struct dmi_system_id __devinitdat
6647 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
6651 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
6654 struct pci_bus * __devinit pcibios_scan_root(int busnum)
6655 diff -urNp linux-2.6.20.3/arch/i386/pci/early.c linux-2.6.20.3/arch/i386/pci/early.c
6656 --- linux-2.6.20.3/arch/i386/pci/early.c 2007-03-13 14:27:08.000000000 -0400
6657 +++ linux-2.6.20.3/arch/i386/pci/early.c 2007-03-23 08:10:06.000000000 -0400
6659 /* Direct PCI access. This is used for PCI accesses in early boot before
6660 the PCI subsystem works. */
6662 -#define PDprintk(x...)
6663 +#define PDprintk(x...) do {} while (0)
6665 u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
6667 diff -urNp linux-2.6.20.3/arch/i386/pci/fixup.c linux-2.6.20.3/arch/i386/pci/fixup.c
6668 --- linux-2.6.20.3/arch/i386/pci/fixup.c 2007-03-13 14:27:08.000000000 -0400
6669 +++ linux-2.6.20.3/arch/i386/pci/fixup.c 2007-03-23 08:10:06.000000000 -0400
6670 @@ -389,7 +389,7 @@ static struct dmi_system_id __devinitdat
6671 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
6675 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
6678 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
6679 diff -urNp linux-2.6.20.3/arch/i386/pci/irq.c linux-2.6.20.3/arch/i386/pci/irq.c
6680 --- linux-2.6.20.3/arch/i386/pci/irq.c 2007-03-13 14:27:08.000000000 -0400
6681 +++ linux-2.6.20.3/arch/i386/pci/irq.c 2007-03-23 08:10:06.000000000 -0400
6682 @@ -507,7 +507,7 @@ static __init int intel_router_probe(str
6683 static struct pci_device_id __initdata pirq_440gx[] = {
6684 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
6685 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
6687 + { PCI_DEVICE(0, 0) }
6690 /* 440GX has a proprietary PIRQ router -- don't use it */
6691 @@ -1049,7 +1049,7 @@ static struct dmi_system_id __initdata p
6692 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
6696 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
6699 static int __init pcibios_irq_init(void)
6700 diff -urNp linux-2.6.20.3/arch/i386/power/cpu.c linux-2.6.20.3/arch/i386/power/cpu.c
6701 --- linux-2.6.20.3/arch/i386/power/cpu.c 2007-03-13 14:27:08.000000000 -0400
6702 +++ linux-2.6.20.3/arch/i386/power/cpu.c 2007-03-23 08:10:06.000000000 -0400
6703 @@ -63,7 +63,7 @@ static void do_fpu_end(void)
6704 static void fix_processor_context(void)
6706 int cpu = smp_processor_id();
6707 - struct tss_struct * t = &per_cpu(init_tss, cpu);
6708 + struct tss_struct * t = init_tss + cpu;
6710 set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
6712 diff -urNp linux-2.6.20.3/arch/ia64/ia32/binfmt_elf32.c linux-2.6.20.3/arch/ia64/ia32/binfmt_elf32.c
6713 --- linux-2.6.20.3/arch/ia64/ia32/binfmt_elf32.c 2007-03-13 14:27:08.000000000 -0400
6714 +++ linux-2.6.20.3/arch/ia64/ia32/binfmt_elf32.c 2007-03-23 08:10:06.000000000 -0400
6715 @@ -45,6 +45,17 @@ randomize_stack_top(unsigned long stack_
6717 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
6719 +#ifdef CONFIG_PAX_ASLR
6720 +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
6722 +#define PAX_DELTA_MMAP_LSB(tsk) IA32_PAGE_SHIFT
6723 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
6724 +#define PAX_DELTA_EXEC_LSB(tsk) IA32_PAGE_SHIFT
6725 +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
6726 +#define PAX_DELTA_STACK_LSB(tsk) IA32_PAGE_SHIFT
6727 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
6730 /* Ugly but avoids duplication */
6731 #include "../../../fs/binfmt_elf.c"
6733 diff -urNp linux-2.6.20.3/arch/ia64/ia32/ia32priv.h linux-2.6.20.3/arch/ia64/ia32/ia32priv.h
6734 --- linux-2.6.20.3/arch/ia64/ia32/ia32priv.h 2007-03-13 14:27:08.000000000 -0400
6735 +++ linux-2.6.20.3/arch/ia64/ia32/ia32priv.h 2007-03-23 08:10:06.000000000 -0400
6736 @@ -304,7 +304,14 @@ struct old_linux32_dirent {
6737 #define ELF_DATA ELFDATA2LSB
6738 #define ELF_ARCH EM_386
6740 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
6741 +#ifdef CONFIG_PAX_RANDUSTACK
6742 +#define __IA32_DELTA_STACK (current->mm->delta_stack)
6744 +#define __IA32_DELTA_STACK 0UL
6747 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
6749 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
6750 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
6752 diff -urNp linux-2.6.20.3/arch/ia64/kernel/module.c linux-2.6.20.3/arch/ia64/kernel/module.c
6753 --- linux-2.6.20.3/arch/ia64/kernel/module.c 2007-03-13 14:27:08.000000000 -0400
6754 +++ linux-2.6.20.3/arch/ia64/kernel/module.c 2007-03-23 08:10:06.000000000 -0400
6755 @@ -321,7 +321,7 @@ module_alloc (unsigned long size)
6757 module_free (struct module *mod, void *module_region)
6759 - if (mod->arch.init_unw_table && module_region == mod->module_init) {
6760 + if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
6761 unw_remove_unwind_table(mod->arch.init_unw_table);
6762 mod->arch.init_unw_table = NULL;
6764 @@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
6768 +in_init_rx (const struct module *mod, uint64_t addr)
6770 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
6774 +in_init_rw (const struct module *mod, uint64_t addr)
6776 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
6780 in_init (const struct module *mod, uint64_t addr)
6782 - return addr - (uint64_t) mod->module_init < mod->init_size;
6783 + return in_init_rx(mod, value) || in_init_rw(mod, value);
6787 +in_core_rx (const struct module *mod, uint64_t addr)
6789 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
6793 +in_core_rw (const struct module *mod, uint64_t addr)
6795 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
6799 in_core (const struct module *mod, uint64_t addr)
6801 - return addr - (uint64_t) mod->module_core < mod->core_size;
6802 + return in_core_rx(mod, value) || in_core_rw(mod, value);
6806 @@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
6810 - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
6811 + if (in_init_rx(mod, val))
6812 + val -= (uint64_t) mod->module_init_rx;
6813 + else if (in_init_rw(mod, val))
6814 + val -= (uint64_t) mod->module_init_rw;
6815 + else if (in_core_rx(mod, val))
6816 + val -= (uint64_t) mod->module_core_rx;
6817 + else if (in_core_rw(mod, val))
6818 + val -= (uint64_t) mod->module_core_rw;
6822 @@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
6823 * addresses have been selected...
6826 - if (mod->core_size > MAX_LTOFF)
6827 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
6829 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
6830 * at the end of the module.
6832 - gp = mod->core_size - MAX_LTOFF / 2;
6833 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
6835 - gp = mod->core_size / 2;
6836 - gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
6837 + gp = (mod->core_size_rx + mod->core_size_rw) / 2;
6838 + gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
6840 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
6842 diff -urNp linux-2.6.20.3/arch/ia64/kernel/ptrace.c linux-2.6.20.3/arch/ia64/kernel/ptrace.c
6843 --- linux-2.6.20.3/arch/ia64/kernel/ptrace.c 2007-03-13 14:27:08.000000000 -0400
6844 +++ linux-2.6.20.3/arch/ia64/kernel/ptrace.c 2007-03-23 08:11:18.000000000 -0400
6846 #include <linux/audit.h>
6847 #include <linux/signal.h>
6848 #include <linux/vs_base.h>
6849 +#include <linux/grsecurity.h>
6851 #include <asm/pgtable.h>
6852 #include <asm/processor.h>
6853 @@ -1446,6 +1447,9 @@ sys_ptrace (long request, pid_t pid, uns
6854 if (pid == 1) /* no messing around with init! */
6857 + if (gr_handle_ptrace(child, request))
6860 if (request == PTRACE_ATTACH) {
6861 ret = ptrace_attach(child);
6863 diff -urNp linux-2.6.20.3/arch/ia64/kernel/sys_ia64.c linux-2.6.20.3/arch/ia64/kernel/sys_ia64.c
6864 --- linux-2.6.20.3/arch/ia64/kernel/sys_ia64.c 2007-03-13 14:27:08.000000000 -0400
6865 +++ linux-2.6.20.3/arch/ia64/kernel/sys_ia64.c 2007-03-23 08:10:06.000000000 -0400
6866 @@ -37,6 +37,13 @@ arch_get_unmapped_area (struct file *fil
6867 if (REGION_NUMBER(addr) == RGN_HPAGE)
6871 +#ifdef CONFIG_PAX_RANDMMAP
6872 + if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
6873 + addr = mm->free_area_cache;
6878 addr = mm->free_area_cache;
6880 @@ -55,9 +62,9 @@ arch_get_unmapped_area (struct file *fil
6881 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6882 /* At this point: (!vma || addr < vma->vm_end). */
6883 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
6884 - if (start_addr != TASK_UNMAPPED_BASE) {
6885 + if (start_addr != mm->mmap_base) {
6886 /* Start a new search --- just in case we missed some holes. */
6887 - addr = TASK_UNMAPPED_BASE;
6888 + addr = mm->mmap_base;
6892 diff -urNp linux-2.6.20.3/arch/ia64/mm/fault.c linux-2.6.20.3/arch/ia64/mm/fault.c
6893 --- linux-2.6.20.3/arch/ia64/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
6894 +++ linux-2.6.20.3/arch/ia64/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
6896 #include <linux/interrupt.h>
6897 #include <linux/kprobes.h>
6898 #include <linux/vs_memory.h>
6899 +#include <linux/binfmts.h>
6901 #include <asm/pgtable.h>
6902 #include <asm/processor.h>
6903 @@ -86,6 +87,23 @@ mapped_kernel_page_is_present (unsigned
6904 return pte_present(pte);
6907 +#ifdef CONFIG_PAX_PAGEEXEC
6908 +void pax_report_insns(void *pc, void *sp)
6912 + printk(KERN_ERR "PAX: bytes at PC: ");
6913 + for (i = 0; i < 8; i++) {
6915 + if (get_user(c, (unsigned int*)pc+i))
6916 + printk("???????? ");
6918 + printk("%08x ", c);
6925 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
6927 @@ -153,9 +171,23 @@ ia64_do_page_fault (unsigned long addres
6928 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
6929 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
6931 - if ((vma->vm_flags & mask) != mask)
6932 + if ((vma->vm_flags & mask) != mask) {
6934 +#ifdef CONFIG_PAX_PAGEEXEC
6935 + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
6936 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
6939 + up_read(&mm->mmap_sem);
6940 + pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
6951 * If for any reason at all we couldn't handle the fault, make
6952 diff -urNp linux-2.6.20.3/arch/ia64/mm/init.c linux-2.6.20.3/arch/ia64/mm/init.c
6953 --- linux-2.6.20.3/arch/ia64/mm/init.c 2007-03-13 14:27:08.000000000 -0400
6954 +++ linux-2.6.20.3/arch/ia64/mm/init.c 2007-03-23 08:10:06.000000000 -0400
6956 #include <linux/swap.h>
6957 #include <linux/proc_fs.h>
6958 #include <linux/bitops.h>
6959 +#include <linux/a.out.h>
6961 -#include <asm/a.out.h>
6962 #include <asm/dma.h>
6963 #include <asm/ia32.h>
6965 diff -urNp linux-2.6.20.3/arch/mips/kernel/binfmt_elfn32.c linux-2.6.20.3/arch/mips/kernel/binfmt_elfn32.c
6966 --- linux-2.6.20.3/arch/mips/kernel/binfmt_elfn32.c 2007-03-13 14:27:08.000000000 -0400
6967 +++ linux-2.6.20.3/arch/mips/kernel/binfmt_elfn32.c 2007-03-23 08:10:06.000000000 -0400
6968 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6969 #undef ELF_ET_DYN_BASE
6970 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
6972 +#ifdef CONFIG_PAX_ASLR
6973 +#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6975 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
6976 +#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6977 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
6978 +#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6979 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
6980 +#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6983 #include <asm/processor.h>
6984 #include <linux/module.h>
6985 #include <linux/elfcore.h>
6986 diff -urNp linux-2.6.20.3/arch/mips/kernel/binfmt_elfo32.c linux-2.6.20.3/arch/mips/kernel/binfmt_elfo32.c
6987 --- linux-2.6.20.3/arch/mips/kernel/binfmt_elfo32.c 2007-03-13 14:27:08.000000000 -0400
6988 +++ linux-2.6.20.3/arch/mips/kernel/binfmt_elfo32.c 2007-03-23 08:10:06.000000000 -0400
6989 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6990 #undef ELF_ET_DYN_BASE
6991 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
6993 +#ifdef CONFIG_PAX_ASLR
6994 +#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6996 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
6997 +#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6998 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
6999 +#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7000 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
7001 +#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7004 #include <asm/processor.h>
7005 #include <linux/module.h>
7006 #include <linux/elfcore.h>
7007 diff -urNp linux-2.6.20.3/arch/mips/kernel/syscall.c linux-2.6.20.3/arch/mips/kernel/syscall.c
7008 --- linux-2.6.20.3/arch/mips/kernel/syscall.c 2007-03-13 14:27:08.000000000 -0400
7009 +++ linux-2.6.20.3/arch/mips/kernel/syscall.c 2007-03-23 08:10:06.000000000 -0400
7010 @@ -88,6 +88,11 @@ unsigned long arch_get_unmapped_area(str
7012 if (filp || (flags & MAP_SHARED))
7015 +#ifdef CONFIG_PAX_RANDMMAP
7016 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7021 addr = COLOUR_ALIGN(addr, pgoff);
7022 @@ -98,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
7023 (!vmm || addr + len <= vmm->vm_start))
7026 - addr = TASK_UNMAPPED_BASE;
7027 + addr = current->mm->mmap_base;
7029 addr = COLOUR_ALIGN(addr, pgoff);
7031 diff -urNp linux-2.6.20.3/arch/mips/mm/fault.c linux-2.6.20.3/arch/mips/mm/fault.c
7032 --- linux-2.6.20.3/arch/mips/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
7033 +++ linux-2.6.20.3/arch/mips/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
7035 #include <asm/ptrace.h>
7036 #include <asm/highmem.h> /* For VMALLOC_END */
7038 +#ifdef CONFIG_PAX_PAGEEXEC
7039 +void pax_report_insns(void *pc)
7043 + printk(KERN_ERR "PAX: bytes at PC: ");
7044 + for (i = 0; i < 5; i++) {
7046 + if (get_user(c, (unsigned int*)pc+i))
7047 + printk("???????? ");
7049 + printk("%08x ", c);
7056 * This routine handles page faults. It determines the address,
7057 * and the problem, and then passes it off to one of the appropriate
7058 diff -urNp linux-2.6.20.3/arch/parisc/kernel/module.c linux-2.6.20.3/arch/parisc/kernel/module.c
7059 --- linux-2.6.20.3/arch/parisc/kernel/module.c 2007-03-13 14:27:08.000000000 -0400
7060 +++ linux-2.6.20.3/arch/parisc/kernel/module.c 2007-03-23 08:10:06.000000000 -0400
7063 /* three functions to determine where in the module core
7064 * or init pieces the location is */
7065 +static inline int in_init_rx(struct module *me, void *loc)
7067 + return (loc >= me->module_init_rx &&
7068 + loc < (me->module_init_rx + me->init_size_rx));
7071 +static inline int in_init_rw(struct module *me, void *loc)
7073 + return (loc >= me->module_init_rw &&
7074 + loc < (me->module_init_rw + me->init_size_rw));
7077 static inline int in_init(struct module *me, void *loc)
7079 - return (loc >= me->module_init &&
7080 - loc <= (me->module_init + me->init_size));
7081 + return in_init_rx(me, loc) || in_init_rw(me, loc);
7084 +static inline int in_core_rx(struct module *me, void *loc)
7086 + return (loc >= me->module_core_rx &&
7087 + loc < (me->module_core_rx + me->core_size_rx));
7090 +static inline int in_core_rw(struct module *me, void *loc)
7092 + return (loc >= me->module_core_rw &&
7093 + loc < (me->module_core_rw + me->core_size_rw));
7096 static inline int in_core(struct module *me, void *loc)
7098 - return (loc >= me->module_core &&
7099 - loc <= (me->module_core + me->core_size));
7100 + return in_core_rx(me, loc) || in_core_rw(me, loc);
7103 static inline int in_local(struct module *me, void *loc)
7104 @@ -295,21 +317,21 @@ int module_frob_arch_sections(CONST Elf_
7107 /* align things a bit */
7108 - me->core_size = ALIGN(me->core_size, 16);
7109 - me->arch.got_offset = me->core_size;
7110 - me->core_size += gots * sizeof(struct got_entry);
7112 - me->core_size = ALIGN(me->core_size, 16);
7113 - me->arch.fdesc_offset = me->core_size;
7114 - me->core_size += fdescs * sizeof(Elf_Fdesc);
7116 - me->core_size = ALIGN(me->core_size, 16);
7117 - me->arch.stub_offset = me->core_size;
7118 - me->core_size += stubs * sizeof(struct stub_entry);
7120 - me->init_size = ALIGN(me->init_size, 16);
7121 - me->arch.init_stub_offset = me->init_size;
7122 - me->init_size += init_stubs * sizeof(struct stub_entry);
7123 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
7124 + me->arch.got_offset = me->core_size_rw;
7125 + me->core_size_rw += gots * sizeof(struct got_entry);
7127 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
7128 + me->arch.fdesc_offset = me->core_size_rw;
7129 + me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
7131 + me->core_size_rx = ALIGN(me->core_size_rx, 16);
7132 + me->arch.stub_offset = me->core_size_rx;
7133 + me->core_size_rx += stubs * sizeof(struct stub_entry);
7135 + me->init_size_rx = ALIGN(me->init_size_rx, 16);
7136 + me->arch.init_stub_offset = me->init_size_rx;
7137 + me->init_size_rx += init_stubs * sizeof(struct stub_entry);
7139 me->arch.got_max = gots;
7140 me->arch.fdesc_max = fdescs;
7141 @@ -329,7 +351,7 @@ static Elf64_Word get_got(struct module
7145 - got = me->module_core + me->arch.got_offset;
7146 + got = me->module_core_rw + me->arch.got_offset;
7147 for (i = 0; got[i].addr; i++)
7148 if (got[i].addr == value)
7150 @@ -347,7 +369,7 @@ static Elf64_Word get_got(struct module
7152 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
7154 - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
7155 + Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
7158 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
7159 @@ -365,7 +387,7 @@ static Elf_Addr get_fdesc(struct module
7161 /* Create new one */
7162 fdesc->addr = value;
7163 - fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
7164 + fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
7165 return (Elf_Addr)fdesc;
7167 #endif /* __LP64__ */
7168 @@ -385,12 +407,12 @@ static Elf_Addr get_stub(struct module *
7170 i = me->arch.init_stub_count++;
7171 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
7172 - stub = me->module_init + me->arch.init_stub_offset +
7173 + stub = me->module_init_rx + me->arch.init_stub_offset +
7174 i * sizeof(struct stub_entry);
7176 i = me->arch.stub_count++;
7177 BUG_ON(me->arch.stub_count > me->arch.stub_max);
7178 - stub = me->module_core + me->arch.stub_offset +
7179 + stub = me->module_core_rx + me->arch.stub_offset +
7180 i * sizeof(struct stub_entry);
7183 @@ -758,7 +780,7 @@ register_unwind_table(struct module *me,
7185 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
7186 end = table + sechdrs[me->arch.unwind_section].sh_size;
7187 - gp = (Elf_Addr)me->module_core + me->arch.got_offset;
7188 + gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
7190 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
7191 me->arch.unwind_section, table, end, gp);
7192 diff -urNp linux-2.6.20.3/arch/parisc/kernel/ptrace.c linux-2.6.20.3/arch/parisc/kernel/ptrace.c
7193 --- linux-2.6.20.3/arch/parisc/kernel/ptrace.c 2007-03-13 14:27:08.000000000 -0400
7194 +++ linux-2.6.20.3/arch/parisc/kernel/ptrace.c 2007-03-23 08:11:18.000000000 -0400
7196 #include <linux/security.h>
7197 #include <linux/compat.h>
7198 #include <linux/signal.h>
7199 +#include <linux/grsecurity.h>
7201 #include <asm/uaccess.h>
7202 #include <asm/pgtable.h>
7203 diff -urNp linux-2.6.20.3/arch/parisc/kernel/sys_parisc.c linux-2.6.20.3/arch/parisc/kernel/sys_parisc.c
7204 --- linux-2.6.20.3/arch/parisc/kernel/sys_parisc.c 2007-03-13 14:27:08.000000000 -0400
7205 +++ linux-2.6.20.3/arch/parisc/kernel/sys_parisc.c 2007-03-23 08:10:06.000000000 -0400
7206 @@ -107,7 +107,7 @@ unsigned long arch_get_unmapped_area(str
7207 if (len > TASK_SIZE)
7210 - addr = TASK_UNMAPPED_BASE;
7211 + addr = current->mm->mmap_base;
7214 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
7215 diff -urNp linux-2.6.20.3/arch/parisc/kernel/traps.c linux-2.6.20.3/arch/parisc/kernel/traps.c
7216 --- linux-2.6.20.3/arch/parisc/kernel/traps.c 2007-03-13 14:27:08.000000000 -0400
7217 +++ linux-2.6.20.3/arch/parisc/kernel/traps.c 2007-03-23 08:10:06.000000000 -0400
7218 @@ -716,9 +716,7 @@ void handle_interruption(int code, struc
7220 down_read(¤t->mm->mmap_sem);
7221 vma = find_vma(current->mm,regs->iaoq[0]);
7222 - if (vma && (regs->iaoq[0] >= vma->vm_start)
7223 - && (vma->vm_flags & VM_EXEC)) {
7225 + if (vma && (regs->iaoq[0] >= vma->vm_start)) {
7226 fault_address = regs->iaoq[0];
7227 fault_space = regs->iasq[0];
7229 diff -urNp linux-2.6.20.3/arch/parisc/mm/fault.c linux-2.6.20.3/arch/parisc/mm/fault.c
7230 --- linux-2.6.20.3/arch/parisc/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
7231 +++ linux-2.6.20.3/arch/parisc/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
7233 #include <linux/sched.h>
7234 #include <linux/interrupt.h>
7235 #include <linux/module.h>
7236 +#include <linux/unistd.h>
7237 +#include <linux/binfmts.h>
7239 #include <asm/uaccess.h>
7240 #include <asm/traps.h>
7241 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
7242 static unsigned long
7243 parisc_acctyp(unsigned long code, unsigned int inst)
7245 - if (code == 6 || code == 16)
7246 + if (code == 6 || code == 7 || code == 16)
7249 switch (inst & 0xf0000000) {
7250 @@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
7254 +#ifdef CONFIG_PAX_PAGEEXEC
7256 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
7258 + * returns 1 when task should be killed
7259 + * 2 when rt_sigreturn trampoline was detected
7260 + * 3 when unpatched PLT trampoline was detected
7262 +static int pax_handle_fetch_fault(struct pt_regs *regs)
7265 +#ifdef CONFIG_PAX_EMUPLT
7268 + do { /* PaX: unpatched PLT emulation */
7269 + unsigned int bl, depwi;
7271 + err = get_user(bl, (unsigned int*)instruction_pointer(regs));
7272 + err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
7277 + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
7278 + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
7280 + err = get_user(ldw, (unsigned int*)addr);
7281 + err |= get_user(bv, (unsigned int*)(addr+4));
7282 + err |= get_user(ldw2, (unsigned int*)(addr+8));
7287 + if (ldw == 0x0E801096U &&
7288 + bv == 0xEAC0C000U &&
7289 + ldw2 == 0x0E881095U)
7291 + unsigned int resolver, map;
7293 + err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
7294 + err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
7298 + regs->gr[20] = instruction_pointer(regs)+8;
7299 + regs->gr[21] = map;
7300 + regs->gr[22] = resolver;
7301 + regs->iaoq[0] = resolver | 3UL;
7302 + regs->iaoq[1] = regs->iaoq[0] + 4;
7309 +#ifdef CONFIG_PAX_EMUTRAMP
7311 +#ifndef CONFIG_PAX_EMUSIGRT
7312 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
7316 + do { /* PaX: rt_sigreturn emulation */
7317 + unsigned int ldi1, ldi2, bel, nop;
7319 + err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
7320 + err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
7321 + err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
7322 + err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
7327 + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
7328 + ldi2 == 0x3414015AU &&
7329 + bel == 0xE4008200U &&
7330 + nop == 0x08000240U)
7332 + regs->gr[25] = (ldi1 & 2) >> 1;
7333 + regs->gr[20] = __NR_rt_sigreturn;
7334 + regs->gr[31] = regs->iaoq[1] + 16;
7335 + regs->sr[0] = regs->iasq[1];
7336 + regs->iaoq[0] = 0x100UL;
7337 + regs->iaoq[1] = regs->iaoq[0] + 4;
7338 + regs->iasq[0] = regs->sr[2];
7339 + regs->iasq[1] = regs->sr[2];
7348 +void pax_report_insns(void *pc, void *sp)
7352 + printk(KERN_ERR "PAX: bytes at PC: ");
7353 + for (i = 0; i < 5; i++) {
7355 + if (get_user(c, (unsigned int*)pc+i))
7356 + printk("???????? ");
7358 + printk("%08x ", c);
7364 void do_page_fault(struct pt_regs *regs, unsigned long code,
7365 unsigned long address)
7367 @@ -168,8 +280,33 @@ good_area:
7369 acc_type = parisc_acctyp(code,regs->iir);
7371 - if ((vma->vm_flags & acc_type) != acc_type)
7372 + if ((vma->vm_flags & acc_type) != acc_type) {
7374 +#ifdef CONFIG_PAX_PAGEEXEC
7375 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
7376 + (address & ~3UL) == instruction_pointer(regs))
7378 + up_read(&mm->mmap_sem);
7379 + switch(pax_handle_fetch_fault(regs)) {
7381 +#ifdef CONFIG_PAX_EMUPLT
7386 +#ifdef CONFIG_PAX_EMUTRAMP
7392 + pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
7401 * If for any reason at all we couldn't handle the fault, make
7402 diff -urNp linux-2.6.20.3/arch/powerpc/kernel/module_32.c linux-2.6.20.3/arch/powerpc/kernel/module_32.c
7403 --- linux-2.6.20.3/arch/powerpc/kernel/module_32.c 2007-03-13 14:27:08.000000000 -0400
7404 +++ linux-2.6.20.3/arch/powerpc/kernel/module_32.c 2007-03-23 08:10:06.000000000 -0400
7405 @@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
7406 me->arch.core_plt_section = i;
7408 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
7409 - printk("Module doesn't contain .plt or .init.plt sections.\n");
7410 + printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
7414 @@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
7416 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
7417 /* Init, or core PLT? */
7418 - if (location >= mod->module_core
7419 - && location < mod->module_core + mod->core_size)
7420 + if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
7421 + (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
7422 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
7424 + else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
7425 + (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
7426 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
7428 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
7432 /* Find this entry, or if that fails, the next avail. entry */
7433 while (entry->jump[0]) {
7434 diff -urNp linux-2.6.20.3/arch/powerpc/kernel/signal_32.c linux-2.6.20.3/arch/powerpc/kernel/signal_32.c
7435 --- linux-2.6.20.3/arch/powerpc/kernel/signal_32.c 2007-03-13 14:27:08.000000000 -0400
7436 +++ linux-2.6.20.3/arch/powerpc/kernel/signal_32.c 2007-03-23 08:10:06.000000000 -0400
7437 @@ -759,7 +759,7 @@ static int handle_rt_signal(unsigned lon
7439 /* Save user registers on the stack */
7440 frame = &rt_sf->uc.uc_mcontext;
7441 - if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
7442 + if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
7443 if (save_user_regs(regs, frame, 0))
7445 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
7446 diff -urNp linux-2.6.20.3/arch/powerpc/kernel/signal_64.c linux-2.6.20.3/arch/powerpc/kernel/signal_64.c
7447 --- linux-2.6.20.3/arch/powerpc/kernel/signal_64.c 2007-03-13 14:27:08.000000000 -0400
7448 +++ linux-2.6.20.3/arch/powerpc/kernel/signal_64.c 2007-03-23 08:10:06.000000000 -0400
7449 @@ -397,7 +397,7 @@ static int setup_rt_frame(int signr, str
7450 current->thread.fpscr.val = 0;
7452 /* Set up to return from userspace. */
7453 - if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
7454 + if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
7455 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
7457 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
7458 diff -urNp linux-2.6.20.3/arch/powerpc/kernel/vdso.c linux-2.6.20.3/arch/powerpc/kernel/vdso.c
7459 --- linux-2.6.20.3/arch/powerpc/kernel/vdso.c 2007-03-13 14:27:08.000000000 -0400
7460 +++ linux-2.6.20.3/arch/powerpc/kernel/vdso.c 2007-03-23 08:10:06.000000000 -0400
7461 @@ -239,7 +239,7 @@ int arch_setup_additional_pages(struct l
7462 vdso_base = VDSO32_MBASE;
7465 - current->mm->context.vdso_base = 0;
7466 + current->mm->context.vdso_base = ~0UL;
7468 /* vDSO has a problem and was disabled, just don't "enable" it for the
7470 @@ -256,7 +256,7 @@ int arch_setup_additional_pages(struct l
7472 down_write(&mm->mmap_sem);
7473 vdso_base = get_unmapped_area(NULL, vdso_base,
7474 - vdso_pages << PAGE_SHIFT, 0, 0);
7475 + vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
7476 if (IS_ERR_VALUE(vdso_base)) {
7479 @@ -284,6 +284,12 @@ int arch_setup_additional_pages(struct l
7482 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC;
7484 +#ifdef CONFIG_PAX_MPROTECT
7485 + if (mm->pax_flags & MF_PAX_MPROTECT)
7486 + vma->vm_flags &= ~VM_MAYWRITE;
7490 * Make sure the vDSO gets into every core dump.
7491 * Dumping its contents makes post-mortem fully interpretable later
7492 @@ -292,7 +298,7 @@ int arch_setup_additional_pages(struct l
7494 vma->vm_flags |= VM_ALWAYSDUMP;
7495 vma->vm_flags |= mm->def_flags;
7496 - vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
7497 + vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
7498 vma->vm_ops = &vdso_vmops;
7500 /* Insert new VMA */
7501 diff -urNp linux-2.6.20.3/arch/powerpc/mm/fault.c linux-2.6.20.3/arch/powerpc/mm/fault.c
7502 --- linux-2.6.20.3/arch/powerpc/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
7503 +++ linux-2.6.20.3/arch/powerpc/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
7505 #include <linux/highmem.h>
7506 #include <linux/module.h>
7507 #include <linux/kprobes.h>
7508 +#include <linux/binfmts.h>
7509 +#include <linux/slab.h>
7510 +#include <linux/pagemap.h>
7511 +#include <linux/compiler.h>
7512 +#include <linux/binfmts.h>
7513 +#include <linux/unistd.h>
7515 #include <asm/page.h>
7516 #include <asm/pgtable.h>
7517 @@ -73,6 +79,364 @@ static inline int notify_page_fault(enum
7521 +#ifdef CONFIG_PAX_EMUSIGRT
7522 +void pax_syscall_close(struct vm_area_struct * vma)
7524 + vma->vm_mm->call_syscall = 0UL;
7527 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7529 + struct page* page;
7530 + unsigned int *kaddr;
7532 + page = alloc_page(GFP_HIGHUSER);
7534 + return NOPAGE_OOM;
7536 + kaddr = kmap(page);
7537 + memset(kaddr, 0, PAGE_SIZE);
7538 + kaddr[0] = 0x44000002U; /* sc */
7539 + __flush_dcache_icache(kaddr);
7542 + *type = VM_FAULT_MAJOR;
7546 +static struct vm_operations_struct pax_vm_ops = {
7547 + .close = pax_syscall_close,
7548 + .nopage = pax_syscall_nopage,
7551 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7555 + memset(vma, 0, sizeof(*vma));
7556 + vma->vm_mm = current->mm;
7557 + vma->vm_start = addr;
7558 + vma->vm_end = addr + PAGE_SIZE;
7559 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7560 + vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
7561 + vma->vm_ops = &pax_vm_ops;
7563 + ret = insert_vm_struct(current->mm, vma);
7567 + ++current->mm->total_vm;
7572 +#ifdef CONFIG_PAX_PAGEEXEC
7574 + * PaX: decide what to do with offenders (regs->nip = fault address)
7576 + * returns 1 when task should be killed
7577 + * 2 when patched GOT trampoline was detected
7578 + * 3 when patched PLT trampoline was detected
7579 + * 4 when unpatched PLT trampoline was detected
7580 + * 5 when sigreturn trampoline was detected
7581 + * 6 when rt_sigreturn trampoline was detected
7583 +static int pax_handle_fetch_fault(struct pt_regs *regs)
7586 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
7590 +#ifdef CONFIG_PAX_EMUPLT
7591 + do { /* PaX: patched GOT emulation */
7592 + unsigned int blrl;
7594 + err = get_user(blrl, (unsigned int*)regs->nip);
7596 + if (!err && blrl == 0x4E800021U) {
7597 + unsigned long temp = regs->nip;
7599 + regs->nip = regs->link & 0xFFFFFFFCUL;
7600 + regs->link = temp + 4UL;
7605 + do { /* PaX: patched PLT emulation #1 */
7608 + err = get_user(b, (unsigned int *)regs->nip);
7610 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
7611 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
7616 + do { /* PaX: unpatched PLT emulation #1 */
7617 + unsigned int li, b;
7619 + err = get_user(li, (unsigned int *)regs->nip);
7620 + err |= get_user(b, (unsigned int *)(regs->nip+4));
7622 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7623 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7624 + unsigned long addr = b | 0xFC000000UL;
7626 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7627 + err = get_user(rlwinm, (unsigned int*)addr);
7628 + err |= get_user(add, (unsigned int*)(addr+4));
7629 + err |= get_user(li2, (unsigned int*)(addr+8));
7630 + err |= get_user(addis2, (unsigned int*)(addr+12));
7631 + err |= get_user(mtctr, (unsigned int*)(addr+16));
7632 + err |= get_user(li3, (unsigned int*)(addr+20));
7633 + err |= get_user(addis3, (unsigned int*)(addr+24));
7634 + err |= get_user(bctr, (unsigned int*)(addr+28));
7639 + if (rlwinm == 0x556C083CU &&
7640 + add == 0x7D6C5A14U &&
7641 + (li2 & 0xFFFF0000U) == 0x39800000U &&
7642 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7643 + mtctr == 0x7D8903A6U &&
7644 + (li3 & 0xFFFF0000U) == 0x39800000U &&
7645 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7646 + bctr == 0x4E800420U)
7648 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7649 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7650 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7651 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7652 + regs->ctr += (addis2 & 0xFFFFU) << 16;
7653 + regs->nip = regs->ctr;
7660 + do { /* PaX: unpatched PLT emulation #2 */
7661 + unsigned int lis, lwzu, b, bctr;
7663 + err = get_user(lis, (unsigned int *)regs->nip);
7664 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
7665 + err |= get_user(b, (unsigned int *)(regs->nip+8));
7666 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
7671 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
7672 + (lwzu & 0xU) == 0xU &&
7673 + (b & 0xFC000003U) == 0x48000000U &&
7674 + bctr == 0x4E800420U)
7676 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7677 + unsigned long addr = b | 0xFC000000UL;
7679 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7680 + err = get_user(addis, (unsigned int*)addr);
7681 + err |= get_user(addi, (unsigned int*)(addr+4));
7682 + err |= get_user(rlwinm, (unsigned int*)(addr+8));
7683 + err |= get_user(add, (unsigned int*)(addr+12));
7684 + err |= get_user(li2, (unsigned int*)(addr+16));
7685 + err |= get_user(addis2, (unsigned int*)(addr+20));
7686 + err |= get_user(mtctr, (unsigned int*)(addr+24));
7687 + err |= get_user(li3, (unsigned int*)(addr+28));
7688 + err |= get_user(addis3, (unsigned int*)(addr+32));
7689 + err |= get_user(bctr, (unsigned int*)(addr+36));
7694 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7695 + (addi & 0xFFFF0000U) == 0x396B0000U &&
7696 + rlwinm == 0x556C083CU &&
7697 + add == 0x7D6C5A14U &&
7698 + (li2 & 0xFFFF0000U) == 0x39800000U &&
7699 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7700 + mtctr == 0x7D8903A6U &&
7701 + (li3 & 0xFFFF0000U) == 0x39800000U &&
7702 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7703 + bctr == 0x4E800420U)
7705 + regs->gpr[PT_R11] =
7706 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7707 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7708 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7709 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7710 + regs->ctr += (addis2 & 0xFFFFU) << 16;
7711 + regs->nip = regs->ctr;
7718 + do { /* PaX: unpatched PLT emulation #3 */
7719 + unsigned int li, b;
7721 + err = get_user(li, (unsigned int *)regs->nip);
7722 + err |= get_user(b, (unsigned int *)(regs->nip+4));
7724 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7725 + unsigned int addis, lwz, mtctr, bctr;
7726 + unsigned long addr = b | 0xFC000000UL;
7728 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7729 + err = get_user(addis, (unsigned int*)addr);
7730 + err |= get_user(lwz, (unsigned int*)(addr+4));
7731 + err |= get_user(mtctr, (unsigned int*)(addr+8));
7732 + err |= get_user(bctr, (unsigned int*)(addr+12));
7737 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7738 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
7739 + mtctr == 0x7D6903A6U &&
7740 + bctr == 0x4E800420U)
7744 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7745 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7747 + err = get_user(r11, (unsigned int*)addr);
7751 + regs->gpr[PT_R11] = r11;
7760 +#ifdef CONFIG_PAX_EMUSIGRT
7761 + do { /* PaX: sigreturn emulation */
7762 + unsigned int li, sc;
7764 + err = get_user(li, (unsigned int *)regs->nip);
7765 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
7767 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
7768 + struct vm_area_struct *vma;
7769 + unsigned long call_syscall;
7771 + down_read(¤t->mm->mmap_sem);
7772 + call_syscall = current->mm->call_syscall;
7773 + up_read(¤t->mm->mmap_sem);
7774 + if (likely(call_syscall))
7777 + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
7779 + down_write(¤t->mm->mmap_sem);
7780 + if (current->mm->call_syscall) {
7781 + call_syscall = current->mm->call_syscall;
7782 + up_write(¤t->mm->mmap_sem);
7783 + if (vma) kmem_cache_free(vm_area_cachep, vma);
7787 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7788 + if (!vma || (call_syscall & ~PAGE_MASK)) {
7789 + up_write(¤t->mm->mmap_sem);
7790 + if (vma) kmem_cache_free(vm_area_cachep, vma);
7794 + if (pax_insert_vma(vma, call_syscall)) {
7795 + up_write(¤t->mm->mmap_sem);
7796 + kmem_cache_free(vm_area_cachep, vma);
7800 + current->mm->call_syscall = call_syscall;
7801 + up_write(¤t->mm->mmap_sem);
7804 + regs->gpr[PT_R0] = __NR_sigreturn;
7805 + regs->nip = call_syscall;
7810 + do { /* PaX: rt_sigreturn emulation */
7811 + unsigned int li, sc;
7813 + err = get_user(li, (unsigned int *)regs->nip);
7814 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
7816 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
7817 + struct vm_area_struct *vma;
7818 + unsigned int call_syscall;
7820 + down_read(¤t->mm->mmap_sem);
7821 + call_syscall = current->mm->call_syscall;
7822 + up_read(¤t->mm->mmap_sem);
7823 + if (likely(call_syscall))
7826 + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
7828 + down_write(¤t->mm->mmap_sem);
7829 + if (current->mm->call_syscall) {
7830 + call_syscall = current->mm->call_syscall;
7831 + up_write(¤t->mm->mmap_sem);
7832 + if (vma) kmem_cache_free(vm_area_cachep, vma);
7836 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7837 + if (!vma || (call_syscall & ~PAGE_MASK)) {
7838 + up_write(¤t->mm->mmap_sem);
7839 + if (vma) kmem_cache_free(vm_area_cachep, vma);
7843 + if (pax_insert_vma(vma, call_syscall)) {
7844 + up_write(¤t->mm->mmap_sem);
7845 + kmem_cache_free(vm_area_cachep, vma);
7849 + current->mm->call_syscall = call_syscall;
7850 + up_write(¤t->mm->mmap_sem);
7853 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
7854 + regs->nip = call_syscall;
7863 +void pax_report_insns(void *pc, void *sp)
7867 + printk(KERN_ERR "PAX: bytes at PC: ");
7868 + for (i = 0; i < 5; i++) {
7870 + if (get_user(c, (unsigned int*)pc+i))
7871 + printk("???????? ");
7873 + printk("%08x ", c);
7880 * Check whether the instruction at regs->nip is a store using
7881 * an update addressing form which will update r1.
7882 @@ -168,7 +532,7 @@ int __kprobes do_page_fault(struct pt_re
7883 * indicate errors in DSISR but can validly be set in SRR1.
7886 - error_code &= 0x48200000;
7887 + error_code &= 0x58200000;
7889 is_write = error_code & DSISR_ISSTORE;
7891 @@ -295,9 +659,9 @@ good_area:
7892 /* protection fault */
7893 if (error_code & DSISR_PROTFAULT)
7896 if (!(vma->vm_flags & VM_EXEC))
7899 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
7902 @@ -368,6 +732,37 @@ bad_area:
7903 bad_area_nosemaphore:
7904 /* User mode accesses cause a SIGSEGV */
7905 if (user_mode(regs)) {
7907 +#ifdef CONFIG_PAX_PAGEEXEC
7908 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
7909 +#ifdef CONFIG_PPC64
7910 + if (is_exec && (error_code & DSISR_PROTFAULT)) {
7912 + if (is_exec && regs->nip == address) {
7914 + switch (pax_handle_fetch_fault(regs)) {
7916 +#ifdef CONFIG_PAX_EMUPLT
7923 +#ifdef CONFIG_PAX_EMUSIGRT
7931 + pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
7937 _exception(SIGSEGV, regs, code, address);
7940 diff -urNp linux-2.6.20.3/arch/powerpc/mm/hugetlbpage.c linux-2.6.20.3/arch/powerpc/mm/hugetlbpage.c
7941 --- linux-2.6.20.3/arch/powerpc/mm/hugetlbpage.c 2007-03-13 14:27:08.000000000 -0400
7942 +++ linux-2.6.20.3/arch/powerpc/mm/hugetlbpage.c 2007-03-23 08:10:06.000000000 -0400
7943 @@ -568,6 +568,10 @@ unsigned long arch_get_unmapped_area(str
7944 if (len > TASK_SIZE)
7947 +#ifdef CONFIG_PAX_RANDMMAP
7948 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
7952 addr = PAGE_ALIGN(addr);
7953 vma = find_vma(mm, addr);
7954 @@ -579,7 +583,7 @@ unsigned long arch_get_unmapped_area(str
7955 if (len > mm->cached_hole_size) {
7956 start_addr = addr = mm->free_area_cache;
7958 - start_addr = addr = TASK_UNMAPPED_BASE;
7959 + start_addr = addr = mm->mmap_base;
7960 mm->cached_hole_size = 0;
7963 @@ -612,8 +616,8 @@ full_search:
7966 /* Make sure we didn't miss any holes */
7967 - if (start_addr != TASK_UNMAPPED_BASE) {
7968 - start_addr = addr = TASK_UNMAPPED_BASE;
7969 + if (start_addr != mm->mmap_base) {
7970 + start_addr = addr = mm->mmap_base;
7971 mm->cached_hole_size = 0;
7974 @@ -648,6 +652,11 @@ arch_get_unmapped_area_topdown(struct fi
7975 mm->free_area_cache = base;
7977 /* requesting a specific address */
7979 +#ifdef CONFIG_PAX_RANDMMAP
7980 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
7984 addr = PAGE_ALIGN(addr);
7985 vma = find_vma(mm, addr);
7986 @@ -727,12 +736,20 @@ fail:
7987 * can happen with large stack limits and large mmap()
7990 - mm->free_area_cache = TASK_UNMAPPED_BASE;
7991 + mm->mmap_base = TASK_UNMAPPED_BASE;
7993 +#ifdef CONFIG_PAX_RANDMMAP
7994 + if (mm->pax_flags & MF_PAX_RANDMMAP)
7995 + mm->mmap_base += mm->delta_mmap;
7998 + mm->free_area_cache = mm->mmap_base;
7999 mm->cached_hole_size = ~0UL;
8000 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
8002 * Restore the topdown base:
8004 + mm->mmap_base = base;
8005 mm->free_area_cache = base;
8006 mm->cached_hole_size = ~0UL;
8008 diff -urNp linux-2.6.20.3/arch/powerpc/mm/mmap.c linux-2.6.20.3/arch/powerpc/mm/mmap.c
8009 --- linux-2.6.20.3/arch/powerpc/mm/mmap.c 2007-03-13 14:27:08.000000000 -0400
8010 +++ linux-2.6.20.3/arch/powerpc/mm/mmap.c 2007-03-23 08:10:06.000000000 -0400
8011 @@ -74,10 +74,22 @@ void arch_pick_mmap_layout(struct mm_str
8013 if (mmap_is_legacy()) {
8014 mm->mmap_base = TASK_UNMAPPED_BASE;
8016 +#ifdef CONFIG_PAX_RANDMMAP
8017 + if (mm->pax_flags & MF_PAX_RANDMMAP)
8018 + mm->mmap_base += mm->delta_mmap;
8021 mm->get_unmapped_area = arch_get_unmapped_area;
8022 mm->unmap_area = arch_unmap_area;
8024 mm->mmap_base = mmap_base();
8026 +#ifdef CONFIG_PAX_RANDMMAP
8027 + if (mm->pax_flags & MF_PAX_RANDMMAP)
8028 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
8031 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8032 mm->unmap_area = arch_unmap_area_topdown;
8034 diff -urNp linux-2.6.20.3/arch/ppc/mm/fault.c linux-2.6.20.3/arch/ppc/mm/fault.c
8035 --- linux-2.6.20.3/arch/ppc/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
8036 +++ linux-2.6.20.3/arch/ppc/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
8038 #include <linux/interrupt.h>
8039 #include <linux/highmem.h>
8040 #include <linux/module.h>
8041 +#include <linux/slab.h>
8042 +#include <linux/pagemap.h>
8043 +#include <linux/compiler.h>
8044 +#include <linux/binfmts.h>
8045 +#include <linux/unistd.h>
8047 #include <asm/page.h>
8048 #include <asm/pgtable.h>
8049 @@ -48,6 +53,364 @@ unsigned long pte_misses; /* updated by
8050 unsigned long pte_errors; /* updated by do_page_fault() */
8051 unsigned int probingmem;
8053 +#ifdef CONFIG_PAX_EMUSIGRT
8054 +void pax_syscall_close(struct vm_area_struct * vma)
8056 + vma->vm_mm->call_syscall = 0UL;
8059 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8061 + struct page* page;
8062 + unsigned int *kaddr;
8064 + page = alloc_page(GFP_HIGHUSER);
8066 + return NOPAGE_OOM;
8068 + kaddr = kmap(page);
8069 + memset(kaddr, 0, PAGE_SIZE);
8070 + kaddr[0] = 0x44000002U; /* sc */
8071 + __flush_dcache_icache(kaddr);
8074 + *type = VM_FAULT_MAJOR;
8078 +static struct vm_operations_struct pax_vm_ops = {
8079 + .close = pax_syscall_close,
8080 + .nopage = pax_syscall_nopage,
8083 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8087 + memset(vma, 0, sizeof(*vma));
8088 + vma->vm_mm = current->mm;
8089 + vma->vm_start = addr;
8090 + vma->vm_end = addr + PAGE_SIZE;
8091 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8092 + vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
8093 + vma->vm_ops = &pax_vm_ops;
8095 + ret = insert_vm_struct(current->mm, vma);
8099 + ++current->mm->total_vm;
8104 +#ifdef CONFIG_PAX_PAGEEXEC
8106 + * PaX: decide what to do with offenders (regs->nip = fault address)
8108 + * returns 1 when task should be killed
8109 + * 2 when patched GOT trampoline was detected
8110 + * 3 when patched PLT trampoline was detected
8111 + * 4 when unpatched PLT trampoline was detected
8112 + * 5 when sigreturn trampoline was detected
8113 + * 6 when rt_sigreturn trampoline was detected
8115 +static int pax_handle_fetch_fault(struct pt_regs *regs)
8118 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
8122 +#ifdef CONFIG_PAX_EMUPLT
8123 + do { /* PaX: patched GOT emulation */
8124 + unsigned int blrl;
8126 + err = get_user(blrl, (unsigned int*)regs->nip);
8128 + if (!err && blrl == 0x4E800021U) {
8129 + unsigned long temp = regs->nip;
8131 + regs->nip = regs->link & 0xFFFFFFFCUL;
8132 + regs->link = temp + 4UL;
8137 + do { /* PaX: patched PLT emulation #1 */
8140 + err = get_user(b, (unsigned int *)regs->nip);
8142 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
8143 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
8148 + do { /* PaX: unpatched PLT emulation #1 */
8149 + unsigned int li, b;
8151 + err = get_user(li, (unsigned int *)regs->nip);
8152 + err |= get_user(b, (unsigned int *)(regs->nip+4));
8154 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8155 + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8156 + unsigned long addr = b | 0xFC000000UL;
8158 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8159 + err = get_user(rlwinm, (unsigned int*)addr);
8160 + err |= get_user(add, (unsigned int*)(addr+4));
8161 + err |= get_user(li2, (unsigned int*)(addr+8));
8162 + err |= get_user(addis2, (unsigned int*)(addr+12));
8163 + err |= get_user(mtctr, (unsigned int*)(addr+16));
8164 + err |= get_user(li3, (unsigned int*)(addr+20));
8165 + err |= get_user(addis3, (unsigned int*)(addr+24));
8166 + err |= get_user(bctr, (unsigned int*)(addr+28));
8171 + if (rlwinm == 0x556C083CU &&
8172 + add == 0x7D6C5A14U &&
8173 + (li2 & 0xFFFF0000U) == 0x39800000U &&
8174 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8175 + mtctr == 0x7D8903A6U &&
8176 + (li3 & 0xFFFF0000U) == 0x39800000U &&
8177 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8178 + bctr == 0x4E800420U)
8180 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8181 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8182 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8183 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8184 + regs->ctr += (addis2 & 0xFFFFU) << 16;
8185 + regs->nip = regs->ctr;
8192 + do { /* PaX: unpatched PLT emulation #2 */
8193 + unsigned int lis, lwzu, b, bctr;
8195 + err = get_user(lis, (unsigned int *)regs->nip);
8196 + err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
8197 + err |= get_user(b, (unsigned int *)(regs->nip+8));
8198 + err |= get_user(bctr, (unsigned int *)(regs->nip+12));
8203 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
8204 + (lwzu & 0xU) == 0xU &&
8205 + (b & 0xFC000003U) == 0x48000000U &&
8206 + bctr == 0x4E800420U)
8208 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8209 + unsigned long addr = b | 0xFC000000UL;
8211 + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8212 + err = get_user(addis, (unsigned int*)addr);
8213 + err |= get_user(addi, (unsigned int*)(addr+4));
8214 + err |= get_user(rlwinm, (unsigned int*)(addr+8));
8215 + err |= get_user(add, (unsigned int*)(addr+12));
8216 + err |= get_user(li2, (unsigned int*)(addr+16));
8217 + err |= get_user(addis2, (unsigned int*)(addr+20));
8218 + err |= get_user(mtctr, (unsigned int*)(addr+24));
8219 + err |= get_user(li3, (unsigned int*)(addr+28));
8220 + err |= get_user(addis3, (unsigned int*)(addr+32));
8221 + err |= get_user(bctr, (unsigned int*)(addr+36));
8226 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8227 + (addi & 0xFFFF0000U) == 0x396B0000U &&
8228 + rlwinm == 0x556C083CU &&
8229 + add == 0x7D6C5A14U &&
8230 + (li2 & 0xFFFF0000U) == 0x39800000U &&
8231 + (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8232 + mtctr == 0x7D8903A6U &&
8233 + (li3 & 0xFFFF0000U) == 0x39800000U &&
8234 + (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8235 + bctr == 0x4E800420U)
8237 + regs->gpr[PT_R11] =
8238 + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8239 + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8240 + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8241 + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8242 + regs->ctr += (addis2 & 0xFFFFU) << 16;
8243 + regs->nip = regs->ctr;
8250 + do { /* PaX: unpatched PLT emulation #3 */
8251 + unsigned int li, b;
8253 + err = get_user(li, (unsigned int *)regs->nip);
8254 + err |= get_user(b, (unsigned int *)(regs->nip+4));
8256 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8257 + unsigned int addis, lwz, mtctr, bctr;
8258 + unsigned long addr = b | 0xFC000000UL;
8260 + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8261 + err = get_user(addis, (unsigned int*)addr);
8262 + err |= get_user(lwz, (unsigned int*)(addr+4));
8263 + err |= get_user(mtctr, (unsigned int*)(addr+8));
8264 + err |= get_user(bctr, (unsigned int*)(addr+12));
8269 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8270 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
8271 + mtctr == 0x7D6903A6U &&
8272 + bctr == 0x4E800420U)
8276 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8277 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8279 + err = get_user(r11, (unsigned int*)addr);
8283 + regs->gpr[PT_R11] = r11;
8292 +#ifdef CONFIG_PAX_EMUSIGRT
8293 + do { /* PaX: sigreturn emulation */
8294 + unsigned int li, sc;
8296 + err = get_user(li, (unsigned int *)regs->nip);
8297 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
8299 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
8300 + struct vm_area_struct *vma;
8301 + unsigned long call_syscall;
8303 + down_read(¤t->mm->mmap_sem);
8304 + call_syscall = current->mm->call_syscall;
8305 + up_read(¤t->mm->mmap_sem);
8306 + if (likely(call_syscall))
8309 + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8311 + down_write(¤t->mm->mmap_sem);
8312 + if (current->mm->call_syscall) {
8313 + call_syscall = current->mm->call_syscall;
8314 + up_write(¤t->mm->mmap_sem);
8315 + if (vma) kmem_cache_free(vm_area_cachep, vma);
8319 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8320 + if (!vma || (call_syscall & ~PAGE_MASK)) {
8321 + up_write(¤t->mm->mmap_sem);
8322 + if (vma) kmem_cache_free(vm_area_cachep, vma);
8326 + if (pax_insert_vma(vma, call_syscall)) {
8327 + up_write(¤t->mm->mmap_sem);
8328 + kmem_cache_free(vm_area_cachep, vma);
8332 + current->mm->call_syscall = call_syscall;
8333 + up_write(¤t->mm->mmap_sem);
8336 + regs->gpr[PT_R0] = __NR_sigreturn;
8337 + regs->nip = call_syscall;
8342 + do { /* PaX: rt_sigreturn emulation */
8343 + unsigned int li, sc;
8345 + err = get_user(li, (unsigned int *)regs->nip);
8346 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
8348 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
8349 + struct vm_area_struct *vma;
8350 + unsigned int call_syscall;
8352 + down_read(¤t->mm->mmap_sem);
8353 + call_syscall = current->mm->call_syscall;
8354 + up_read(¤t->mm->mmap_sem);
8355 + if (likely(call_syscall))
8358 + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8360 + down_write(¤t->mm->mmap_sem);
8361 + if (current->mm->call_syscall) {
8362 + call_syscall = current->mm->call_syscall;
8363 + up_write(¤t->mm->mmap_sem);
8364 + if (vma) kmem_cache_free(vm_area_cachep, vma);
8368 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8369 + if (!vma || (call_syscall & ~PAGE_MASK)) {
8370 + up_write(¤t->mm->mmap_sem);
8371 + if (vma) kmem_cache_free(vm_area_cachep, vma);
8375 + if (pax_insert_vma(vma, call_syscall)) {
8376 + up_write(¤t->mm->mmap_sem);
8377 + kmem_cache_free(vm_area_cachep, vma);
8381 + current->mm->call_syscall = call_syscall;
8382 + up_write(¤t->mm->mmap_sem);
8385 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
8386 + regs->nip = call_syscall;
8395 +void pax_report_insns(void *pc, void *sp)
8399 + printk(KERN_ERR "PAX: bytes at PC: ");
8400 + for (i = 0; i < 5; i++) {
8402 + if (get_user(c, (unsigned int*)pc+i))
8403 + printk("???????? ");
8405 + printk("%08x ", c);
8412 * Check whether the instruction at regs->nip is a store using
8413 * an update addressing form which will update r1.
8414 @@ -108,7 +471,7 @@ int do_page_fault(struct pt_regs *regs,
8415 * indicate errors in DSISR but can validly be set in SRR1.
8417 if (TRAP(regs) == 0x400)
8418 - error_code &= 0x48200000;
8419 + error_code &= 0x58200000;
8421 is_write = error_code & 0x02000000;
8422 #endif /* CONFIG_4xx || CONFIG_BOOKE */
8423 @@ -203,15 +566,14 @@ good_area:
8429 /* It would be nice to actually enforce the VM execute
8430 permission on CPUs which can do so, but far too
8431 much stuff in userspace doesn't get the permissions
8432 right, so we let any page be executed for now. */
8433 if (! (vma->vm_flags & VM_EXEC))
8438 /* Since 4xx/Book-E supports per-page execute permission,
8439 * we lazily flush dcache to icache. */
8441 @@ -234,6 +596,7 @@ good_area:
8442 pte_unmap_unlock(ptep, ptl);
8448 /* protection fault */
8449 @@ -279,6 +642,33 @@ bad_area:
8451 /* User mode accesses cause a SIGSEGV */
8452 if (user_mode(regs)) {
8454 +#ifdef CONFIG_PAX_PAGEEXEC
8455 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
8456 + if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
8457 + switch (pax_handle_fetch_fault(regs)) {
8459 +#ifdef CONFIG_PAX_EMUPLT
8466 +#ifdef CONFIG_PAX_EMUSIGRT
8474 + pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
8480 _exception(SIGSEGV, regs, code, address);
8483 diff -urNp linux-2.6.20.3/arch/s390/kernel/module.c linux-2.6.20.3/arch/s390/kernel/module.c
8484 --- linux-2.6.20.3/arch/s390/kernel/module.c 2007-03-13 14:27:08.000000000 -0400
8485 +++ linux-2.6.20.3/arch/s390/kernel/module.c 2007-03-23 08:10:06.000000000 -0400
8486 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
8488 /* Increase core size by size of got & plt and set start
8489 offsets for got and plt. */
8490 - me->core_size = ALIGN(me->core_size, 4);
8491 - me->arch.got_offset = me->core_size;
8492 - me->core_size += me->arch.got_size;
8493 - me->arch.plt_offset = me->core_size;
8494 - me->core_size += me->arch.plt_size;
8495 + me->core_size_rw = ALIGN(me->core_size_rw, 4);
8496 + me->arch.got_offset = me->core_size_rw;
8497 + me->core_size_rw += me->arch.got_size;
8498 + me->arch.plt_offset = me->core_size_rx;
8499 + me->core_size_rx += me->arch.plt_size;
8503 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8504 if (info->got_initialized == 0) {
8507 - gotent = me->module_core + me->arch.got_offset +
8508 + gotent = me->module_core_rw + me->arch.got_offset +
8511 info->got_initialized = 1;
8512 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8513 else if (r_type == R_390_GOTENT ||
8514 r_type == R_390_GOTPLTENT)
8515 *(unsigned int *) loc =
8516 - (val + (Elf_Addr) me->module_core - loc) >> 1;
8517 + (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
8518 else if (r_type == R_390_GOT64 ||
8519 r_type == R_390_GOTPLT64)
8520 *(unsigned long *) loc = val;
8521 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8522 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
8523 if (info->plt_initialized == 0) {
8525 - ip = me->module_core + me->arch.plt_offset +
8526 + ip = me->module_core_rx + me->arch.plt_offset +
8528 #ifndef CONFIG_64BIT
8529 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
8530 @@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8531 val = me->arch.plt_offset - me->arch.got_offset +
8532 info->plt_offset + rela->r_addend;
8534 - val = (Elf_Addr) me->module_core +
8535 + val = (Elf_Addr) me->module_core_rx +
8536 me->arch.plt_offset + info->plt_offset +
8537 rela->r_addend - loc;
8538 if (r_type == R_390_PLT16DBL)
8539 @@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8540 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
8541 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
8542 val = val + rela->r_addend -
8543 - ((Elf_Addr) me->module_core + me->arch.got_offset);
8544 + ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
8545 if (r_type == R_390_GOTOFF16)
8546 *(unsigned short *) loc = val;
8547 else if (r_type == R_390_GOTOFF32)
8548 @@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8550 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
8551 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
8552 - val = (Elf_Addr) me->module_core + me->arch.got_offset +
8553 + val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
8554 rela->r_addend - loc;
8555 if (r_type == R_390_GOTPC)
8556 *(unsigned int *) loc = val;
8557 diff -urNp linux-2.6.20.3/arch/sparc/kernel/ptrace.c linux-2.6.20.3/arch/sparc/kernel/ptrace.c
8558 --- linux-2.6.20.3/arch/sparc/kernel/ptrace.c 2007-03-13 14:27:08.000000000 -0400
8559 +++ linux-2.6.20.3/arch/sparc/kernel/ptrace.c 2007-03-23 08:11:18.000000000 -0400
8561 #include <linux/security.h>
8562 #include <linux/signal.h>
8563 #include <linux/vs_base.h>
8564 +#include <linux/grsecurity.h>
8566 #include <asm/pgtable.h>
8567 #include <asm/system.h>
8568 @@ -308,6 +309,11 @@ asmlinkage void do_ptrace(struct pt_regs
8572 + if (gr_handle_ptrace(child, request)) {
8573 + pt_error_return(regs, EPERM);
8577 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
8578 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
8579 if (ptrace_attach(child)) {
8580 diff -urNp linux-2.6.20.3/arch/sparc/kernel/sys_sparc.c linux-2.6.20.3/arch/sparc/kernel/sys_sparc.c
8581 --- linux-2.6.20.3/arch/sparc/kernel/sys_sparc.c 2007-03-13 14:27:08.000000000 -0400
8582 +++ linux-2.6.20.3/arch/sparc/kernel/sys_sparc.c 2007-03-23 08:10:06.000000000 -0400
8583 @@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
8584 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
8587 - addr = TASK_UNMAPPED_BASE;
8588 + addr = current->mm->mmap_base;
8590 if (flags & MAP_SHARED)
8591 addr = COLOUR_ALIGN(addr);
8592 diff -urNp linux-2.6.20.3/arch/sparc/Makefile linux-2.6.20.3/arch/sparc/Makefile
8593 --- linux-2.6.20.3/arch/sparc/Makefile 2007-03-13 14:27:08.000000000 -0400
8594 +++ linux-2.6.20.3/arch/sparc/Makefile 2007-03-23 08:11:18.000000000 -0400
8595 @@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
8596 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
8597 INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
8599 -CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
8600 +CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
8601 CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
8602 DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
8603 NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
8604 diff -urNp linux-2.6.20.3/arch/sparc/mm/fault.c linux-2.6.20.3/arch/sparc/mm/fault.c
8605 --- linux-2.6.20.3/arch/sparc/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
8606 +++ linux-2.6.20.3/arch/sparc/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
8608 #include <linux/smp_lock.h>
8609 #include <linux/interrupt.h>
8610 #include <linux/module.h>
8611 +#include <linux/slab.h>
8612 +#include <linux/pagemap.h>
8613 +#include <linux/compiler.h>
8614 +#include <linux/binfmts.h>
8616 #include <asm/system.h>
8617 #include <asm/page.h>
8618 @@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
8619 return safe_compute_effective_address(regs, insn);
8622 +#ifdef CONFIG_PAX_PAGEEXEC
8623 +void pax_emuplt_close(struct vm_area_struct * vma)
8625 + vma->vm_mm->call_dl_resolve = 0UL;
8628 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8630 + struct page* page;
8631 + unsigned int *kaddr;
8633 + page = alloc_page(GFP_HIGHUSER);
8635 + return NOPAGE_OOM;
8637 + kaddr = kmap(page);
8638 + memset(kaddr, 0, PAGE_SIZE);
8639 + kaddr[0] = 0x9DE3BFA8U; /* save */
8640 + flush_dcache_page(page);
8643 + *type = VM_FAULT_MAJOR;
8648 +static struct vm_operations_struct pax_vm_ops = {
8649 + .close = pax_emuplt_close,
8650 + .nopage = pax_emuplt_nopage,
8653 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8657 + memset(vma, 0, sizeof(*vma));
8658 + vma->vm_mm = current->mm;
8659 + vma->vm_start = addr;
8660 + vma->vm_end = addr + PAGE_SIZE;
8661 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8662 + vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
8663 + vma->vm_ops = &pax_vm_ops;
8665 + ret = insert_vm_struct(current->mm, vma);
8669 + ++current->mm->total_vm;
8674 + * PaX: decide what to do with offenders (regs->pc = fault address)
8676 + * returns 1 when task should be killed
8677 + * 2 when patched PLT trampoline was detected
8678 + * 3 when unpatched PLT trampoline was detected
8680 +static int pax_handle_fetch_fault(struct pt_regs *regs)
8683 +#ifdef CONFIG_PAX_EMUPLT
8686 + do { /* PaX: patched PLT emulation #1 */
8687 + unsigned int sethi1, sethi2, jmpl;
8689 + err = get_user(sethi1, (unsigned int*)regs->pc);
8690 + err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
8691 + err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
8696 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8697 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
8698 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
8700 + unsigned int addr;
8702 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
8703 + addr = regs->u_regs[UREG_G1];
8704 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
8706 + regs->npc = addr+4;
8711 + { /* PaX: patched PLT emulation #2 */
8714 + err = get_user(ba, (unsigned int*)regs->pc);
8716 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
8717 + unsigned int addr;
8719 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
8721 + regs->npc = addr+4;
8726 + do { /* PaX: patched PLT emulation #3 */
8727 + unsigned int sethi, jmpl, nop;
8729 + err = get_user(sethi, (unsigned int*)regs->pc);
8730 + err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
8731 + err |= get_user(nop, (unsigned int*)(regs->pc+8));
8736 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
8737 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
8738 + nop == 0x01000000U)
8740 + unsigned int addr;
8742 + addr = (sethi & 0x003FFFFFU) << 10;
8743 + regs->u_regs[UREG_G1] = addr;
8744 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
8746 + regs->npc = addr+4;
8751 + do { /* PaX: unpatched PLT emulation step 1 */
8752 + unsigned int sethi, ba, nop;
8754 + err = get_user(sethi, (unsigned int*)regs->pc);
8755 + err |= get_user(ba, (unsigned int*)(regs->pc+4));
8756 + err |= get_user(nop, (unsigned int*)(regs->pc+8));
8761 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
8762 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
8763 + nop == 0x01000000U)
8765 + unsigned int addr, save, call;
8767 + if ((ba & 0xFFC00000U) == 0x30800000U)
8768 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
8770 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
8772 + err = get_user(save, (unsigned int*)addr);
8773 + err |= get_user(call, (unsigned int*)(addr+4));
8774 + err |= get_user(nop, (unsigned int*)(addr+8));
8778 + if (save == 0x9DE3BFA8U &&
8779 + (call & 0xC0000000U) == 0x40000000U &&
8780 + nop == 0x01000000U)
8782 + struct vm_area_struct *vma;
8783 + unsigned long call_dl_resolve;
8785 + down_read(¤t->mm->mmap_sem);
8786 + call_dl_resolve = current->mm->call_dl_resolve;
8787 + up_read(¤t->mm->mmap_sem);
8788 + if (likely(call_dl_resolve))
8791 + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8793 + down_write(¤t->mm->mmap_sem);
8794 + if (current->mm->call_dl_resolve) {
8795 + call_dl_resolve = current->mm->call_dl_resolve;
8796 + up_write(¤t->mm->mmap_sem);
8797 + if (vma) kmem_cache_free(vm_area_cachep, vma);
8801 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8802 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
8803 + up_write(¤t->mm->mmap_sem);
8804 + if (vma) kmem_cache_free(vm_area_cachep, vma);
8808 + if (pax_insert_vma(vma, call_dl_resolve)) {
8809 + up_write(¤t->mm->mmap_sem);
8810 + kmem_cache_free(vm_area_cachep, vma);
8814 + current->mm->call_dl_resolve = call_dl_resolve;
8815 + up_write(¤t->mm->mmap_sem);
8818 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
8819 + regs->pc = call_dl_resolve;
8820 + regs->npc = addr+4;
8826 + do { /* PaX: unpatched PLT emulation step 2 */
8827 + unsigned int save, call, nop;
8829 + err = get_user(save, (unsigned int*)(regs->pc-4));
8830 + err |= get_user(call, (unsigned int*)regs->pc);
8831 + err |= get_user(nop, (unsigned int*)(regs->pc+4));
8835 + if (save == 0x9DE3BFA8U &&
8836 + (call & 0xC0000000U) == 0x40000000U &&
8837 + nop == 0x01000000U)
8839 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
8841 + regs->u_regs[UREG_RETPC] = regs->pc;
8842 + regs->pc = dl_resolve;
8843 + regs->npc = dl_resolve+4;
8852 +void pax_report_insns(void *pc, void *sp)
8856 + printk(KERN_ERR "PAX: bytes at PC: ");
8857 + for (i = 0; i < 5; i++) {
8859 + if (get_user(c, (unsigned int*)pc+i))
8860 + printk("???????? ");
8862 + printk("%08x ", c);
8868 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
8869 unsigned long address)
8871 @@ -280,6 +530,24 @@ good_area:
8872 if(!(vma->vm_flags & VM_WRITE))
8876 +#ifdef CONFIG_PAX_PAGEEXEC
8877 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
8878 + up_read(&mm->mmap_sem);
8879 + switch (pax_handle_fetch_fault(regs)) {
8881 +#ifdef CONFIG_PAX_EMUPLT
8888 + pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
8893 /* Allow reads even for write-only mappings */
8894 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
8896 diff -urNp linux-2.6.20.3/arch/sparc/mm/init.c linux-2.6.20.3/arch/sparc/mm/init.c
8897 --- linux-2.6.20.3/arch/sparc/mm/init.c 2007-03-13 14:27:08.000000000 -0400
8898 +++ linux-2.6.20.3/arch/sparc/mm/init.c 2007-03-23 08:10:06.000000000 -0400
8899 @@ -333,17 +333,17 @@ void __init paging_init(void)
8901 /* Initialize the protection map with non-constant, MMU dependent values. */
8902 protection_map[0] = PAGE_NONE;
8903 - protection_map[1] = PAGE_READONLY;
8904 - protection_map[2] = PAGE_COPY;
8905 - protection_map[3] = PAGE_COPY;
8906 + protection_map[1] = PAGE_READONLY_NOEXEC;
8907 + protection_map[2] = PAGE_COPY_NOEXEC;
8908 + protection_map[3] = PAGE_COPY_NOEXEC;
8909 protection_map[4] = PAGE_READONLY;
8910 protection_map[5] = PAGE_READONLY;
8911 protection_map[6] = PAGE_COPY;
8912 protection_map[7] = PAGE_COPY;
8913 protection_map[8] = PAGE_NONE;
8914 - protection_map[9] = PAGE_READONLY;
8915 - protection_map[10] = PAGE_SHARED;
8916 - protection_map[11] = PAGE_SHARED;
8917 + protection_map[9] = PAGE_READONLY_NOEXEC;
8918 + protection_map[10] = PAGE_SHARED_NOEXEC;
8919 + protection_map[11] = PAGE_SHARED_NOEXEC;
8920 protection_map[12] = PAGE_READONLY;
8921 protection_map[13] = PAGE_READONLY;
8922 protection_map[14] = PAGE_SHARED;
8923 diff -urNp linux-2.6.20.3/arch/sparc/mm/srmmu.c linux-2.6.20.3/arch/sparc/mm/srmmu.c
8924 --- linux-2.6.20.3/arch/sparc/mm/srmmu.c 2007-03-13 14:27:08.000000000 -0400
8925 +++ linux-2.6.20.3/arch/sparc/mm/srmmu.c 2007-03-23 08:10:06.000000000 -0400
8926 @@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
8927 BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
8928 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
8929 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
8931 +#ifdef CONFIG_PAX_PAGEEXEC
8932 + BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
8933 + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
8934 + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
8937 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
8938 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
8940 diff -urNp linux-2.6.20.3/arch/sparc64/kernel/Makefile linux-2.6.20.3/arch/sparc64/kernel/Makefile
8941 --- linux-2.6.20.3/arch/sparc64/kernel/Makefile 2007-03-13 14:27:08.000000000 -0400
8942 +++ linux-2.6.20.3/arch/sparc64/kernel/Makefile 2007-03-23 08:10:06.000000000 -0400
8946 EXTRA_AFLAGS := -ansi
8947 -EXTRA_CFLAGS := -Werror
8948 +#EXTRA_CFLAGS := -Werror
8950 extra-y := head.o init_task.o vmlinux.lds
8952 diff -urNp linux-2.6.20.3/arch/sparc64/kernel/pci_iommu.c linux-2.6.20.3/arch/sparc64/kernel/pci_iommu.c
8953 --- linux-2.6.20.3/arch/sparc64/kernel/pci_iommu.c 2007-03-13 14:27:08.000000000 -0400
8954 +++ linux-2.6.20.3/arch/sparc64/kernel/pci_iommu.c 2007-03-23 08:10:06.000000000 -0400
8955 @@ -64,7 +64,7 @@ static void __iommu_flushall(struct pci_
8956 #define IOPTE_IS_DUMMY(iommu, iopte) \
8957 ((iopte_val(*iopte) & IOPTE_PAGE) == (iommu)->dummy_page_pa)
8959 -static void inline iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte)
8960 +inline static void iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte)
8962 unsigned long val = iopte_val(*iopte);
8964 diff -urNp linux-2.6.20.3/arch/sparc64/kernel/ptrace.c linux-2.6.20.3/arch/sparc64/kernel/ptrace.c
8965 --- linux-2.6.20.3/arch/sparc64/kernel/ptrace.c 2007-03-13 14:27:08.000000000 -0400
8966 +++ linux-2.6.20.3/arch/sparc64/kernel/ptrace.c 2007-03-23 08:11:31.000000000 -0400
8968 #include <linux/audit.h>
8969 #include <linux/signal.h>
8970 #include <linux/vs_base.h>
8971 +#include <linux/grsecurity.h>
8973 #include <asm/asi.h>
8974 #include <asm/pgtable.h>
8975 @@ -221,6 +222,11 @@ asmlinkage void do_ptrace(struct pt_regs
8979 + if (gr_handle_ptrace(child, (long)request)) {
8980 + pt_error_return(regs, EPERM);
8984 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
8985 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
8986 if (ptrace_attach(child)) {
8987 diff -urNp linux-2.6.20.3/arch/sparc64/kernel/sys_sparc.c linux-2.6.20.3/arch/sparc64/kernel/sys_sparc.c
8988 --- linux-2.6.20.3/arch/sparc64/kernel/sys_sparc.c 2007-03-13 14:27:08.000000000 -0400
8989 +++ linux-2.6.20.3/arch/sparc64/kernel/sys_sparc.c 2007-03-23 08:10:06.000000000 -0400
8990 @@ -140,6 +140,10 @@ unsigned long arch_get_unmapped_area(str
8991 if (filp || (flags & MAP_SHARED))
8994 +#ifdef CONFIG_PAX_RANDMMAP
8995 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
9000 addr = COLOUR_ALIGN(addr, pgoff);
9001 @@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str
9004 if (len > mm->cached_hole_size) {
9005 - start_addr = addr = mm->free_area_cache;
9006 + start_addr = addr = mm->free_area_cache;
9008 - start_addr = addr = TASK_UNMAPPED_BASE;
9009 + start_addr = addr = mm->mmap_base;
9010 mm->cached_hole_size = 0;
9013 @@ -175,8 +179,8 @@ full_search:
9014 vma = find_vma(mm, VA_EXCLUDE_END);
9016 if (unlikely(task_size < addr)) {
9017 - if (start_addr != TASK_UNMAPPED_BASE) {
9018 - start_addr = addr = TASK_UNMAPPED_BASE;
9019 + if (start_addr != mm->mmap_base) {
9020 + start_addr = addr = mm->mmap_base;
9021 mm->cached_hole_size = 0;
9024 @@ -379,6 +383,12 @@ void arch_pick_mmap_layout(struct mm_str
9025 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
9026 sysctl_legacy_va_layout) {
9027 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
9029 +#ifdef CONFIG_PAX_RANDMMAP
9030 + if (mm->pax_flags & MF_PAX_RANDMMAP)
9031 + mm->mmap_base += mm->delta_mmap;
9034 mm->get_unmapped_area = arch_get_unmapped_area;
9035 mm->unmap_area = arch_unmap_area;
9037 @@ -393,6 +403,12 @@ void arch_pick_mmap_layout(struct mm_str
9038 gap = (task_size / 6 * 5);
9040 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
9042 +#ifdef CONFIG_PAX_RANDMMAP
9043 + if (mm->pax_flags & MF_PAX_RANDMMAP)
9044 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
9047 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
9048 mm->unmap_area = arch_unmap_area_topdown;
9050 diff -urNp linux-2.6.20.3/arch/sparc64/mm/fault.c linux-2.6.20.3/arch/sparc64/mm/fault.c
9051 --- linux-2.6.20.3/arch/sparc64/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
9052 +++ linux-2.6.20.3/arch/sparc64/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
9054 #include <linux/interrupt.h>
9055 #include <linux/kprobes.h>
9056 #include <linux/kallsyms.h>
9057 +#include <linux/slab.h>
9058 +#include <linux/pagemap.h>
9059 +#include <linux/compiler.h>
9060 +#include <linux/binfmts.h>
9062 #include <asm/page.h>
9063 #include <asm/pgtable.h>
9064 @@ -290,6 +294,369 @@ cannot_handle:
9065 unhandled_fault (address, current, regs);
9068 +#ifdef CONFIG_PAX_PAGEEXEC
9069 +#ifdef CONFIG_PAX_EMUPLT
9070 +static void pax_emuplt_close(struct vm_area_struct * vma)
9072 + vma->vm_mm->call_dl_resolve = 0UL;
9075 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
9077 + struct page* page;
9078 + unsigned int *kaddr;
9080 + page = alloc_page(GFP_HIGHUSER);
9082 + return NOPAGE_OOM;
9084 + kaddr = kmap(page);
9085 + memset(kaddr, 0, PAGE_SIZE);
9086 + kaddr[0] = 0x9DE3BFA8U; /* save */
9087 + flush_dcache_page(page);
9090 + *type = VM_FAULT_MAJOR;
9094 +static struct vm_operations_struct pax_vm_ops = {
9095 + .close = pax_emuplt_close,
9096 + .nopage = pax_emuplt_nopage,
9099 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
9103 + memset(vma, 0, sizeof(*vma));
9104 + vma->vm_mm = current->mm;
9105 + vma->vm_start = addr;
9106 + vma->vm_end = addr + PAGE_SIZE;
9107 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
9108 + vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
9109 + vma->vm_ops = &pax_vm_ops;
9111 + ret = insert_vm_struct(current->mm, vma);
9115 + ++current->mm->total_vm;
9121 + * PaX: decide what to do with offenders (regs->tpc = fault address)
9123 + * returns 1 when task should be killed
9124 + * 2 when patched PLT trampoline was detected
9125 + * 3 when unpatched PLT trampoline was detected
9127 +static int pax_handle_fetch_fault(struct pt_regs *regs)
9130 +#ifdef CONFIG_PAX_EMUPLT
9133 + do { /* PaX: patched PLT emulation #1 */
9134 + unsigned int sethi1, sethi2, jmpl;
9136 + err = get_user(sethi1, (unsigned int*)regs->tpc);
9137 + err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
9138 + err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
9143 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9144 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
9145 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
9147 + unsigned long addr;
9149 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
9150 + addr = regs->u_regs[UREG_G1];
9151 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
9153 + regs->tnpc = addr+4;
9158 + { /* PaX: patched PLT emulation #2 */
9161 + err = get_user(ba, (unsigned int*)regs->tpc);
9163 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
9164 + unsigned long addr;
9166 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
9168 + regs->tnpc = addr+4;
9173 + do { /* PaX: patched PLT emulation #3 */
9174 + unsigned int sethi, jmpl, nop;
9176 + err = get_user(sethi, (unsigned int*)regs->tpc);
9177 + err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
9178 + err |= get_user(nop, (unsigned int*)(regs->tpc+8));
9183 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
9184 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
9185 + nop == 0x01000000U)
9187 + unsigned long addr;
9189 + addr = (sethi & 0x003FFFFFU) << 10;
9190 + regs->u_regs[UREG_G1] = addr;
9191 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
9193 + regs->tnpc = addr+4;
9198 + do { /* PaX: patched PLT emulation #4 */
9199 + unsigned int mov1, call, mov2;
9201 + err = get_user(mov1, (unsigned int*)regs->tpc);
9202 + err |= get_user(call, (unsigned int*)(regs->tpc+4));
9203 + err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
9208 + if (mov1 == 0x8210000FU &&
9209 + (call & 0xC0000000U) == 0x40000000U &&
9210 + mov2 == 0x9E100001U)
9212 + unsigned long addr;
9214 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
9215 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
9217 + regs->tnpc = addr+4;
9222 + do { /* PaX: patched PLT emulation #5 */
9223 + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
9225 + err = get_user(sethi1, (unsigned int*)regs->tpc);
9226 + err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
9227 + err |= get_user(or1, (unsigned int*)(regs->tpc+8));
9228 + err |= get_user(or2, (unsigned int*)(regs->tpc+12));
9229 + err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
9230 + err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
9231 + err |= get_user(nop, (unsigned int*)(regs->tpc+24));
9236 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9237 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
9238 + (or1 & 0xFFFFE000U) == 0x82106000U &&
9239 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
9240 + sllx == 0x83287020 &&
9241 + jmpl == 0x81C04005U &&
9242 + nop == 0x01000000U)
9244 + unsigned long addr;
9246 + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
9247 + regs->u_regs[UREG_G1] <<= 32;
9248 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
9249 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
9251 + regs->tnpc = addr+4;
9256 + do { /* PaX: patched PLT emulation #6 */
9257 + unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
9259 + err = get_user(sethi1, (unsigned int*)regs->tpc);
9260 + err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
9261 + err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
9262 + err |= get_user(or, (unsigned int*)(regs->tpc+12));
9263 + err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
9264 + err |= get_user(nop, (unsigned int*)(regs->tpc+20));
9269 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9270 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
9271 + sllx == 0x83287020 &&
9272 + (or & 0xFFFFE000U) == 0x8A116000U &&
9273 + jmpl == 0x81C04005U &&
9274 + nop == 0x01000000U)
9276 + unsigned long addr;
9278 + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
9279 + regs->u_regs[UREG_G1] <<= 32;
9280 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
9281 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
9283 + regs->tnpc = addr+4;
9288 + do { /* PaX: patched PLT emulation #7 */
9289 + unsigned int sethi, ba, nop;
9291 + err = get_user(sethi, (unsigned int*)regs->tpc);
9292 + err |= get_user(ba, (unsigned int*)(regs->tpc+4));
9293 + err |= get_user(nop, (unsigned int*)(regs->tpc+8));
9298 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
9299 + (ba & 0xFFF00000U) == 0x30600000U &&
9300 + nop == 0x01000000U)
9302 + unsigned long addr;
9304 + addr = (sethi & 0x003FFFFFU) << 10;
9305 + regs->u_regs[UREG_G1] = addr;
9306 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
9308 + regs->tnpc = addr+4;
9313 + do { /* PaX: unpatched PLT emulation step 1 */
9314 + unsigned int sethi, ba, nop;
9316 + err = get_user(sethi, (unsigned int*)regs->tpc);
9317 + err |= get_user(ba, (unsigned int*)(regs->tpc+4));
9318 + err |= get_user(nop, (unsigned int*)(regs->tpc+8));
9323 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
9324 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
9325 + nop == 0x01000000U)
9327 + unsigned long addr;
9328 + unsigned int save, call;
9330 + if ((ba & 0xFFC00000U) == 0x30800000U)
9331 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
9333 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
9335 + err = get_user(save, (unsigned int*)addr);
9336 + err |= get_user(call, (unsigned int*)(addr+4));
9337 + err |= get_user(nop, (unsigned int*)(addr+8));
9341 + if (save == 0x9DE3BFA8U &&
9342 + (call & 0xC0000000U) == 0x40000000U &&
9343 + nop == 0x01000000U)
9345 + struct vm_area_struct *vma;
9346 + unsigned long call_dl_resolve;
9348 + down_read(¤t->mm->mmap_sem);
9349 + call_dl_resolve = current->mm->call_dl_resolve;
9350 + up_read(¤t->mm->mmap_sem);
9351 + if (likely(call_dl_resolve))
9354 + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9356 + down_write(¤t->mm->mmap_sem);
9357 + if (current->mm->call_dl_resolve) {
9358 + call_dl_resolve = current->mm->call_dl_resolve;
9359 + up_write(¤t->mm->mmap_sem);
9360 + if (vma) kmem_cache_free(vm_area_cachep, vma);
9364 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9365 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
9366 + up_write(¤t->mm->mmap_sem);
9367 + if (vma) kmem_cache_free(vm_area_cachep, vma);
9371 + if (pax_insert_vma(vma, call_dl_resolve)) {
9372 + up_write(¤t->mm->mmap_sem);
9373 + kmem_cache_free(vm_area_cachep, vma);
9377 + current->mm->call_dl_resolve = call_dl_resolve;
9378 + up_write(¤t->mm->mmap_sem);
9381 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
9382 + regs->tpc = call_dl_resolve;
9383 + regs->tnpc = addr+4;
9389 + do { /* PaX: unpatched PLT emulation step 2 */
9390 + unsigned int save, call, nop;
9392 + err = get_user(save, (unsigned int*)(regs->tpc-4));
9393 + err |= get_user(call, (unsigned int*)regs->tpc);
9394 + err |= get_user(nop, (unsigned int*)(regs->tpc+4));
9398 + if (save == 0x9DE3BFA8U &&
9399 + (call & 0xC0000000U) == 0x40000000U &&
9400 + nop == 0x01000000U)
9402 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
9404 + regs->u_regs[UREG_RETPC] = regs->tpc;
9405 + regs->tpc = dl_resolve;
9406 + regs->tnpc = dl_resolve+4;
9415 +void pax_report_insns(void *pc, void *sp)
9419 + printk(KERN_ERR "PAX: bytes at PC: ");
9420 + for (i = 0; i < 5; i++) {
9422 + if (get_user(c, (unsigned int*)pc+i))
9423 + printk("???????? ");
9425 + printk("%08x ", c);
9431 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
9433 struct mm_struct *mm = current->mm;
9434 @@ -332,8 +699,10 @@ asmlinkage void __kprobes do_sparc64_fau
9437 if (test_thread_flag(TIF_32BIT)) {
9438 - if (!(regs->tstate & TSTATE_PRIV))
9439 + if (!(regs->tstate & TSTATE_PRIV)) {
9440 regs->tpc &= 0xffffffff;
9441 + regs->tnpc &= 0xffffffff;
9443 address &= 0xffffffff;
9446 @@ -350,6 +719,29 @@ asmlinkage void __kprobes do_sparc64_fau
9450 +#ifdef CONFIG_PAX_PAGEEXEC
9451 + /* PaX: detect ITLB misses on non-exec pages */
9452 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
9453 + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
9455 + if (address != regs->tpc)
9458 + up_read(&mm->mmap_sem);
9459 + switch (pax_handle_fetch_fault(regs)) {
9461 +#ifdef CONFIG_PAX_EMUPLT
9468 + pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
9473 /* Pure DTLB misses do not tell us whether the fault causing
9474 * load/store/atomic was a write or not, it only says that there
9475 * was no match. So in such a case we (carefully) read the
9476 diff -urNp linux-2.6.20.3/arch/sparc64/mm/Makefile linux-2.6.20.3/arch/sparc64/mm/Makefile
9477 --- linux-2.6.20.3/arch/sparc64/mm/Makefile 2007-03-13 14:27:08.000000000 -0400
9478 +++ linux-2.6.20.3/arch/sparc64/mm/Makefile 2007-03-23 08:10:06.000000000 -0400
9482 EXTRA_AFLAGS := -ansi
9483 -EXTRA_CFLAGS := -Werror
9484 +#EXTRA_CFLAGS := -Werror
9486 obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
9488 diff -urNp linux-2.6.20.3/arch/v850/kernel/module.c linux-2.6.20.3/arch/v850/kernel/module.c
9489 --- linux-2.6.20.3/arch/v850/kernel/module.c 2007-03-13 14:27:08.000000000 -0400
9490 +++ linux-2.6.20.3/arch/v850/kernel/module.c 2007-03-23 08:10:06.000000000 -0400
9491 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
9492 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
9494 /* Init, or core PLT? */
9495 - if (location >= mod->module_core
9496 - && location < mod->module_core + mod->core_size)
9497 + if (location >= mod->module_core_rx
9498 + && location < mod->module_core_rx + mod->core_size_rx)
9499 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
9501 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
9502 diff -urNp linux-2.6.20.3/arch/x86_64/boot/compressed/head.S linux-2.6.20.3/arch/x86_64/boot/compressed/head.S
9503 --- linux-2.6.20.3/arch/x86_64/boot/compressed/head.S 2007-03-13 14:27:08.000000000 -0400
9504 +++ linux-2.6.20.3/arch/x86_64/boot/compressed/head.S 2007-03-23 08:10:06.000000000 -0400
9505 @@ -41,11 +41,13 @@ startup_32:
9508 lss stack_start,%esp
9509 + movl 0x000000,%ecx
9511 1: incl %eax # check that A20 really IS enabled
9512 movl %eax,0x000000 # loop forever if it isn't
9515 + movl %ecx,0x000000
9518 * Initialize eflags. Some BIOS's leave bits like NT set. This would
9519 diff -urNp linux-2.6.20.3/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.20.3/arch/x86_64/ia32/ia32_binfmt.c
9520 --- linux-2.6.20.3/arch/x86_64/ia32/ia32_binfmt.c 2007-03-13 14:27:08.000000000 -0400
9521 +++ linux-2.6.20.3/arch/x86_64/ia32/ia32_binfmt.c 2007-03-23 08:10:06.000000000 -0400
9522 @@ -141,6 +141,17 @@ struct elf_prpsinfo
9523 //#include <asm/ia32.h>
9524 #include <linux/elf.h>
9526 +#ifdef CONFIG_PAX_ASLR
9527 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x08048000UL
9529 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
9530 +#define PAX_DELTA_MMAP_LEN(tsk) 16
9531 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
9532 +#define PAX_DELTA_EXEC_LEN(tsk) 16
9533 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
9534 +#define PAX_DELTA_STACK_LEN(tsk) 16
9537 typedef struct user_i387_ia32_struct elf_fpregset_t;
9538 typedef struct user32_fxsr_struct elf_fpxregset_t;
9540 diff -urNp linux-2.6.20.3/arch/x86_64/ia32/mmap32.c linux-2.6.20.3/arch/x86_64/ia32/mmap32.c
9541 --- linux-2.6.20.3/arch/x86_64/ia32/mmap32.c 2007-03-13 14:27:08.000000000 -0400
9542 +++ linux-2.6.20.3/arch/x86_64/ia32/mmap32.c 2007-03-23 08:10:06.000000000 -0400
9543 @@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
9544 (current->personality & ADDR_COMPAT_LAYOUT) ||
9545 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
9546 mm->mmap_base = TASK_UNMAPPED_BASE;
9548 +#ifdef CONFIG_PAX_RANDMMAP
9549 + if (mm->pax_flags & MF_PAX_RANDMMAP)
9550 + mm->mmap_base += mm->delta_mmap;
9553 mm->get_unmapped_area = arch_get_unmapped_area;
9554 mm->unmap_area = arch_unmap_area;
9556 mm->mmap_base = mmap_base(mm);
9558 +#ifdef CONFIG_PAX_RANDMMAP
9559 + if (mm->pax_flags & MF_PAX_RANDMMAP)
9560 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
9563 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
9564 mm->unmap_area = arch_unmap_area_topdown;
9566 diff -urNp linux-2.6.20.3/arch/x86_64/ia32/syscall32.c linux-2.6.20.3/arch/x86_64/ia32/syscall32.c
9567 --- linux-2.6.20.3/arch/x86_64/ia32/syscall32.c 2007-03-13 14:27:08.000000000 -0400
9568 +++ linux-2.6.20.3/arch/x86_64/ia32/syscall32.c 2007-03-23 08:10:06.000000000 -0400
9569 @@ -49,16 +49,21 @@ int syscall32_setup_pages(struct linux_b
9570 struct mm_struct *mm = current->mm;
9573 - vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9574 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
9578 - memset(vma, 0, sizeof(struct vm_area_struct));
9579 /* Could randomize here */
9580 vma->vm_start = VSYSCALL32_BASE;
9581 vma->vm_end = VSYSCALL32_END;
9582 /* MAYWRITE to allow gdb to COW and set breakpoints */
9583 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
9585 +#ifdef CONFIG_PAX_MPROTECT
9586 + if (mm->pax_flags & MF_PAX_MPROTECT)
9587 + vma->vm_flags &= ~VM_MAYWRITE;
9591 * Make sure the vDSO gets into every core dump.
9592 * Dumping its contents makes post-mortem fully interpretable later
9593 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/ioport.c linux-2.6.20.3/arch/x86_64/kernel/ioport.c
9594 --- linux-2.6.20.3/arch/x86_64/kernel/ioport.c 2007-03-13 14:27:08.000000000 -0400
9595 +++ linux-2.6.20.3/arch/x86_64/kernel/ioport.c 2007-03-23 08:11:31.000000000 -0400
9596 @@ -41,8 +41,16 @@ asmlinkage long sys_ioperm(unsigned long
9598 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
9601 +#ifdef CONFIG_GRKERNSEC_IO
9603 + gr_handle_ioperm();
9607 if (turn_on && !capable(CAP_SYS_RAWIO))
9612 * If it's the first ioperm() call in this thread's lifetime, set the
9613 @@ -111,8 +119,13 @@ asmlinkage long sys_iopl(unsigned int le
9615 /* Trying to gain more privileges? */
9617 +#ifdef CONFIG_GRKERNSEC_IO
9621 if (!capable(CAP_SYS_RAWIO))
9625 regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
9627 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/process.c linux-2.6.20.3/arch/x86_64/kernel/process.c
9628 --- linux-2.6.20.3/arch/x86_64/kernel/process.c 2007-03-13 14:27:08.000000000 -0400
9629 +++ linux-2.6.20.3/arch/x86_64/kernel/process.c 2007-03-23 08:10:06.000000000 -0400
9630 @@ -878,10 +878,3 @@ int dump_task_regs(struct task_struct *t
9635 -unsigned long arch_align_stack(unsigned long sp)
9637 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
9638 - sp -= get_random_int() % 8192;
9641 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/ptrace.c linux-2.6.20.3/arch/x86_64/kernel/ptrace.c
9642 --- linux-2.6.20.3/arch/x86_64/kernel/ptrace.c 2007-03-13 14:27:08.000000000 -0400
9643 +++ linux-2.6.20.3/arch/x86_64/kernel/ptrace.c 2007-03-23 08:11:31.000000000 -0400
9645 #include <linux/audit.h>
9646 #include <linux/seccomp.h>
9647 #include <linux/signal.h>
9648 +#include <linux/grsecurity.h>
9650 #include <asm/uaccess.h>
9651 #include <asm/pgtable.h>
9652 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/setup64.c linux-2.6.20.3/arch/x86_64/kernel/setup64.c
9653 --- linux-2.6.20.3/arch/x86_64/kernel/setup64.c 2007-03-13 14:27:08.000000000 -0400
9654 +++ linux-2.6.20.3/arch/x86_64/kernel/setup64.c 2007-03-23 08:10:06.000000000 -0400
9655 @@ -38,7 +38,6 @@ char boot_cpu_stack[IRQSTACKSIZE] __attr
9657 unsigned long __supported_pte_mask __read_mostly = ~0UL;
9658 EXPORT_SYMBOL(__supported_pte_mask);
9659 -static int do_not_nx __cpuinitdata = 0;
9662 Control non executable mappings for 64bit processes.
9663 @@ -52,16 +51,14 @@ static int __init nonx_setup(char *str)
9665 if (!strncmp(str, "on", 2)) {
9666 __supported_pte_mask |= _PAGE_NX;
9668 } else if (!strncmp(str, "off", 3)) {
9670 __supported_pte_mask &= ~_PAGE_NX;
9674 early_param("noexec", nonx_setup);
9676 -int force_personality32 = 0;
9677 +int force_personality32;
9680 Control non executable heap for 32bit processes.
9681 @@ -175,7 +172,7 @@ void __cpuinit check_efer(void)
9684 rdmsrl(MSR_EFER, efer);
9685 - if (!(efer & EFER_NX) || do_not_nx) {
9686 + if (!(efer & EFER_NX)) {
9687 __supported_pte_mask &= ~_PAGE_NX;
9690 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/signal.c linux-2.6.20.3/arch/x86_64/kernel/signal.c
9691 --- linux-2.6.20.3/arch/x86_64/kernel/signal.c 2007-03-13 14:27:08.000000000 -0400
9692 +++ linux-2.6.20.3/arch/x86_64/kernel/signal.c 2007-03-23 08:10:06.000000000 -0400
9693 @@ -254,8 +254,8 @@ static int setup_rt_frame(int sig, struc
9694 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
9695 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
9696 if (sizeof(*set) == 16) {
9697 - __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
9698 - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
9699 + err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
9700 + err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
9702 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
9704 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/sys_x86_64.c linux-2.6.20.3/arch/x86_64/kernel/sys_x86_64.c
9705 --- linux-2.6.20.3/arch/x86_64/kernel/sys_x86_64.c 2007-03-13 14:27:08.000000000 -0400
9706 +++ linux-2.6.20.3/arch/x86_64/kernel/sys_x86_64.c 2007-03-23 08:10:06.000000000 -0400
9707 @@ -65,8 +65,8 @@ out:
9711 -static void find_start_end(unsigned long flags, unsigned long *begin,
9712 - unsigned long *end)
9713 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
9714 + unsigned long *begin, unsigned long *end)
9716 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
9717 /* This is usually used needed to map code in small
9718 @@ -79,7 +79,7 @@ static void find_start_end(unsigned long
9719 *begin = 0x40000000;
9722 - *begin = TASK_UNMAPPED_BASE;
9723 + *begin = mm->mmap_base;
9727 @@ -93,11 +93,15 @@ arch_get_unmapped_area(struct file *filp
9728 unsigned long start_addr;
9729 unsigned long begin, end;
9731 - find_start_end(flags, &begin, &end);
9732 + find_start_end(mm, flags, &begin, &end);
9737 +#ifdef CONFIG_PAX_RANDMMAP
9738 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
9742 addr = PAGE_ALIGN(addr);
9743 vma = find_vma(mm, addr);
9744 diff -urNp linux-2.6.20.3/arch/x86_64/mm/fault.c linux-2.6.20.3/arch/x86_64/mm/fault.c
9745 --- linux-2.6.20.3/arch/x86_64/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
9746 +++ linux-2.6.20.3/arch/x86_64/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
9748 #include <linux/module.h>
9749 #include <linux/kprobes.h>
9750 #include <linux/uaccess.h>
9751 +#include <linux/binfmts.h>
9753 #include <asm/system.h>
9754 #include <asm/pgalloc.h>
9755 @@ -322,6 +323,33 @@ static int vmalloc_fault(unsigned long a
9759 +#ifdef CONFIG_PAX_PAGEEXEC
9760 +void pax_report_insns(void *pc, void *sp)
9764 + printk(KERN_ERR "PAX: bytes at PC: ");
9765 + for (i = 0; i < 20; i++) {
9767 + if (get_user(c, (unsigned char __user *)pc+i))
9770 + printk("%02x ", c);
9774 + printk(KERN_ERR "PAX: bytes at SP-8: ");
9775 + for (i = -1; i < 10; i++) {
9777 + if (get_user(c, (unsigned long __user *)sp+i))
9778 + printk("???????????????? ");
9780 + printk("%016lx ", c);
9786 int page_fault_trace = 0;
9787 int exception_trace = 1;
9789 @@ -453,6 +481,8 @@ asmlinkage void __kprobes do_page_fault(
9791 info.si_code = SEGV_ACCERR;
9793 + if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
9795 switch (error_code & (PF_PROT|PF_WRITE)) {
9796 default: /* 3: write, present */
9798 @@ -519,7 +549,14 @@ bad_area_nosemaphore:
9799 tsk->comm, tsk->pid, tsk->xid, address,
9800 regs->rip, regs->rsp, error_code);
9804 +#ifdef CONFIG_PAX_PAGEEXEC
9805 + if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
9806 + pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
9811 tsk->thread.cr2 = address;
9812 /* Kernel addresses are always protection faults */
9813 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
9814 diff -urNp linux-2.6.20.3/arch/x86_64/mm/mmap.c linux-2.6.20.3/arch/x86_64/mm/mmap.c
9815 --- linux-2.6.20.3/arch/x86_64/mm/mmap.c 2007-03-13 14:27:08.000000000 -0400
9816 +++ linux-2.6.20.3/arch/x86_64/mm/mmap.c 2007-03-23 08:10:06.000000000 -0400
9817 @@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
9818 unsigned rnd = get_random_int() & 0xfffffff;
9819 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
9822 +#ifdef CONFIG_PAX_RANDMMAP
9823 + if (mm->pax_flags & MF_PAX_RANDMMAP)
9824 + mm->mmap_base += mm->delta_mmap;
9827 mm->get_unmapped_area = arch_get_unmapped_area;
9828 mm->unmap_area = arch_unmap_area;
9830 diff -urNp linux-2.6.20.3/crypto/lrw.c linux-2.6.20.3/crypto/lrw.c
9831 --- linux-2.6.20.3/crypto/lrw.c 2007-03-13 14:27:08.000000000 -0400
9832 +++ linux-2.6.20.3/crypto/lrw.c 2007-03-23 08:10:06.000000000 -0400
9833 @@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
9834 struct priv *ctx = crypto_tfm_ctx(parent);
9835 struct crypto_cipher *child = ctx->child;
9837 - be128 tmp = { 0 };
9838 + be128 tmp = { 0, 0 };
9839 int bsize = crypto_cipher_blocksize(child);
9841 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
9842 diff -urNp linux-2.6.20.3/Documentation/dontdiff linux-2.6.20.3/Documentation/dontdiff
9843 --- linux-2.6.20.3/Documentation/dontdiff 2007-03-13 14:27:08.000000000 -0400
9844 +++ linux-2.6.20.3/Documentation/dontdiff 2007-03-23 08:10:05.000000000 -0400
9845 @@ -55,7 +55,7 @@ aic7*seq.h*
9854 @@ -127,6 +127,7 @@ pss_boot.h
9862 @@ -139,8 +140,11 @@ utsrelease.h*
9874 diff -urNp linux-2.6.20.3/drivers/acpi/blacklist.c linux-2.6.20.3/drivers/acpi/blacklist.c
9875 --- linux-2.6.20.3/drivers/acpi/blacklist.c 2007-03-13 14:27:08.000000000 -0400
9876 +++ linux-2.6.20.3/drivers/acpi/blacklist.c 2007-03-23 08:10:06.000000000 -0400
9877 @@ -70,7 +70,7 @@ static struct acpi_blacklist_item acpi_b
9878 {"ASUS\0\0", "P2B-S ", 0, ACPI_DSDT, all_versions,
9879 "Bogus PCI routing", 1},
9882 + {"", "", 0, 0, 0, all_versions, 0}
9885 #if CONFIG_ACPI_BLACKLIST_YEAR
9886 diff -urNp linux-2.6.20.3/drivers/acpi/glue.c linux-2.6.20.3/drivers/acpi/glue.c
9887 --- linux-2.6.20.3/drivers/acpi/glue.c 2007-03-13 14:27:08.000000000 -0400
9888 +++ linux-2.6.20.3/drivers/acpi/glue.c 2007-03-23 08:10:06.000000000 -0400
9891 #define DBG(x...) printk(PREFIX x)
9894 +#define DBG(x...) do {} while (0)
9896 static LIST_HEAD(bus_type_list);
9897 static DECLARE_RWSEM(bus_type_sem);
9898 diff -urNp linux-2.6.20.3/drivers/acpi/processor_core.c linux-2.6.20.3/drivers/acpi/processor_core.c
9899 --- linux-2.6.20.3/drivers/acpi/processor_core.c 2007-03-13 14:27:08.000000000 -0400
9900 +++ linux-2.6.20.3/drivers/acpi/processor_core.c 2007-03-23 08:10:06.000000000 -0400
9901 @@ -531,7 +531,7 @@ static int __cpuinit acpi_processor_star
9905 - BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
9906 + BUG_ON(pr->id >= NR_CPUS);
9910 diff -urNp linux-2.6.20.3/drivers/acpi/processor_idle.c linux-2.6.20.3/drivers/acpi/processor_idle.c
9911 --- linux-2.6.20.3/drivers/acpi/processor_idle.c 2007-03-13 14:27:08.000000000 -0400
9912 +++ linux-2.6.20.3/drivers/acpi/processor_idle.c 2007-03-23 08:10:06.000000000 -0400
9913 @@ -153,7 +153,7 @@ static struct dmi_system_id __cpuinitdat
9914 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
9915 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
9918 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
9921 static inline u32 ticks_elapsed(u32 t1, u32 t2)
9922 diff -urNp linux-2.6.20.3/drivers/acpi/sleep/main.c linux-2.6.20.3/drivers/acpi/sleep/main.c
9923 --- linux-2.6.20.3/drivers/acpi/sleep/main.c 2007-03-13 14:27:08.000000000 -0400
9924 +++ linux-2.6.20.3/drivers/acpi/sleep/main.c 2007-03-23 08:10:06.000000000 -0400
9925 @@ -197,7 +197,7 @@ static struct dmi_system_id __initdata a
9926 .ident = "Toshiba Satellite 4030cdt",
9927 .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
9930 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
9933 static int __init acpi_sleep_init(void)
9934 diff -urNp linux-2.6.20.3/drivers/ata/ata_piix.c linux-2.6.20.3/drivers/ata/ata_piix.c
9935 --- linux-2.6.20.3/drivers/ata/ata_piix.c 2007-03-13 14:27:08.000000000 -0400
9936 +++ linux-2.6.20.3/drivers/ata/ata_piix.c 2007-03-23 08:10:06.000000000 -0400
9937 @@ -247,7 +247,7 @@ static const struct pci_device_id piix_p
9938 /* SATA Controller IDE (ICH9M) */
9939 { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
9941 - { } /* terminate list */
9942 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
9945 static struct pci_driver piix_pci_driver = {
9946 @@ -574,7 +574,7 @@ static const struct ich_laptop ich_lapto
9947 /* devid, subvendor, subdev */
9948 { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
9955 diff -urNp linux-2.6.20.3/drivers/ata/libata-core.c linux-2.6.20.3/drivers/ata/libata-core.c
9956 --- linux-2.6.20.3/drivers/ata/libata-core.c 2007-03-13 14:27:08.000000000 -0400
9957 +++ linux-2.6.20.3/drivers/ata/libata-core.c 2007-03-23 08:10:06.000000000 -0400
9958 @@ -460,7 +460,7 @@ static const struct ata_xfer_ent {
9959 { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
9960 { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
9961 { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
9967 @@ -2226,7 +2226,7 @@ static const struct ata_timing ata_timin
9969 /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
9972 + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
9975 #define ENOUGH(v,unit) (((v)-1)/(unit)+1)
9976 @@ -3321,7 +3321,7 @@ static const struct ata_blacklist_entry
9977 /* Devices with NCQ limits */
9984 static int ata_strim(char *s, size_t len)
9985 diff -urNp linux-2.6.20.3/drivers/char/agp/frontend.c linux-2.6.20.3/drivers/char/agp/frontend.c
9986 --- linux-2.6.20.3/drivers/char/agp/frontend.c 2007-03-13 14:27:08.000000000 -0400
9987 +++ linux-2.6.20.3/drivers/char/agp/frontend.c 2007-03-23 08:10:06.000000000 -0400
9988 @@ -818,7 +818,7 @@ static int agpioc_reserve_wrap(struct ag
9989 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
9992 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
9993 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
9996 client = agp_find_client_by_pid(reserve.pid);
9997 diff -urNp linux-2.6.20.3/drivers/char/agp/intel-agp.c linux-2.6.20.3/drivers/char/agp/intel-agp.c
9998 --- linux-2.6.20.3/drivers/char/agp/intel-agp.c 2007-03-13 14:27:08.000000000 -0400
9999 +++ linux-2.6.20.3/drivers/char/agp/intel-agp.c 2007-03-23 08:10:06.000000000 -0400
10000 @@ -2026,7 +2026,7 @@ static struct pci_device_id agp_intel_pc
10001 ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
10002 ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
10003 ID(PCI_DEVICE_ID_INTEL_82965G_HB),
10005 + { 0, 0, 0, 0, 0, 0, 0 }
10008 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
10009 diff -urNp linux-2.6.20.3/drivers/char/drm/drm_drawable.c linux-2.6.20.3/drivers/char/drm/drm_drawable.c
10010 --- linux-2.6.20.3/drivers/char/drm/drm_drawable.c 2007-03-13 14:27:08.000000000 -0400
10011 +++ linux-2.6.20.3/drivers/char/drm/drm_drawable.c 2007-03-23 08:10:06.000000000 -0400
10012 @@ -234,7 +234,7 @@ int drm_update_drawable_info(DRM_IOCTL_A
10013 idx = id / (8 * sizeof(*bitfield));
10014 shift = id % (8 * sizeof(*bitfield));
10016 - if (idx < 0 || idx >= bitfield_length ||
10017 + if (idx >= bitfield_length ||
10018 !(bitfield[idx] & (1 << shift))) {
10019 DRM_ERROR("No such drawable %d\n", update.handle);
10020 return DRM_ERR(EINVAL);
10021 @@ -319,7 +319,7 @@ drm_drawable_info_t *drm_get_drawable_in
10022 idx = id / (8 * sizeof(*bitfield));
10023 shift = id % (8 * sizeof(*bitfield));
10025 - if (idx < 0 || idx >= dev->drw_bitfield_length ||
10026 + if (idx >= dev->drw_bitfield_length ||
10027 !(bitfield[idx] & (1 << shift))) {
10028 DRM_DEBUG("No such drawable %d\n", id);
10030 diff -urNp linux-2.6.20.3/drivers/char/drm/drm_pciids.h linux-2.6.20.3/drivers/char/drm/drm_pciids.h
10031 --- linux-2.6.20.3/drivers/char/drm/drm_pciids.h 2007-03-13 14:27:08.000000000 -0400
10032 +++ linux-2.6.20.3/drivers/char/drm/drm_pciids.h 2007-03-23 08:10:06.000000000 -0400
10033 @@ -239,7 +239,7 @@
10034 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10035 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10036 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10038 + {0, 0, 0, 0, 0, 0, 0 }
10040 #define i830_PCI_IDS \
10041 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10042 diff -urNp linux-2.6.20.3/drivers/char/hpet.c linux-2.6.20.3/drivers/char/hpet.c
10043 --- linux-2.6.20.3/drivers/char/hpet.c 2007-03-13 14:27:08.000000000 -0400
10044 +++ linux-2.6.20.3/drivers/char/hpet.c 2007-03-23 08:10:06.000000000 -0400
10045 @@ -1008,7 +1008,7 @@ static struct acpi_driver hpet_acpi_driv
10049 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
10050 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
10052 static int __init hpet_init(void)
10054 diff -urNp linux-2.6.20.3/drivers/char/hw_random/intel-rng.c linux-2.6.20.3/drivers/char/hw_random/intel-rng.c
10055 --- linux-2.6.20.3/drivers/char/hw_random/intel-rng.c 2007-03-13 14:27:08.000000000 -0400
10056 +++ linux-2.6.20.3/drivers/char/hw_random/intel-rng.c 2007-03-23 08:10:06.000000000 -0400
10057 @@ -139,7 +139,7 @@ static const struct pci_device_id pci_tb
10059 { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
10060 { 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E */
10061 - { 0, }, /* terminate list */
10062 + { 0, 0, 0, 0, 0, 0, 0 }, /* terminate list */
10064 MODULE_DEVICE_TABLE(pci, pci_tbl);
10066 diff -urNp linux-2.6.20.3/drivers/char/keyboard.c linux-2.6.20.3/drivers/char/keyboard.c
10067 --- linux-2.6.20.3/drivers/char/keyboard.c 2007-03-13 14:27:08.000000000 -0400
10068 +++ linux-2.6.20.3/drivers/char/keyboard.c 2007-03-23 08:11:31.000000000 -0400
10069 @@ -203,7 +203,7 @@ int setkeycode(unsigned int scancode, un
10071 if (scancode >= dev->keycodemax)
10073 - if (keycode < 0 || keycode > KEY_MAX)
10074 + if (keycode > KEY_MAX)
10076 if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
10078 @@ -628,6 +628,16 @@ static void k_spec(struct vc_data *vc, u
10079 kbd->kbdmode == VC_MEDIUMRAW) &&
10080 value != KVAL(K_SAK))
10081 return; /* SAK is allowed even in raw mode */
10083 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
10085 + void *func = fn_handler[value];
10086 + if (func == fn_show_state || func == fn_show_ptregs ||
10087 + func == fn_show_mem)
10092 fn_handler[value](vc);
10095 @@ -1354,7 +1364,7 @@ static const struct input_device_id kbd_
10096 .evbit = { BIT(EV_SND) },
10099 - { }, /* Terminating entry */
10100 + { 0 }, /* Terminating entry */
10103 MODULE_DEVICE_TABLE(input, kbd_ids);
10104 diff -urNp linux-2.6.20.3/drivers/char/mem.c linux-2.6.20.3/drivers/char/mem.c
10105 --- linux-2.6.20.3/drivers/char/mem.c 2007-03-13 14:27:08.000000000 -0400
10106 +++ linux-2.6.20.3/drivers/char/mem.c 2007-03-23 08:11:31.000000000 -0400
10108 #include <linux/bootmem.h>
10109 #include <linux/pipe_fs_i.h>
10110 #include <linux/pfn.h>
10111 +#include <linux/grsecurity.h>
10113 #include <asm/uaccess.h>
10114 #include <asm/io.h>
10116 # include <linux/efi.h>
10119 +#ifdef CONFIG_GRKERNSEC
10120 +extern struct file_operations grsec_fops;
10124 * Architectures vary in how they handle caching for addresses
10125 * outside of main memory.
10126 @@ -174,6 +179,11 @@ static ssize_t write_mem(struct file * f
10127 if (!valid_phys_addr_range(p, count))
10130 +#ifdef CONFIG_GRKERNSEC_KMEM
10131 + gr_handle_mem_write();
10137 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
10138 @@ -275,6 +285,11 @@ static int mmap_mem(struct file * file,
10139 if (!private_mapping_ok(vma))
10142 +#ifdef CONFIG_GRKERNSEC_KMEM
10143 + if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
10147 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
10149 vma->vm_page_prot);
10150 @@ -506,6 +521,11 @@ static ssize_t write_kmem(struct file *
10152 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
10154 +#ifdef CONFIG_GRKERNSEC_KMEM
10155 + gr_handle_kmem_write();
10159 if (p < (unsigned long) high_memory) {
10162 @@ -645,8 +665,24 @@ static inline size_t read_zero_pagealign
10166 +#ifdef CONFIG_PAX_SEGMEXEC
10167 + if (vma->vm_flags & VM_MIRROR) {
10168 + unsigned long addr_m;
10169 + struct vm_area_struct * vma_m;
10171 + addr_m = vma->vm_start + vma->vm_mirror;
10172 + vma_m = find_vma(mm, addr_m);
10173 + if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
10174 + addr_m = addr + vma->vm_mirror;
10175 + zap_page_range(vma_m, addr_m, count, NULL);
10177 + printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
10178 + addr, vma->vm_start);
10182 zap_page_range(vma, addr, count, NULL);
10183 - if (zeromap_page_range(vma, addr, count, PAGE_COPY))
10184 + if (zeromap_page_range(vma, addr, count, vma->vm_page_prot))
10188 @@ -799,6 +835,16 @@ static loff_t memory_lseek(struct file *
10190 static int open_port(struct inode * inode, struct file * filp)
10192 +#ifdef CONFIG_GRKERNSEC_KMEM
10193 + gr_handle_open_port();
10197 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
10200 +static int open_mem(struct inode * inode, struct file * filp)
10202 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
10205 @@ -806,7 +852,6 @@ static int open_port(struct inode * inod
10206 #define full_lseek null_lseek
10207 #define write_zero write_null
10208 #define read_full read_zero
10209 -#define open_mem open_port
10210 #define open_kmem open_mem
10211 #define open_oldmem open_mem
10213 @@ -939,6 +984,11 @@ static int memory_open(struct inode * in
10214 filp->f_op = &oldmem_fops;
10217 +#ifdef CONFIG_GRKERNSEC
10219 + filp->f_op = &grsec_fops;
10225 @@ -971,6 +1021,9 @@ static const struct {
10226 #ifdef CONFIG_CRASH_DUMP
10227 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
10229 +#ifdef CONFIG_GRKERNSEC
10230 + {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
10234 static struct class *mem_class;
10235 diff -urNp linux-2.6.20.3/drivers/char/n_tty.c linux-2.6.20.3/drivers/char/n_tty.c
10236 --- linux-2.6.20.3/drivers/char/n_tty.c 2007-03-13 14:27:08.000000000 -0400
10237 +++ linux-2.6.20.3/drivers/char/n_tty.c 2007-03-23 08:10:06.000000000 -0400
10238 @@ -1559,6 +1559,8 @@ struct tty_ldisc tty_ldisc_N_TTY = {
10239 normal_poll, /* poll */
10241 n_tty_receive_buf, /* receive_buf */
10242 - n_tty_write_wakeup /* write_wakeup */
10243 + n_tty_write_wakeup, /* write_wakeup */
10244 + NULL, /* owner */
10248 diff -urNp linux-2.6.20.3/drivers/char/nvram.c linux-2.6.20.3/drivers/char/nvram.c
10249 --- linux-2.6.20.3/drivers/char/nvram.c 2007-03-13 14:27:08.000000000 -0400
10250 +++ linux-2.6.20.3/drivers/char/nvram.c 2007-03-23 08:10:06.000000000 -0400
10251 @@ -450,7 +450,10 @@ static const struct file_operations nvra
10252 static struct miscdevice nvram_dev = {
10263 diff -urNp linux-2.6.20.3/drivers/char/random.c linux-2.6.20.3/drivers/char/random.c
10264 --- linux-2.6.20.3/drivers/char/random.c 2007-03-13 14:27:08.000000000 -0400
10265 +++ linux-2.6.20.3/drivers/char/random.c 2007-03-23 08:43:07.000000000 -0400
10266 @@ -248,8 +248,13 @@
10268 * Configuration information
10270 +#ifdef CONFIG_GRKERNSEC_RANDNET
10271 +#define INPUT_POOL_WORDS 512
10272 +#define OUTPUT_POOL_WORDS 128
10274 #define INPUT_POOL_WORDS 128
10275 #define OUTPUT_POOL_WORDS 32
10277 #define SEC_XFER_SIZE 512
10280 @@ -286,10 +291,17 @@ static struct poolinfo {
10282 int tap1, tap2, tap3, tap4, tap5;
10283 } poolinfo_table[] = {
10284 +#ifdef CONFIG_GRKERNSEC_RANDNET
10285 + /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
10286 + { 512, 411, 308, 208, 104, 1 },
10287 + /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
10288 + { 128, 103, 76, 51, 25, 1 },
10290 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
10291 { 128, 103, 76, 51, 25, 1 },
10292 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
10293 { 32, 26, 20, 14, 7, 1 },
10296 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
10297 { 2048, 1638, 1231, 819, 411, 1 },
10298 @@ -1662,3 +1674,25 @@ randomize_range(unsigned long start, uns
10300 return PAGE_ALIGN(get_random_int() % range + start);
10303 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
10304 +unsigned long pax_get_random_long(void)
10306 + static time_t rekey_time;
10307 + static __u32 secret[12];
10311 + * Pick a random secret every REKEY_INTERVAL seconds.
10313 + t = get_seconds();
10314 + if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
10316 + get_random_bytes(secret, sizeof(secret));
10319 + secret[1] = half_md4_transform(secret+8, secret);
10320 + secret[0] = half_md4_transform(secret+8, secret);
10321 + return *(unsigned long *)secret;
10324 diff -urNp linux-2.6.20.3/drivers/char/vt_ioctl.c linux-2.6.20.3/drivers/char/vt_ioctl.c
10325 --- linux-2.6.20.3/drivers/char/vt_ioctl.c 2007-03-13 14:27:08.000000000 -0400
10326 +++ linux-2.6.20.3/drivers/char/vt_ioctl.c 2007-03-23 08:11:31.000000000 -0400
10327 @@ -95,6 +95,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
10332 +#ifdef CONFIG_GRKERNSEC
10333 + if (!capable(CAP_SYS_TTY_CONFIG))
10337 if (!i && v == K_NOSUCHMAP) {
10338 /* deallocate map */
10339 key_map = key_maps[s];
10340 @@ -235,6 +241,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
10344 +#ifdef CONFIG_GRKERNSEC
10345 + if (!capable(CAP_SYS_TTY_CONFIG)) {
10352 first_free = funcbufptr + (funcbufsize - funcbufleft);
10353 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
10354 diff -urNp linux-2.6.20.3/drivers/edac/edac_mc.h linux-2.6.20.3/drivers/edac/edac_mc.h
10355 --- linux-2.6.20.3/drivers/edac/edac_mc.h 2007-03-13 14:27:08.000000000 -0400
10356 +++ linux-2.6.20.3/drivers/edac/edac_mc.h 2007-03-23 08:10:06.000000000 -0400
10357 @@ -71,11 +71,11 @@ extern int edac_debug_level;
10359 #else /* !CONFIG_EDAC_DEBUG */
10361 -#define debugf0( ... )
10362 -#define debugf1( ... )
10363 -#define debugf2( ... )
10364 -#define debugf3( ... )
10365 -#define debugf4( ... )
10366 +#define debugf0( ... ) do {} while (0)
10367 +#define debugf1( ... ) do {} while (0)
10368 +#define debugf2( ... ) do {} while (0)
10369 +#define debugf3( ... ) do {} while (0)
10370 +#define debugf4( ... ) do {} while (0)
10372 #endif /* !CONFIG_EDAC_DEBUG */
10374 diff -urNp linux-2.6.20.3/drivers/hwmon/fscpos.c linux-2.6.20.3/drivers/hwmon/fscpos.c
10375 --- linux-2.6.20.3/drivers/hwmon/fscpos.c 2007-03-13 14:27:08.000000000 -0400
10376 +++ linux-2.6.20.3/drivers/hwmon/fscpos.c 2007-03-23 08:10:06.000000000 -0400
10377 @@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
10378 unsigned long v = simple_strtoul(buf, NULL, 10);
10380 /* Range: 0..255 */
10381 - if (v < 0) v = 0;
10382 if (v > 255) v = 255;
10384 mutex_lock(&data->update_lock);
10385 diff -urNp linux-2.6.20.3/drivers/hwmon/k8temp.c linux-2.6.20.3/drivers/hwmon/k8temp.c
10386 --- linux-2.6.20.3/drivers/hwmon/k8temp.c 2007-03-13 14:27:08.000000000 -0400
10387 +++ linux-2.6.20.3/drivers/hwmon/k8temp.c 2007-03-23 08:10:06.000000000 -0400
10388 @@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
10390 static struct pci_device_id k8temp_ids[] = {
10391 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
10393 + { 0, 0, 0, 0, 0, 0, 0 },
10396 MODULE_DEVICE_TABLE(pci, k8temp_ids);
10397 diff -urNp linux-2.6.20.3/drivers/hwmon/sis5595.c linux-2.6.20.3/drivers/hwmon/sis5595.c
10398 --- linux-2.6.20.3/drivers/hwmon/sis5595.c 2007-03-13 14:27:08.000000000 -0400
10399 +++ linux-2.6.20.3/drivers/hwmon/sis5595.c 2007-03-23 08:10:06.000000000 -0400
10400 @@ -757,7 +757,7 @@ static struct sis5595_data *sis5595_upda
10402 static struct pci_device_id sis5595_pci_ids[] = {
10403 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
10405 + { 0, 0, 0, 0, 0, 0, 0 }
10408 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
10409 diff -urNp linux-2.6.20.3/drivers/hwmon/via686a.c linux-2.6.20.3/drivers/hwmon/via686a.c
10410 --- linux-2.6.20.3/drivers/hwmon/via686a.c 2007-03-13 14:27:08.000000000 -0400
10411 +++ linux-2.6.20.3/drivers/hwmon/via686a.c 2007-03-23 08:10:06.000000000 -0400
10412 @@ -814,7 +814,7 @@ static struct via686a_data *via686a_upda
10414 static struct pci_device_id via686a_pci_ids[] = {
10415 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
10417 + { 0, 0, 0, 0, 0, 0, 0 }
10420 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
10421 diff -urNp linux-2.6.20.3/drivers/hwmon/vt8231.c linux-2.6.20.3/drivers/hwmon/vt8231.c
10422 --- linux-2.6.20.3/drivers/hwmon/vt8231.c 2007-03-13 14:27:08.000000000 -0400
10423 +++ linux-2.6.20.3/drivers/hwmon/vt8231.c 2007-03-23 08:10:06.000000000 -0400
10424 @@ -666,7 +666,7 @@ static struct i2c_driver vt8231_driver =
10426 static struct pci_device_id vt8231_pci_ids[] = {
10427 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
10429 + { 0, 0, 0, 0, 0, 0, 0 }
10432 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
10433 diff -urNp linux-2.6.20.3/drivers/hwmon/w83791d.c linux-2.6.20.3/drivers/hwmon/w83791d.c
10434 --- linux-2.6.20.3/drivers/hwmon/w83791d.c 2007-03-13 14:27:08.000000000 -0400
10435 +++ linux-2.6.20.3/drivers/hwmon/w83791d.c 2007-03-23 08:10:06.000000000 -0400
10436 @@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct
10437 static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
10438 static int w83791d_detach_client(struct i2c_client *client);
10440 -static int w83791d_read(struct i2c_client *client, u8 register);
10441 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
10442 +static int w83791d_read(struct i2c_client *client, u8 reg);
10443 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
10444 static struct w83791d_data *w83791d_update_device(struct device *dev);
10447 diff -urNp linux-2.6.20.3/drivers/i2c/busses/i2c-i801.c linux-2.6.20.3/drivers/i2c/busses/i2c-i801.c
10448 --- linux-2.6.20.3/drivers/i2c/busses/i2c-i801.c 2007-03-13 14:27:08.000000000 -0400
10449 +++ linux-2.6.20.3/drivers/i2c/busses/i2c-i801.c 2007-03-23 08:10:06.000000000 -0400
10450 @@ -459,7 +459,7 @@ static struct pci_device_id i801_ids[] =
10451 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
10452 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
10453 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
10455 + { 0, 0, 0, 0, 0, 0, 0 }
10458 MODULE_DEVICE_TABLE (pci, i801_ids);
10459 diff -urNp linux-2.6.20.3/drivers/i2c/busses/i2c-i810.c linux-2.6.20.3/drivers/i2c/busses/i2c-i810.c
10460 --- linux-2.6.20.3/drivers/i2c/busses/i2c-i810.c 2007-03-13 14:27:08.000000000 -0400
10461 +++ linux-2.6.20.3/drivers/i2c/busses/i2c-i810.c 2007-03-23 08:10:06.000000000 -0400
10462 @@ -196,7 +196,7 @@ static struct pci_device_id i810_ids[] _
10463 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
10464 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
10465 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
10467 + { 0, 0, 0, 0, 0, 0, 0 },
10470 MODULE_DEVICE_TABLE (pci, i810_ids);
10471 diff -urNp linux-2.6.20.3/drivers/i2c/busses/i2c-piix4.c linux-2.6.20.3/drivers/i2c/busses/i2c-piix4.c
10472 --- linux-2.6.20.3/drivers/i2c/busses/i2c-piix4.c 2007-03-13 14:27:08.000000000 -0400
10473 +++ linux-2.6.20.3/drivers/i2c/busses/i2c-piix4.c 2007-03-23 08:10:06.000000000 -0400
10474 @@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat
10476 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
10479 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
10482 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
10483 @@ -408,7 +408,7 @@ static struct pci_device_id piix4_ids[]
10484 .driver_data = 3 },
10485 { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
10486 .driver_data = 0 },
10488 + { 0, 0, 0, 0, 0, 0, 0 }
10491 MODULE_DEVICE_TABLE (pci, piix4_ids);
10492 diff -urNp linux-2.6.20.3/drivers/i2c/i2c-core.c linux-2.6.20.3/drivers/i2c/i2c-core.c
10493 --- linux-2.6.20.3/drivers/i2c/i2c-core.c 2007-03-13 14:27:08.000000000 -0400
10494 +++ linux-2.6.20.3/drivers/i2c/i2c-core.c 2007-03-23 08:10:06.000000000 -0400
10495 @@ -113,7 +113,7 @@ static ssize_t i2c_adapter_show_name(str
10497 static struct class_device_attribute i2c_adapter_attrs[] = {
10498 __ATTR(name, S_IRUGO, i2c_adapter_show_name, NULL),
10500 + { {NULL, NULL, 0}, NULL, NULL },
10503 struct class i2c_adapter_class = {
10504 diff -urNp linux-2.6.20.3/drivers/ide/ide-cd.c linux-2.6.20.3/drivers/ide/ide-cd.c
10505 --- linux-2.6.20.3/drivers/ide/ide-cd.c 2007-03-13 14:27:08.000000000 -0400
10506 +++ linux-2.6.20.3/drivers/ide/ide-cd.c 2007-03-23 08:10:06.000000000 -0400
10507 @@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
10508 sector &= ~(bio_sectors -1);
10509 valid = (sector - failed_command->sector) << 9;
10513 if (sector < get_capacity(info->disk) &&
10514 drive->probed_capacity - sector < 4 * 75) {
10515 set_capacity(info->disk, sector);
10516 diff -urNp linux-2.6.20.3/drivers/ieee1394/dv1394.c linux-2.6.20.3/drivers/ieee1394/dv1394.c
10517 --- linux-2.6.20.3/drivers/ieee1394/dv1394.c 2007-03-13 14:27:08.000000000 -0400
10518 +++ linux-2.6.20.3/drivers/ieee1394/dv1394.c 2007-03-23 08:10:06.000000000 -0400
10519 @@ -740,7 +740,7 @@ static void frame_prepare(struct video_c
10520 based upon DIF section and sequence
10523 -static void inline
10524 +static inline void
10525 frame_put_packet (struct frame *f, struct packet *p)
10527 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
10528 @@ -919,7 +919,7 @@ static int do_dv1394_init(struct video_c
10529 /* default SYT offset is 3 cycles */
10530 init->syt_offset = 3;
10532 - if ( (init->channel > 63) || (init->channel < 0) )
10533 + if (init->channel > 63)
10534 init->channel = 63;
10536 chan_mask = (u64)1 << init->channel;
10537 @@ -2174,7 +2174,7 @@ static struct ieee1394_device_id dv1394_
10538 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
10539 .version = AVC_SW_VERSION_ENTRY & 0xffffff
10542 + { 0, 0, 0, 0, 0, 0 }
10545 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
10546 diff -urNp linux-2.6.20.3/drivers/ieee1394/eth1394.c linux-2.6.20.3/drivers/ieee1394/eth1394.c
10547 --- linux-2.6.20.3/drivers/ieee1394/eth1394.c 2007-03-13 14:27:08.000000000 -0400
10548 +++ linux-2.6.20.3/drivers/ieee1394/eth1394.c 2007-03-23 08:10:06.000000000 -0400
10549 @@ -468,7 +468,7 @@ static struct ieee1394_device_id eth1394
10550 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
10551 .version = ETHER1394_GASP_VERSION,
10554 + { 0, 0, 0, 0, 0, 0 }
10557 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
10558 diff -urNp linux-2.6.20.3/drivers/ieee1394/hosts.c linux-2.6.20.3/drivers/ieee1394/hosts.c
10559 --- linux-2.6.20.3/drivers/ieee1394/hosts.c 2007-03-13 14:27:08.000000000 -0400
10560 +++ linux-2.6.20.3/drivers/ieee1394/hosts.c 2007-03-23 08:10:06.000000000 -0400
10561 @@ -79,6 +79,7 @@ static int dummy_isoctl(struct hpsb_iso
10564 static struct hpsb_host_driver dummy_driver = {
10566 .transmit_packet = dummy_transmit_packet,
10567 .devctl = dummy_devctl,
10568 .isoctl = dummy_isoctl
10569 diff -urNp linux-2.6.20.3/drivers/ieee1394/ohci1394.c linux-2.6.20.3/drivers/ieee1394/ohci1394.c
10570 --- linux-2.6.20.3/drivers/ieee1394/ohci1394.c 2007-03-13 14:27:08.000000000 -0400
10571 +++ linux-2.6.20.3/drivers/ieee1394/ohci1394.c 2007-03-23 08:10:06.000000000 -0400
10572 @@ -161,9 +161,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
10573 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
10575 /* Module Parameters */
10576 -static int phys_dma = 1;
10577 +static int phys_dma = 0;
10578 module_param(phys_dma, int, 0444);
10579 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
10580 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
10582 static void dma_trm_tasklet(unsigned long data);
10583 static void dma_trm_reset(struct dma_trm_ctx *d);
10584 @@ -3645,7 +3645,7 @@ static struct pci_device_id ohci1394_pci
10585 .subvendor = PCI_ANY_ID,
10586 .subdevice = PCI_ANY_ID,
10589 + { 0, 0, 0, 0, 0, 0, 0 },
10592 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
10593 diff -urNp linux-2.6.20.3/drivers/ieee1394/raw1394.c linux-2.6.20.3/drivers/ieee1394/raw1394.c
10594 --- linux-2.6.20.3/drivers/ieee1394/raw1394.c 2007-03-13 14:27:08.000000000 -0400
10595 +++ linux-2.6.20.3/drivers/ieee1394/raw1394.c 2007-03-23 08:10:06.000000000 -0400
10596 @@ -2981,7 +2981,7 @@ static struct ieee1394_device_id raw1394
10597 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
10598 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
10599 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
10601 + { 0, 0, 0, 0, 0, 0 }
10604 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
10605 diff -urNp linux-2.6.20.3/drivers/ieee1394/sbp2.c linux-2.6.20.3/drivers/ieee1394/sbp2.c
10606 --- linux-2.6.20.3/drivers/ieee1394/sbp2.c 2007-03-13 14:27:08.000000000 -0400
10607 +++ linux-2.6.20.3/drivers/ieee1394/sbp2.c 2007-03-23 08:10:06.000000000 -0400
10608 @@ -250,7 +250,7 @@ static struct ieee1394_device_id sbp2_id
10609 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
10610 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
10611 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
10613 + { 0, 0, 0, 0, 0, 0 }
10615 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
10617 @@ -2118,7 +2118,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
10618 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
10619 MODULE_LICENSE("GPL");
10621 -static int sbp2_module_init(void)
10622 +static int __init sbp2_module_init(void)
10626 diff -urNp linux-2.6.20.3/drivers/ieee1394/video1394.c linux-2.6.20.3/drivers/ieee1394/video1394.c
10627 --- linux-2.6.20.3/drivers/ieee1394/video1394.c 2007-03-13 14:27:08.000000000 -0400
10628 +++ linux-2.6.20.3/drivers/ieee1394/video1394.c 2007-03-23 08:10:06.000000000 -0400
10629 @@ -894,7 +894,7 @@ static long video1394_ioctl(struct file
10630 if (unlikely(d == NULL))
10633 - if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
10634 + if (unlikely(v.buffer>=d->num_desc - 1)) {
10635 PRINT(KERN_ERR, ohci->host->id,
10636 "Buffer %d out of range",v.buffer);
10638 @@ -960,7 +960,7 @@ static long video1394_ioctl(struct file
10639 if (unlikely(d == NULL))
10642 - if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
10643 + if (unlikely(v.buffer>d->num_desc - 1)) {
10644 PRINT(KERN_ERR, ohci->host->id,
10645 "Buffer %d out of range",v.buffer);
10647 @@ -1031,7 +1031,7 @@ static long video1394_ioctl(struct file
10648 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
10649 if (d == NULL) return -EFAULT;
10651 - if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
10652 + if (v.buffer>=d->num_desc - 1) {
10653 PRINT(KERN_ERR, ohci->host->id,
10654 "Buffer %d out of range",v.buffer);
10656 @@ -1138,7 +1138,7 @@ static long video1394_ioctl(struct file
10657 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
10658 if (d == NULL) return -EFAULT;
10660 - if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
10661 + if (v.buffer>=d->num_desc-1) {
10662 PRINT(KERN_ERR, ohci->host->id,
10663 "Buffer %d out of range",v.buffer);
10665 @@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
10666 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
10667 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
10670 + { 0, 0, 0, 0, 0, 0 }
10673 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
10674 diff -urNp linux-2.6.20.3/drivers/input/keyboard/atkbd.c linux-2.6.20.3/drivers/input/keyboard/atkbd.c
10675 --- linux-2.6.20.3/drivers/input/keyboard/atkbd.c 2007-03-13 14:27:08.000000000 -0400
10676 +++ linux-2.6.20.3/drivers/input/keyboard/atkbd.c 2007-03-23 08:10:06.000000000 -0400
10677 @@ -1065,7 +1065,7 @@ static struct serio_device_id atkbd_seri
10679 .extra = SERIO_ANY,
10685 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
10686 diff -urNp linux-2.6.20.3/drivers/input/mouse/lifebook.c linux-2.6.20.3/drivers/input/mouse/lifebook.c
10687 --- linux-2.6.20.3/drivers/input/mouse/lifebook.c 2007-03-13 14:27:08.000000000 -0400
10688 +++ linux-2.6.20.3/drivers/input/mouse/lifebook.c 2007-03-23 08:10:06.000000000 -0400
10689 @@ -63,7 +63,7 @@ static struct dmi_system_id lifebook_dmi
10690 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
10694 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
10697 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
10698 diff -urNp linux-2.6.20.3/drivers/input/mouse/psmouse-base.c linux-2.6.20.3/drivers/input/mouse/psmouse-base.c
10699 --- linux-2.6.20.3/drivers/input/mouse/psmouse-base.c 2007-03-13 14:27:08.000000000 -0400
10700 +++ linux-2.6.20.3/drivers/input/mouse/psmouse-base.c 2007-03-23 08:10:06.000000000 -0400
10701 @@ -1282,7 +1282,7 @@ static struct serio_device_id psmouse_se
10703 .extra = SERIO_ANY,
10709 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
10710 diff -urNp linux-2.6.20.3/drivers/input/mouse/synaptics.c linux-2.6.20.3/drivers/input/mouse/synaptics.c
10711 --- linux-2.6.20.3/drivers/input/mouse/synaptics.c 2007-03-13 14:27:08.000000000 -0400
10712 +++ linux-2.6.20.3/drivers/input/mouse/synaptics.c 2007-03-23 08:10:06.000000000 -0400
10713 @@ -380,7 +380,7 @@ static void synaptics_process_packet(str
10716 if (SYN_MODEL_PEN(priv->model_id))
10717 - ; /* Nothing, treat a pen as a single finger */
10718 + break; /* Nothing, treat a pen as a single finger */
10721 if (SYN_CAP_PALMDETECT(priv->capabilities))
10722 @@ -617,7 +617,7 @@ static struct dmi_system_id toshiba_dmi_
10723 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
10727 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
10731 diff -urNp linux-2.6.20.3/drivers/input/mousedev.c linux-2.6.20.3/drivers/input/mousedev.c
10732 --- linux-2.6.20.3/drivers/input/mousedev.c 2007-03-13 14:27:08.000000000 -0400
10733 +++ linux-2.6.20.3/drivers/input/mousedev.c 2007-03-23 08:10:06.000000000 -0400
10734 @@ -731,7 +731,7 @@ static struct input_handler mousedev_han
10736 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
10737 static struct miscdevice psaux_mouse = {
10738 - PSMOUSE_MINOR, "psaux", &mousedev_fops
10739 + PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
10741 static int psaux_registered;
10743 diff -urNp linux-2.6.20.3/drivers/input/serio/i8042-x86ia64io.h linux-2.6.20.3/drivers/input/serio/i8042-x86ia64io.h
10744 --- linux-2.6.20.3/drivers/input/serio/i8042-x86ia64io.h 2007-03-13 14:27:08.000000000 -0400
10745 +++ linux-2.6.20.3/drivers/input/serio/i8042-x86ia64io.h 2007-03-23 08:10:06.000000000 -0400
10746 @@ -92,7 +92,7 @@ static struct dmi_system_id __initdata i
10747 DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
10751 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
10755 @@ -201,7 +201,7 @@ static struct dmi_system_id __initdata i
10756 DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
10760 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
10764 diff -urNp linux-2.6.20.3/drivers/input/serio/libps2.c linux-2.6.20.3/drivers/input/serio/libps2.c
10765 --- linux-2.6.20.3/drivers/input/serio/libps2.c 2007-03-13 14:27:08.000000000 -0400
10766 +++ linux-2.6.20.3/drivers/input/serio/libps2.c 2007-03-23 08:10:06.000000000 -0400
10767 @@ -97,7 +97,7 @@ EXPORT_SYMBOL(ps2_drain);
10769 int ps2_is_keyboard_id(char id_byte)
10771 - const static char keyboard_ids[] = {
10772 + static const char keyboard_ids[] = {
10773 0xab, /* Regular keyboards */
10774 0xac, /* NCD Sun keyboard */
10775 0x2b, /* Trust keyboard, translated */
10776 diff -urNp linux-2.6.20.3/drivers/input/serio/serio_raw.c linux-2.6.20.3/drivers/input/serio/serio_raw.c
10777 --- linux-2.6.20.3/drivers/input/serio/serio_raw.c 2007-03-13 14:27:08.000000000 -0400
10778 +++ linux-2.6.20.3/drivers/input/serio/serio_raw.c 2007-03-23 08:10:06.000000000 -0400
10779 @@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
10781 .extra = SERIO_ANY,
10787 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
10788 diff -urNp linux-2.6.20.3/drivers/kvm/kvm_main.c linux-2.6.20.3/drivers/kvm/kvm_main.c
10789 --- linux-2.6.20.3/drivers/kvm/kvm_main.c 2007-03-13 14:27:08.000000000 -0400
10790 +++ linux-2.6.20.3/drivers/kvm/kvm_main.c 2007-03-23 08:10:06.000000000 -0400
10791 @@ -50,19 +50,19 @@ static struct kvm_stats_debugfs_item {
10793 struct dentry *dentry;
10794 } debugfs_entries[] = {
10795 - { "pf_fixed", &kvm_stat.pf_fixed },
10796 - { "pf_guest", &kvm_stat.pf_guest },
10797 - { "tlb_flush", &kvm_stat.tlb_flush },
10798 - { "invlpg", &kvm_stat.invlpg },
10799 - { "exits", &kvm_stat.exits },
10800 - { "io_exits", &kvm_stat.io_exits },
10801 - { "mmio_exits", &kvm_stat.mmio_exits },
10802 - { "signal_exits", &kvm_stat.signal_exits },
10803 - { "irq_window", &kvm_stat.irq_window_exits },
10804 - { "halt_exits", &kvm_stat.halt_exits },
10805 - { "request_irq", &kvm_stat.request_irq_exits },
10806 - { "irq_exits", &kvm_stat.irq_exits },
10808 + { "pf_fixed", &kvm_stat.pf_fixed, NULL },
10809 + { "pf_guest", &kvm_stat.pf_guest, NULL },
10810 + { "tlb_flush", &kvm_stat.tlb_flush, NULL },
10811 + { "invlpg", &kvm_stat.invlpg, NULL },
10812 + { "exits", &kvm_stat.exits, NULL },
10813 + { "io_exits", &kvm_stat.io_exits, NULL },
10814 + { "mmio_exits", &kvm_stat.mmio_exits, NULL },
10815 + { "signal_exits", &kvm_stat.signal_exits, NULL },
10816 + { "irq_window", &kvm_stat.irq_window_exits, NULL },
10817 + { "halt_exits", &kvm_stat.halt_exits, NULL },
10818 + { "request_irq", &kvm_stat.request_irq_exits, NULL },
10819 + { "irq_exits", &kvm_stat.irq_exits, NULL },
10823 static struct dentry *debugfs_dir;
10824 @@ -1741,7 +1741,7 @@ static int kvm_dev_ioctl_interrupt(struc
10826 if (!valid_vcpu(irq->vcpu))
10828 - if (irq->irq < 0 || irq->irq >= 256)
10829 + if (irq->irq >= 256)
10831 vcpu = vcpu_load(kvm, irq->vcpu);
10833 @@ -2003,6 +2003,9 @@ static struct miscdevice kvm_dev = {
10834 MISC_DYNAMIC_MINOR,
10842 static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
10843 diff -urNp linux-2.6.20.3/drivers/kvm/vmx.c linux-2.6.20.3/drivers/kvm/vmx.c
10844 --- linux-2.6.20.3/drivers/kvm/vmx.c 2007-03-13 14:27:08.000000000 -0400
10845 +++ linux-2.6.20.3/drivers/kvm/vmx.c 2007-03-23 08:10:06.000000000 -0400
10846 @@ -1860,7 +1860,7 @@ again:
10847 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
10849 #ifndef CONFIG_X86_64
10850 - asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
10851 + asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
10855 diff -urNp linux-2.6.20.3/drivers/md/bitmap.c linux-2.6.20.3/drivers/md/bitmap.c
10856 --- linux-2.6.20.3/drivers/md/bitmap.c 2007-03-13 14:27:08.000000000 -0400
10857 +++ linux-2.6.20.3/drivers/md/bitmap.c 2007-03-23 08:10:06.000000000 -0400
10860 # define PRINTK(x...) printk(KERN_DEBUG x)
10862 -# define PRINTK(x...)
10863 +# define PRINTK(x...) do {} while (0)
10867 diff -urNp linux-2.6.20.3/drivers/mtd/devices/doc2001.c linux-2.6.20.3/drivers/mtd/devices/doc2001.c
10868 --- linux-2.6.20.3/drivers/mtd/devices/doc2001.c 2007-03-13 14:27:08.000000000 -0400
10869 +++ linux-2.6.20.3/drivers/mtd/devices/doc2001.c 2007-03-23 08:11:31.000000000 -0400
10870 @@ -401,6 +401,8 @@ static int doc_read (struct mtd_info *mt
10871 /* Don't allow read past end of device */
10872 if (from >= this->totlen)
10877 /* Don't allow a single read to cross a 512-byte block boundary */
10878 if (from + len > ((from | 0x1ff) + 1))
10879 diff -urNp linux-2.6.20.3/drivers/net/eepro100.c linux-2.6.20.3/drivers/net/eepro100.c
10880 --- linux-2.6.20.3/drivers/net/eepro100.c 2007-03-13 14:27:08.000000000 -0400
10881 +++ linux-2.6.20.3/drivers/net/eepro100.c 2007-03-23 08:10:06.000000000 -0400
10882 @@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
10883 # define rx_align(skb) skb_reserve((skb), 2)
10884 # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
10886 -# define rx_align(skb)
10887 +# define rx_align(skb) do {} while (0)
10888 # define RxFD_ALIGNMENT
10891 @@ -2339,33 +2339,33 @@ static void __devexit eepro100_remove_on
10894 static struct pci_device_id eepro100_pci_tbl[] = {
10895 - { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
10896 - { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
10897 - { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
10898 - { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
10899 - { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
10900 - { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
10901 - { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
10902 - { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
10903 - { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
10904 - { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
10905 - { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
10906 - { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
10907 - { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
10908 - { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
10909 - { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
10910 - { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
10911 - { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
10912 - { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
10913 - { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
10914 - { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
10915 - { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
10916 - { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
10917 - { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
10918 - { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
10919 - { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
10920 - { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
10922 + { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10923 + { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10924 + { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10925 + { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10926 + { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10927 + { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10928 + { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10929 + { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10930 + { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10931 + { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10932 + { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10933 + { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10934 + { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10935 + { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10936 + { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10937 + { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10938 + { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10939 + { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10940 + { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10941 + { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10942 + { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10943 + { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10944 + { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10945 + { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10946 + { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10947 + { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10948 + { 0, 0, 0, 0, 0, 0, 0 }
10950 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
10952 diff -urNp linux-2.6.20.3/drivers/net/pcnet32.c linux-2.6.20.3/drivers/net/pcnet32.c
10953 --- linux-2.6.20.3/drivers/net/pcnet32.c 2007-03-13 14:27:08.000000000 -0400
10954 +++ linux-2.6.20.3/drivers/net/pcnet32.c 2007-03-23 08:10:06.000000000 -0400
10955 @@ -82,7 +82,7 @@ static int cards_found;
10957 * VLB I/O addresses
10959 -static unsigned int pcnet32_portlist[] __initdata =
10960 +static unsigned int pcnet32_portlist[] __devinitdata =
10961 { 0x300, 0x320, 0x340, 0x360, 0 };
10963 static int pcnet32_debug = 0;
10964 diff -urNp linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv.c linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv.c
10965 --- linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv.c 2007-03-13 14:27:08.000000000 -0400
10966 +++ linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv.c 2007-03-23 08:10:06.000000000 -0400
10967 @@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
10968 .port_type = PCIE_RC_PORT,
10969 .service_type = PCIE_PORT_SERVICE_AER,
10971 - { /* end: all zeroes */ }
10972 + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
10975 static struct pci_error_handlers aer_error_handlers = {
10976 diff -urNp linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv_core.c
10977 --- linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv_core.c 2007-03-13 14:27:08.000000000 -0400
10978 +++ linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv_core.c 2007-03-23 08:10:06.000000000 -0400
10979 @@ -647,7 +647,7 @@ static void aer_isr_one_error(struct pci
10980 struct aer_err_source *e_src)
10982 struct device *s_device;
10983 - struct aer_err_info e_info = {0, 0, 0,};
10984 + struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
10988 diff -urNp linux-2.6.20.3/drivers/pci/pcie/portdrv_pci.c linux-2.6.20.3/drivers/pci/pcie/portdrv_pci.c
10989 --- linux-2.6.20.3/drivers/pci/pcie/portdrv_pci.c 2007-03-13 14:27:08.000000000 -0400
10990 +++ linux-2.6.20.3/drivers/pci/pcie/portdrv_pci.c 2007-03-23 08:10:06.000000000 -0400
10991 @@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
10992 static const struct pci_device_id port_pci_ids[] = { {
10993 /* handle any PCI-Express port */
10994 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
10995 - }, { /* end: all zeroes */ }
10996 + }, { 0, 0, 0, 0, 0, 0, 0 }
10998 MODULE_DEVICE_TABLE(pci, port_pci_ids);
11000 diff -urNp linux-2.6.20.3/drivers/pci/proc.c linux-2.6.20.3/drivers/pci/proc.c
11001 --- linux-2.6.20.3/drivers/pci/proc.c 2007-03-13 14:27:08.000000000 -0400
11002 +++ linux-2.6.20.3/drivers/pci/proc.c 2007-03-23 08:11:31.000000000 -0400
11003 @@ -467,7 +467,15 @@ static int __init pci_proc_init(void)
11005 struct proc_dir_entry *entry;
11006 struct pci_dev *dev = NULL;
11007 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11008 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11009 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
11010 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11011 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
11014 proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
11016 entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
11018 entry->proc_fops = &proc_bus_pci_dev_operations;
11019 diff -urNp linux-2.6.20.3/drivers/pcmcia/ti113x.h linux-2.6.20.3/drivers/pcmcia/ti113x.h
11020 --- linux-2.6.20.3/drivers/pcmcia/ti113x.h 2007-03-13 14:27:08.000000000 -0400
11021 +++ linux-2.6.20.3/drivers/pcmcia/ti113x.h 2007-03-23 08:10:06.000000000 -0400
11022 @@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
11023 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
11024 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
11027 + { 0, 0, 0, 0, 0, 0, 0 }
11030 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
11031 diff -urNp linux-2.6.20.3/drivers/pcmcia/yenta_socket.c linux-2.6.20.3/drivers/pcmcia/yenta_socket.c
11032 --- linux-2.6.20.3/drivers/pcmcia/yenta_socket.c 2007-03-13 14:27:08.000000000 -0400
11033 +++ linux-2.6.20.3/drivers/pcmcia/yenta_socket.c 2007-03-23 08:10:06.000000000 -0400
11034 @@ -1359,7 +1359,7 @@ static struct pci_device_id yenta_table
11036 /* match any cardbus bridge */
11037 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
11038 - { /* all zeroes */ }
11039 + { 0, 0, 0, 0, 0, 0, 0 }
11041 MODULE_DEVICE_TABLE(pci, yenta_table);
11043 diff -urNp linux-2.6.20.3/drivers/pnp/pnpbios/bioscalls.c linux-2.6.20.3/drivers/pnp/pnpbios/bioscalls.c
11044 --- linux-2.6.20.3/drivers/pnp/pnpbios/bioscalls.c 2007-03-13 14:27:08.000000000 -0400
11045 +++ linux-2.6.20.3/drivers/pnp/pnpbios/bioscalls.c 2007-03-23 08:10:06.000000000 -0400
11046 @@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
11047 set_limit(gdt[(selname) >> 3], size); \
11050 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
11051 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
11054 * At some point we want to use this stack frame pointer to unwind
11055 @@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
11056 struct desc_struct save_desc_40;
11059 +#ifdef CONFIG_PAX_KERNEXEC
11060 + unsigned long cr0;
11064 * PnP BIOSes are generally not terribly re-entrant.
11065 * Also, don't rely on them to save everything correctly.
11066 @@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
11067 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
11068 spin_lock_irqsave(&pnp_bios_lock, flags);
11070 +#ifdef CONFIG_PAX_KERNEXEC
11071 + pax_open_kernel(cr0);
11074 /* The lock prevents us bouncing CPU here */
11076 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
11077 @@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
11081 - spin_unlock_irqrestore(&pnp_bios_lock, flags);
11083 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
11085 +#ifdef CONFIG_PAX_KERNEXEC
11086 + pax_close_kernel(cr0);
11089 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
11092 /* If we get here and this is set then the PnP BIOS faulted on us. */
11093 diff -urNp linux-2.6.20.3/drivers/pnp/quirks.c linux-2.6.20.3/drivers/pnp/quirks.c
11094 --- linux-2.6.20.3/drivers/pnp/quirks.c 2007-03-13 14:27:08.000000000 -0400
11095 +++ linux-2.6.20.3/drivers/pnp/quirks.c 2007-03-23 08:10:06.000000000 -0400
11096 @@ -126,7 +126,7 @@ static struct pnp_fixup pnp_fixups[] = {
11097 { "CTL0043", quirk_sb16audio_resources },
11098 { "CTL0044", quirk_sb16audio_resources },
11099 { "CTL0045", quirk_sb16audio_resources },
11104 void pnp_fixup_device(struct pnp_dev *dev)
11105 diff -urNp linux-2.6.20.3/drivers/pnp/resource.c linux-2.6.20.3/drivers/pnp/resource.c
11106 --- linux-2.6.20.3/drivers/pnp/resource.c 2007-03-13 14:27:08.000000000 -0400
11107 +++ linux-2.6.20.3/drivers/pnp/resource.c 2007-03-23 08:10:06.000000000 -0400
11108 @@ -364,7 +364,7 @@ int pnp_check_irq(struct pnp_dev * dev,
11111 /* check if the resource is valid */
11112 - if (*irq < 0 || *irq > 15)
11116 /* check if the resource is reserved */
11117 @@ -430,7 +430,7 @@ int pnp_check_dma(struct pnp_dev * dev,
11120 /* check if the resource is valid */
11121 - if (*dma < 0 || *dma == 4 || *dma > 7)
11122 + if (*dma == 4 || *dma > 7)
11125 /* check if the resource is reserved */
11126 diff -urNp linux-2.6.20.3/drivers/scsi/scsi_lib.c linux-2.6.20.3/drivers/scsi/scsi_lib.c
11127 --- linux-2.6.20.3/drivers/scsi/scsi_lib.c 2007-03-13 14:27:08.000000000 -0400
11128 +++ linux-2.6.20.3/drivers/scsi/scsi_lib.c 2007-03-23 08:10:06.000000000 -0400
11129 @@ -44,7 +44,7 @@ struct scsi_host_sg_pool {
11130 #error SCSI_MAX_PHYS_SEGMENTS is too small
11133 -#define SP(x) { x, "sgpool-" #x }
11134 +#define SP(x) { x, "sgpool-" #x, NULL, NULL }
11135 static struct scsi_host_sg_pool scsi_sg_pools[] = {
11138 diff -urNp linux-2.6.20.3/drivers/scsi/scsi_logging.h linux-2.6.20.3/drivers/scsi/scsi_logging.h
11139 --- linux-2.6.20.3/drivers/scsi/scsi_logging.h 2007-03-13 14:27:08.000000000 -0400
11140 +++ linux-2.6.20.3/drivers/scsi/scsi_logging.h 2007-03-23 08:10:06.000000000 -0400
11141 @@ -51,7 +51,7 @@ do { \
11145 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
11146 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
11147 #endif /* CONFIG_SCSI_LOGGING */
11150 diff -urNp linux-2.6.20.3/drivers/serial/8250_pci.c linux-2.6.20.3/drivers/serial/8250_pci.c
11151 --- linux-2.6.20.3/drivers/serial/8250_pci.c 2007-03-13 14:27:08.000000000 -0400
11152 +++ linux-2.6.20.3/drivers/serial/8250_pci.c 2007-03-23 08:10:06.000000000 -0400
11153 @@ -2394,7 +2394,7 @@ static struct pci_device_id serial_pci_t
11154 PCI_ANY_ID, PCI_ANY_ID,
11155 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
11156 0xffff00, pbn_default },
11158 + { 0, 0, 0, 0, 0, 0, 0 }
11161 static struct pci_driver serial_pci_driver = {
11162 diff -urNp linux-2.6.20.3/drivers/usb/class/cdc-acm.c linux-2.6.20.3/drivers/usb/class/cdc-acm.c
11163 --- linux-2.6.20.3/drivers/usb/class/cdc-acm.c 2007-03-13 14:27:08.000000000 -0400
11164 +++ linux-2.6.20.3/drivers/usb/class/cdc-acm.c 2007-03-23 08:10:06.000000000 -0400
11165 @@ -1107,7 +1107,7 @@ static struct usb_device_id acm_ids[] =
11166 USB_CDC_ACM_PROTO_AT_CDMA) },
11168 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
11170 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
11173 MODULE_DEVICE_TABLE (usb, acm_ids);
11174 diff -urNp linux-2.6.20.3/drivers/usb/class/usblp.c linux-2.6.20.3/drivers/usb/class/usblp.c
11175 --- linux-2.6.20.3/drivers/usb/class/usblp.c 2007-03-13 14:27:08.000000000 -0400
11176 +++ linux-2.6.20.3/drivers/usb/class/usblp.c 2007-03-23 08:10:06.000000000 -0400
11177 @@ -218,7 +218,7 @@ static const struct quirk_printer_struct
11178 { 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */
11179 { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
11180 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
11185 static int usblp_select_alts(struct usblp *usblp);
11186 @@ -1239,7 +1239,7 @@ static struct usb_device_id usblp_ids []
11187 { USB_INTERFACE_INFO(7, 1, 1) },
11188 { USB_INTERFACE_INFO(7, 1, 2) },
11189 { USB_INTERFACE_INFO(7, 1, 3) },
11190 - { } /* Terminating entry */
11191 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
11194 MODULE_DEVICE_TABLE (usb, usblp_ids);
11195 diff -urNp linux-2.6.20.3/drivers/usb/core/hub.c linux-2.6.20.3/drivers/usb/core/hub.c
11196 --- linux-2.6.20.3/drivers/usb/core/hub.c 2007-03-13 14:27:08.000000000 -0400
11197 +++ linux-2.6.20.3/drivers/usb/core/hub.c 2007-03-23 08:10:06.000000000 -0400
11198 @@ -2861,7 +2861,7 @@ static struct usb_device_id hub_id_table
11199 .bDeviceClass = USB_CLASS_HUB},
11200 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
11201 .bInterfaceClass = USB_CLASS_HUB},
11202 - { } /* Terminating entry */
11203 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
11206 MODULE_DEVICE_TABLE (usb, hub_id_table);
11207 diff -urNp linux-2.6.20.3/drivers/usb/host/ehci-pci.c linux-2.6.20.3/drivers/usb/host/ehci-pci.c
11208 --- linux-2.6.20.3/drivers/usb/host/ehci-pci.c 2007-03-13 14:27:08.000000000 -0400
11209 +++ linux-2.6.20.3/drivers/usb/host/ehci-pci.c 2007-03-23 08:10:06.000000000 -0400
11210 @@ -361,7 +361,7 @@ static const struct pci_device_id pci_id
11211 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
11212 .driver_data = (unsigned long) &ehci_pci_hc_driver,
11214 - { /* end: all zeroes */ }
11215 + { 0, 0, 0, 0, 0, 0, 0 }
11217 MODULE_DEVICE_TABLE(pci, pci_ids);
11219 diff -urNp linux-2.6.20.3/drivers/usb/host/uhci-hcd.c linux-2.6.20.3/drivers/usb/host/uhci-hcd.c
11220 --- linux-2.6.20.3/drivers/usb/host/uhci-hcd.c 2007-03-13 14:27:08.000000000 -0400
11221 +++ linux-2.6.20.3/drivers/usb/host/uhci-hcd.c 2007-03-23 08:10:06.000000000 -0400
11222 @@ -902,7 +902,7 @@ static const struct pci_device_id uhci_p
11223 /* handle any USB UHCI controller */
11224 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
11225 .driver_data = (unsigned long) &uhci_driver,
11226 - }, { /* end: all zeroes */ }
11227 + }, { 0, 0, 0, 0, 0, 0, 0 }
11230 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
11231 diff -urNp linux-2.6.20.3/drivers/usb/storage/debug.h linux-2.6.20.3/drivers/usb/storage/debug.h
11232 --- linux-2.6.20.3/drivers/usb/storage/debug.h 2007-03-13 14:27:08.000000000 -0400
11233 +++ linux-2.6.20.3/drivers/usb/storage/debug.h 2007-03-23 08:10:06.000000000 -0400
11234 @@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
11235 #define US_DEBUGPX(x...) printk( x )
11236 #define US_DEBUG(x) x
11238 -#define US_DEBUGP(x...)
11239 -#define US_DEBUGPX(x...)
11240 -#define US_DEBUG(x)
11241 +#define US_DEBUGP(x...) do {} while (0)
11242 +#define US_DEBUGPX(x...) do {} while (0)
11243 +#define US_DEBUG(x) do {} while (0)
11247 diff -urNp linux-2.6.20.3/drivers/usb/storage/usb.c linux-2.6.20.3/drivers/usb/storage/usb.c
11248 --- linux-2.6.20.3/drivers/usb/storage/usb.c 2007-03-13 14:27:08.000000000 -0400
11249 +++ linux-2.6.20.3/drivers/usb/storage/usb.c 2007-03-23 08:10:06.000000000 -0400
11250 @@ -141,7 +141,7 @@ static struct usb_device_id storage_usb_
11253 /* Terminating entry */
11255 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
11258 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
11259 @@ -181,7 +181,7 @@ static struct us_unusual_dev us_unusual_
11262 /* Terminating entry */
11264 + { NULL, NULL, 0, 0, NULL }
11268 diff -urNp linux-2.6.20.3/drivers/video/fbcmap.c linux-2.6.20.3/drivers/video/fbcmap.c
11269 --- linux-2.6.20.3/drivers/video/fbcmap.c 2007-03-13 14:27:08.000000000 -0400
11270 +++ linux-2.6.20.3/drivers/video/fbcmap.c 2007-03-23 08:10:06.000000000 -0400
11271 @@ -251,8 +251,7 @@ int fb_set_user_cmap(struct fb_cmap_user
11272 int rc, size = cmap->len * sizeof(u16);
11273 struct fb_cmap umap;
11275 - if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
11276 - !info->fbops->fb_setcmap))
11277 + if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
11280 memset(&umap, 0, sizeof(struct fb_cmap));
11281 diff -urNp linux-2.6.20.3/drivers/video/fbmem.c linux-2.6.20.3/drivers/video/fbmem.c
11282 --- linux-2.6.20.3/drivers/video/fbmem.c 2007-03-13 14:27:08.000000000 -0400
11283 +++ linux-2.6.20.3/drivers/video/fbmem.c 2007-03-23 08:10:06.000000000 -0400
11284 @@ -936,9 +936,9 @@ fb_ioctl(struct inode *inode, struct fil
11285 case FBIOPUT_CON2FBMAP:
11286 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
11288 - if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
11289 + if (con2fb.console > MAX_NR_CONSOLES)
11291 - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
11292 + if (con2fb.framebuffer >= FB_MAX)
11295 if (!registered_fb[con2fb.framebuffer])
11296 diff -urNp linux-2.6.20.3/drivers/video/fbmon.c linux-2.6.20.3/drivers/video/fbmon.c
11297 --- linux-2.6.20.3/drivers/video/fbmon.c 2007-03-13 14:27:08.000000000 -0400
11298 +++ linux-2.6.20.3/drivers/video/fbmon.c 2007-03-23 08:10:06.000000000 -0400
11301 #define DPRINTK(fmt, args...) printk(fmt,## args)
11303 -#define DPRINTK(fmt, args...)
11304 +#define DPRINTK(fmt, args...) do {} while (0)
11307 #define FBMON_FIX_HEADER 1
11308 diff -urNp linux-2.6.20.3/drivers/video/i810/i810_accel.c linux-2.6.20.3/drivers/video/i810/i810_accel.c
11309 --- linux-2.6.20.3/drivers/video/i810/i810_accel.c 2007-03-13 14:27:08.000000000 -0400
11310 +++ linux-2.6.20.3/drivers/video/i810/i810_accel.c 2007-03-23 08:10:06.000000000 -0400
11311 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct
11314 printk("ringbuffer lockup!!!\n");
11315 + printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
11316 i810_report_error(mmio);
11317 par->dev_flags |= LOCKUP;
11318 info->pixmap.scan_align = 1;
11319 diff -urNp linux-2.6.20.3/drivers/video/i810/i810_main.c linux-2.6.20.3/drivers/video/i810/i810_main.c
11320 --- linux-2.6.20.3/drivers/video/i810/i810_main.c 2007-03-13 14:27:08.000000000 -0400
11321 +++ linux-2.6.20.3/drivers/video/i810/i810_main.c 2007-03-23 08:11:31.000000000 -0400
11322 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
11323 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
11324 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
11325 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
11327 + { 0, 0, 0, 0, 0, 0, 0 },
11330 static struct pci_driver i810fb_driver = {
11331 @@ -1506,7 +1506,7 @@ static int i810fb_cursor(struct fb_info
11332 int size = ((cursor->image.width + 7) >> 3) *
11333 cursor->image.height;
11335 - u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
11336 + u8 *data = kmalloc(64 * 8, GFP_KERNEL);
11340 diff -urNp linux-2.6.20.3/drivers/video/modedb.c linux-2.6.20.3/drivers/video/modedb.c
11341 --- linux-2.6.20.3/drivers/video/modedb.c 2007-03-13 14:27:08.000000000 -0400
11342 +++ linux-2.6.20.3/drivers/video/modedb.c 2007-03-23 08:10:06.000000000 -0400
11343 @@ -38,228 +38,228 @@ static const struct fb_videomode modedb[
11345 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
11346 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
11347 - 0, FB_VMODE_NONINTERLACED
11348 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11350 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
11351 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
11352 - 0, FB_VMODE_NONINTERLACED
11353 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11355 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
11356 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
11357 - 0, FB_VMODE_NONINTERLACED
11358 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11360 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
11361 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
11362 - 0, FB_VMODE_INTERLACED
11363 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
11365 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
11366 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
11367 - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11368 + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11370 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
11371 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
11372 - 0, FB_VMODE_NONINTERLACED
11373 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11375 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
11376 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
11377 - 0, FB_VMODE_NONINTERLACED
11378 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11380 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
11381 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
11382 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11383 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11385 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
11386 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
11387 - 0, FB_VMODE_NONINTERLACED
11388 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11390 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
11391 NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
11392 - 0, FB_VMODE_INTERLACED
11393 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
11395 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
11396 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
11397 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11398 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11400 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
11401 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
11402 - 0, FB_VMODE_NONINTERLACED
11403 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11405 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
11406 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
11407 - 0, FB_VMODE_NONINTERLACED
11408 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11410 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
11411 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
11412 - 0, FB_VMODE_NONINTERLACED
11413 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11415 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
11416 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
11417 - 0, FB_VMODE_NONINTERLACED
11418 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11420 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
11421 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
11422 - 0, FB_VMODE_NONINTERLACED
11423 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11425 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
11426 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
11427 - 0, FB_VMODE_INTERLACED
11428 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
11430 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
11431 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
11432 - 0, FB_VMODE_NONINTERLACED
11433 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11435 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
11436 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
11437 - 0, FB_VMODE_NONINTERLACED
11438 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11440 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
11441 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
11442 - 0, FB_VMODE_NONINTERLACED
11443 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11445 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
11446 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
11447 - 0, FB_VMODE_NONINTERLACED
11448 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11450 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
11451 NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
11452 - 0, FB_VMODE_NONINTERLACED
11453 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11455 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
11456 NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
11457 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11458 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11460 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
11461 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
11462 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11463 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11465 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
11466 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
11467 - 0, FB_VMODE_NONINTERLACED
11468 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11470 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
11471 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
11472 - 0, FB_VMODE_NONINTERLACED
11473 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11475 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
11476 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
11477 - 0, FB_VMODE_NONINTERLACED
11478 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11480 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
11481 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
11482 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11483 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11485 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
11486 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
11487 - 0, FB_VMODE_NONINTERLACED
11488 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11490 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
11491 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
11492 - 0, FB_VMODE_NONINTERLACED
11493 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11495 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
11496 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
11497 - 0, FB_VMODE_NONINTERLACED
11498 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11500 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
11501 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
11502 - 0, FB_VMODE_NONINTERLACED
11503 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11505 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
11506 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
11507 - 0, FB_VMODE_NONINTERLACED
11508 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11510 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
11511 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
11512 - 0, FB_VMODE_NONINTERLACED
11513 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11515 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
11516 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
11517 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11518 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11520 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
11521 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
11522 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11523 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11525 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
11526 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
11527 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11528 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11530 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
11531 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
11532 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11533 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11535 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
11536 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
11537 - 0, FB_VMODE_NONINTERLACED
11538 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11540 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
11541 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
11542 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11543 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11545 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
11546 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
11547 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11548 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11550 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
11551 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
11552 - 0, FB_VMODE_NONINTERLACED
11553 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11555 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
11556 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
11557 - 0, FB_VMODE_NONINTERLACED
11558 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11560 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
11561 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
11562 - 0, FB_VMODE_DOUBLE
11563 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11565 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
11566 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
11567 - 0, FB_VMODE_DOUBLE
11568 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11570 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
11571 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
11572 - 0, FB_VMODE_DOUBLE
11573 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11575 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
11576 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
11577 - 0, FB_VMODE_DOUBLE
11578 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11580 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
11581 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
11582 - 0, FB_VMODE_DOUBLE
11583 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11585 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
11586 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
11587 - 0, FB_VMODE_DOUBLE
11588 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11590 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
11591 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
11592 - 0, FB_VMODE_DOUBLE
11593 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11595 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
11596 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
11597 - 0, FB_VMODE_DOUBLE
11598 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11600 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
11601 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
11602 - 0, FB_VMODE_DOUBLE
11603 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11605 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
11606 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
11607 - 0, FB_VMODE_DOUBLE
11608 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11610 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
11611 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
11612 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
11613 - FB_VMODE_NONINTERLACED
11614 + FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11616 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
11617 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
11618 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11619 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11621 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
11622 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
11623 - 0, FB_VMODE_NONINTERLACED
11624 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11628 diff -urNp linux-2.6.20.3/drivers/video/vesafb.c linux-2.6.20.3/drivers/video/vesafb.c
11629 --- linux-2.6.20.3/drivers/video/vesafb.c 2007-03-13 14:27:08.000000000 -0400
11630 +++ linux-2.6.20.3/drivers/video/vesafb.c 2007-03-23 08:10:06.000000000 -0400
11631 @@ -266,7 +266,7 @@ static int __init vesafb_probe(struct pl
11632 size_remap = size_total;
11633 vesafb_fix.smem_len = size_remap;
11636 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
11637 screen_info.vesapm_seg = 0;
11640 diff -urNp linux-2.6.20.3/fs/binfmt_aout.c linux-2.6.20.3/fs/binfmt_aout.c
11641 --- linux-2.6.20.3/fs/binfmt_aout.c 2007-03-13 14:27:08.000000000 -0400
11642 +++ linux-2.6.20.3/fs/binfmt_aout.c 2007-03-23 08:11:31.000000000 -0400
11644 #include <linux/personality.h>
11645 #include <linux/init.h>
11646 #include <linux/vs_memory.h>
11647 +#include <linux/grsecurity.h>
11649 #include <asm/system.h>
11650 #include <asm/uaccess.h>
11651 @@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
11652 /* If the size of the dump file exceeds the rlimit, then see what would happen
11653 if we wrote the stack, but not the data area. */
11655 + gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
11656 if ((dump.u_dsize+dump.u_ssize) >
11657 current->signal->rlim[RLIMIT_CORE].rlim_cur)
11660 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
11661 if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
11662 current->signal->rlim[RLIMIT_CORE].rlim_cur)
11664 @@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
11666 /* Make sure we have enough room to write the stack and data areas. */
11668 + gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
11669 if ((dump.u_ssize) >
11670 current->signal->rlim[RLIMIT_CORE].rlim_cur)
11673 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
11674 if ((dump.u_ssize+1) * PAGE_SIZE >
11675 current->signal->rlim[RLIMIT_CORE].rlim_cur)
11677 @@ -294,6 +299,8 @@ static int load_aout_binary(struct linux
11678 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
11679 if (rlim >= RLIM_INFINITY)
11682 + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
11683 if (ex.a_data + ex.a_bss > rlim)
11686 @@ -326,6 +333,28 @@ static int load_aout_binary(struct linux
11687 current->mm->mmap = NULL;
11688 compute_creds(bprm);
11689 current->flags &= ~PF_FORKNOEXEC;
11691 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
11692 + current->mm->pax_flags = 0UL;
11695 +#ifdef CONFIG_PAX_PAGEEXEC
11696 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
11697 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
11699 +#ifdef CONFIG_PAX_EMUTRAMP
11700 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
11701 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
11704 +#ifdef CONFIG_PAX_MPROTECT
11705 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
11706 + current->mm->pax_flags |= MF_PAX_MPROTECT;
11713 if (N_MAGIC(ex) == NMAGIC) {
11714 loff_t pos = fd_offset;
11715 @@ -421,7 +450,7 @@ static int load_aout_binary(struct linux
11717 down_write(¤t->mm->mmap_sem);
11718 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
11719 - PROT_READ | PROT_WRITE | PROT_EXEC,
11720 + PROT_READ | PROT_WRITE,
11721 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
11722 fd_offset + ex.a_text);
11723 up_write(¤t->mm->mmap_sem);
11724 diff -urNp linux-2.6.20.3/fs/binfmt_elf.c linux-2.6.20.3/fs/binfmt_elf.c
11725 --- linux-2.6.20.3/fs/binfmt_elf.c 2007-03-13 14:27:08.000000000 -0400
11726 +++ linux-2.6.20.3/fs/binfmt_elf.c 2007-03-23 08:11:31.000000000 -0400
11727 @@ -40,10 +40,16 @@
11728 #include <linux/random.h>
11729 #include <linux/elf.h>
11730 #include <linux/vs_memory.h>
11731 +#include <linux/grsecurity.h>
11733 #include <asm/uaccess.h>
11734 #include <asm/param.h>
11735 #include <asm/page.h>
11737 +#ifdef CONFIG_PAX_SEGMEXEC
11738 +#include <asm/desc.h>
11741 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
11742 static int load_elf_library(struct file *);
11743 static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
11744 @@ -84,6 +90,8 @@ static struct linux_binfmt elf_format =
11746 static int set_brk(unsigned long start, unsigned long end)
11748 + unsigned long e = end;
11750 start = ELF_PAGEALIGN(start);
11751 end = ELF_PAGEALIGN(end);
11753 @@ -94,7 +102,7 @@ static int set_brk(unsigned long start,
11754 if (BAD_ADDR(addr))
11757 - current->mm->start_brk = current->mm->brk = end;
11758 + current->mm->start_brk = current->mm->brk = e;
11762 @@ -315,10 +323,9 @@ static unsigned long load_elf_interp(str
11764 struct elf_phdr *elf_phdata;
11765 struct elf_phdr *eppnt;
11766 - unsigned long load_addr = 0;
11767 - int load_addr_set = 0;
11768 + unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
11769 unsigned long last_bss = 0, elf_bss = 0;
11770 - unsigned long error = ~0UL;
11771 + unsigned long error = -EINVAL;
11772 int retval, i, size;
11774 /* First of all, some simple consistency checks */
11775 @@ -357,66 +364,86 @@ static unsigned long load_elf_interp(str
11779 +#ifdef CONFIG_PAX_SEGMEXEC
11780 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
11781 + task_size = SEGMEXEC_TASK_SIZE;
11784 eppnt = elf_phdata;
11785 + min_addr = task_size;
11789 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
11790 - if (eppnt->p_type == PT_LOAD) {
11791 - int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
11792 - int elf_prot = 0;
11793 - unsigned long vaddr = 0;
11794 - unsigned long k, map_addr;
11796 - if (eppnt->p_flags & PF_R)
11797 - elf_prot = PROT_READ;
11798 - if (eppnt->p_flags & PF_W)
11799 - elf_prot |= PROT_WRITE;
11800 - if (eppnt->p_flags & PF_X)
11801 - elf_prot |= PROT_EXEC;
11802 - vaddr = eppnt->p_vaddr;
11803 - if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
11804 - elf_type |= MAP_FIXED;
11806 - map_addr = elf_map(interpreter, load_addr + vaddr,
11807 - eppnt, elf_prot, elf_type);
11808 - error = map_addr;
11809 - if (BAD_ADDR(map_addr))
11812 - if (!load_addr_set &&
11813 - interp_elf_ex->e_type == ET_DYN) {
11814 - load_addr = map_addr - ELF_PAGESTART(vaddr);
11815 - load_addr_set = 1;
11817 + if (eppnt->p_type != PT_LOAD)
11821 - * Check to see if the section's size will overflow the
11822 - * allowed task size. Note that p_filesz must always be
11823 - * <= p_memsize so it's only necessary to check p_memsz.
11825 - k = load_addr + eppnt->p_vaddr;
11826 - if (BAD_ADDR(k) ||
11827 - eppnt->p_filesz > eppnt->p_memsz ||
11828 - eppnt->p_memsz > TASK_SIZE ||
11829 - TASK_SIZE - eppnt->p_memsz < k) {
11834 + * Check to see if the section's size will overflow the
11835 + * allowed task size. Note that p_filesz must always be
11836 + * <= p_memsize so it is only necessary to check p_memsz.
11838 + if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
11842 - * Find the end of the file mapping for this phdr, and
11843 - * keep track of the largest address we see for this.
11845 - k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
11848 + if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
11849 + min_addr = ELF_PAGESTART(eppnt->p_vaddr);
11850 + if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
11851 + max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
11853 + if (min_addr >= max_addr || max_addr > task_size)
11857 - * Do the same thing for the memory mapping - between
11858 - * elf_bss and last_bss is the bss section.
11860 - k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
11861 - if (k > last_bss)
11864 + if (interp_elf_ex->e_type == ET_DYN) {
11865 + load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
11867 + if (load_addr >= task_size)
11870 + load_addr -= min_addr;
11873 + eppnt = elf_phdata;
11874 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
11875 + int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
11876 + int elf_prot = 0;
11877 + unsigned long vaddr = 0;
11878 + unsigned long k, map_addr;
11880 + if (eppnt->p_type != PT_LOAD)
11883 + if (eppnt->p_flags & PF_R)
11884 + elf_prot = PROT_READ;
11885 + if (eppnt->p_flags & PF_W)
11886 + elf_prot |= PROT_WRITE;
11887 + if (eppnt->p_flags & PF_X)
11888 + elf_prot |= PROT_EXEC;
11889 + vaddr = eppnt->p_vaddr;
11891 + map_addr = elf_map(interpreter, load_addr + vaddr,
11892 + eppnt, elf_prot, elf_type);
11893 + error = map_addr;
11894 + if (BAD_ADDR(map_addr))
11897 + k = load_addr + eppnt->p_vaddr;
11900 + * Find the end of the file mapping for this phdr, and
11901 + * keep track of the largest address we see for this.
11903 + k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
11908 + * Do the same thing for the memory mapping - between
11909 + * elf_bss and last_bss is the bss section.
11911 + k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
11912 + if (k > last_bss)
11917 @@ -444,6 +471,8 @@ static unsigned long load_elf_interp(str
11919 *interp_load_addr = load_addr;
11920 error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
11921 + if (BAD_ADDR(error))
11926 @@ -454,7 +483,7 @@ out:
11927 static unsigned long load_aout_interp(struct exec *interp_ex,
11928 struct file *interpreter)
11930 - unsigned long text_data, elf_entry = ~0UL;
11931 + unsigned long text_data, elf_entry = -EINVAL;
11932 char __user * addr;
11935 @@ -497,6 +526,180 @@ out:
11939 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
11940 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
11942 + unsigned long pax_flags = 0UL;
11944 +#ifdef CONFIG_PAX_PAGEEXEC
11945 + if (elf_phdata->p_flags & PF_PAGEEXEC)
11946 + pax_flags |= MF_PAX_PAGEEXEC;
11949 +#ifdef CONFIG_PAX_SEGMEXEC
11950 + if (elf_phdata->p_flags & PF_SEGMEXEC)
11951 + pax_flags |= MF_PAX_SEGMEXEC;
11954 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
11955 + if (pax_flags & MF_PAX_PAGEEXEC)
11956 + pax_flags &= ~MF_PAX_SEGMEXEC;
11959 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
11960 + if (pax_flags & MF_PAX_SEGMEXEC)
11961 + pax_flags &= ~MF_PAX_PAGEEXEC;
11964 +#ifdef CONFIG_PAX_EMUTRAMP
11965 + if (elf_phdata->p_flags & PF_EMUTRAMP)
11966 + pax_flags |= MF_PAX_EMUTRAMP;
11969 +#ifdef CONFIG_PAX_MPROTECT
11970 + if (elf_phdata->p_flags & PF_MPROTECT)
11971 + pax_flags |= MF_PAX_MPROTECT;
11974 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
11975 + if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
11976 + pax_flags |= MF_PAX_RANDMMAP;
11979 + return pax_flags;
11983 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
11984 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
11986 + unsigned long pax_flags = 0UL;
11988 +#ifdef CONFIG_PAX_PAGEEXEC
11989 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
11990 + pax_flags |= MF_PAX_PAGEEXEC;
11993 +#ifdef CONFIG_PAX_SEGMEXEC
11994 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
11995 + pax_flags |= MF_PAX_SEGMEXEC;
11998 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
11999 + if (pax_flags & MF_PAX_PAGEEXEC)
12000 + pax_flags &= ~MF_PAX_SEGMEXEC;
12003 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
12004 + if (pax_flags & MF_PAX_SEGMEXEC)
12005 + pax_flags &= ~MF_PAX_PAGEEXEC;
12008 +#ifdef CONFIG_PAX_EMUTRAMP
12009 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
12010 + pax_flags |= MF_PAX_EMUTRAMP;
12013 +#ifdef CONFIG_PAX_MPROTECT
12014 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
12015 + pax_flags |= MF_PAX_MPROTECT;
12018 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
12019 + if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
12020 + pax_flags |= MF_PAX_RANDMMAP;
12023 + return pax_flags;
12027 +#ifdef CONFIG_PAX_EI_PAX
12028 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
12030 + unsigned long pax_flags = 0UL;
12032 +#ifdef CONFIG_PAX_PAGEEXEC
12033 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
12034 + pax_flags |= MF_PAX_PAGEEXEC;
12037 +#ifdef CONFIG_PAX_SEGMEXEC
12038 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
12039 + pax_flags |= MF_PAX_SEGMEXEC;
12042 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
12043 + if (pax_flags & MF_PAX_PAGEEXEC)
12044 + pax_flags &= ~MF_PAX_SEGMEXEC;
12047 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
12048 + if (pax_flags & MF_PAX_SEGMEXEC)
12049 + pax_flags &= ~MF_PAX_PAGEEXEC;
12052 +#ifdef CONFIG_PAX_EMUTRAMP
12053 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
12054 + pax_flags |= MF_PAX_EMUTRAMP;
12057 +#ifdef CONFIG_PAX_MPROTECT
12058 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
12059 + pax_flags |= MF_PAX_MPROTECT;
12062 +#ifdef CONFIG_PAX_ASLR
12063 + if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
12064 + pax_flags |= MF_PAX_RANDMMAP;
12067 + return pax_flags;
12071 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
12072 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
12074 + unsigned long pax_flags = 0UL;
12076 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
12080 +#ifdef CONFIG_PAX_EI_PAX
12081 + pax_flags = pax_parse_ei_pax(elf_ex);
12084 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
12085 + for (i = 0UL; i < elf_ex->e_phnum; i++)
12086 + if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
12087 + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
12088 + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
12089 + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
12090 + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
12091 + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
12094 +#ifdef CONFIG_PAX_SOFTMODE
12095 + if (pax_softmode)
12096 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
12100 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
12105 + if (0 > pax_check_flags(&pax_flags))
12108 + current->mm->pax_flags = pax_flags;
12114 * These are the functions used to load ELF style executables and shared
12115 * libraries. There is no binary dependent code anywhere else.
12116 @@ -534,7 +737,7 @@ static int load_elf_binary(struct linux_
12117 char * elf_interpreter = NULL;
12118 unsigned int interpreter_type = INTERPRETER_NONE;
12119 unsigned char ibcs2_interpreter = 0;
12120 - unsigned long error;
12121 + unsigned long error = 0;
12122 struct elf_phdr *elf_ppnt, *elf_phdata;
12123 unsigned long elf_bss, elf_brk;
12124 int elf_exec_fileno;
12125 @@ -552,6 +755,7 @@ static int load_elf_binary(struct linux_
12126 struct elfhdr interp_elf_ex;
12127 struct exec interp_ex;
12129 + unsigned long task_size = TASK_SIZE;
12131 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
12133 @@ -782,14 +986,91 @@ static int load_elf_binary(struct linux_
12134 current->mm->end_code = 0;
12135 current->mm->mmap = NULL;
12136 current->flags &= ~PF_FORKNOEXEC;
12138 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
12139 + current->mm->pax_flags = 0UL;
12142 +#ifdef CONFIG_PAX_DLRESOLVE
12143 + current->mm->call_dl_resolve = 0UL;
12146 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
12147 + current->mm->call_syscall = 0UL;
12150 +#ifdef CONFIG_PAX_ASLR
12151 + current->mm->delta_mmap = 0UL;
12152 + current->mm->delta_exec = 0UL;
12153 + current->mm->delta_stack = 0UL;
12156 current->mm->def_flags = def_flags;
12158 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
12159 + if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
12160 + send_sig(SIGKILL, current, 0);
12161 + goto out_free_dentry;
12165 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
12166 + pax_set_initial_flags(bprm);
12167 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
12168 + if (pax_set_initial_flags_func)
12169 + (pax_set_initial_flags_func)(bprm);
12172 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
12173 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
12174 + current->mm->context.user_cs_limit = PAGE_SIZE;
12177 +#ifdef CONFIG_PAX_SEGMEXEC
12178 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
12179 + current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
12180 + current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
12181 + task_size = SEGMEXEC_TASK_SIZE;
12185 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
12186 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12187 + set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
12188 + put_cpu_no_resched();
12192 +#ifdef CONFIG_PAX_ASLR
12193 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
12194 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
12196 + current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
12197 + current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
12198 + current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
12202 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12203 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
12204 + executable_stack = EXSTACK_DEFAULT;
12207 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
12208 may depend on the personality. */
12209 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
12211 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12212 + if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
12215 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
12216 current->personality |= READ_IMPLIES_EXEC;
12218 +#ifdef CONFIG_PAX_ASLR
12219 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
12222 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
12223 current->flags |= PF_RANDOMIZE;
12224 arch_pick_mmap_layout(current->mm);
12225 @@ -865,6 +1146,15 @@ static int load_elf_binary(struct linux_
12226 * might try to exec. This is because the brk will
12227 * follow the loader, and is not movable. */
12228 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
12230 +#ifdef CONFIG_PAX_RANDMMAP
12231 + /* PaX: randomize base address at the default exe base if requested */
12232 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
12233 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
12234 + elf_flags |= MAP_FIXED;
12240 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
12241 @@ -895,9 +1185,9 @@ static int load_elf_binary(struct linux_
12242 * allowed task size. Note that p_filesz must always be
12243 * <= p_memsz so it is only necessary to check p_memsz.
12245 - if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
12246 - elf_ppnt->p_memsz > TASK_SIZE ||
12247 - TASK_SIZE - elf_ppnt->p_memsz < k) {
12248 + if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
12249 + elf_ppnt->p_memsz > task_size ||
12250 + task_size - elf_ppnt->p_memsz < k) {
12251 /* set_brk can never work. Avoid overflows. */
12252 send_sig(SIGKILL, current, 0);
12253 goto out_free_dentry;
12254 @@ -924,6 +1214,12 @@ static int load_elf_binary(struct linux_
12255 start_data += load_bias;
12256 end_data += load_bias;
12258 +#ifdef CONFIG_PAX_RANDMMAP
12259 + if (current->mm->pax_flags & MF_PAX_RANDMMAP)
12260 + elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
12261 +#undef pax_delta_mask
12264 /* Calling set_brk effectively mmaps the pages that we need
12265 * for the bss and break sections. We must do this before
12266 * mapping in the interpreter, to make sure it doesn't wind
12267 @@ -1186,7 +1482,7 @@ static int dump_seek(struct file *file,
12269 * I think we should skip something. But I am not sure how. H.J.
12271 -static int maydump(struct vm_area_struct *vma)
12272 +static int maydump(struct vm_area_struct *vma, long signr)
12274 /* The vma can be set up to tell us the answer directly. */
12275 if (vma->vm_flags & VM_ALWAYSDUMP)
12276 @@ -1201,7 +1497,7 @@ static int maydump(struct vm_area_struct
12277 return vma->vm_file->f_path.dentry->d_inode->i_nlink == 0;
12279 /* If it hasn't been written to, don't write it out */
12280 - if (!vma->anon_vma)
12281 + if (signr != SIGKILL && !vma->anon_vma)
12285 @@ -1258,8 +1554,11 @@ static int writenote(struct memelfnote *
12288 #define DUMP_WRITE(addr, nr) \
12290 + gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
12291 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
12292 - goto end_coredump;
12293 + goto end_coredump; \
12295 #define DUMP_SEEK(off) \
12296 if (!dump_seek(file, (off))) \
12298 @@ -1647,7 +1946,7 @@ static int elf_core_dump(long signr, str
12299 phdr.p_offset = offset;
12300 phdr.p_vaddr = vma->vm_start;
12302 - phdr.p_filesz = maydump(vma) ? sz : 0;
12303 + phdr.p_filesz = maydump(vma, signr) ? sz : 0;
12305 offset += phdr.p_filesz;
12306 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
12307 @@ -1690,7 +1989,7 @@ static int elf_core_dump(long signr, str
12308 vma = next_vma(vma, gate_vma)) {
12309 unsigned long addr;
12311 - if (!maydump(vma))
12312 + if (!maydump(vma, signr))
12315 for (addr = vma->vm_start;
12316 @@ -1710,6 +2009,7 @@ static int elf_core_dump(long signr, str
12317 flush_cache_page(vma, addr,
12318 page_to_pfn(page));
12319 kaddr = kmap(page);
12320 + gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
12321 if ((size += PAGE_SIZE) > limit ||
12322 !dump_write(file, kaddr,
12324 diff -urNp linux-2.6.20.3/fs/binfmt_flat.c linux-2.6.20.3/fs/binfmt_flat.c
12325 --- linux-2.6.20.3/fs/binfmt_flat.c 2007-03-13 14:27:08.000000000 -0400
12326 +++ linux-2.6.20.3/fs/binfmt_flat.c 2007-03-23 08:10:06.000000000 -0400
12327 @@ -551,7 +551,9 @@ static int load_flat_file(struct linux_b
12328 realdatastart = (unsigned long) -ENOMEM;
12329 printk("Unable to allocate RAM for process data, errno %d\n",
12331 + down_write(¤t->mm->mmap_sem);
12332 do_munmap(current->mm, textpos, text_len);
12333 + up_write(¤t->mm->mmap_sem);
12334 ret = realdatastart;
12337 @@ -573,8 +575,10 @@ static int load_flat_file(struct linux_b
12339 if (result >= (unsigned long)-4096) {
12340 printk("Unable to read data+bss, errno %d\n", (int)-result);
12341 + down_write(¤t->mm->mmap_sem);
12342 do_munmap(current->mm, textpos, text_len);
12343 do_munmap(current->mm, realdatastart, data_len + extra);
12344 + up_write(¤t->mm->mmap_sem);
12348 @@ -638,8 +642,10 @@ static int load_flat_file(struct linux_b
12350 if (result >= (unsigned long)-4096) {
12351 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
12352 + down_write(¤t->mm->mmap_sem);
12353 do_munmap(current->mm, textpos, text_len + data_len + extra +
12354 MAX_SHARED_LIBS * sizeof(unsigned long));
12355 + up_write(¤t->mm->mmap_sem);
12359 diff -urNp linux-2.6.20.3/fs/binfmt_misc.c linux-2.6.20.3/fs/binfmt_misc.c
12360 --- linux-2.6.20.3/fs/binfmt_misc.c 2007-03-13 14:27:08.000000000 -0400
12361 +++ linux-2.6.20.3/fs/binfmt_misc.c 2007-03-23 08:10:06.000000000 -0400
12362 @@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
12363 struct files_struct *files = NULL;
12367 + if (!enabled || bprm->misc)
12372 /* to keep locking time low, we copy the interpreter string */
12373 read_lock(&entries_lock);
12374 fmt = check_file(bprm);
12375 @@ -729,7 +731,7 @@ static int bm_fill_super(struct super_bl
12376 static struct tree_descr bm_files[] = {
12377 [1] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
12378 [2] = {"register", &bm_register_operations, S_IWUSR},
12379 - /* last one */ {""}
12380 + /* last one */ {"", NULL, 0}
12382 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
12384 diff -urNp linux-2.6.20.3/fs/block_dev.c linux-2.6.20.3/fs/block_dev.c
12385 --- linux-2.6.20.3/fs/block_dev.c 2007-03-13 14:27:08.000000000 -0400
12386 +++ linux-2.6.20.3/fs/block_dev.c 2007-03-23 08:10:06.000000000 -0400
12387 @@ -950,7 +950,7 @@ static int bd_claim_by_kobject(struct bl
12388 struct kobject *kobj)
12391 - struct bd_holder *bo, *found;
12392 + struct bd_holder *bo, *found = NULL;
12396 diff -urNp linux-2.6.20.3/fs/buffer.c linux-2.6.20.3/fs/buffer.c
12397 --- linux-2.6.20.3/fs/buffer.c 2007-03-13 14:27:08.000000000 -0400
12398 +++ linux-2.6.20.3/fs/buffer.c 2007-03-23 08:11:31.000000000 -0400
12400 #include <linux/bitops.h>
12401 #include <linux/mpage.h>
12402 #include <linux/bit_spinlock.h>
12403 +#include <linux/grsecurity.h>
12405 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
12406 static void invalidate_bh_lrus(void);
12407 @@ -2021,6 +2022,7 @@ static int __generic_cont_expand(struct
12410 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
12411 + gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
12412 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
12413 send_sig(SIGXFSZ, current, 0);
12415 diff -urNp linux-2.6.20.3/fs/cifs/cifssmb.c linux-2.6.20.3/fs/cifs/cifssmb.c
12416 --- linux-2.6.20.3/fs/cifs/cifssmb.c 2007-03-13 14:27:08.000000000 -0400
12417 +++ linux-2.6.20.3/fs/cifs/cifssmb.c 2007-03-23 08:10:06.000000000 -0400
12418 @@ -2812,10 +2812,10 @@ GetExtAttrOut:
12421 /* security id for everyone */
12422 -const static struct cifs_sid sid_everyone =
12423 +static const struct cifs_sid sid_everyone =
12424 {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
12426 -const static struct cifs_sid sid_user =
12427 +static const struct cifs_sid sid_user =
12428 {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
12430 /* Convert CIFS ACL to POSIX form */
12431 diff -urNp linux-2.6.20.3/fs/cifs/cifs_uniupr.h linux-2.6.20.3/fs/cifs/cifs_uniupr.h
12432 --- linux-2.6.20.3/fs/cifs/cifs_uniupr.h 2007-03-13 14:27:08.000000000 -0400
12433 +++ linux-2.6.20.3/fs/cifs/cifs_uniupr.h 2007-03-23 08:10:06.000000000 -0400
12434 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
12435 {0x0490, 0x04cc, UniCaseRangeU0490},
12436 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
12437 {0xff40, 0xff5a, UniCaseRangeUff40},
12443 diff -urNp linux-2.6.20.3/fs/cifs/smbdes.c linux-2.6.20.3/fs/cifs/smbdes.c
12444 --- linux-2.6.20.3/fs/cifs/smbdes.c 2007-03-13 14:27:08.000000000 -0400
12445 +++ linux-2.6.20.3/fs/cifs/smbdes.c 2007-03-23 08:10:06.000000000 -0400
12446 @@ -196,15 +196,18 @@ dohash(char *out, char *in, char *key, i
12455 + char *er; /* er[48] */
12457 /* Have to reduce stack usage */
12458 - pk1 = kmalloc(56+56+64+64,GFP_KERNEL);
12461 + pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
12462 + ki = kmalloc(16*48, GFP_KERNEL);
12463 + er = kmalloc(48+48+32+32+32, GFP_KERNEL);
12464 + if (!pk1 || !ki || !er)
12469 @@ -222,7 +225,7 @@ dohash(char *out, char *in, char *key, i
12470 lshift(d, sc[i], 28);
12472 concat(cd, c, d, 28, 28);
12473 - permute(ki[i], cd, perm2, 48);
12474 + permute(ki+48*i, cd, perm2, 48);
12477 permute(pd1, in, perm3, 64);
12478 @@ -233,18 +236,12 @@ dohash(char *out, char *in, char *key, i
12481 for (i = 0; i < 16; i++) {
12482 - char *er; /* er[48] */
12483 char *erk; /* erk[48] */
12485 char *cb; /* cb[32] */
12486 char *pcb; /* pcb[32] */
12487 char *r2; /* r2[32] */
12489 - er = kmalloc(48+48+32+32+32, GFP_KERNEL);
12497 @@ -252,7 +249,7 @@ dohash(char *out, char *in, char *key, i
12499 permute(er, r, perm4, 48);
12501 - xor(erk, er, ki[forw ? i : 15 - i], 48);
12502 + xor(erk, er, ki+48*(forw ? i : 15 - i), 48);
12504 for (j = 0; j < 8; j++)
12505 for (k = 0; k < 6; k++)
12506 @@ -282,13 +279,15 @@ dohash(char *out, char *in, char *key, i
12508 for (j = 0; j < 32; j++)
12514 concat(rl, r, l, 32, 32);
12516 permute(out, rl, perm6, 64);
12524 diff -urNp linux-2.6.20.3/fs/compat.c linux-2.6.20.3/fs/compat.c
12525 --- linux-2.6.20.3/fs/compat.c 2007-03-13 14:27:08.000000000 -0400
12526 +++ linux-2.6.20.3/fs/compat.c 2007-03-23 08:11:31.000000000 -0400
12528 #include <linux/highmem.h>
12529 #include <linux/poll.h>
12530 #include <linux/mm.h>
12531 +#include <linux/grsecurity.h>
12533 #include <net/sock.h> /* siocdevprivate_ioctl */
12535 @@ -1496,6 +1497,11 @@ int compat_do_execve(char * filename,
12539 +#ifdef CONFIG_GRKERNSEC
12540 + struct file *old_exec_file;
12541 + struct acl_subject_label *old_acl;
12542 + struct rlimit old_rlim[RLIM_NLIMITS];
12546 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
12547 @@ -1513,6 +1519,15 @@ int compat_do_execve(char * filename,
12549 bprm->filename = filename;
12550 bprm->interp = filename;
12552 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
12553 + retval = -EAGAIN;
12554 + if (gr_handle_nproc())
12556 + retval = -EACCES;
12557 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
12560 bprm->mm = mm_alloc();
12563 @@ -1551,10 +1566,39 @@ int compat_do_execve(char * filename,
12567 + if (!gr_tpe_allow(file)) {
12568 + retval = -EACCES;
12572 + if (gr_check_crash_exec(file)) {
12573 + retval = -EACCES;
12577 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
12579 + gr_handle_exec_args(bprm, (char __user * __user *)argv);
12581 +#ifdef CONFIG_GRKERNSEC
12582 + old_acl = current->acl;
12583 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
12584 + old_exec_file = current->exec_file;
12586 + current->exec_file = file;
12589 + gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
12591 retval = search_binary_handler(bprm, regs);
12593 free_arg_pages(bprm);
12595 +#ifdef CONFIG_GRKERNSEC
12596 + if (old_exec_file)
12597 + fput(old_exec_file);
12600 /* execve success */
12601 security_bprm_free(bprm);
12602 acct_update_integrals(current);
12603 @@ -1562,6 +1606,13 @@ int compat_do_execve(char * filename,
12607 +#ifdef CONFIG_GRKERNSEC
12608 + current->acl = old_acl;
12609 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
12610 + fput(current->exec_file);
12611 + current->exec_file = old_exec_file;
12615 /* Something went wrong, return the inode and free the argument pages*/
12616 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
12617 diff -urNp linux-2.6.20.3/fs/dcache.c linux-2.6.20.3/fs/dcache.c
12618 --- linux-2.6.20.3/fs/dcache.c 2007-03-13 14:27:08.000000000 -0400
12619 +++ linux-2.6.20.3/fs/dcache.c 2007-03-23 08:11:31.000000000 -0400
12620 @@ -1747,7 +1747,7 @@ shouldnt_be_hashed:
12622 * "buflen" should be positive. Caller holds the dcache_lock.
12624 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
12625 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
12626 struct dentry *root, struct vfsmount *rootmnt,
12627 char *buffer, int buflen)
12629 diff -urNp linux-2.6.20.3/fs/debugfs/inode.c linux-2.6.20.3/fs/debugfs/inode.c
12630 --- linux-2.6.20.3/fs/debugfs/inode.c 2007-03-13 14:27:08.000000000 -0400
12631 +++ linux-2.6.20.3/fs/debugfs/inode.c 2007-03-23 08:10:06.000000000 -0400
12632 @@ -114,7 +114,7 @@ static inline int debugfs_positive(struc
12634 static int debug_fill_super(struct super_block *sb, void *data, int silent)
12636 - static struct tree_descr debug_files[] = {{""}};
12637 + static struct tree_descr debug_files[] = {{"", NULL, 0}};
12639 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
12641 diff -urNp linux-2.6.20.3/fs/exec.c linux-2.6.20.3/fs/exec.c
12642 --- linux-2.6.20.3/fs/exec.c 2007-03-13 14:27:08.000000000 -0400
12643 +++ linux-2.6.20.3/fs/exec.c 2007-03-23 08:25:38.000000000 -0400
12645 #include <linux/cn_proc.h>
12646 #include <linux/audit.h>
12647 #include <linux/vs_memory.h>
12648 +#include <linux/random.h>
12649 +#include <linux/grsecurity.h>
12651 #include <asm/uaccess.h>
12652 #include <asm/mmu_context.h>
12653 @@ -69,6 +71,15 @@ EXPORT_SYMBOL(suid_dumpable);
12654 static struct linux_binfmt *formats;
12655 static DEFINE_RWLOCK(binfmt_lock);
12657 +#ifdef CONFIG_PAX_SOFTMODE
12658 +unsigned int pax_softmode;
12661 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
12662 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
12663 +EXPORT_SYMBOL(pax_set_initial_flags_func);
12666 int register_binfmt(struct linux_binfmt * fmt)
12668 struct linux_binfmt ** tmp = &formats;
12669 @@ -313,6 +324,10 @@ void install_arg_page(struct vm_area_str
12670 if (unlikely(anon_vma_prepare(vma)))
12673 +#ifdef CONFIG_PAX_SEGMEXEC
12674 + if (page_count(page) == 1)
12677 flush_dcache_page(page);
12678 pte = get_locked_pte(mm, address, &ptl);
12680 @@ -322,9 +337,21 @@ void install_arg_page(struct vm_area_str
12683 inc_mm_counter(mm, anon_rss);
12685 +#ifdef CONFIG_PAX_SEGMEXEC
12686 + if (page_count(page) == 1)
12689 lru_cache_add_active(page);
12690 set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
12691 page, vma->vm_page_prot))));
12693 +#ifdef CONFIG_PAX_SEGMEXEC
12694 + if (page_count(page) != 1)
12695 + page_add_anon_rmap(page, vma, address);
12699 page_add_new_anon_rmap(page, vma, address);
12700 pte_unmap_unlock(pte, ptl);
12702 @@ -347,6 +374,10 @@ int setup_arg_pages(struct linux_binprm
12706 +#ifdef CONFIG_PAX_SEGMEXEC
12707 + struct vm_area_struct *mpnt_m = NULL;
12710 #ifdef CONFIG_STACK_GROWSUP
12711 /* Move the argument and environment strings to the bottom of the
12713 @@ -406,11 +437,19 @@ int setup_arg_pages(struct linux_binprm
12714 bprm->loader += stack_base;
12715 bprm->exec += stack_base;
12717 - mpnt = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
12718 + mpnt = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
12722 - memset(mpnt, 0, sizeof(*mpnt));
12723 +#ifdef CONFIG_PAX_SEGMEXEC
12724 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
12725 + mpnt_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
12727 + kmem_cache_free(vm_area_cachep, mpnt);
12733 down_write(&mm->mmap_sem);
12735 @@ -432,14 +471,51 @@ int setup_arg_pages(struct linux_binprm
12737 mpnt->vm_flags = VM_STACK_FLAGS;
12738 mpnt->vm_flags |= mm->def_flags;
12739 - mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
12741 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
12742 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
12743 + mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
12747 + mpnt->vm_page_prot = protection_map[mpnt->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
12748 if ((ret = insert_vm_struct(mm, mpnt))) {
12749 up_write(&mm->mmap_sem);
12750 kmem_cache_free(vm_area_cachep, mpnt);
12752 +#ifdef CONFIG_PAX_SEGMEXEC
12754 + kmem_cache_free(vm_area_cachep, mpnt_m);
12759 vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
12760 mm->stack_vm = mm->total_vm;
12762 +#ifdef CONFIG_PAX_SEGMEXEC
12765 + if (!(mpnt->vm_flags & VM_EXEC)) {
12766 + mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
12767 + mpnt_m->vm_page_prot = PAGE_NONE;
12769 + mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
12770 + mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
12771 + if ((ret = insert_vm_struct(mm, mpnt_m))) {
12772 + up_write(&mm->mmap_sem);
12773 + kmem_cache_free(vm_area_cachep, mpnt_m);
12776 + mpnt_m->vm_flags |= VM_MIRROR;
12777 + mpnt->vm_flags |= VM_MIRROR;
12778 + mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
12779 + mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
12780 + mpnt_m->vm_pgoff = mpnt->vm_pgoff;
12781 + mm->total_vm += vma_pages(mpnt_m);
12787 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
12788 @@ -545,6 +621,14 @@ int setup_arg_pages(struct linux_binprm
12790 bprm->page[i] = NULL;
12791 install_arg_page(mpnt, page, stack_base);
12793 +#ifdef CONFIG_PAX_SEGMEXEC
12795 + page_cache_get(page);
12796 + install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
12801 stack_base += PAGE_SIZE;
12803 @@ -1129,6 +1213,11 @@ int do_execve(char * filename,
12807 +#ifdef CONFIG_GRKERNSEC
12808 + struct file *old_exec_file;
12809 + struct acl_subject_label *old_acl;
12810 + struct rlimit old_rlim[RLIM_NLIMITS];
12814 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
12815 @@ -1140,10 +1229,29 @@ int do_execve(char * filename,
12819 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1);
12821 + if (gr_handle_nproc()) {
12822 + allow_write_access(file);
12827 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
12828 + allow_write_access(file);
12835 bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
12837 +#ifdef CONFIG_PAX_RANDUSTACK
12838 + if (randomize_va_space)
12839 + bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
12843 bprm->filename = filename;
12844 bprm->interp = filename;
12845 @@ -1185,8 +1293,38 @@ int do_execve(char * filename,
12849 + if (!gr_tpe_allow(file)) {
12850 + retval = -EACCES;
12854 + if (gr_check_crash_exec(file)) {
12855 + retval = -EACCES;
12859 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
12861 + gr_handle_exec_args(bprm, argv);
12863 +#ifdef CONFIG_GRKERNSEC
12864 + old_acl = current->acl;
12865 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
12866 + old_exec_file = current->exec_file;
12868 + current->exec_file = file;
12871 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
12875 retval = search_binary_handler(bprm,regs);
12877 +#ifdef CONFIG_GRKERNSEC
12878 + if (old_exec_file)
12879 + fput(old_exec_file);
12881 free_arg_pages(bprm);
12883 /* execve success */
12884 @@ -1196,6 +1334,14 @@ int do_execve(char * filename,
12889 +#ifdef CONFIG_GRKERNSEC
12890 + current->acl = old_acl;
12891 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
12892 + fput(current->exec_file);
12893 + current->exec_file = old_exec_file;
12897 /* Something went wrong, return the inode and free the argument pages*/
12898 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
12899 @@ -1356,6 +1502,114 @@ static void format_corename(char *corena
12903 +int pax_check_flags(unsigned long * flags)
12907 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
12908 + if (*flags & MF_PAX_SEGMEXEC)
12910 + *flags &= ~MF_PAX_SEGMEXEC;
12911 + retval = -EINVAL;
12915 + if ((*flags & MF_PAX_PAGEEXEC)
12917 +#ifdef CONFIG_PAX_PAGEEXEC
12918 + && (*flags & MF_PAX_SEGMEXEC)
12923 + *flags &= ~MF_PAX_PAGEEXEC;
12924 + retval = -EINVAL;
12927 + if ((*flags & MF_PAX_MPROTECT)
12929 +#ifdef CONFIG_PAX_MPROTECT
12930 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
12935 + *flags &= ~MF_PAX_MPROTECT;
12936 + retval = -EINVAL;
12939 + if ((*flags & MF_PAX_EMUTRAMP)
12941 +#ifdef CONFIG_PAX_EMUTRAMP
12942 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
12947 + *flags &= ~MF_PAX_EMUTRAMP;
12948 + retval = -EINVAL;
12954 +EXPORT_SYMBOL(pax_check_flags);
12956 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12957 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
12959 + struct task_struct *tsk = current;
12960 + struct mm_struct *mm = current->mm;
12961 + char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
12962 + char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
12963 + char* path_exec=NULL;
12964 + char* path_fault=NULL;
12965 + unsigned long start=0UL, end=0UL, offset=0UL;
12967 + if (buffer_exec && buffer_fault) {
12968 + struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
12970 + down_read(&mm->mmap_sem);
12972 + while (vma && (!vma_exec || !vma_fault)) {
12973 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
12975 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
12977 + vma = vma->vm_next;
12980 + path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE);
12981 + if (IS_ERR(path_exec))
12982 + path_exec = "<path too long>";
12985 + start = vma_fault->vm_start;
12986 + end = vma_fault->vm_end;
12987 + offset = vma_fault->vm_pgoff << PAGE_SHIFT;
12988 + if (vma_fault->vm_file) {
12989 + path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE);
12990 + if (IS_ERR(path_fault))
12991 + path_fault = "<path too long>";
12993 + path_fault = "<anonymous mapping>";
12995 + up_read(&mm->mmap_sem);
12997 + if (tsk->signal->curr_ip)
12998 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: execution attempt in: %s, %08lx-%08lx %08lx\n", NIPQUAD(tsk->signal->curr_ip), path_fault, start, end, offset);
13000 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
13001 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
13002 + "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
13003 + tsk->uid, tsk->euid, pc, sp);
13004 + free_page((unsigned long)buffer_exec);
13005 + free_page((unsigned long)buffer_fault);
13006 + pax_report_insns(pc, sp);
13007 + do_coredump(SIGKILL, SIGKILL, regs);
13011 static void zap_process(struct task_struct *start)
13013 struct task_struct *t;
13014 @@ -1496,6 +1750,10 @@ int do_coredump(long signr, int exit_cod
13016 clear_thread_flag(TIF_SIGPENDING);
13018 + if (signr == SIGKILL || signr == SIGILL)
13019 + gr_handle_brute_attach(current);
13021 + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
13022 if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
13025 diff -urNp linux-2.6.20.3/fs/ext2/balloc.c linux-2.6.20.3/fs/ext2/balloc.c
13026 --- linux-2.6.20.3/fs/ext2/balloc.c 2007-03-13 14:27:08.000000000 -0400
13027 +++ linux-2.6.20.3/fs/ext2/balloc.c 2007-03-23 08:11:31.000000000 -0400
13028 @@ -111,7 +111,7 @@ static int reserve_blocks(struct super_b
13029 if (free_blocks < count)
13030 count = free_blocks;
13032 - if (free_blocks < root_blocks + count && !capable(CAP_SYS_RESOURCE) &&
13033 + if (free_blocks < root_blocks + count && !capable_nolog(CAP_SYS_RESOURCE) &&
13034 sbi->s_resuid != current->fsuid &&
13035 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
13037 diff -urNp linux-2.6.20.3/fs/ext3/balloc.c linux-2.6.20.3/fs/ext3/balloc.c
13038 --- linux-2.6.20.3/fs/ext3/balloc.c 2007-03-13 14:27:08.000000000 -0400
13039 +++ linux-2.6.20.3/fs/ext3/balloc.c 2007-03-23 08:11:31.000000000 -0400
13040 @@ -1373,7 +1373,7 @@ static int ext3_has_free_blocks(struct e
13041 DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
13043 cond = (free_blocks < root_blocks + 1 &&
13044 - !capable(CAP_SYS_RESOURCE) &&
13045 + !capable_nolog(CAP_SYS_RESOURCE) &&
13046 sbi->s_resuid != current->fsuid &&
13047 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
13049 diff -urNp linux-2.6.20.3/fs/ext3/xattr.c linux-2.6.20.3/fs/ext3/xattr.c
13050 --- linux-2.6.20.3/fs/ext3/xattr.c 2007-03-13 14:27:08.000000000 -0400
13051 +++ linux-2.6.20.3/fs/ext3/xattr.c 2007-03-23 08:10:06.000000000 -0400
13056 -# define ea_idebug(f...)
13057 -# define ea_bdebug(f...)
13058 +# define ea_idebug(f...) do {} while (0)
13059 +# define ea_bdebug(f...) do {} while (0)
13062 static void ext3_xattr_cache_insert(struct buffer_head *);
13063 diff -urNp linux-2.6.20.3/fs/ext4/balloc.c linux-2.6.20.3/fs/ext4/balloc.c
13064 --- linux-2.6.20.3/fs/ext4/balloc.c 2007-03-13 14:27:08.000000000 -0400
13065 +++ linux-2.6.20.3/fs/ext4/balloc.c 2007-03-23 08:11:31.000000000 -0400
13066 @@ -1390,7 +1390,7 @@ static int ext4_has_free_blocks(struct s
13067 DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
13069 cond = (free_blocks < root_blocks + 1 &&
13070 - !capable(CAP_SYS_RESOURCE) &&
13071 + !capable_nolog(CAP_SYS_RESOURCE) &&
13072 sbi->s_resuid != current->fsuid &&
13073 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
13075 diff -urNp linux-2.6.20.3/fs/fcntl.c linux-2.6.20.3/fs/fcntl.c
13076 --- linux-2.6.20.3/fs/fcntl.c 2007-03-13 14:27:08.000000000 -0400
13077 +++ linux-2.6.20.3/fs/fcntl.c 2007-03-23 08:11:31.000000000 -0400
13079 #include <linux/signal.h>
13080 #include <linux/rcupdate.h>
13081 #include <linux/vs_limit.h>
13082 +#include <linux/grsecurity.h>
13084 #include <asm/poll.h>
13085 #include <asm/siginfo.h>
13086 @@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
13087 struct fdtable *fdt;
13090 + gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
13091 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
13094 @@ -83,6 +85,7 @@ repeat:
13095 fdt->max_fds, start);
13098 + gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
13099 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
13101 if (!vx_files_avail(1))
13102 @@ -140,6 +143,8 @@ asmlinkage long sys_dup2(unsigned int ol
13103 struct files_struct * files = current->files;
13104 struct fdtable *fdt;
13106 + gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
13108 spin_lock(&files->file_lock);
13109 if (!(file = fcheck(oldfd)))
13111 @@ -458,7 +463,8 @@ static inline int sigio_perm(struct task
13112 return (((fown->euid == 0) ||
13113 (fown->euid == p->suid) || (fown->euid == p->uid) ||
13114 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
13115 - !security_file_send_sigiotask(p, fown, sig));
13116 + !security_file_send_sigiotask(p, fown, sig) &&
13117 + !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
13120 static void send_sigio_to_task(struct task_struct *p,
13121 diff -urNp linux-2.6.20.3/fs/fuse/control.c linux-2.6.20.3/fs/fuse/control.c
13122 --- linux-2.6.20.3/fs/fuse/control.c 2007-03-13 14:27:08.000000000 -0400
13123 +++ linux-2.6.20.3/fs/fuse/control.c 2007-03-23 08:10:06.000000000 -0400
13124 @@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
13126 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
13128 - struct tree_descr empty_descr = {""};
13129 + struct tree_descr empty_descr = {"", NULL, 0};
13130 struct fuse_conn *fc;
13133 diff -urNp linux-2.6.20.3/fs/Kconfig linux-2.6.20.3/fs/Kconfig
13134 --- linux-2.6.20.3/fs/Kconfig 2007-03-13 14:27:08.000000000 -0400
13135 +++ linux-2.6.20.3/fs/Kconfig 2007-03-23 08:11:31.000000000 -0400
13136 @@ -923,7 +923,7 @@ config PROC_FS
13139 bool "/proc/kcore support" if !ARM
13140 - depends on PROC_FS && MMU
13141 + depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
13144 bool "/proc/vmcore support (EXPERIMENTAL)"
13145 diff -urNp linux-2.6.20.3/fs/namei.c linux-2.6.20.3/fs/namei.c
13146 --- linux-2.6.20.3/fs/namei.c 2007-03-13 14:27:08.000000000 -0400
13147 +++ linux-2.6.20.3/fs/namei.c 2007-03-23 08:11:31.000000000 -0400
13149 #include <linux/vs_base.h>
13150 #include <linux/vs_tag.h>
13151 #include <linux/vs_cowbl.h>
13152 +#include <linux/grsecurity.h>
13153 #include <asm/namei.h>
13154 #include <asm/uaccess.h>
13156 @@ -637,6 +638,13 @@ static inline int do_follow_link(struct
13157 err = security_inode_follow_link(path->dentry, nd);
13161 + if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
13162 + path->dentry->d_inode, path->dentry, nd->mnt)) {
13167 current->link_count++;
13168 current->total_link_count++;
13170 @@ -982,11 +990,18 @@ return_reval:
13174 + if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
13175 + path_release(nd);
13180 dput_path(&next, nd);
13183 + if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
13189 @@ -1598,9 +1613,17 @@ static int open_namei_create(struct name
13191 struct dentry *dir = nd->dentry;
13193 + if (!gr_acl_handle_creat(path->dentry, nd->dentry, nd->mnt, flag, mode)) {
13195 + goto out_unlock_dput;
13198 if (!IS_POSIXACL(dir->d_inode))
13199 mode &= ~current->fs->umask;
13200 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
13202 + gr_handle_create(path->dentry, nd->mnt);
13204 mutex_unlock(&dir->d_inode->i_mutex);
13206 nd->dentry = path->dentry;
13207 @@ -1651,6 +1674,17 @@ int open_namei(int dfd, const char *path
13212 + if (gr_handle_rawio(nd->dentry->d_inode)) {
13217 + if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
13225 @@ -1700,6 +1734,23 @@ do_last:
13227 * It already exists.
13230 + if (gr_handle_rawio(path.dentry->d_inode)) {
13231 + mutex_unlock(&dir->d_inode->i_mutex);
13235 + if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
13236 + mutex_unlock(&dir->d_inode->i_mutex);
13240 + if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
13241 + mutex_unlock(&dir->d_inode->i_mutex);
13246 mutex_unlock(&dir->d_inode->i_mutex);
13247 audit_inode_update(path.dentry->d_inode);
13249 @@ -1755,6 +1806,13 @@ do_link:
13250 error = security_inode_follow_link(path.dentry, nd);
13254 + if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
13255 + path.dentry, nd->mnt)) {
13260 error = __do_follow_link(&path, nd);
13262 /* Does someone understand code flow here? Or it is only
13263 @@ -1883,6 +1941,22 @@ asmlinkage long sys_mknodat(int dfd, con
13264 if (!IS_POSIXACL(nd.dentry->d_inode))
13265 mode &= ~current->fs->umask;
13266 if (!IS_ERR(dentry)) {
13267 + if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
13270 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
13271 + path_release(&nd);
13275 + if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
13278 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
13279 + path_release(&nd);
13283 switch (mode & S_IFMT) {
13284 case 0: case S_IFREG:
13285 error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
13286 @@ -1900,6 +1974,10 @@ asmlinkage long sys_mknodat(int dfd, con
13292 + gr_handle_create(dentry, nd.mnt);
13296 mutex_unlock(&nd.dentry->d_inode->i_mutex);
13297 @@ -1957,9 +2035,18 @@ asmlinkage long sys_mkdirat(int dfd, con
13298 if (IS_ERR(dentry))
13301 + if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) {
13303 + goto out_unlock_dput;
13306 if (!IS_POSIXACL(nd.dentry->d_inode))
13307 mode &= ~current->fs->umask;
13308 error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
13311 + gr_handle_create(dentry, nd.mnt);
13315 mutex_unlock(&nd.dentry->d_inode->i_mutex);
13316 @@ -2041,6 +2128,8 @@ static long do_rmdir(int dfd, const char
13318 struct dentry *dentry;
13319 struct nameidata nd;
13320 + ino_t saved_ino = 0;
13321 + dev_t saved_dev = 0;
13323 name = getname(pathname);
13325 @@ -2066,7 +2155,22 @@ static long do_rmdir(int dfd, const char
13326 error = PTR_ERR(dentry);
13327 if (IS_ERR(dentry))
13330 + if (dentry->d_inode != NULL) {
13331 + if (dentry->d_inode->i_nlink <= 1) {
13332 + saved_ino = dentry->d_inode->i_ino;
13333 + saved_dev = dentry->d_inode->i_sb->s_dev;
13336 + if (!gr_acl_handle_rmdir(dentry, nd.mnt)) {
13341 error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
13342 + if (!error && (saved_dev || saved_ino))
13343 + gr_handle_delete(saved_ino, saved_dev);
13347 mutex_unlock(&nd.dentry->d_inode->i_mutex);
13348 @@ -2125,6 +2229,8 @@ static long do_unlinkat(int dfd, const c
13349 struct dentry *dentry;
13350 struct nameidata nd;
13351 struct inode *inode = NULL;
13352 + ino_t saved_ino = 0;
13353 + dev_t saved_dev = 0;
13355 name = getname(pathname);
13357 @@ -2140,13 +2246,26 @@ static long do_unlinkat(int dfd, const c
13358 dentry = lookup_hash(&nd);
13359 error = PTR_ERR(dentry);
13360 if (!IS_ERR(dentry)) {
13362 /* Why not before? Because we want correct error value */
13363 if (nd.last.name[nd.last.len])
13365 inode = dentry->d_inode;
13368 + if (inode->i_nlink <= 1) {
13369 + saved_ino = inode->i_ino;
13370 + saved_dev = inode->i_sb->s_dev;
13373 + if (!gr_acl_handle_unlink(dentry, nd.mnt))
13376 atomic_inc(&inode->i_count);
13377 - error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
13380 + error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
13381 + if (!error && (saved_ino || saved_dev))
13382 + gr_handle_delete(saved_ino, saved_dev);
13386 @@ -2227,7 +2346,16 @@ asmlinkage long sys_symlinkat(const char
13387 if (IS_ERR(dentry))
13390 + if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) {
13392 + goto out_dput_unlock;
13395 error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
13398 + gr_handle_create(dentry, nd.mnt);
13402 mutex_unlock(&nd.dentry->d_inode->i_mutex);
13403 @@ -2322,7 +2450,25 @@ asmlinkage long sys_linkat(int olddfd, c
13404 error = PTR_ERR(new_dentry);
13405 if (IS_ERR(new_dentry))
13408 + if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
13409 + old_nd.dentry->d_inode,
13410 + old_nd.dentry->d_inode->i_mode, to)) {
13412 + goto out_unlock_dput;
13415 + if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
13416 + old_nd.dentry, old_nd.mnt, to)) {
13418 + goto out_unlock_dput;
13421 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
13424 + gr_handle_create(new_dentry, nd.mnt);
13428 mutex_unlock(&nd.dentry->d_inode->i_mutex);
13429 @@ -2548,8 +2694,16 @@ static int do_rename(int olddfd, const c
13430 if (new_dentry == trap)
13433 - error = vfs_rename(old_dir->d_inode, old_dentry,
13434 + error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
13435 + old_dentry, old_dir->d_inode, oldnd.mnt,
13439 + error = vfs_rename(old_dir->d_inode, old_dentry,
13440 new_dir->d_inode, new_dentry);
13442 + gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry,
13443 + new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
13447 diff -urNp linux-2.6.20.3/fs/namespace.c linux-2.6.20.3/fs/namespace.c
13448 --- linux-2.6.20.3/fs/namespace.c 2007-03-13 14:27:08.000000000 -0400
13449 +++ linux-2.6.20.3/fs/namespace.c 2007-03-23 08:11:31.000000000 -0400
13451 #include <linux/vs_tag.h>
13452 #include <linux/vserver/space.h>
13453 #include <linux/vserver/global.h>
13454 +#include <linux/grsecurity.h>
13455 #include <asm/uaccess.h>
13456 #include <asm/unistd.h>
13458 @@ -658,6 +659,8 @@ static int do_umount(struct vfsmount *mn
13459 DQUOT_OFF(sb->s_dqh);
13460 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
13463 + gr_log_remount(mnt->mnt_devname, retval);
13465 up_write(&sb->s_umount);
13467 @@ -678,6 +681,9 @@ static int do_umount(struct vfsmount *mn
13468 security_sb_umount_busy(mnt);
13469 up_write(&namespace_sem);
13470 release_mounts(&umount_list);
13472 + gr_log_unmount(mnt->mnt_devname, retval);
13477 @@ -1504,6 +1510,11 @@ long do_mount(char *dev_name, char *dir_
13481 + if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
13486 if (flags & MS_REMOUNT)
13487 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
13489 @@ -1518,6 +1529,9 @@ long do_mount(char *dev_name, char *dir_
13490 dev_name, data_page);
13494 + gr_log_mount(dev_name, dir_name, retval);
13499 @@ -1772,6 +1786,9 @@ asmlinkage long sys_pivot_root(const cha
13500 if (!capable(CAP_SYS_ADMIN))
13503 + if (gr_handle_chroot_pivot())
13508 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
13509 diff -urNp linux-2.6.20.3/fs/nls/nls_base.c linux-2.6.20.3/fs/nls/nls_base.c
13510 --- linux-2.6.20.3/fs/nls/nls_base.c 2007-03-13 14:27:08.000000000 -0400
13511 +++ linux-2.6.20.3/fs/nls/nls_base.c 2007-03-23 08:10:06.000000000 -0400
13512 @@ -42,7 +42,7 @@ static struct utf8_table utf8_table[] =
13513 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
13514 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
13515 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
13516 - {0, /* end of table */}
13517 + {0, 0, 0, 0, 0, /* end of table */}
13521 diff -urNp linux-2.6.20.3/fs/ntfs/file.c linux-2.6.20.3/fs/ntfs/file.c
13522 --- linux-2.6.20.3/fs/ntfs/file.c 2007-03-13 14:27:08.000000000 -0400
13523 +++ linux-2.6.20.3/fs/ntfs/file.c 2007-03-23 08:10:06.000000000 -0400
13524 @@ -2335,6 +2335,6 @@ struct inode_operations ntfs_file_inode_
13525 #endif /* NTFS_RW */
13528 -const struct file_operations ntfs_empty_file_ops = {};
13529 +const struct file_operations ntfs_empty_file_ops;
13531 -struct inode_operations ntfs_empty_inode_ops = {};
13532 +struct inode_operations ntfs_empty_inode_ops;
13533 diff -urNp linux-2.6.20.3/fs/open.c linux-2.6.20.3/fs/open.c
13534 --- linux-2.6.20.3/fs/open.c 2007-03-13 14:27:08.000000000 -0400
13535 +++ linux-2.6.20.3/fs/open.c 2007-03-23 08:11:31.000000000 -0400
13537 #include <linux/vs_dlimit.h>
13538 #include <linux/vs_tag.h>
13539 #include <linux/vs_cowbl.h>
13540 +#include <linux/grsecurity.h>
13542 int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
13544 @@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
13548 + if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
13551 newattrs.ia_size = length;
13552 newattrs.ia_valid = ATTR_SIZE | time_attrs;
13554 @@ -398,6 +402,9 @@ asmlinkage long sys_faccessat(int dfd, c
13555 if(IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
13558 + if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
13564 @@ -427,6 +434,8 @@ asmlinkage long sys_chdir(const char __u
13568 + gr_log_chdir(nd.dentry, nd.mnt);
13570 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
13573 @@ -457,6 +466,13 @@ asmlinkage long sys_fchdir(unsigned int
13576 error = file_permission(file, MAY_EXEC);
13578 + if (!error && !gr_chroot_fchdir(dentry, mnt))
13582 + gr_log_chdir(dentry, mnt);
13585 set_fs_pwd(current->fs, mnt, dentry);
13587 @@ -482,8 +498,16 @@ asmlinkage long sys_chroot(const char __
13588 if (!capable(CAP_SYS_CHROOT))
13591 + if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
13592 + goto dput_and_out;
13594 set_fs_root(current->fs, nd.mnt, nd.dentry);
13597 + gr_handle_chroot_caps(current);
13599 + gr_handle_chroot_chdir(nd.dentry, nd.mnt);
13604 @@ -514,9 +538,22 @@ asmlinkage long sys_fchmod(unsigned int
13606 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
13609 + if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
13614 mutex_lock(&inode->i_mutex);
13615 if (mode == (mode_t) -1)
13616 mode = inode->i_mode;
13618 + if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
13620 + mutex_unlock(&inode->i_mutex);
13624 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
13625 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
13626 err = notify_change(dentry, &newattrs);
13627 @@ -549,9 +586,21 @@ asmlinkage long sys_fchmodat(int dfd, co
13628 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
13631 + if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
13633 + goto dput_and_out;
13636 mutex_lock(&inode->i_mutex);
13637 if (mode == (mode_t) -1)
13638 mode = inode->i_mode;
13640 + if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
13642 + mutex_unlock(&inode->i_mutex);
13643 + goto dput_and_out;
13646 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
13647 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
13648 error = notify_change(nd.dentry, &newattrs);
13649 @@ -595,6 +644,12 @@ static int chown_common(struct dentry *
13651 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
13654 + if (!gr_acl_handle_chown(dentry, mnt)) {
13659 newattrs.ia_valid = ATTR_CTIME;
13660 if (user != (uid_t) -1) {
13661 newattrs.ia_valid |= ATTR_UID;
13662 @@ -871,6 +926,7 @@ repeat:
13663 * N.B. For clone tasks sharing a files structure, this test
13664 * will limit the total number of files that can be opened.
13666 + gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
13667 if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
13670 diff -urNp linux-2.6.20.3/fs/partitions/efi.c linux-2.6.20.3/fs/partitions/efi.c
13671 --- linux-2.6.20.3/fs/partitions/efi.c 2007-03-13 14:27:08.000000000 -0400
13672 +++ linux-2.6.20.3/fs/partitions/efi.c 2007-03-23 08:10:06.000000000 -0400
13675 #define Dprintk(x...) printk(KERN_DEBUG x)
13677 -#define Dprintk(x...)
13678 +#define Dprintk(x...) do {} while (0)
13681 /* This allows a kernel command line option 'gpt' to override
13682 diff -urNp linux-2.6.20.3/fs/pipe.c linux-2.6.20.3/fs/pipe.c
13683 --- linux-2.6.20.3/fs/pipe.c 2007-03-13 14:27:08.000000000 -0400
13684 +++ linux-2.6.20.3/fs/pipe.c 2007-03-23 08:11:31.000000000 -0400
13685 @@ -827,7 +827,7 @@ void free_pipe_info(struct inode *inode)
13686 inode->i_pipe = NULL;
13689 -static struct vfsmount *pipe_mnt __read_mostly;
13690 +struct vfsmount *pipe_mnt __read_mostly;
13691 static int pipefs_delete_dentry(struct dentry *dentry)
13694 diff -urNp linux-2.6.20.3/fs/proc/array.c linux-2.6.20.3/fs/proc/array.c
13695 --- linux-2.6.20.3/fs/proc/array.c 2007-03-13 14:27:08.000000000 -0400
13696 +++ linux-2.6.20.3/fs/proc/array.c 2007-03-23 08:11:31.000000000 -0400
13697 @@ -304,6 +304,21 @@ static inline char *task_cap(struct task
13698 (unsigned)vx_info_mbcap(vxi, p->cap_effective));
13701 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13702 +static inline char *task_pax(struct task_struct *p, char *buffer)
13705 + return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
13706 + p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
13707 + p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
13708 + p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
13709 + p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
13710 + p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
13712 + return buffer + sprintf(buffer, "PaX:\t-----\n");
13716 int proc_pid_status(struct task_struct *task, char * buffer)
13718 char * orig = buffer;
13719 @@ -309,9 +324,20 @@ int proc_pid_status(struct task_struct *
13720 #if defined(CONFIG_S390)
13721 buffer = task_show_regs(task, buffer);
13724 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13725 + buffer = task_pax(task, buffer);
13728 return buffer - orig;
13731 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
13732 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
13733 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
13734 + _mm->pax_flags & MF_PAX_SEGMEXEC))
13737 static int do_task_stat(struct task_struct *task, char * buffer, int whole)
13739 unsigned long vsize, eip, esp, wchan = ~0UL;
13740 @@ -398,6 +424,19 @@ static int do_task_stat(struct task_stru
13741 stime = task->stime;
13744 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
13745 + if (PAX_RAND_FLAGS(mm)) {
13751 +#ifdef CONFIG_GRKERNSEC_HIDESYM
13757 /* scale priority and nice values from timeslices to -20..20 */
13758 /* to make it look like a "normal" Unix priority/nice value */
13759 priority = task_prio(task);
13760 @@ -437,9 +476,15 @@ static int do_task_stat(struct task_stru
13762 mm ? get_mm_rss(mm) : 0,
13764 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
13765 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
13766 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
13767 + PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
13769 mm ? mm->start_code : 0,
13770 mm ? mm->end_code : 0,
13771 mm ? mm->start_stack : 0,
13775 /* The signal information here is obsolete.
13776 @@ -486,3 +531,14 @@ int proc_pid_statm(struct task_struct *t
13777 return sprintf(buffer,"%d %d %d %d %d %d %d\n",
13778 size, resident, shared, text, lib, data, 0);
13781 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
13782 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
13786 + len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
13791 diff -urNp linux-2.6.20.3/fs/proc/base.c linux-2.6.20.3/fs/proc/base.c
13792 --- linux-2.6.20.3/fs/proc/base.c 2007-03-13 14:27:08.000000000 -0400
13793 +++ linux-2.6.20.3/fs/proc/base.c 2007-03-23 08:11:31.000000000 -0400
13795 #include <linux/oom.h>
13796 #include <linux/vs_context.h>
13797 #include <linux/vs_network.h>
13798 +#include <linux/grsecurity.h>
13800 #include "internal.h"
13802 @@ -197,7 +198,7 @@ static int proc_root_link(struct inode *
13803 (task->parent == current && \
13804 (task->ptrace & PT_PTRACED) && \
13805 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
13806 - security_ptrace(current,task) == 0))
13807 + security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
13809 static int proc_pid_environ(struct task_struct *task, char * buffer)
13811 @@ -330,6 +331,8 @@ static int proc_fd_access_allowed(struct
13812 task = get_proc_task(inode);
13814 allowed = ptrace_may_attach(task);
13815 + if (allowed != 0)
13816 + allowed = !gr_acl_handle_procpidmem(task);
13817 put_task_struct(task);
13820 @@ -523,7 +526,7 @@ static ssize_t mem_read(struct file * fi
13824 - if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
13825 + if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
13829 @@ -593,7 +596,7 @@ static ssize_t mem_write(struct file * f
13833 - if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
13834 + if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
13838 @@ -1035,7 +1038,11 @@ static struct inode *proc_pid_make_inode
13840 if (task_dumpable(task)) {
13841 inode->i_uid = task->euid;
13842 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
13843 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
13845 inode->i_gid = task->egid;
13848 /* procfs is xid tagged */
13849 inode->i_tag = (tag_t)vx_task_xid(task);
13850 @@ -1048,17 +1055,45 @@ static int pid_getattr(struct vfsmount *
13852 struct inode *inode = dentry->d_inode;
13853 struct task_struct *task;
13854 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
13855 + struct task_struct *tmp = current;
13858 generic_fillattr(inode, stat);
13863 task = pid_task(proc_pid(inode), PIDTYPE_PID);
13866 + if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
13867 + rcu_read_unlock();
13873 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
13874 + && (!tmp->uid || (tmp->uid == task->uid)
13875 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
13876 + || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
13881 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
13882 +#ifdef CONFIG_GRKERNSEC_PROC_USER
13883 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
13884 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
13885 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
13887 task_dumpable(task)) {
13888 stat->uid = task->euid;
13889 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
13890 + stat->gid = CONFIG_GRKERNSEC_PROC_GID;
13892 stat->gid = task->egid;
13897 @@ -1093,11 +1127,26 @@ static int pid_revalidate(struct dentry
13899 struct inode *inode = dentry->d_inode;
13900 struct task_struct *task = get_proc_task(inode);
13902 + if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
13903 + put_task_struct(task);
13908 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
13909 +#ifdef CONFIG_GRKERNSEC_PROC_USER
13910 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
13911 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
13912 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
13914 task_dumpable(task)) {
13915 inode->i_uid = task->euid;
13916 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
13917 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
13919 inode->i_gid = task->egid;
13924 @@ -1111,6 +1159,7 @@ static int pid_revalidate(struct dentry
13925 put_task_struct(task);
13932 @@ -1336,6 +1387,9 @@ static struct dentry *proc_lookupfd(stru
13936 + if (gr_acl_handle_procpidmem(task))
13939 result = proc_fd_instantiate(dir, dentry, task, &fd);
13941 put_task_struct(task);
13942 @@ -1380,6 +1434,8 @@ static int proc_readfd(struct file * fil
13946 + if (gr_acl_handle_procpidmem(p))
13948 files = get_files_struct(p);
13951 @@ -1479,6 +1535,9 @@ static struct dentry *proc_pident_lookup
13952 !memcmp(dentry->d_name.name, "ninfo", 5)))
13955 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
13959 * Yes, it does not scale. And it should not. Don't add
13960 * new entries into /proc/<tgid>/ without very good reasons.
13961 @@ -1531,6 +1590,9 @@ static int proc_pident_readdir(struct fi
13965 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
13971 @@ -1791,6 +1853,9 @@ static struct dentry *proc_base_lookup(s
13975 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
13978 error = proc_base_instantiate(dir, dentry, task, p);
13981 @@ -1881,6 +1946,9 @@ static struct pid_entry tgid_base_stuff[
13982 #ifdef CONFIG_TASK_IO_ACCOUNTING
13983 INF("io", S_IRUGO, pid_io_accounting),
13985 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
13986 + INF("ipaddr", S_IRUSR, pid_ipaddr),
13990 static int proc_tgid_base_readdir(struct file * filp,
13991 @@ -1984,7 +2052,14 @@ static struct dentry *proc_pid_instantia
13995 +#ifdef CONFIG_GRKERNSEC_PROC_USER
13996 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
13997 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
13998 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
13999 + inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
14001 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
14003 inode->i_op = &proc_tgid_base_inode_operations;
14004 inode->i_fop = &proc_tgid_base_operations;
14005 inode->i_flags|=S_IMMUTABLE;
14006 @@ -2049,7 +2124,11 @@ struct dentry *proc_pid_lookup(struct in
14010 + if (gr_check_hidden_task(task))
14011 + goto out_put_task;
14013 result = proc_pid_instantiate(dir, dentry, task, NULL);
14015 put_task_struct(task);
14018 @@ -2083,6 +2162,9 @@ int proc_pid_readdir(struct file * filp,
14020 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
14021 struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
14022 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14023 + struct task_struct *tmp = current;
14025 struct task_struct *task;
14028 @@ -2117,6 +2199,18 @@ int proc_pid_readdir(struct file * filp,
14030 put_task_struct(task), task = next_tgid(tgid + 1)) {
14033 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)
14034 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14035 + || (tmp->uid && (task->uid != tmp->uid)
14036 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
14037 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
14044 filp->f_pos = tgid + TGID_OFFSET;
14045 if (!vx_proc_task_visible(task))
14047 diff -urNp linux-2.6.20.3/fs/proc/inode.c linux-2.6.20.3/fs/proc/inode.c
14048 --- linux-2.6.20.3/fs/proc/inode.c 2007-03-13 14:27:08.000000000 -0400
14049 +++ linux-2.6.20.3/fs/proc/inode.c 2007-03-23 08:11:31.000000000 -0400
14050 @@ -166,7 +166,11 @@ struct inode *proc_get_inode(struct supe
14052 inode->i_mode = de->mode;
14053 inode->i_uid = de->uid;
14054 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
14055 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
14057 inode->i_gid = de->gid;
14061 PROC_I(inode)->vx_flags = de->vx_flags;
14062 diff -urNp linux-2.6.20.3/fs/proc/internal.h linux-2.6.20.3/fs/proc/internal.h
14063 --- linux-2.6.20.3/fs/proc/internal.h 2007-03-13 14:27:08.000000000 -0400
14064 +++ linux-2.6.20.3/fs/proc/internal.h 2007-03-23 08:11:31.000000000 -0400
14065 @@ -37,6 +37,9 @@ extern int proc_tid_stat(struct task_str
14066 extern int proc_tgid_stat(struct task_struct *, char *);
14067 extern int proc_pid_status(struct task_struct *, char *);
14068 extern int proc_pid_statm(struct task_struct *, char *);
14069 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
14070 +extern int proc_pid_ipaddr(struct task_struct*,char*);
14073 extern struct file_operations proc_maps_operations;
14074 extern struct file_operations proc_numa_maps_operations;
14075 diff -urNp linux-2.6.20.3/fs/proc/proc_misc.c linux-2.6.20.3/fs/proc/proc_misc.c
14076 --- linux-2.6.20.3/fs/proc/proc_misc.c 2007-03-13 14:27:08.000000000 -0400
14077 +++ linux-2.6.20.3/fs/proc/proc_misc.c 2007-03-23 08:11:31.000000000 -0400
14078 @@ -673,6 +673,8 @@ void create_seq_entry(char *name, mode_t
14079 void __init proc_misc_init(void)
14081 struct proc_dir_entry *entry;
14086 int (*read_proc)(char*,char**,off_t,int,int*,void*);
14087 @@ -688,7 +690,9 @@ void __init proc_misc_init(void)
14088 {"stram", stram_read_proc},
14090 {"filesystems", filesystems_read_proc},
14091 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
14092 {"cmdline", cmdline_read_proc},
14094 {"locks", locks_read_proc},
14095 {"execdomains", execdomains_read_proc},
14097 @@ -696,6 +700,15 @@ void __init proc_misc_init(void)
14098 for (p = simple_ones; p->name; p++)
14099 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
14101 +#ifdef CONFIG_GRKERNSEC_PROC_USER
14102 + gr_mode = S_IRUSR;
14103 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14104 + gr_mode = S_IRUSR | S_IRGRP;
14106 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
14107 + create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
14110 proc_symlink("mounts", NULL, "self/mounts");
14112 /* And now for trickier ones */
14113 @@ -704,7 +717,11 @@ void __init proc_misc_init(void)
14115 entry->proc_fops = &proc_kmsg_operations;
14117 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
14118 + create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
14120 create_seq_entry("devices", 0, &proc_devinfo_operations);
14122 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
14123 #ifdef CONFIG_BLOCK
14124 create_seq_entry("partitions", 0, &proc_partitions_operations);
14125 @@ -712,7 +729,11 @@ void __init proc_misc_init(void)
14126 create_seq_entry("stat", 0, &proc_stat_operations);
14127 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
14129 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
14130 + create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
14132 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
14134 #ifdef CONFIG_DEBUG_SLAB_LEAK
14135 create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
14137 @@ -729,7 +750,7 @@ void __init proc_misc_init(void)
14138 #ifdef CONFIG_SCHEDSTATS
14139 create_seq_entry("schedstat", 0, &proc_schedstat_operations);
14141 -#ifdef CONFIG_PROC_KCORE
14142 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
14143 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
14144 if (proc_root_kcore) {
14145 proc_root_kcore->proc_fops = &proc_kcore_operations;
14146 diff -urNp linux-2.6.20.3/fs/proc/root.c linux-2.6.20.3/fs/proc/root.c
14147 --- linux-2.6.20.3/fs/proc/root.c 2007-03-13 14:27:08.000000000 -0400
14148 +++ linux-2.6.20.3/fs/proc/root.c 2007-03-23 08:11:31.000000000 -0400
14149 @@ -65,7 +65,13 @@ void __init proc_root_init(void)
14153 +#ifdef CONFIG_GRKERNSEC_PROC_USER
14154 + proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
14155 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14156 + proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
14158 proc_net = proc_mkdir("net", NULL);
14160 proc_net_stat = proc_mkdir("net/stat", NULL);
14162 #ifdef CONFIG_SYSVIPC
14163 @@ -89,7 +95,15 @@ void __init proc_root_init(void)
14164 #ifdef CONFIG_PROC_DEVICETREE
14165 proc_device_tree_init();
14167 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
14168 +#ifdef CONFIG_GRKERNSEC_PROC_USER
14169 + proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
14170 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14171 + proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
14174 proc_bus = proc_mkdir("bus", NULL);
14179 diff -urNp linux-2.6.20.3/fs/proc/task_mmu.c linux-2.6.20.3/fs/proc/task_mmu.c
14180 --- linux-2.6.20.3/fs/proc/task_mmu.c 2007-03-13 14:27:08.000000000 -0400
14181 +++ linux-2.6.20.3/fs/proc/task_mmu.c 2007-03-23 08:21:11.000000000 -0400
14182 @@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
14183 "VmStk:\t%8lu kB\n"
14184 "VmExe:\t%8lu kB\n"
14185 "VmLib:\t%8lu kB\n"
14186 - "VmPTE:\t%8lu kB\n",
14187 - hiwater_vm << (PAGE_SHIFT-10),
14188 + "VmPTE:\t%8lu kB\n"
14190 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14191 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
14194 + ,hiwater_vm << (PAGE_SHIFT-10),
14195 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
14196 mm->locked_vm << (PAGE_SHIFT-10),
14197 hiwater_rss << (PAGE_SHIFT-10),
14198 total_rss << (PAGE_SHIFT-10),
14199 data << (PAGE_SHIFT-10),
14200 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
14201 - (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
14202 + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
14204 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14205 + , mm->context.user_cs_base, mm->context.user_cs_limit
14213 @@ -122,6 +134,12 @@ struct mem_size_stats
14214 unsigned long private_dirty;
14217 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14218 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
14219 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
14220 + _mm->pax_flags & MF_PAX_SEGMEXEC))
14223 static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
14225 struct proc_maps_private *priv = m->private;
14226 @@ -141,13 +159,22 @@ static int show_map_internal(struct seq_
14229 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
14230 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14231 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
14232 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
14237 flags & VM_READ ? 'r' : '-',
14238 flags & VM_WRITE ? 'w' : '-',
14239 flags & VM_EXEC ? 'x' : '-',
14240 flags & VM_MAYSHARE ? 's' : 'p',
14241 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14242 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
14244 vma->vm_pgoff << PAGE_SHIFT,
14246 MAJOR(dev), MINOR(dev), ino, &len);
14249 @@ -161,11 +188,11 @@ static int show_map_internal(struct seq_
14250 const char *name = arch_vma_name(vma);
14253 - if (vma->vm_start <= mm->start_brk &&
14254 - vma->vm_end >= mm->brk) {
14255 + if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
14257 - } else if (vma->vm_start <= mm->start_stack &&
14258 - vma->vm_end >= mm->start_stack) {
14259 + } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
14260 + (vma->vm_start <= mm->start_stack &&
14261 + vma->vm_end >= mm->start_stack)) {
14265 @@ -179,7 +206,25 @@ static int show_map_internal(struct seq_
14272 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14273 + if (PAX_RAND_FLAGS(mm))
14275 + "Size: %8lu kB\n"
14277 + "Shared_Clean: %8lu kB\n"
14278 + "Shared_Dirty: %8lu kB\n"
14279 + "Private_Clean: %8lu kB\n"
14280 + "Private_Dirty: %8lu kB\n",
14292 @@ -193,6 +238,7 @@ static int show_map_internal(struct seq_
14293 mss->shared_dirty >> 10,
14294 mss->private_clean >> 10,
14295 mss->private_dirty >> 10);
14298 if (m->count < m->size) /* vma is copied successfully */
14299 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
14300 diff -urNp linux-2.6.20.3/fs/readdir.c linux-2.6.20.3/fs/readdir.c
14301 --- linux-2.6.20.3/fs/readdir.c 2007-03-13 14:27:08.000000000 -0400
14302 +++ linux-2.6.20.3/fs/readdir.c 2007-03-23 08:11:31.000000000 -0400
14304 #include <linux/security.h>
14305 #include <linux/syscalls.h>
14306 #include <linux/unistd.h>
14307 +#include <linux/namei.h>
14308 +#include <linux/grsecurity.h>
14310 #include <asm/uaccess.h>
14312 @@ -65,6 +67,7 @@ struct old_linux_dirent {
14314 struct readdir_callback {
14315 struct old_linux_dirent __user * dirent;
14316 + struct file * file;
14320 @@ -80,6 +83,10 @@ static int fillonedir(void * __buf, cons
14322 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
14325 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
14329 dirent = buf->dirent;
14330 if (!access_ok(VERIFY_WRITE, dirent,
14331 @@ -111,6 +118,7 @@ asmlinkage long old_readdir(unsigned int
14334 buf.dirent = dirent;
14337 error = vfs_readdir(file, fillonedir, &buf);
14339 @@ -137,6 +145,7 @@ struct linux_dirent {
14340 struct getdents_callback {
14341 struct linux_dirent __user * current_dir;
14342 struct linux_dirent __user * previous;
14343 + struct file * file;
14347 @@ -155,6 +164,10 @@ static int filldir(void * __buf, const c
14349 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
14352 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
14355 dirent = buf->previous;
14357 if (__put_user(offset, &dirent->d_off))
14358 @@ -201,6 +214,7 @@ asmlinkage long sys_getdents(unsigned in
14359 buf.previous = NULL;
14364 error = vfs_readdir(file, filldir, &buf);
14366 @@ -225,6 +239,7 @@ out:
14367 struct getdents_callback64 {
14368 struct linux_dirent64 __user * current_dir;
14369 struct linux_dirent64 __user * previous;
14370 + struct file *file;
14374 @@ -239,6 +254,10 @@ static int filldir64(void * __buf, const
14375 buf->error = -EINVAL; /* only used if we fail.. */
14376 if (reclen > buf->count)
14379 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
14382 dirent = buf->previous;
14384 if (__put_user(offset, &dirent->d_off))
14385 @@ -285,6 +304,7 @@ asmlinkage long sys_getdents64(unsigned
14387 buf.current_dir = dirent;
14388 buf.previous = NULL;
14393 diff -urNp linux-2.6.20.3/fs/udf/balloc.c linux-2.6.20.3/fs/udf/balloc.c
14394 --- linux-2.6.20.3/fs/udf/balloc.c 2007-03-13 14:27:08.000000000 -0400
14395 +++ linux-2.6.20.3/fs/udf/balloc.c 2007-03-23 08:10:06.000000000 -0400
14396 @@ -153,8 +153,7 @@ static void udf_bitmap_free_blocks(struc
14397 unsigned long overflow;
14399 mutex_lock(&sbi->s_alloc_mutex);
14400 - if (bloc.logicalBlockNum < 0 ||
14401 - (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
14402 + if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
14404 udf_debug("%d < %d || %d + %d > %d\n",
14405 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
14406 @@ -227,7 +226,7 @@ static int udf_bitmap_prealloc_blocks(st
14407 struct buffer_head *bh;
14409 mutex_lock(&sbi->s_alloc_mutex);
14410 - if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
14411 + if (first_block >= UDF_SB_PARTLEN(sb, partition))
14414 if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
14415 @@ -294,7 +293,7 @@ static int udf_bitmap_new_block(struct s
14416 mutex_lock(&sbi->s_alloc_mutex);
14419 - if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
14420 + if (goal >= UDF_SB_PARTLEN(sb, partition))
14423 nr_groups = bitmap->s_nr_groups;
14424 @@ -434,8 +433,7 @@ static void udf_table_free_blocks(struct
14427 mutex_lock(&sbi->s_alloc_mutex);
14428 - if (bloc.logicalBlockNum < 0 ||
14429 - (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
14430 + if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
14432 udf_debug("%d < %d || %d + %d > %d\n",
14433 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
14434 @@ -682,7 +680,7 @@ static int udf_table_prealloc_blocks(str
14435 struct buffer_head *bh;
14438 - if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
14439 + if (first_block >= UDF_SB_PARTLEN(sb, partition))
14442 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
14443 @@ -762,7 +760,7 @@ static int udf_table_new_block(struct su
14446 mutex_lock(&sbi->s_alloc_mutex);
14447 - if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
14448 + if (goal >= UDF_SB_PARTLEN(sb, partition))
14451 /* We search for the closest matching block to goal. If we find a exact hit,
14452 diff -urNp linux-2.6.20.3/fs/udf/inode.c linux-2.6.20.3/fs/udf/inode.c
14453 --- linux-2.6.20.3/fs/udf/inode.c 2007-03-13 14:27:08.000000000 -0400
14454 +++ linux-2.6.20.3/fs/udf/inode.c 2007-03-23 08:10:06.000000000 -0400
14455 @@ -300,9 +300,6 @@ static int udf_get_block(struct inode *i
14460 - goto abort_negative;
14462 if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
14464 UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
14465 @@ -323,10 +320,6 @@ static int udf_get_block(struct inode *i
14471 - udf_warning(inode->i_sb, "udf_get_block", "block < 0");
14475 static struct buffer_head *
14476 diff -urNp linux-2.6.20.3/fs/ufs/inode.c linux-2.6.20.3/fs/ufs/inode.c
14477 --- linux-2.6.20.3/fs/ufs/inode.c 2007-03-13 14:27:08.000000000 -0400
14478 +++ linux-2.6.20.3/fs/ufs/inode.c 2007-03-23 08:10:06.000000000 -0400
14479 @@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod
14482 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
14483 - if (i_block < 0) {
14484 - ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
14485 - } else if (i_block < direct_blocks) {
14486 + if (i_block < direct_blocks) {
14487 offsets[n++] = i_block;
14488 } else if ((i_block -= direct_blocks) < indirect_blocks) {
14489 offsets[n++] = UFS_IND_BLOCK;
14490 @@ -425,8 +423,6 @@ int ufs_getfrag_block(struct inode *inod
14493 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
14494 - if (fragment < 0)
14495 - goto abort_negative;
14497 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
14498 << uspi->s_fpbshift))
14499 @@ -489,10 +485,6 @@ abort:
14504 - ufs_warning(sb, "ufs_get_block", "block < 0");
14508 ufs_warning(sb, "ufs_get_block", "block > big");
14510 diff -urNp linux-2.6.20.3/fs/utimes.c linux-2.6.20.3/fs/utimes.c
14511 --- linux-2.6.20.3/fs/utimes.c 2007-03-13 14:27:08.000000000 -0400
14512 +++ linux-2.6.20.3/fs/utimes.c 2007-03-23 08:11:31.000000000 -0400
14514 #include <linux/utime.h>
14515 #include <linux/mount.h>
14516 #include <linux/vs_cowbl.h>
14517 +#include <linux/grsecurity.h>
14518 #include <asm/uaccess.h>
14519 #include <asm/unistd.h>
14521 @@ -63,6 +64,12 @@ asmlinkage long sys_utime(char __user *
14522 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
14526 + if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
14528 + goto dput_and_out;
14531 mutex_lock(&inode->i_mutex);
14532 error = notify_change(nd.dentry, &newattrs);
14533 mutex_unlock(&inode->i_mutex);
14534 @@ -115,6 +122,12 @@ long do_utimes(int dfd, char __user *fil
14535 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
14539 + if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
14541 + goto dput_and_out;
14544 mutex_lock(&inode->i_mutex);
14545 error = notify_change(nd.dentry, &newattrs);
14546 mutex_unlock(&inode->i_mutex);
14547 diff -urNp linux-2.6.20.3/fs/xfs/linux-2.6/xfs_file.c linux-2.6.20.3/fs/xfs/linux-2.6/xfs_file.c
14548 --- linux-2.6.20.3/fs/xfs/linux-2.6/xfs_file.c 2007-03-13 14:27:08.000000000 -0400
14549 +++ linux-2.6.20.3/fs/xfs/linux-2.6/xfs_file.c 2007-03-23 08:10:06.000000000 -0400
14550 @@ -342,6 +342,12 @@ xfs_file_mmap(
14552 struct vm_area_struct *vma)
14555 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
14556 + if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
14557 + vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
14560 vma->vm_ops = &xfs_file_vm_ops;
14562 #ifdef CONFIG_XFS_DMAPI
14563 diff -urNp linux-2.6.20.3/fs/xfs/xfs_bmap.c linux-2.6.20.3/fs/xfs/xfs_bmap.c
14564 --- linux-2.6.20.3/fs/xfs/xfs_bmap.c 2007-03-13 14:27:08.000000000 -0400
14565 +++ linux-2.6.20.3/fs/xfs/xfs_bmap.c 2007-03-23 08:10:06.000000000 -0400
14566 @@ -376,7 +376,7 @@ xfs_bmap_validate_ret(
14570 -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
14571 +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
14574 #if defined(XFS_RW_TRACE)
14575 diff -urNp linux-2.6.20.3/grsecurity/gracl_alloc.c linux-2.6.20.3/grsecurity/gracl_alloc.c
14576 --- linux-2.6.20.3/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
14577 +++ linux-2.6.20.3/grsecurity/gracl_alloc.c 2007-03-23 08:11:31.000000000 -0400
14579 +#include <linux/kernel.h>
14580 +#include <linux/mm.h>
14581 +#include <linux/slab.h>
14582 +#include <linux/vmalloc.h>
14583 +#include <linux/gracl.h>
14584 +#include <linux/grsecurity.h>
14586 +static unsigned long alloc_stack_next = 1;
14587 +static unsigned long alloc_stack_size = 1;
14588 +static void **alloc_stack;
14590 +static __inline__ int
14593 + if (alloc_stack_next == 1)
14596 + kfree(alloc_stack[alloc_stack_next - 2]);
14598 + alloc_stack_next--;
14603 +static __inline__ void
14604 +alloc_push(void *buf)
14606 + if (alloc_stack_next >= alloc_stack_size)
14609 + alloc_stack[alloc_stack_next - 1] = buf;
14611 + alloc_stack_next++;
14617 +acl_alloc(unsigned long len)
14621 + if (len > PAGE_SIZE)
14624 + ret = kmalloc(len, GFP_KERNEL);
14633 +acl_free_all(void)
14635 + if (gr_acl_is_enabled() || !alloc_stack)
14638 + while (alloc_pop()) ;
14640 + if (alloc_stack) {
14641 + if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
14642 + kfree(alloc_stack);
14644 + vfree(alloc_stack);
14647 + alloc_stack = NULL;
14648 + alloc_stack_size = 1;
14649 + alloc_stack_next = 1;
14655 +acl_alloc_stack_init(unsigned long size)
14657 + if ((size * sizeof (void *)) <= PAGE_SIZE)
14659 + (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
14661 + alloc_stack = (void **) vmalloc(size * sizeof (void *));
14663 + alloc_stack_size = size;
14665 + if (!alloc_stack)
14670 diff -urNp linux-2.6.20.3/grsecurity/gracl.c linux-2.6.20.3/grsecurity/gracl.c
14671 --- linux-2.6.20.3/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
14672 +++ linux-2.6.20.3/grsecurity/gracl.c 2007-03-23 08:11:31.000000000 -0400
14674 +#include <linux/kernel.h>
14675 +#include <linux/module.h>
14676 +#include <linux/sched.h>
14677 +#include <linux/mm.h>
14678 +#include <linux/file.h>
14679 +#include <linux/fs.h>
14680 +#include <linux/namei.h>
14681 +#include <linux/mount.h>
14682 +#include <linux/tty.h>
14683 +#include <linux/proc_fs.h>
14684 +#include <linux/smp_lock.h>
14685 +#include <linux/slab.h>
14686 +#include <linux/vmalloc.h>
14687 +#include <linux/types.h>
14688 +#include <linux/capability.h>
14689 +#include <linux/sysctl.h>
14690 +#include <linux/netdevice.h>
14691 +#include <linux/ptrace.h>
14692 +#include <linux/gracl.h>
14693 +#include <linux/gralloc.h>
14694 +#include <linux/grsecurity.h>
14695 +#include <linux/grinternal.h>
14696 +#include <linux/pid_namespace.h>
14697 +#include <linux/percpu.h>
14699 +#include <asm/uaccess.h>
14700 +#include <asm/errno.h>
14701 +#include <asm/mman.h>
14703 +static struct acl_role_db acl_role_set;
14704 +static struct name_db name_set;
14705 +static struct inodev_db inodev_set;
14707 +/* for keeping track of userspace pointers used for subjects, so we
14708 + can share references in the kernel as well
14711 +static struct dentry *real_root;
14712 +static struct vfsmount *real_root_mnt;
14714 +static struct acl_subj_map_db subj_map_set;
14716 +static struct acl_role_label *default_role;
14718 +static u16 acl_sp_role_value;
14720 +extern char *gr_shared_page[4];
14721 +static DECLARE_MUTEX(gr_dev_sem);
14722 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
14724 +struct gr_arg *gr_usermode;
14726 +static unsigned int gr_status = GR_STATUS_INIT;
14728 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
14729 +extern void gr_clear_learn_entries(void);
14731 +#ifdef CONFIG_GRKERNSEC_RESLOG
14732 +extern void gr_log_resource(const struct task_struct *task,
14733 + const int res, const unsigned long wanted, const int gt);
14736 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
14737 + struct dentry *root, struct vfsmount *rootmnt,
14738 + char *buffer, int buflen);
14740 +unsigned char *gr_system_salt;
14741 +unsigned char *gr_system_sum;
14743 +static struct sprole_pw **acl_special_roles = NULL;
14744 +static __u16 num_sprole_pws = 0;
14746 +static struct acl_role_label *kernel_role = NULL;
14748 +static unsigned int gr_auth_attempts = 0;
14749 +static unsigned long gr_auth_expires = 0UL;
14751 +extern struct vfsmount *sock_mnt;
14752 +extern struct vfsmount *pipe_mnt;
14753 +extern struct vfsmount *shm_mnt;
14754 +static struct acl_object_label *fakefs_obj;
14756 +extern int gr_init_uidset(void);
14757 +extern void gr_free_uidset(void);
14758 +extern void gr_remove_uid(uid_t uid);
14759 +extern int gr_find_uid(uid_t uid);
14762 +gr_acl_is_enabled(void)
14764 + return (gr_status & GR_READY);
14767 +char gr_roletype_to_char(void)
14769 + switch (current->role->roletype &
14770 + (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
14771 + GR_ROLE_SPECIAL)) {
14772 + case GR_ROLE_DEFAULT:
14774 + case GR_ROLE_USER:
14776 + case GR_ROLE_GROUP:
14778 + case GR_ROLE_SPECIAL:
14786 +gr_acl_tpe_check(void)
14788 + if (unlikely(!(gr_status & GR_READY)))
14790 + if (current->role->roletype & GR_ROLE_TPE)
14797 +gr_handle_rawio(const struct inode *inode)
14799 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
14800 + if (inode && S_ISBLK(inode->i_mode) &&
14801 + grsec_enable_chroot_caps && proc_is_chrooted(current) &&
14802 + !capable(CAP_SYS_RAWIO))
14809 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
14812 + unsigned long *l1;
14813 + unsigned long *l2;
14814 + unsigned char *c1;
14815 + unsigned char *c2;
14818 + if (likely(lena != lenb))
14821 + l1 = (unsigned long *)a;
14822 + l2 = (unsigned long *)b;
14824 + num_longs = lena / sizeof(unsigned long);
14826 + for (i = num_longs; i--; l1++, l2++) {
14827 + if (unlikely(*l1 != *l2))
14831 + c1 = (unsigned char *) l1;
14832 + c2 = (unsigned char *) l2;
14834 + i = lena - (num_longs * sizeof(unsigned long));
14836 + for (; i--; c1++, c2++) {
14837 + if (unlikely(*c1 != *c2))
14845 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
14846 + struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
14848 + char *end = buf + buflen;
14854 + retval = end - 1;
14857 + if (dentry == root && vfsmnt == rootmnt)
14859 + if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
14860 + namelen = strlen(dentry->d_name.name);
14861 + buflen -= namelen;
14864 + if (dentry->d_parent != root || vfsmnt != rootmnt)
14868 + retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
14869 + if (unlikely(IS_ERR(retval)))
14871 + retval = strcpy(buf, "<path too long>");
14872 + else if (namelen != 0) {
14873 + end = buf + buflen - 1; // accounts for null termination
14874 + if (dentry->d_parent != root || vfsmnt != rootmnt)
14875 + *end++ = '/'; // accounted for above with buflen--
14876 + memcpy(end, dentry->d_name.name, namelen);
14883 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
14884 + char *buf, int buflen)
14888 + /* we can use real_root, real_root_mnt, because this is only called
14889 + by the RBAC system */
14890 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
14896 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
14897 + char *buf, int buflen)
14900 + struct dentry *root;
14901 + struct vfsmount *rootmnt;
14902 + struct task_struct *reaper = child_reaper(current);
14904 + /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
14905 + read_lock(&reaper->fs->lock);
14906 + root = dget(reaper->fs->root);
14907 + rootmnt = mntget(reaper->fs->rootmnt);
14908 + read_unlock(&reaper->fs->lock);
14910 + spin_lock(&dcache_lock);
14911 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
14912 + spin_unlock(&dcache_lock);
14920 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
14923 + spin_lock(&dcache_lock);
14924 + ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
14926 + spin_unlock(&dcache_lock);
14931 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
14933 + return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
14938 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
14940 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
14945 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
14947 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
14952 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
14954 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
14959 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
14961 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
14966 +to_gr_audit(const __u32 reqmode)
14968 + /* masks off auditable permission flags, then shifts them to create
14969 + auditing flags, and adds the special case of append auditing if
14970 + we're requesting write */
14971 + return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
14974 +struct acl_subject_label *
14975 +lookup_subject_map(const struct acl_subject_label *userp)
14977 + unsigned int index = shash(userp, subj_map_set.s_size);
14978 + struct subject_map *match;
14980 + match = subj_map_set.s_hash[index];
14982 + while (match && match->user != userp)
14983 + match = match->next;
14985 + if (match != NULL)
14986 + return match->kernel;
14992 +insert_subj_map_entry(struct subject_map *subjmap)
14994 + unsigned int index = shash(subjmap->user, subj_map_set.s_size);
14995 + struct subject_map **curr;
14997 + subjmap->prev = NULL;
14999 + curr = &subj_map_set.s_hash[index];
15000 + if (*curr != NULL)
15001 + (*curr)->prev = subjmap;
15003 + subjmap->next = *curr;
15009 +static struct acl_role_label *
15010 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
15013 + unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
15014 + struct acl_role_label *match;
15015 + struct role_allowed_ip *ipp;
15018 + match = acl_role_set.r_hash[index];
15021 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
15022 + for (x = 0; x < match->domain_child_num; x++) {
15023 + if (match->domain_children[x] == uid)
15026 + } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
15028 + match = match->next;
15031 + if (match == NULL) {
15033 + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
15034 + match = acl_role_set.r_hash[index];
15037 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
15038 + for (x = 0; x < match->domain_child_num; x++) {
15039 + if (match->domain_children[x] == gid)
15042 + } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
15044 + match = match->next;
15047 + if (match == NULL)
15048 + match = default_role;
15049 + if (match->allowed_ips == NULL)
15052 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
15054 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
15055 + (ntohl(ipp->addr) & ipp->netmask)))
15058 + match = default_role;
15060 + } else if (match->allowed_ips == NULL) {
15063 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
15065 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
15066 + (ntohl(ipp->addr) & ipp->netmask)))
15075 +struct acl_subject_label *
15076 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
15077 + const struct acl_role_label *role)
15079 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
15080 + struct acl_subject_label *match;
15082 + match = role->subj_hash[index];
15084 + while (match && (match->inode != ino || match->device != dev ||
15085 + (match->mode & GR_DELETED))) {
15086 + match = match->next;
15089 + if (match && !(match->mode & GR_DELETED))
15095 +static struct acl_object_label *
15096 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
15097 + const struct acl_subject_label *subj)
15099 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
15100 + struct acl_object_label *match;
15102 + match = subj->obj_hash[index];
15104 + while (match && (match->inode != ino || match->device != dev ||
15105 + (match->mode & GR_DELETED))) {
15106 + match = match->next;
15109 + if (match && !(match->mode & GR_DELETED))
15115 +static struct acl_object_label *
15116 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
15117 + const struct acl_subject_label *subj)
15119 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
15120 + struct acl_object_label *match;
15122 + match = subj->obj_hash[index];
15124 + while (match && (match->inode != ino || match->device != dev ||
15125 + !(match->mode & GR_DELETED))) {
15126 + match = match->next;
15129 + if (match && (match->mode & GR_DELETED))
15132 + match = subj->obj_hash[index];
15134 + while (match && (match->inode != ino || match->device != dev ||
15135 + (match->mode & GR_DELETED))) {
15136 + match = match->next;
15139 + if (match && !(match->mode & GR_DELETED))
15145 +static struct name_entry *
15146 +lookup_name_entry(const char *name)
15148 + unsigned int len = strlen(name);
15149 + unsigned int key = full_name_hash(name, len);
15150 + unsigned int index = key % name_set.n_size;
15151 + struct name_entry *match;
15153 + match = name_set.n_hash[index];
15155 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
15156 + match = match->next;
15161 +static struct inodev_entry *
15162 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
15164 + unsigned int index = fhash(ino, dev, inodev_set.i_size);
15165 + struct inodev_entry *match;
15167 + match = inodev_set.i_hash[index];
15169 + while (match && (match->nentry->inode != ino || match->nentry->device != dev))
15170 + match = match->next;
15176 +insert_inodev_entry(struct inodev_entry *entry)
15178 + unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
15179 + inodev_set.i_size);
15180 + struct inodev_entry **curr;
15182 + entry->prev = NULL;
15184 + curr = &inodev_set.i_hash[index];
15185 + if (*curr != NULL)
15186 + (*curr)->prev = entry;
15188 + entry->next = *curr;
15195 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
15197 + unsigned int index =
15198 + rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
15199 + struct acl_role_label **curr;
15201 + role->prev = NULL;
15203 + curr = &acl_role_set.r_hash[index];
15204 + if (*curr != NULL)
15205 + (*curr)->prev = role;
15207 + role->next = *curr;
15214 +insert_acl_role_label(struct acl_role_label *role)
15218 + if (role->roletype & GR_ROLE_DOMAIN) {
15219 + for (i = 0; i < role->domain_child_num; i++)
15220 + __insert_acl_role_label(role, role->domain_children[i]);
15222 + __insert_acl_role_label(role, role->uidgid);
15226 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
15228 + struct name_entry **curr, *nentry;
15229 + struct inodev_entry *ientry;
15230 + unsigned int len = strlen(name);
15231 + unsigned int key = full_name_hash(name, len);
15232 + unsigned int index = key % name_set.n_size;
15234 + curr = &name_set.n_hash[index];
15236 + while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
15237 + curr = &((*curr)->next);
15239 + if (*curr != NULL)
15242 + nentry = acl_alloc(sizeof (struct name_entry));
15243 + if (nentry == NULL)
15245 + ientry = acl_alloc(sizeof (struct inodev_entry));
15246 + if (ientry == NULL)
15248 + ientry->nentry = nentry;
15250 + nentry->key = key;
15251 + nentry->name = name;
15252 + nentry->inode = inode;
15253 + nentry->device = device;
15254 + nentry->len = len;
15256 + nentry->prev = NULL;
15257 + curr = &name_set.n_hash[index];
15258 + if (*curr != NULL)
15259 + (*curr)->prev = nentry;
15260 + nentry->next = *curr;
15263 + /* insert us into the table searchable by inode/dev */
15264 + insert_inodev_entry(ientry);
15270 +insert_acl_obj_label(struct acl_object_label *obj,
15271 + struct acl_subject_label *subj)
15273 + unsigned int index =
15274 + fhash(obj->inode, obj->device, subj->obj_hash_size);
15275 + struct acl_object_label **curr;
15278 + obj->prev = NULL;
15280 + curr = &subj->obj_hash[index];
15281 + if (*curr != NULL)
15282 + (*curr)->prev = obj;
15284 + obj->next = *curr;
15291 +insert_acl_subj_label(struct acl_subject_label *obj,
15292 + struct acl_role_label *role)
15294 + unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
15295 + struct acl_subject_label **curr;
15297 + obj->prev = NULL;
15299 + curr = &role->subj_hash[index];
15300 + if (*curr != NULL)
15301 + (*curr)->prev = obj;
15303 + obj->next = *curr;
15309 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
15312 +create_table(__u32 * len, int elementsize)
15314 + unsigned int table_sizes[] = {
15315 + 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
15316 + 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
15317 + 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
15318 + 268435399, 536870909, 1073741789, 2147483647
15320 + void *newtable = NULL;
15321 + unsigned int pwr = 0;
15323 + while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
15324 + table_sizes[pwr] <= *len)
15327 + if (table_sizes[pwr] <= *len)
15330 + if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
15332 + kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
15334 + newtable = vmalloc(table_sizes[pwr] * elementsize);
15336 + *len = table_sizes[pwr];
15342 +init_variables(const struct gr_arg *arg)
15344 + struct task_struct *reaper = child_reaper(current);
15345 + unsigned int stacksize;
15347 + subj_map_set.s_size = arg->role_db.num_subjects;
15348 + acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
15349 + name_set.n_size = arg->role_db.num_objects;
15350 + inodev_set.i_size = arg->role_db.num_objects;
15352 + if (!subj_map_set.s_size || !acl_role_set.r_size ||
15353 + !name_set.n_size || !inodev_set.i_size)
15356 + if (!gr_init_uidset())
15359 + /* set up the stack that holds allocation info */
15361 + stacksize = arg->role_db.num_pointers + 5;
15363 + if (!acl_alloc_stack_init(stacksize))
15366 + /* grab reference for the real root dentry and vfsmount */
15367 + read_lock(&reaper->fs->lock);
15368 + real_root_mnt = mntget(reaper->fs->rootmnt);
15369 + real_root = dget(reaper->fs->root);
15370 + read_unlock(&reaper->fs->lock);
15372 + fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
15373 + if (fakefs_obj == NULL)
15375 + fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
15377 + subj_map_set.s_hash =
15378 + (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
15379 + acl_role_set.r_hash =
15380 + (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
15381 + name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
15382 + inodev_set.i_hash =
15383 + (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
15385 + if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
15386 + !name_set.n_hash || !inodev_set.i_hash)
15389 + memset(subj_map_set.s_hash, 0,
15390 + sizeof(struct subject_map *) * subj_map_set.s_size);
15391 + memset(acl_role_set.r_hash, 0,
15392 + sizeof (struct acl_role_label *) * acl_role_set.r_size);
15393 + memset(name_set.n_hash, 0,
15394 + sizeof (struct name_entry *) * name_set.n_size);
15395 + memset(inodev_set.i_hash, 0,
15396 + sizeof (struct inodev_entry *) * inodev_set.i_size);
15401 +/* free information not needed after startup
15402 + currently contains user->kernel pointer mappings for subjects
15406 +free_init_variables(void)
15410 + if (subj_map_set.s_hash) {
15411 + for (i = 0; i < subj_map_set.s_size; i++) {
15412 + if (subj_map_set.s_hash[i]) {
15413 + kfree(subj_map_set.s_hash[i]);
15414 + subj_map_set.s_hash[i] = NULL;
15418 + if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
15420 + kfree(subj_map_set.s_hash);
15422 + vfree(subj_map_set.s_hash);
15429 +free_variables(void)
15431 + struct acl_subject_label *s;
15432 + struct acl_role_label *r;
15433 + struct task_struct *task, *task2;
15434 + unsigned int i, x;
15436 + gr_clear_learn_entries();
15438 + read_lock(&tasklist_lock);
15439 + do_each_thread(task2, task) {
15440 + task->acl_sp_role = 0;
15441 + task->acl_role_id = 0;
15442 + task->acl = NULL;
15443 + task->role = NULL;
15444 + } while_each_thread(task2, task);
15445 + read_unlock(&tasklist_lock);
15447 + /* release the reference to the real root dentry and vfsmount */
15450 + real_root = NULL;
15451 + if (real_root_mnt)
15452 + mntput(real_root_mnt);
15453 + real_root_mnt = NULL;
15455 + /* free all object hash tables */
15457 + FOR_EACH_ROLE_START(r, i)
15458 + if (r->subj_hash == NULL)
15460 + FOR_EACH_SUBJECT_START(r, s, x)
15461 + if (s->obj_hash == NULL)
15463 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
15464 + kfree(s->obj_hash);
15466 + vfree(s->obj_hash);
15467 + FOR_EACH_SUBJECT_END(s, x)
15468 + FOR_EACH_NESTED_SUBJECT_START(r, s)
15469 + if (s->obj_hash == NULL)
15471 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
15472 + kfree(s->obj_hash);
15474 + vfree(s->obj_hash);
15475 + FOR_EACH_NESTED_SUBJECT_END(s)
15476 + if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
15477 + kfree(r->subj_hash);
15479 + vfree(r->subj_hash);
15480 + r->subj_hash = NULL;
15481 + FOR_EACH_ROLE_END(r,i)
15485 + if (acl_role_set.r_hash) {
15486 + if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
15488 + kfree(acl_role_set.r_hash);
15490 + vfree(acl_role_set.r_hash);
15492 + if (name_set.n_hash) {
15493 + if ((name_set.n_size * sizeof (struct name_entry *)) <=
15495 + kfree(name_set.n_hash);
15497 + vfree(name_set.n_hash);
15500 + if (inodev_set.i_hash) {
15501 + if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
15503 + kfree(inodev_set.i_hash);
15505 + vfree(inodev_set.i_hash);
15508 + gr_free_uidset();
15510 + memset(&name_set, 0, sizeof (struct name_db));
15511 + memset(&inodev_set, 0, sizeof (struct inodev_db));
15512 + memset(&acl_role_set, 0, sizeof (struct acl_role_db));
15513 + memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
15515 + default_role = NULL;
15521 +count_user_objs(struct acl_object_label *userp)
15523 + struct acl_object_label o_tmp;
15527 + if (copy_from_user(&o_tmp, userp,
15528 + sizeof (struct acl_object_label)))
15531 + userp = o_tmp.prev;
15538 +static struct acl_subject_label *
15539 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
15542 +copy_user_glob(struct acl_object_label *obj)
15544 + struct acl_object_label *g_tmp, **guser;
15545 + unsigned int len;
15548 + if (obj->globbed == NULL)
15551 + guser = &obj->globbed;
15553 + g_tmp = (struct acl_object_label *)
15554 + acl_alloc(sizeof (struct acl_object_label));
15555 + if (g_tmp == NULL)
15558 + if (copy_from_user(g_tmp, *guser,
15559 + sizeof (struct acl_object_label)))
15562 + len = strnlen_user(g_tmp->filename, PATH_MAX);
15564 + if (!len || len >= PATH_MAX)
15567 + if ((tmp = (char *) acl_alloc(len)) == NULL)
15570 + if (copy_from_user(tmp, g_tmp->filename, len))
15573 + g_tmp->filename = tmp;
15576 + guser = &(g_tmp->next);
15583 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
15584 + struct acl_role_label *role)
15586 + struct acl_object_label *o_tmp;
15587 + unsigned int len;
15592 + if ((o_tmp = (struct acl_object_label *)
15593 + acl_alloc(sizeof (struct acl_object_label))) == NULL)
15596 + if (copy_from_user(o_tmp, userp,
15597 + sizeof (struct acl_object_label)))
15600 + userp = o_tmp->prev;
15602 + len = strnlen_user(o_tmp->filename, PATH_MAX);
15604 + if (!len || len >= PATH_MAX)
15607 + if ((tmp = (char *) acl_alloc(len)) == NULL)
15610 + if (copy_from_user(tmp, o_tmp->filename, len))
15613 + o_tmp->filename = tmp;
15615 + insert_acl_obj_label(o_tmp, subj);
15616 + if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
15620 + ret = copy_user_glob(o_tmp);
15624 + if (o_tmp->nested) {
15625 + o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
15626 + if (IS_ERR(o_tmp->nested))
15627 + return PTR_ERR(o_tmp->nested);
15629 + /* insert into nested subject list */
15630 + o_tmp->nested->next = role->hash->first;
15631 + role->hash->first = o_tmp->nested;
15639 +count_user_subjs(struct acl_subject_label *userp)
15641 + struct acl_subject_label s_tmp;
15645 + if (copy_from_user(&s_tmp, userp,
15646 + sizeof (struct acl_subject_label)))
15649 + userp = s_tmp.prev;
15650 + /* do not count nested subjects against this count, since
15651 + they are not included in the hash table, but are
15652 + attached to objects. We have already counted
15653 + the subjects in userspace for the allocation
15656 + if (!(s_tmp.mode & GR_NESTED))
15664 +copy_user_allowedips(struct acl_role_label *rolep)
15666 + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
15668 + ruserip = rolep->allowed_ips;
15670 + while (ruserip) {
15673 + if ((rtmp = (struct role_allowed_ip *)
15674 + acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
15677 + if (copy_from_user(rtmp, ruserip,
15678 + sizeof (struct role_allowed_ip)))
15681 + ruserip = rtmp->prev;
15684 + rtmp->prev = NULL;
15685 + rolep->allowed_ips = rtmp;
15687 + rlast->next = rtmp;
15688 + rtmp->prev = rlast;
15692 + rtmp->next = NULL;
15699 +copy_user_transitions(struct acl_role_label *rolep)
15701 + struct role_transition *rusertp, *rtmp = NULL, *rlast;
15703 + unsigned int len;
15706 + rusertp = rolep->transitions;
15708 + while (rusertp) {
15711 + if ((rtmp = (struct role_transition *)
15712 + acl_alloc(sizeof (struct role_transition))) == NULL)
15715 + if (copy_from_user(rtmp, rusertp,
15716 + sizeof (struct role_transition)))
15719 + rusertp = rtmp->prev;
15721 + len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
15723 + if (!len || len >= GR_SPROLE_LEN)
15726 + if ((tmp = (char *) acl_alloc(len)) == NULL)
15729 + if (copy_from_user(tmp, rtmp->rolename, len))
15732 + rtmp->rolename = tmp;
15735 + rtmp->prev = NULL;
15736 + rolep->transitions = rtmp;
15738 + rlast->next = rtmp;
15739 + rtmp->prev = rlast;
15743 + rtmp->next = NULL;
15749 +static struct acl_subject_label *
15750 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
15752 + struct acl_subject_label *s_tmp = NULL, *s_tmp2;
15753 + unsigned int len;
15756 + struct acl_ip_label **i_tmp, *i_utmp2;
15757 + struct gr_hash_struct ghash;
15758 + struct subject_map *subjmap;
15759 + unsigned int i_num;
15762 + s_tmp = lookup_subject_map(userp);
15764 + /* we've already copied this subject into the kernel, just return
15765 + the reference to it, and don't copy it over again
15770 + if ((s_tmp = (struct acl_subject_label *)
15771 + acl_alloc(sizeof (struct acl_subject_label))) == NULL)
15772 + return ERR_PTR(-ENOMEM);
15774 + subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
15775 + if (subjmap == NULL)
15776 + return ERR_PTR(-ENOMEM);
15778 + subjmap->user = userp;
15779 + subjmap->kernel = s_tmp;
15780 + insert_subj_map_entry(subjmap);
15782 + if (copy_from_user(s_tmp, userp,
15783 + sizeof (struct acl_subject_label)))
15784 + return ERR_PTR(-EFAULT);
15786 + len = strnlen_user(s_tmp->filename, PATH_MAX);
15788 + if (!len || len >= PATH_MAX)
15789 + return ERR_PTR(-EINVAL);
15791 + if ((tmp = (char *) acl_alloc(len)) == NULL)
15792 + return ERR_PTR(-ENOMEM);
15794 + if (copy_from_user(tmp, s_tmp->filename, len))
15795 + return ERR_PTR(-EFAULT);
15797 + s_tmp->filename = tmp;
15799 + if (!strcmp(s_tmp->filename, "/"))
15800 + role->root_label = s_tmp;
15802 + if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
15803 + return ERR_PTR(-EFAULT);
15805 + /* copy user and group transition tables */
15807 + if (s_tmp->user_trans_num) {
15810 + uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
15811 + if (uidlist == NULL)
15812 + return ERR_PTR(-ENOMEM);
15813 + if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
15814 + return ERR_PTR(-EFAULT);
15816 + s_tmp->user_transitions = uidlist;
15819 + if (s_tmp->group_trans_num) {
15822 + gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
15823 + if (gidlist == NULL)
15824 + return ERR_PTR(-ENOMEM);
15825 + if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
15826 + return ERR_PTR(-EFAULT);
15828 + s_tmp->group_transitions = gidlist;
15831 + /* set up object hash table */
15832 + num_objs = count_user_objs(ghash.first);
15834 + s_tmp->obj_hash_size = num_objs;
15835 + s_tmp->obj_hash =
15836 + (struct acl_object_label **)
15837 + create_table(&(s_tmp->obj_hash_size), sizeof(void *));
15839 + if (!s_tmp->obj_hash)
15840 + return ERR_PTR(-ENOMEM);
15842 + memset(s_tmp->obj_hash, 0,
15843 + s_tmp->obj_hash_size *
15844 + sizeof (struct acl_object_label *));
15846 + /* add in objects */
15847 + err = copy_user_objs(ghash.first, s_tmp, role);
15850 + return ERR_PTR(err);
15852 + /* set pointer for parent subject */
15853 + if (s_tmp->parent_subject) {
15854 + s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
15856 + if (IS_ERR(s_tmp2))
15859 + s_tmp->parent_subject = s_tmp2;
15862 + /* add in ip acls */
15864 + if (!s_tmp->ip_num) {
15865 + s_tmp->ips = NULL;
15870 + (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
15872 + acl_ip_label *));
15875 + return ERR_PTR(-ENOMEM);
15877 + for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
15878 + *(i_tmp + i_num) =
15879 + (struct acl_ip_label *)
15880 + acl_alloc(sizeof (struct acl_ip_label));
15881 + if (!*(i_tmp + i_num))
15882 + return ERR_PTR(-ENOMEM);
15884 + if (copy_from_user
15885 + (&i_utmp2, s_tmp->ips + i_num,
15886 + sizeof (struct acl_ip_label *)))
15887 + return ERR_PTR(-EFAULT);
15889 + if (copy_from_user
15890 + (*(i_tmp + i_num), i_utmp2,
15891 + sizeof (struct acl_ip_label)))
15892 + return ERR_PTR(-EFAULT);
15894 + if ((*(i_tmp + i_num))->iface == NULL)
15897 + len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
15898 + if (!len || len >= IFNAMSIZ)
15899 + return ERR_PTR(-EINVAL);
15900 + tmp = acl_alloc(len);
15902 + return ERR_PTR(-ENOMEM);
15903 + if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
15904 + return ERR_PTR(-EFAULT);
15905 + (*(i_tmp + i_num))->iface = tmp;
15908 + s_tmp->ips = i_tmp;
15911 + if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
15913 + return ERR_PTR(-ENOMEM);
15919 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
15921 + struct acl_subject_label s_pre;
15922 + struct acl_subject_label * ret;
15926 + if (copy_from_user(&s_pre, userp,
15927 + sizeof (struct acl_subject_label)))
15930 + /* do not add nested subjects here, add
15931 + while parsing objects
15934 + if (s_pre.mode & GR_NESTED) {
15935 + userp = s_pre.prev;
15939 + ret = do_copy_user_subj(userp, role);
15941 + err = PTR_ERR(ret);
15945 + insert_acl_subj_label(ret, role);
15947 + userp = s_pre.prev;
15954 +copy_user_acl(struct gr_arg *arg)
15956 + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
15957 + struct sprole_pw *sptmp;
15958 + struct gr_hash_struct *ghash;
15959 + uid_t *domainlist;
15960 + unsigned int r_num;
15961 + unsigned int len;
15967 + /* we need a default and kernel role */
15968 + if (arg->role_db.num_roles < 2)
15971 + /* copy special role authentication info from userspace */
15973 + num_sprole_pws = arg->num_sprole_pws;
15974 + acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
15976 + if (!acl_special_roles) {
15981 + for (i = 0; i < num_sprole_pws; i++) {
15982 + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
15987 + if (copy_from_user(sptmp, arg->sprole_pws + i,
15988 + sizeof (struct sprole_pw))) {
15994 + strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
15996 + if (!len || len >= GR_SPROLE_LEN) {
16001 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
16006 + if (copy_from_user(tmp, sptmp->rolename, len)) {
16011 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
16012 + printk(KERN_ALERT "Copying special role %s\n", tmp);
16014 + sptmp->rolename = tmp;
16015 + acl_special_roles[i] = sptmp;
16018 + r_utmp = (struct acl_role_label **) arg->role_db.r_table;
16020 + for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
16021 + r_tmp = acl_alloc(sizeof (struct acl_role_label));
16028 + if (copy_from_user(&r_utmp2, r_utmp + r_num,
16029 + sizeof (struct acl_role_label *))) {
16034 + if (copy_from_user(r_tmp, r_utmp2,
16035 + sizeof (struct acl_role_label))) {
16040 + len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
16042 + if (!len || len >= PATH_MAX) {
16047 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
16051 + if (copy_from_user(tmp, r_tmp->rolename, len)) {
16055 + r_tmp->rolename = tmp;
16057 + if (!strcmp(r_tmp->rolename, "default")
16058 + && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
16059 + default_role = r_tmp;
16060 + } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
16061 + kernel_role = r_tmp;
16064 + if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
16068 + if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
16073 + r_tmp->hash = ghash;
16075 + num_subjs = count_user_subjs(r_tmp->hash->first);
16077 + r_tmp->subj_hash_size = num_subjs;
16078 + r_tmp->subj_hash =
16079 + (struct acl_subject_label **)
16080 + create_table(&(r_tmp->subj_hash_size), sizeof(void *));
16082 + if (!r_tmp->subj_hash) {
16087 + err = copy_user_allowedips(r_tmp);
16091 + /* copy domain info */
16092 + if (r_tmp->domain_children != NULL) {
16093 + domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
16094 + if (domainlist == NULL) {
16098 + if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
16102 + r_tmp->domain_children = domainlist;
16105 + err = copy_user_transitions(r_tmp);
16109 + memset(r_tmp->subj_hash, 0,
16110 + r_tmp->subj_hash_size *
16111 + sizeof (struct acl_subject_label *));
16113 + err = copy_user_subjs(r_tmp->hash->first, r_tmp);
16118 + /* set nested subject list to null */
16119 + r_tmp->hash->first = NULL;
16121 + insert_acl_role_label(r_tmp);
16126 + free_variables();
16133 +gracl_init(struct gr_arg *args)
16137 + memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
16138 + memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
16140 + if (init_variables(args)) {
16141 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
16143 + free_variables();
16147 + error = copy_user_acl(args);
16148 + free_init_variables();
16150 + free_variables();
16154 + if ((error = gr_set_acls(0))) {
16155 + free_variables();
16159 + gr_status |= GR_READY;
16164 +/* derived from glibc fnmatch() 0: match, 1: no match*/
16167 +glob_match(const char *p, const char *n)
16171 + while ((c = *p++) != '\0') {
16176 + else if (*n == '/')
16184 + for (c = *p++; c == '?' || c == '*'; c = *p++) {
16187 + else if (c == '?') {
16197 + const char *endp;
16199 + if ((endp = strchr(n, '/')) == NULL)
16200 + endp = n + strlen(n);
16203 + for (--p; n < endp; ++n)
16204 + if (!glob_match(p, n))
16206 + } else if (c == '/') {
16207 + while (*n != '\0' && *n != '/')
16209 + if (*n == '/' && !glob_match(p, n + 1))
16212 + for (--p; n < endp; ++n)
16213 + if (*n == c && !glob_match(p, n))
16224 + if (*n == '\0' || *n == '/')
16227 + not = (*p == '!' || *p == '^');
16233 + unsigned char fn = (unsigned char)*n;
16243 + if (c == '-' && *p != ']') {
16244 + unsigned char cend = *p++;
16246 + if (cend == '\0')
16249 + if (cold <= fn && fn <= cend)
16263 + while (c != ']') {
16290 +static struct acl_object_label *
16291 +chk_glob_label(struct acl_object_label *globbed,
16292 + struct dentry *dentry, struct vfsmount *mnt, char **path)
16294 + struct acl_object_label *tmp;
16296 + if (*path == NULL)
16297 + *path = gr_to_filename_nolock(dentry, mnt);
16302 + if (!glob_match(tmp->filename, *path))
16310 +static struct acl_object_label *
16311 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
16312 + const ino_t curr_ino, const dev_t curr_dev,
16313 + const struct acl_subject_label *subj, char **path)
16315 + struct acl_subject_label *tmpsubj;
16316 + struct acl_object_label *retval;
16317 + struct acl_object_label *retval2;
16319 + tmpsubj = (struct acl_subject_label *) subj;
16320 + read_lock(&gr_inode_lock);
16322 + retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
16324 + if (retval->globbed) {
16325 + retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
16326 + (struct vfsmount *)orig_mnt, path);
16328 + retval = retval2;
16332 + } while ((tmpsubj = tmpsubj->parent_subject));
16333 + read_unlock(&gr_inode_lock);
16338 +static __inline__ struct acl_object_label *
16339 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
16340 + const struct dentry *curr_dentry,
16341 + const struct acl_subject_label *subj, char **path)
16343 + return __full_lookup(orig_dentry, orig_mnt,
16344 + curr_dentry->d_inode->i_ino,
16345 + curr_dentry->d_inode->i_sb->s_dev, subj, path);
16348 +static struct acl_object_label *
16349 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
16350 + const struct acl_subject_label *subj, char *path)
16352 + struct dentry *dentry = (struct dentry *) l_dentry;
16353 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
16354 + struct acl_object_label *retval;
16356 + spin_lock(&dcache_lock);
16358 + if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt)) {
16359 + retval = fakefs_obj;
16364 + if (dentry == real_root && mnt == real_root_mnt)
16367 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
16368 + if (mnt->mnt_parent == mnt)
16371 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
16372 + if (retval != NULL)
16375 + dentry = mnt->mnt_mountpoint;
16376 + mnt = mnt->mnt_parent;
16380 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
16381 + if (retval != NULL)
16384 + dentry = dentry->d_parent;
16387 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
16389 + if (retval == NULL)
16390 + retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
16392 + spin_unlock(&dcache_lock);
16396 +static __inline__ struct acl_object_label *
16397 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
16398 + const struct acl_subject_label *subj)
16400 + char *path = NULL;
16401 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
16404 +static __inline__ struct acl_object_label *
16405 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
16406 + const struct acl_subject_label *subj, char *path)
16408 + return __chk_obj_label(l_dentry, l_mnt, subj, path);
16411 +static struct acl_subject_label *
16412 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
16413 + const struct acl_role_label *role)
16415 + struct dentry *dentry = (struct dentry *) l_dentry;
16416 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
16417 + struct acl_subject_label *retval;
16419 + spin_lock(&dcache_lock);
16422 + if (dentry == real_root && mnt == real_root_mnt)
16424 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
16425 + if (mnt->mnt_parent == mnt)
16428 + read_lock(&gr_inode_lock);
16430 + lookup_acl_subj_label(dentry->d_inode->i_ino,
16431 + dentry->d_inode->i_sb->s_dev, role);
16432 + read_unlock(&gr_inode_lock);
16433 + if (retval != NULL)
16436 + dentry = mnt->mnt_mountpoint;
16437 + mnt = mnt->mnt_parent;
16441 + read_lock(&gr_inode_lock);
16442 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
16443 + dentry->d_inode->i_sb->s_dev, role);
16444 + read_unlock(&gr_inode_lock);
16445 + if (retval != NULL)
16448 + dentry = dentry->d_parent;
16451 + read_lock(&gr_inode_lock);
16452 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
16453 + dentry->d_inode->i_sb->s_dev, role);
16454 + read_unlock(&gr_inode_lock);
16456 + if (unlikely(retval == NULL)) {
16457 + read_lock(&gr_inode_lock);
16458 + retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
16459 + real_root->d_inode->i_sb->s_dev, role);
16460 + read_unlock(&gr_inode_lock);
16463 + spin_unlock(&dcache_lock);
16469 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
16471 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
16472 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
16473 + task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
16474 + 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
16480 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
16481 + const unsigned int effective, const unsigned int fs)
16483 + security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
16484 + task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
16485 + task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
16486 + type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
16492 +gr_check_link(const struct dentry * new_dentry,
16493 + const struct dentry * parent_dentry,
16494 + const struct vfsmount * parent_mnt,
16495 + const struct dentry * old_dentry, const struct vfsmount * old_mnt)
16497 + struct acl_object_label *obj;
16498 + __u32 oldmode, newmode;
16501 + if (unlikely(!(gr_status & GR_READY)))
16502 + return (GR_CREATE | GR_LINK);
16504 + obj = chk_obj_label(old_dentry, old_mnt, current->acl);
16505 + oldmode = obj->mode;
16507 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
16508 + oldmode |= (GR_CREATE | GR_LINK);
16510 + needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
16511 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
16512 + needmode |= GR_SETID | GR_AUDIT_SETID;
16515 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
16516 + oldmode | needmode);
16518 + needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
16519 + GR_SETID | GR_READ | GR_FIND | GR_DELETE |
16520 + GR_INHERIT | GR_AUDIT_INHERIT);
16522 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
16525 + if ((oldmode & needmode) != needmode)
16528 + needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
16529 + if ((newmode & needmode) != needmode)
16532 + if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
16535 + needmode = oldmode;
16536 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
16537 + needmode |= GR_SETID;
16539 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
16540 + gr_log_learn(current, old_dentry, old_mnt, needmode);
16541 + return (GR_CREATE | GR_LINK);
16542 + } else if (newmode & GR_SUPPRESS)
16543 + return GR_SUPPRESS;
16549 +gr_search_file(const struct dentry * dentry, const __u32 mode,
16550 + const struct vfsmount * mnt)
16552 + __u32 retval = mode;
16553 + struct acl_subject_label *curracl;
16554 + struct acl_object_label *currobj;
16556 + if (unlikely(!(gr_status & GR_READY)))
16557 + return (mode & ~GR_AUDITS);
16559 + curracl = current->acl;
16561 + currobj = chk_obj_label(dentry, mnt, curracl);
16562 + retval = currobj->mode & mode;
16565 + ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
16566 + && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
16567 + __u32 new_mode = mode;
16569 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
16571 + retval = new_mode;
16573 + if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
16574 + new_mode |= GR_INHERIT;
16576 + if (!(mode & GR_NOLEARN))
16577 + gr_log_learn(current, dentry, mnt, new_mode);
16584 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
16585 + const struct vfsmount * mnt, const __u32 mode)
16587 + struct name_entry *match;
16588 + struct acl_object_label *matchpo;
16589 + struct acl_subject_label *curracl;
16593 + if (unlikely(!(gr_status & GR_READY)))
16594 + return (mode & ~GR_AUDITS);
16596 + preempt_disable();
16597 + path = gr_to_filename_rbac(new_dentry, mnt);
16598 + match = lookup_name_entry(path);
16601 + goto check_parent;
16603 + curracl = current->acl;
16605 + read_lock(&gr_inode_lock);
16606 + matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
16607 + read_unlock(&gr_inode_lock);
16610 + if ((matchpo->mode & mode) !=
16611 + (mode & ~(GR_AUDITS | GR_SUPPRESS))
16612 + && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
16613 + __u32 new_mode = mode;
16615 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
16617 + gr_log_learn(current, new_dentry, mnt, new_mode);
16619 + preempt_enable();
16622 + preempt_enable();
16623 + return (matchpo->mode & mode);
16627 + curracl = current->acl;
16629 + matchpo = chk_obj_create_label(parent, mnt, curracl, path);
16630 + retval = matchpo->mode & mode;
16632 + if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
16633 + && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
16634 + __u32 new_mode = mode;
16636 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
16638 + gr_log_learn(current, new_dentry, mnt, new_mode);
16639 + preempt_enable();
16643 + preempt_enable();
16648 +gr_check_hidden_task(const struct task_struct *task)
16650 + if (unlikely(!(gr_status & GR_READY)))
16653 + if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
16660 +gr_check_protected_task(const struct task_struct *task)
16662 + if (unlikely(!(gr_status & GR_READY) || !task))
16665 + if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
16666 + task->acl != current->acl)
16673 +gr_copy_label(struct task_struct *tsk)
16675 + tsk->signal->used_accept = 0;
16676 + tsk->acl_sp_role = 0;
16677 + tsk->acl_role_id = current->acl_role_id;
16678 + tsk->acl = current->acl;
16679 + tsk->role = current->role;
16680 + tsk->signal->curr_ip = current->signal->curr_ip;
16681 + if (current->exec_file)
16682 + get_file(current->exec_file);
16683 + tsk->exec_file = current->exec_file;
16684 + tsk->is_writable = current->is_writable;
16685 + if (unlikely(current->signal->used_accept))
16686 + current->signal->curr_ip = 0;
16692 +gr_set_proc_res(struct task_struct *task)
16694 + struct acl_subject_label *proc;
16695 + unsigned short i;
16697 + proc = task->acl;
16699 + if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
16702 + for (i = 0; i < (GR_NLIMITS - 1); i++) {
16703 + if (!(proc->resmask & (1 << i)))
16706 + task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
16707 + task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
16714 +gr_check_user_change(int real, int effective, int fs)
16721 + int effectiveok = 0;
16724 + if (unlikely(!(gr_status & GR_READY)))
16727 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
16728 + gr_log_learn_id_change(current, 'u', real, effective, fs);
16730 + num = current->acl->user_trans_num;
16731 + uidlist = current->acl->user_transitions;
16733 + if (uidlist == NULL)
16738 + if (effective == -1)
16743 + if (current->acl->user_trans_type & GR_ID_ALLOW) {
16744 + for (i = 0; i < num; i++) {
16745 + curuid = (int)uidlist[i];
16746 + if (real == curuid)
16748 + if (effective == curuid)
16750 + if (fs == curuid)
16753 + } else if (current->acl->user_trans_type & GR_ID_DENY) {
16754 + for (i = 0; i < num; i++) {
16755 + curuid = (int)uidlist[i];
16756 + if (real == curuid)
16758 + if (effective == curuid)
16760 + if (fs == curuid)
16763 + /* not in deny list */
16771 + if (realok && effectiveok && fsok)
16774 + gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
16780 +gr_check_group_change(int real, int effective, int fs)
16787 + int effectiveok = 0;
16790 + if (unlikely(!(gr_status & GR_READY)))
16793 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
16794 + gr_log_learn_id_change(current, 'g', real, effective, fs);
16796 + num = current->acl->group_trans_num;
16797 + gidlist = current->acl->group_transitions;
16799 + if (gidlist == NULL)
16804 + if (effective == -1)
16809 + if (current->acl->group_trans_type & GR_ID_ALLOW) {
16810 + for (i = 0; i < num; i++) {
16811 + curgid = (int)gidlist[i];
16812 + if (real == curgid)
16814 + if (effective == curgid)
16816 + if (fs == curgid)
16819 + } else if (current->acl->group_trans_type & GR_ID_DENY) {
16820 + for (i = 0; i < num; i++) {
16821 + curgid = (int)gidlist[i];
16822 + if (real == curgid)
16824 + if (effective == curgid)
16826 + if (fs == curgid)
16829 + /* not in deny list */
16837 + if (realok && effectiveok && fsok)
16840 + gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
16846 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
16848 + struct acl_role_label *role = task->role;
16849 + struct acl_subject_label *subj = NULL;
16850 + struct acl_object_label *obj;
16851 + struct file *filp;
16853 + if (unlikely(!(gr_status & GR_READY)))
16856 + filp = task->exec_file;
16858 + /* kernel process, we'll give them the kernel role */
16859 + if (unlikely(!filp)) {
16860 + task->role = kernel_role;
16861 + task->acl = kernel_role->root_label;
16863 + } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
16864 + role = lookup_acl_role_label(task, uid, gid);
16866 + /* perform subject lookup in possibly new role
16867 + we can use this result below in the case where role == task->role
16869 + subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
16871 + /* if we changed uid/gid, but result in the same role
16872 + and are using inheritance, don't lose the inherited subject
16873 + if current subject is other than what normal lookup
16874 + would result in, we arrived via inheritance, don't
16877 + if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
16878 + (subj == task->acl)))
16879 + task->acl = subj;
16881 + task->role = role;
16883 + task->is_writable = 0;
16885 + /* ignore additional mmap checks for processes that are writable
16886 + by the default ACL */
16887 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
16888 + if (unlikely(obj->mode & GR_WRITE))
16889 + task->is_writable = 1;
16890 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
16891 + if (unlikely(obj->mode & GR_WRITE))
16892 + task->is_writable = 1;
16894 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
16895 + printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
16898 + gr_set_proc_res(task);
16904 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
16906 + struct task_struct *task = current;
16907 + struct acl_subject_label *newacl;
16908 + struct acl_object_label *obj;
16911 + if (unlikely(!(gr_status & GR_READY)))
16914 + newacl = chk_subj_label(dentry, mnt, task->role);
16917 + if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
16918 + GR_POVERRIDE) && (task->acl != newacl) &&
16919 + !(task->role->roletype & GR_ROLE_GOD) &&
16920 + !gr_search_file(dentry, GR_PTRACERD, mnt) &&
16921 + !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
16922 + (atomic_read(&task->fs->count) > 1 ||
16923 + atomic_read(&task->files->count) > 1 ||
16924 + atomic_read(&task->sighand->count) > 1)) {
16925 + task_unlock(task);
16926 + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
16929 + task_unlock(task);
16931 + obj = chk_obj_label(dentry, mnt, task->acl);
16932 + retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
16934 + if (!(task->acl->mode & GR_INHERITLEARN) &&
16935 + ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
16937 + task->acl = obj->nested;
16939 + task->acl = newacl;
16940 + } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
16941 + gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
16943 + task->is_writable = 0;
16945 + /* ignore additional mmap checks for processes that are writable
16946 + by the default ACL */
16947 + obj = chk_obj_label(dentry, mnt, default_role->root_label);
16948 + if (unlikely(obj->mode & GR_WRITE))
16949 + task->is_writable = 1;
16950 + obj = chk_obj_label(dentry, mnt, task->role->root_label);
16951 + if (unlikely(obj->mode & GR_WRITE))
16952 + task->is_writable = 1;
16954 + gr_set_proc_res(task);
16956 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
16957 + printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
16963 +do_handle_delete(const ino_t ino, const dev_t dev)
16965 + struct acl_object_label *matchpo;
16966 + struct acl_subject_label *matchps;
16967 + struct acl_subject_label *subj;
16968 + struct acl_role_label *role;
16969 + unsigned int i, x;
16971 + FOR_EACH_ROLE_START(role, i)
16972 + FOR_EACH_SUBJECT_START(role, subj, x)
16973 + if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
16974 + matchpo->mode |= GR_DELETED;
16975 + FOR_EACH_SUBJECT_END(subj,x)
16976 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
16977 + if (subj->inode == ino && subj->device == dev)
16978 + subj->mode |= GR_DELETED;
16979 + FOR_EACH_NESTED_SUBJECT_END(subj)
16980 + if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
16981 + matchps->mode |= GR_DELETED;
16982 + FOR_EACH_ROLE_END(role,i)
16988 +gr_handle_delete(const ino_t ino, const dev_t dev)
16990 + if (unlikely(!(gr_status & GR_READY)))
16993 + write_lock(&gr_inode_lock);
16994 + if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
16995 + do_handle_delete(ino, dev);
16996 + write_unlock(&gr_inode_lock);
17002 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
17003 + const ino_t newinode, const dev_t newdevice,
17004 + struct acl_subject_label *subj)
17006 + unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
17007 + struct acl_object_label *match;
17009 + match = subj->obj_hash[index];
17011 + while (match && (match->inode != oldinode ||
17012 + match->device != olddevice ||
17013 + !(match->mode & GR_DELETED)))
17014 + match = match->next;
17016 + if (match && (match->inode == oldinode)
17017 + && (match->device == olddevice)
17018 + && (match->mode & GR_DELETED)) {
17019 + if (match->prev == NULL) {
17020 + subj->obj_hash[index] = match->next;
17021 + if (match->next != NULL)
17022 + match->next->prev = NULL;
17024 + match->prev->next = match->next;
17025 + if (match->next != NULL)
17026 + match->next->prev = match->prev;
17028 + match->prev = NULL;
17029 + match->next = NULL;
17030 + match->inode = newinode;
17031 + match->device = newdevice;
17032 + match->mode &= ~GR_DELETED;
17034 + insert_acl_obj_label(match, subj);
17041 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
17042 + const ino_t newinode, const dev_t newdevice,
17043 + struct acl_role_label *role)
17045 + unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
17046 + struct acl_subject_label *match;
17048 + match = role->subj_hash[index];
17050 + while (match && (match->inode != oldinode ||
17051 + match->device != olddevice ||
17052 + !(match->mode & GR_DELETED)))
17053 + match = match->next;
17055 + if (match && (match->inode == oldinode)
17056 + && (match->device == olddevice)
17057 + && (match->mode & GR_DELETED)) {
17058 + if (match->prev == NULL) {
17059 + role->subj_hash[index] = match->next;
17060 + if (match->next != NULL)
17061 + match->next->prev = NULL;
17063 + match->prev->next = match->next;
17064 + if (match->next != NULL)
17065 + match->next->prev = match->prev;
17067 + match->prev = NULL;
17068 + match->next = NULL;
17069 + match->inode = newinode;
17070 + match->device = newdevice;
17071 + match->mode &= ~GR_DELETED;
17073 + insert_acl_subj_label(match, role);
17080 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
17081 + const ino_t newinode, const dev_t newdevice)
17083 + unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
17084 + struct inodev_entry *match;
17086 + match = inodev_set.i_hash[index];
17088 + while (match && (match->nentry->inode != oldinode ||
17089 + match->nentry->device != olddevice))
17090 + match = match->next;
17092 + if (match && (match->nentry->inode == oldinode)
17093 + && (match->nentry->device == olddevice)) {
17094 + if (match->prev == NULL) {
17095 + inodev_set.i_hash[index] = match->next;
17096 + if (match->next != NULL)
17097 + match->next->prev = NULL;
17099 + match->prev->next = match->next;
17100 + if (match->next != NULL)
17101 + match->next->prev = match->prev;
17103 + match->prev = NULL;
17104 + match->next = NULL;
17105 + match->nentry->inode = newinode;
17106 + match->nentry->device = newdevice;
17108 + insert_inodev_entry(match);
17115 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
17116 + const struct vfsmount *mnt)
17118 + struct acl_subject_label *subj;
17119 + struct acl_role_label *role;
17120 + unsigned int i, x;
17122 + FOR_EACH_ROLE_START(role, i)
17123 + update_acl_subj_label(matchn->inode, matchn->device,
17124 + dentry->d_inode->i_ino,
17125 + dentry->d_inode->i_sb->s_dev, role);
17127 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
17128 + if ((subj->inode == dentry->d_inode->i_ino) &&
17129 + (subj->device == dentry->d_inode->i_sb->s_dev)) {
17130 + subj->inode = dentry->d_inode->i_ino;
17131 + subj->device = dentry->d_inode->i_sb->s_dev;
17133 + FOR_EACH_NESTED_SUBJECT_END(subj)
17134 + FOR_EACH_SUBJECT_START(role, subj, x)
17135 + update_acl_obj_label(matchn->inode, matchn->device,
17136 + dentry->d_inode->i_ino,
17137 + dentry->d_inode->i_sb->s_dev, subj);
17138 + FOR_EACH_SUBJECT_END(subj,x)
17139 + FOR_EACH_ROLE_END(role,i)
17141 + update_inodev_entry(matchn->inode, matchn->device,
17142 + dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
17148 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
17150 + struct name_entry *matchn;
17152 + if (unlikely(!(gr_status & GR_READY)))
17155 + preempt_disable();
17156 + matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
17158 + if (unlikely((unsigned long)matchn)) {
17159 + write_lock(&gr_inode_lock);
17160 + do_handle_create(matchn, dentry, mnt);
17161 + write_unlock(&gr_inode_lock);
17163 + preempt_enable();
17169 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
17170 + struct dentry *old_dentry,
17171 + struct dentry *new_dentry,
17172 + struct vfsmount *mnt, const __u8 replace)
17174 + struct name_entry *matchn;
17176 + if (unlikely(!(gr_status & GR_READY)))
17179 + preempt_disable();
17180 + matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
17182 + /* we wouldn't have to check d_inode if it weren't for
17183 + NFS silly-renaming
17186 + write_lock(&gr_inode_lock);
17187 + if (unlikely(replace && new_dentry->d_inode)) {
17188 + if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
17189 + new_dentry->d_inode->i_sb->s_dev) &&
17190 + (old_dentry->d_inode->i_nlink <= 1)))
17191 + do_handle_delete(new_dentry->d_inode->i_ino,
17192 + new_dentry->d_inode->i_sb->s_dev);
17195 + if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
17196 + old_dentry->d_inode->i_sb->s_dev) &&
17197 + (old_dentry->d_inode->i_nlink <= 1)))
17198 + do_handle_delete(old_dentry->d_inode->i_ino,
17199 + old_dentry->d_inode->i_sb->s_dev);
17201 + if (unlikely((unsigned long)matchn))
17202 + do_handle_create(matchn, old_dentry, mnt);
17204 + write_unlock(&gr_inode_lock);
17205 + preempt_enable();
17211 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
17212 + unsigned char **sum)
17214 + struct acl_role_label *r;
17215 + struct role_allowed_ip *ipp;
17216 + struct role_transition *trans;
17220 + /* check transition table */
17222 + for (trans = current->role->transitions; trans; trans = trans->next) {
17223 + if (!strcmp(rolename, trans->rolename)) {
17232 + /* handle special roles that do not require authentication
17235 + FOR_EACH_ROLE_START(r, i)
17236 + if (!strcmp(rolename, r->rolename) &&
17237 + (r->roletype & GR_ROLE_SPECIAL)) {
17239 + if (r->allowed_ips != NULL) {
17240 + for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
17241 + if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
17242 + (ntohl(ipp->addr) & ipp->netmask))
17250 + if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
17251 + ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
17257 + FOR_EACH_ROLE_END(r,i)
17259 + for (i = 0; i < num_sprole_pws; i++) {
17260 + if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
17261 + *salt = acl_special_roles[i]->salt;
17262 + *sum = acl_special_roles[i]->sum;
17271 +assign_special_role(char *rolename)
17273 + struct acl_object_label *obj;
17274 + struct acl_role_label *r;
17275 + struct acl_role_label *assigned = NULL;
17276 + struct task_struct *tsk;
17277 + struct file *filp;
17280 + FOR_EACH_ROLE_START(r, i)
17281 + if (!strcmp(rolename, r->rolename) &&
17282 + (r->roletype & GR_ROLE_SPECIAL))
17284 + FOR_EACH_ROLE_END(r,i)
17289 + read_lock(&tasklist_lock);
17290 + read_lock(&grsec_exec_file_lock);
17292 + tsk = current->parent;
17296 + filp = tsk->exec_file;
17297 + if (filp == NULL)
17300 + tsk->is_writable = 0;
17302 + tsk->acl_sp_role = 1;
17303 + tsk->acl_role_id = ++acl_sp_role_value;
17304 + tsk->role = assigned;
17305 + tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
17307 + /* ignore additional mmap checks for processes that are writable
17308 + by the default ACL */
17309 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
17310 + if (unlikely(obj->mode & GR_WRITE))
17311 + tsk->is_writable = 1;
17312 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
17313 + if (unlikely(obj->mode & GR_WRITE))
17314 + tsk->is_writable = 1;
17316 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
17317 + printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
17321 + read_unlock(&grsec_exec_file_lock);
17322 + read_unlock(&tasklist_lock);
17326 +int gr_check_secure_terminal(struct task_struct *task)
17328 + struct task_struct *p, *p2, *p3;
17329 + struct files_struct *files;
17330 + struct fdtable *fdt;
17331 + struct file *our_file = NULL, *file;
17334 + if (task->signal->tty == NULL)
17337 + files = get_files_struct(task);
17338 + if (files != NULL) {
17340 + fdt = files_fdtable(files);
17341 + for (i=0; i < fdt->max_fds; i++) {
17342 + file = fcheck_files(files, i);
17343 + if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
17348 + rcu_read_unlock();
17349 + put_files_struct(files);
17352 + if (our_file == NULL)
17355 + read_lock(&tasklist_lock);
17356 + do_each_thread(p2, p) {
17357 + files = get_files_struct(p);
17358 + if (files == NULL ||
17359 + (p->signal && p->signal->tty == task->signal->tty)) {
17360 + if (files != NULL)
17361 + put_files_struct(files);
17365 + fdt = files_fdtable(files);
17366 + for (i=0; i < fdt->max_fds; i++) {
17367 + file = fcheck_files(files, i);
17368 + if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
17369 + file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
17371 + while (p3->pid > 0) {
17378 + gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
17379 + gr_handle_alertkill(p);
17380 + rcu_read_unlock();
17381 + put_files_struct(files);
17382 + read_unlock(&tasklist_lock);
17387 + rcu_read_unlock();
17388 + put_files_struct(files);
17389 + } while_each_thread(p2, p);
17390 + read_unlock(&tasklist_lock);
17397 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
17399 + struct gr_arg_wrapper uwrap;
17400 + unsigned char *sprole_salt;
17401 + unsigned char *sprole_sum;
17402 + int error = sizeof (struct gr_arg_wrapper);
17405 + down(&gr_dev_sem);
17407 + if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
17412 + if (count != sizeof (struct gr_arg_wrapper)) {
17413 + gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
17419 + if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
17420 + gr_auth_expires = 0;
17421 + gr_auth_attempts = 0;
17424 + if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
17429 + if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
17434 + if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
17439 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
17440 + gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
17441 + time_after(gr_auth_expires, get_seconds())) {
17446 + /* if non-root trying to do anything other than use a special role,
17447 + do not attempt authentication, do not count towards authentication
17451 + if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
17452 + gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
17458 + /* ensure pw and special role name are null terminated */
17460 + gr_usermode->pw[GR_PW_LEN - 1] = '\0';
17461 + gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
17464 + * We have our enough of the argument structure..(we have yet
17465 + * to copy_from_user the tables themselves) . Copy the tables
17466 + * only if we need them, i.e. for loading operations. */
17468 + switch (gr_usermode->mode) {
17470 + if (gr_status & GR_READY) {
17472 + if (!gr_check_secure_terminal(current))
17478 + if ((gr_status & GR_READY)
17479 + && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
17480 + gr_status &= ~GR_READY;
17481 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
17482 + free_variables();
17483 + memset(gr_usermode, 0, sizeof (struct gr_arg));
17484 + memset(gr_system_salt, 0, GR_SALT_LEN);
17485 + memset(gr_system_sum, 0, GR_SHA_LEN);
17486 + } else if (gr_status & GR_READY) {
17487 + gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
17490 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
17495 + if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
17496 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
17498 + if (gr_status & GR_READY)
17502 + gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
17506 + if (!(gr_status & GR_READY)) {
17507 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
17509 + } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
17511 + gr_status &= ~GR_READY;
17512 + free_variables();
17513 + if (!(error2 = gracl_init(gr_usermode))) {
17515 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
17519 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
17522 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
17527 + if (unlikely(!(gr_status & GR_READY))) {
17528 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
17533 + if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
17534 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
17535 + if (gr_usermode->segv_device && gr_usermode->segv_inode) {
17536 + struct acl_subject_label *segvacl;
17538 + lookup_acl_subj_label(gr_usermode->segv_inode,
17539 + gr_usermode->segv_device,
17542 + segvacl->crashes = 0;
17543 + segvacl->expires = 0;
17545 + } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
17546 + gr_remove_uid(gr_usermode->segv_uid);
17549 + gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
17555 + if (unlikely(!(gr_status & GR_READY))) {
17556 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
17561 + if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
17562 + current->role->expires = 0;
17563 + current->role->auth_attempts = 0;
17566 + if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
17567 + time_after(current->role->expires, get_seconds())) {
17572 + if (lookup_special_role_auth
17573 + (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
17574 + && ((!sprole_salt && !sprole_sum)
17575 + || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
17577 + assign_special_role(gr_usermode->sp_role);
17578 + read_lock(&tasklist_lock);
17579 + if (current->parent)
17580 + p = current->parent->role->rolename;
17581 + read_unlock(&tasklist_lock);
17582 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
17583 + p, acl_sp_role_value);
17585 + gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
17587 + if(!(current->role->auth_attempts++))
17588 + current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
17594 + if (unlikely(!(gr_status & GR_READY))) {
17595 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
17600 + if (current->role->roletype & GR_ROLE_SPECIAL) {
17604 + read_lock(&tasklist_lock);
17605 + if (current->parent) {
17606 + p = current->parent->role->rolename;
17607 + i = current->parent->acl_role_id;
17609 + read_unlock(&tasklist_lock);
17611 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
17614 + gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
17620 + gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
17625 + if (error != -EPERM)
17628 + if(!(gr_auth_attempts++))
17629 + gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
17637 +gr_set_acls(const int type)
17639 + struct acl_object_label *obj;
17640 + struct task_struct *task, *task2;
17641 + struct file *filp;
17642 + struct acl_role_label *role = current->role;
17643 + __u16 acl_role_id = current->acl_role_id;
17645 + read_lock(&tasklist_lock);
17646 + read_lock(&grsec_exec_file_lock);
17647 + do_each_thread(task2, task) {
17648 + /* check to see if we're called from the exit handler,
17649 + if so, only replace ACLs that have inherited the admin
17652 + if (type && (task->role != role ||
17653 + task->acl_role_id != acl_role_id))
17656 + task->acl_role_id = 0;
17657 + task->acl_sp_role = 0;
17659 + if ((filp = task->exec_file)) {
17660 + task->role = lookup_acl_role_label(task, task->uid, task->gid);
17663 + chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
17666 + struct acl_subject_label *curr;
17667 + curr = task->acl;
17669 + task->is_writable = 0;
17670 + /* ignore additional mmap checks for processes that are writable
17671 + by the default ACL */
17672 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
17673 + if (unlikely(obj->mode & GR_WRITE))
17674 + task->is_writable = 1;
17675 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
17676 + if (unlikely(obj->mode & GR_WRITE))
17677 + task->is_writable = 1;
17679 + gr_set_proc_res(task);
17681 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
17682 + printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
17685 + read_unlock(&grsec_exec_file_lock);
17686 + read_unlock(&tasklist_lock);
17687 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
17691 + // it's a kernel process
17692 + task->role = kernel_role;
17693 + task->acl = kernel_role->root_label;
17694 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
17695 + task->acl->mode &= ~GR_PROCFIND;
17698 + } while_each_thread(task2, task);
17699 + read_unlock(&grsec_exec_file_lock);
17700 + read_unlock(&tasklist_lock);
17705 +gr_learn_resource(const struct task_struct *task,
17706 + const int res, const unsigned long wanted, const int gt)
17708 + struct acl_subject_label *acl;
17710 + if (unlikely((gr_status & GR_READY) &&
17711 + task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
17712 + goto skip_reslog;
17714 +#ifdef CONFIG_GRKERNSEC_RESLOG
17715 + gr_log_resource(task, res, wanted, gt);
17719 + if (unlikely(!(gr_status & GR_READY) || !wanted))
17724 + if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
17725 + !(acl->resmask & (1 << (unsigned short) res))))
17728 + if (wanted >= acl->res[res].rlim_cur) {
17729 + unsigned long res_add;
17731 + res_add = wanted;
17734 + res_add += GR_RLIM_CPU_BUMP;
17736 + case RLIMIT_FSIZE:
17737 + res_add += GR_RLIM_FSIZE_BUMP;
17739 + case RLIMIT_DATA:
17740 + res_add += GR_RLIM_DATA_BUMP;
17742 + case RLIMIT_STACK:
17743 + res_add += GR_RLIM_STACK_BUMP;
17745 + case RLIMIT_CORE:
17746 + res_add += GR_RLIM_CORE_BUMP;
17749 + res_add += GR_RLIM_RSS_BUMP;
17751 + case RLIMIT_NPROC:
17752 + res_add += GR_RLIM_NPROC_BUMP;
17754 + case RLIMIT_NOFILE:
17755 + res_add += GR_RLIM_NOFILE_BUMP;
17757 + case RLIMIT_MEMLOCK:
17758 + res_add += GR_RLIM_MEMLOCK_BUMP;
17761 + res_add += GR_RLIM_AS_BUMP;
17763 + case RLIMIT_LOCKS:
17764 + res_add += GR_RLIM_LOCKS_BUMP;
17768 + acl->res[res].rlim_cur = res_add;
17770 + if (wanted > acl->res[res].rlim_max)
17771 + acl->res[res].rlim_max = res_add;
17773 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
17774 + task->role->roletype, acl->filename,
17775 + acl->res[res].rlim_cur, acl->res[res].rlim_max,
17776 + "", (unsigned long) res);
17782 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
17784 +pax_set_initial_flags(struct linux_binprm *bprm)
17786 + struct task_struct *task = current;
17787 + struct acl_subject_label *proc;
17788 + unsigned long flags;
17790 + if (unlikely(!(gr_status & GR_READY)))
17793 + flags = pax_get_flags(task);
17795 + proc = task->acl;
17797 + if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
17798 + flags &= ~MF_PAX_PAGEEXEC;
17799 + if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
17800 + flags &= ~MF_PAX_SEGMEXEC;
17801 + if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
17802 + flags &= ~MF_PAX_RANDMMAP;
17803 + if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
17804 + flags &= ~MF_PAX_EMUTRAMP;
17805 + if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
17806 + flags &= ~MF_PAX_MPROTECT;
17808 + if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
17809 + flags |= MF_PAX_PAGEEXEC;
17810 + if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
17811 + flags |= MF_PAX_SEGMEXEC;
17812 + if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
17813 + flags |= MF_PAX_RANDMMAP;
17814 + if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
17815 + flags |= MF_PAX_EMUTRAMP;
17816 + if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
17817 + flags |= MF_PAX_MPROTECT;
17819 + pax_set_flags(task, flags);
17825 +#ifdef CONFIG_SYSCTL
17826 +extern struct proc_dir_entry *proc_sys_root;
17828 +/* the following function is called under the BKL */
17831 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
17832 + const void *newval)
17834 + struct proc_dir_entry *tmp;
17835 + struct nameidata nd;
17836 + const char *proc_sys = "/proc/sys";
17838 + struct acl_object_label *obj;
17839 + unsigned short len = 0, pos = 0, depth = 0, i;
17843 + if (unlikely(!(gr_status & GR_READY)))
17846 + path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
17851 + mode |= GR_WRITE;
17853 + /* convert the requested sysctl entry into a pathname */
17855 + for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
17856 + len += strlen(tmp->name);
17861 + if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
17862 + return 0; /* deny */
17864 + memset(path, 0, PAGE_SIZE);
17866 + memcpy(path, proc_sys, strlen(proc_sys));
17868 + pos += strlen(proc_sys);
17870 + for (; depth > 0; depth--) {
17873 + for (i = 1, tmp = table->de; tmp != proc_sys_root;
17874 + tmp = tmp->parent) {
17875 + if (depth == i) {
17876 + memcpy(path + pos, tmp->name,
17877 + strlen(tmp->name));
17878 + pos += strlen(tmp->name);
17884 + err = path_lookup(path, LOOKUP_FOLLOW, &nd);
17889 + obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
17890 + err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
17892 + if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
17893 + ((err & mode) != mode))) {
17894 + __u32 new_mode = mode;
17896 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
17899 + gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
17900 + } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
17901 + gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
17902 + path, (mode & GR_READ) ? " reading" : "",
17903 + (mode & GR_WRITE) ? " writing" : "");
17905 + } else if ((err & mode) != mode) {
17907 + } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
17908 + gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
17909 + path, (mode & GR_READ) ? " reading" : "",
17910 + (mode & GR_WRITE) ? " writing" : "");
17913 + path_release(&nd);
17921 +gr_handle_proc_ptrace(struct task_struct *task)
17923 + struct file *filp;
17924 + struct task_struct *tmp = task;
17925 + struct task_struct *curtemp = current;
17928 + if (unlikely(!(gr_status & GR_READY)))
17931 + read_lock(&tasklist_lock);
17932 + read_lock(&grsec_exec_file_lock);
17933 + filp = task->exec_file;
17935 + while (tmp->pid > 0) {
17936 + if (tmp == curtemp)
17938 + tmp = tmp->parent;
17941 + if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
17942 + read_unlock(&grsec_exec_file_lock);
17943 + read_unlock(&tasklist_lock);
17947 + retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
17948 + read_unlock(&grsec_exec_file_lock);
17949 + read_unlock(&tasklist_lock);
17951 + if (retmode & GR_NOPTRACE)
17954 + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
17955 + && (current->acl != task->acl || (current->acl != current->role->root_label
17956 + && current->pid != task->pid)))
17963 +gr_handle_ptrace(struct task_struct *task, const long request)
17965 + struct task_struct *tmp = task;
17966 + struct task_struct *curtemp = current;
17969 + if (unlikely(!(gr_status & GR_READY)))
17972 + read_lock(&tasklist_lock);
17973 + while (tmp->pid > 0) {
17974 + if (tmp == curtemp)
17976 + tmp = tmp->parent;
17979 + if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
17980 + read_unlock(&tasklist_lock);
17981 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
17984 + read_unlock(&tasklist_lock);
17986 + read_lock(&grsec_exec_file_lock);
17987 + if (unlikely(!task->exec_file)) {
17988 + read_unlock(&grsec_exec_file_lock);
17992 + retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
17993 + read_unlock(&grsec_exec_file_lock);
17995 + if (retmode & GR_NOPTRACE) {
17996 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
18000 + if (retmode & GR_PTRACERD) {
18001 + switch (request) {
18002 + case PTRACE_POKETEXT:
18003 + case PTRACE_POKEDATA:
18004 + case PTRACE_POKEUSR:
18005 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
18006 + case PTRACE_SETREGS:
18007 + case PTRACE_SETFPREGS:
18010 + case PTRACE_SETFPXREGS:
18012 +#ifdef CONFIG_ALTIVEC
18013 + case PTRACE_SETVRREGS:
18019 + } else if (!(current->acl->mode & GR_POVERRIDE) &&
18020 + !(current->role->roletype & GR_ROLE_GOD) &&
18021 + (current->acl != task->acl)) {
18022 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
18029 +static int is_writable_mmap(const struct file *filp)
18031 + struct task_struct *task = current;
18032 + struct acl_object_label *obj, *obj2;
18034 + if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
18035 + !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
18036 + obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
18037 + obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
18038 + task->role->root_label);
18039 + if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
18040 + gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
18048 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
18052 + if (unlikely(!file || !(prot & PROT_EXEC)))
18055 + if (is_writable_mmap(file))
18059 + gr_search_file(file->f_dentry,
18060 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
18063 + if (!gr_tpe_allow(file))
18066 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
18067 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
18069 + } else if (unlikely(!(mode & GR_EXEC))) {
18071 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
18072 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
18080 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
18084 + if (unlikely(!file || !(prot & PROT_EXEC)))
18087 + if (is_writable_mmap(file))
18091 + gr_search_file(file->f_dentry,
18092 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
18095 + if (!gr_tpe_allow(file))
18098 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
18099 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
18101 + } else if (unlikely(!(mode & GR_EXEC))) {
18103 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
18104 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
18112 +gr_acl_handle_psacct(struct task_struct *task, const long code)
18114 + unsigned long runtime;
18115 + unsigned long cputime;
18116 + unsigned int wday, cday;
18121 + if (unlikely(!(gr_status & GR_READY) || !task->acl ||
18122 + !(task->acl->mode & GR_PROCACCT)))
18125 + runtime = xtime.tv_sec - task->start_time.tv_sec;
18126 + wday = runtime / (3600 * 24);
18127 + runtime -= wday * (3600 * 24);
18128 + whr = runtime / 3600;
18129 + runtime -= whr * 3600;
18130 + wmin = runtime / 60;
18131 + runtime -= wmin * 60;
18134 + cputime = (task->utime + task->stime) / HZ;
18135 + cday = cputime / (3600 * 24);
18136 + cputime -= cday * (3600 * 24);
18137 + chr = cputime / 3600;
18138 + cputime -= chr * 3600;
18139 + cmin = cputime / 60;
18140 + cputime -= cmin * 60;
18143 + gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
18148 +void gr_set_kernel_label(struct task_struct *task)
18150 + if (gr_status & GR_READY) {
18151 + task->role = kernel_role;
18152 + task->acl = kernel_role->root_label;
18157 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
18159 + struct task_struct *task = current;
18160 + struct dentry *dentry = file->f_dentry;
18161 + struct vfsmount *mnt = file->f_vfsmnt;
18162 + struct acl_object_label *obj, *tmp;
18163 + struct acl_subject_label *subj;
18164 + unsigned int bufsize;
18168 + if (unlikely(!(gr_status & GR_READY)))
18171 + if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
18174 + subj = task->acl;
18176 + obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
18178 + return (obj->mode & GR_FIND) ? 1 : 0;
18179 + } while ((subj = subj->parent_subject));
18181 + obj = chk_obj_label(dentry, mnt, task->acl);
18182 + if (obj->globbed == NULL)
18183 + return (obj->mode & GR_FIND) ? 1 : 0;
18185 + is_not_root = ((obj->filename[0] == '/') &&
18186 + (obj->filename[1] == '\0')) ? 0 : 1;
18187 + bufsize = PAGE_SIZE - namelen - is_not_root;
18189 + /* check bufsize > PAGE_SIZE || bufsize == 0 */
18190 + if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
18193 + preempt_disable();
18194 + path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
18197 + bufsize = strlen(path);
18199 + /* if base is "/", don't append an additional slash */
18201 + *(path + bufsize) = '/';
18202 + memcpy(path + bufsize + is_not_root, name, namelen);
18203 + *(path + bufsize + namelen + is_not_root) = '\0';
18205 + tmp = obj->globbed;
18207 + if (!glob_match(tmp->filename, path)) {
18208 + preempt_enable();
18209 + return (tmp->mode & GR_FIND) ? 1 : 0;
18213 + preempt_enable();
18214 + return (obj->mode & GR_FIND) ? 1 : 0;
18217 +EXPORT_SYMBOL(gr_learn_resource);
18218 +EXPORT_SYMBOL(gr_set_kernel_label);
18219 +#ifdef CONFIG_SECURITY
18220 +EXPORT_SYMBOL(gr_check_user_change);
18221 +EXPORT_SYMBOL(gr_check_group_change);
18224 diff -urNp linux-2.6.20.3/grsecurity/gracl_cap.c linux-2.6.20.3/grsecurity/gracl_cap.c
18225 --- linux-2.6.20.3/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
18226 +++ linux-2.6.20.3/grsecurity/gracl_cap.c 2007-03-23 08:11:31.000000000 -0400
18228 +#include <linux/kernel.h>
18229 +#include <linux/module.h>
18230 +#include <linux/sched.h>
18231 +#include <linux/capability.h>
18232 +#include <linux/gracl.h>
18233 +#include <linux/grsecurity.h>
18234 +#include <linux/grinternal.h>
18236 +static const char *captab_log[] = {
18238 + "CAP_DAC_OVERRIDE",
18239 + "CAP_DAC_READ_SEARCH",
18246 + "CAP_LINUX_IMMUTABLE",
18247 + "CAP_NET_BIND_SERVICE",
18248 + "CAP_NET_BROADCAST",
18253 + "CAP_SYS_MODULE",
18255 + "CAP_SYS_CHROOT",
18256 + "CAP_SYS_PTRACE",
18261 + "CAP_SYS_RESOURCE",
18263 + "CAP_SYS_TTY_CONFIG",
18268 +EXPORT_SYMBOL(gr_task_is_capable);
18269 +EXPORT_SYMBOL(gr_is_capable_nolog);
18272 +gr_task_is_capable(struct task_struct *task, const int cap)
18274 + struct acl_subject_label *curracl;
18275 + __u32 cap_drop = 0, cap_mask = 0;
18277 + if (!gr_acl_is_enabled())
18280 + curracl = task->acl;
18282 + cap_drop = curracl->cap_lower;
18283 + cap_mask = curracl->cap_mask;
18285 + while ((curracl = curracl->parent_subject)) {
18286 + if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
18287 + cap_drop |= curracl->cap_lower & (1 << cap);
18288 + cap_mask |= curracl->cap_mask;
18291 + if (!cap_raised(cap_drop, cap))
18294 + curracl = task->acl;
18296 + if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
18297 + && cap_raised(task->cap_effective, cap)) {
18298 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
18299 + task->role->roletype, task->uid,
18300 + task->gid, task->exec_file ?
18301 + gr_to_filename(task->exec_file->f_dentry,
18302 + task->exec_file->f_vfsmnt) : curracl->filename,
18303 + curracl->filename, 0UL,
18304 + 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
18308 + if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
18309 + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
18314 +gr_is_capable_nolog(const int cap)
18316 + struct acl_subject_label *curracl;
18317 + __u32 cap_drop = 0, cap_mask = 0;
18319 + if (!gr_acl_is_enabled())
18322 + curracl = current->acl;
18324 + cap_drop = curracl->cap_lower;
18325 + cap_mask = curracl->cap_mask;
18327 + while ((curracl = curracl->parent_subject)) {
18328 + cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
18329 + cap_mask |= curracl->cap_mask;
18332 + if (!cap_raised(cap_drop, cap))
18338 diff -urNp linux-2.6.20.3/grsecurity/gracl_fs.c linux-2.6.20.3/grsecurity/gracl_fs.c
18339 --- linux-2.6.20.3/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
18340 +++ linux-2.6.20.3/grsecurity/gracl_fs.c 2007-03-23 08:11:31.000000000 -0400
18342 +#include <linux/kernel.h>
18343 +#include <linux/sched.h>
18344 +#include <linux/types.h>
18345 +#include <linux/fs.h>
18346 +#include <linux/file.h>
18347 +#include <linux/stat.h>
18348 +#include <linux/grsecurity.h>
18349 +#include <linux/grinternal.h>
18350 +#include <linux/gracl.h>
18353 +gr_acl_handle_hidden_file(const struct dentry * dentry,
18354 + const struct vfsmount * mnt)
18358 + if (unlikely(!dentry->d_inode))
18362 + gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
18364 + if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
18365 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
18367 + } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
18368 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
18370 + } else if (unlikely(!(mode & GR_FIND)))
18377 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
18380 + __u32 reqmode = GR_FIND;
18383 + if (unlikely(!dentry->d_inode))
18386 + if (unlikely(fmode & O_APPEND))
18387 + reqmode |= GR_APPEND;
18388 + else if (unlikely(fmode & FMODE_WRITE))
18389 + reqmode |= GR_WRITE;
18390 + if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
18391 + reqmode |= GR_READ;
18394 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
18397 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
18398 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
18399 + reqmode & GR_READ ? " reading" : "",
18400 + reqmode & GR_WRITE ? " writing" : reqmode &
18401 + GR_APPEND ? " appending" : "");
18404 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
18406 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
18407 + reqmode & GR_READ ? " reading" : "",
18408 + reqmode & GR_WRITE ? " writing" : reqmode &
18409 + GR_APPEND ? " appending" : "");
18411 + } else if (unlikely((mode & reqmode) != reqmode))
18418 +gr_acl_handle_creat(const struct dentry * dentry,
18419 + const struct dentry * p_dentry,
18420 + const struct vfsmount * p_mnt, const int fmode,
18423 + __u32 reqmode = GR_WRITE | GR_CREATE;
18426 + if (unlikely(fmode & O_APPEND))
18427 + reqmode |= GR_APPEND;
18428 + if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
18429 + reqmode |= GR_READ;
18430 + if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
18431 + reqmode |= GR_SETID;
18434 + gr_check_create(dentry, p_dentry, p_mnt,
18435 + reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
18437 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
18438 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
18439 + reqmode & GR_READ ? " reading" : "",
18440 + reqmode & GR_WRITE ? " writing" : reqmode &
18441 + GR_APPEND ? " appending" : "");
18444 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
18446 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
18447 + reqmode & GR_READ ? " reading" : "",
18448 + reqmode & GR_WRITE ? " writing" : reqmode &
18449 + GR_APPEND ? " appending" : "");
18451 + } else if (unlikely((mode & reqmode) != reqmode))
18458 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
18461 + __u32 mode, reqmode = GR_FIND;
18463 + if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
18464 + reqmode |= GR_EXEC;
18465 + if (fmode & S_IWOTH)
18466 + reqmode |= GR_WRITE;
18467 + if (fmode & S_IROTH)
18468 + reqmode |= GR_READ;
18471 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
18474 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
18475 + gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
18476 + reqmode & GR_READ ? " reading" : "",
18477 + reqmode & GR_WRITE ? " writing" : "",
18478 + reqmode & GR_EXEC ? " executing" : "");
18481 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
18483 + gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
18484 + reqmode & GR_READ ? " reading" : "",
18485 + reqmode & GR_WRITE ? " writing" : "",
18486 + reqmode & GR_EXEC ? " executing" : "");
18488 + } else if (unlikely((mode & reqmode) != reqmode))
18494 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
18498 + mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
18500 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
18501 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
18503 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
18504 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
18506 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
18509 + return (reqmode);
18513 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
18515 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
18519 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
18521 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
18525 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
18527 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
18531 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
18533 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
18537 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
18540 + if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
18543 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
18544 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
18545 + GR_FCHMOD_ACL_MSG);
18547 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
18552 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
18555 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
18556 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
18557 + GR_CHMOD_ACL_MSG);
18559 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
18564 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
18566 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
18570 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
18572 + return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
18576 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
18578 + return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
18579 + GR_UNIXCONNECT_ACL_MSG);
18582 +/* hardlinks require at minimum create permission,
18583 + any additional privilege required is based on the
18584 + privilege of the file being linked to
18587 +gr_acl_handle_link(const struct dentry * new_dentry,
18588 + const struct dentry * parent_dentry,
18589 + const struct vfsmount * parent_mnt,
18590 + const struct dentry * old_dentry,
18591 + const struct vfsmount * old_mnt, const char *to)
18594 + __u32 needmode = GR_CREATE | GR_LINK;
18595 + __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
18598 + gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
18601 + if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
18602 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
18604 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
18605 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
18607 + } else if (unlikely((mode & needmode) != needmode))
18614 +gr_acl_handle_symlink(const struct dentry * new_dentry,
18615 + const struct dentry * parent_dentry,
18616 + const struct vfsmount * parent_mnt, const char *from)
18618 + __u32 needmode = GR_WRITE | GR_CREATE;
18622 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
18623 + GR_CREATE | GR_AUDIT_CREATE |
18624 + GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
18626 + if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
18627 + gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
18629 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
18630 + gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
18632 + } else if (unlikely((mode & needmode) != needmode))
18635 + return (GR_WRITE | GR_CREATE);
18638 +static __u32 generic_fs_create_handler(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, __u32 reqmode, const char *fmt)
18642 + mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
18644 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
18645 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
18647 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
18648 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
18650 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
18653 + return (reqmode);
18657 +gr_acl_handle_mknod(const struct dentry * new_dentry,
18658 + const struct dentry * parent_dentry,
18659 + const struct vfsmount * parent_mnt,
18662 + __u32 reqmode = GR_WRITE | GR_CREATE;
18663 + if (unlikely(mode & (S_ISUID | S_ISGID)))
18664 + reqmode |= GR_SETID;
18666 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
18667 + reqmode, GR_MKNOD_ACL_MSG);
18671 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
18672 + const struct dentry *parent_dentry,
18673 + const struct vfsmount *parent_mnt)
18675 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
18676 + GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
18679 +#define RENAME_CHECK_SUCCESS(old, new) \
18680 + (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
18681 + ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
18684 +gr_acl_handle_rename(struct dentry *new_dentry,
18685 + struct dentry *parent_dentry,
18686 + const struct vfsmount *parent_mnt,
18687 + struct dentry *old_dentry,
18688 + struct inode *old_parent_inode,
18689 + struct vfsmount *old_mnt, const char *newname)
18691 + __u32 comp1, comp2;
18694 + if (unlikely(!gr_acl_is_enabled()))
18697 + if (!new_dentry->d_inode) {
18698 + comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
18699 + GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
18700 + GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
18701 + comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
18702 + GR_DELETE | GR_AUDIT_DELETE |
18703 + GR_AUDIT_READ | GR_AUDIT_WRITE |
18704 + GR_SUPPRESS, old_mnt);
18706 + comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
18707 + GR_CREATE | GR_DELETE |
18708 + GR_AUDIT_CREATE | GR_AUDIT_DELETE |
18709 + GR_AUDIT_READ | GR_AUDIT_WRITE |
18710 + GR_SUPPRESS, parent_mnt);
18712 + gr_search_file(old_dentry,
18713 + GR_READ | GR_WRITE | GR_AUDIT_READ |
18714 + GR_DELETE | GR_AUDIT_DELETE |
18715 + GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
18718 + if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
18719 + ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
18720 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
18721 + else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
18722 + && !(comp2 & GR_SUPPRESS)) {
18723 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
18725 + } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
18732 +gr_acl_handle_exit(void)
18736 + struct file *exec_file;
18738 + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
18739 + id = current->acl_role_id;
18740 + rolename = current->role->rolename;
18742 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
18745 + write_lock(&grsec_exec_file_lock);
18746 + exec_file = current->exec_file;
18747 + current->exec_file = NULL;
18748 + write_unlock(&grsec_exec_file_lock);
18755 +gr_acl_handle_procpidmem(const struct task_struct *task)
18757 + if (unlikely(!gr_acl_is_enabled()))
18760 + if (task->acl->mode & GR_PROTPROCFD)
18765 diff -urNp linux-2.6.20.3/grsecurity/gracl_ip.c linux-2.6.20.3/grsecurity/gracl_ip.c
18766 --- linux-2.6.20.3/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
18767 +++ linux-2.6.20.3/grsecurity/gracl_ip.c 2007-03-23 08:11:31.000000000 -0400
18769 +#include <linux/kernel.h>
18770 +#include <asm/uaccess.h>
18771 +#include <asm/errno.h>
18772 +#include <net/sock.h>
18773 +#include <linux/file.h>
18774 +#include <linux/fs.h>
18775 +#include <linux/net.h>
18776 +#include <linux/in.h>
18777 +#include <linux/skbuff.h>
18778 +#include <linux/ip.h>
18779 +#include <linux/udp.h>
18780 +#include <linux/smp_lock.h>
18781 +#include <linux/types.h>
18782 +#include <linux/sched.h>
18783 +#include <linux/netdevice.h>
18784 +#include <linux/inetdevice.h>
18785 +#include <linux/gracl.h>
18786 +#include <linux/grsecurity.h>
18787 +#include <linux/grinternal.h>
18789 +#define GR_BIND 0x01
18790 +#define GR_CONNECT 0x02
18791 +#define GR_INVERT 0x04
18793 +static const char * gr_protocols[256] = {
18794 + "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
18795 + "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
18796 + "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
18797 + "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
18798 + "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
18799 + "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
18800 + "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
18801 + "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
18802 + "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
18803 + "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
18804 + "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
18805 + "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
18806 + "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
18807 + "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
18808 + "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
18809 + "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
18810 + "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
18811 + "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
18812 + "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
18813 + "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
18814 + "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
18815 + "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
18816 + "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
18817 + "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
18818 + "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
18819 + "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
18820 + "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
18821 + "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
18822 + "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
18823 + "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
18824 + "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
18825 + "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
18828 +static const char * gr_socktypes[11] = {
18829 + "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
18830 + "unknown:7", "unknown:8", "unknown:9", "packet"
18834 +gr_proto_to_name(unsigned char proto)
18836 + return gr_protocols[proto];
18840 +gr_socktype_to_name(unsigned char type)
18842 + return gr_socktypes[type];
18846 +gr_search_socket(const int domain, const int type, const int protocol)
18848 + struct acl_subject_label *curr;
18850 + if (unlikely(!gr_acl_is_enabled()))
18853 + if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
18854 + || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
18855 + goto exit; // let the kernel handle it
18857 + curr = current->acl;
18862 + if ((curr->ip_type & (1 << type)) &&
18863 + (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
18866 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
18867 + /* we don't place acls on raw sockets , and sometimes
18868 + dgram/ip sockets are opened for ioctl and not
18869 + bind/connect, so we'll fake a bind learn log */
18870 + if (type == SOCK_RAW || type == SOCK_PACKET) {
18871 + __u32 fakeip = 0;
18872 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
18873 + current->role->roletype, current->uid,
18874 + current->gid, current->exec_file ?
18875 + gr_to_filename(current->exec_file->f_dentry,
18876 + current->exec_file->f_vfsmnt) :
18877 + curr->filename, curr->filename,
18878 + NIPQUAD(fakeip), 0, type,
18879 + protocol, GR_CONNECT,
18880 +NIPQUAD(current->signal->curr_ip));
18881 + } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
18882 + __u32 fakeip = 0;
18883 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
18884 + current->role->roletype, current->uid,
18885 + current->gid, current->exec_file ?
18886 + gr_to_filename(current->exec_file->f_dentry,
18887 + current->exec_file->f_vfsmnt) :
18888 + curr->filename, curr->filename,
18889 + NIPQUAD(fakeip), 0, type,
18890 + protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
18892 + /* we'll log when they use connect or bind */
18896 + gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
18897 + gr_socktype_to_name(type), gr_proto_to_name(protocol));
18904 +int check_ip_policy(struct acl_ip_label *ip, __u32 ip_addr, __u16 ip_port, __u8 protocol, const int mode, const int type, __u32 our_addr, __u32 our_netmask)
18906 + if ((ip->mode & mode) &&
18907 + (ip_port >= ip->low) &&
18908 + (ip_port <= ip->high) &&
18909 + ((ntohl(ip_addr) & our_netmask) ==
18910 + (ntohl(our_addr) & our_netmask))
18911 + && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
18912 + && (ip->type & (1 << type))) {
18913 + if (ip->mode & GR_INVERT)
18914 + return 2; // specifically denied
18916 + return 1; // allowed
18919 + return 0; // not specifically allowed, may continue parsing
18923 +gr_search_connectbind(const int mode, const struct sock *sk,
18924 + const struct sockaddr_in *addr, const int type)
18926 + char iface[IFNAMSIZ] = {0};
18927 + struct acl_subject_label *curr;
18928 + struct acl_ip_label *ip;
18929 + struct net_device *dev;
18930 + struct in_device *idev;
18933 + __u32 ip_addr = 0;
18935 + __u32 our_netmask;
18937 + __u16 ip_port = 0;
18939 + if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
18942 + curr = current->acl;
18947 + ip_addr = addr->sin_addr.s_addr;
18948 + ip_port = ntohs(addr->sin_port);
18950 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
18951 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
18952 + current->role->roletype, current->uid,
18953 + current->gid, current->exec_file ?
18954 + gr_to_filename(current->exec_file->f_dentry,
18955 + current->exec_file->f_vfsmnt) :
18956 + curr->filename, curr->filename,
18957 + NIPQUAD(ip_addr), ip_port, type,
18958 + sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
18962 + for (i = 0; i < curr->ip_num; i++) {
18963 + ip = *(curr->ips + i);
18964 + if (ip->iface != NULL) {
18965 + strncpy(iface, ip->iface, IFNAMSIZ - 1);
18966 + p = strchr(iface, ':');
18969 + dev = dev_get_by_name(iface);
18972 + idev = in_dev_get(dev);
18973 + if (idev == NULL) {
18979 + if (!strcmp(ip->iface, ifa->ifa_label)) {
18980 + our_addr = ifa->ifa_address;
18981 + our_netmask = 0xffffffff;
18982 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
18984 + rcu_read_unlock();
18985 + in_dev_put(idev);
18988 + } else if (ret == 2) {
18989 + rcu_read_unlock();
18990 + in_dev_put(idev);
18995 + } endfor_ifa(idev);
18996 + rcu_read_unlock();
18997 + in_dev_put(idev);
19000 + our_addr = ip->addr;
19001 + our_netmask = ip->netmask;
19002 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
19005 + else if (ret == 2)
19011 + if (mode == GR_BIND)
19012 + gr_log_int5_str2(GR_DONT_AUDIT, GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
19013 + else if (mode == GR_CONNECT)
19014 + gr_log_int5_str2(GR_DONT_AUDIT, GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
19020 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
19022 + return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
19026 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
19028 + return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
19031 +int gr_search_listen(const struct socket *sock)
19033 + struct sock *sk = sock->sk;
19034 + struct sockaddr_in addr;
19036 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
19037 + addr.sin_port = inet_sk(sk)->sport;
19039 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
19042 +int gr_search_accept(const struct socket *sock)
19044 + struct sock *sk = sock->sk;
19045 + struct sockaddr_in addr;
19047 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
19048 + addr.sin_port = inet_sk(sk)->sport;
19050 + return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
19054 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
19057 + return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
19059 + struct sockaddr_in sin;
19060 + const struct inet_sock *inet = inet_sk(sk);
19062 + sin.sin_addr.s_addr = inet->daddr;
19063 + sin.sin_port = inet->dport;
19065 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
19070 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
19072 + struct sockaddr_in sin;
19074 + if (unlikely(skb->len < sizeof (struct udphdr)))
19075 + return 1; // skip this packet
19077 + sin.sin_addr.s_addr = skb->nh.iph->saddr;
19078 + sin.sin_port = skb->h.uh->source;
19080 + return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
19082 diff -urNp linux-2.6.20.3/grsecurity/gracl_learn.c linux-2.6.20.3/grsecurity/gracl_learn.c
19083 --- linux-2.6.20.3/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
19084 +++ linux-2.6.20.3/grsecurity/gracl_learn.c 2007-03-23 08:11:31.000000000 -0400
19086 +#include <linux/kernel.h>
19087 +#include <linux/mm.h>
19088 +#include <linux/sched.h>
19089 +#include <linux/poll.h>
19090 +#include <linux/smp_lock.h>
19091 +#include <linux/string.h>
19092 +#include <linux/file.h>
19093 +#include <linux/types.h>
19094 +#include <linux/vmalloc.h>
19095 +#include <linux/grinternal.h>
19097 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
19098 + size_t count, loff_t *ppos);
19099 +extern int gr_acl_is_enabled(void);
19101 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
19102 +static int gr_learn_attached;
19104 +/* use a 512k buffer */
19105 +#define LEARN_BUFFER_SIZE (512 * 1024)
19107 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
19108 +static DECLARE_MUTEX(gr_learn_user_sem);
19110 +/* we need to maintain two buffers, so that the kernel context of grlearn
19111 + uses a semaphore around the userspace copying, and the other kernel contexts
19112 + use a spinlock when copying into the buffer, since they cannot sleep
19114 +static char *learn_buffer;
19115 +static char *learn_buffer_user;
19116 +static int learn_buffer_len;
19117 +static int learn_buffer_user_len;
19120 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
19122 + DECLARE_WAITQUEUE(wait, current);
19123 + ssize_t retval = 0;
19125 + add_wait_queue(&learn_wait, &wait);
19126 + set_current_state(TASK_INTERRUPTIBLE);
19128 + down(&gr_learn_user_sem);
19129 + spin_lock(&gr_learn_lock);
19130 + if (learn_buffer_len)
19132 + spin_unlock(&gr_learn_lock);
19133 + up(&gr_learn_user_sem);
19134 + if (file->f_flags & O_NONBLOCK) {
19135 + retval = -EAGAIN;
19138 + if (signal_pending(current)) {
19139 + retval = -ERESTARTSYS;
19146 + memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
19147 + learn_buffer_user_len = learn_buffer_len;
19148 + retval = learn_buffer_len;
19149 + learn_buffer_len = 0;
19151 + spin_unlock(&gr_learn_lock);
19153 + if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
19154 + retval = -EFAULT;
19156 + up(&gr_learn_user_sem);
19158 + set_current_state(TASK_RUNNING);
19159 + remove_wait_queue(&learn_wait, &wait);
19163 +static unsigned int
19164 +poll_learn(struct file * file, poll_table * wait)
19166 + poll_wait(file, &learn_wait, wait);
19168 + if (learn_buffer_len)
19169 + return (POLLIN | POLLRDNORM);
19175 +gr_clear_learn_entries(void)
19179 + down(&gr_learn_user_sem);
19180 + if (learn_buffer != NULL) {
19181 + spin_lock(&gr_learn_lock);
19182 + tmp = learn_buffer;
19183 + learn_buffer = NULL;
19184 + spin_unlock(&gr_learn_lock);
19185 + vfree(learn_buffer);
19187 + if (learn_buffer_user != NULL) {
19188 + vfree(learn_buffer_user);
19189 + learn_buffer_user = NULL;
19191 + learn_buffer_len = 0;
19192 + up(&gr_learn_user_sem);
19198 +gr_add_learn_entry(const char *fmt, ...)
19201 + unsigned int len;
19203 + if (!gr_learn_attached)
19206 + spin_lock(&gr_learn_lock);
19208 + /* leave a gap at the end so we know when it's "full" but don't have to
19209 + compute the exact length of the string we're trying to append
19211 + if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
19212 + spin_unlock(&gr_learn_lock);
19213 + wake_up_interruptible(&learn_wait);
19216 + if (learn_buffer == NULL) {
19217 + spin_unlock(&gr_learn_lock);
19221 + va_start(args, fmt);
19222 + len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
19225 + learn_buffer_len += len + 1;
19227 + spin_unlock(&gr_learn_lock);
19228 + wake_up_interruptible(&learn_wait);
19234 +open_learn(struct inode *inode, struct file *file)
19236 + if (file->f_mode & FMODE_READ && gr_learn_attached)
19238 + if (file->f_mode & FMODE_READ) {
19240 + down(&gr_learn_user_sem);
19241 + if (learn_buffer == NULL)
19242 + learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
19243 + if (learn_buffer_user == NULL)
19244 + learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
19245 + if (learn_buffer == NULL) {
19246 + retval = -ENOMEM;
19249 + if (learn_buffer_user == NULL) {
19250 + retval = -ENOMEM;
19253 + learn_buffer_len = 0;
19254 + learn_buffer_user_len = 0;
19255 + gr_learn_attached = 1;
19257 + up(&gr_learn_user_sem);
19264 +close_learn(struct inode *inode, struct file *file)
19268 + if (file->f_mode & FMODE_READ) {
19269 + down(&gr_learn_user_sem);
19270 + if (learn_buffer != NULL) {
19271 + spin_lock(&gr_learn_lock);
19272 + tmp = learn_buffer;
19273 + learn_buffer = NULL;
19274 + spin_unlock(&gr_learn_lock);
19277 + if (learn_buffer_user != NULL) {
19278 + vfree(learn_buffer_user);
19279 + learn_buffer_user = NULL;
19281 + learn_buffer_len = 0;
19282 + learn_buffer_user_len = 0;
19283 + gr_learn_attached = 0;
19284 + up(&gr_learn_user_sem);
19290 +struct file_operations grsec_fops = {
19291 + .read = read_learn,
19292 + .write = write_grsec_handler,
19293 + .open = open_learn,
19294 + .release = close_learn,
19295 + .poll = poll_learn,
19297 diff -urNp linux-2.6.20.3/grsecurity/gracl_res.c linux-2.6.20.3/grsecurity/gracl_res.c
19298 --- linux-2.6.20.3/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
19299 +++ linux-2.6.20.3/grsecurity/gracl_res.c 2007-03-23 08:11:31.000000000 -0400
19301 +#include <linux/kernel.h>
19302 +#include <linux/sched.h>
19303 +#include <linux/gracl.h>
19304 +#include <linux/grinternal.h>
19306 +static const char *restab_log[] = {
19307 + [RLIMIT_CPU] = "RLIMIT_CPU",
19308 + [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
19309 + [RLIMIT_DATA] = "RLIMIT_DATA",
19310 + [RLIMIT_STACK] = "RLIMIT_STACK",
19311 + [RLIMIT_CORE] = "RLIMIT_CORE",
19312 + [RLIMIT_RSS] = "RLIMIT_RSS",
19313 + [RLIMIT_NPROC] = "RLIMIT_NPROC",
19314 + [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
19315 + [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
19316 + [RLIMIT_AS] = "RLIMIT_AS",
19317 + [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
19318 + [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
19322 +gr_log_resource(const struct task_struct *task,
19323 + const int res, const unsigned long wanted, const int gt)
19325 + if (res == RLIMIT_NPROC &&
19326 + (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
19327 + cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
19329 + else if (res == RLIMIT_MEMLOCK &&
19330 + cap_raised(task->cap_effective, CAP_IPC_LOCK))
19333 + if (!gr_acl_is_enabled() && !grsec_resource_logging)
19336 + preempt_disable();
19338 + if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
19339 + (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
19340 + task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
19341 + gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
19342 + preempt_enable_no_resched();
19346 diff -urNp linux-2.6.20.3/grsecurity/gracl_segv.c linux-2.6.20.3/grsecurity/gracl_segv.c
19347 --- linux-2.6.20.3/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
19348 +++ linux-2.6.20.3/grsecurity/gracl_segv.c 2007-03-23 08:11:31.000000000 -0400
19350 +#include <linux/kernel.h>
19351 +#include <linux/mm.h>
19352 +#include <asm/uaccess.h>
19353 +#include <asm/errno.h>
19354 +#include <asm/mman.h>
19355 +#include <net/sock.h>
19356 +#include <linux/file.h>
19357 +#include <linux/fs.h>
19358 +#include <linux/net.h>
19359 +#include <linux/in.h>
19360 +#include <linux/smp_lock.h>
19361 +#include <linux/slab.h>
19362 +#include <linux/types.h>
19363 +#include <linux/sched.h>
19364 +#include <linux/timer.h>
19365 +#include <linux/gracl.h>
19366 +#include <linux/grsecurity.h>
19367 +#include <linux/grinternal.h>
19369 +static struct crash_uid *uid_set;
19370 +static unsigned short uid_used;
19371 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
19372 +extern rwlock_t gr_inode_lock;
19373 +extern struct acl_subject_label *
19374 + lookup_acl_subj_label(const ino_t inode, const dev_t dev,
19375 + struct acl_role_label *role);
19376 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
19379 +gr_init_uidset(void)
19382 + kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
19385 + return uid_set ? 1 : 0;
19389 +gr_free_uidset(void)
19398 +gr_find_uid(const uid_t uid)
19400 + struct crash_uid *tmp = uid_set;
19402 + int low = 0, high = uid_used - 1, mid;
19404 + while (high >= low) {
19405 + mid = (low + high) >> 1;
19406 + buid = tmp[mid].uid;
19418 +static __inline__ void
19419 +gr_insertsort(void)
19421 + unsigned short i, j;
19422 + struct crash_uid index;
19424 + for (i = 1; i < uid_used; i++) {
19425 + index = uid_set[i];
19427 + while ((j > 0) && uid_set[j - 1].uid > index.uid) {
19428 + uid_set[j] = uid_set[j - 1];
19431 + uid_set[j] = index;
19437 +static __inline__ void
19438 +gr_insert_uid(const uid_t uid, const unsigned long expires)
19442 + if (uid_used == GR_UIDTABLE_MAX)
19445 + loc = gr_find_uid(uid);
19448 + uid_set[loc].expires = expires;
19452 + uid_set[uid_used].uid = uid;
19453 + uid_set[uid_used].expires = expires;
19462 +gr_remove_uid(const unsigned short loc)
19464 + unsigned short i;
19466 + for (i = loc + 1; i < uid_used; i++)
19467 + uid_set[i - 1] = uid_set[i];
19475 +gr_check_crash_uid(const uid_t uid)
19480 + if (unlikely(!gr_acl_is_enabled()))
19483 + spin_lock(&gr_uid_lock);
19484 + loc = gr_find_uid(uid);
19489 + if (time_before_eq(uid_set[loc].expires, get_seconds()))
19490 + gr_remove_uid(loc);
19495 + spin_unlock(&gr_uid_lock);
19499 +static __inline__ int
19500 +proc_is_setxid(const struct task_struct *task)
19502 + if (task->uid != task->euid || task->uid != task->suid ||
19503 + task->uid != task->fsuid)
19505 + if (task->gid != task->egid || task->gid != task->sgid ||
19506 + task->gid != task->fsgid)
19511 +static __inline__ int
19512 +gr_fake_force_sig(int sig, struct task_struct *t)
19514 + unsigned long int flags;
19517 + spin_lock_irqsave(&t->sighand->siglock, flags);
19518 + if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
19519 + t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
19520 + sigdelset(&t->blocked, sig);
19521 + recalc_sigpending_tsk(t);
19523 + ret = specific_send_sig_info(sig, (void*)1L, t);
19524 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
19530 +gr_handle_crash(struct task_struct *task, const int sig)
19532 + struct acl_subject_label *curr;
19533 + struct acl_subject_label *curr2;
19534 + struct task_struct *tsk, *tsk2;
19536 + if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
19539 + if (unlikely(!gr_acl_is_enabled()))
19542 + curr = task->acl;
19544 + if (!(curr->resmask & (1 << GR_CRASH_RES)))
19547 + if (time_before_eq(curr->expires, get_seconds())) {
19548 + curr->expires = 0;
19549 + curr->crashes = 0;
19554 + if (!curr->expires)
19555 + curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
19557 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
19558 + time_after(curr->expires, get_seconds())) {
19559 + if (task->uid && proc_is_setxid(task)) {
19560 + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
19561 + spin_lock(&gr_uid_lock);
19562 + gr_insert_uid(task->uid, curr->expires);
19563 + spin_unlock(&gr_uid_lock);
19564 + curr->expires = 0;
19565 + curr->crashes = 0;
19566 + read_lock(&tasklist_lock);
19567 + do_each_thread(tsk2, tsk) {
19568 + if (tsk != task && tsk->uid == task->uid)
19569 + gr_fake_force_sig(SIGKILL, tsk);
19570 + } while_each_thread(tsk2, tsk);
19571 + read_unlock(&tasklist_lock);
19573 + gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
19574 + read_lock(&tasklist_lock);
19575 + do_each_thread(tsk2, tsk) {
19576 + if (likely(tsk != task)) {
19577 + curr2 = tsk->acl;
19579 + if (curr2->device == curr->device &&
19580 + curr2->inode == curr->inode)
19581 + gr_fake_force_sig(SIGKILL, tsk);
19583 + } while_each_thread(tsk2, tsk);
19584 + read_unlock(&tasklist_lock);
19592 +gr_check_crash_exec(const struct file *filp)
19594 + struct acl_subject_label *curr;
19596 + if (unlikely(!gr_acl_is_enabled()))
19599 + read_lock(&gr_inode_lock);
19600 + curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
19601 + filp->f_dentry->d_inode->i_sb->s_dev,
19603 + read_unlock(&gr_inode_lock);
19605 + if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
19606 + (!curr->crashes && !curr->expires))
19609 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
19610 + time_after(curr->expires, get_seconds()))
19612 + else if (time_before_eq(curr->expires, get_seconds())) {
19613 + curr->crashes = 0;
19614 + curr->expires = 0;
19621 +gr_handle_alertkill(struct task_struct *task)
19623 + struct acl_subject_label *curracl;
19625 + struct task_struct *p, *p2;
19627 + if (unlikely(!gr_acl_is_enabled()))
19630 + curracl = task->acl;
19631 + curr_ip = task->signal->curr_ip;
19633 + if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
19634 + read_lock(&tasklist_lock);
19635 + do_each_thread(p2, p) {
19636 + if (p->signal->curr_ip == curr_ip)
19637 + gr_fake_force_sig(SIGKILL, p);
19638 + } while_each_thread(p2, p);
19639 + read_unlock(&tasklist_lock);
19640 + } else if (curracl->mode & GR_KILLPROC)
19641 + gr_fake_force_sig(SIGKILL, task);
19645 diff -urNp linux-2.6.20.3/grsecurity/gracl_shm.c linux-2.6.20.3/grsecurity/gracl_shm.c
19646 --- linux-2.6.20.3/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
19647 +++ linux-2.6.20.3/grsecurity/gracl_shm.c 2007-03-23 08:11:31.000000000 -0400
19649 +#include <linux/kernel.h>
19650 +#include <linux/mm.h>
19651 +#include <linux/sched.h>
19652 +#include <linux/file.h>
19653 +#include <linux/ipc.h>
19654 +#include <linux/gracl.h>
19655 +#include <linux/grsecurity.h>
19656 +#include <linux/grinternal.h>
19659 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
19660 + const time_t shm_createtime, const uid_t cuid, const int shmid)
19662 + struct task_struct *task;
19664 + if (!gr_acl_is_enabled())
19667 + task = find_task_by_pid(shm_cprid);
19669 + if (unlikely(!task))
19670 + task = find_task_by_pid(shm_lapid);
19672 + if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
19673 + (task->pid == shm_lapid)) &&
19674 + (task->acl->mode & GR_PROTSHM) &&
19675 + (task->acl != current->acl))) {
19676 + gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
19682 diff -urNp linux-2.6.20.3/grsecurity/grsec_chdir.c linux-2.6.20.3/grsecurity/grsec_chdir.c
19683 --- linux-2.6.20.3/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
19684 +++ linux-2.6.20.3/grsecurity/grsec_chdir.c 2007-03-23 08:11:31.000000000 -0400
19686 +#include <linux/kernel.h>
19687 +#include <linux/sched.h>
19688 +#include <linux/fs.h>
19689 +#include <linux/file.h>
19690 +#include <linux/grsecurity.h>
19691 +#include <linux/grinternal.h>
19694 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
19696 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
19697 + if ((grsec_enable_chdir && grsec_enable_group &&
19698 + in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
19699 + !grsec_enable_group)) {
19700 + gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
19705 diff -urNp linux-2.6.20.3/grsecurity/grsec_chroot.c linux-2.6.20.3/grsecurity/grsec_chroot.c
19706 --- linux-2.6.20.3/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
19707 +++ linux-2.6.20.3/grsecurity/grsec_chroot.c 2007-03-23 08:11:31.000000000 -0400
19709 +#include <linux/kernel.h>
19710 +#include <linux/module.h>
19711 +#include <linux/sched.h>
19712 +#include <linux/file.h>
19713 +#include <linux/fs.h>
19714 +#include <linux/mount.h>
19715 +#include <linux/types.h>
19716 +#include <linux/pid_namespace.h>
19717 +#include <linux/grsecurity.h>
19718 +#include <linux/grinternal.h>
19721 +gr_handle_chroot_unix(const pid_t pid)
19723 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
19724 + struct pid *spid = NULL;
19726 + if (unlikely(!grsec_enable_chroot_unix))
19729 + if (likely(!proc_is_chrooted(current)))
19732 + read_lock(&tasklist_lock);
19734 + spid = find_pid(pid);
19736 + struct task_struct *p;
19737 + p = pid_task(spid, PIDTYPE_PID);
19739 + if (unlikely(!have_same_root(current, p))) {
19741 + read_unlock(&tasklist_lock);
19742 + gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
19747 + read_unlock(&tasklist_lock);
19753 +gr_handle_chroot_nice(void)
19755 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
19756 + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
19757 + gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
19765 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
19767 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
19768 + if (grsec_enable_chroot_nice && (niceval < task_nice(p))
19769 + && proc_is_chrooted(current)) {
19770 + gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
19778 +gr_handle_chroot_rawio(const struct inode *inode)
19780 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
19781 + if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
19782 + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
19789 +gr_pid_is_chrooted(struct task_struct *p)
19791 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
19792 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
19796 + if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
19797 + !have_same_root(current, p)) {
19806 +EXPORT_SYMBOL(gr_pid_is_chrooted);
19808 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
19809 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
19811 + struct dentry *dentry = (struct dentry *)u_dentry;
19812 + struct vfsmount *mnt = (struct vfsmount *)u_mnt;
19813 + struct dentry *realroot;
19814 + struct vfsmount *realrootmnt;
19815 + struct dentry *currentroot;
19816 + struct vfsmount *currentmnt;
19817 + struct task_struct *reaper = child_reaper(current);
19820 + read_lock(&reaper->fs->lock);
19821 + realrootmnt = mntget(reaper->fs->rootmnt);
19822 + realroot = dget(reaper->fs->root);
19823 + read_unlock(&reaper->fs->lock);
19825 + read_lock(¤t->fs->lock);
19826 + currentmnt = mntget(current->fs->rootmnt);
19827 + currentroot = dget(current->fs->root);
19828 + read_unlock(¤t->fs->lock);
19830 + spin_lock(&dcache_lock);
19832 + if (unlikely((dentry == realroot && mnt == realrootmnt)
19833 + || (dentry == currentroot && mnt == currentmnt)))
19835 + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
19836 + if (mnt->mnt_parent == mnt)
19838 + dentry = mnt->mnt_mountpoint;
19839 + mnt = mnt->mnt_parent;
19842 + dentry = dentry->d_parent;
19844 + spin_unlock(&dcache_lock);
19846 + dput(currentroot);
19847 + mntput(currentmnt);
19849 + /* access is outside of chroot */
19850 + if (dentry == realroot && mnt == realrootmnt)
19854 + mntput(realrootmnt);
19860 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
19862 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
19863 + if (!grsec_enable_chroot_fchdir)
19866 + if (!proc_is_chrooted(current))
19868 + else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
19869 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
19877 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
19878 + const time_t shm_createtime)
19880 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
19881 + struct pid *pid = NULL;
19882 + time_t starttime;
19884 + if (unlikely(!grsec_enable_chroot_shmat))
19887 + if (likely(!proc_is_chrooted(current)))
19890 + read_lock(&tasklist_lock);
19892 + pid = find_pid(shm_cprid);
19894 + struct task_struct *p;
19895 + p = pid_task(pid, PIDTYPE_PID);
19897 + starttime = p->start_time.tv_sec;
19898 + if (unlikely(!have_same_root(current, p) &&
19899 + time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
19901 + read_unlock(&tasklist_lock);
19902 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
19907 + pid = find_pid(shm_lapid);
19909 + struct task_struct *p;
19910 + p = pid_task(pid, PIDTYPE_PID);
19912 + if (unlikely(!have_same_root(current, p))) {
19914 + read_unlock(&tasklist_lock);
19915 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
19922 + read_unlock(&tasklist_lock);
19928 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
19930 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
19931 + if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
19932 + gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
19938 +gr_handle_chroot_mknod(const struct dentry *dentry,
19939 + const struct vfsmount *mnt, const int mode)
19941 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
19942 + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
19943 + proc_is_chrooted(current)) {
19944 + gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
19952 +gr_handle_chroot_mount(const struct dentry *dentry,
19953 + const struct vfsmount *mnt, const char *dev_name)
19955 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
19956 + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
19957 + gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
19965 +gr_handle_chroot_pivot(void)
19967 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
19968 + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
19969 + gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
19977 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
19979 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
19980 + if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
19981 + !gr_is_outside_chroot(dentry, mnt)) {
19982 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
19990 +gr_handle_chroot_caps(struct task_struct *task)
19992 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
19993 + if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
19994 + task->cap_permitted =
19995 + cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
19996 + task->cap_inheritable =
19997 + cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
19998 + task->cap_effective =
19999 + cap_drop(task->cap_effective, GR_CHROOT_CAPS);
20006 +gr_handle_chroot_sysctl(const int op)
20008 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
20009 + if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
20017 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
20019 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
20020 + if (grsec_enable_chroot_chdir)
20021 + set_fs_pwd(current->fs, mnt, dentry);
20027 +gr_handle_chroot_chmod(const struct dentry *dentry,
20028 + const struct vfsmount *mnt, const int mode)
20030 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
20031 + if (grsec_enable_chroot_chmod &&
20032 + ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
20033 + proc_is_chrooted(current)) {
20034 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
20041 +#ifdef CONFIG_SECURITY
20042 +EXPORT_SYMBOL(gr_handle_chroot_caps);
20044 diff -urNp linux-2.6.20.3/grsecurity/grsec_disabled.c linux-2.6.20.3/grsecurity/grsec_disabled.c
20045 --- linux-2.6.20.3/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
20046 +++ linux-2.6.20.3/grsecurity/grsec_disabled.c 2007-03-23 08:11:31.000000000 -0400
20048 +#include <linux/kernel.h>
20049 +#include <linux/module.h>
20050 +#include <linux/sched.h>
20051 +#include <linux/file.h>
20052 +#include <linux/fs.h>
20053 +#include <linux/kdev_t.h>
20054 +#include <linux/net.h>
20055 +#include <linux/in.h>
20056 +#include <linux/ip.h>
20057 +#include <linux/skbuff.h>
20058 +#include <linux/sysctl.h>
20060 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
20062 +pax_set_initial_flags(struct linux_binprm *bprm)
20068 +#ifdef CONFIG_SYSCTL
20070 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
20077 +gr_acl_is_enabled(void)
20083 +gr_handle_rawio(const struct inode *inode)
20089 +gr_acl_handle_psacct(struct task_struct *task, const long code)
20095 +gr_handle_ptrace(struct task_struct *task, const long request)
20101 +gr_handle_proc_ptrace(struct task_struct *task)
20107 +gr_learn_resource(const struct task_struct *task,
20108 + const int res, const unsigned long wanted, const int gt)
20114 +gr_set_acls(const int type)
20120 +gr_check_hidden_task(const struct task_struct *tsk)
20126 +gr_check_protected_task(const struct task_struct *task)
20132 +gr_copy_label(struct task_struct *tsk)
20138 +gr_set_pax_flags(struct task_struct *task)
20144 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
20150 +gr_handle_delete(const ino_t ino, const dev_t dev)
20156 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
20162 +gr_handle_crash(struct task_struct *task, const int sig)
20168 +gr_check_crash_exec(const struct file *filp)
20174 +gr_check_crash_uid(const uid_t uid)
20180 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
20181 + struct dentry *old_dentry,
20182 + struct dentry *new_dentry,
20183 + struct vfsmount *mnt, const __u8 replace)
20189 +gr_search_socket(const int family, const int type, const int protocol)
20195 +gr_search_connectbind(const int mode, const struct socket *sock,
20196 + const struct sockaddr_in *addr)
20202 +gr_task_is_capable(struct task_struct *task, const int cap)
20208 +gr_is_capable_nolog(const int cap)
20214 +gr_handle_alertkill(struct task_struct *task)
20220 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
20226 +gr_acl_handle_hidden_file(const struct dentry * dentry,
20227 + const struct vfsmount * mnt)
20233 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
20240 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
20246 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
20252 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
20253 + unsigned int *vm_flags)
20259 +gr_acl_handle_truncate(const struct dentry * dentry,
20260 + const struct vfsmount * mnt)
20266 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
20272 +gr_acl_handle_access(const struct dentry * dentry,
20273 + const struct vfsmount * mnt, const int fmode)
20279 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
20286 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
20293 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
20299 +grsecurity_init(void)
20305 +gr_acl_handle_mknod(const struct dentry * new_dentry,
20306 + const struct dentry * parent_dentry,
20307 + const struct vfsmount * parent_mnt,
20314 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
20315 + const struct dentry * parent_dentry,
20316 + const struct vfsmount * parent_mnt)
20322 +gr_acl_handle_symlink(const struct dentry * new_dentry,
20323 + const struct dentry * parent_dentry,
20324 + const struct vfsmount * parent_mnt, const char *from)
20330 +gr_acl_handle_link(const struct dentry * new_dentry,
20331 + const struct dentry * parent_dentry,
20332 + const struct vfsmount * parent_mnt,
20333 + const struct dentry * old_dentry,
20334 + const struct vfsmount * old_mnt, const char *to)
20340 +gr_acl_handle_rename(const struct dentry *new_dentry,
20341 + const struct dentry *parent_dentry,
20342 + const struct vfsmount *parent_mnt,
20343 + const struct dentry *old_dentry,
20344 + const struct inode *old_parent_inode,
20345 + const struct vfsmount *old_mnt, const char *newname)
20351 +gr_acl_handle_filldir(const struct file *file, const char *name,
20352 + const int namelen, const ino_t ino)
20358 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
20359 + const time_t shm_createtime, const uid_t cuid, const int shmid)
20365 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
20371 +gr_search_accept(const struct socket *sock)
20377 +gr_search_listen(const struct socket *sock)
20383 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
20389 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
20395 +gr_acl_handle_creat(const struct dentry * dentry,
20396 + const struct dentry * p_dentry,
20397 + const struct vfsmount * p_mnt, const int fmode,
20404 +gr_acl_handle_exit(void)
20410 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
20416 +gr_set_role_label(const uid_t uid, const gid_t gid)
20422 +gr_acl_handle_procpidmem(const struct task_struct *task)
20428 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
20434 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
20440 +gr_set_kernel_label(struct task_struct *task)
20446 +gr_check_user_change(int real, int effective, int fs)
20452 +gr_check_group_change(int real, int effective, int fs)
20458 +EXPORT_SYMBOL(gr_task_is_capable);
20459 +EXPORT_SYMBOL(gr_is_capable_nolog);
20460 +EXPORT_SYMBOL(gr_learn_resource);
20461 +EXPORT_SYMBOL(gr_set_kernel_label);
20462 +#ifdef CONFIG_SECURITY
20463 +EXPORT_SYMBOL(gr_check_user_change);
20464 +EXPORT_SYMBOL(gr_check_group_change);
20466 diff -urNp linux-2.6.20.3/grsecurity/grsec_exec.c linux-2.6.20.3/grsecurity/grsec_exec.c
20467 --- linux-2.6.20.3/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
20468 +++ linux-2.6.20.3/grsecurity/grsec_exec.c 2007-03-23 08:11:31.000000000 -0400
20470 +#include <linux/kernel.h>
20471 +#include <linux/sched.h>
20472 +#include <linux/file.h>
20473 +#include <linux/binfmts.h>
20474 +#include <linux/smp_lock.h>
20475 +#include <linux/fs.h>
20476 +#include <linux/types.h>
20477 +#include <linux/grdefs.h>
20478 +#include <linux/grinternal.h>
20479 +#include <linux/capability.h>
20481 +#include <asm/uaccess.h>
20483 +#ifdef CONFIG_GRKERNSEC_EXECLOG
20484 +static char gr_exec_arg_buf[132];
20485 +static DECLARE_MUTEX(gr_exec_arg_sem);
20489 +gr_handle_nproc(void)
20491 +#ifdef CONFIG_GRKERNSEC_EXECVE
20492 + if (grsec_enable_execve && current->user &&
20493 + (atomic_read(¤t->user->processes) >
20494 + current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
20495 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
20496 + gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
20504 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
20506 +#ifdef CONFIG_GRKERNSEC_EXECLOG
20507 + char *grarg = gr_exec_arg_buf;
20508 + unsigned int i, x, execlen = 0;
20511 + if (!((grsec_enable_execlog && grsec_enable_group &&
20512 + in_group_p(grsec_audit_gid))
20513 + || (grsec_enable_execlog && !grsec_enable_group)))
20516 + down(&gr_exec_arg_sem);
20517 + memset(grarg, 0, sizeof(gr_exec_arg_buf));
20519 + if (unlikely(argv == NULL))
20522 + for (i = 0; i < bprm->argc && execlen < 128; i++) {
20523 + const char __user *p;
20524 + unsigned int len;
20526 + if (copy_from_user(&p, argv + i, sizeof(p)))
20530 + len = strnlen_user(p, 128 - execlen);
20531 + if (len > 128 - execlen)
20532 + len = 128 - execlen;
20533 + else if (len > 0)
20535 + if (copy_from_user(grarg + execlen, p, len))
20538 + /* rewrite unprintable characters */
20539 + for (x = 0; x < len; x++) {
20540 + c = *(grarg + execlen + x);
20541 + if (c < 32 || c > 126)
20542 + *(grarg + execlen + x) = ' ';
20546 + *(grarg + execlen) = ' ';
20547 + *(grarg + execlen + 1) = '\0';
20552 + gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
20553 + bprm->file->f_vfsmnt, grarg);
20554 + up(&gr_exec_arg_sem);
20558 diff -urNp linux-2.6.20.3/grsecurity/grsec_fifo.c linux-2.6.20.3/grsecurity/grsec_fifo.c
20559 --- linux-2.6.20.3/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
20560 +++ linux-2.6.20.3/grsecurity/grsec_fifo.c 2007-03-23 08:11:31.000000000 -0400
20562 +#include <linux/kernel.h>
20563 +#include <linux/sched.h>
20564 +#include <linux/fs.h>
20565 +#include <linux/file.h>
20566 +#include <linux/grinternal.h>
20569 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
20570 + const struct dentry *dir, const int flag, const int acc_mode)
20572 +#ifdef CONFIG_GRKERNSEC_FIFO
20573 + if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
20574 + !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
20575 + (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
20576 + (current->fsuid != dentry->d_inode->i_uid)) {
20577 + if (!generic_permission(dentry->d_inode, acc_mode, NULL))
20578 + gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
20584 diff -urNp linux-2.6.20.3/grsecurity/grsec_fork.c linux-2.6.20.3/grsecurity/grsec_fork.c
20585 --- linux-2.6.20.3/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
20586 +++ linux-2.6.20.3/grsecurity/grsec_fork.c 2007-03-23 08:11:31.000000000 -0400
20588 +#include <linux/kernel.h>
20589 +#include <linux/sched.h>
20590 +#include <linux/grsecurity.h>
20591 +#include <linux/grinternal.h>
20592 +#include <linux/errno.h>
20595 +gr_log_forkfail(const int retval)
20597 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
20598 + if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
20599 + gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
20603 diff -urNp linux-2.6.20.3/grsecurity/grsec_init.c linux-2.6.20.3/grsecurity/grsec_init.c
20604 --- linux-2.6.20.3/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
20605 +++ linux-2.6.20.3/grsecurity/grsec_init.c 2007-03-23 08:11:31.000000000 -0400
20607 +#include <linux/kernel.h>
20608 +#include <linux/sched.h>
20609 +#include <linux/mm.h>
20610 +#include <linux/smp_lock.h>
20611 +#include <linux/gracl.h>
20612 +#include <linux/slab.h>
20613 +#include <linux/vmalloc.h>
20614 +#include <linux/percpu.h>
20616 +int grsec_enable_shm;
20617 +int grsec_enable_link;
20618 +int grsec_enable_dmesg;
20619 +int grsec_enable_fifo;
20620 +int grsec_enable_execve;
20621 +int grsec_enable_execlog;
20622 +int grsec_enable_signal;
20623 +int grsec_enable_forkfail;
20624 +int grsec_enable_time;
20625 +int grsec_enable_audit_textrel;
20626 +int grsec_enable_group;
20627 +int grsec_audit_gid;
20628 +int grsec_enable_chdir;
20629 +int grsec_enable_audit_ipc;
20630 +int grsec_enable_mount;
20631 +int grsec_enable_chroot_findtask;
20632 +int grsec_enable_chroot_mount;
20633 +int grsec_enable_chroot_shmat;
20634 +int grsec_enable_chroot_fchdir;
20635 +int grsec_enable_chroot_double;
20636 +int grsec_enable_chroot_pivot;
20637 +int grsec_enable_chroot_chdir;
20638 +int grsec_enable_chroot_chmod;
20639 +int grsec_enable_chroot_mknod;
20640 +int grsec_enable_chroot_nice;
20641 +int grsec_enable_chroot_execlog;
20642 +int grsec_enable_chroot_caps;
20643 +int grsec_enable_chroot_sysctl;
20644 +int grsec_enable_chroot_unix;
20645 +int grsec_enable_tpe;
20646 +int grsec_tpe_gid;
20647 +int grsec_enable_tpe_all;
20648 +int grsec_enable_socket_all;
20649 +int grsec_socket_all_gid;
20650 +int grsec_enable_socket_client;
20651 +int grsec_socket_client_gid;
20652 +int grsec_enable_socket_server;
20653 +int grsec_socket_server_gid;
20654 +int grsec_resource_logging;
20657 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
20658 +unsigned long grsec_alert_wtime = 0;
20659 +unsigned long grsec_alert_fyet = 0;
20661 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
20663 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
20665 +char *gr_shared_page[4];
20667 +char *gr_alert_log_fmt;
20668 +char *gr_audit_log_fmt;
20669 +char *gr_alert_log_buf;
20670 +char *gr_audit_log_buf;
20672 +extern struct gr_arg *gr_usermode;
20673 +extern unsigned char *gr_system_salt;
20674 +extern unsigned char *gr_system_sum;
20677 +grsecurity_init(void)
20680 + /* create the per-cpu shared pages */
20682 + preempt_disable();
20683 + for (j = 0; j < 4; j++) {
20684 + gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
20685 + if (gr_shared_page[j] == NULL) {
20686 + panic("Unable to allocate grsecurity shared page");
20690 + preempt_enable();
20692 + /* allocate log buffers */
20693 + gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
20694 + if (!gr_alert_log_fmt) {
20695 + panic("Unable to allocate grsecurity alert log format buffer");
20698 + gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
20699 + if (!gr_audit_log_fmt) {
20700 + panic("Unable to allocate grsecurity audit log format buffer");
20703 + gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
20704 + if (!gr_alert_log_buf) {
20705 + panic("Unable to allocate grsecurity alert log buffer");
20708 + gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
20709 + if (!gr_audit_log_buf) {
20710 + panic("Unable to allocate grsecurity audit log buffer");
20714 + /* allocate memory for authentication structure */
20715 + gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
20716 + gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
20717 + gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
20719 + if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
20720 + panic("Unable to allocate grsecurity authentication structure");
20724 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
20725 +#ifndef CONFIG_GRKERNSEC_SYSCTL
20728 +#ifdef CONFIG_GRKERNSEC_SHM
20729 + grsec_enable_shm = 1;
20731 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
20732 + grsec_enable_audit_textrel = 1;
20734 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
20735 + grsec_enable_group = 1;
20736 + grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
20738 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
20739 + grsec_enable_chdir = 1;
20741 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20742 + grsec_enable_audit_ipc = 1;
20744 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
20745 + grsec_enable_mount = 1;
20747 +#ifdef CONFIG_GRKERNSEC_LINK
20748 + grsec_enable_link = 1;
20750 +#ifdef CONFIG_GRKERNSEC_DMESG
20751 + grsec_enable_dmesg = 1;
20753 +#ifdef CONFIG_GRKERNSEC_FIFO
20754 + grsec_enable_fifo = 1;
20756 +#ifdef CONFIG_GRKERNSEC_EXECVE
20757 + grsec_enable_execve = 1;
20759 +#ifdef CONFIG_GRKERNSEC_EXECLOG
20760 + grsec_enable_execlog = 1;
20762 +#ifdef CONFIG_GRKERNSEC_SIGNAL
20763 + grsec_enable_signal = 1;
20765 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
20766 + grsec_enable_forkfail = 1;
20768 +#ifdef CONFIG_GRKERNSEC_TIME
20769 + grsec_enable_time = 1;
20771 +#ifdef CONFIG_GRKERNSEC_RESLOG
20772 + grsec_resource_logging = 1;
20774 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
20775 + grsec_enable_chroot_findtask = 1;
20777 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
20778 + grsec_enable_chroot_unix = 1;
20780 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
20781 + grsec_enable_chroot_mount = 1;
20783 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
20784 + grsec_enable_chroot_fchdir = 1;
20786 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
20787 + grsec_enable_chroot_shmat = 1;
20789 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
20790 + grsec_enable_chroot_double = 1;
20792 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
20793 + grsec_enable_chroot_pivot = 1;
20795 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
20796 + grsec_enable_chroot_chdir = 1;
20798 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
20799 + grsec_enable_chroot_chmod = 1;
20801 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
20802 + grsec_enable_chroot_mknod = 1;
20804 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
20805 + grsec_enable_chroot_nice = 1;
20807 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
20808 + grsec_enable_chroot_execlog = 1;
20810 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
20811 + grsec_enable_chroot_caps = 1;
20813 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
20814 + grsec_enable_chroot_sysctl = 1;
20816 +#ifdef CONFIG_GRKERNSEC_TPE
20817 + grsec_enable_tpe = 1;
20818 + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
20819 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
20820 + grsec_enable_tpe_all = 1;
20823 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
20824 + grsec_enable_socket_all = 1;
20825 + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
20827 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
20828 + grsec_enable_socket_client = 1;
20829 + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
20831 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
20832 + grsec_enable_socket_server = 1;
20833 + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
20839 diff -urNp linux-2.6.20.3/grsecurity/grsec_ipc.c linux-2.6.20.3/grsecurity/grsec_ipc.c
20840 --- linux-2.6.20.3/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
20841 +++ linux-2.6.20.3/grsecurity/grsec_ipc.c 2007-03-23 08:11:31.000000000 -0400
20843 +#include <linux/kernel.h>
20844 +#include <linux/sched.h>
20845 +#include <linux/types.h>
20846 +#include <linux/ipc.h>
20847 +#include <linux/grsecurity.h>
20848 +#include <linux/grinternal.h>
20851 +gr_log_msgget(const int ret, const int msgflg)
20853 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20854 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20855 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
20856 + !grsec_enable_group)) && (ret >= 0)
20857 + && (msgflg & IPC_CREAT))
20858 + gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
20864 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
20866 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20867 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20868 + grsec_enable_audit_ipc) ||
20869 + (grsec_enable_audit_ipc && !grsec_enable_group))
20870 + gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
20876 +gr_log_semget(const int err, const int semflg)
20878 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20879 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20880 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
20881 + !grsec_enable_group)) && (err >= 0)
20882 + && (semflg & IPC_CREAT))
20883 + gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
20889 +gr_log_semrm(const uid_t uid, const uid_t cuid)
20891 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20892 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20893 + grsec_enable_audit_ipc) ||
20894 + (grsec_enable_audit_ipc && !grsec_enable_group))
20895 + gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
20901 +gr_log_shmget(const int err, const int shmflg, const size_t size)
20903 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20904 + if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20905 + grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
20906 + !grsec_enable_group)) && (err >= 0)
20907 + && (shmflg & IPC_CREAT))
20908 + gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
20914 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
20916 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20917 + if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20918 + grsec_enable_audit_ipc) ||
20919 + (grsec_enable_audit_ipc && !grsec_enable_group))
20920 + gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
20924 diff -urNp linux-2.6.20.3/grsecurity/grsec_link.c linux-2.6.20.3/grsecurity/grsec_link.c
20925 --- linux-2.6.20.3/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
20926 +++ linux-2.6.20.3/grsecurity/grsec_link.c 2007-03-23 08:11:31.000000000 -0400
20928 +#include <linux/kernel.h>
20929 +#include <linux/sched.h>
20930 +#include <linux/fs.h>
20931 +#include <linux/file.h>
20932 +#include <linux/grinternal.h>
20935 +gr_handle_follow_link(const struct inode *parent,
20936 + const struct inode *inode,
20937 + const struct dentry *dentry, const struct vfsmount *mnt)
20939 +#ifdef CONFIG_GRKERNSEC_LINK
20940 + if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
20941 + (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
20942 + (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
20943 + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
20951 +gr_handle_hardlink(const struct dentry *dentry,
20952 + const struct vfsmount *mnt,
20953 + struct inode *inode, const int mode, const char *to)
20955 +#ifdef CONFIG_GRKERNSEC_LINK
20956 + if (grsec_enable_link && current->fsuid != inode->i_uid &&
20957 + (!S_ISREG(mode) || (mode & S_ISUID) ||
20958 + ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
20959 + (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
20960 + !capable(CAP_FOWNER) && current->uid) {
20961 + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
20967 diff -urNp linux-2.6.20.3/grsecurity/grsec_log.c linux-2.6.20.3/grsecurity/grsec_log.c
20968 --- linux-2.6.20.3/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
20969 +++ linux-2.6.20.3/grsecurity/grsec_log.c 2007-03-23 08:11:31.000000000 -0400
20971 +#include <linux/kernel.h>
20972 +#include <linux/sched.h>
20973 +#include <linux/file.h>
20974 +#include <linux/tty.h>
20975 +#include <linux/fs.h>
20976 +#include <linux/grinternal.h>
20978 +#define BEGIN_LOCKS(x) \
20979 + read_lock(&tasklist_lock); \
20980 + read_lock(&grsec_exec_file_lock); \
20981 + if (x != GR_DO_AUDIT) \
20982 + spin_lock(&grsec_alert_lock); \
20984 + spin_lock(&grsec_audit_lock)
20986 +#define END_LOCKS(x) \
20987 + if (x != GR_DO_AUDIT) \
20988 + spin_unlock(&grsec_alert_lock); \
20990 + spin_unlock(&grsec_audit_lock); \
20991 + read_unlock(&grsec_exec_file_lock); \
20992 + read_unlock(&tasklist_lock); \
20993 + if (x == GR_DONT_AUDIT) \
20994 + gr_handle_alertkill(current)
21001 +extern char *gr_alert_log_fmt;
21002 +extern char *gr_audit_log_fmt;
21003 +extern char *gr_alert_log_buf;
21004 +extern char *gr_audit_log_buf;
21006 +static int gr_log_start(int audit)
21008 + char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
21009 + char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
21010 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
21012 + if (audit == GR_DO_AUDIT)
21015 + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
21016 + grsec_alert_wtime = jiffies;
21017 + grsec_alert_fyet = 0;
21018 + } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
21019 + grsec_alert_fyet++;
21020 + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
21021 + grsec_alert_wtime = jiffies;
21022 + grsec_alert_fyet++;
21023 + printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
21025 + } else return FLOODING;
21028 + memset(buf, 0, PAGE_SIZE);
21029 + if (current->signal->curr_ip && gr_acl_is_enabled()) {
21030 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
21031 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
21032 + } else if (current->signal->curr_ip) {
21033 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
21034 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
21035 + } else if (gr_acl_is_enabled()) {
21036 + sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
21037 + snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
21039 + sprintf(fmt, "%s%s", loglevel, "grsec: ");
21040 + strcpy(buf, fmt);
21043 + return NO_FLOODING;
21046 +static void gr_log_middle(int audit, const char *msg, va_list ap)
21048 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
21049 + unsigned int len = strlen(buf);
21051 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
21056 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
21058 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
21059 + unsigned int len = strlen(buf);
21062 + va_start(ap, msg);
21063 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
21069 +static void gr_log_end(int audit)
21071 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
21072 + unsigned int len = strlen(buf);
21074 + snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
21075 + printk("%s\n", buf);
21080 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
21083 + char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
21084 + char *str1, *str2, *str3;
21086 + unsigned long ulong1, ulong2;
21087 + struct dentry *dentry;
21088 + struct vfsmount *mnt;
21089 + struct file *file;
21090 + struct task_struct *task;
21093 + BEGIN_LOCKS(audit);
21094 + logtype = gr_log_start(audit);
21095 + if (logtype == FLOODING) {
21096 + END_LOCKS(audit);
21099 + va_start(ap, argtypes);
21100 + switch (argtypes) {
21101 + case GR_TTYSNIFF:
21102 + task = va_arg(ap, struct task_struct *);
21103 + gr_log_middle_varargs(audit, msg, NIPQUAD(task->signal->curr_ip), gr_task_fullpath0(task), task->comm, task->pid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid);
21106 + dentry = va_arg(ap, struct dentry *);
21107 + mnt = va_arg(ap, struct vfsmount *);
21108 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
21110 + case GR_RBAC_STR:
21111 + dentry = va_arg(ap, struct dentry *);
21112 + mnt = va_arg(ap, struct vfsmount *);
21113 + str1 = va_arg(ap, char *);
21114 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
21116 + case GR_STR_RBAC:
21117 + str1 = va_arg(ap, char *);
21118 + dentry = va_arg(ap, struct dentry *);
21119 + mnt = va_arg(ap, struct vfsmount *);
21120 + gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
21122 + case GR_RBAC_MODE2:
21123 + dentry = va_arg(ap, struct dentry *);
21124 + mnt = va_arg(ap, struct vfsmount *);
21125 + str1 = va_arg(ap, char *);
21126 + str2 = va_arg(ap, char *);
21127 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
21129 + case GR_RBAC_MODE3:
21130 + dentry = va_arg(ap, struct dentry *);
21131 + mnt = va_arg(ap, struct vfsmount *);
21132 + str1 = va_arg(ap, char *);
21133 + str2 = va_arg(ap, char *);
21134 + str3 = va_arg(ap, char *);
21135 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
21137 + case GR_FILENAME:
21138 + dentry = va_arg(ap, struct dentry *);
21139 + mnt = va_arg(ap, struct vfsmount *);
21140 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
21142 + case GR_STR_FILENAME:
21143 + str1 = va_arg(ap, char *);
21144 + dentry = va_arg(ap, struct dentry *);
21145 + mnt = va_arg(ap, struct vfsmount *);
21146 + gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
21148 + case GR_FILENAME_STR:
21149 + dentry = va_arg(ap, struct dentry *);
21150 + mnt = va_arg(ap, struct vfsmount *);
21151 + str1 = va_arg(ap, char *);
21152 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
21154 + case GR_FILENAME_TWO_INT:
21155 + dentry = va_arg(ap, struct dentry *);
21156 + mnt = va_arg(ap, struct vfsmount *);
21157 + num1 = va_arg(ap, int);
21158 + num2 = va_arg(ap, int);
21159 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
21161 + case GR_FILENAME_TWO_INT_STR:
21162 + dentry = va_arg(ap, struct dentry *);
21163 + mnt = va_arg(ap, struct vfsmount *);
21164 + num1 = va_arg(ap, int);
21165 + num2 = va_arg(ap, int);
21166 + str1 = va_arg(ap, char *);
21167 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
21170 + file = va_arg(ap, struct file *);
21171 + ulong1 = va_arg(ap, unsigned long);
21172 + ulong2 = va_arg(ap, unsigned long);
21173 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
21176 + task = va_arg(ap, struct task_struct *);
21177 + gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt) : "(none)", task->comm, task->pid);
21179 + case GR_RESOURCE:
21180 + task = va_arg(ap, struct task_struct *);
21181 + ulong1 = va_arg(ap, unsigned long);
21182 + str1 = va_arg(ap, char *);
21183 + ulong2 = va_arg(ap, unsigned long);
21184 + gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
21187 + task = va_arg(ap, struct task_struct *);
21188 + str1 = va_arg(ap, char *);
21189 + gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
21192 + task = va_arg(ap, struct task_struct *);
21193 + num1 = va_arg(ap, int);
21194 + gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
21197 + task = va_arg(ap, struct task_struct *);
21198 + ulong1 = va_arg(ap, unsigned long);
21199 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, task->uid, ulong1);
21202 + task = va_arg(ap, struct task_struct *);
21203 + ulong1 = va_arg(ap, unsigned long);
21204 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, ulong1);
21208 + unsigned int wday, cday;
21212 + char cur_tty[64] = { 0 };
21213 + char parent_tty[64] = { 0 };
21215 + task = va_arg(ap, struct task_struct *);
21216 + wday = va_arg(ap, unsigned int);
21217 + cday = va_arg(ap, unsigned int);
21218 + whr = va_arg(ap, int);
21219 + chr = va_arg(ap, int);
21220 + wmin = va_arg(ap, int);
21221 + cmin = va_arg(ap, int);
21222 + wsec = va_arg(ap, int);
21223 + csec = va_arg(ap, int);
21224 + ulong1 = va_arg(ap, unsigned long);
21226 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, NIPQUAD(task->signal->curr_ip), tty_name(task->signal->tty, cur_tty), task->uid, task->euid, task->gid, task->egid, wday, whr, wmin, wsec, cday, chr, cmin, csec, (task->flags & PF_SIGNALED) ? "killed by signal" : "exited", ulong1, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, NIPQUAD(task->parent->signal->curr_ip), tty_name(task->parent->signal->tty, parent_tty), task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
21230 + gr_log_middle(audit, msg, ap);
21233 + gr_log_end(audit);
21234 + END_LOCKS(audit);
21236 diff -urNp linux-2.6.20.3/grsecurity/grsec_mem.c linux-2.6.20.3/grsecurity/grsec_mem.c
21237 --- linux-2.6.20.3/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
21238 +++ linux-2.6.20.3/grsecurity/grsec_mem.c 2007-03-23 08:11:31.000000000 -0400
21240 +#include <linux/kernel.h>
21241 +#include <linux/sched.h>
21242 +#include <linux/mm.h>
21243 +#include <linux/mman.h>
21244 +#include <linux/grinternal.h>
21247 +gr_handle_ioperm(void)
21249 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
21254 +gr_handle_iopl(void)
21256 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
21261 +gr_handle_mem_write(void)
21263 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
21268 +gr_handle_kmem_write(void)
21270 + gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
21275 +gr_handle_open_port(void)
21277 + gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
21282 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
21284 + unsigned long start, end;
21287 + end = start + vma->vm_end - vma->vm_start;
21289 + if (start > end) {
21290 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
21294 + /* allowed ranges : ISA I/O BIOS */
21295 + if ((start >= __pa(high_memory))
21297 + || (start >= 0x000a0000 && end <= 0x00100000)
21298 + || (start >= 0x00000000 && end <= 0x00001000)
21303 + if (vma->vm_flags & VM_WRITE) {
21304 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
21307 + vma->vm_flags &= ~VM_MAYWRITE;
21311 diff -urNp linux-2.6.20.3/grsecurity/grsec_mount.c linux-2.6.20.3/grsecurity/grsec_mount.c
21312 --- linux-2.6.20.3/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
21313 +++ linux-2.6.20.3/grsecurity/grsec_mount.c 2007-03-23 08:11:31.000000000 -0400
21315 +#include <linux/kernel.h>
21316 +#include <linux/sched.h>
21317 +#include <linux/grsecurity.h>
21318 +#include <linux/grinternal.h>
21321 +gr_log_remount(const char *devname, const int retval)
21323 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
21324 + if (grsec_enable_mount && (retval >= 0))
21325 + gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
21331 +gr_log_unmount(const char *devname, const int retval)
21333 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
21334 + if (grsec_enable_mount && (retval >= 0))
21335 + gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
21341 +gr_log_mount(const char *from, const char *to, const int retval)
21343 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
21344 + if (grsec_enable_mount && (retval >= 0))
21345 + gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
21349 diff -urNp linux-2.6.20.3/grsecurity/grsec_sig.c linux-2.6.20.3/grsecurity/grsec_sig.c
21350 --- linux-2.6.20.3/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
21351 +++ linux-2.6.20.3/grsecurity/grsec_sig.c 2007-03-23 08:11:31.000000000 -0400
21353 +#include <linux/kernel.h>
21354 +#include <linux/sched.h>
21355 +#include <linux/grsecurity.h>
21356 +#include <linux/grinternal.h>
21359 +gr_log_signal(const int sig, const struct task_struct *t)
21361 +#ifdef CONFIG_GRKERNSEC_SIGNAL
21362 + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
21363 + (sig == SIGABRT) || (sig == SIGBUS))) {
21364 + if (t->pid == current->pid) {
21365 + gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
21367 + gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
21375 +gr_handle_signal(const struct task_struct *p, const int sig)
21377 +#ifdef CONFIG_GRKERNSEC
21378 + if (current->pid > 1 && gr_check_protected_task(p)) {
21379 + gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
21381 + } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
21388 +void gr_handle_brute_attach(struct task_struct *p)
21390 +#ifdef CONFIG_GRKERNSEC_BRUTE
21391 + read_lock(&tasklist_lock);
21392 + read_lock(&grsec_exec_file_lock);
21393 + if (p->parent && p->parent->exec_file == p->exec_file)
21394 + p->parent->brute = 1;
21395 + read_unlock(&grsec_exec_file_lock);
21396 + read_unlock(&tasklist_lock);
21401 +void gr_handle_brute_check(void)
21403 +#ifdef CONFIG_GRKERNSEC_BRUTE
21404 + if (current->brute) {
21405 + set_current_state(TASK_UNINTERRUPTIBLE);
21406 + schedule_timeout(30 * HZ);
21412 diff -urNp linux-2.6.20.3/grsecurity/grsec_sock.c linux-2.6.20.3/grsecurity/grsec_sock.c
21413 --- linux-2.6.20.3/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
21414 +++ linux-2.6.20.3/grsecurity/grsec_sock.c 2007-03-23 08:11:31.000000000 -0400
21416 +#include <linux/kernel.h>
21417 +#include <linux/module.h>
21418 +#include <linux/sched.h>
21419 +#include <linux/file.h>
21420 +#include <linux/net.h>
21421 +#include <linux/in.h>
21422 +#include <linux/ip.h>
21423 +#include <net/sock.h>
21424 +#include <net/inet_sock.h>
21425 +#include <linux/grsecurity.h>
21426 +#include <linux/grinternal.h>
21427 +#include <linux/gracl.h>
21429 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
21430 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
21431 +EXPORT_SYMBOL(udp_v4_lookup);
21434 +EXPORT_SYMBOL(gr_cap_rtnetlink);
21436 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
21437 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
21439 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
21440 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
21442 +#ifdef CONFIG_UNIX_MODULE
21443 +EXPORT_SYMBOL(gr_acl_handle_unix);
21444 +EXPORT_SYMBOL(gr_acl_handle_mknod);
21445 +EXPORT_SYMBOL(gr_handle_chroot_unix);
21446 +EXPORT_SYMBOL(gr_handle_create);
21449 +#ifdef CONFIG_GRKERNSEC
21450 +#define gr_conn_table_size 32749
21451 +struct conn_table_entry {
21452 + struct conn_table_entry *next;
21453 + struct signal_struct *sig;
21456 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
21457 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
21459 +extern const char * gr_socktype_to_name(unsigned char type);
21460 +extern const char * gr_proto_to_name(unsigned char proto);
21462 +static __inline__ int
21463 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
21465 + return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
21468 +static __inline__ int
21469 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
21470 + __u16 sport, __u16 dport)
21472 + if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
21473 + sig->gr_sport == sport && sig->gr_dport == dport))
21479 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
21481 + struct conn_table_entry **match;
21482 + unsigned int index;
21484 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
21485 + sig->gr_sport, sig->gr_dport,
21486 + gr_conn_table_size);
21488 + newent->sig = sig;
21490 + match = &gr_conn_table[index];
21491 + newent->next = *match;
21497 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
21499 + struct conn_table_entry *match, *last = NULL;
21500 + unsigned int index;
21502 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
21503 + sig->gr_sport, sig->gr_dport,
21504 + gr_conn_table_size);
21506 + match = gr_conn_table[index];
21507 + while (match && !conn_match(match->sig,
21508 + sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
21509 + sig->gr_dport)) {
21511 + match = match->next;
21516 + last->next = match->next;
21518 + gr_conn_table[index] = NULL;
21525 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
21526 + __u16 sport, __u16 dport)
21528 + struct conn_table_entry *match;
21529 + unsigned int index;
21531 + index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
21533 + match = gr_conn_table[index];
21534 + while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
21535 + match = match->next;
21538 + return match->sig;
21545 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
21547 +#ifdef CONFIG_GRKERNSEC
21548 + struct signal_struct *sig = task->signal;
21549 + struct conn_table_entry *newent;
21551 + newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
21552 + if (newent == NULL)
21554 + /* no bh lock needed since we are called with bh disabled */
21555 + spin_lock(&gr_conn_table_lock);
21556 + gr_del_task_from_ip_table_nolock(sig);
21557 + sig->gr_saddr = inet->rcv_saddr;
21558 + sig->gr_daddr = inet->daddr;
21559 + sig->gr_sport = inet->sport;
21560 + sig->gr_dport = inet->dport;
21561 + gr_add_to_task_ip_table_nolock(sig, newent);
21562 + spin_unlock(&gr_conn_table_lock);
21567 +void gr_del_task_from_ip_table(struct task_struct *task)
21569 +#ifdef CONFIG_GRKERNSEC
21570 + spin_lock(&gr_conn_table_lock);
21571 + gr_del_task_from_ip_table_nolock(task->signal);
21572 + spin_unlock(&gr_conn_table_lock);
21578 +gr_attach_curr_ip(const struct sock *sk)
21580 +#ifdef CONFIG_GRKERNSEC
21581 + struct signal_struct *p, *set;
21582 + const struct inet_sock *inet = inet_sk(sk);
21584 + if (unlikely(sk->sk_protocol != IPPROTO_TCP))
21587 + set = current->signal;
21589 + spin_lock_bh(&gr_conn_table_lock);
21590 + p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
21591 + inet->dport, inet->sport);
21592 + if (unlikely(p != NULL)) {
21593 + set->curr_ip = p->curr_ip;
21594 + set->used_accept = 1;
21595 + gr_del_task_from_ip_table_nolock(p);
21596 + spin_unlock_bh(&gr_conn_table_lock);
21599 + spin_unlock_bh(&gr_conn_table_lock);
21601 + set->curr_ip = inet->daddr;
21602 + set->used_accept = 1;
21608 +gr_handle_sock_all(const int family, const int type, const int protocol)
21610 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
21611 + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
21612 + (family != AF_UNIX) && (family != AF_LOCAL)) {
21613 + gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
21621 +gr_handle_sock_server(const struct sockaddr *sck)
21623 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
21624 + if (grsec_enable_socket_server &&
21625 + in_group_p(grsec_socket_server_gid) &&
21626 + sck && (sck->sa_family != AF_UNIX) &&
21627 + (sck->sa_family != AF_LOCAL)) {
21628 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
21636 +gr_handle_sock_server_other(const struct sock *sck)
21638 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
21639 + if (grsec_enable_socket_server &&
21640 + in_group_p(grsec_socket_server_gid) &&
21641 + sck && (sck->sk_family != AF_UNIX) &&
21642 + (sck->sk_family != AF_LOCAL)) {
21643 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
21651 +gr_handle_sock_client(const struct sockaddr *sck)
21653 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
21654 + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
21655 + sck && (sck->sa_family != AF_UNIX) &&
21656 + (sck->sa_family != AF_LOCAL)) {
21657 + gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
21665 +gr_cap_rtnetlink(void)
21667 +#ifdef CONFIG_GRKERNSEC
21668 + if (!gr_acl_is_enabled())
21669 + return vx_mbcap(cap_effective);
21670 + else if (cap_raised(vx_mbcap(cap_effective), CAP_NET_ADMIN) &&
21671 + gr_task_is_capable(current, CAP_NET_ADMIN))
21672 + vx_mbcap(cap_effective);
21676 + vx_mbcap(cap_effective);
21679 diff -urNp linux-2.6.20.3/grsecurity/grsec_sysctl.c linux-2.6.20.3/grsecurity/grsec_sysctl.c
21680 --- linux-2.6.20.3/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
21681 +++ linux-2.6.20.3/grsecurity/grsec_sysctl.c 2007-03-23 08:11:31.000000000 -0400
21683 +#include <linux/kernel.h>
21684 +#include <linux/sched.h>
21685 +#include <linux/sysctl.h>
21686 +#include <linux/grsecurity.h>
21687 +#include <linux/grinternal.h>
21689 +#ifdef CONFIG_GRKERNSEC_MODSTOP
21690 +int grsec_modstop;
21694 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
21696 +#ifdef CONFIG_GRKERNSEC_SYSCTL
21697 + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
21698 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
21702 +#ifdef CONFIG_GRKERNSEC_MODSTOP
21703 + if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
21704 + grsec_modstop && (op & 002)) {
21705 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
21712 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
21713 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
21714 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
21715 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
21716 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
21717 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
21718 +GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
21719 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID,
21720 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
21721 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
21724 +ctl_table grsecurity_table[] = {
21725 +#ifdef CONFIG_GRKERNSEC_SYSCTL
21726 +#ifdef CONFIG_GRKERNSEC_LINK
21728 + .ctl_name = GS_LINK,
21729 + .procname = "linking_restrictions",
21730 + .data = &grsec_enable_link,
21731 + .maxlen = sizeof(int),
21733 + .proc_handler = &proc_dointvec,
21736 +#ifdef CONFIG_GRKERNSEC_FIFO
21738 + .ctl_name = GS_FIFO,
21739 + .procname = "fifo_restrictions",
21740 + .data = &grsec_enable_fifo,
21741 + .maxlen = sizeof(int),
21743 + .proc_handler = &proc_dointvec,
21746 +#ifdef CONFIG_GRKERNSEC_EXECVE
21748 + .ctl_name = GS_EXECVE,
21749 + .procname = "execve_limiting",
21750 + .data = &grsec_enable_execve,
21751 + .maxlen = sizeof(int),
21753 + .proc_handler = &proc_dointvec,
21756 +#ifdef CONFIG_GRKERNSEC_EXECLOG
21758 + .ctl_name = GS_EXECLOG,
21759 + .procname = "exec_logging",
21760 + .data = &grsec_enable_execlog,
21761 + .maxlen = sizeof(int),
21763 + .proc_handler = &proc_dointvec,
21766 +#ifdef CONFIG_GRKERNSEC_SIGNAL
21768 + .ctl_name = GS_SIGNAL,
21769 + .procname = "signal_logging",
21770 + .data = &grsec_enable_signal,
21771 + .maxlen = sizeof(int),
21773 + .proc_handler = &proc_dointvec,
21776 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
21778 + .ctl_name = GS_FORKFAIL,
21779 + .procname = "forkfail_logging",
21780 + .data = &grsec_enable_forkfail,
21781 + .maxlen = sizeof(int),
21783 + .proc_handler = &proc_dointvec,
21786 +#ifdef CONFIG_GRKERNSEC_TIME
21788 + .ctl_name = GS_TIME,
21789 + .procname = "timechange_logging",
21790 + .data = &grsec_enable_time,
21791 + .maxlen = sizeof(int),
21793 + .proc_handler = &proc_dointvec,
21796 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
21798 + .ctl_name = GS_CHROOT_SHMAT,
21799 + .procname = "chroot_deny_shmat",
21800 + .data = &grsec_enable_chroot_shmat,
21801 + .maxlen = sizeof(int),
21803 + .proc_handler = &proc_dointvec,
21806 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
21808 + .ctl_name = GS_CHROOT_UNIX,
21809 + .procname = "chroot_deny_unix",
21810 + .data = &grsec_enable_chroot_unix,
21811 + .maxlen = sizeof(int),
21813 + .proc_handler = &proc_dointvec,
21816 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
21818 + .ctl_name = GS_CHROOT_MNT,
21819 + .procname = "chroot_deny_mount",
21820 + .data = &grsec_enable_chroot_mount,
21821 + .maxlen = sizeof(int),
21823 + .proc_handler = &proc_dointvec,
21826 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
21828 + .ctl_name = GS_CHROOT_FCHDIR,
21829 + .procname = "chroot_deny_fchdir",
21830 + .data = &grsec_enable_chroot_fchdir,
21831 + .maxlen = sizeof(int),
21833 + .proc_handler = &proc_dointvec,
21836 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
21838 + .ctl_name = GS_CHROOT_DBL,
21839 + .procname = "chroot_deny_chroot",
21840 + .data = &grsec_enable_chroot_double,
21841 + .maxlen = sizeof(int),
21843 + .proc_handler = &proc_dointvec,
21846 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
21848 + .ctl_name = GS_CHROOT_PVT,
21849 + .procname = "chroot_deny_pivot",
21850 + .data = &grsec_enable_chroot_pivot,
21851 + .maxlen = sizeof(int),
21853 + .proc_handler = &proc_dointvec,
21856 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
21858 + .ctl_name = GS_CHROOT_CD,
21859 + .procname = "chroot_enforce_chdir",
21860 + .data = &grsec_enable_chroot_chdir,
21861 + .maxlen = sizeof(int),
21863 + .proc_handler = &proc_dointvec,
21866 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
21868 + .ctl_name = GS_CHROOT_CM,
21869 + .procname = "chroot_deny_chmod",
21870 + .data = &grsec_enable_chroot_chmod,
21871 + .maxlen = sizeof(int),
21873 + .proc_handler = &proc_dointvec,
21876 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
21878 + .ctl_name = GS_CHROOT_MK,
21879 + .procname = "chroot_deny_mknod",
21880 + .data = &grsec_enable_chroot_mknod,
21881 + .maxlen = sizeof(int),
21883 + .proc_handler = &proc_dointvec,
21886 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
21888 + .ctl_name = GS_CHROOT_NI,
21889 + .procname = "chroot_restrict_nice",
21890 + .data = &grsec_enable_chroot_nice,
21891 + .maxlen = sizeof(int),
21893 + .proc_handler = &proc_dointvec,
21896 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
21898 + .ctl_name = GS_CHROOT_EXECLOG,
21899 + .procname = "chroot_execlog",
21900 + .data = &grsec_enable_chroot_execlog,
21901 + .maxlen = sizeof(int),
21903 + .proc_handler = &proc_dointvec,
21906 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
21908 + .ctl_name = GS_CHROOT_CAPS,
21909 + .procname = "chroot_caps",
21910 + .data = &grsec_enable_chroot_caps,
21911 + .maxlen = sizeof(int),
21913 + .proc_handler = &proc_dointvec,
21916 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
21918 + .ctl_name = GS_CHROOT_SYSCTL,
21919 + .procname = "chroot_deny_sysctl",
21920 + .data = &grsec_enable_chroot_sysctl,
21921 + .maxlen = sizeof(int),
21923 + .proc_handler = &proc_dointvec,
21926 +#ifdef CONFIG_GRKERNSEC_TPE
21928 + .ctl_name = GS_TPE,
21929 + .procname = "tpe",
21930 + .data = &grsec_enable_tpe,
21931 + .maxlen = sizeof(int),
21933 + .proc_handler = &proc_dointvec,
21936 + .ctl_name = GS_TPE_GID,
21937 + .procname = "tpe_gid",
21938 + .data = &grsec_tpe_gid,
21939 + .maxlen = sizeof(int),
21941 + .proc_handler = &proc_dointvec,
21944 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
21946 + .ctl_name = GS_TPE_ALL,
21947 + .procname = "tpe_restrict_all",
21948 + .data = &grsec_enable_tpe_all,
21949 + .maxlen = sizeof(int),
21951 + .proc_handler = &proc_dointvec,
21954 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
21956 + .ctl_name = GS_SOCKET_ALL,
21957 + .procname = "socket_all",
21958 + .data = &grsec_enable_socket_all,
21959 + .maxlen = sizeof(int),
21961 + .proc_handler = &proc_dointvec,
21964 + .ctl_name = GS_SOCKET_ALL_GID,
21965 + .procname = "socket_all_gid",
21966 + .data = &grsec_socket_all_gid,
21967 + .maxlen = sizeof(int),
21969 + .proc_handler = &proc_dointvec,
21972 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
21974 + .ctl_name = GS_SOCKET_CLIENT,
21975 + .procname = "socket_client",
21976 + .data = &grsec_enable_socket_client,
21977 + .maxlen = sizeof(int),
21979 + .proc_handler = &proc_dointvec,
21982 + .ctl_name = GS_SOCKET_CLIENT_GID,
21983 + .procname = "socket_client_gid",
21984 + .data = &grsec_socket_client_gid,
21985 + .maxlen = sizeof(int),
21987 + .proc_handler = &proc_dointvec,
21990 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
21992 + .ctl_name = GS_SOCKET_SERVER,
21993 + .procname = "socket_server",
21994 + .data = &grsec_enable_socket_server,
21995 + .maxlen = sizeof(int),
21997 + .proc_handler = &proc_dointvec,
22000 + .ctl_name = GS_SOCKET_SERVER_GID,
22001 + .procname = "socket_server_gid",
22002 + .data = &grsec_socket_server_gid,
22003 + .maxlen = sizeof(int),
22005 + .proc_handler = &proc_dointvec,
22008 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
22010 + .ctl_name = GS_GROUP,
22011 + .procname = "audit_group",
22012 + .data = &grsec_enable_group,
22013 + .maxlen = sizeof(int),
22015 + .proc_handler = &proc_dointvec,
22018 + .ctl_name = GS_GID,
22019 + .procname = "audit_gid",
22020 + .data = &grsec_audit_gid,
22021 + .maxlen = sizeof(int),
22023 + .proc_handler = &proc_dointvec,
22026 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
22028 + .ctl_name = GS_ACHDIR,
22029 + .procname = "audit_chdir",
22030 + .data = &grsec_enable_chdir,
22031 + .maxlen = sizeof(int),
22033 + .proc_handler = &proc_dointvec,
22036 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
22038 + .ctl_name = GS_AMOUNT,
22039 + .procname = "audit_mount",
22040 + .data = &grsec_enable_mount,
22041 + .maxlen = sizeof(int),
22043 + .proc_handler = &proc_dointvec,
22046 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
22048 + .ctl_name = GS_AIPC,
22049 + .procname = "audit_ipc",
22050 + .data = &grsec_enable_audit_ipc,
22051 + .maxlen = sizeof(int),
22053 + .proc_handler = &proc_dointvec,
22056 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
22058 + .ctl_name = GS_TEXTREL,
22059 + .procname = "audit_textrel",
22060 + .data = &grsec_enable_audit_textrel,
22061 + .maxlen = sizeof(int),
22063 + .proc_handler = &proc_dointvec,
22066 +#ifdef CONFIG_GRKERNSEC_DMESG
22068 + .ctl_name = GS_DMSG,
22069 + .procname = "dmesg",
22070 + .data = &grsec_enable_dmesg,
22071 + .maxlen = sizeof(int),
22073 + .proc_handler = &proc_dointvec,
22076 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
22078 + .ctl_name = GS_FINDTASK,
22079 + .procname = "chroot_findtask",
22080 + .data = &grsec_enable_chroot_findtask,
22081 + .maxlen = sizeof(int),
22083 + .proc_handler = &proc_dointvec,
22086 +#ifdef CONFIG_GRKERNSEC_SHM
22088 + .ctl_name = GS_SHM,
22089 + .procname = "destroy_unused_shm",
22090 + .data = &grsec_enable_shm,
22091 + .maxlen = sizeof(int),
22093 + .proc_handler = &proc_dointvec,
22096 +#ifdef CONFIG_GRKERNSEC_RESLOG
22098 + .ctl_name = GS_RESLOG,
22099 + .procname = "resource_logging",
22100 + .data = &grsec_resource_logging,
22101 + .maxlen = sizeof(int),
22103 + .proc_handler = &proc_dointvec,
22107 + .ctl_name = GS_LOCK,
22108 + .procname = "grsec_lock",
22109 + .data = &grsec_lock,
22110 + .maxlen = sizeof(int),
22112 + .proc_handler = &proc_dointvec,
22115 +#ifdef CONFIG_GRKERNSEC_MODSTOP
22117 + .ctl_name = GS_MODSTOP,
22118 + .procname = "disable_modules",
22119 + .data = &grsec_modstop,
22120 + .maxlen = sizeof(int),
22122 + .proc_handler = &proc_dointvec,
22125 + { .ctl_name = 0 }
22129 +int gr_check_modstop(void)
22131 +#ifdef CONFIG_GRKERNSEC_MODSTOP
22132 + if (grsec_modstop == 1) {
22133 + gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
22139 diff -urNp linux-2.6.20.3/grsecurity/grsec_textrel.c linux-2.6.20.3/grsecurity/grsec_textrel.c
22140 --- linux-2.6.20.3/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
22141 +++ linux-2.6.20.3/grsecurity/grsec_textrel.c 2007-03-23 08:11:31.000000000 -0400
22143 +#include <linux/kernel.h>
22144 +#include <linux/sched.h>
22145 +#include <linux/mm.h>
22146 +#include <linux/file.h>
22147 +#include <linux/grinternal.h>
22148 +#include <linux/grsecurity.h>
22151 +gr_log_textrel(struct vm_area_struct * vma)
22153 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
22154 + if (grsec_enable_audit_textrel)
22155 + gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
22159 diff -urNp linux-2.6.20.3/grsecurity/grsec_time.c linux-2.6.20.3/grsecurity/grsec_time.c
22160 --- linux-2.6.20.3/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
22161 +++ linux-2.6.20.3/grsecurity/grsec_time.c 2007-03-23 08:11:31.000000000 -0400
22163 +#include <linux/kernel.h>
22164 +#include <linux/sched.h>
22165 +#include <linux/grinternal.h>
22168 +gr_log_timechange(void)
22170 +#ifdef CONFIG_GRKERNSEC_TIME
22171 + if (grsec_enable_time)
22172 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
22176 diff -urNp linux-2.6.20.3/grsecurity/grsec_tpe.c linux-2.6.20.3/grsecurity/grsec_tpe.c
22177 --- linux-2.6.20.3/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
22178 +++ linux-2.6.20.3/grsecurity/grsec_tpe.c 2007-03-23 08:11:31.000000000 -0400
22180 +#include <linux/kernel.h>
22181 +#include <linux/sched.h>
22182 +#include <linux/file.h>
22183 +#include <linux/fs.h>
22184 +#include <linux/grinternal.h>
22186 +extern int gr_acl_tpe_check(void);
22189 +gr_tpe_allow(const struct file *file)
22191 +#ifdef CONFIG_GRKERNSEC
22192 + struct inode *inode = file->f_dentry->d_parent->d_inode;
22194 + if (current->uid && ((grsec_enable_tpe &&
22195 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
22196 + !in_group_p(grsec_tpe_gid)
22198 + in_group_p(grsec_tpe_gid)
22200 + ) || gr_acl_tpe_check()) &&
22201 + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
22202 + (inode->i_mode & S_IWOTH))))) {
22203 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
22206 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
22207 + if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
22208 + ((inode->i_uid && (inode->i_uid != current->uid)) ||
22209 + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
22210 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
22217 diff -urNp linux-2.6.20.3/grsecurity/grsum.c linux-2.6.20.3/grsecurity/grsum.c
22218 --- linux-2.6.20.3/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
22219 +++ linux-2.6.20.3/grsecurity/grsum.c 2007-03-23 08:11:31.000000000 -0400
22221 +#include <linux/kernel.h>
22222 +#include <linux/sched.h>
22223 +#include <linux/mm.h>
22224 +#include <linux/scatterlist.h>
22225 +#include <linux/crypto.h>
22226 +#include <linux/gracl.h>
22229 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
22230 +#error "crypto and sha256 must be built into the kernel"
22234 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
22237 + struct crypto_hash *tfm;
22238 + struct hash_desc desc;
22239 + struct scatterlist sg;
22240 + unsigned char temp_sum[GR_SHA_LEN];
22241 + volatile int retval = 0;
22242 + volatile int dummy = 0;
22245 + tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
22246 + if (IS_ERR(tfm)) {
22247 + /* should never happen, since sha256 should be built in */
22254 + crypto_hash_init(&desc);
22257 + sg_set_buf(&sg, p, GR_SALT_LEN);
22258 + crypto_hash_update(&desc, &sg, sg.length);
22261 + sg_set_buf(&sg, p, strlen(p));
22263 + crypto_hash_update(&desc, &sg, sg.length);
22265 + crypto_hash_final(&desc, temp_sum);
22267 + memset(entry->pw, 0, GR_PW_LEN);
22269 + for (i = 0; i < GR_SHA_LEN; i++)
22270 + if (sum[i] != temp_sum[i])
22273 + dummy = 1; // waste a cycle
22275 + crypto_free_hash(tfm);
22279 diff -urNp linux-2.6.20.3/grsecurity/Kconfig linux-2.6.20.3/grsecurity/Kconfig
22280 --- linux-2.6.20.3/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
22281 +++ linux-2.6.20.3/grsecurity/Kconfig 2007-03-23 08:11:31.000000000 -0400
22284 +# grecurity configuration
22290 + bool "Grsecurity"
22292 + select CRYPTO_SHA256
22294 + If you say Y here, you will be able to configure many features
22295 + that will enhance the security of your system. It is highly
22296 + recommended that you say Y here and read through the help
22297 + for each option so that you fully understand the features and
22298 + can evaluate their usefulness for your machine.
22301 + prompt "Security Level"
22302 + depends GRKERNSEC
22303 + default GRKERNSEC_CUSTOM
22305 +config GRKERNSEC_LOW
22307 + select GRKERNSEC_LINK
22308 + select GRKERNSEC_FIFO
22309 + select GRKERNSEC_EXECVE
22310 + select GRKERNSEC_RANDNET
22311 + select GRKERNSEC_DMESG
22312 + select GRKERNSEC_CHROOT_CHDIR
22313 + select GRKERNSEC_MODSTOP if (MODULES)
22316 + If you choose this option, several of the grsecurity options will
22317 + be enabled that will give you greater protection against a number
22318 + of attacks, while assuring that none of your software will have any
22319 + conflicts with the additional security measures. If you run a lot
22320 + of unusual software, or you are having problems with the higher
22321 + security levels, you should say Y here. With this option, the
22322 + following features are enabled:
22324 + - Linking restrictions
22325 + - FIFO restrictions
22326 + - Enforcing RLIMIT_NPROC on execve
22327 + - Restricted dmesg
22328 + - Enforced chdir("/") on chroot
22329 + - Runtime module disabling
22331 +config GRKERNSEC_MEDIUM
22334 + select PAX_EI_PAX
22335 + select PAX_PT_PAX_FLAGS
22336 + select PAX_HAVE_ACL_FLAGS
22337 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22338 + select GRKERNSEC_CHROOT_SYSCTL
22339 + select GRKERNSEC_LINK
22340 + select GRKERNSEC_FIFO
22341 + select GRKERNSEC_EXECVE
22342 + select GRKERNSEC_DMESG
22343 + select GRKERNSEC_RANDNET
22344 + select GRKERNSEC_FORKFAIL
22345 + select GRKERNSEC_TIME
22346 + select GRKERNSEC_SIGNAL
22347 + select GRKERNSEC_CHROOT
22348 + select GRKERNSEC_CHROOT_UNIX
22349 + select GRKERNSEC_CHROOT_MOUNT
22350 + select GRKERNSEC_CHROOT_PIVOT
22351 + select GRKERNSEC_CHROOT_DOUBLE
22352 + select GRKERNSEC_CHROOT_CHDIR
22353 + select GRKERNSEC_CHROOT_MKNOD
22354 + select GRKERNSEC_PROC
22355 + select GRKERNSEC_PROC_USERGROUP
22356 + select GRKERNSEC_MODSTOP if (MODULES)
22357 + select PAX_RANDUSTACK
22359 + select PAX_RANDMMAP
22362 + If you say Y here, several features in addition to those included
22363 + in the low additional security level will be enabled. These
22364 + features provide even more security to your system, though in rare
22365 + cases they may be incompatible with very old or poorly written
22366 + software. If you enable this option, make sure that your auth
22367 + service (identd) is running as gid 1001. With this option,
22368 + the following features (in addition to those provided in the
22369 + low additional security level) will be enabled:
22371 + - Randomized TCP source ports
22372 + - Failed fork logging
22373 + - Time change logging
22375 + - Deny mounts in chroot
22376 + - Deny double chrooting
22377 + - Deny sysctl writes in chroot
22378 + - Deny mknod in chroot
22379 + - Deny access to abstract AF_UNIX sockets out of chroot
22380 + - Deny pivot_root in chroot
22381 + - Denied writes of /dev/kmem, /dev/mem, and /dev/port
22382 + - /proc restrictions with special GID set to 10 (usually wheel)
22383 + - Address Space Layout Randomization (ASLR)
22385 +config GRKERNSEC_HIGH
22387 + select GRKERNSEC_LINK
22388 + select GRKERNSEC_FIFO
22389 + select GRKERNSEC_EXECVE
22390 + select GRKERNSEC_DMESG
22391 + select GRKERNSEC_FORKFAIL
22392 + select GRKERNSEC_TIME
22393 + select GRKERNSEC_SIGNAL
22394 + select GRKERNSEC_CHROOT_SHMAT
22395 + select GRKERNSEC_CHROOT_UNIX
22396 + select GRKERNSEC_CHROOT_MOUNT
22397 + select GRKERNSEC_CHROOT_FCHDIR
22398 + select GRKERNSEC_CHROOT_PIVOT
22399 + select GRKERNSEC_CHROOT_DOUBLE
22400 + select GRKERNSEC_CHROOT_CHDIR
22401 + select GRKERNSEC_CHROOT_MKNOD
22402 + select GRKERNSEC_CHROOT_CAPS
22403 + select GRKERNSEC_CHROOT_SYSCTL
22404 + select GRKERNSEC_CHROOT_FINDTASK
22405 + select GRKERNSEC_PROC
22406 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22407 + select GRKERNSEC_HIDESYM
22408 + select GRKERNSEC_BRUTE
22409 + select GRKERNSEC_SHM if (SYSVIPC)
22410 + select GRKERNSEC_PROC_USERGROUP
22411 + select GRKERNSEC_KMEM
22412 + select GRKERNSEC_RESLOG
22413 + select GRKERNSEC_RANDNET
22414 + select GRKERNSEC_PROC_ADD
22415 + select GRKERNSEC_CHROOT_CHMOD
22416 + select GRKERNSEC_CHROOT_NICE
22417 + select GRKERNSEC_AUDIT_MOUNT
22418 + select GRKERNSEC_MODSTOP if (MODULES)
22420 + select PAX_RANDUSTACK
22422 + select PAX_RANDMMAP
22423 + select PAX_NOEXEC
22424 + select PAX_MPROTECT
22425 + select PAX_EI_PAX
22426 + select PAX_PT_PAX_FLAGS
22427 + select PAX_HAVE_ACL_FLAGS
22428 + select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
22429 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
22430 + select PAX_SEGMEXEC if (X86 && !X86_64)
22431 + select PAX_PAGEEXEC if (!X86)
22432 + select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
22433 + select PAX_DLRESOLVE if (SPARC32 || SPARC64)
22434 + select PAX_SYSCALL if (PPC32)
22435 + select PAX_EMUTRAMP if (PARISC)
22436 + select PAX_EMUSIGRT if (PARISC)
22437 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
22439 + If you say Y here, many of the features of grsecurity will be
22440 + enabled, which will protect you against many kinds of attacks
22441 + against your system. The heightened security comes at a cost
22442 + of an increased chance of incompatibilities with rare software
22443 + on your machine. Since this security level enables PaX, you should
22444 + view <http://pax.grsecurity.net> and read about the PaX
22445 + project. While you are there, download chpax and run it on
22446 + binaries that cause problems with PaX. Also remember that
22447 + since the /proc restrictions are enabled, you must run your
22448 + identd as gid 1001. This security level enables the following
22449 + features in addition to those listed in the low and medium
22452 + - Additional /proc restrictions
22453 + - Chmod restrictions in chroot
22454 + - No signals, ptrace, or viewing of processes outside of chroot
22455 + - Capability restrictions in chroot
22456 + - Deny fchdir out of chroot
22457 + - Priority restrictions in chroot
22458 + - Segmentation-based implementation of PaX
22459 + - Mprotect restrictions
22460 + - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
22461 + - Kernel stack randomization
22462 + - Mount/unmount/remount logging
22463 + - Kernel symbol hiding
22464 + - Destroy unused shared memory
22465 + - Prevention of memory exhaustion-based exploits
22466 +config GRKERNSEC_CUSTOM
22469 + If you say Y here, you will be able to configure every grsecurity
22470 + option, which allows you to enable many more features that aren't
22471 + covered in the basic security levels. These additional features
22472 + include TPE, socket restrictions, and the sysctl system for
22473 + grsecurity. It is advised that you read through the help for
22474 + each option to determine its usefulness in your situation.
22478 +menu "Address Space Protection"
22479 +depends on GRKERNSEC
22481 +config GRKERNSEC_KMEM
22482 + bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
22484 + If you say Y here, /dev/kmem and /dev/mem won't be allowed to
22485 + be written to via mmap or otherwise to modify the running kernel.
22486 + /dev/port will also not be allowed to be opened. If you have module
22487 + support disabled, enabling this will close up four ways that are
22488 + currently used to insert malicious code into the running kernel.
22489 + Even with all these features enabled, we still highly recommend that
22490 + you use the RBAC system, as it is still possible for an attacker to
22491 + modify the running kernel through privileged I/O granted by ioperm/iopl.
22492 + If you are not using XFree86, you may be able to stop this additional
22493 + case by enabling the 'Disable privileged I/O' option. Though nothing
22494 + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
22495 + but only to video memory, which is the only writing we allow in this
22496 + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
22497 + not be allowed to mprotect it with PROT_WRITE later.
22498 + It is highly recommended that you say Y here if you meet all the
22499 + conditions above.
22501 +config GRKERNSEC_IO
22502 + bool "Disable privileged I/O"
22506 + If you say Y here, all ioperm and iopl calls will return an error.
22507 + Ioperm and iopl can be used to modify the running kernel.
22508 + Unfortunately, some programs need this access to operate properly,
22509 + the most notable of which are XFree86 and hwclock. hwclock can be
22510 + remedied by having RTC support in the kernel, so CONFIG_RTC is
22511 + enabled if this option is enabled, to ensure that hwclock operates
22512 + correctly. XFree86 still will not operate correctly with this option
22513 + enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
22514 + and you still want to protect your kernel against modification,
22515 + use the RBAC system.
22517 +config GRKERNSEC_PROC_MEMMAP
22518 + bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
22519 + depends on PAX_NOEXEC || PAX_ASLR
22521 + If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
22522 + give no information about the addresses of its mappings if
22523 + PaX features that rely on random addresses are enabled on the task.
22524 + If you use PaX it is greatly recommended that you say Y here as it
22525 + closes up a hole that makes the full ASLR useless for suid
22528 +config GRKERNSEC_BRUTE
22529 + bool "Deter exploit bruteforcing"
22531 + If you say Y here, attempts to bruteforce exploits against forking
22532 + daemons such as apache or sshd will be deterred. When a child of a
22533 + forking daemon is killed by PaX or crashes due to an illegal
22534 + instruction, the parent process will be delayed 30 seconds upon every
22535 + subsequent fork until the administrator is able to assess the
22536 + situation and restart the daemon. It is recommended that you also
22537 + enable signal logging in the auditing section so that logs are
22538 + generated when a process performs an illegal instruction.
22540 +config GRKERNSEC_MODSTOP
22541 + bool "Runtime module disabling"
22542 + depends on MODULES
22544 + If you say Y here, you will be able to disable the ability to (un)load
22545 + modules at runtime. This feature is useful if you need the ability
22546 + to load kernel modules at boot time, but do not want to allow an
22547 + attacker to load a rootkit kernel module into the system, or to remove
22548 + a loaded kernel module important to system functioning. You should
22549 + enable the /dev/mem protection feature as well, since rootkits can be
22550 + inserted into the kernel via other methods than kernel modules. Since
22551 + an untrusted module could still be loaded by modifying init scripts and
22552 + rebooting the system, it is also recommended that you enable the RBAC
22553 + system. If you enable this option, a sysctl option with name
22554 + "disable_modules" will be created. Setting this option to "1" disables
22555 + module loading. After this option is set, no further writes to it are
22556 + allowed until the system is rebooted.
22558 +config GRKERNSEC_HIDESYM
22559 + bool "Hide kernel symbols"
22561 + If you say Y here, getting information on loaded modules, and
22562 + displaying all kernel symbols through a syscall will be restricted
22563 + to users with CAP_SYS_MODULE. This option is only effective
22564 + provided the following conditions are met:
22565 + 1) The kernel using grsecurity is not precompiled by some distribution
22566 + 2) You are using the RBAC system and hiding other files such as your
22567 + kernel image and System.map
22568 + 3) You have the additional /proc restrictions enabled, which removes
22570 + If the above conditions are met, this option will aid to provide a
22571 + useful protection against local and remote kernel exploitation of
22572 + overflows and arbitrary read/write vulnerabilities.
22575 +menu "Role Based Access Control Options"
22576 +depends on GRKERNSEC
22578 +config GRKERNSEC_ACL_HIDEKERN
22579 + bool "Hide kernel processes"
22581 + If you say Y here, all kernel threads will be hidden to all
22582 + processes but those whose subject has the "view hidden processes"
22585 +config GRKERNSEC_ACL_MAXTRIES
22586 + int "Maximum tries before password lockout"
22589 + This option enforces the maximum number of times a user can attempt
22590 + to authorize themselves with the grsecurity RBAC system before being
22591 + denied the ability to attempt authorization again for a specified time.
22592 + The lower the number, the harder it will be to brute-force a password.
22594 +config GRKERNSEC_ACL_TIMEOUT
22595 + int "Time to wait after max password tries, in seconds"
22598 + This option specifies the time the user must wait after attempting to
22599 + authorize to the RBAC system with the maximum number of invalid
22600 + passwords. The higher the number, the harder it will be to brute-force
22604 +menu "Filesystem Protections"
22605 +depends on GRKERNSEC
22607 +config GRKERNSEC_PROC
22608 + bool "Proc restrictions"
22610 + If you say Y here, the permissions of the /proc filesystem
22611 + will be altered to enhance system security and privacy. You MUST
22612 + choose either a user only restriction or a user and group restriction.
22613 + Depending upon the option you choose, you can either restrict users to
22614 + see only the processes they themselves run, or choose a group that can
22615 + view all processes and files normally restricted to root if you choose
22616 + the "restrict to user only" option. NOTE: If you're running identd as
22617 + a non-root user, you will have to run it as the group you specify here.
22619 +config GRKERNSEC_PROC_USER
22620 + bool "Restrict /proc to user only"
22621 + depends on GRKERNSEC_PROC
22623 + If you say Y here, non-root users will only be able to view their own
22624 + processes, and restricts them from viewing network-related information,
22625 + and viewing kernel symbol and module information.
22627 +config GRKERNSEC_PROC_USERGROUP
22628 + bool "Allow special group"
22629 + depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
22631 + If you say Y here, you will be able to select a group that will be
22632 + able to view all processes, network-related information, and
22633 + kernel and symbol information. This option is useful if you want
22634 + to run identd as a non-root user.
22636 +config GRKERNSEC_PROC_GID
22637 + int "GID for special group"
22638 + depends on GRKERNSEC_PROC_USERGROUP
22641 +config GRKERNSEC_PROC_ADD
22642 + bool "Additional restrictions"
22643 + depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
22645 + If you say Y here, additional restrictions will be placed on
22646 + /proc that keep normal users from viewing device information and
22647 + slabinfo information that could be useful for exploits.
22649 +config GRKERNSEC_LINK
22650 + bool "Linking restrictions"
22652 + If you say Y here, /tmp race exploits will be prevented, since users
22653 + will no longer be able to follow symlinks owned by other users in
22654 + world-writable +t directories (i.e. /tmp), unless the owner of the
22655 + symlink is the owner of the directory. users will also not be
22656 + able to hardlink to files they do not own. If the sysctl option is
22657 + enabled, a sysctl option with name "linking_restrictions" is created.
22659 +config GRKERNSEC_FIFO
22660 + bool "FIFO restrictions"
22662 + If you say Y here, users will not be able to write to FIFOs they don't
22663 + own in world-writable +t directories (i.e. /tmp), unless the owner of
22664 + the FIFO is the same owner of the directory it's held in. If the sysctl
22665 + option is enabled, a sysctl option with name "fifo_restrictions" is
22668 +config GRKERNSEC_CHROOT
22669 + bool "Chroot jail restrictions"
22671 + If you say Y here, you will be able to choose several options that will
22672 + make breaking out of a chrooted jail much more difficult. If you
22673 + encounter no software incompatibilities with the following options, it
22674 + is recommended that you enable each one.
22676 +config GRKERNSEC_CHROOT_MOUNT
22677 + bool "Deny mounts"
22678 + depends on GRKERNSEC_CHROOT
22680 + If you say Y here, processes inside a chroot will not be able to
22681 + mount or remount filesystems. If the sysctl option is enabled, a
22682 + sysctl option with name "chroot_deny_mount" is created.
22684 +config GRKERNSEC_CHROOT_DOUBLE
22685 + bool "Deny double-chroots"
22686 + depends on GRKERNSEC_CHROOT
22688 + If you say Y here, processes inside a chroot will not be able to chroot
22689 + again outside the chroot. This is a widely used method of breaking
22690 + out of a chroot jail and should not be allowed. If the sysctl
22691 + option is enabled, a sysctl option with name
22692 + "chroot_deny_chroot" is created.
22694 +config GRKERNSEC_CHROOT_PIVOT
22695 + bool "Deny pivot_root in chroot"
22696 + depends on GRKERNSEC_CHROOT
22698 + If you say Y here, processes inside a chroot will not be able to use
22699 + a function called pivot_root() that was introduced in Linux 2.3.41. It
22700 + works similar to chroot in that it changes the root filesystem. This
22701 + function could be misused in a chrooted process to attempt to break out
22702 + of the chroot, and therefore should not be allowed. If the sysctl
22703 + option is enabled, a sysctl option with name "chroot_deny_pivot" is
22706 +config GRKERNSEC_CHROOT_CHDIR
22707 + bool "Enforce chdir(\"/\") on all chroots"
22708 + depends on GRKERNSEC_CHROOT
22710 + If you say Y here, the current working directory of all newly-chrooted
22711 + applications will be set to the the root directory of the chroot.
22712 + The man page on chroot(2) states:
22713 + Note that this call does not change the current working
22714 + directory, so that `.' can be outside the tree rooted at
22715 + `/'. In particular, the super-user can escape from a
22716 + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
22718 + It is recommended that you say Y here, since it's not known to break
22719 + any software. If the sysctl option is enabled, a sysctl option with
22720 + name "chroot_enforce_chdir" is created.
22722 +config GRKERNSEC_CHROOT_CHMOD
22723 + bool "Deny (f)chmod +s"
22724 + depends on GRKERNSEC_CHROOT
22726 + If you say Y here, processes inside a chroot will not be able to chmod
22727 + or fchmod files to make them have suid or sgid bits. This protects
22728 + against another published method of breaking a chroot. If the sysctl
22729 + option is enabled, a sysctl option with name "chroot_deny_chmod" is
22732 +config GRKERNSEC_CHROOT_FCHDIR
22733 + bool "Deny fchdir out of chroot"
22734 + depends on GRKERNSEC_CHROOT
22736 + If you say Y here, a well-known method of breaking chroots by fchdir'ing
22737 + to a file descriptor of the chrooting process that points to a directory
22738 + outside the filesystem will be stopped. If the sysctl option
22739 + is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
22741 +config GRKERNSEC_CHROOT_MKNOD
22742 + bool "Deny mknod"
22743 + depends on GRKERNSEC_CHROOT
22745 + If you say Y here, processes inside a chroot will not be allowed to
22746 + mknod. The problem with using mknod inside a chroot is that it
22747 + would allow an attacker to create a device entry that is the same
22748 + as one on the physical root of your system, which could range from
22749 + anything from the console device to a device for your harddrive (which
22750 + they could then use to wipe the drive or steal data). It is recommended
22751 + that you say Y here, unless you run into software incompatibilities.
22752 + If the sysctl option is enabled, a sysctl option with name
22753 + "chroot_deny_mknod" is created.
22755 +config GRKERNSEC_CHROOT_SHMAT
22756 + bool "Deny shmat() out of chroot"
22757 + depends on GRKERNSEC_CHROOT
22759 + If you say Y here, processes inside a chroot will not be able to attach
22760 + to shared memory segments that were created outside of the chroot jail.
22761 + It is recommended that you say Y here. If the sysctl option is enabled,
22762 + a sysctl option with name "chroot_deny_shmat" is created.
22764 +config GRKERNSEC_CHROOT_UNIX
22765 + bool "Deny access to abstract AF_UNIX sockets out of chroot"
22766 + depends on GRKERNSEC_CHROOT
22768 + If you say Y here, processes inside a chroot will not be able to
22769 + connect to abstract (meaning not belonging to a filesystem) Unix
22770 + domain sockets that were bound outside of a chroot. It is recommended
22771 + that you say Y here. If the sysctl option is enabled, a sysctl option
22772 + with name "chroot_deny_unix" is created.
22774 +config GRKERNSEC_CHROOT_FINDTASK
22775 + bool "Protect outside processes"
22776 + depends on GRKERNSEC_CHROOT
22778 + If you say Y here, processes inside a chroot will not be able to
22779 + kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
22780 + or view any process outside of the chroot. If the sysctl
22781 + option is enabled, a sysctl option with name "chroot_findtask" is
22784 +config GRKERNSEC_CHROOT_NICE
22785 + bool "Restrict priority changes"
22786 + depends on GRKERNSEC_CHROOT
22788 + If you say Y here, processes inside a chroot will not be able to raise
22789 + the priority of processes in the chroot, or alter the priority of
22790 + processes outside the chroot. This provides more security than simply
22791 + removing CAP_SYS_NICE from the process' capability set. If the
22792 + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
22795 +config GRKERNSEC_CHROOT_SYSCTL
22796 + bool "Deny sysctl writes"
22797 + depends on GRKERNSEC_CHROOT
22799 + If you say Y here, an attacker in a chroot will not be able to
22800 + write to sysctl entries, either by sysctl(2) or through a /proc
22801 + interface. It is strongly recommended that you say Y here. If the
22802 + sysctl option is enabled, a sysctl option with name
22803 + "chroot_deny_sysctl" is created.
22805 +config GRKERNSEC_CHROOT_CAPS
22806 + bool "Capability restrictions"
22807 + depends on GRKERNSEC_CHROOT
22809 + If you say Y here, the capabilities on all root processes within a
22810 + chroot jail will be lowered to stop module insertion, raw i/o,
22811 + system and net admin tasks, rebooting the system, modifying immutable
22812 + files, modifying IPC owned by another, and changing the system time.
22813 + This is left an option because it can break some apps. Disable this
22814 + if your chrooted apps are having problems performing those kinds of
22815 + tasks. If the sysctl option is enabled, a sysctl option with
22816 + name "chroot_caps" is created.
22819 +menu "Kernel Auditing"
22820 +depends on GRKERNSEC
22822 +config GRKERNSEC_AUDIT_GROUP
22823 + bool "Single group for auditing"
22825 + If you say Y here, the exec, chdir, (un)mount, and ipc logging features
22826 + will only operate on a group you specify. This option is recommended
22827 + if you only want to watch certain users instead of having a large
22828 + amount of logs from the entire system. If the sysctl option is enabled,
22829 + a sysctl option with name "audit_group" is created.
22831 +config GRKERNSEC_AUDIT_GID
22832 + int "GID for auditing"
22833 + depends on GRKERNSEC_AUDIT_GROUP
22836 +config GRKERNSEC_EXECLOG
22837 + bool "Exec logging"
22839 + If you say Y here, all execve() calls will be logged (since the
22840 + other exec*() calls are frontends to execve(), all execution
22841 + will be logged). Useful for shell-servers that like to keep track
22842 + of their users. If the sysctl option is enabled, a sysctl option with
22843 + name "exec_logging" is created.
22844 + WARNING: This option when enabled will produce a LOT of logs, especially
22845 + on an active system.
22847 +config GRKERNSEC_RESLOG
22848 + bool "Resource logging"
22850 + If you say Y here, all attempts to overstep resource limits will
22851 + be logged with the resource name, the requested size, and the current
22852 + limit. It is highly recommended that you say Y here. If the sysctl
22853 + option is enabled, a sysctl option with name "resource_logging" is
22854 + created. If the RBAC system is enabled, the sysctl value is ignored.
22856 +config GRKERNSEC_CHROOT_EXECLOG
22857 + bool "Log execs within chroot"
22859 + If you say Y here, all executions inside a chroot jail will be logged
22860 + to syslog. This can cause a large amount of logs if certain
22861 + applications (eg. djb's daemontools) are installed on the system, and
22862 + is therefore left as an option. If the sysctl option is enabled, a
22863 + sysctl option with name "chroot_execlog" is created.
22865 +config GRKERNSEC_AUDIT_CHDIR
22866 + bool "Chdir logging"
22868 + If you say Y here, all chdir() calls will be logged. If the sysctl
22869 + option is enabled, a sysctl option with name "audit_chdir" is created.
22871 +config GRKERNSEC_AUDIT_MOUNT
22872 + bool "(Un)Mount logging"
22874 + If you say Y here, all mounts and unmounts will be logged. If the
22875 + sysctl option is enabled, a sysctl option with name "audit_mount" is
22878 +config GRKERNSEC_AUDIT_IPC
22879 + bool "IPC logging"
22881 + If you say Y here, creation and removal of message queues, semaphores,
22882 + and shared memory will be logged. If the sysctl option is enabled, a
22883 + sysctl option with name "audit_ipc" is created.
22885 +config GRKERNSEC_SIGNAL
22886 + bool "Signal logging"
22888 + If you say Y here, certain important signals will be logged, such as
22889 + SIGSEGV, which will as a result inform you of when a error in a program
22890 + occurred, which in some cases could mean a possible exploit attempt.
22891 + If the sysctl option is enabled, a sysctl option with name
22892 + "signal_logging" is created.
22894 +config GRKERNSEC_FORKFAIL
22895 + bool "Fork failure logging"
22897 + If you say Y here, all failed fork() attempts will be logged.
22898 + This could suggest a fork bomb, or someone attempting to overstep
22899 + their process limit. If the sysctl option is enabled, a sysctl option
22900 + with name "forkfail_logging" is created.
22902 +config GRKERNSEC_TIME
22903 + bool "Time change logging"
22905 + If you say Y here, any changes of the system clock will be logged.
22906 + If the sysctl option is enabled, a sysctl option with name
22907 + "timechange_logging" is created.
22909 +config GRKERNSEC_PROC_IPADDR
22910 + bool "/proc/<pid>/ipaddr support"
22912 + If you say Y here, a new entry will be added to each /proc/<pid>
22913 + directory that contains the IP address of the person using the task.
22914 + The IP is carried across local TCP and AF_UNIX stream sockets.
22915 + This information can be useful for IDS/IPSes to perform remote response
22916 + to a local attack. The entry is readable by only the owner of the
22917 + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
22918 + the RBAC system), and thus does not create privacy concerns.
22920 +config GRKERNSEC_AUDIT_TEXTREL
22921 + bool 'ELF text relocations logging (READ HELP)'
22922 + depends on PAX_MPROTECT
22924 + If you say Y here, text relocations will be logged with the filename
22925 + of the offending library or binary. The purpose of the feature is
22926 + to help Linux distribution developers get rid of libraries and
22927 + binaries that need text relocations which hinder the future progress
22928 + of PaX. Only Linux distribution developers should say Y here, and
22929 + never on a production machine, as this option creates an information
22930 + leak that could aid an attacker in defeating the randomization of
22931 + a single memory region. If the sysctl option is enabled, a sysctl
22932 + option with name "audit_textrel" is created.
22936 +menu "Executable Protections"
22937 +depends on GRKERNSEC
22939 +config GRKERNSEC_EXECVE
22940 + bool "Enforce RLIMIT_NPROC on execs"
22942 + If you say Y here, users with a resource limit on processes will
22943 + have the value checked during execve() calls. The current system
22944 + only checks the system limit during fork() calls. If the sysctl option
22945 + is enabled, a sysctl option with name "execve_limiting" is created.
22947 +config GRKERNSEC_SHM
22948 + bool "Destroy unused shared memory"
22949 + depends on SYSVIPC
22951 + If you say Y here, shared memory will be destroyed when no one is
22952 + attached to it. Otherwise, resources involved with the shared
22953 + memory can be used up and not be associated with any process (as the
22954 + shared memory still exists, and the creating process has exited). If
22955 + the sysctl option is enabled, a sysctl option with name
22956 + "destroy_unused_shm" is created.
22958 +config GRKERNSEC_DMESG
22959 + bool "Dmesg(8) restriction"
22961 + If you say Y here, non-root users will not be able to use dmesg(8)
22962 + to view up to the last 4kb of messages in the kernel's log buffer.
22963 + If the sysctl option is enabled, a sysctl option with name "dmesg" is
22966 +config GRKERNSEC_TPE
22967 + bool "Trusted Path Execution (TPE)"
22969 + If you say Y here, you will be able to choose a gid to add to the
22970 + supplementary groups of users you want to mark as "untrusted."
22971 + These users will not be able to execute any files that are not in
22972 + root-owned directories writable only by root. If the sysctl option
22973 + is enabled, a sysctl option with name "tpe" is created.
22975 +config GRKERNSEC_TPE_ALL
22976 + bool "Partially restrict non-root users"
22977 + depends on GRKERNSEC_TPE
22979 + If you say Y here, All non-root users other than the ones in the
22980 + group specified in the main TPE option will only be allowed to
22981 + execute files in directories they own that are not group or
22982 + world-writable, or in directories owned by root and writable only by
22983 + root. If the sysctl option is enabled, a sysctl option with name
22984 + "tpe_restrict_all" is created.
22986 +config GRKERNSEC_TPE_INVERT
22987 + bool "Invert GID option"
22988 + depends on GRKERNSEC_TPE
22990 + If you say Y here, the group you specify in the TPE configuration will
22991 + decide what group TPE restrictions will be *disabled* for. This
22992 + option is useful if you want TPE restrictions to be applied to most
22993 + users on the system.
22995 +config GRKERNSEC_TPE_GID
22996 + int "GID for untrusted users"
22997 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
23000 + If you have selected the "Invert GID option" above, setting this
23001 + GID determines what group TPE restrictions will be *disabled* for.
23002 + If you have not selected the "Invert GID option" above, setting this
23003 + GID determines what group TPE restrictions will be *enabled* for.
23004 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23007 +config GRKERNSEC_TPE_GID
23008 + int "GID for trusted users"
23009 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
23012 + If you have selected the "Invert GID option" above, setting this
23013 + GID determines what group TPE restrictions will be *disabled* for.
23014 + If you have not selected the "Invert GID option" above, setting this
23015 + GID determines what group TPE restrictions will be *enabled* for.
23016 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23020 +menu "Network Protections"
23021 +depends on GRKERNSEC
23023 +config GRKERNSEC_RANDNET
23024 + bool "Larger entropy pools"
23026 + If you say Y here, the entropy pools used for many features of Linux
23027 + and grsecurity will be doubled in size. Since several grsecurity
23028 + features use additional randomness, it is recommended that you say Y
23029 + here. Saying Y here has a similar effect as modifying
23030 + /proc/sys/kernel/random/poolsize.
23032 +config GRKERNSEC_SOCKET
23033 + bool "Socket restrictions"
23035 + If you say Y here, you will be able to choose from several options.
23036 + If you assign a GID on your system and add it to the supplementary
23037 + groups of users you want to restrict socket access to, this patch
23038 + will perform up to three things, based on the option(s) you choose.
23040 +config GRKERNSEC_SOCKET_ALL
23041 + bool "Deny any sockets to group"
23042 + depends on GRKERNSEC_SOCKET
23044 + If you say Y here, you will be able to choose a GID of whose users will
23045 + be unable to connect to other hosts from your machine or run server
23046 + applications from your machine. If the sysctl option is enabled, a
23047 + sysctl option with name "socket_all" is created.
23049 +config GRKERNSEC_SOCKET_ALL_GID
23050 + int "GID to deny all sockets for"
23051 + depends on GRKERNSEC_SOCKET_ALL
23054 + Here you can choose the GID to disable socket access for. Remember to
23055 + add the users you want socket access disabled for to the GID
23056 + specified here. If the sysctl option is enabled, a sysctl option
23057 + with name "socket_all_gid" is created.
23059 +config GRKERNSEC_SOCKET_CLIENT
23060 + bool "Deny client sockets to group"
23061 + depends on GRKERNSEC_SOCKET
23063 + If you say Y here, you will be able to choose a GID of whose users will
23064 + be unable to connect to other hosts from your machine, but will be
23065 + able to run servers. If this option is enabled, all users in the group
23066 + you specify will have to use passive mode when initiating ftp transfers
23067 + from the shell on your machine. If the sysctl option is enabled, a
23068 + sysctl option with name "socket_client" is created.
23070 +config GRKERNSEC_SOCKET_CLIENT_GID
23071 + int "GID to deny client sockets for"
23072 + depends on GRKERNSEC_SOCKET_CLIENT
23075 + Here you can choose the GID to disable client socket access for.
23076 + Remember to add the users you want client socket access disabled for to
23077 + the GID specified here. If the sysctl option is enabled, a sysctl
23078 + option with name "socket_client_gid" is created.
23080 +config GRKERNSEC_SOCKET_SERVER
23081 + bool "Deny server sockets to group"
23082 + depends on GRKERNSEC_SOCKET
23084 + If you say Y here, you will be able to choose a GID of whose users will
23085 + be unable to run server applications from your machine. If the sysctl
23086 + option is enabled, a sysctl option with name "socket_server" is created.
23088 +config GRKERNSEC_SOCKET_SERVER_GID
23089 + int "GID to deny server sockets for"
23090 + depends on GRKERNSEC_SOCKET_SERVER
23093 + Here you can choose the GID to disable server socket access for.
23094 + Remember to add the users you want server socket access disabled for to
23095 + the GID specified here. If the sysctl option is enabled, a sysctl
23096 + option with name "socket_server_gid" is created.
23099 +menu "Sysctl support"
23100 +depends on GRKERNSEC && SYSCTL
23102 +config GRKERNSEC_SYSCTL
23103 + bool "Sysctl support"
23105 + If you say Y here, you will be able to change the options that
23106 + grsecurity runs with at bootup, without having to recompile your
23107 + kernel. You can echo values to files in /proc/sys/kernel/grsecurity
23108 + to enable (1) or disable (0) various features. All the sysctl entries
23109 + are mutable until the "grsec_lock" entry is set to a non-zero value.
23110 + All features enabled in the kernel configuration are disabled at boot
23111 + if you do not say Y to the "Turn on features by default" option.
23112 + All options should be set at startup, and the grsec_lock entry should
23113 + be set to a non-zero value after all the options are set.
23114 + *THIS IS EXTREMELY IMPORTANT*
23116 +config GRKERNSEC_SYSCTL_ON
23117 + bool "Turn on features by default"
23118 + depends on GRKERNSEC_SYSCTL
23120 + If you say Y here, instead of having all features enabled in the
23121 + kernel configuration disabled at boot time, the features will be
23122 + enabled at boot time. It is recommended you say Y here unless
23123 + there is some reason you would want all sysctl-tunable features to
23124 + be disabled by default. As mentioned elsewhere, it is important
23125 + to enable the grsec_lock entry once you have finished modifying
23126 + the sysctl entries.
23129 +menu "Logging Options"
23130 +depends on GRKERNSEC
23132 +config GRKERNSEC_FLOODTIME
23133 + int "Seconds in between log messages (minimum)"
23136 + This option allows you to enforce the number of seconds between
23137 + grsecurity log messages. The default should be suitable for most
23138 + people, however, if you choose to change it, choose a value small enough
23139 + to allow informative logs to be produced, but large enough to
23140 + prevent flooding.
23142 +config GRKERNSEC_FLOODBURST
23143 + int "Number of messages in a burst (maximum)"
23146 + This option allows you to choose the maximum number of messages allowed
23147 + within the flood time interval you chose in a separate option. The
23148 + default should be suitable for most people, however if you find that
23149 + many of your logs are being interpreted as flooding, you may want to
23150 + raise this value.
23155 diff -urNp linux-2.6.20.3/grsecurity/Makefile linux-2.6.20.3/grsecurity/Makefile
23156 --- linux-2.6.20.3/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
23157 +++ linux-2.6.20.3/grsecurity/Makefile 2007-03-23 08:11:31.000000000 -0400
23159 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
23160 +# during 2001-2005 it has been completely redesigned by Brad Spengler
23161 +# into an RBAC system
23163 +# All code in this directory and various hooks inserted throughout the kernel
23164 +# are copyright Brad Spengler, and released under the GPL v2 or higher
23166 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
23167 + grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
23168 + grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
23170 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
23171 + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
23172 + gracl_learn.o grsec_log.o
23173 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
23175 +ifndef CONFIG_GRKERNSEC
23176 +obj-y += grsec_disabled.o
23179 diff -urNp linux-2.6.20.3/include/acpi/acmacros.h linux-2.6.20.3/include/acpi/acmacros.h
23180 --- linux-2.6.20.3/include/acpi/acmacros.h 2007-03-13 14:27:08.000000000 -0400
23181 +++ linux-2.6.20.3/include/acpi/acmacros.h 2007-03-23 08:10:06.000000000 -0400
23182 @@ -672,7 +672,7 @@
23183 #define ACPI_DUMP_PATHNAME(a,b,c,d)
23184 #define ACPI_DUMP_RESOURCE_LIST(a)
23185 #define ACPI_DUMP_BUFFER(a,b)
23186 -#define ACPI_DEBUG_PRINT(pl)
23187 +#define ACPI_DEBUG_PRINT(pl) do {} while (0)
23188 #define ACPI_DEBUG_PRINT_RAW(pl)
23190 #define return_VOID return
23191 diff -urNp linux-2.6.20.3/include/asm-alpha/a.out.h linux-2.6.20.3/include/asm-alpha/a.out.h
23192 --- linux-2.6.20.3/include/asm-alpha/a.out.h 2007-03-13 14:27:08.000000000 -0400
23193 +++ linux-2.6.20.3/include/asm-alpha/a.out.h 2007-03-23 08:10:06.000000000 -0400
23194 @@ -98,7 +98,7 @@ struct exec
23195 set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
23196 ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
23198 -#define STACK_TOP \
23199 +#define __STACK_TOP \
23200 (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
23203 diff -urNp linux-2.6.20.3/include/asm-alpha/elf.h linux-2.6.20.3/include/asm-alpha/elf.h
23204 --- linux-2.6.20.3/include/asm-alpha/elf.h 2007-03-13 14:27:08.000000000 -0400
23205 +++ linux-2.6.20.3/include/asm-alpha/elf.h 2007-03-23 08:10:06.000000000 -0400
23206 @@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
23208 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
23210 +#ifdef CONFIG_PAX_ASLR
23211 +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
23213 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
23214 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
23215 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
23216 +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
23217 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
23218 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
23221 /* $0 is set by ld.so to a pointer to a function which might be
23222 registered using atexit. This provides a mean for the dynamic
23223 linker to call DT_FINI functions for shared libraries that have
23224 diff -urNp linux-2.6.20.3/include/asm-alpha/kmap_types.h linux-2.6.20.3/include/asm-alpha/kmap_types.h
23225 --- linux-2.6.20.3/include/asm-alpha/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
23226 +++ linux-2.6.20.3/include/asm-alpha/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
23227 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
23232 +D(13) KM_CLEARPAGE,
23237 diff -urNp linux-2.6.20.3/include/asm-alpha/page.h linux-2.6.20.3/include/asm-alpha/page.h
23238 --- linux-2.6.20.3/include/asm-alpha/page.h 2007-03-13 14:27:08.000000000 -0400
23239 +++ linux-2.6.20.3/include/asm-alpha/page.h 2007-03-23 08:10:06.000000000 -0400
23240 @@ -93,6 +93,15 @@ typedef unsigned long pgprot_t;
23241 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
23242 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
23244 +#ifdef CONFIG_PAX_PAGEEXEC
23245 +#ifdef CONFIG_PAX_MPROTECT
23246 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
23247 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
23249 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
23253 #include <asm-generic/memory_model.h>
23254 #include <asm-generic/page.h>
23256 diff -urNp linux-2.6.20.3/include/asm-alpha/pgtable.h linux-2.6.20.3/include/asm-alpha/pgtable.h
23257 --- linux-2.6.20.3/include/asm-alpha/pgtable.h 2007-03-13 14:27:08.000000000 -0400
23258 +++ linux-2.6.20.3/include/asm-alpha/pgtable.h 2007-03-23 08:10:06.000000000 -0400
23259 @@ -101,6 +101,17 @@ struct vm_area_struct;
23260 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
23261 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
23262 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
23264 +#ifdef CONFIG_PAX_PAGEEXEC
23265 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
23266 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
23267 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
23269 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
23270 +# define PAGE_COPY_NOEXEC PAGE_COPY
23271 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
23274 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
23276 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
23277 diff -urNp linux-2.6.20.3/include/asm-arm/a.out.h linux-2.6.20.3/include/asm-arm/a.out.h
23278 --- linux-2.6.20.3/include/asm-arm/a.out.h 2007-03-13 14:27:08.000000000 -0400
23279 +++ linux-2.6.20.3/include/asm-arm/a.out.h 2007-03-23 08:10:06.000000000 -0400
23280 @@ -28,7 +28,7 @@ struct exec
23284 -#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
23285 +#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
23286 TASK_SIZE : TASK_SIZE_26)
23289 diff -urNp linux-2.6.20.3/include/asm-arm/elf.h linux-2.6.20.3/include/asm-arm/elf.h
23290 --- linux-2.6.20.3/include/asm-arm/elf.h 2007-03-13 14:27:08.000000000 -0400
23291 +++ linux-2.6.20.3/include/asm-arm/elf.h 2007-03-23 08:10:06.000000000 -0400
23292 @@ -110,6 +110,17 @@ extern char elf_platform[];
23294 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
23296 +#ifdef CONFIG_PAX_ASLR
23297 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x00008000UL
23299 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
23300 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
23301 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
23302 +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
23303 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
23304 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
23307 /* When the program starts, a1 contains a pointer to a function to be
23308 registered with atexit, as per the SVR4 ABI. A value of 0 means we
23309 have no such handler. */
23310 diff -urNp linux-2.6.20.3/include/asm-arm/kmap_types.h linux-2.6.20.3/include/asm-arm/kmap_types.h
23311 --- linux-2.6.20.3/include/asm-arm/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
23312 +++ linux-2.6.20.3/include/asm-arm/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
23313 @@ -18,6 +18,7 @@ enum km_type {
23321 diff -urNp linux-2.6.20.3/include/asm-arm26/kmap_types.h linux-2.6.20.3/include/asm-arm26/kmap_types.h
23322 --- linux-2.6.20.3/include/asm-arm26/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
23323 +++ linux-2.6.20.3/include/asm-arm26/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
23334 diff -urNp linux-2.6.20.3/include/asm-cris/kmap_types.h linux-2.6.20.3/include/asm-cris/kmap_types.h
23335 --- linux-2.6.20.3/include/asm-cris/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
23336 +++ linux-2.6.20.3/include/asm-cris/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
23337 @@ -19,6 +19,7 @@ enum km_type {
23345 diff -urNp linux-2.6.20.3/include/asm-frv/kmap_types.h linux-2.6.20.3/include/asm-frv/kmap_types.h
23346 --- linux-2.6.20.3/include/asm-frv/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
23347 +++ linux-2.6.20.3/include/asm-frv/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
23348 @@ -23,6 +23,7 @@ enum km_type {
23356 diff -urNp linux-2.6.20.3/include/asm-h8300/kmap_types.h linux-2.6.20.3/include/asm-h8300/kmap_types.h
23357 --- linux-2.6.20.3/include/asm-h8300/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
23358 +++ linux-2.6.20.3/include/asm-h8300/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
23359 @@ -15,6 +15,7 @@ enum km_type {
23367 diff -urNp linux-2.6.20.3/include/asm-i386/alternative.h linux-2.6.20.3/include/asm-i386/alternative.h
23368 --- linux-2.6.20.3/include/asm-i386/alternative.h 2007-03-13 14:27:08.000000000 -0400
23369 +++ linux-2.6.20.3/include/asm-i386/alternative.h 2007-03-23 08:10:06.000000000 -0400
23370 @@ -57,7 +57,7 @@ static inline void alternatives_smp_swit
23371 " .byte 662b-661b\n" /* sourcelen */ \
23372 " .byte 664f-663f\n" /* replacementlen */ \
23374 - ".section .altinstr_replacement,\"ax\"\n" \
23375 + ".section .altinstr_replacement,\"a\"\n" \
23376 "663:\n\t" newinstr "\n664:\n" /* replacement */\
23377 ".previous" :: "i" (feature) : "memory")
23379 @@ -81,7 +81,7 @@ static inline void alternatives_smp_swit
23380 " .byte 662b-661b\n" /* sourcelen */ \
23381 " .byte 664f-663f\n" /* replacementlen */ \
23383 - ".section .altinstr_replacement,\"ax\"\n" \
23384 + ".section .altinstr_replacement,\"a\"\n" \
23385 "663:\n\t" newinstr "\n664:\n" /* replacement */\
23386 ".previous" :: "i" (feature), ##input)
23388 diff -urNp linux-2.6.20.3/include/asm-i386/a.out.h linux-2.6.20.3/include/asm-i386/a.out.h
23389 --- linux-2.6.20.3/include/asm-i386/a.out.h 2007-03-13 14:27:08.000000000 -0400
23390 +++ linux-2.6.20.3/include/asm-i386/a.out.h 2007-03-23 08:10:06.000000000 -0400
23391 @@ -19,7 +19,11 @@ struct exec
23395 -#define STACK_TOP TASK_SIZE
23396 +#ifdef CONFIG_PAX_SEGMEXEC
23397 +#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
23399 +#define __STACK_TOP TASK_SIZE
23404 diff -urNp linux-2.6.20.3/include/asm-i386/apic.h linux-2.6.20.3/include/asm-i386/apic.h
23405 --- linux-2.6.20.3/include/asm-i386/apic.h 2007-03-13 14:27:08.000000000 -0400
23406 +++ linux-2.6.20.3/include/asm-i386/apic.h 2007-03-23 08:10:06.000000000 -0400
23408 #include <asm/processor.h>
23409 #include <asm/system.h>
23411 -#define Dprintk(x...)
23412 +#define Dprintk(x...) do {} while (0)
23416 diff -urNp linux-2.6.20.3/include/asm-i386/checksum.h linux-2.6.20.3/include/asm-i386/checksum.h
23417 --- linux-2.6.20.3/include/asm-i386/checksum.h 2007-03-13 14:27:08.000000000 -0400
23418 +++ linux-2.6.20.3/include/asm-i386/checksum.h 2007-03-23 08:10:06.000000000 -0400
23419 @@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
23420 asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
23421 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
23423 +asmlinkage __wsum csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
23424 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
23426 +asmlinkage __wsum csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
23427 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
23430 * Note: when you get a NULL pointer exception here this means someone
23431 * passed in an incorrect kernel address to one of these functions.
23432 @@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
23433 int len, __wsum sum, int *err_ptr)
23436 - return csum_partial_copy_generic((__force void *)src, dst,
23437 + return csum_partial_copy_generic_from_user((__force void *)src, dst,
23438 len, sum, err_ptr, NULL);
23441 @@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
23444 if (access_ok(VERIFY_WRITE, dst, len))
23445 - return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
23446 + return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
23449 *err_ptr = -EFAULT;
23450 diff -urNp linux-2.6.20.3/include/asm-i386/desc.h linux-2.6.20.3/include/asm-i386/desc.h
23451 --- linux-2.6.20.3/include/asm-i386/desc.h 2007-03-13 14:27:08.000000000 -0400
23452 +++ linux-2.6.20.3/include/asm-i386/desc.h 2007-03-23 08:10:06.000000000 -0400
23455 #include <linux/preempt.h>
23456 #include <linux/smp.h>
23457 -#include <linux/percpu.h>
23459 #include <asm/mmu.h>
23461 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
23462 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
23464 struct Xgt_desc_struct {
23465 unsigned short size;
23466 - unsigned long address __attribute__((packed));
23467 + struct desc_struct *address __attribute__((packed));
23468 unsigned short pad;
23469 } __attribute__ ((packed));
23471 -extern struct Xgt_desc_struct idt_descr;
23472 -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
23474 +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
23476 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
23478 - return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
23479 + return cpu_gdt_table[cpu];
23482 extern struct desc_struct idt_table[];
23483 @@ -76,9 +73,21 @@ static inline void pack_gate(__u32 *a, _
23485 static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
23488 +#ifdef CONFIG_PAX_KERNEXEC
23489 + unsigned long cr0;
23491 + pax_open_kernel(cr0);
23494 #define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
23498 +#ifdef CONFIG_PAX_KERNEXEC
23499 + pax_close_kernel(cr0);
23504 #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)
23505 @@ -88,8 +97,20 @@ static inline void load_TLS(struct threa
23506 static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b)
23508 __u32 *lp = (__u32 *)((char *)dt + entry*8);
23510 +#ifdef CONFIG_PAX_KERNEXEC
23511 + unsigned long cr0;
23513 + pax_open_kernel(cr0);
23519 +#ifdef CONFIG_PAX_KERNEXEC
23520 + pax_close_kernel(cr0);
23525 #define set_ldt native_set_ldt
23526 @@ -144,7 +165,7 @@ static inline void __set_tss_desc(unsign
23527 ((info)->seg_32bit << 22) | \
23528 ((info)->limit_in_pages << 23) | \
23529 ((info)->useable << 20) | \
23533 #define LDT_empty(info) (\
23534 (info)->base_addr == 0 && \
23535 @@ -176,15 +197,23 @@ static inline void load_LDT(mm_context_t
23539 -static inline unsigned long get_desc_base(unsigned long *desc)
23540 +static inline unsigned long get_desc_base(struct desc_struct *desc)
23542 unsigned long base;
23543 - base = ((desc[0] >> 16) & 0x0000ffff) |
23544 - ((desc[1] << 16) & 0x00ff0000) |
23545 - (desc[1] & 0xff000000);
23546 + base = ((desc->a >> 16) & 0x0000ffff) |
23547 + ((desc->b << 16) & 0x00ff0000) |
23548 + (desc->b & 0xff000000);
23552 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
23556 + pack_descriptor(&a, &b, base, limit - 1, 0xFB, 0xC);
23557 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
23560 #else /* __ASSEMBLY__ */
23563 diff -urNp linux-2.6.20.3/include/asm-i386/elf.h linux-2.6.20.3/include/asm-i386/elf.h
23564 --- linux-2.6.20.3/include/asm-i386/elf.h 2007-03-13 14:27:08.000000000 -0400
23565 +++ linux-2.6.20.3/include/asm-i386/elf.h 2007-03-23 08:10:06.000000000 -0400
23566 @@ -75,7 +75,22 @@ typedef struct user_fxsr_struct elf_fpxr
23567 the loader. We need to make sure that it is out of the way of the program
23568 that it will "exec", and that there is sufficient room for the brk. */
23570 +#ifdef CONFIG_PAX_SEGMEXEC
23571 +#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
23573 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
23576 +#ifdef CONFIG_PAX_ASLR
23577 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000000UL
23579 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
23580 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
23581 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
23582 +#define PAX_DELTA_EXEC_LEN(tsk) 15
23583 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
23584 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
23587 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
23588 now struct_user_regs, they are different) */
23589 @@ -133,7 +148,7 @@ extern int dump_task_extended_fpu (struc
23590 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
23592 #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
23593 -#define VDSO_BASE ((unsigned long)current->mm->context.vdso)
23594 +#define VDSO_BASE (current->mm->context.vdso)
23596 #ifdef CONFIG_COMPAT_VDSO
23597 # define VDSO_COMPAT_BASE VDSO_HIGH_BASE
23598 diff -urNp linux-2.6.20.3/include/asm-i386/futex.h linux-2.6.20.3/include/asm-i386/futex.h
23599 --- linux-2.6.20.3/include/asm-i386/futex.h 2007-03-13 14:27:08.000000000 -0400
23600 +++ linux-2.6.20.3/include/asm-i386/futex.h 2007-03-23 08:11:31.000000000 -0400
23603 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
23604 __asm__ __volatile ( \
23605 + "movw %w6, %%ds\n"\
23607 -"2: .section .fixup,\"ax\"\n\
23610 + .section .fixup,\"ax\"\n\
23614 @@ -21,16 +24,19 @@
23617 : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
23618 - : "i" (-EFAULT), "0" (oparg), "1" (0))
23619 + : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
23621 #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
23622 __asm__ __volatile ( \
23623 -"1: movl %2, %0\n\
23624 +" movw %w7, %%es\n\
23625 +1: movl %%es:%2, %0\n\
23628 -"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
23629 +"2: " LOCK_PREFIX "cmpxchgl %3, %%es:%2\n\
23631 -3: .section .fixup,\"ax\"\n\
23634 + .section .fixup,\"ax\"\n\
23640 : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
23642 - : "r" (oparg), "i" (-EFAULT), "1" (0))
23643 + : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
23646 futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
23647 @@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op,
23648 pagefault_disable();
23650 if (op == FUTEX_OP_SET)
23651 - __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
23652 + __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
23654 #ifndef CONFIG_X86_BSWAP
23655 if (boot_cpu_data.x86 == 3)
23656 @@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op,
23660 - __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
23661 + __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret,
23662 oldval, uaddr, oparg);
23665 @@ -111,9 +117,11 @@ futex_atomic_cmpxchg_inatomic(int __user
23668 __asm__ __volatile__(
23669 - "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
23671 - "2: .section .fixup, \"ax\" \n"
23672 + " movw %w5, %%ds \n"
23673 + "1: " LOCK_PREFIX "cmpxchgl %3, %%ds:%1 \n"
23674 + "2: pushl %%ss \n"
23676 + " .section .fixup, \"ax\" \n"
23680 @@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
23683 : "=a" (oldval), "+m" (*uaddr)
23684 - : "i" (-EFAULT), "r" (newval), "0" (oldval)
23685 + : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
23689 diff -urNp linux-2.6.20.3/include/asm-i386/i387.h linux-2.6.20.3/include/asm-i386/i387.h
23690 --- linux-2.6.20.3/include/asm-i386/i387.h 2007-03-13 14:27:08.000000000 -0400
23691 +++ linux-2.6.20.3/include/asm-i386/i387.h 2007-03-23 08:10:06.000000000 -0400
23692 @@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
23693 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
23695 /* We need a safe address that is cheap to find and that is already
23696 - in L1 during context switch. The best choices are unfortunately
23697 - different for UP and SMP */
23699 -#define safe_address (__per_cpu_offset[0])
23701 -#define safe_address (kstat_cpu(0).cpustat.user)
23703 + in L1 during context switch. */
23704 +#define safe_address (init_tss[smp_processor_id()].esp0)
23707 * These must be called with preempt disabled
23708 diff -urNp linux-2.6.20.3/include/asm-i386/irqflags.h linux-2.6.20.3/include/asm-i386/irqflags.h
23709 --- linux-2.6.20.3/include/asm-i386/irqflags.h 2007-03-13 14:27:08.000000000 -0400
23710 +++ linux-2.6.20.3/include/asm-i386/irqflags.h 2007-03-23 08:10:06.000000000 -0400
23711 @@ -84,6 +84,8 @@ static inline unsigned long __raw_local_
23712 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
23713 #define INTERRUPT_RETURN iret
23714 #define GET_CR0_INTO_EAX movl %cr0, %eax
23715 +#define GET_CR0_INTO_EDX movl %cr0, %edx
23716 +#define SET_CR0_FROM_EDX movl %edx, %cr0
23717 #endif /* __ASSEMBLY__ */
23718 #endif /* CONFIG_PARAVIRT */
23720 diff -urNp linux-2.6.20.3/include/asm-i386/kmap_types.h linux-2.6.20.3/include/asm-i386/kmap_types.h
23721 --- linux-2.6.20.3/include/asm-i386/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
23722 +++ linux-2.6.20.3/include/asm-i386/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
23723 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
23728 +D(13) KM_CLEARPAGE,
23733 diff -urNp linux-2.6.20.3/include/asm-i386/mach-default/apm.h linux-2.6.20.3/include/asm-i386/mach-default/apm.h
23734 --- linux-2.6.20.3/include/asm-i386/mach-default/apm.h 2007-03-13 14:27:08.000000000 -0400
23735 +++ linux-2.6.20.3/include/asm-i386/mach-default/apm.h 2007-03-23 08:10:06.000000000 -0400
23736 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
23737 __asm__ __volatile__(APM_DO_ZERO_SEGS
23740 - "lcall *%%cs:apm_bios_entry\n\t"
23741 + "lcall *%%ss:apm_bios_entry\n\t"
23745 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
23746 __asm__ __volatile__(APM_DO_ZERO_SEGS
23749 - "lcall *%%cs:apm_bios_entry\n\t"
23750 + "lcall *%%ss:apm_bios_entry\n\t"
23754 diff -urNp linux-2.6.20.3/include/asm-i386/mach-default/do_timer.h linux-2.6.20.3/include/asm-i386/mach-default/do_timer.h
23755 --- linux-2.6.20.3/include/asm-i386/mach-default/do_timer.h 2007-03-13 14:27:08.000000000 -0400
23756 +++ linux-2.6.20.3/include/asm-i386/mach-default/do_timer.h 2007-03-23 08:10:06.000000000 -0400
23757 @@ -18,7 +18,7 @@ static inline void do_timer_interrupt_ho
23761 - update_process_times(user_mode_vm(get_irq_regs()));
23762 + update_process_times(user_mode(get_irq_regs()));
23765 * In the SMP case we use the local APIC timer interrupt to do the
23766 diff -urNp linux-2.6.20.3/include/asm-i386/mach-voyager/do_timer.h linux-2.6.20.3/include/asm-i386/mach-voyager/do_timer.h
23767 --- linux-2.6.20.3/include/asm-i386/mach-voyager/do_timer.h 2007-03-13 14:27:08.000000000 -0400
23768 +++ linux-2.6.20.3/include/asm-i386/mach-voyager/do_timer.h 2007-03-23 08:10:06.000000000 -0400
23769 @@ -5,7 +5,7 @@ static inline void do_timer_interrupt_ho
23773 - update_process_times(user_mode_vm(irq_regs));
23774 + update_process_times(user_mode(irq_regs));
23777 voyager_timer_interrupt();
23778 diff -urNp linux-2.6.20.3/include/asm-i386/mman.h linux-2.6.20.3/include/asm-i386/mman.h
23779 --- linux-2.6.20.3/include/asm-i386/mman.h 2007-03-13 14:27:08.000000000 -0400
23780 +++ linux-2.6.20.3/include/asm-i386/mman.h 2007-03-23 08:10:06.000000000 -0400
23782 #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
23783 #define MAP_NONBLOCK 0x10000 /* do not block on IO */
23785 +#ifdef CONFIG_PAX_SEGMEXEC
23786 +#define MAP_MIRROR 0x20000
23789 #define MCL_CURRENT 1 /* lock all current mappings */
23790 #define MCL_FUTURE 2 /* lock all future mappings */
23792 diff -urNp linux-2.6.20.3/include/asm-i386/mmu_context.h linux-2.6.20.3/include/asm-i386/mmu_context.h
23793 --- linux-2.6.20.3/include/asm-i386/mmu_context.h 2007-03-13 14:27:08.000000000 -0400
23794 +++ linux-2.6.20.3/include/asm-i386/mmu_context.h 2007-03-23 09:11:44.000000000 -0400
23795 @@ -45,6 +45,20 @@ static inline void switch_mm(struct mm_s
23797 if (unlikely(prev->context.ldt != next->context.ldt))
23798 load_LDT_nolock(&next->context);
23800 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
23801 + smp_mb__before_clear_bit();
23802 + cpu_clear(cpu, prev->context.cpu_user_cs_mask);
23803 + smp_mb__after_clear_bit();
23804 + cpu_set(cpu, next->context.cpu_user_cs_mask);
23807 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
23808 + if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
23809 + prev->context.user_cs_limit != next->context.user_cs_limit))
23810 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
23816 @@ -57,6 +71,15 @@ static inline void switch_mm(struct mm_s
23818 load_cr3(next->pgd);
23819 load_LDT_nolock(&next->context);
23821 +#ifdef CONFIG_PAX_PAGEEXEC
23822 + cpu_set(cpu, next->context.cpu_user_cs_mask);
23825 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
23826 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
23832 diff -urNp linux-2.6.20.3/include/asm-i386/mmu.h linux-2.6.20.3/include/asm-i386/mmu.h
23833 --- linux-2.6.20.3/include/asm-i386/mmu.h 2007-03-13 14:27:08.000000000 -0400
23834 +++ linux-2.6.20.3/include/asm-i386/mmu.h 2007-03-23 09:12:24.000000000 -0400
23838 struct semaphore sem;
23841 + struct desc_struct *ldt;
23842 + unsigned long vdso;
23844 + unsigned long user_cs_base;
23845 + unsigned long user_cs_limit;
23847 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
23848 + cpumask_t cpu_user_cs_mask;
23854 diff -urNp linux-2.6.20.3/include/asm-i386/module.h linux-2.6.20.3/include/asm-i386/module.h
23855 --- linux-2.6.20.3/include/asm-i386/module.h 2007-03-13 14:27:08.000000000 -0400
23856 +++ linux-2.6.20.3/include/asm-i386/module.h 2007-03-23 08:11:31.000000000 -0400
23857 @@ -68,6 +68,12 @@ struct mod_arch_specific
23858 #define MODULE_STACKSIZE ""
23861 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
23862 +#ifdef CONFIG_GRKERNSEC
23863 +#define MODULE_GRSEC "GRSECURTY "
23865 +#define MODULE_GRSEC ""
23868 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
23870 #endif /* _ASM_I386_MODULE_H */
23871 diff -urNp linux-2.6.20.3/include/asm-i386/page.h linux-2.6.20.3/include/asm-i386/page.h
23872 --- linux-2.6.20.3/include/asm-i386/page.h 2007-03-13 14:27:08.000000000 -0400
23873 +++ linux-2.6.20.3/include/asm-i386/page.h 2007-03-23 08:10:06.000000000 -0400
23875 #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
23878 +#include <asm/boot.h>
23879 #ifndef __ASSEMBLY__
23882 @@ -51,14 +52,15 @@ typedef struct { unsigned long long pgpr
23883 #define pmd_val(x) ((x).pmd)
23884 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
23885 #define __pmd(x) ((pmd_t) { (x) } )
23886 +#define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
23887 #define HPAGE_SHIFT 21
23888 #include <asm-generic/pgtable-nopud.h>
23890 typedef struct { unsigned long pte_low; } pte_t;
23891 typedef struct { unsigned long pgd; } pgd_t;
23892 typedef struct { unsigned long pgprot; } pgprot_t;
23893 -#define boot_pte_t pte_t /* or would you rather have a typedef */
23894 #define pte_val(x) ((x).pte_low)
23895 +#define __pte(x) ((pte_t) { (x) } )
23896 #define HPAGE_SHIFT 22
23897 #include <asm-generic/pgtable-nopmd.h>
23899 @@ -74,7 +76,6 @@ typedef struct { unsigned long pgprot; }
23900 #define pgd_val(x) ((x).pgd)
23901 #define pgprot_val(x) ((x).pgprot)
23903 -#define __pte(x) ((pte_t) { (x) } )
23904 #define __pgd(x) ((pgd_t) { (x) } )
23905 #define __pgprot(x) ((pgprot_t) { (x) } )
23907 @@ -118,6 +119,15 @@ extern int page_is_ram(unsigned long pag
23908 #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET)
23911 +#ifdef CONFIG_PAX_KERNEXEC
23912 +#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + ((LOAD_PHYSICAL_ADDR + 4*1024*1024 - 1) & ~(4*1024*1024 - 1)))
23913 +#ifndef __ASSEMBLY__
23914 +extern unsigned char MODULES_VADDR[];
23915 +extern unsigned char MODULES_END[];
23918 +#define __KERNEL_TEXT_OFFSET (0)
23921 #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
23922 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
23923 @@ -140,6 +150,19 @@ extern int page_is_ram(unsigned long pag
23924 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
23925 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
23927 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
23928 +#ifdef CONFIG_PAX_MPROTECT
23929 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
23930 + ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
23932 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
23936 +#ifdef CONFIG_PAX_PAGEEXEC
23937 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
23940 #include <asm-generic/memory_model.h>
23941 #include <asm-generic/page.h>
23943 diff -urNp linux-2.6.20.3/include/asm-i386/paravirt.h linux-2.6.20.3/include/asm-i386/paravirt.h
23944 --- linux-2.6.20.3/include/asm-i386/paravirt.h 2007-03-13 14:27:08.000000000 -0400
23945 +++ linux-2.6.20.3/include/asm-i386/paravirt.h 2007-03-23 08:10:06.000000000 -0400
23946 @@ -150,7 +150,7 @@ struct paravirt_ops
23947 static asmlinkage void (*__paravirtprobe_##fn)(void) __attribute_used__ \
23948 __attribute__((__section__(".paravirtprobe"))) = fn
23950 -extern struct paravirt_ops paravirt_ops;
23951 +extern const struct paravirt_ops paravirt_ops;
23953 #define paravirt_enabled() (paravirt_ops.paravirt_enabled)
23955 @@ -479,7 +479,7 @@ static inline unsigned long __raw_local_
23957 #define INTERRUPT_RETURN \
23958 PARA_PATCH(PARAVIRT_INTERRUPT_RETURN, CLBR_ANY, \
23959 - jmp *%cs:paravirt_ops+PARAVIRT_iret)
23960 + jmp *%ss:paravirt_ops+PARAVIRT_iret)
23962 #define DISABLE_INTERRUPTS(clobbers) \
23963 PARA_PATCH(PARAVIRT_IRQ_DISABLE, clobbers, \
23964 @@ -490,16 +490,26 @@ static inline unsigned long __raw_local_
23965 #define ENABLE_INTERRUPTS(clobbers) \
23966 PARA_PATCH(PARAVIRT_IRQ_ENABLE, clobbers, \
23967 pushl %ecx; pushl %edx; \
23968 - call *%cs:paravirt_ops+PARAVIRT_irq_enable; \
23969 + call *%ss:paravirt_ops+PARAVIRT_irq_enable; \
23970 popl %edx; popl %ecx)
23972 #define ENABLE_INTERRUPTS_SYSEXIT \
23973 PARA_PATCH(PARAVIRT_STI_SYSEXIT, CLBR_ANY, \
23974 - jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit)
23975 + jmp *%ss:paravirt_ops+PARAVIRT_irq_enable_sysexit)
23977 -#define GET_CR0_INTO_EAX \
23978 +#define GET_CR0_INTO_EAX \
23979 call *paravirt_ops+PARAVIRT_read_cr0
23981 +#define GET_CR0_INTO_EDX \
23982 + movl %eax, %edx; \
23983 + call *%ss:paravirt_ops+PARAVIRT_read_cr0; \
23984 + xchgl %eax, %edx; \
23986 +#define SET_CR0_FROM_EDX \
23987 + xchgl %edx, %eax; \
23988 + call *%ss:paravirt_ops+PARAVIRT_write_cr0; \
23991 #endif /* __ASSEMBLY__ */
23992 #endif /* CONFIG_PARAVIRT */
23993 #endif /* __ASM_PARAVIRT_H */
23994 diff -urNp linux-2.6.20.3/include/asm-i386/pda.h linux-2.6.20.3/include/asm-i386/pda.h
23995 --- linux-2.6.20.3/include/asm-i386/pda.h 2007-03-13 14:27:08.000000000 -0400
23996 +++ linux-2.6.20.3/include/asm-i386/pda.h 2007-03-23 08:35:45.000000000 -0400
23997 @@ -11,14 +11,15 @@
24001 - struct i386_pda *_pda; /* pointer to self */
24002 + struct i386_pda * const _pda; /* pointer to self */
24005 struct task_struct *pcurrent; /* current process */
24006 struct pt_regs *irq_regs;
24009 -extern struct i386_pda *_cpu_pda[];
24010 +extern struct i386_pda * const _cpu_pda[];
24011 +extern struct i386_pda __cpu_pda[];
24013 #define cpu_pda(i) (_cpu_pda[i])
24015 @@ -33,10 +34,13 @@ extern void __bad_pda_field(void);
24016 clobbers, so gcc can readily analyse them. */
24017 extern struct i386_pda _proxy_pda;
24019 +#ifdef CONFIG_PAX_KERNEXEC
24020 #define pda_to_op(op,field,val) \
24022 + unsigned long cr0; \
24023 typedef typeof(_proxy_pda.field) T__; \
24024 if (0) { T__ tmp__; tmp__ = (val); } \
24025 + pax_open_kernel(cr0); \
24026 switch (sizeof(_proxy_pda.field)) { \
24028 asm(op "b %1,%%gs:%c2" \
24029 @@ -58,7 +62,36 @@ extern struct i386_pda _proxy_pda;
24031 default: __bad_pda_field(); \
24033 + pax_close_kernel(cr0); \
24036 +#define pda_to_op(op,field,val) \
24038 + typedef typeof(_proxy_pda.field) T__; \
24039 + if (0) { T__ tmp__; tmp__ = (val); } \
24040 + switch (sizeof(_proxy_pda.field)) { \
24042 + asm(op "b %1,%%gs:%c2" \
24043 + : "+m" (_proxy_pda.field) \
24044 + :"ri" ((T__)val), \
24045 + "i"(pda_offset(field))); \
24048 + asm(op "w %1,%%gs:%c2" \
24049 + : "+m" (_proxy_pda.field) \
24050 + :"ri" ((T__)val), \
24051 + "i"(pda_offset(field))); \
24054 + asm(op "l %1,%%gs:%c2" \
24055 + : "+m" (_proxy_pda.field) \
24056 + :"ri" ((T__)val), \
24057 + "i"(pda_offset(field))); \
24059 + default: __bad_pda_field(); \
24064 #define pda_from_op(op,field) \
24066 diff -urNp linux-2.6.20.3/include/asm-i386/pgalloc.h linux-2.6.20.3/include/asm-i386/pgalloc.h
24067 --- linux-2.6.20.3/include/asm-i386/pgalloc.h 2007-03-13 14:27:08.000000000 -0400
24068 +++ linux-2.6.20.3/include/asm-i386/pgalloc.h 2007-03-23 08:10:06.000000000 -0400
24070 #include <linux/threads.h>
24071 #include <linux/mm.h> /* for struct page */
24073 +#ifdef CONFIG_COMPAT_VDSO
24074 #define pmd_populate_kernel(mm, pmd, pte) \
24075 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
24077 +#define pmd_populate_kernel(mm, pmd, pte) \
24078 + set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
24081 #define pmd_populate(mm, pmd, pte) \
24082 set_pmd(pmd, __pmd(_PAGE_TABLE + \
24083 diff -urNp linux-2.6.20.3/include/asm-i386/pgtable.h linux-2.6.20.3/include/asm-i386/pgtable.h
24084 --- linux-2.6.20.3/include/asm-i386/pgtable.h 2007-03-13 14:27:08.000000000 -0400
24085 +++ linux-2.6.20.3/include/asm-i386/pgtable.h 2007-03-23 08:10:06.000000000 -0400
24086 @@ -34,7 +34,6 @@ struct vm_area_struct;
24088 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
24089 extern unsigned long empty_zero_page[1024];
24090 -extern pgd_t swapper_pg_dir[1024];
24091 extern struct kmem_cache *pgd_cache;
24092 extern struct kmem_cache *pmd_cache;
24093 extern spinlock_t pgd_lock;
24094 @@ -59,6 +58,11 @@ void paging_init(void);
24095 # include <asm/pgtable-2level-defs.h>
24098 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
24099 +#ifdef CONFIG_X86_PAE
24100 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
24103 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
24104 #define PGDIR_MASK (~(PGDIR_SIZE-1))
24106 @@ -68,9 +72,11 @@ void paging_init(void);
24107 #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
24108 #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
24110 +#ifndef CONFIG_X86_PAE
24111 #define TWOLEVEL_PGDIR_SHIFT 22
24112 #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
24113 #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
24116 /* Just any arbitrary offset to the start of the vmalloc VM area: the
24117 * current 8MB value just means that there will be a 8MB "hole" after the
24118 @@ -137,21 +143,30 @@ void paging_init(void);
24119 #define PAGE_NONE \
24120 __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
24121 #define PAGE_SHARED \
24122 - __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
24123 + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
24125 #define PAGE_SHARED_EXEC \
24126 __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
24127 -#define PAGE_COPY_NOEXEC \
24128 - __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
24129 #define PAGE_COPY_EXEC \
24130 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
24131 -#define PAGE_COPY \
24133 #define PAGE_READONLY \
24134 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
24135 #define PAGE_READONLY_EXEC \
24136 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
24138 +#ifdef CONFIG_PAX_PAGEEXEC
24139 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
24140 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
24141 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
24143 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
24144 +# define PAGE_COPY_NOEXEC \
24145 + __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
24146 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
24149 +#define PAGE_COPY \
24151 #define _PAGE_KERNEL \
24152 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
24153 #define _PAGE_KERNEL_EXEC \
24154 @@ -176,18 +191,18 @@ extern unsigned long long __PAGE_KERNEL,
24155 * This is the closest we can get..
24157 #define __P000 PAGE_NONE
24158 -#define __P001 PAGE_READONLY
24159 -#define __P010 PAGE_COPY
24160 -#define __P011 PAGE_COPY
24161 +#define __P001 PAGE_READONLY_NOEXEC
24162 +#define __P010 PAGE_COPY_NOEXEC
24163 +#define __P011 PAGE_COPY_NOEXEC
24164 #define __P100 PAGE_READONLY_EXEC
24165 #define __P101 PAGE_READONLY_EXEC
24166 #define __P110 PAGE_COPY_EXEC
24167 #define __P111 PAGE_COPY_EXEC
24169 #define __S000 PAGE_NONE
24170 -#define __S001 PAGE_READONLY
24171 -#define __S010 PAGE_SHARED
24172 -#define __S011 PAGE_SHARED
24173 +#define __S001 PAGE_READONLY_NOEXEC
24174 +#define __S010 PAGE_SHARED_NOEXEC
24175 +#define __S011 PAGE_SHARED_NOEXEC
24176 #define __S100 PAGE_READONLY_EXEC
24177 #define __S101 PAGE_READONLY_EXEC
24178 #define __S110 PAGE_SHARED_EXEC
24179 @@ -497,6 +512,9 @@ do { \
24180 #define update_mmu_cache(vma,address,pte) do { } while (0)
24181 #endif /* !__ASSEMBLY__ */
24183 +#define HAVE_ARCH_UNMAPPED_AREA
24184 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
24186 #ifdef CONFIG_FLATMEM
24187 #define kern_addr_valid(addr) (1)
24188 #endif /* CONFIG_FLATMEM */
24189 diff -urNp linux-2.6.20.3/include/asm-i386/processor.h linux-2.6.20.3/include/asm-i386/processor.h
24190 --- linux-2.6.20.3/include/asm-i386/processor.h 2007-03-13 14:27:08.000000000 -0400
24191 +++ linux-2.6.20.3/include/asm-i386/processor.h 2007-03-23 08:10:06.000000000 -0400
24193 #include <asm/system.h>
24194 #include <linux/cache.h>
24195 #include <linux/threads.h>
24196 -#include <asm/percpu.h>
24197 #include <linux/cpumask.h>
24198 #include <linux/init.h>
24200 @@ -99,8 +98,6 @@ struct cpuinfo_x86 {
24202 extern struct cpuinfo_x86 boot_cpu_data;
24203 extern struct cpuinfo_x86 new_cpu_data;
24204 -extern struct tss_struct doublefault_tss;
24205 -DECLARE_PER_CPU(struct tss_struct, init_tss);
24208 extern struct cpuinfo_x86 cpu_data[];
24209 @@ -274,10 +271,19 @@ extern int bootloader_type;
24211 #define TASK_SIZE (PAGE_OFFSET)
24213 +#ifdef CONFIG_PAX_SEGMEXEC
24214 +#define SEGMEXEC_TASK_SIZE ((PAGE_OFFSET) / 2)
24217 /* This decides where the kernel will search for a free chunk of vm
24218 * space during mmap's.
24221 +#ifdef CONFIG_PAX_SEGMEXEC
24222 +#define TASK_UNMAPPED_BASE (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
24224 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
24227 #define HAVE_ARCH_PICK_MMAP_LAYOUT
24229 @@ -393,6 +399,9 @@ struct tss_struct {
24231 #define ARCH_MIN_TASKALIGN 16
24233 +extern struct tss_struct doublefault_tss;
24234 +extern struct tss_struct init_tss[NR_CPUS];
24236 struct thread_struct {
24237 /* cached TLS descriptors. */
24238 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
24239 @@ -421,6 +430,7 @@ struct thread_struct {
24242 #define INIT_THREAD { \
24243 + .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
24244 .vm86_info = NULL, \
24245 .sysenter_cs = __KERNEL_CS, \
24246 .io_bitmap_ptr = NULL, \
24247 @@ -434,7 +444,7 @@ struct thread_struct {
24248 * be within the limit.
24250 #define INIT_TSS { \
24251 - .esp0 = sizeof(init_stack) + (long)&init_stack, \
24252 + .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
24253 .ss0 = __KERNEL_DS, \
24254 .ss1 = __KERNEL_CS, \
24255 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
24256 @@ -474,11 +484,7 @@ void show_trace(struct task_struct *task
24257 unsigned long get_wchan(struct task_struct *p);
24259 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
24260 -#define KSTK_TOP(info) \
24262 - unsigned long *__ptr = (unsigned long *)(info); \
24263 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
24265 +#define KSTK_TOP(info) ((info)->task.thread.esp0)
24268 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
24269 @@ -493,7 +499,7 @@ unsigned long get_wchan(struct task_stru
24270 #define task_pt_regs(task) \
24272 struct pt_regs *__regs__; \
24273 - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
24274 + __regs__ = (struct pt_regs *)((task)->thread.esp0); \
24278 @@ -742,7 +748,7 @@ extern unsigned long boot_option_idle_ov
24279 extern void enable_sep_cpu(void);
24280 extern int sysenter_setup(void);
24282 -extern int init_gdt(int cpu, struct task_struct *idle);
24283 +extern void init_gdt(int cpu, struct task_struct *idle);
24284 extern void cpu_set_gdt(int);
24285 extern void secondary_cpu_init(void);
24287 diff -urNp linux-2.6.20.3/include/asm-i386/ptrace.h linux-2.6.20.3/include/asm-i386/ptrace.h
24288 --- linux-2.6.20.3/include/asm-i386/ptrace.h 2007-03-13 14:27:08.000000000 -0400
24289 +++ linux-2.6.20.3/include/asm-i386/ptrace.h 2007-03-23 08:10:06.000000000 -0400
24290 @@ -35,17 +35,18 @@ struct task_struct;
24291 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
24294 - * user_mode_vm(regs) determines whether a register set came from user mode.
24295 + * user_mode(regs) determines whether a register set came from user mode.
24296 * This is true if V8086 mode was enabled OR if the register set was from
24297 * protected mode with RPL-3 CS value. This tricky test checks that with
24298 * one comparison. Many places in the kernel can bypass this full check
24299 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
24300 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
24303 -static inline int user_mode(struct pt_regs *regs)
24304 +static inline int user_mode_novm(struct pt_regs *regs)
24306 return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
24308 -static inline int user_mode_vm(struct pt_regs *regs)
24309 +static inline int user_mode(struct pt_regs *regs)
24311 return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
24313 diff -urNp linux-2.6.20.3/include/asm-i386/segment.h linux-2.6.20.3/include/asm-i386/segment.h
24314 --- linux-2.6.20.3/include/asm-i386/segment.h 2007-03-13 14:27:08.000000000 -0400
24315 +++ linux-2.6.20.3/include/asm-i386/segment.h 2007-03-23 08:10:06.000000000 -0400
24317 #define GDT_SIZE (GDT_ENTRIES * 8)
24319 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
24320 -#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
24321 +#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
24322 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
24323 -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
24324 +#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
24326 /* Simple and small GDT entries for booting only */
24328 diff -urNp linux-2.6.20.3/include/asm-i386/serial.h linux-2.6.20.3/include/asm-i386/serial.h
24329 --- linux-2.6.20.3/include/asm-i386/serial.h 2007-03-13 14:27:08.000000000 -0400
24330 +++ linux-2.6.20.3/include/asm-i386/serial.h 2007-03-23 08:10:06.000000000 -0400
24333 #define SERIAL_PORT_DFNS \
24334 /* UART CLK PORT IRQ FLAGS */ \
24335 - { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
24336 - { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
24337 - { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
24338 - { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
24339 + { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS, 0 ,0, NULL, 0 }, /* ttyS0 */ \
24340 + { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS, 0 ,0, NULL, 0 }, /* ttyS1 */ \
24341 + { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS, 0 ,0, NULL, 0 }, /* ttyS2 */ \
24342 + { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS, 0 ,0, NULL, 0 }, /* ttyS3 */
24343 diff -urNp linux-2.6.20.3/include/asm-i386/system.h linux-2.6.20.3/include/asm-i386/system.h
24344 --- linux-2.6.20.3/include/asm-i386/system.h 2007-03-13 14:27:08.000000000 -0400
24345 +++ linux-2.6.20.3/include/asm-i386/system.h 2007-03-23 08:10:06.000000000 -0400
24346 @@ -152,6 +152,21 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t"
24347 /* Set the 'TS' bit */
24348 #define stts() write_cr0(8 | read_cr0())
24350 +#define pax_open_kernel(cr0) \
24352 + typecheck(unsigned long,cr0); \
24353 + preempt_disable(); \
24354 + cr0 = read_cr0(); \
24355 + write_cr0(cr0 & ~0x10000UL); \
24358 +#define pax_close_kernel(cr0) \
24360 + typecheck(unsigned long,cr0); \
24361 + write_cr0(cr0); \
24362 + preempt_enable_no_resched(); \
24365 #endif /* __KERNEL__ */
24367 static inline unsigned long get_limit(unsigned long segment)
24368 @@ -159,7 +174,7 @@ static inline unsigned long get_limit(un
24369 unsigned long __limit;
24370 __asm__("lsll %1,%0"
24371 :"=r" (__limit):"r" (segment));
24372 - return __limit+1;
24376 #define nop() __asm__ __volatile__ ("nop")
24377 @@ -520,7 +535,7 @@ static inline void sched_cacheflush(void
24381 -extern unsigned long arch_align_stack(unsigned long sp);
24382 +#define arch_align_stack(x) (x)
24383 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
24385 void default_idle(void);
24386 diff -urNp linux-2.6.20.3/include/asm-i386/uaccess.h linux-2.6.20.3/include/asm-i386/uaccess.h
24387 --- linux-2.6.20.3/include/asm-i386/uaccess.h 2007-03-13 14:27:08.000000000 -0400
24388 +++ linux-2.6.20.3/include/asm-i386/uaccess.h 2007-03-23 08:10:06.000000000 -0400
24390 #include <linux/prefetch.h>
24391 #include <linux/string.h>
24392 #include <asm/page.h>
24393 +#include <asm/segment.h>
24395 #define VERIFY_READ 0
24396 #define VERIFY_WRITE 1
24399 #define get_ds() (KERNEL_DS)
24400 #define get_fs() (current_thread_info()->addr_limit)
24401 -#define set_fs(x) (current_thread_info()->addr_limit = (x))
24402 +void __set_fs(mm_segment_t x, int cpu);
24403 +void set_fs(mm_segment_t x);
24405 #define segment_eq(a,b) ((a).seg == (b).seg)
24407 @@ -280,9 +282,12 @@ extern void __put_user_8(void);
24409 #define __put_user_u64(x, addr, err) \
24410 __asm__ __volatile__( \
24411 - "1: movl %%eax,0(%2)\n" \
24412 - "2: movl %%edx,4(%2)\n" \
24413 + " movw %w5,%%ds\n" \
24414 + "1: movl %%eax,%%ds:0(%2)\n" \
24415 + "2: movl %%edx,%%ds:4(%2)\n" \
24417 + " pushl %%ss\n" \
24419 ".section .fixup,\"ax\"\n" \
24420 "4: movl %3,%0\n" \
24422 @@ -293,7 +298,8 @@ extern void __put_user_8(void);
24426 - : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
24427 + : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
24430 #ifdef CONFIG_X86_WP_WORKS_OK
24432 @@ -332,8 +338,11 @@ struct __large_struct { unsigned long bu
24434 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
24435 __asm__ __volatile__( \
24436 - "1: mov"itype" %"rtype"1,%2\n" \
24437 + " movw %w5,%%ds\n" \
24438 + "1: mov"itype" %"rtype"1,%%ds:%2\n" \
24440 + " pushl %%ss\n" \
24442 ".section .fixup,\"ax\"\n" \
24443 "3: movl %3,%0\n" \
24445 @@ -343,7 +352,8 @@ struct __large_struct { unsigned long bu
24449 - : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
24450 + : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
24454 #define __get_user_nocheck(x,ptr,size) \
24455 @@ -371,8 +381,11 @@ do { \
24457 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
24458 __asm__ __volatile__( \
24459 - "1: mov"itype" %2,%"rtype"1\n" \
24460 + " movw %w5,%%ds\n" \
24461 + "1: mov"itype" %%ds:%2,%"rtype"1\n" \
24463 + " pushl %%ss\n" \
24465 ".section .fixup,\"ax\"\n" \
24466 "3: movl %3,%0\n" \
24467 " xor"itype" %"rtype"1,%"rtype"1\n" \
24468 @@ -383,7 +396,7 @@ do { \
24471 : "=r"(err), ltype (x) \
24472 - : "m"(__m(addr)), "i"(errret), "0"(err))
24473 + : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
24476 unsigned long __must_check __copy_to_user_ll(void __user *to,
24477 diff -urNp linux-2.6.20.3/include/asm-ia64/elf.h linux-2.6.20.3/include/asm-ia64/elf.h
24478 --- linux-2.6.20.3/include/asm-ia64/elf.h 2007-03-13 14:27:08.000000000 -0400
24479 +++ linux-2.6.20.3/include/asm-ia64/elf.h 2007-03-23 08:10:06.000000000 -0400
24480 @@ -162,6 +162,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
24481 typedef struct ia64_fpreg elf_fpreg_t;
24482 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
24484 +#ifdef CONFIG_PAX_ASLR
24485 +#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
24487 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
24488 +#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
24489 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
24490 +#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
24491 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
24492 +#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
24496 struct pt_regs; /* forward declaration... */
24497 diff -urNp linux-2.6.20.3/include/asm-ia64/kmap_types.h linux-2.6.20.3/include/asm-ia64/kmap_types.h
24498 --- linux-2.6.20.3/include/asm-ia64/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
24499 +++ linux-2.6.20.3/include/asm-ia64/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
24500 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
24505 +D(13) KM_CLEARPAGE,
24510 diff -urNp linux-2.6.20.3/include/asm-ia64/page.h linux-2.6.20.3/include/asm-ia64/page.h
24511 --- linux-2.6.20.3/include/asm-ia64/page.h 2007-03-13 14:27:08.000000000 -0400
24512 +++ linux-2.6.20.3/include/asm-ia64/page.h 2007-03-23 08:10:06.000000000 -0400
24513 @@ -226,5 +226,14 @@ get_order (unsigned long size)
24514 (((current->personality & READ_IMPLIES_EXEC) != 0) \
24517 +#ifdef CONFIG_PAX_PAGEEXEC
24518 +#ifdef CONFIG_PAX_MPROTECT
24519 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24520 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24522 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24526 # endif /* __KERNEL__ */
24527 #endif /* _ASM_IA64_PAGE_H */
24528 diff -urNp linux-2.6.20.3/include/asm-ia64/pgtable.h linux-2.6.20.3/include/asm-ia64/pgtable.h
24529 --- linux-2.6.20.3/include/asm-ia64/pgtable.h 2007-03-13 14:27:08.000000000 -0400
24530 +++ linux-2.6.20.3/include/asm-ia64/pgtable.h 2007-03-23 08:10:06.000000000 -0400
24531 @@ -143,6 +143,17 @@
24532 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
24533 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
24534 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
24536 +#ifdef CONFIG_PAX_PAGEEXEC
24537 +# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
24538 +# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
24539 +# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
24541 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
24542 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
24543 +# define PAGE_COPY_NOEXEC PAGE_COPY
24546 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
24547 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
24548 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
24549 diff -urNp linux-2.6.20.3/include/asm-ia64/processor.h linux-2.6.20.3/include/asm-ia64/processor.h
24550 --- linux-2.6.20.3/include/asm-ia64/processor.h 2007-03-13 14:27:08.000000000 -0400
24551 +++ linux-2.6.20.3/include/asm-ia64/processor.h 2007-03-23 08:10:06.000000000 -0400
24552 @@ -274,7 +274,7 @@ struct thread_struct {
24555 .map_base = DEFAULT_MAP_BASE, \
24556 - .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
24557 + .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \
24558 .task_size = DEFAULT_TASK_SIZE, \
24559 .last_fph_cpu = -1, \
24561 diff -urNp linux-2.6.20.3/include/asm-ia64/ustack.h linux-2.6.20.3/include/asm-ia64/ustack.h
24562 --- linux-2.6.20.3/include/asm-ia64/ustack.h 2007-03-13 14:27:08.000000000 -0400
24563 +++ linux-2.6.20.3/include/asm-ia64/ustack.h 2007-03-23 08:10:06.000000000 -0400
24564 @@ -10,10 +10,10 @@
24566 /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
24567 #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
24568 -#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
24569 +#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
24572 -/* Make a default stack size of 2GiB */
24573 +/* Make a default stack size of 2GB */
24574 #define DEFAULT_USER_STACK_SIZE (1UL << 31)
24576 #endif /* _ASM_IA64_USTACK_H */
24577 diff -urNp linux-2.6.20.3/include/asm-m32r/kmap_types.h linux-2.6.20.3/include/asm-m32r/kmap_types.h
24578 --- linux-2.6.20.3/include/asm-m32r/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
24579 +++ linux-2.6.20.3/include/asm-m32r/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
24580 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
24585 +D(13) KM_CLEARPAGE,
24590 diff -urNp linux-2.6.20.3/include/asm-m68k/kmap_types.h linux-2.6.20.3/include/asm-m68k/kmap_types.h
24591 --- linux-2.6.20.3/include/asm-m68k/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
24592 +++ linux-2.6.20.3/include/asm-m68k/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
24593 @@ -15,6 +15,7 @@ enum km_type {
24601 diff -urNp linux-2.6.20.3/include/asm-m68knommu/kmap_types.h linux-2.6.20.3/include/asm-m68knommu/kmap_types.h
24602 --- linux-2.6.20.3/include/asm-m68knommu/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
24603 +++ linux-2.6.20.3/include/asm-m68knommu/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
24604 @@ -15,6 +15,7 @@ enum km_type {
24612 diff -urNp linux-2.6.20.3/include/asm-mips/a.out.h linux-2.6.20.3/include/asm-mips/a.out.h
24613 --- linux-2.6.20.3/include/asm-mips/a.out.h 2007-03-13 14:27:08.000000000 -0400
24614 +++ linux-2.6.20.3/include/asm-mips/a.out.h 2007-03-23 08:10:06.000000000 -0400
24615 @@ -35,10 +35,10 @@ struct exec
24618 #ifdef CONFIG_32BIT
24619 -#define STACK_TOP TASK_SIZE
24620 +#define __STACK_TOP TASK_SIZE
24622 #ifdef CONFIG_64BIT
24623 -#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
24624 +#define __STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
24628 diff -urNp linux-2.6.20.3/include/asm-mips/elf.h linux-2.6.20.3/include/asm-mips/elf.h
24629 --- linux-2.6.20.3/include/asm-mips/elf.h 2007-03-13 14:27:08.000000000 -0400
24630 +++ linux-2.6.20.3/include/asm-mips/elf.h 2007-03-23 08:10:06.000000000 -0400
24631 @@ -371,4 +371,15 @@ extern int dump_task_fpu(struct task_str
24632 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
24635 +#ifdef CONFIG_PAX_ASLR
24636 +#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
24638 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
24639 +#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
24640 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
24641 +#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
24642 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
24643 +#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
24646 #endif /* _ASM_ELF_H */
24647 diff -urNp linux-2.6.20.3/include/asm-mips/kmap_types.h linux-2.6.20.3/include/asm-mips/kmap_types.h
24648 --- linux-2.6.20.3/include/asm-mips/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
24649 +++ linux-2.6.20.3/include/asm-mips/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
24650 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
24655 +D(13) KM_CLEARPAGE,
24660 diff -urNp linux-2.6.20.3/include/asm-mips/page.h linux-2.6.20.3/include/asm-mips/page.h
24661 --- linux-2.6.20.3/include/asm-mips/page.h 2007-03-13 14:27:08.000000000 -0400
24662 +++ linux-2.6.20.3/include/asm-mips/page.h 2007-03-23 08:10:06.000000000 -0400
24663 @@ -75,7 +75,7 @@ extern void copy_user_highpage(struct pa
24664 #ifdef CONFIG_CPU_MIPS32
24665 typedef struct { unsigned long pte_low, pte_high; } pte_t;
24666 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
24667 - #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
24668 + #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
24670 typedef struct { unsigned long long pte; } pte_t;
24671 #define pte_val(x) ((x).pte)
24672 @@ -170,6 +170,15 @@ typedef struct { unsigned long pgprot; }
24673 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
24674 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24676 +#ifdef CONFIG_PAX_PAGEEXEC
24677 +#ifdef CONFIG_PAX_MPROTECT
24678 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24679 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24681 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24685 #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
24686 #define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
24688 diff -urNp linux-2.6.20.3/include/asm-parisc/a.out.h linux-2.6.20.3/include/asm-parisc/a.out.h
24689 --- linux-2.6.20.3/include/asm-parisc/a.out.h 2007-03-13 14:27:08.000000000 -0400
24690 +++ linux-2.6.20.3/include/asm-parisc/a.out.h 2007-03-23 08:10:06.000000000 -0400
24691 @@ -22,7 +22,7 @@ struct exec
24692 /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
24695 -#define STACK_TOP TASK_SIZE
24696 +#define __STACK_TOP TASK_SIZE
24700 diff -urNp linux-2.6.20.3/include/asm-parisc/elf.h linux-2.6.20.3/include/asm-parisc/elf.h
24701 --- linux-2.6.20.3/include/asm-parisc/elf.h 2007-03-13 14:27:08.000000000 -0400
24702 +++ linux-2.6.20.3/include/asm-parisc/elf.h 2007-03-23 08:10:06.000000000 -0400
24703 @@ -337,6 +337,17 @@ struct pt_regs; /* forward declaration..
24705 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
24707 +#ifdef CONFIG_PAX_ASLR
24708 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
24710 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
24711 +#define PAX_DELTA_MMAP_LEN(tsk) 16
24712 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
24713 +#define PAX_DELTA_EXEC_LEN(tsk) 16
24714 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
24715 +#define PAX_DELTA_STACK_LEN(tsk) 16
24718 /* This yields a mask that user programs can use to figure out what
24719 instruction set this CPU supports. This could be done in user space,
24720 but it's not easy, and we've already done it here. */
24721 diff -urNp linux-2.6.20.3/include/asm-parisc/kmap_types.h linux-2.6.20.3/include/asm-parisc/kmap_types.h
24722 --- linux-2.6.20.3/include/asm-parisc/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
24723 +++ linux-2.6.20.3/include/asm-parisc/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
24724 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
24729 +D(13) KM_CLEARPAGE,
24734 diff -urNp linux-2.6.20.3/include/asm-parisc/page.h linux-2.6.20.3/include/asm-parisc/page.h
24735 --- linux-2.6.20.3/include/asm-parisc/page.h 2007-03-13 14:27:08.000000000 -0400
24736 +++ linux-2.6.20.3/include/asm-parisc/page.h 2007-03-23 08:10:06.000000000 -0400
24737 @@ -166,6 +166,15 @@ extern int npmem_ranges;
24738 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
24739 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24741 +#ifdef CONFIG_PAX_PAGEEXEC
24742 +#ifdef CONFIG_PAX_MPROTECT
24743 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24744 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24746 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24750 #include <asm-generic/memory_model.h>
24751 #include <asm-generic/page.h>
24753 diff -urNp linux-2.6.20.3/include/asm-parisc/pgtable.h linux-2.6.20.3/include/asm-parisc/pgtable.h
24754 --- linux-2.6.20.3/include/asm-parisc/pgtable.h 2007-03-13 14:27:08.000000000 -0400
24755 +++ linux-2.6.20.3/include/asm-parisc/pgtable.h 2007-03-23 08:10:06.000000000 -0400
24756 @@ -219,6 +219,17 @@ extern void *vmalloc_start;
24757 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
24758 #define PAGE_COPY PAGE_EXECREAD
24759 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
24761 +#ifdef CONFIG_PAX_PAGEEXEC
24762 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
24763 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
24764 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
24766 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
24767 +# define PAGE_COPY_NOEXEC PAGE_COPY
24768 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
24771 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
24772 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
24773 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
24774 diff -urNp linux-2.6.20.3/include/asm-powerpc/a.out.h linux-2.6.20.3/include/asm-powerpc/a.out.h
24775 --- linux-2.6.20.3/include/asm-powerpc/a.out.h 2007-03-13 14:27:08.000000000 -0400
24776 +++ linux-2.6.20.3/include/asm-powerpc/a.out.h 2007-03-23 08:10:06.000000000 -0400
24777 @@ -23,12 +23,12 @@ struct exec
24778 #define STACK_TOP_USER64 TASK_SIZE_USER64
24779 #define STACK_TOP_USER32 TASK_SIZE_USER32
24781 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
24782 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
24783 STACK_TOP_USER32 : STACK_TOP_USER64)
24785 #else /* __powerpc64__ */
24787 -#define STACK_TOP TASK_SIZE
24788 +#define __STACK_TOP TASK_SIZE
24790 #endif /* __powerpc64__ */
24791 #endif /* __KERNEL__ */
24792 diff -urNp linux-2.6.20.3/include/asm-powerpc/elf.h linux-2.6.20.3/include/asm-powerpc/elf.h
24793 --- linux-2.6.20.3/include/asm-powerpc/elf.h 2007-03-13 14:27:08.000000000 -0400
24794 +++ linux-2.6.20.3/include/asm-powerpc/elf.h 2007-03-23 08:10:06.000000000 -0400
24795 @@ -159,6 +159,26 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
24796 typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
24799 +#ifdef CONFIG_PAX_ASLR
24800 +#define PAX_ELF_ET_DYN_BASE(tsk) (0x10000000UL)
24802 +#ifdef __powerpc64__
24803 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
24804 +#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 16 : 28)
24805 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
24806 +#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 16 : 28)
24807 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
24808 +#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 16 : 28)
24810 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
24811 +#define PAX_DELTA_MMAP_LEN(tsk) 15
24812 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
24813 +#define PAX_DELTA_EXEC_LEN(tsk) 15
24814 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
24815 +#define PAX_DELTA_STACK_LEN(tsk) 15
24821 * This is used to ensure we don't load something for the wrong architecture.
24822 diff -urNp linux-2.6.20.3/include/asm-powerpc/kmap_types.h linux-2.6.20.3/include/asm-powerpc/kmap_types.h
24823 --- linux-2.6.20.3/include/asm-powerpc/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
24824 +++ linux-2.6.20.3/include/asm-powerpc/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
24825 @@ -26,6 +26,7 @@ enum km_type {
24828 KM_PPC_SYNC_ICACHE,
24833 diff -urNp linux-2.6.20.3/include/asm-powerpc/page_64.h linux-2.6.20.3/include/asm-powerpc/page_64.h
24834 --- linux-2.6.20.3/include/asm-powerpc/page_64.h 2007-03-13 14:27:08.000000000 -0400
24835 +++ linux-2.6.20.3/include/asm-powerpc/page_64.h 2007-03-23 08:10:06.000000000 -0400
24836 @@ -160,15 +160,18 @@ extern unsigned int HPAGE_SHIFT;
24837 * stack by default, so in the absense of a PT_GNU_STACK program header
24838 * we turn execute permission off.
24840 -#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
24841 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24842 +#define VM_STACK_DEFAULT_FLAGS32 \
24843 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
24844 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24846 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
24847 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24849 +#ifndef CONFIG_PAX_PAGEEXEC
24850 #define VM_STACK_DEFAULT_FLAGS \
24851 (test_thread_flag(TIF_32BIT) ? \
24852 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
24855 #include <asm-generic/page.h>
24857 diff -urNp linux-2.6.20.3/include/asm-powerpc/page.h linux-2.6.20.3/include/asm-powerpc/page.h
24858 --- linux-2.6.20.3/include/asm-powerpc/page.h 2007-03-13 14:27:08.000000000 -0400
24859 +++ linux-2.6.20.3/include/asm-powerpc/page.h 2007-03-23 08:10:06.000000000 -0400
24861 * and needs to be executable. This means the whole heap ends
24862 * up being executable.
24864 -#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
24865 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24866 +#define VM_DATA_DEFAULT_FLAGS32 \
24867 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
24868 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24870 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
24871 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24873 #include <asm/page_32.h>
24876 +#ifdef CONFIG_PAX_PAGEEXEC
24877 +#ifdef CONFIG_PAX_MPROTECT
24878 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24879 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24881 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24885 /* align addr on a size boundary - adjust address up/down if needed */
24886 #define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
24887 #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
24888 diff -urNp linux-2.6.20.3/include/asm-ppc/mmu_context.h linux-2.6.20.3/include/asm-ppc/mmu_context.h
24889 --- linux-2.6.20.3/include/asm-ppc/mmu_context.h 2007-03-13 14:27:08.000000000 -0400
24890 +++ linux-2.6.20.3/include/asm-ppc/mmu_context.h 2007-03-23 08:10:06.000000000 -0400
24891 @@ -144,7 +144,8 @@ static inline void get_mmu_context(struc
24892 static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
24894 mm->context.id = NO_CONTEXT;
24895 - mm->context.vdso_base = 0;
24896 + if (t == current)
24897 + mm->context.vdso_base = ~0UL;
24901 diff -urNp linux-2.6.20.3/include/asm-ppc/page.h linux-2.6.20.3/include/asm-ppc/page.h
24902 --- linux-2.6.20.3/include/asm-ppc/page.h 2007-03-13 14:27:08.000000000 -0400
24903 +++ linux-2.6.20.3/include/asm-ppc/page.h 2007-03-23 08:10:06.000000000 -0400
24904 @@ -173,6 +173,15 @@ extern __inline__ int get_order(unsigned
24905 /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
24906 #define __HAVE_ARCH_GATE_AREA 1
24908 +#ifdef CONFIG_PAX_PAGEEXEC
24909 +#ifdef CONFIG_PAX_MPROTECT
24910 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24911 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24913 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24917 #include <asm-generic/memory_model.h>
24918 #endif /* __KERNEL__ */
24919 #endif /* _PPC_PAGE_H */
24920 diff -urNp linux-2.6.20.3/include/asm-ppc/pgtable.h linux-2.6.20.3/include/asm-ppc/pgtable.h
24921 --- linux-2.6.20.3/include/asm-ppc/pgtable.h 2007-03-13 14:27:08.000000000 -0400
24922 +++ linux-2.6.20.3/include/asm-ppc/pgtable.h 2007-03-23 08:10:06.000000000 -0400
24923 @@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
24925 #define PAGE_NONE __pgprot(_PAGE_BASE)
24926 #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
24927 -#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
24928 +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
24929 #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
24930 -#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
24931 +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
24932 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
24933 -#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
24934 +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
24936 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
24937 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
24938 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
24939 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
24941 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
24942 +# define PAGE_COPY_NOEXEC PAGE_COPY
24943 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
24946 #define PAGE_KERNEL __pgprot(_PAGE_RAM)
24947 #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
24948 @@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
24949 * This is the closest we can get..
24951 #define __P000 PAGE_NONE
24952 -#define __P001 PAGE_READONLY_X
24953 -#define __P010 PAGE_COPY
24954 -#define __P011 PAGE_COPY_X
24955 -#define __P100 PAGE_READONLY
24956 +#define __P001 PAGE_READONLY_NOEXEC
24957 +#define __P010 PAGE_COPY_NOEXEC
24958 +#define __P011 PAGE_COPY_NOEXEC
24959 +#define __P100 PAGE_READONLY_X
24960 #define __P101 PAGE_READONLY_X
24961 -#define __P110 PAGE_COPY
24962 +#define __P110 PAGE_COPY_X
24963 #define __P111 PAGE_COPY_X
24965 #define __S000 PAGE_NONE
24966 -#define __S001 PAGE_READONLY_X
24967 -#define __S010 PAGE_SHARED
24968 -#define __S011 PAGE_SHARED_X
24969 -#define __S100 PAGE_READONLY
24970 +#define __S001 PAGE_READONLY_NOEXEC
24971 +#define __S010 PAGE_SHARED_NOEXEC
24972 +#define __S011 PAGE_SHARED_NOEXEC
24973 +#define __S100 PAGE_READONLY_X
24974 #define __S101 PAGE_READONLY_X
24975 -#define __S110 PAGE_SHARED
24976 +#define __S110 PAGE_SHARED_X
24977 #define __S111 PAGE_SHARED_X
24979 #ifndef __ASSEMBLY__
24980 diff -urNp linux-2.6.20.3/include/asm-s390/kmap_types.h linux-2.6.20.3/include/asm-s390/kmap_types.h
24981 --- linux-2.6.20.3/include/asm-s390/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
24982 +++ linux-2.6.20.3/include/asm-s390/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
24983 @@ -16,6 +16,7 @@ enum km_type {
24991 diff -urNp linux-2.6.20.3/include/asm-sh/kmap_types.h linux-2.6.20.3/include/asm-sh/kmap_types.h
24992 --- linux-2.6.20.3/include/asm-sh/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
24993 +++ linux-2.6.20.3/include/asm-sh/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
24994 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
24999 +D(13) KM_CLEARPAGE,
25004 diff -urNp linux-2.6.20.3/include/asm-sparc/a.out.h linux-2.6.20.3/include/asm-sparc/a.out.h
25005 --- linux-2.6.20.3/include/asm-sparc/a.out.h 2007-03-13 14:27:08.000000000 -0400
25006 +++ linux-2.6.20.3/include/asm-sparc/a.out.h 2007-03-23 08:10:06.000000000 -0400
25007 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
25009 #include <asm/page.h>
25011 -#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
25012 +#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
25014 #endif /* __KERNEL__ */
25016 diff -urNp linux-2.6.20.3/include/asm-sparc/elf.h linux-2.6.20.3/include/asm-sparc/elf.h
25017 --- linux-2.6.20.3/include/asm-sparc/elf.h 2007-03-13 14:27:08.000000000 -0400
25018 +++ linux-2.6.20.3/include/asm-sparc/elf.h 2007-03-23 08:10:06.000000000 -0400
25019 @@ -143,6 +143,17 @@ do { unsigned long *dest = &(__elf_regs[
25021 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
25023 +#ifdef CONFIG_PAX_ASLR
25024 +#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
25026 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
25027 +#define PAX_DELTA_MMAP_LEN(tsk) 16
25028 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
25029 +#define PAX_DELTA_EXEC_LEN(tsk) 16
25030 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
25031 +#define PAX_DELTA_STACK_LEN(tsk) 16
25034 /* This yields a mask that user programs can use to figure out what
25035 instruction set this cpu supports. This can NOT be done in userspace
25037 diff -urNp linux-2.6.20.3/include/asm-sparc/kmap_types.h linux-2.6.20.3/include/asm-sparc/kmap_types.h
25038 --- linux-2.6.20.3/include/asm-sparc/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
25039 +++ linux-2.6.20.3/include/asm-sparc/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
25040 @@ -15,6 +15,7 @@ enum km_type {
25048 diff -urNp linux-2.6.20.3/include/asm-sparc/page.h linux-2.6.20.3/include/asm-sparc/page.h
25049 --- linux-2.6.20.3/include/asm-sparc/page.h 2007-03-13 14:27:08.000000000 -0400
25050 +++ linux-2.6.20.3/include/asm-sparc/page.h 2007-03-23 08:10:06.000000000 -0400
25051 @@ -160,6 +160,15 @@ extern unsigned long pfn_base;
25052 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
25053 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
25055 +#ifdef CONFIG_PAX_PAGEEXEC
25056 +#ifdef CONFIG_PAX_MPROTECT
25057 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
25058 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25060 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25064 #include <asm-generic/memory_model.h>
25065 #include <asm-generic/page.h>
25067 diff -urNp linux-2.6.20.3/include/asm-sparc/pgtable.h linux-2.6.20.3/include/asm-sparc/pgtable.h
25068 --- linux-2.6.20.3/include/asm-sparc/pgtable.h 2007-03-13 14:27:08.000000000 -0400
25069 +++ linux-2.6.20.3/include/asm-sparc/pgtable.h 2007-03-23 08:10:06.000000000 -0400
25070 @@ -49,6 +49,13 @@ BTFIXUPDEF_INT(page_none)
25071 BTFIXUPDEF_INT(page_shared)
25072 BTFIXUPDEF_INT(page_copy)
25073 BTFIXUPDEF_INT(page_readonly)
25075 +#ifdef CONFIG_PAX_PAGEEXEC
25076 +BTFIXUPDEF_INT(page_shared_noexec)
25077 +BTFIXUPDEF_INT(page_copy_noexec)
25078 +BTFIXUPDEF_INT(page_readonly_noexec)
25081 BTFIXUPDEF_INT(page_kernel)
25083 #define PMD_SHIFT SUN4C_PMD_SHIFT
25084 @@ -70,6 +77,16 @@ BTFIXUPDEF_INT(page_kernel)
25085 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
25086 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
25088 +#ifdef CONFIG_PAX_PAGEEXEC
25089 +# define PAGE_SHARED_NOEXEC __pgprot(BTFIXUP_INT(page_shared_noexec))
25090 +# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
25091 +# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
25093 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
25094 +# define PAGE_COPY_NOEXEC PAGE_COPY
25095 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
25098 extern unsigned long page_kernel;
25101 diff -urNp linux-2.6.20.3/include/asm-sparc/pgtsrmmu.h linux-2.6.20.3/include/asm-sparc/pgtsrmmu.h
25102 --- linux-2.6.20.3/include/asm-sparc/pgtsrmmu.h 2007-03-13 14:27:08.000000000 -0400
25103 +++ linux-2.6.20.3/include/asm-sparc/pgtsrmmu.h 2007-03-23 08:10:06.000000000 -0400
25104 @@ -115,6 +115,16 @@
25105 SRMMU_EXEC | SRMMU_REF)
25106 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
25107 SRMMU_EXEC | SRMMU_REF)
25109 +#ifdef CONFIG_PAX_PAGEEXEC
25110 +#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
25111 + SRMMU_WRITE | SRMMU_REF)
25112 +#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
25114 +#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
25118 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
25119 SRMMU_DIRTY | SRMMU_REF)
25121 diff -urNp linux-2.6.20.3/include/asm-sparc/uaccess.h linux-2.6.20.3/include/asm-sparc/uaccess.h
25122 --- linux-2.6.20.3/include/asm-sparc/uaccess.h 2007-03-13 14:27:08.000000000 -0400
25123 +++ linux-2.6.20.3/include/asm-sparc/uaccess.h 2007-03-23 08:10:06.000000000 -0400
25125 * No one can read/write anything from userland in the kernel space by setting
25126 * large size and address near to PAGE_OFFSET - a fault will break his intentions.
25128 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
25129 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
25130 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
25131 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
25132 #define access_ok(type, addr, size) \
25133 diff -urNp linux-2.6.20.3/include/asm-sparc64/a.out.h linux-2.6.20.3/include/asm-sparc64/a.out.h
25134 --- linux-2.6.20.3/include/asm-sparc64/a.out.h 2007-03-13 14:27:08.000000000 -0400
25135 +++ linux-2.6.20.3/include/asm-sparc64/a.out.h 2007-03-23 08:10:06.000000000 -0400
25136 @@ -98,7 +98,7 @@ struct relocation_info /* used when head
25137 #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
25138 #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL))
25140 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
25141 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
25142 STACK_TOP32 : STACK_TOP64)
25145 diff -urNp linux-2.6.20.3/include/asm-sparc64/elf.h linux-2.6.20.3/include/asm-sparc64/elf.h
25146 --- linux-2.6.20.3/include/asm-sparc64/elf.h 2007-03-13 14:27:08.000000000 -0400
25147 +++ linux-2.6.20.3/include/asm-sparc64/elf.h 2007-03-23 08:10:06.000000000 -0400
25148 @@ -142,6 +142,16 @@ typedef struct {
25149 #define ELF_ET_DYN_BASE 0x0000010000000000UL
25152 +#ifdef CONFIG_PAX_ASLR
25153 +#define PAX_ELF_ET_DYN_BASE(tsk) (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
25155 +#define PAX_DELTA_MMAP_LSB(tsk) (PAGE_SHIFT + 1)
25156 +#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 14 : 28 )
25157 +#define PAX_DELTA_EXEC_LSB(tsk) (PAGE_SHIFT + 1)
25158 +#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 14 : 28 )
25159 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
25160 +#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 15 : 29 )
25163 /* This yields a mask that user programs can use to figure out what
25164 instruction set this cpu supports. */
25165 diff -urNp linux-2.6.20.3/include/asm-sparc64/kmap_types.h linux-2.6.20.3/include/asm-sparc64/kmap_types.h
25166 --- linux-2.6.20.3/include/asm-sparc64/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
25167 +++ linux-2.6.20.3/include/asm-sparc64/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
25168 @@ -19,6 +19,7 @@ enum km_type {
25176 diff -urNp linux-2.6.20.3/include/asm-sparc64/page.h linux-2.6.20.3/include/asm-sparc64/page.h
25177 --- linux-2.6.20.3/include/asm-sparc64/page.h 2007-03-13 14:27:08.000000000 -0400
25178 +++ linux-2.6.20.3/include/asm-sparc64/page.h 2007-03-23 08:10:06.000000000 -0400
25179 @@ -141,6 +141,15 @@ typedef unsigned long pgprot_t;
25180 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
25181 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
25183 +#ifdef CONFIG_PAX_PAGEEXEC
25184 +#ifdef CONFIG_PAX_MPROTECT
25185 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
25186 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25188 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25192 #include <asm-generic/page.h>
25194 #endif /* __KERNEL__ */
25195 diff -urNp linux-2.6.20.3/include/asm-v850/kmap_types.h linux-2.6.20.3/include/asm-v850/kmap_types.h
25196 --- linux-2.6.20.3/include/asm-v850/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
25197 +++ linux-2.6.20.3/include/asm-v850/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
25198 @@ -13,6 +13,7 @@ enum km_type {
25206 diff -urNp linux-2.6.20.3/include/asm-x86_64/a.out.h linux-2.6.20.3/include/asm-x86_64/a.out.h
25207 --- linux-2.6.20.3/include/asm-x86_64/a.out.h 2007-03-13 14:27:08.000000000 -0400
25208 +++ linux-2.6.20.3/include/asm-x86_64/a.out.h 2007-03-23 08:10:06.000000000 -0400
25209 @@ -21,7 +21,7 @@ struct exec
25212 #include <linux/thread_info.h>
25213 -#define STACK_TOP TASK_SIZE
25214 +#define __STACK_TOP TASK_SIZE
25217 #endif /* __A_OUT_GNU_H__ */
25218 diff -urNp linux-2.6.20.3/include/asm-x86_64/elf.h linux-2.6.20.3/include/asm-x86_64/elf.h
25219 --- linux-2.6.20.3/include/asm-x86_64/elf.h 2007-03-13 14:27:08.000000000 -0400
25220 +++ linux-2.6.20.3/include/asm-x86_64/elf.h 2007-03-23 08:10:06.000000000 -0400
25221 @@ -92,6 +92,17 @@ typedef struct user_i387_struct elf_fpre
25223 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
25225 +#ifdef CONFIG_PAX_ASLR
25226 +#define PAX_ELF_ET_DYN_BASE(tsk) (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
25228 +#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
25229 +#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 32)
25230 +#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
25231 +#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 32)
25232 +#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
25233 +#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 32)
25236 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
25237 now struct_user_regs, they are different). Assumes current is the process
25239 diff -urNp linux-2.6.20.3/include/asm-x86_64/ia32.h linux-2.6.20.3/include/asm-x86_64/ia32.h
25240 --- linux-2.6.20.3/include/asm-x86_64/ia32.h 2007-03-13 14:27:08.000000000 -0400
25241 +++ linux-2.6.20.3/include/asm-x86_64/ia32.h 2007-03-23 08:10:06.000000000 -0400
25242 @@ -156,7 +156,13 @@ struct ustat32 {
25246 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
25247 +#ifdef CONFIG_PAX_RANDUSTACK
25248 +#define IA32_DELTA_STACK (current->mm->delta_stack)
25250 +#define IA32_DELTA_STACK 0UL
25253 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
25257 diff -urNp linux-2.6.20.3/include/asm-x86_64/kmap_types.h linux-2.6.20.3/include/asm-x86_64/kmap_types.h
25258 --- linux-2.6.20.3/include/asm-x86_64/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
25259 +++ linux-2.6.20.3/include/asm-x86_64/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
25260 @@ -13,6 +13,7 @@ enum km_type {
25268 diff -urNp linux-2.6.20.3/include/asm-x86_64/page.h linux-2.6.20.3/include/asm-x86_64/page.h
25269 --- linux-2.6.20.3/include/asm-x86_64/page.h 2007-03-13 14:27:08.000000000 -0400
25270 +++ linux-2.6.20.3/include/asm-x86_64/page.h 2007-03-23 08:10:06.000000000 -0400
25271 @@ -88,6 +88,8 @@ typedef struct { unsigned long pgprot; }
25272 #define __PAGE_OFFSET 0xffff810000000000
25273 #endif /* !__ASSEMBLY__ */
25275 +#define __KERNEL_TEXT_OFFSET (0)
25277 /* to align the pointer to the (next) page boundary */
25278 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
25280 @@ -133,6 +135,15 @@ typedef struct { unsigned long pgprot; }
25281 (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
25282 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
25284 +#ifdef CONFIG_PAX_PAGEEXEC
25285 +#ifdef CONFIG_PAX_MPROTECT
25286 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
25287 + ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25289 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25293 #define __HAVE_ARCH_GATE_AREA 1
25295 #include <asm-generic/memory_model.h>
25296 diff -urNp linux-2.6.20.3/include/asm-x86_64/pgalloc.h linux-2.6.20.3/include/asm-x86_64/pgalloc.h
25297 --- linux-2.6.20.3/include/asm-x86_64/pgalloc.h 2007-03-13 14:27:08.000000000 -0400
25298 +++ linux-2.6.20.3/include/asm-x86_64/pgalloc.h 2007-03-23 08:10:06.000000000 -0400
25300 #include <linux/mm.h>
25302 #define pmd_populate_kernel(mm, pmd, pte) \
25303 - set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
25304 + set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
25305 #define pud_populate(mm, pud, pmd) \
25306 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
25307 #define pgd_populate(mm, pgd, pud) \
25308 diff -urNp linux-2.6.20.3/include/asm-x86_64/pgtable.h linux-2.6.20.3/include/asm-x86_64/pgtable.h
25309 --- linux-2.6.20.3/include/asm-x86_64/pgtable.h 2007-03-13 14:27:08.000000000 -0400
25310 +++ linux-2.6.20.3/include/asm-x86_64/pgtable.h 2007-03-23 08:10:06.000000000 -0400
25311 @@ -174,6 +174,10 @@ static inline pte_t ptep_get_and_clear_f
25312 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
25313 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
25314 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
25316 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
25317 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
25319 #define __PAGE_KERNEL \
25320 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
25321 #define __PAGE_KERNEL_EXEC \
25322 @@ -261,7 +265,15 @@ static inline pte_t pfn_pte(unsigned lon
25323 #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
25324 static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
25325 static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
25326 -static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); }
25328 +static inline int pte_exec(pte_t pte)
25330 + if (__supported_pte_mask & _PAGE_NX)
25331 + return pte_val(pte) & _PAGE_NX;
25333 + return pte_val(pte) & _PAGE_USER;
25336 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
25337 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
25338 static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
25339 @@ -269,12 +281,30 @@ static inline int pte_file(pte_t pte) {
25340 static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; }
25342 static inline pte_t pte_rdprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
25343 -static inline pte_t pte_exprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
25345 +static inline pte_t pte_exprotect(pte_t pte)
25347 + if (__supported_pte_mask & _PAGE_NX)
25348 + set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
25350 + set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
25354 static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
25355 static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
25356 static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
25357 static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
25358 -static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); return pte; }
25360 +extern inline pte_t pte_mkexec(pte_t pte)
25362 + if (__supported_pte_mask & _PAGE_NX)
25363 + set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
25365 + set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
25369 static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
25370 static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
25371 static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
25372 diff -urNp linux-2.6.20.3/include/asm-x86_64/system.h linux-2.6.20.3/include/asm-x86_64/system.h
25373 --- linux-2.6.20.3/include/asm-x86_64/system.h 2007-03-13 14:27:08.000000000 -0400
25374 +++ linux-2.6.20.3/include/asm-x86_64/system.h 2007-03-23 08:10:06.000000000 -0400
25375 @@ -248,7 +248,7 @@ static inline unsigned long __cmpxchg(vo
25377 void cpu_idle_wait(void);
25379 -extern unsigned long arch_align_stack(unsigned long sp);
25380 +#define arch_align_stack(x) (x)
25381 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
25384 diff -urNp linux-2.6.20.3/include/asm-xtensa/kmap_types.h linux-2.6.20.3/include/asm-xtensa/kmap_types.h
25385 --- linux-2.6.20.3/include/asm-xtensa/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
25386 +++ linux-2.6.20.3/include/asm-xtensa/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
25387 @@ -25,6 +25,7 @@ enum km_type {
25395 diff -urNp linux-2.6.20.3/include/linux/a.out.h linux-2.6.20.3/include/linux/a.out.h
25396 --- linux-2.6.20.3/include/linux/a.out.h 2007-03-13 14:27:08.000000000 -0400
25397 +++ linux-2.6.20.3/include/linux/a.out.h 2007-03-23 08:10:06.000000000 -0400
25400 #include <asm/a.out.h>
25402 +#ifdef CONFIG_PAX_RANDUSTACK
25403 +#define __DELTA_STACK (current->mm->delta_stack)
25405 +#define __DELTA_STACK 0UL
25409 +#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
25412 #endif /* __STRUCT_EXEC_OVERRIDE__ */
25414 /* these go in the N_MACHTYPE field */
25415 @@ -37,6 +47,14 @@ enum machine_type {
25416 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
25419 +/* Constants for the N_FLAGS field */
25420 +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
25421 +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
25422 +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
25423 +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
25424 +/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
25425 +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
25427 #if !defined (N_MAGIC)
25428 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
25430 diff -urNp linux-2.6.20.3/include/linux/binfmts.h linux-2.6.20.3/include/linux/binfmts.h
25431 --- linux-2.6.20.3/include/linux/binfmts.h 2007-03-13 14:27:08.000000000 -0400
25432 +++ linux-2.6.20.3/include/linux/binfmts.h 2007-03-23 08:10:06.000000000 -0400
25433 @@ -7,10 +7,10 @@ struct pt_regs;
25436 * MAX_ARG_PAGES defines the number of pages allocated for arguments
25437 - * and envelope for the new program. 32 should suffice, this gives
25438 - * a maximum env+arg of 128kB w/4KB pages!
25439 + * and envelope for the new program. 33 should suffice, this gives
25440 + * a maximum env+arg of 132kB w/4KB pages!
25442 -#define MAX_ARG_PAGES 32
25443 +#define MAX_ARG_PAGES 33
25445 /* sizeof(linux_binprm->buf) */
25446 #define BINPRM_BUF_SIZE 128
25447 @@ -38,6 +38,7 @@ struct linux_binprm{
25448 unsigned interp_flags;
25449 unsigned interp_data;
25450 unsigned long loader, exec;
25454 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
25455 @@ -88,5 +89,8 @@ extern void compute_creds(struct linux_b
25456 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
25457 extern int set_binfmt(struct linux_binfmt *new);
25459 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
25460 +void pax_report_insns(void *pc, void *sp);
25462 #endif /* __KERNEL__ */
25463 #endif /* _LINUX_BINFMTS_H */
25464 diff -urNp linux-2.6.20.3/include/linux/capability.h linux-2.6.20.3/include/linux/capability.h
25465 --- linux-2.6.20.3/include/linux/capability.h 2007-03-13 14:27:08.000000000 -0400
25466 +++ linux-2.6.20.3/include/linux/capability.h 2007-03-23 08:11:31.000000000 -0400
25467 @@ -358,6 +358,7 @@ static inline kernel_cap_t cap_invert(ke
25468 #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK)
25470 int capable(int cap);
25471 +int capable_nolog(int cap);
25472 int __capable(struct task_struct *t, int cap);
25474 #endif /* __KERNEL__ */
25475 diff -urNp linux-2.6.20.3/include/linux/elf.h linux-2.6.20.3/include/linux/elf.h
25476 --- linux-2.6.20.3/include/linux/elf.h 2007-03-13 14:27:08.000000000 -0400
25477 +++ linux-2.6.20.3/include/linux/elf.h 2007-03-23 08:10:06.000000000 -0400
25482 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
25483 +#undef elf_read_implies_exec
25486 #ifndef elf_read_implies_exec
25487 /* Executables for which elf_read_implies_exec() returns TRUE will
25488 have the READ_IMPLIES_EXEC personality flag set automatically.
25489 @@ -49,6 +53,16 @@ typedef __s64 Elf64_Sxword;
25491 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
25493 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
25495 +/* Constants for the e_flags field */
25496 +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
25497 +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
25498 +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
25499 +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
25500 +/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
25501 +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
25503 /* These constants define the different elf file types */
25506 @@ -83,6 +97,8 @@ typedef __s64 Elf64_Sxword;
25507 #define DT_DEBUG 21
25508 #define DT_TEXTREL 22
25509 #define DT_JMPREL 23
25510 +#define DT_FLAGS 30
25511 + #define DF_TEXTREL 0x00000004
25512 #define DT_LOPROC 0x70000000
25513 #define DT_HIPROC 0x7fffffff
25515 @@ -212,6 +228,19 @@ typedef struct elf64_hdr {
25519 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
25520 +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
25521 +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
25522 +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
25523 +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
25524 +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
25525 +/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
25526 +/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
25527 +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
25528 +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
25529 +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
25530 +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
25532 typedef struct elf32_phdr{
25534 Elf32_Off p_offset;
25535 @@ -304,6 +333,8 @@ typedef struct elf64_shdr {
25541 #define ELFMAG0 0x7f /* EI_MAG */
25542 #define ELFMAG1 'E'
25543 #define ELFMAG2 'L'
25544 @@ -361,6 +392,7 @@ extern Elf32_Dyn _DYNAMIC [];
25545 #define elf_phdr elf32_phdr
25546 #define elf_note elf32_note
25547 #define elf_addr_t Elf32_Off
25548 +#define elf_dyn Elf32_Dyn
25552 @@ -369,6 +401,7 @@ extern Elf64_Dyn _DYNAMIC [];
25553 #define elf_phdr elf64_phdr
25554 #define elf_note elf64_note
25555 #define elf_addr_t Elf64_Off
25556 +#define elf_dyn Elf64_Dyn
25560 diff -urNp linux-2.6.20.3/include/linux/ext4_fs_extents.h linux-2.6.20.3/include/linux/ext4_fs_extents.h
25561 --- linux-2.6.20.3/include/linux/ext4_fs_extents.h 2007-03-13 14:27:08.000000000 -0400
25562 +++ linux-2.6.20.3/include/linux/ext4_fs_extents.h 2007-03-23 08:10:06.000000000 -0400
25565 #define ext_debug(a...) printk(a)
25567 -#define ext_debug(a...)
25568 +#define ext_debug(a...) do {} while (0)
25572 diff -urNp linux-2.6.20.3/include/linux/gracl.h linux-2.6.20.3/include/linux/gracl.h
25573 --- linux-2.6.20.3/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
25574 +++ linux-2.6.20.3/include/linux/gracl.h 2007-03-23 08:11:31.000000000 -0400
25579 +#include <linux/grdefs.h>
25580 +#include <linux/resource.h>
25581 +#include <linux/dcache.h>
25582 +#include <asm/resource.h>
25584 +/* Major status information */
25586 +#define GR_VERSION "grsecurity 2.1.10"
25587 +#define GRSECURITY_VERSION 0x2110
25602 +/* Password setup definitions
25603 + * kernel/grhash.c */
25606 + GR_SALT_LEN = 16,
25611 + GR_SPROLE_LEN = 64,
25614 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
25616 +/* Begin Data Structures */
25618 +struct sprole_pw {
25619 + unsigned char *rolename;
25620 + unsigned char salt[GR_SALT_LEN];
25621 + unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
25624 +struct name_entry {
25630 + struct name_entry *prev;
25631 + struct name_entry *next;
25634 +struct inodev_entry {
25635 + struct name_entry *nentry;
25636 + struct inodev_entry *prev;
25637 + struct inodev_entry *next;
25640 +struct acl_role_db {
25641 + struct acl_role_label **r_hash;
25645 +struct inodev_db {
25646 + struct inodev_entry **i_hash;
25651 + struct name_entry **n_hash;
25655 +struct crash_uid {
25657 + unsigned long expires;
25660 +struct gr_hash_struct {
25662 + void **nametable;
25664 + __u32 table_size;
25669 +/* Userspace Grsecurity ACL data structures */
25671 +struct acl_subject_label {
25679 + struct rlimit res[GR_NLIMITS];
25682 + __u8 user_trans_type;
25683 + __u8 group_trans_type;
25684 + uid_t *user_transitions;
25685 + gid_t *group_transitions;
25686 + __u16 user_trans_num;
25687 + __u16 group_trans_num;
25689 + __u32 ip_proto[8];
25691 + struct acl_ip_label **ips;
25695 + unsigned long expires;
25697 + struct acl_subject_label *parent_subject;
25698 + struct gr_hash_struct *hash;
25699 + struct acl_subject_label *prev;
25700 + struct acl_subject_label *next;
25702 + struct acl_object_label **obj_hash;
25703 + __u32 obj_hash_size;
25707 +struct role_allowed_ip {
25711 + struct role_allowed_ip *prev;
25712 + struct role_allowed_ip *next;
25715 +struct role_transition {
25718 + struct role_transition *prev;
25719 + struct role_transition *next;
25722 +struct acl_role_label {
25727 + __u16 auth_attempts;
25728 + unsigned long expires;
25730 + struct acl_subject_label *root_label;
25731 + struct gr_hash_struct *hash;
25733 + struct acl_role_label *prev;
25734 + struct acl_role_label *next;
25736 + struct role_transition *transitions;
25737 + struct role_allowed_ip *allowed_ips;
25738 + uid_t *domain_children;
25739 + __u16 domain_child_num;
25741 + struct acl_subject_label **subj_hash;
25742 + __u32 subj_hash_size;
25745 +struct user_acl_role_db {
25746 + struct acl_role_label **r_table;
25747 + __u32 num_pointers; /* Number of allocations to track */
25748 + __u32 num_roles; /* Number of roles */
25749 + __u32 num_domain_children; /* Number of domain children */
25750 + __u32 num_subjects; /* Number of subjects */
25751 + __u32 num_objects; /* Number of objects */
25754 +struct acl_object_label {
25760 + struct acl_subject_label *nested;
25761 + struct acl_object_label *globbed;
25763 + /* next two structures not used */
25765 + struct acl_object_label *prev;
25766 + struct acl_object_label *next;
25769 +struct acl_ip_label {
25778 + /* next two structures not used */
25780 + struct acl_ip_label *prev;
25781 + struct acl_ip_label *next;
25785 + struct user_acl_role_db role_db;
25786 + unsigned char pw[GR_PW_LEN];
25787 + unsigned char salt[GR_SALT_LEN];
25788 + unsigned char sum[GR_SHA_LEN];
25789 + unsigned char sp_role[GR_SPROLE_LEN];
25790 + struct sprole_pw *sprole_pws;
25791 + dev_t segv_device;
25792 + ino_t segv_inode;
25794 + __u16 num_sprole_pws;
25798 +struct gr_arg_wrapper {
25799 + struct gr_arg *arg;
25804 +struct subject_map {
25805 + struct acl_subject_label *user;
25806 + struct acl_subject_label *kernel;
25807 + struct subject_map *prev;
25808 + struct subject_map *next;
25811 +struct acl_subj_map_db {
25812 + struct subject_map **s_hash;
25816 +/* End Data Structures Section */
25818 +/* Hash functions generated by empirical testing by Brad Spengler
25819 + Makes good use of the low bits of the inode. Generally 0-1 times
25820 + in loop for successful match. 0-3 for unsuccessful match.
25821 + Shift/add algorithm with modulus of table size and an XOR*/
25823 +static __inline__ unsigned int
25824 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
25826 + return (((uid << type) + (uid ^ type)) % sz);
25829 + static __inline__ unsigned int
25830 +shash(const struct acl_subject_label *userp, const unsigned int sz)
25832 + return ((const unsigned long)userp % sz);
25835 +static __inline__ unsigned int
25836 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
25838 + return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
25841 +static __inline__ unsigned int
25842 +nhash(const char *name, const __u16 len, const unsigned int sz)
25844 + return full_name_hash(name, len) % sz;
25847 +#define FOR_EACH_ROLE_START(role,iter) \
25850 + while (iter < acl_role_set.r_size) { \
25851 + if (role == NULL) \
25852 + role = acl_role_set.r_hash[iter]; \
25853 + if (role == NULL) { \
25858 +#define FOR_EACH_ROLE_END(role,iter) \
25859 + role = role->next; \
25860 + if (role == NULL) \
25864 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
25867 + while (iter < role->subj_hash_size) { \
25868 + if (subj == NULL) \
25869 + subj = role->subj_hash[iter]; \
25870 + if (subj == NULL) { \
25875 +#define FOR_EACH_SUBJECT_END(subj,iter) \
25876 + subj = subj->next; \
25877 + if (subj == NULL) \
25882 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
25883 + subj = role->hash->first; \
25884 + while (subj != NULL) {
25886 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
25887 + subj = subj->next; \
25892 diff -urNp linux-2.6.20.3/include/linux/gralloc.h linux-2.6.20.3/include/linux/gralloc.h
25893 --- linux-2.6.20.3/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
25894 +++ linux-2.6.20.3/include/linux/gralloc.h 2007-03-23 08:11:31.000000000 -0400
25896 +#ifndef __GRALLOC_H
25897 +#define __GRALLOC_H
25899 +void acl_free_all(void);
25900 +int acl_alloc_stack_init(unsigned long size);
25901 +void *acl_alloc(unsigned long len);
25904 diff -urNp linux-2.6.20.3/include/linux/grdefs.h linux-2.6.20.3/include/linux/grdefs.h
25905 --- linux-2.6.20.3/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
25906 +++ linux-2.6.20.3/include/linux/grdefs.h 2007-03-23 08:11:31.000000000 -0400
25911 +/* Begin grsecurity status declarations */
25915 + GR_STATUS_INIT = 0x00 // disabled state
25918 +/* Begin ACL declarations */
25923 + GR_ROLE_USER = 0x0001,
25924 + GR_ROLE_GROUP = 0x0002,
25925 + GR_ROLE_DEFAULT = 0x0004,
25926 + GR_ROLE_SPECIAL = 0x0008,
25927 + GR_ROLE_AUTH = 0x0010,
25928 + GR_ROLE_NOPW = 0x0020,
25929 + GR_ROLE_GOD = 0x0040,
25930 + GR_ROLE_LEARN = 0x0080,
25931 + GR_ROLE_TPE = 0x0100,
25932 + GR_ROLE_DOMAIN = 0x0200,
25933 + GR_ROLE_PAM = 0x0400
25936 +/* ACL Subject and Object mode flags */
25938 + GR_DELETED = 0x80000000
25941 +/* ACL Object-only mode flags */
25943 + GR_READ = 0x00000001,
25944 + GR_APPEND = 0x00000002,
25945 + GR_WRITE = 0x00000004,
25946 + GR_EXEC = 0x00000008,
25947 + GR_FIND = 0x00000010,
25948 + GR_INHERIT = 0x00000020,
25949 + GR_SETID = 0x00000040,
25950 + GR_CREATE = 0x00000080,
25951 + GR_DELETE = 0x00000100,
25952 + GR_LINK = 0x00000200,
25953 + GR_AUDIT_READ = 0x00000400,
25954 + GR_AUDIT_APPEND = 0x00000800,
25955 + GR_AUDIT_WRITE = 0x00001000,
25956 + GR_AUDIT_EXEC = 0x00002000,
25957 + GR_AUDIT_FIND = 0x00004000,
25958 + GR_AUDIT_INHERIT= 0x00008000,
25959 + GR_AUDIT_SETID = 0x00010000,
25960 + GR_AUDIT_CREATE = 0x00020000,
25961 + GR_AUDIT_DELETE = 0x00040000,
25962 + GR_AUDIT_LINK = 0x00080000,
25963 + GR_PTRACERD = 0x00100000,
25964 + GR_NOPTRACE = 0x00200000,
25965 + GR_SUPPRESS = 0x00400000,
25966 + GR_NOLEARN = 0x00800000
25969 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
25970 + GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
25971 + GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
25973 +/* ACL subject-only mode flags */
25975 + GR_KILL = 0x00000001,
25976 + GR_VIEW = 0x00000002,
25977 + GR_PROTECTED = 0x00000004,
25978 + GR_LEARN = 0x00000008,
25979 + GR_OVERRIDE = 0x00000010,
25980 + /* just a placeholder, this mode is only used in userspace */
25981 + GR_DUMMY = 0x00000020,
25982 + GR_PROTSHM = 0x00000040,
25983 + GR_KILLPROC = 0x00000080,
25984 + GR_KILLIPPROC = 0x00000100,
25985 + /* just a placeholder, this mode is only used in userspace */
25986 + GR_NOTROJAN = 0x00000200,
25987 + GR_PROTPROCFD = 0x00000400,
25988 + GR_PROCACCT = 0x00000800,
25989 + GR_RELAXPTRACE = 0x00001000,
25990 + GR_NESTED = 0x00002000,
25991 + GR_INHERITLEARN = 0x00004000,
25992 + GR_PROCFIND = 0x00008000,
25993 + GR_POVERRIDE = 0x00010000,
25994 + GR_KERNELAUTH = 0x00020000,
25998 + GR_PAX_ENABLE_SEGMEXEC = 0x0001,
25999 + GR_PAX_ENABLE_PAGEEXEC = 0x0002,
26000 + GR_PAX_ENABLE_MPROTECT = 0x0004,
26001 + GR_PAX_ENABLE_RANDMMAP = 0x0008,
26002 + GR_PAX_ENABLE_EMUTRAMP = 0x0010,
26003 + GR_PAX_DISABLE_SEGMEXEC = 0x0100,
26004 + GR_PAX_DISABLE_PAGEEXEC = 0x0200,
26005 + GR_PAX_DISABLE_MPROTECT = 0x0400,
26006 + GR_PAX_DISABLE_RANDMMAP = 0x0800,
26007 + GR_PAX_DISABLE_EMUTRAMP = 0x1000,
26011 + GR_ID_USER = 0x01,
26012 + GR_ID_GROUP = 0x02,
26016 + GR_ID_ALLOW = 0x01,
26017 + GR_ID_DENY = 0x02,
26020 +#define GR_CRASH_RES 11
26021 +#define GR_UIDTABLE_MAX 500
26023 +/* begin resource learning section */
26025 + GR_RLIM_CPU_BUMP = 60,
26026 + GR_RLIM_FSIZE_BUMP = 50000,
26027 + GR_RLIM_DATA_BUMP = 10000,
26028 + GR_RLIM_STACK_BUMP = 1000,
26029 + GR_RLIM_CORE_BUMP = 10000,
26030 + GR_RLIM_RSS_BUMP = 500000,
26031 + GR_RLIM_NPROC_BUMP = 1,
26032 + GR_RLIM_NOFILE_BUMP = 5,
26033 + GR_RLIM_MEMLOCK_BUMP = 50000,
26034 + GR_RLIM_AS_BUMP = 500000,
26035 + GR_RLIM_LOCKS_BUMP = 2
26039 diff -urNp linux-2.6.20.3/include/linux/grinternal.h linux-2.6.20.3/include/linux/grinternal.h
26040 --- linux-2.6.20.3/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
26041 +++ linux-2.6.20.3/include/linux/grinternal.h 2007-03-23 08:11:31.000000000 -0400
26043 +#ifndef __GRINTERNAL_H
26044 +#define __GRINTERNAL_H
26046 +#ifdef CONFIG_GRKERNSEC
26048 +#include <linux/fs.h>
26049 +#include <linux/gracl.h>
26050 +#include <linux/grdefs.h>
26051 +#include <linux/grmsg.h>
26053 +void gr_add_learn_entry(const char *fmt, ...);
26054 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
26055 + const struct vfsmount *mnt);
26056 +__u32 gr_check_create(const struct dentry *new_dentry,
26057 + const struct dentry *parent,
26058 + const struct vfsmount *mnt, const __u32 mode);
26059 +int gr_check_protected_task(const struct task_struct *task);
26060 +__u32 to_gr_audit(const __u32 reqmode);
26061 +int gr_set_acls(const int type);
26063 +int gr_acl_is_enabled(void);
26064 +char gr_roletype_to_char(void);
26066 +void gr_handle_alertkill(struct task_struct *task);
26067 +char *gr_to_filename(const struct dentry *dentry,
26068 + const struct vfsmount *mnt);
26069 +char *gr_to_filename1(const struct dentry *dentry,
26070 + const struct vfsmount *mnt);
26071 +char *gr_to_filename2(const struct dentry *dentry,
26072 + const struct vfsmount *mnt);
26073 +char *gr_to_filename3(const struct dentry *dentry,
26074 + const struct vfsmount *mnt);
26076 +extern int grsec_enable_link;
26077 +extern int grsec_enable_fifo;
26078 +extern int grsec_enable_execve;
26079 +extern int grsec_enable_shm;
26080 +extern int grsec_enable_execlog;
26081 +extern int grsec_enable_signal;
26082 +extern int grsec_enable_forkfail;
26083 +extern int grsec_enable_time;
26084 +extern int grsec_enable_chroot_shmat;
26085 +extern int grsec_enable_chroot_findtask;
26086 +extern int grsec_enable_chroot_mount;
26087 +extern int grsec_enable_chroot_double;
26088 +extern int grsec_enable_chroot_pivot;
26089 +extern int grsec_enable_chroot_chdir;
26090 +extern int grsec_enable_chroot_chmod;
26091 +extern int grsec_enable_chroot_mknod;
26092 +extern int grsec_enable_chroot_fchdir;
26093 +extern int grsec_enable_chroot_nice;
26094 +extern int grsec_enable_chroot_execlog;
26095 +extern int grsec_enable_chroot_caps;
26096 +extern int grsec_enable_chroot_sysctl;
26097 +extern int grsec_enable_chroot_unix;
26098 +extern int grsec_enable_tpe;
26099 +extern int grsec_tpe_gid;
26100 +extern int grsec_enable_tpe_all;
26101 +extern int grsec_enable_sidcaps;
26102 +extern int grsec_enable_socket_all;
26103 +extern int grsec_socket_all_gid;
26104 +extern int grsec_enable_socket_client;
26105 +extern int grsec_socket_client_gid;
26106 +extern int grsec_enable_socket_server;
26107 +extern int grsec_socket_server_gid;
26108 +extern int grsec_audit_gid;
26109 +extern int grsec_enable_group;
26110 +extern int grsec_enable_audit_ipc;
26111 +extern int grsec_enable_audit_textrel;
26112 +extern int grsec_enable_mount;
26113 +extern int grsec_enable_chdir;
26114 +extern int grsec_resource_logging;
26115 +extern int grsec_lock;
26117 +extern spinlock_t grsec_alert_lock;
26118 +extern unsigned long grsec_alert_wtime;
26119 +extern unsigned long grsec_alert_fyet;
26121 +extern spinlock_t grsec_audit_lock;
26123 +extern rwlock_t grsec_exec_file_lock;
26125 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
26126 + gr_to_filename2(tsk->exec_file->f_dentry, \
26127 + tsk->exec_file->f_vfsmnt) : "/")
26129 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
26130 + gr_to_filename3(tsk->parent->exec_file->f_dentry, \
26131 + tsk->parent->exec_file->f_vfsmnt) : "/")
26133 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
26134 + gr_to_filename(tsk->exec_file->f_dentry, \
26135 + tsk->exec_file->f_vfsmnt) : "/")
26137 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
26138 + gr_to_filename1(tsk->parent->exec_file->f_dentry, \
26139 + tsk->parent->exec_file->f_vfsmnt) : "/")
26141 +#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
26142 + ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
26143 + child_reaper(tsk_a)->fs->root->d_inode->i_sb->s_dev) || \
26144 + (tsk_a->fs->root->d_inode->i_ino != \
26145 + child_reaper(tsk_a)->fs->root->d_inode->i_ino)))
26147 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
26148 + (tsk_a->fs->root->d_inode->i_sb->s_dev == \
26149 + tsk_b->fs->root->d_inode->i_sb->s_dev) && \
26150 + (tsk_a->fs->root->d_inode->i_ino == \
26151 + tsk_b->fs->root->d_inode->i_ino))
26153 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
26154 + task->pid, task->uid, \
26155 + task->euid, task->gid, task->egid, \
26156 + gr_parent_task_fullpath(task), \
26157 + task->parent->comm, task->parent->pid, \
26158 + task->parent->uid, task->parent->euid, \
26159 + task->parent->gid, task->parent->egid
26161 +#define GR_CHROOT_CAPS ( \
26162 + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
26163 + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
26164 + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
26165 + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
26166 + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
26167 + CAP_TO_MASK(CAP_IPC_OWNER))
26169 +#define security_learn(normal_msg,args...) \
26171 + read_lock(&grsec_exec_file_lock); \
26172 + gr_add_learn_entry(normal_msg "\n", ## args); \
26173 + read_unlock(&grsec_exec_file_lock); \
26179 + GR_DONT_AUDIT_GOOD
26192 + GR_ONE_INT_TWO_STR,
26197 + GR_FIVE_INT_TWO_STR,
26203 + GR_FILENAME_TWO_INT,
26204 + GR_FILENAME_TWO_INT_STR,
26215 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
26216 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
26217 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
26218 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
26219 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
26220 +#define gr_log_fs_rbac_mode3(audit, msg, dentry, mnt, str1, str2, str3) gr_log_varargs(audit, msg, GR_RBAC_MODE3, dentry, mnt, str1, str2, str3)
26221 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
26222 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
26223 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
26224 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
26225 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
26226 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
26227 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
26228 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
26229 +#define gr_log_int5_str2(audit, msg, num1, num2, str1, str2) gr_log_varargs(audit, msg, GR_FIVE_INT_TWO_STR, num1, num2, str1, str2)
26230 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
26231 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
26232 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
26233 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
26234 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
26235 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
26236 +#define gr_log_fs_int2_str(audit, msg, dentry, mnt, num1, num2, str) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT_STR, dentry, mnt, num1, num2, str)
26237 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
26238 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
26239 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
26240 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
26241 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
26242 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
26243 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
26244 +#define gr_log_procacct(audit, msg, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) gr_log_varargs(audit, msg, GR_PSACCT, task, num1, num2, num3, num4, num5, num6, num7, num8, num9)
26246 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
26251 diff -urNp linux-2.6.20.3/include/linux/grmsg.h linux-2.6.20.3/include/linux/grmsg.h
26252 --- linux-2.6.20.3/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
26253 +++ linux-2.6.20.3/include/linux/grmsg.h 2007-03-23 08:11:31.000000000 -0400
26255 +#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u"
26256 +#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u"
26257 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
26258 +#define GR_STOPMOD_MSG "denied modification of module state by "
26259 +#define GR_IOPERM_MSG "denied use of ioperm() by "
26260 +#define GR_IOPL_MSG "denied use of iopl() by "
26261 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
26262 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
26263 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
26264 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
26265 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
26266 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
26267 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
26268 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
26269 +#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"
26270 +#define GR_ID_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%c\t%d\t%d\t%d\t%u.%u.%u.%u"
26271 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
26272 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
26273 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
26274 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
26275 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
26276 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
26277 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
26278 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
26279 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
26280 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
26281 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
26282 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
26283 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
26284 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
26285 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
26286 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
26287 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
26288 +#define GR_NPROC_MSG "denied overstep of process limit by "
26289 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
26290 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
26291 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
26292 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
26293 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
26294 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
26295 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
26296 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
26297 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
26298 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
26299 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
26300 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
26301 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
26302 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
26303 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
26304 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
26305 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
26306 +#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"
26307 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
26308 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
26309 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
26310 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
26311 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
26312 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
26313 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
26314 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
26315 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
26316 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
26317 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
26318 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
26319 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
26320 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
26321 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
26322 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
26323 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
26324 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
26325 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
26326 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
26327 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
26328 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
26329 +#define GR_NICE_CHROOT_MSG "denied priority change by "
26330 +#define GR_UNISIGLOG_MSG "signal %d sent to "
26331 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
26332 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
26333 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
26334 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
26335 +#define GR_TIME_MSG "time set by "
26336 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
26337 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
26338 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
26339 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
26340 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
26341 +#define GR_BIND_MSG "denied bind() by "
26342 +#define GR_CONNECT_MSG "denied connect() by "
26343 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
26344 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
26345 +#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"
26346 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
26347 +#define GR_CAP_ACL_MSG "use of %s denied for "
26348 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
26349 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
26350 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
26351 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
26352 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
26353 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
26354 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
26355 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
26356 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
26357 +#define GR_SEM_AUDIT_MSG "semaphore created by "
26358 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
26359 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
26360 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
26361 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
26362 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
26363 diff -urNp linux-2.6.20.3/include/linux/grsecurity.h linux-2.6.20.3/include/linux/grsecurity.h
26364 --- linux-2.6.20.3/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
26365 +++ linux-2.6.20.3/include/linux/grsecurity.h 2007-03-23 08:11:31.000000000 -0400
26367 +#ifndef GR_SECURITY_H
26368 +#define GR_SECURITY_H
26369 +#include <linux/fs.h>
26370 +#include <linux/binfmts.h>
26371 +#include <linux/gracl.h>
26373 +void gr_handle_brute_attach(struct task_struct *p);
26374 +void gr_handle_brute_check(void);
26376 +char gr_roletype_to_char(void);
26378 +int gr_check_user_change(int real, int effective, int fs);
26379 +int gr_check_group_change(int real, int effective, int fs);
26381 +void gr_del_task_from_ip_table(struct task_struct *p);
26383 +int gr_pid_is_chrooted(struct task_struct *p);
26384 +int gr_handle_chroot_nice(void);
26385 +int gr_handle_chroot_sysctl(const int op);
26386 +int gr_handle_chroot_setpriority(struct task_struct *p,
26387 + const int niceval);
26388 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
26389 +int gr_handle_chroot_chroot(const struct dentry *dentry,
26390 + const struct vfsmount *mnt);
26391 +void gr_handle_chroot_caps(struct task_struct *task);
26392 +void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
26393 +int gr_handle_chroot_chmod(const struct dentry *dentry,
26394 + const struct vfsmount *mnt, const int mode);
26395 +int gr_handle_chroot_mknod(const struct dentry *dentry,
26396 + const struct vfsmount *mnt, const int mode);
26397 +int gr_handle_chroot_mount(const struct dentry *dentry,
26398 + const struct vfsmount *mnt,
26399 + const char *dev_name);
26400 +int gr_handle_chroot_pivot(void);
26401 +int gr_handle_chroot_unix(const pid_t pid);
26403 +int gr_handle_rawio(const struct inode *inode);
26404 +int gr_handle_nproc(void);
26406 +void gr_handle_ioperm(void);
26407 +void gr_handle_iopl(void);
26409 +int gr_tpe_allow(const struct file *file);
26411 +int gr_random_pid(void);
26413 +void gr_log_forkfail(const int retval);
26414 +void gr_log_timechange(void);
26415 +void gr_log_signal(const int sig, const struct task_struct *t);
26416 +void gr_log_chdir(const struct dentry *dentry,
26417 + const struct vfsmount *mnt);
26418 +void gr_log_chroot_exec(const struct dentry *dentry,
26419 + const struct vfsmount *mnt);
26420 +void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
26421 +void gr_log_remount(const char *devname, const int retval);
26422 +void gr_log_unmount(const char *devname, const int retval);
26423 +void gr_log_mount(const char *from, const char *to, const int retval);
26424 +void gr_log_msgget(const int ret, const int msgflg);
26425 +void gr_log_msgrm(const uid_t uid, const uid_t cuid);
26426 +void gr_log_semget(const int err, const int semflg);
26427 +void gr_log_semrm(const uid_t uid, const uid_t cuid);
26428 +void gr_log_shmget(const int err, const int shmflg, const size_t size);
26429 +void gr_log_shmrm(const uid_t uid, const uid_t cuid);
26430 +void gr_log_textrel(struct vm_area_struct *vma);
26432 +int gr_handle_follow_link(const struct inode *parent,
26433 + const struct inode *inode,
26434 + const struct dentry *dentry,
26435 + const struct vfsmount *mnt);
26436 +int gr_handle_fifo(const struct dentry *dentry,
26437 + const struct vfsmount *mnt,
26438 + const struct dentry *dir, const int flag,
26439 + const int acc_mode);
26440 +int gr_handle_hardlink(const struct dentry *dentry,
26441 + const struct vfsmount *mnt,
26442 + struct inode *inode,
26443 + const int mode, const char *to);
26445 +int gr_task_is_capable(struct task_struct *task, const int cap);
26446 +int gr_is_capable_nolog(const int cap);
26447 +void gr_learn_resource(const struct task_struct *task, const int limit,
26448 + const unsigned long wanted, const int gt);
26449 +void gr_copy_label(struct task_struct *tsk);
26450 +void gr_handle_crash(struct task_struct *task, const int sig);
26451 +int gr_handle_signal(const struct task_struct *p, const int sig);
26452 +int gr_check_crash_uid(const uid_t uid);
26453 +int gr_check_protected_task(const struct task_struct *task);
26454 +int gr_acl_handle_mmap(const struct file *file,
26455 + const unsigned long prot);
26456 +int gr_acl_handle_mprotect(const struct file *file,
26457 + const unsigned long prot);
26458 +int gr_check_hidden_task(const struct task_struct *tsk);
26459 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
26460 + const struct vfsmount *mnt);
26461 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
26462 + const struct vfsmount *mnt);
26463 +__u32 gr_acl_handle_access(const struct dentry *dentry,
26464 + const struct vfsmount *mnt, const int fmode);
26465 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
26466 + const struct vfsmount *mnt, mode_t mode);
26467 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
26468 + const struct vfsmount *mnt, mode_t mode);
26469 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
26470 + const struct vfsmount *mnt);
26471 +int gr_handle_ptrace(struct task_struct *task, const long request);
26472 +int gr_handle_proc_ptrace(struct task_struct *task);
26473 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
26474 + const struct vfsmount *mnt);
26475 +int gr_check_crash_exec(const struct file *filp);
26476 +int gr_acl_is_enabled(void);
26477 +void gr_set_kernel_label(struct task_struct *task);
26478 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
26479 + const gid_t gid);
26480 +int gr_set_proc_label(const struct dentry *dentry,
26481 + const struct vfsmount *mnt);
26482 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
26483 + const struct vfsmount *mnt);
26484 +__u32 gr_acl_handle_open(const struct dentry *dentry,
26485 + const struct vfsmount *mnt, const int fmode);
26486 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
26487 + const struct dentry *p_dentry,
26488 + const struct vfsmount *p_mnt, const int fmode,
26489 + const int imode);
26490 +void gr_handle_create(const struct dentry *dentry,
26491 + const struct vfsmount *mnt);
26492 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
26493 + const struct dentry *parent_dentry,
26494 + const struct vfsmount *parent_mnt,
26496 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
26497 + const struct dentry *parent_dentry,
26498 + const struct vfsmount *parent_mnt);
26499 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
26500 + const struct vfsmount *mnt);
26501 +void gr_handle_delete(const ino_t ino, const dev_t dev);
26502 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
26503 + const struct vfsmount *mnt);
26504 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
26505 + const struct dentry *parent_dentry,
26506 + const struct vfsmount *parent_mnt,
26507 + const char *from);
26508 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
26509 + const struct dentry *parent_dentry,
26510 + const struct vfsmount *parent_mnt,
26511 + const struct dentry *old_dentry,
26512 + const struct vfsmount *old_mnt, const char *to);
26513 +int gr_acl_handle_rename(struct dentry *new_dentry,
26514 + struct dentry *parent_dentry,
26515 + const struct vfsmount *parent_mnt,
26516 + struct dentry *old_dentry,
26517 + struct inode *old_parent_inode,
26518 + struct vfsmount *old_mnt, const char *newname);
26519 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
26520 + struct dentry *old_dentry,
26521 + struct dentry *new_dentry,
26522 + struct vfsmount *mnt, const __u8 replace);
26523 +__u32 gr_check_link(const struct dentry *new_dentry,
26524 + const struct dentry *parent_dentry,
26525 + const struct vfsmount *parent_mnt,
26526 + const struct dentry *old_dentry,
26527 + const struct vfsmount *old_mnt);
26528 +int gr_acl_handle_filldir(const struct file *file, const char *name,
26529 + const unsigned int namelen, const ino_t ino);
26531 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
26532 + const struct vfsmount *mnt);
26533 +void gr_acl_handle_exit(void);
26534 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
26535 +int gr_acl_handle_procpidmem(const struct task_struct *task);
26536 +__u32 gr_cap_rtnetlink(void);
26538 +#ifdef CONFIG_SYSVIPC
26539 +void gr_shm_exit(struct task_struct *task);
26541 +static inline void gr_shm_exit(struct task_struct *task)
26547 +#ifdef CONFIG_GRKERNSEC
26548 +void gr_handle_mem_write(void);
26549 +void gr_handle_kmem_write(void);
26550 +void gr_handle_open_port(void);
26551 +int gr_handle_mem_mmap(const unsigned long offset,
26552 + struct vm_area_struct *vma);
26554 +unsigned long pax_get_random_long(void);
26555 +#define get_random_long() pax_get_random_long()
26557 +extern int grsec_enable_dmesg;
26558 +extern int grsec_enable_randsrc;
26559 +extern int grsec_enable_shm;
26563 diff -urNp linux-2.6.20.3/include/linux/highmem.h linux-2.6.20.3/include/linux/highmem.h
26564 --- linux-2.6.20.3/include/linux/highmem.h 2007-03-13 14:27:08.000000000 -0400
26565 +++ linux-2.6.20.3/include/linux/highmem.h 2007-03-23 08:10:06.000000000 -0400
26566 @@ -81,6 +81,13 @@ static inline void clear_highpage(struct
26567 kunmap_atomic(kaddr, KM_USER0);
26570 +static inline void sanitize_highpage(struct page *page)
26572 + void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
26573 + clear_page(kaddr);
26574 + kunmap_atomic(kaddr, KM_CLEARPAGE);
26578 * Same but also flushes aliased cache contents to RAM.
26580 diff -urNp linux-2.6.20.3/include/linux/jbd2.h linux-2.6.20.3/include/linux/jbd2.h
26581 --- linux-2.6.20.3/include/linux/jbd2.h 2007-03-13 14:27:08.000000000 -0400
26582 +++ linux-2.6.20.3/include/linux/jbd2.h 2007-03-23 08:10:06.000000000 -0400
26583 @@ -68,7 +68,7 @@ extern int jbd2_journal_enable_debug;
26587 -#define jbd_debug(f, a...) /**/
26588 +#define jbd_debug(f, a...) do {} while (0)
26591 extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
26592 diff -urNp linux-2.6.20.3/include/linux/jbd.h linux-2.6.20.3/include/linux/jbd.h
26593 --- linux-2.6.20.3/include/linux/jbd.h 2007-03-13 14:27:08.000000000 -0400
26594 +++ linux-2.6.20.3/include/linux/jbd.h 2007-03-23 08:10:06.000000000 -0400
26595 @@ -68,7 +68,7 @@ extern int journal_enable_debug;
26599 -#define jbd_debug(f, a...) /**/
26600 +#define jbd_debug(f, a...) do {} while (0)
26603 extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
26604 diff -urNp linux-2.6.20.3/include/linux/mman.h linux-2.6.20.3/include/linux/mman.h
26605 --- linux-2.6.20.3/include/linux/mman.h 2007-03-13 14:27:08.000000000 -0400
26606 +++ linux-2.6.20.3/include/linux/mman.h 2007-03-23 08:10:06.000000000 -0400
26607 @@ -61,6 +61,11 @@ static inline unsigned long
26608 calc_vm_flag_bits(unsigned long flags)
26610 return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
26612 +#ifdef CONFIG_PAX_SEGMEXEC
26613 + _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
26616 _calc_vm_trans(flags, MAP_DENYWRITE, VM_DENYWRITE ) |
26617 _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
26618 _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED );
26619 diff -urNp linux-2.6.20.3/include/linux/mm.h linux-2.6.20.3/include/linux/mm.h
26620 --- linux-2.6.20.3/include/linux/mm.h 2007-03-13 14:27:08.000000000 -0400
26621 +++ linux-2.6.20.3/include/linux/mm.h 2007-03-23 08:10:06.000000000 -0400
26622 @@ -39,6 +39,7 @@ extern int sysctl_legacy_va_layout;
26623 #include <asm/page.h>
26624 #include <asm/pgtable.h>
26625 #include <asm/processor.h>
26626 +#include <asm/mman.h>
26628 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
26630 @@ -112,8 +113,43 @@ struct vm_area_struct {
26632 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
26635 + unsigned long vm_mirror; /* PaX: mirror distance */
26638 +#ifdef CONFIG_PAX_SOFTMODE
26639 +extern unsigned int pax_softmode;
26642 +extern int pax_check_flags(unsigned long *);
26644 +/* if tsk != current then task_lock must be held on it */
26645 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
26646 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
26648 + if (likely(tsk->mm))
26649 + return tsk->mm->pax_flags;
26654 +/* if tsk != current then task_lock must be held on it */
26655 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
26657 + if (likely(tsk->mm)) {
26658 + tsk->mm->pax_flags = flags;
26665 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
26666 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
26667 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
26668 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
26671 extern struct kmem_cache *vm_area_cachep;
26674 @@ -170,6 +206,18 @@ extern unsigned int kobjsize(const void
26675 #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */
26676 #define VM_ALWAYSDUMP 0x04000000 /* Always include in core dumps */
26678 +#ifdef CONFIG_PAX_SEGMEXEC
26679 +#define VM_MIRROR 0x08000000 /* vma is mirroring another */
26682 +#ifdef CONFIG_PAX_MPROTECT
26683 +#define VM_MAYNOTWRITE 0x10000000 /* vma cannot be granted VM_WRITE any more */
26686 +#ifdef __VM_STACK_FLAGS
26687 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
26690 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
26691 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
26693 @@ -1115,7 +1163,6 @@ static inline unsigned long vma_pages(st
26696 pgprot_t vm_get_page_prot(unsigned long vm_flags);
26697 -struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
26698 struct page *vmalloc_to_page(void *addr);
26699 unsigned long vmalloc_to_pfn(void *addr);
26700 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
26701 @@ -1167,5 +1214,11 @@ extern int randomize_va_space;
26703 __attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma);
26705 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
26706 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
26708 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
26711 #endif /* __KERNEL__ */
26712 #endif /* _LINUX_MM_H */
26713 diff -urNp linux-2.6.20.3/include/linux/module.h linux-2.6.20.3/include/linux/module.h
26714 --- linux-2.6.20.3/include/linux/module.h 2007-03-13 14:27:08.000000000 -0400
26715 +++ linux-2.6.20.3/include/linux/module.h 2007-03-23 08:10:06.000000000 -0400
26716 @@ -297,16 +297,16 @@ struct module
26719 /* If this is non-NULL, vfree after init() returns */
26720 - void *module_init;
26721 + void *module_init_rx, *module_init_rw;
26723 /* Here is the actual code + data, vfree'd on unload. */
26724 - void *module_core;
26725 + void *module_core_rx, *module_core_rw;
26727 /* Here are the sizes of the init and core sections */
26728 - unsigned long init_size, core_size;
26729 + unsigned long init_size_rw, core_size_rw;
26731 /* The size of the executable code in each section. */
26732 - unsigned long init_text_size, core_text_size;
26733 + unsigned long init_size_rx, core_size_rx;
26735 /* The handle returned from unwind_add_table. */
26737 diff -urNp linux-2.6.20.3/include/linux/moduleloader.h linux-2.6.20.3/include/linux/moduleloader.h
26738 --- linux-2.6.20.3/include/linux/moduleloader.h 2007-03-13 14:27:08.000000000 -0400
26739 +++ linux-2.6.20.3/include/linux/moduleloader.h 2007-03-23 08:10:06.000000000 -0400
26740 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
26741 sections. Returns NULL on failure. */
26742 void *module_alloc(unsigned long size);
26744 +#ifdef CONFIG_PAX_KERNEXEC
26745 +void *module_alloc_exec(unsigned long size);
26747 +#define module_alloc_exec(x) module_alloc(x)
26750 /* Free memory returned from module_alloc. */
26751 void module_free(struct module *mod, void *module_region);
26753 +#ifdef CONFIG_PAX_KERNEXEC
26754 +void module_free_exec(struct module *mod, void *module_region);
26756 +#define module_free_exec(x, y) module_free(x, y)
26759 /* Apply the given relocation to the (simplified) ELF. Return -error
26761 int apply_relocate(Elf_Shdr *sechdrs,
26762 diff -urNp linux-2.6.20.3/include/linux/random.h linux-2.6.20.3/include/linux/random.h
26763 --- linux-2.6.20.3/include/linux/random.h 2007-03-13 14:27:08.000000000 -0400
26764 +++ linux-2.6.20.3/include/linux/random.h 2007-03-23 08:10:06.000000000 -0400
26765 @@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
26766 extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
26767 __be16 sport, __be16 dport);
26769 +extern unsigned long pax_get_random_long(void);
26772 extern struct file_operations random_fops, urandom_fops;
26774 diff -urNp linux-2.6.20.3/include/linux/sched.h linux-2.6.20.3/include/linux/sched.h
26775 --- linux-2.6.20.3/include/linux/sched.h 2007-03-13 14:27:08.000000000 -0400
26776 +++ linux-2.6.20.3/include/linux/sched.h 2007-03-23 08:11:31.000000000 -0400
26777 @@ -88,6 +88,7 @@ struct sched_param {
26779 struct exec_domain;
26780 struct futex_pi_state;
26781 +struct linux_binprm;
26784 * List of flags we want to share for kernel threads,
26785 @@ -373,8 +374,34 @@ struct mm_struct {
26787 rwlock_t ioctx_list_lock;
26788 struct kioctx *ioctx_list;
26790 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
26791 + unsigned long pax_flags;
26794 +#ifdef CONFIG_PAX_DLRESOLVE
26795 + unsigned long call_dl_resolve;
26798 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
26799 + unsigned long call_syscall;
26802 +#ifdef CONFIG_PAX_ASLR
26803 + unsigned long delta_mmap; /* randomized offset */
26804 + unsigned long delta_exec; /* randomized offset */
26805 + unsigned long delta_stack; /* randomized offset */
26810 +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
26811 +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
26812 +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
26813 +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
26814 +/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
26815 +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
26817 struct sighand_struct {
26819 struct k_sigaction action[_NSIG];
26820 @@ -491,6 +518,15 @@ struct signal_struct {
26821 #ifdef CONFIG_TASKSTATS
26822 struct taskstats *stats;
26825 +#ifdef CONFIG_GRKERNSEC
26831 + u8 used_accept:1;
26835 /* Context switch must be unlocked if interrupts are to be enabled */
26836 @@ -1038,6 +1074,17 @@ struct task_struct {
26837 struct list_head pi_state_list;
26838 struct futex_pi_state *pi_state_cache;
26840 +#ifdef CONFIG_GRKERNSEC
26842 + struct acl_subject_label *acl;
26843 + struct acl_role_label *role;
26844 + struct file *exec_file;
26846 + u8 acl_sp_role:1;
26847 + u8 is_writable:1;
26851 atomic_t fs_excl; /* holding fs exclusive resources */
26852 struct rcu_head rcu;
26854 @@ -1634,6 +1681,12 @@ extern void arch_pick_mmap_layout(struct
26855 static inline void arch_pick_mmap_layout(struct mm_struct *mm)
26857 mm->mmap_base = TASK_UNMAPPED_BASE;
26859 +#ifdef CONFIG_PAX_RANDMMAP
26860 + if (mm->pax_flags & MF_PAX_RANDMMAP)
26861 + mm->mmap_base += mm->delta_mmap;
26864 mm->get_unmapped_area = arch_get_unmapped_area;
26865 mm->unmap_area = arch_unmap_area;
26867 diff -urNp linux-2.6.20.3/include/linux/shm.h linux-2.6.20.3/include/linux/shm.h
26868 --- linux-2.6.20.3/include/linux/shm.h 2007-03-13 14:27:08.000000000 -0400
26869 +++ linux-2.6.20.3/include/linux/shm.h 2007-03-23 08:11:31.000000000 -0400
26870 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
26873 struct user_struct *mlock_user;
26874 +#ifdef CONFIG_GRKERNSEC
26875 + time_t shm_createtime;
26880 /* shm_mode upper byte flags */
26881 diff -urNp linux-2.6.20.3/include/linux/skbuff.h linux-2.6.20.3/include/linux/skbuff.h
26882 --- linux-2.6.20.3/include/linux/skbuff.h 2007-03-13 14:27:08.000000000 -0400
26883 +++ linux-2.6.20.3/include/linux/skbuff.h 2007-03-23 08:10:06.000000000 -0400
26884 @@ -373,7 +373,7 @@ extern void skb_truesize_bug(struc
26886 static inline void skb_truesize_check(struct sk_buff *skb)
26888 - if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
26889 + if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len))
26890 skb_truesize_bug(skb);
26893 diff -urNp linux-2.6.20.3/include/linux/sysctl.h linux-2.6.20.3/include/linux/sysctl.h
26894 --- linux-2.6.20.3/include/linux/sysctl.h 2007-03-13 14:27:08.000000000 -0400
26895 +++ linux-2.6.20.3/include/linux/sysctl.h 2007-03-23 08:29:10.000000000 -0400
26896 @@ -160,9 +160,21 @@ enum
26897 KERN_MAX_LOCK_DEPTH=74,
26898 KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
26899 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
26901 +#ifdef CONFIG_GRKERNSEC
26902 + KERN_GRSECURITY=98, /* grsecurity */
26905 +#ifdef CONFIG_PAX_SOFTMODE
26906 + KERN_PAX=99, /* PaX control */
26911 +#ifdef CONFIG_PAX_SOFTMODE
26913 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
26917 /* CTL_VM names: */
26919 diff -urNp linux-2.6.20.3/include/linux/uaccess.h linux-2.6.20.3/include/linux/uaccess.h
26920 --- linux-2.6.20.3/include/linux/uaccess.h 2007-03-13 14:27:08.000000000 -0400
26921 +++ linux-2.6.20.3/include/linux/uaccess.h 2007-03-23 08:10:06.000000000 -0400
26922 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
26924 mm_segment_t old_fs = get_fs(); \
26926 - set_fs(KERNEL_DS); \
26927 pagefault_disable(); \
26928 + set_fs(KERNEL_DS); \
26929 ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
26930 - pagefault_enable(); \
26932 + pagefault_enable(); \
26936 diff -urNp linux-2.6.20.3/include/linux/udf_fs.h linux-2.6.20.3/include/linux/udf_fs.h
26937 --- linux-2.6.20.3/include/linux/udf_fs.h 2007-03-13 14:27:08.000000000 -0400
26938 +++ linux-2.6.20.3/include/linux/udf_fs.h 2007-03-23 08:10:06.000000000 -0400
26943 -#define udf_debug(f, a...) /**/
26944 +#define udf_debug(f, a...) do {} while (0)
26947 #define udf_info(f, a...) \
26948 diff -urNp linux-2.6.20.3/include/net/sctp/sctp.h linux-2.6.20.3/include/net/sctp/sctp.h
26949 --- linux-2.6.20.3/include/net/sctp/sctp.h 2007-03-13 14:27:08.000000000 -0400
26950 +++ linux-2.6.20.3/include/net/sctp/sctp.h 2007-03-23 08:10:06.000000000 -0400
26951 @@ -306,8 +306,8 @@ extern int sctp_debug_flag;
26953 #else /* SCTP_DEBUG */
26955 -#define SCTP_DEBUG_PRINTK(whatever...)
26956 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
26957 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
26958 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
26959 #define SCTP_ENABLE_DEBUG
26960 #define SCTP_DISABLE_DEBUG
26961 #define SCTP_ASSERT(expr, str, func)
26962 diff -urNp linux-2.6.20.3/include/sound/core.h linux-2.6.20.3/include/sound/core.h
26963 --- linux-2.6.20.3/include/sound/core.h 2007-03-13 14:27:08.000000000 -0400
26964 +++ linux-2.6.20.3/include/sound/core.h 2007-03-23 08:10:06.000000000 -0400
26965 @@ -365,9 +365,9 @@ void snd_verbose_printd(const char *file
26967 #else /* !CONFIG_SND_DEBUG */
26969 -#define snd_printd(fmt, args...) /* nothing */
26970 +#define snd_printd(fmt, args...) do {} while (0)
26971 #define snd_assert(expr, args...) (void)(expr)
26972 -#define snd_BUG() /* nothing */
26973 +#define snd_BUG() do {} while (0)
26975 #endif /* CONFIG_SND_DEBUG */
26977 diff -urNp linux-2.6.20.3/init/do_mounts.c linux-2.6.20.3/init/do_mounts.c
26978 --- linux-2.6.20.3/init/do_mounts.c 2007-03-13 14:27:08.000000000 -0400
26979 +++ linux-2.6.20.3/init/do_mounts.c 2007-03-23 08:10:06.000000000 -0400
26980 @@ -65,11 +65,12 @@ static dev_t try_name(char *name, int pa
26982 /* read device number from .../dev */
26984 - sprintf(path, "/sys/block/%s/dev", name);
26985 - fd = sys_open(path, 0, 0);
26986 + if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
26988 + fd = sys_open((char __user *)path, 0, 0);
26991 - len = sys_read(fd, buf, 32);
26992 + len = sys_read(fd, (char __user *)buf, 32);
26994 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
26996 @@ -95,11 +96,12 @@ static dev_t try_name(char *name, int pa
26999 /* otherwise read range from .../range */
27000 - sprintf(path, "/sys/block/%s/range", name);
27001 - fd = sys_open(path, 0, 0);
27002 + if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
27004 + fd = sys_open((char __user *)path, 0, 0);
27007 - len = sys_read(fd, buf, 32);
27008 + len = sys_read(fd, (char __user *)buf, 32);
27010 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
27012 @@ -268,11 +270,11 @@ static void __init get_fs_names(char *pa
27014 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
27016 - int err = sys_mount(name, "/root", fs, flags, data);
27017 + int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
27021 - sys_chdir("/root");
27022 + sys_chdir((char __user *)"/root");
27023 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
27024 printk("VFS: Mounted root (%s filesystem)%s.\n",
27025 current->fs->pwdmnt->mnt_sb->s_type->name,
27026 @@ -354,18 +356,18 @@ void __init change_floppy(char *fmt, ...
27027 va_start(args, fmt);
27028 vsprintf(buf, fmt, args);
27030 - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
27031 + fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
27033 sys_ioctl(fd, FDEJECT, 0);
27036 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
27037 - fd = sys_open("/dev/console", O_RDWR, 0);
27038 + fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
27040 sys_ioctl(fd, TCGETS, (long)&termios);
27041 termios.c_lflag &= ~ICANON;
27042 sys_ioctl(fd, TCSETSF, (long)&termios);
27043 - sys_read(fd, &c, 1);
27044 + sys_read(fd, (char __user *)&c, 1);
27045 termios.c_lflag |= ICANON;
27046 sys_ioctl(fd, TCSETSF, (long)&termios);
27048 @@ -442,8 +444,8 @@ void __init prepare_namespace(void)
27052 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
27054 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
27055 + sys_chroot((char __user *)".");
27056 security_sb_post_mountroot();
27059 diff -urNp linux-2.6.20.3/init/do_mounts.h linux-2.6.20.3/init/do_mounts.h
27060 --- linux-2.6.20.3/init/do_mounts.h 2007-03-13 14:27:08.000000000 -0400
27061 +++ linux-2.6.20.3/init/do_mounts.h 2007-03-23 08:10:06.000000000 -0400
27062 @@ -15,15 +15,15 @@ extern char *root_device_name;
27064 static inline int create_dev(char *name, dev_t dev)
27066 - sys_unlink(name);
27067 - return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
27068 + sys_unlink((char __user *)name);
27069 + return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
27072 #if BITS_PER_LONG == 32
27073 static inline u32 bstat(char *name)
27075 struct stat64 stat;
27076 - if (sys_stat64(name, &stat) != 0)
27077 + if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
27079 if (!S_ISBLK(stat.st_mode))
27081 diff -urNp linux-2.6.20.3/init/do_mounts_md.c linux-2.6.20.3/init/do_mounts_md.c
27082 --- linux-2.6.20.3/init/do_mounts_md.c 2007-03-13 14:27:08.000000000 -0400
27083 +++ linux-2.6.20.3/init/do_mounts_md.c 2007-03-23 08:10:06.000000000 -0400
27084 @@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
27085 partitioned ? "_d" : "", minor,
27086 md_setup_args[ent].device_names);
27088 - fd = sys_open(name, 0, 0);
27089 + fd = sys_open((char __user *)name, 0, 0);
27091 printk(KERN_ERR "md: open failed - cannot start "
27092 "array %s\n", name);
27093 @@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
27097 - fd = sys_open(name, 0, 0);
27098 + fd = sys_open((char __user *)name, 0, 0);
27099 sys_ioctl(fd, BLKRRPART, 0);
27102 @@ -271,7 +271,7 @@ void __init md_run_setup(void)
27103 if (raid_noautodetect)
27104 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
27106 - int fd = sys_open("/dev/md0", 0, 0);
27107 + int fd = sys_open((char __user *)"/dev/md0", 0, 0);
27109 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
27111 diff -urNp linux-2.6.20.3/init/initramfs.c linux-2.6.20.3/init/initramfs.c
27112 --- linux-2.6.20.3/init/initramfs.c 2007-03-13 14:27:08.000000000 -0400
27113 +++ linux-2.6.20.3/init/initramfs.c 2007-03-23 08:10:06.000000000 -0400
27114 @@ -240,7 +240,7 @@ static int __init maybe_link(void)
27116 char *old = find_link(major, minor, ino, mode, collected);
27118 - return (sys_link(old, collected) < 0) ? -1 : 1;
27119 + return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
27123 @@ -249,11 +249,11 @@ static void __init clean_path(char *path
27127 - if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
27128 + if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
27129 if (S_ISDIR(st.st_mode))
27131 + sys_rmdir((char __user *)path);
27133 - sys_unlink(path);
27134 + sys_unlink((char __user *)path);
27138 @@ -276,7 +276,7 @@ static int __init do_name(void)
27139 int openflags = O_WRONLY|O_CREAT;
27141 openflags |= O_TRUNC;
27142 - wfd = sys_open(collected, openflags, mode);
27143 + wfd = sys_open((char __user *)collected, openflags, mode);
27146 sys_fchown(wfd, uid, gid);
27147 @@ -285,15 +285,15 @@ static int __init do_name(void)
27150 } else if (S_ISDIR(mode)) {
27151 - sys_mkdir(collected, mode);
27152 - sys_chown(collected, uid, gid);
27153 - sys_chmod(collected, mode);
27154 + sys_mkdir((char __user *)collected, mode);
27155 + sys_chown((char __user *)collected, uid, gid);
27156 + sys_chmod((char __user *)collected, mode);
27157 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
27158 S_ISFIFO(mode) || S_ISSOCK(mode)) {
27159 if (maybe_link() == 0) {
27160 - sys_mknod(collected, mode, rdev);
27161 - sys_chown(collected, uid, gid);
27162 - sys_chmod(collected, mode);
27163 + sys_mknod((char __user *)collected, mode, rdev);
27164 + sys_chown((char __user *)collected, uid, gid);
27165 + sys_chmod((char __user *)collected, mode);
27169 @@ -302,13 +302,13 @@ static int __init do_name(void)
27170 static int __init do_copy(void)
27172 if (count >= body_len) {
27173 - sys_write(wfd, victim, body_len);
27174 + sys_write(wfd, (char __user *)victim, body_len);
27180 - sys_write(wfd, victim, count);
27181 + sys_write(wfd, (char __user *)victim, count);
27185 @@ -319,8 +319,8 @@ static int __init do_symlink(void)
27187 collected[N_ALIGN(name_len) + body_len] = '\0';
27188 clean_path(collected, 0);
27189 - sys_symlink(collected + N_ALIGN(name_len), collected);
27190 - sys_lchown(collected, uid, gid);
27191 + sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
27192 + sys_lchown((char __user *)collected, uid, gid);
27194 next_state = Reset;
27196 diff -urNp linux-2.6.20.3/init/Kconfig linux-2.6.20.3/init/Kconfig
27197 --- linux-2.6.20.3/init/Kconfig 2007-03-13 14:27:08.000000000 -0400
27198 +++ linux-2.6.20.3/init/Kconfig 2007-03-23 08:11:31.000000000 -0400
27199 @@ -350,6 +350,7 @@ config SYSCTL_SYSCALL
27201 bool "Load all symbols for debugging/ksymoops" if EMBEDDED
27203 + depends on !GRKERNSEC_HIDESYM
27205 Say Y here to let the kernel print out symbolic crash information and
27206 symbolic stack backtraces. This increases the size of the kernel
27207 diff -urNp linux-2.6.20.3/init/main.c linux-2.6.20.3/init/main.c
27208 --- linux-2.6.20.3/init/main.c 2007-03-13 14:27:08.000000000 -0400
27209 +++ linux-2.6.20.3/init/main.c 2007-03-23 08:11:31.000000000 -0400
27210 @@ -106,6 +106,7 @@ static inline void mark_rodata_ro(void)
27212 extern void tc_init(void);
27214 +extern void grsecurity_init(void);
27216 enum system_states system_state;
27217 EXPORT_SYMBOL(system_state);
27218 @@ -176,6 +177,15 @@ static int __init set_reset_devices(char
27220 __setup("reset_devices", set_reset_devices);
27222 +#ifdef CONFIG_PAX_SOFTMODE
27223 +static int __init setup_pax_softmode(char *str)
27225 + get_option(&str, &pax_softmode);
27228 +__setup("pax_softmode=", setup_pax_softmode);
27231 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
27232 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
27233 static const char *panic_later, *panic_param;
27234 @@ -756,6 +766,8 @@ static int init(void * unused)
27235 prepare_namespace();
27238 + grsecurity_init();
27241 * Ok, we have completed the initial bootup, and
27242 * we're essentially up and running. Get rid of the
27243 diff -urNp linux-2.6.20.3/ipc/msg.c linux-2.6.20.3/ipc/msg.c
27244 --- linux-2.6.20.3/ipc/msg.c 2007-03-13 14:27:08.000000000 -0400
27245 +++ linux-2.6.20.3/ipc/msg.c 2007-03-23 08:11:31.000000000 -0400
27247 #include <linux/mutex.h>
27248 #include <linux/nsproxy.h>
27249 #include <linux/vs_base.h>
27250 +#include <linux/grsecurity.h>
27252 #include <asm/current.h>
27253 #include <asm/uaccess.h>
27254 @@ -288,6 +289,8 @@ asmlinkage long sys_msgget(key_t key, in
27256 mutex_unlock(&msg_ids(ns).mutex);
27258 + gr_log_msgget(ret, msgflg);
27263 @@ -554,6 +557,7 @@ asmlinkage long sys_msgctl(int msqid, in
27267 + gr_log_msgrm(ipcp->uid, ipcp->cuid);
27268 freeque(ns, msq, msqid);
27271 diff -urNp linux-2.6.20.3/ipc/sem.c linux-2.6.20.3/ipc/sem.c
27272 --- linux-2.6.20.3/ipc/sem.c 2007-03-13 14:27:08.000000000 -0400
27273 +++ linux-2.6.20.3/ipc/sem.c 2007-03-23 08:11:31.000000000 -0400
27275 #include <linux/nsproxy.h>
27276 #include <linux/vs_base.h>
27277 #include <linux/vs_limit.h>
27278 +#include <linux/grsecurity.h>
27280 #include <asm/uaccess.h>
27282 @@ -296,6 +297,9 @@ asmlinkage long sys_semget (key_t key, i
27285 mutex_unlock(&sem_ids(ns).mutex);
27287 + gr_log_semget(err, semflg);
27292 @@ -897,6 +901,7 @@ static int semctl_down(struct ipc_namesp
27296 + gr_log_semrm(ipcp->uid, ipcp->cuid);
27297 freeary(ns, sma, semid);
27300 diff -urNp linux-2.6.20.3/ipc/shm.c linux-2.6.20.3/ipc/shm.c
27301 --- linux-2.6.20.3/ipc/shm.c 2007-03-13 14:27:08.000000000 -0400
27302 +++ linux-2.6.20.3/ipc/shm.c 2007-03-23 08:11:31.000000000 -0400
27304 #include <linux/nsproxy.h>
27305 #include <linux/vs_context.h>
27306 #include <linux/vs_limit.h>
27307 +#include <linux/grsecurity.h>
27309 #include <asm/uaccess.h>
27311 @@ -67,6 +68,14 @@ static void shm_destroy (struct ipc_name
27312 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
27315 +#ifdef CONFIG_GRKERNSEC
27316 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
27317 + const time_t shm_createtime, const uid_t cuid,
27318 + const int shmid);
27319 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
27320 + const time_t shm_createtime);
27323 static void __ipc_init __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
27325 ns->ids[IPC_SHM_IDS] = ids;
27326 @@ -79,6 +88,8 @@ static void __ipc_init __shm_init_ns(str
27328 static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
27330 + gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
27332 if (shp->shm_nattch){
27333 shp->shm_perm.mode |= SHM_DEST;
27334 /* Do not find it any more */
27335 @@ -216,6 +227,17 @@ static void shm_close (struct vm_area_st
27336 shp->shm_lprid = current->tgid;
27337 shp->shm_dtim = get_seconds();
27339 +#ifdef CONFIG_GRKERNSEC_SHM
27340 + if (grsec_enable_shm) {
27341 + if (shp->shm_nattch == 0) {
27342 + shp->shm_perm.mode |= SHM_DEST;
27343 + shm_destroy(ns, shp);
27346 + mutex_unlock(&shm_ids(ns).mutex);
27350 if(shp->shm_nattch == 0 &&
27351 shp->shm_perm.mode & SHM_DEST)
27352 shm_destroy(ns, shp);
27353 @@ -326,6 +348,9 @@ static int newseg (struct ipc_namespace
27354 shp->shm_lprid = 0;
27355 shp->shm_atim = shp->shm_dtim = 0;
27356 shp->shm_ctim = get_seconds();
27357 +#ifdef CONFIG_GRKERNSEC
27358 + shp->shm_createtime = get_seconds();
27360 shp->shm_segsz = size;
27361 shp->shm_nattch = 0;
27362 shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
27363 @@ -385,6 +410,8 @@ asmlinkage long sys_shmget (key_t key, s
27365 mutex_unlock(&shm_ids(ns).mutex);
27367 + gr_log_shmget(err, shmflg, size);
27372 @@ -842,9 +869,23 @@ long do_shmat(int shmid, char __user *sh
27376 +#ifdef CONFIG_GRKERNSEC
27377 + if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
27378 + shp->shm_perm.cuid, shmid) ||
27379 + !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
27385 file = shp->shm_file;
27386 size = i_size_read(file->f_path.dentry->d_inode);
27389 +#ifdef CONFIG_GRKERNSEC
27390 + shp->shm_lapid = current->pid;
27395 down_write(¤t->mm->mmap_sem);
27396 @@ -1014,3 +1055,27 @@ static int sysvipc_shm_proc_show(struct
27401 +void gr_shm_exit(struct task_struct *task)
27403 +#ifdef CONFIG_GRKERNSEC_SHM
27405 + struct shmid_kernel *shp;
27406 + struct ipc_namespace *ns;
27408 + ns = current->nsproxy->ipc_ns;
27410 + if (!grsec_enable_shm)
27413 + for (i = 0; i <= shm_ids(ns).max_id; i++) {
27414 + shp = shm_get(ns, i);
27415 + if (shp && (shp->shm_cprid == task->pid) &&
27416 + (shp->shm_nattch <= 0)) {
27417 + shp->shm_perm.mode |= SHM_DEST;
27418 + shm_destroy(ns, shp);
27424 diff -urNp linux-2.6.20.3/kernel/acct.c linux-2.6.20.3/kernel/acct.c
27425 --- linux-2.6.20.3/kernel/acct.c 2007-03-13 14:27:08.000000000 -0400
27426 +++ linux-2.6.20.3/kernel/acct.c 2007-03-23 08:10:06.000000000 -0400
27427 @@ -511,7 +511,7 @@ static void do_acct_process(struct file
27429 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
27430 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
27431 - file->f_op->write(file, (char *)&ac,
27432 + file->f_op->write(file, (char __user *)&ac,
27433 sizeof(acct_t), &file->f_pos);
27434 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
27436 diff -urNp linux-2.6.20.3/kernel/capability.c linux-2.6.20.3/kernel/capability.c
27437 --- linux-2.6.20.3/kernel/capability.c 2007-03-13 14:27:08.000000000 -0400
27438 +++ linux-2.6.20.3/kernel/capability.c 2007-03-23 08:11:31.000000000 -0400
27440 #include <linux/security.h>
27441 #include <linux/syscalls.h>
27442 #include <linux/vs_context.h>
27443 +#include <linux/grsecurity.h>
27444 #include <asm/uaccess.h>
27446 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
27447 @@ -237,14 +238,25 @@ out:
27451 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
27452 +extern int gr_is_capable_nolog(const int cap);
27454 int __capable(struct task_struct *t, int cap)
27456 - if (security_capable(t, cap) == 0) {
27457 + if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
27458 t->flags |= PF_SUPERPRIV;
27463 +int capable_nolog(int cap)
27465 + if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
27466 + current->flags |= PF_SUPERPRIV;
27471 EXPORT_SYMBOL(__capable);
27473 #include <linux/vserver/base.h>
27474 @@ -249,3 +261,4 @@ int capable(int cap)
27475 return __capable(current, cap);
27477 EXPORT_SYMBOL(capable);
27478 +EXPORT_SYMBOL(capable_nolog);
27479 diff -urNp linux-2.6.20.3/kernel/configs.c linux-2.6.20.3/kernel/configs.c
27480 --- linux-2.6.20.3/kernel/configs.c 2007-03-13 14:27:08.000000000 -0400
27481 +++ linux-2.6.20.3/kernel/configs.c 2007-03-23 08:11:31.000000000 -0400
27482 @@ -88,8 +88,16 @@ static int __init ikconfig_init(void)
27483 struct proc_dir_entry *entry;
27485 /* create the current config file */
27486 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
27487 +#ifdef CONFIG_GRKERNSEC_PROC_USER
27488 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
27489 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
27490 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
27493 entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
27499 diff -urNp linux-2.6.20.3/kernel/exit.c linux-2.6.20.3/kernel/exit.c
27500 --- linux-2.6.20.3/kernel/exit.c 2007-03-13 14:27:08.000000000 -0400
27501 +++ linux-2.6.20.3/kernel/exit.c 2007-03-23 08:11:31.000000000 -0400
27503 #include <linux/vs_network.h>
27504 #include <linux/vs_pid.h>
27505 #include <linux/vserver/global.h>
27506 +#include <linux/grsecurity.h>
27508 +#ifdef CONFIG_GRKERNSEC
27509 +extern rwlock_t grsec_exec_file_lock;
27512 #include <asm/uaccess.h>
27513 #include <asm/unistd.h>
27514 @@ -118,6 +123,7 @@ static void __exit_signal(struct task_st
27516 __unhash_process(tsk);
27518 + gr_del_task_from_ip_table(tsk);
27519 tsk->signal = NULL;
27520 tsk->sighand = NULL;
27521 spin_unlock(&sighand->siglock);
27522 @@ -273,6 +279,15 @@ static void reparent_to_init(void)
27524 write_lock_irq(&tasklist_lock);
27526 +#ifdef CONFIG_GRKERNSEC
27527 + write_lock(&grsec_exec_file_lock);
27528 + if (current->exec_file) {
27529 + fput(current->exec_file);
27530 + current->exec_file = NULL;
27532 + write_unlock(&grsec_exec_file_lock);
27535 ptrace_unlink(current);
27536 /* Reparent to init */
27537 remove_parent(current);
27538 @@ -280,6 +295,8 @@ static void reparent_to_init(void)
27539 current->real_parent = child_reaper(current);
27540 add_parent(current);
27542 + gr_set_kernel_label(current);
27544 /* Set the exit signal to SIGCHLD so we signal init on exit */
27545 current->exit_signal = SIGCHLD;
27547 @@ -374,6 +391,17 @@ void daemonize(const char *name, ...)
27548 vsnprintf(current->comm, sizeof(current->comm), name, args);
27551 +#ifdef CONFIG_GRKERNSEC
27552 + write_lock(&grsec_exec_file_lock);
27553 + if (current->exec_file) {
27554 + fput(current->exec_file);
27555 + current->exec_file = NULL;
27557 + write_unlock(&grsec_exec_file_lock);
27560 + gr_set_kernel_label(current);
27563 * If we were started as result of loading a module, close all of the
27564 * user space pages. We don't need them, and if we didn't close them
27565 @@ -918,11 +946,15 @@ fastcall NORET_TYPE void do_exit(long co
27567 taskstats_exit(tsk, group_dead);
27569 + gr_acl_handle_psacct(tsk, code);
27570 + gr_acl_handle_exit();
27577 + gr_shm_exit(tsk);
27581 diff -urNp linux-2.6.20.3/kernel/fork.c linux-2.6.20.3/kernel/fork.c
27582 --- linux-2.6.20.3/kernel/fork.c 2007-03-13 14:27:08.000000000 -0400
27583 +++ linux-2.6.20.3/kernel/fork.c 2007-03-23 08:11:31.000000000 -0400
27585 #include <linux/vs_limit.h>
27586 #include <linux/vs_memory.h>
27587 #include <linux/vserver/global.h>
27588 +#include <linux/grsecurity.h>
27590 #include <asm/pgtable.h>
27591 #include <asm/pgalloc.h>
27592 @@ -180,7 +181,7 @@ static struct task_struct *dup_task_stru
27593 setup_thread_stack(tsk, orig);
27595 #ifdef CONFIG_CC_STACKPROTECTOR
27596 - tsk->stack_canary = get_random_int();
27597 + tsk->stack_canary = pax_get_random_long();
27600 /* One for us, one for whoever does the "release_task()" (usually parent) */
27601 @@ -212,8 +213,8 @@ static inline int dup_mmap(struct mm_str
27604 mm->mmap_cache = NULL;
27605 - mm->free_area_cache = oldmm->mmap_base;
27606 - mm->cached_hole_size = ~0UL;
27607 + mm->free_area_cache = oldmm->free_area_cache;
27608 + mm->cached_hole_size = oldmm->cached_hole_size;
27610 __set_mm_counter(mm, file_rss, 0);
27611 __set_mm_counter(mm, anon_rss, 0);
27612 @@ -338,7 +339,7 @@ static struct mm_struct * mm_init(struct
27613 spin_lock_init(&mm->page_table_lock);
27614 rwlock_init(&mm->ioctx_list_lock);
27615 mm->ioctx_list = NULL;
27616 - mm->free_area_cache = TASK_UNMAPPED_BASE;
27617 + mm->free_area_cache = ~0UL;
27618 mm->cached_hole_size = ~0UL;
27620 if (likely(!mm_alloc_pgd(mm))) {
27621 @@ -993,6 +994,9 @@ static struct task_struct *copy_process(
27626 + gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
27628 if (!vx_nproc_avail(1))
27629 goto bad_fork_cleanup_vm;
27631 @@ -1126,6 +1130,8 @@ static struct task_struct *copy_process(
27633 goto bad_fork_cleanup_namespaces;
27635 + gr_copy_label(p);
27637 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
27639 * Clear TID on mm_release()?
27640 @@ -1304,6 +1310,8 @@ bad_fork_cleanup_count:
27644 + gr_log_forkfail(retval);
27646 return ERR_PTR(retval);
27649 @@ -1376,6 +1384,8 @@ long do_fork(unsigned long clone_flags,
27651 struct completion vfork;
27653 + gr_handle_brute_check();
27655 if (clone_flags & CLONE_VFORK) {
27656 p->vfork_done = &vfork;
27657 init_completion(&vfork);
27658 diff -urNp linux-2.6.20.3/kernel/futex.c linux-2.6.20.3/kernel/futex.c
27659 --- linux-2.6.20.3/kernel/futex.c 2007-03-13 14:27:08.000000000 -0400
27660 +++ linux-2.6.20.3/kernel/futex.c 2007-03-23 08:10:06.000000000 -0400
27661 @@ -183,6 +183,11 @@ static int get_futex_key(u32 __user *uad
27665 +#ifdef CONFIG_PAX_SEGMEXEC
27666 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((unsigned long)uaddr >= SEGMEXEC_TASK_SIZE))
27671 * The futex address must be "naturally" aligned.
27673 @@ -195,8 +200,8 @@ static int get_futex_key(u32 __user *uad
27674 * The futex is hashed differently depending on whether
27675 * it's in a shared or private mapping. So check vma first.
27677 - vma = find_extend_vma(mm, address);
27678 - if (unlikely(!vma))
27679 + vma = find_vma(mm, address);
27680 + if (unlikely(!vma || address < vma->vm_start))
27684 diff -urNp linux-2.6.20.3/kernel/irq/handle.c linux-2.6.20.3/kernel/irq/handle.c
27685 --- linux-2.6.20.3/kernel/irq/handle.c 2007-03-13 14:27:08.000000000 -0400
27686 +++ linux-2.6.20.3/kernel/irq/handle.c 2007-03-23 08:10:06.000000000 -0400
27687 @@ -56,7 +56,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
27689 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
27691 - .affinity = CPU_MASK_ALL
27692 + .affinity = CPU_MASK_ALL,
27697 diff -urNp linux-2.6.20.3/kernel/kallsyms.c linux-2.6.20.3/kernel/kallsyms.c
27698 --- linux-2.6.20.3/kernel/kallsyms.c 2007-03-13 14:27:08.000000000 -0400
27699 +++ linux-2.6.20.3/kernel/kallsyms.c 2007-03-23 08:11:31.000000000 -0400
27700 @@ -72,8 +72,8 @@ static inline int is_kernel(unsigned lon
27702 static int is_ksym_addr(unsigned long addr)
27705 - return is_kernel(addr);
27706 + if (all_var && is_kernel(addr))
27709 return is_kernel_text(addr) || is_kernel_inittext(addr) ||
27710 is_kernel_extratext(addr);
27711 @@ -334,7 +334,6 @@ static unsigned long get_ksymbol_core(st
27713 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
27715 - iter->name[0] = '\0';
27716 iter->nameoff = get_symbol_offset(new_pos);
27717 iter->pos = new_pos;
27719 @@ -413,7 +412,7 @@ static int kallsyms_open(struct inode *i
27720 struct kallsym_iter *iter;
27723 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
27724 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
27727 reset_iter(iter, 0);
27728 @@ -444,7 +443,15 @@ static int __init kallsyms_init(void)
27730 struct proc_dir_entry *entry;
27732 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
27733 +#ifdef CONFIG_GRKERNSEC_PROC_USER
27734 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
27735 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
27736 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
27739 entry = create_proc_entry("kallsyms", 0444, NULL);
27742 entry->proc_fops = &kallsyms_operations;
27744 diff -urNp linux-2.6.20.3/kernel/kprobes.c linux-2.6.20.3/kernel/kprobes.c
27745 --- linux-2.6.20.3/kernel/kprobes.c 2007-03-13 14:27:08.000000000 -0400
27746 +++ linux-2.6.20.3/kernel/kprobes.c 2007-03-23 08:10:06.000000000 -0400
27747 @@ -162,7 +162,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
27748 * kernel image and loaded module images reside. This is required
27749 * so x86_64 can correctly handle the %rip-relative fixups.
27751 - kip->insns = module_alloc(PAGE_SIZE);
27752 + kip->insns = module_alloc_exec(PAGE_SIZE);
27756 diff -urNp linux-2.6.20.3/kernel/module.c linux-2.6.20.3/kernel/module.c
27757 --- linux-2.6.20.3/kernel/module.c 2007-03-13 14:27:08.000000000 -0400
27758 +++ linux-2.6.20.3/kernel/module.c 2007-03-23 08:11:31.000000000 -0400
27760 #include <asm/uaccess.h>
27761 #include <asm/semaphore.h>
27762 #include <asm/cacheflush.h>
27764 +#ifdef CONFIG_PAX_KERNEXEC
27765 +#include <asm/desc.h>
27768 #include <linux/license.h>
27771 @@ -67,6 +72,8 @@ static LIST_HEAD(modules);
27773 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
27775 +extern int gr_check_modstop(void);
27777 int register_module_notifier(struct notifier_block * nb)
27779 return blocking_notifier_chain_register(&module_notify_list, nb);
27780 @@ -656,6 +663,9 @@ sys_delete_module(const char __user *nam
27781 char name[MODULE_NAME_LEN];
27782 int ret, forced = 0;
27784 + if (gr_check_modstop())
27787 if (!capable(CAP_SYS_MODULE))
27790 @@ -1196,16 +1206,19 @@ static void free_module(struct module *m
27791 module_unload_free(mod);
27793 /* This may be NULL, but that's OK */
27794 - module_free(mod, mod->module_init);
27795 + module_free(mod, mod->module_init_rw);
27796 + module_free_exec(mod, mod->module_init_rx);
27799 percpu_modfree(mod->percpu);
27801 /* Free lock-classes: */
27802 - lockdep_free_key_range(mod->module_core, mod->core_size);
27803 + lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
27804 + lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
27806 /* Finally, free the core (containing the module structure) */
27807 - module_free(mod, mod->module_core);
27808 + module_free_exec(mod, mod->module_core_rx);
27809 + module_free(mod, mod->module_core_rw);
27812 void *__symbol_get(const char *symbol)
27813 @@ -1362,11 +1375,14 @@ static void layout_sections(struct modul
27814 || strncmp(secstrings + s->sh_name,
27817 - s->sh_entsize = get_offset(&mod->core_size, s);
27818 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
27819 + s->sh_entsize = get_offset(&mod->core_size_rw, s);
27821 + s->sh_entsize = get_offset(&mod->core_size_rx, s);
27822 DEBUGP("\t%s\n", secstrings + s->sh_name);
27825 - mod->core_text_size = mod->core_size;
27826 + mod->core_size_rx = mod->core_size_rx;
27829 DEBUGP("Init section allocation order:\n");
27830 @@ -1380,12 +1396,15 @@ static void layout_sections(struct modul
27831 || strncmp(secstrings + s->sh_name,
27834 - s->sh_entsize = (get_offset(&mod->init_size, s)
27835 - | INIT_OFFSET_MASK);
27836 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
27837 + s->sh_entsize = get_offset(&mod->init_size_rw, s);
27839 + s->sh_entsize = get_offset(&mod->init_size_rx, s);
27840 + s->sh_entsize |= INIT_OFFSET_MASK;
27841 DEBUGP("\t%s\n", secstrings + s->sh_name);
27844 - mod->init_text_size = mod->init_size;
27845 + mod->init_size_rx = mod->init_size_rx;
27849 @@ -1567,6 +1586,10 @@ static struct module *load_module(void _
27850 struct exception_table_entry *extable;
27851 mm_segment_t old_fs;
27853 +#ifdef CONFIG_PAX_KERNEXEC
27854 + unsigned long cr0;
27857 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
27859 if (len < sizeof(*hdr))
27860 @@ -1725,21 +1748,57 @@ static struct module *load_module(void _
27861 layout_sections(mod, hdr, sechdrs, secstrings);
27863 /* Do the allocs. */
27864 - ptr = module_alloc(mod->core_size);
27865 + ptr = module_alloc(mod->core_size_rw);
27870 - memset(ptr, 0, mod->core_size);
27871 - mod->module_core = ptr;
27872 + memset(ptr, 0, mod->core_size_rw);
27873 + mod->module_core_rw = ptr;
27875 + ptr = module_alloc(mod->init_size_rw);
27876 + if (!ptr && mod->init_size_rw) {
27878 + goto free_core_rw;
27880 + memset(ptr, 0, mod->init_size_rw);
27881 + mod->module_init_rw = ptr;
27883 + ptr = module_alloc_exec(mod->core_size_rx);
27886 + goto free_init_rw;
27889 - ptr = module_alloc(mod->init_size);
27890 - if (!ptr && mod->init_size) {
27891 +#ifdef CONFIG_PAX_KERNEXEC
27892 + pax_open_kernel(cr0);
27895 + memset(ptr, 0, mod->core_size_rx);
27897 +#ifdef CONFIG_PAX_KERNEXEC
27898 + pax_close_kernel(cr0);
27901 + mod->module_core_rx = ptr;
27903 + ptr = module_alloc_exec(mod->init_size_rx);
27904 + if (!ptr && mod->init_size_rx) {
27907 + goto free_core_rx;
27909 - memset(ptr, 0, mod->init_size);
27910 - mod->module_init = ptr;
27912 +#ifdef CONFIG_PAX_KERNEXEC
27913 + pax_open_kernel(cr0);
27916 + memset(ptr, 0, mod->init_size_rx);
27918 +#ifdef CONFIG_PAX_KERNEXEC
27919 + pax_close_kernel(cr0);
27922 + mod->module_init_rx = ptr;
27924 /* Transfer each section which specifies SHF_ALLOC */
27925 DEBUGP("final section addresses:\n");
27926 @@ -1749,17 +1808,44 @@ static struct module *load_module(void _
27927 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
27930 - if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
27931 - dest = mod->module_init
27932 - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
27934 - dest = mod->module_core + sechdrs[i].sh_entsize;
27935 + if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
27936 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
27937 + dest = mod->module_init_rw
27938 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
27940 + dest = mod->module_init_rx
27941 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
27943 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
27944 + dest = mod->module_core_rw + sechdrs[i].sh_entsize;
27946 + dest = mod->module_core_rx + sechdrs[i].sh_entsize;
27949 + if (sechdrs[i].sh_type != SHT_NOBITS) {
27951 - if (sechdrs[i].sh_type != SHT_NOBITS)
27952 - memcpy(dest, (void *)sechdrs[i].sh_addr,
27953 - sechdrs[i].sh_size);
27954 +#ifdef CONFIG_PAX_KERNEXEC
27955 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
27956 + pax_open_kernel(cr0);
27959 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
27961 +#ifdef CONFIG_PAX_KERNEXEC
27962 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
27963 + pax_close_kernel(cr0);
27967 /* Update sh_addr to point to copy in image. */
27968 - sechdrs[i].sh_addr = (unsigned long)dest;
27970 +#ifdef CONFIG_PAX_KERNEXEC
27971 + if (sechdrs[i].sh_flags & SHF_EXECINSTR)
27972 + sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
27976 + sechdrs[i].sh_addr = (unsigned long)dest;
27977 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
27979 /* Module has been moved. */
27980 @@ -1780,8 +1866,18 @@ static struct module *load_module(void _
27981 setup_modinfo(mod, sechdrs, infoindex);
27983 /* Fix up syms, so that st_value is a pointer to location. */
27985 +#ifdef CONFIG_PAX_KERNEXEC
27986 + pax_open_kernel(cr0);
27989 err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
27992 +#ifdef CONFIG_PAX_KERNEXEC
27993 + pax_close_kernel(cr0);
27999 @@ -1836,11 +1932,20 @@ static struct module *load_module(void _
28000 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
28003 +#ifdef CONFIG_PAX_KERNEXEC
28004 + pax_open_kernel(cr0);
28007 if (sechdrs[i].sh_type == SHT_REL)
28008 err = apply_relocate(sechdrs, strtab, symindex, i,mod);
28009 else if (sechdrs[i].sh_type == SHT_RELA)
28010 err = apply_relocate_add(sechdrs, strtab, symindex, i,
28013 +#ifdef CONFIG_PAX_KERNEXEC
28014 + pax_close_kernel(cr0);
28020 @@ -1854,14 +1959,31 @@ static struct module *load_module(void _
28021 /* Set up and sort exception table */
28022 mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
28023 mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
28025 +#ifdef CONFIG_PAX_KERNEXEC
28026 + pax_open_kernel(cr0);
28029 sort_extable(extable, extable + mod->num_exentries);
28031 +#ifdef CONFIG_PAX_KERNEXEC
28032 + pax_close_kernel(cr0);
28035 /* Finally, copy percpu area over. */
28036 percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
28037 sechdrs[pcpuindex].sh_size);
28039 +#ifdef CONFIG_PAX_KERNEXEC
28040 + pax_open_kernel(cr0);
28043 add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
28045 +#ifdef CONFIG_PAX_KERNEXEC
28046 + pax_close_kernel(cr0);
28049 err = module_finalize(hdr, sechdrs, mod);
28052 @@ -1875,12 +1997,12 @@ static struct module *load_module(void _
28053 * Do it before processing of module parameters, so the module
28054 * can provide parameter accessor functions of its own.
28056 - if (mod->module_init)
28057 - flush_icache_range((unsigned long)mod->module_init,
28058 - (unsigned long)mod->module_init
28059 - + mod->init_size);
28060 - flush_icache_range((unsigned long)mod->module_core,
28061 - (unsigned long)mod->module_core + mod->core_size);
28062 + if (mod->module_init_rx)
28063 + flush_icache_range((unsigned long)mod->module_init_rx,
28064 + (unsigned long)mod->module_init_rx
28065 + + mod->init_size_rx);
28066 + flush_icache_range((unsigned long)mod->module_core_rx,
28067 + (unsigned long)mod->module_core_rx + mod->core_size_rx);
28071 @@ -1923,9 +2045,13 @@ static struct module *load_module(void _
28072 module_arch_cleanup(mod);
28074 module_unload_free(mod);
28075 - module_free(mod, mod->module_init);
28077 - module_free(mod, mod->module_core);
28078 + module_free_exec(mod, mod->module_init_rx);
28080 + module_free_exec(mod, mod->module_core_rx);
28082 + module_free(mod, mod->module_init_rw);
28084 + module_free(mod, mod->module_core_rw);
28087 percpu_modfree(percpu);
28088 @@ -1961,6 +2087,9 @@ sys_init_module(void __user *umod,
28089 struct module *mod;
28092 + if (gr_check_modstop())
28095 /* Must have permission */
28096 if (!capable(CAP_SYS_MODULE))
28098 @@ -2012,10 +2141,12 @@ sys_init_module(void __user *umod,
28099 /* Drop initial reference. */
28101 unwind_remove_table(mod->unwind_info, 1);
28102 - module_free(mod, mod->module_init);
28103 - mod->module_init = NULL;
28104 - mod->init_size = 0;
28105 - mod->init_text_size = 0;
28106 + module_free(mod, mod->module_init_rw);
28107 + module_free_exec(mod, mod->module_init_rx);
28108 + mod->module_init_rw = NULL;
28109 + mod->module_init_rx = NULL;
28110 + mod->init_size_rw = 0;
28111 + mod->init_size_rx = 0;
28112 mutex_unlock(&module_mutex);
28115 @@ -2046,10 +2177,14 @@ static const char *get_ksymbol(struct mo
28116 unsigned long nextval;
28118 /* At worse, next value is at end of module */
28119 - if (within(addr, mod->module_init, mod->init_size))
28120 - nextval = (unsigned long)mod->module_init+mod->init_text_size;
28122 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
28123 + if (within(addr, mod->module_init_rx, mod->init_size_rx))
28124 + nextval = (unsigned long)mod->module_init_rw;
28125 + else if (within(addr, mod->module_init_rw, mod->init_size_rw))
28126 + nextval = (unsigned long)mod->module_core_rx;
28127 + else if (within(addr, mod->module_core_rx, mod->core_size_rx))
28128 + nextval = (unsigned long)mod->module_core_rw;
28130 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
28132 /* Scan for closest preceeding symbol, and next symbol. (ELF
28133 starts real symbols at 1). */
28134 @@ -2090,8 +2225,10 @@ const char *module_address_lookup(unsign
28135 struct module *mod;
28137 list_for_each_entry(mod, &modules, list) {
28138 - if (within(addr, mod->module_init, mod->init_size)
28139 - || within(addr, mod->module_core, mod->core_size)) {
28140 + if (within(addr, mod->module_init_rx, mod->init_size_rx)
28141 + || within(addr, mod->module_init_rw, mod->init_size_rw)
28142 + || within(addr, mod->module_core_rx, mod->core_size_rx)
28143 + || within(addr, mod->module_core_rw, mod->core_size_rw)) {
28145 *modname = mod->name;
28146 return get_ksymbol(mod, addr, size, offset);
28147 @@ -2212,7 +2349,7 @@ static int m_show(struct seq_file *m, vo
28150 seq_printf(m, "%s %lu",
28151 - mod->name, mod->init_size + mod->core_size);
28152 + mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
28153 print_unload_info(m, mod);
28155 /* Informative for users. */
28156 @@ -2221,7 +2358,7 @@ static int m_show(struct seq_file *m, vo
28157 mod->state == MODULE_STATE_COMING ? "Loading":
28159 /* Used by oprofile and other similar tools. */
28160 - seq_printf(m, " 0x%p", mod->module_core);
28161 + seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
28165 @@ -2279,7 +2416,8 @@ int is_module_address(unsigned long addr
28166 spin_lock_irqsave(&modlist_lock, flags);
28168 list_for_each_entry(mod, &modules, list) {
28169 - if (within(addr, mod->module_core, mod->core_size)) {
28170 + if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
28171 + within(addr, mod->module_core_rw, mod->core_size_rw)) {
28172 spin_unlock_irqrestore(&modlist_lock, flags);
28175 @@ -2297,8 +2435,8 @@ struct module *__module_text_address(uns
28176 struct module *mod;
28178 list_for_each_entry(mod, &modules, list)
28179 - if (within(addr, mod->module_init, mod->init_text_size)
28180 - || within(addr, mod->module_core, mod->core_text_size))
28181 + if (within(addr, mod->module_init_rx, mod->init_size_rx)
28182 + || within(addr, mod->module_core_rx, mod->core_size_rx))
28186 diff -urNp linux-2.6.20.3/kernel/mutex.c linux-2.6.20.3/kernel/mutex.c
28187 --- linux-2.6.20.3/kernel/mutex.c 2007-03-13 14:27:08.000000000 -0400
28188 +++ linux-2.6.20.3/kernel/mutex.c 2007-03-23 08:10:06.000000000 -0400
28189 @@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
28191 * This function is similar to (but not equivalent to) down().
28193 -void inline fastcall __sched mutex_lock(struct mutex *lock)
28194 +inline void fastcall __sched mutex_lock(struct mutex *lock)
28198 diff -urNp linux-2.6.20.3/kernel/pid.c linux-2.6.20.3/kernel/pid.c
28199 --- linux-2.6.20.3/kernel/pid.c 2007-03-13 14:27:08.000000000 -0400
28200 +++ linux-2.6.20.3/kernel/pid.c 2007-03-23 08:11:31.000000000 -0400
28202 #include <linux/hash.h>
28203 #include <linux/pid_namespace.h>
28204 #include <linux/vs_pid.h>
28205 +#include <linux/grsecurity.h>
28207 #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
28208 static struct hlist_head *pid_hash;
28209 @@ -36,7 +37,7 @@ static struct kmem_cache *pid_cachep;
28211 int pid_max = PID_MAX_DEFAULT;
28213 -#define RESERVED_PIDS 300
28214 +#define RESERVED_PIDS 500
28216 int pid_max_min = RESERVED_PIDS + 1;
28217 int pid_max_max = PID_MAX_LIMIT;
28218 @@ -318,6 +319,8 @@ struct task_struct *find_task_by_pid_typ
28219 /* maybe VS_WATCH_P in the future? */
28220 !vx_check(task->xid, VS_WATCH|VS_IDENT))
28222 + if (gr_pid_is_chrooted(task))
28227 diff -urNp linux-2.6.20.3/kernel/posix-cpu-timers.c linux-2.6.20.3/kernel/posix-cpu-timers.c
28228 --- linux-2.6.20.3/kernel/posix-cpu-timers.c 2007-03-13 14:27:08.000000000 -0400
28229 +++ linux-2.6.20.3/kernel/posix-cpu-timers.c 2007-03-23 08:11:31.000000000 -0400
28231 #include <linux/posix-timers.h>
28232 #include <asm/uaccess.h>
28233 #include <linux/errno.h>
28234 +#include <linux/grsecurity.h>
28236 static int check_clock(const clockid_t which_clock)
28238 @@ -1139,6 +1140,7 @@ static void check_process_timers(struct
28239 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
28242 + gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
28243 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
28245 * At the soft limit, send a SIGXCPU every second.
28246 diff -urNp linux-2.6.20.3/kernel/power/poweroff.c linux-2.6.20.3/kernel/power/poweroff.c
28247 --- linux-2.6.20.3/kernel/power/poweroff.c 2007-03-13 14:27:08.000000000 -0400
28248 +++ linux-2.6.20.3/kernel/power/poweroff.c 2007-03-23 08:10:06.000000000 -0400
28249 @@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
28250 .enable_mask = SYSRQ_ENABLE_BOOT,
28253 -static int pm_sysrq_init(void)
28254 +static int __init pm_sysrq_init(void)
28256 register_sysrq_key('o', &sysrq_poweroff_op);
28258 diff -urNp linux-2.6.20.3/kernel/printk.c linux-2.6.20.3/kernel/printk.c
28259 --- linux-2.6.20.3/kernel/printk.c 2007-03-13 14:27:08.000000000 -0400
28260 +++ linux-2.6.20.3/kernel/printk.c 2007-03-23 08:11:31.000000000 -0400
28262 #include <linux/syscalls.h>
28263 #include <linux/jiffies.h>
28264 #include <linux/vs_cvirt.h>
28265 +#include <linux/grsecurity.h>
28267 #include <asm/uaccess.h>
28269 @@ -186,6 +187,11 @@ int do_syslog(int type, char __user *buf
28273 +#ifdef CONFIG_GRKERNSEC_DMESG
28274 + if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
28278 error = security_syslog(type);
28281 diff -urNp linux-2.6.20.3/kernel/ptrace.c linux-2.6.20.3/kernel/ptrace.c
28282 --- linux-2.6.20.3/kernel/ptrace.c 2007-03-13 14:27:08.000000000 -0400
28283 +++ linux-2.6.20.3/kernel/ptrace.c 2007-03-23 08:11:31.000000000 -0400
28285 #include <linux/security.h>
28286 #include <linux/signal.h>
28287 #include <linux/vs_context.h>
28288 +#include <linux/grsecurity.h>
28290 #include <asm/pgtable.h>
28291 #include <asm/uaccess.h>
28292 @@ -138,12 +139,12 @@ static int may_attach(struct task_struct
28293 (current->uid != task->uid) ||
28294 (current->gid != task->egid) ||
28295 (current->gid != task->sgid) ||
28296 - (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
28297 + (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
28301 dumpable = task->mm->dumpable;
28302 - if (!dumpable && !capable(CAP_SYS_PTRACE))
28303 + if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
28305 if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT))
28307 @@ -487,6 +488,11 @@ asmlinkage long sys_ptrace(long request,
28309 goto out_put_task_struct;
28311 + if (gr_handle_ptrace(child, request)) {
28313 + goto out_put_task_struct;
28316 ret = arch_ptrace(child, request, addr, data);
28318 goto out_put_task_struct;
28319 diff -urNp linux-2.6.20.3/kernel/rcupdate.c linux-2.6.20.3/kernel/rcupdate.c
28320 --- linux-2.6.20.3/kernel/rcupdate.c 2007-03-13 14:27:08.000000000 -0400
28321 +++ linux-2.6.20.3/kernel/rcupdate.c 2007-03-23 08:10:06.000000000 -0400
28322 @@ -63,11 +63,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk
28323 .cpumask = CPU_MASK_NONE,
28326 -DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
28327 -DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
28328 +DEFINE_PER_CPU(struct rcu_data, rcu_data);
28329 +DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
28331 /* Fake initialization required by compiler */
28332 -static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
28333 +static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet);
28334 static int blimit = 10;
28335 static int qhimark = 10000;
28336 static int qlowmark = 100;
28337 diff -urNp linux-2.6.20.3/kernel/resource.c linux-2.6.20.3/kernel/resource.c
28338 --- linux-2.6.20.3/kernel/resource.c 2007-03-13 14:27:08.000000000 -0400
28339 +++ linux-2.6.20.3/kernel/resource.c 2007-03-23 08:11:31.000000000 -0400
28340 @@ -133,10 +133,27 @@ static int __init ioresources_init(void)
28342 struct proc_dir_entry *entry;
28344 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
28345 +#ifdef CONFIG_GRKERNSEC_PROC_USER
28346 + entry = create_proc_entry("ioports", S_IRUSR, NULL);
28347 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
28348 + entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
28351 entry = create_proc_entry("ioports", 0, NULL);
28354 entry->proc_fops = &proc_ioports_operations;
28356 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
28357 +#ifdef CONFIG_GRKERNSEC_PROC_USER
28358 + entry = create_proc_entry("iomem", S_IRUSR, NULL);
28359 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
28360 + entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
28363 entry = create_proc_entry("iomem", 0, NULL);
28366 entry->proc_fops = &proc_iomem_operations;
28368 diff -urNp linux-2.6.20.3/kernel/sched.c linux-2.6.20.3/kernel/sched.c
28369 --- linux-2.6.20.3/kernel/sched.c 2007-03-13 14:27:08.000000000 -0400
28370 +++ linux-2.6.20.3/kernel/sched.c 2007-03-23 08:11:31.000000000 -0400
28372 #include <linux/tsacct_kern.h>
28373 #include <linux/kprobes.h>
28374 #include <linux/delayacct.h>
28375 +#include <linux/grsecurity.h>
28376 #include <asm/tlb.h>
28378 #include <asm/unistd.h>
28379 @@ -4111,7 +4112,8 @@ asmlinkage long sys_nice(int increment)
28383 - if (increment < 0 && !can_nice(current, nice))
28384 + if (increment < 0 && (!can_nice(current, nice) ||
28385 + gr_handle_chroot_nice()))
28386 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
28388 retval = security_task_setnice(current, nice);
28389 diff -urNp linux-2.6.20.3/kernel/signal.c linux-2.6.20.3/kernel/signal.c
28390 --- linux-2.6.20.3/kernel/signal.c 2007-03-13 14:27:08.000000000 -0400
28391 +++ linux-2.6.20.3/kernel/signal.c 2007-03-23 08:11:31.000000000 -0400
28393 #include <linux/capability.h>
28394 #include <linux/freezer.h>
28395 #include <linux/pid_namespace.h>
28396 +#include <linux/grsecurity.h>
28397 #include <linux/nsproxy.h>
28398 #include <linux/vs_context.h>
28399 #include <linux/vs_pid.h>
28400 @@ -596,11 +597,11 @@ static int check_kill_permission(int sig
28401 sig, info, t, vx_task_xid(t), t->pid);
28404 - if (((sig != SIGCONT) ||
28405 + if ((((sig != SIGCONT) ||
28406 (process_session(current) != process_session(t)))
28407 && (current->euid ^ t->suid) && (current->euid ^ t->uid)
28408 && (current->uid ^ t->suid) && (current->uid ^ t->uid)
28409 - && !capable(CAP_KILL))
28410 + && !capable(CAP_KILL)) || gr_handle_signal(t, sig))
28414 @@ -612,8 +613,10 @@ static int check_kill_permission(int sig
28417 error = security_task_kill(t, info, sig, 0);
28420 audit_signal_info(sig, t); /* Let audit system see the signal */
28421 + gr_log_signal(sig, t);
28426 @@ -791,7 +794,7 @@ out_set:
28427 (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
28432 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
28435 @@ -845,6 +848,10 @@ force_sig_info(int sig, struct siginfo *
28438 ret = specific_send_sig_info(sig, info, t);
28440 + gr_log_signal(sig, t);
28441 + gr_handle_crash(t, sig);
28443 spin_unlock_irqrestore(&t->sighand->siglock, flags);
28446 diff -urNp linux-2.6.20.3/kernel/sys.c linux-2.6.20.3/kernel/sys.c
28447 --- linux-2.6.20.3/kernel/sys.c 2007-03-13 14:27:08.000000000 -0400
28448 +++ linux-2.6.20.3/kernel/sys.c 2007-03-23 08:11:31.000000000 -0400
28450 #include <linux/signal.h>
28451 #include <linux/cn_proc.h>
28452 #include <linux/getcpu.h>
28453 +#include <linux/grsecurity.h>
28455 #include <linux/compat.h>
28456 #include <linux/syscalls.h>
28457 @@ -583,6 +584,12 @@ static int set_one_prio(struct task_stru
28462 + if (gr_handle_chroot_setpriority(p, niceval)) {
28467 no_nice = security_task_setnice(p, niceval);
28470 @@ -961,6 +968,9 @@ asmlinkage long sys_setregid(gid_t rgid,
28471 if (rgid != (gid_t) -1 ||
28472 (egid != (gid_t) -1 && egid != old_rgid))
28473 current->sgid = new_egid;
28475 + gr_set_role_label(current, current->uid, new_rgid);
28477 current->fsgid = new_egid;
28478 current->egid = new_egid;
28479 current->gid = new_rgid;
28480 @@ -988,6 +998,9 @@ asmlinkage long sys_setgid(gid_t gid)
28481 current->mm->dumpable = suid_dumpable;
28485 + gr_set_role_label(current, current->uid, gid);
28487 current->gid = current->egid = current->sgid = current->fsgid = gid;
28488 } else if ((gid == current->gid) || (gid == current->sgid)) {
28489 if (old_egid != gid) {
28490 @@ -1025,6 +1038,9 @@ static int set_user(uid_t new_ruid, int
28491 current->mm->dumpable = suid_dumpable;
28495 + gr_set_role_label(current, new_ruid, current->gid);
28497 current->uid = new_ruid;
28500 @@ -1127,6 +1143,9 @@ asmlinkage long sys_setuid(uid_t uid)
28501 } else if ((uid != current->uid) && (uid != new_suid))
28504 + if (gr_check_crash_uid(uid))
28507 if (old_euid != uid) {
28508 current->mm->dumpable = suid_dumpable;
28510 @@ -1229,8 +1248,10 @@ asmlinkage long sys_setresgid(gid_t rgid
28511 current->egid = egid;
28513 current->fsgid = current->egid;
28514 - if (rgid != (gid_t) -1)
28515 + if (rgid != (gid_t) -1) {
28516 + gr_set_role_label(current, current->uid, rgid);
28517 current->gid = rgid;
28519 if (sgid != (gid_t) -1)
28520 current->sgid = sgid;
28522 @@ -1378,7 +1399,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
28523 write_lock_irq(&tasklist_lock);
28526 - p = find_task_by_pid(pid);
28527 + /* grsec: replaced find_task_by_pid with equivalent call
28528 + which lacks the chroot restriction
28530 + p = pid_task(find_pid(pid), PIDTYPE_PID);
28534 @@ -2092,7 +2116,7 @@ asmlinkage long sys_prctl(int option, un
28535 error = current->mm->dumpable;
28537 case PR_SET_DUMPABLE:
28538 - if (arg2 < 0 || arg2 > 1) {
28543 diff -urNp linux-2.6.20.3/kernel/sysctl.c linux-2.6.20.3/kernel/sysctl.c
28544 --- linux-2.6.20.3/kernel/sysctl.c 2007-03-13 14:27:08.000000000 -0400
28545 +++ linux-2.6.20.3/kernel/sysctl.c 2007-03-23 08:11:31.000000000 -0400
28546 @@ -58,6 +58,14 @@ extern int proc_nr_files(ctl_table *tabl
28549 #if defined(CONFIG_SYSCTL)
28550 +#include <linux/grsecurity.h>
28551 +#include <linux/grinternal.h>
28553 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
28554 + const void *newval);
28555 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
28557 +extern int gr_handle_chroot_sysctl(const int op);
28559 /* External variables not in a header file. */
28561 @@ -156,7 +164,7 @@ static int proc_do_cad_pid(ctl_table *ta
28563 static ctl_table root_table[];
28564 static struct ctl_table_header root_table_header =
28565 - { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
28566 + { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry), 0, NULL };
28568 static ctl_table kern_table[];
28569 static ctl_table vm_table[];
28570 @@ -170,6 +178,7 @@ extern ctl_table pty_table[];
28571 #ifdef CONFIG_INOTIFY_USER
28572 extern ctl_table inotify_table[];
28574 +extern ctl_table grsecurity_table[];
28576 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
28577 int sysctl_legacy_va_layout;
28578 @@ -209,6 +218,21 @@ static void *get_ipc(ctl_table *table, i
28579 #define get_ipc(T,W) ((T)->data)
28582 +#ifdef CONFIG_PAX_SOFTMODE
28583 +static ctl_table pax_table[] = {
28585 + .ctl_name = PAX_SOFTMODE,
28586 + .procname = "softmode",
28587 + .data = &pax_softmode,
28588 + .maxlen = sizeof(unsigned int),
28590 + .proc_handler = &proc_dointvec,
28593 + { .ctl_name = 0 }
28597 /* /proc declarations: */
28599 #ifdef CONFIG_PROC_SYSCTL
28600 @@ -270,7 +294,6 @@ static ctl_table root_table[] = {
28602 .child = dev_table,
28608 @@ -791,6 +814,23 @@ static ctl_table kern_table[] = {
28612 +#ifdef CONFIG_PAX_SOFTMODE
28614 + .ctl_name = KERN_PAX,
28615 + .procname = "pax",
28617 + .child = pax_table,
28621 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
28623 + .ctl_name = KERN_GRSECURITY,
28624 + .procname = "grsecurity",
28626 + .child = grsecurity_table,
28632 @@ -1305,6 +1345,10 @@ static int test_perm(int mode, int op)
28633 static inline int ctl_perm(ctl_table *table, int op)
28636 + if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
28638 + if (gr_handle_chroot_sysctl(op))
28640 error = security_sysctl(table, op);
28643 @@ -1344,6 +1388,10 @@ repeat:
28644 table = table->child;
28648 + if (!gr_handle_sysctl(table, oldval, newval))
28651 error = do_sysctl_strategy(table, name, nlen,
28654 diff -urNp linux-2.6.20.3/kernel/time.c linux-2.6.20.3/kernel/time.c
28655 --- linux-2.6.20.3/kernel/time.c 2007-03-13 14:27:08.000000000 -0400
28656 +++ linux-2.6.20.3/kernel/time.c 2007-03-23 08:11:31.000000000 -0400
28658 #include <linux/security.h>
28659 #include <linux/fs.h>
28660 #include <linux/module.h>
28661 +#include <linux/grsecurity.h>
28663 #include <asm/uaccess.h>
28664 #include <asm/unistd.h>
28665 @@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user
28668 vx_settimeofday(&tv);
28670 + gr_log_timechange();
28675 @@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct
28679 + gr_log_timechange();
28681 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
28684 diff -urNp linux-2.6.20.3/lib/radix-tree.c linux-2.6.20.3/lib/radix-tree.c
28685 --- linux-2.6.20.3/lib/radix-tree.c 2007-03-13 14:27:08.000000000 -0400
28686 +++ linux-2.6.20.3/lib/radix-tree.c 2007-03-23 08:10:06.000000000 -0400
28687 @@ -76,7 +76,7 @@ struct radix_tree_preload {
28689 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
28691 -DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
28692 +DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} };
28694 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
28696 diff -urNp linux-2.6.20.3/localversion-grsec linux-2.6.20.3/localversion-grsec
28697 --- linux-2.6.20.3/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
28698 +++ linux-2.6.20.3/localversion-grsec 2007-03-23 08:11:31.000000000 -0400
28701 diff -urNp linux-2.6.20.3/Makefile linux-2.6.20.3/Makefile
28702 --- linux-2.6.20.3/Makefile 2007-03-13 14:27:08.000000000 -0400
28703 +++ linux-2.6.20.3/Makefile 2007-03-23 08:11:31.000000000 -0400
28704 @@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \
28706 CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
28708 -CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
28709 +CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
28710 -fno-strict-aliasing -fno-common
28711 AFLAGS := -D__ASSEMBLY__
28713 @@ -553,7 +553,7 @@ export mod_strip_cmd
28716 ifeq ($(KBUILD_EXTMOD),)
28717 -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
28718 +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
28720 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
28721 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
28722 diff -urNp linux-2.6.20.3/mm/filemap.c linux-2.6.20.3/mm/filemap.c
28723 --- linux-2.6.20.3/mm/filemap.c 2007-03-13 14:27:08.000000000 -0400
28724 +++ linux-2.6.20.3/mm/filemap.c 2007-03-23 08:11:31.000000000 -0400
28726 #include <linux/security.h>
28727 #include <linux/syscalls.h>
28728 #include <linux/cpuset.h>
28729 +#include <linux/grsecurity.h>
28730 #include "filemap.h"
28731 #include "internal.h"
28733 @@ -1717,7 +1718,13 @@ int generic_file_mmap(struct file * file
28734 struct address_space *mapping = file->f_mapping;
28736 if (!mapping->a_ops->readpage)
28740 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
28741 + if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
28742 + vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
28745 file_accessed(file);
28746 vma->vm_ops = &generic_file_vm_ops;
28748 @@ -1955,6 +1962,7 @@ inline int generic_write_checks(struct f
28749 *pos = i_size_read(inode);
28751 if (limit != RLIM_INFINITY) {
28752 + gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
28753 if (*pos >= limit) {
28754 send_sig(SIGXFSZ, current, 0);
28756 diff -urNp linux-2.6.20.3/mm/filemap_xip.c linux-2.6.20.3/mm/filemap_xip.c
28757 --- linux-2.6.20.3/mm/filemap_xip.c 2007-03-13 14:27:08.000000000 -0400
28758 +++ linux-2.6.20.3/mm/filemap_xip.c 2007-03-23 08:10:06.000000000 -0400
28759 @@ -262,6 +262,11 @@ int xip_file_mmap(struct file * file, st
28761 BUG_ON(!file->f_mapping->a_ops->get_xip_page);
28763 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
28764 + if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
28765 + vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
28768 file_accessed(file);
28769 vma->vm_ops = &xip_file_vm_ops;
28771 diff -urNp linux-2.6.20.3/mm/madvise.c linux-2.6.20.3/mm/madvise.c
28772 --- linux-2.6.20.3/mm/madvise.c 2007-03-13 14:27:08.000000000 -0400
28773 +++ linux-2.6.20.3/mm/madvise.c 2007-03-23 08:10:06.000000000 -0400
28775 * We can potentially split a vm area into separate
28776 * areas, each area with its own behavior.
28779 +#ifdef CONFIG_PAX_SEGMEXEC
28780 +static long __madvise_behavior(struct vm_area_struct * vma,
28781 + struct vm_area_struct **prev,
28782 + unsigned long start, unsigned long end, int behavior);
28784 +static long madvise_behavior(struct vm_area_struct * vma,
28785 + struct vm_area_struct **prev,
28786 + unsigned long start, unsigned long end, int behavior)
28788 + if (vma->vm_flags & VM_MIRROR) {
28789 + struct vm_area_struct * vma_m, * prev_m;
28790 + unsigned long start_m, end_m;
28793 + start_m = vma->vm_start + vma->vm_mirror;
28794 + vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
28795 + if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
28796 + start_m = start + vma->vm_mirror;
28797 + end_m = end + vma->vm_mirror;
28798 + error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
28802 + printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
28807 + return __madvise_behavior(vma, prev, start, end, behavior);
28810 +static long __madvise_behavior(struct vm_area_struct * vma,
28811 + struct vm_area_struct **prev,
28812 + unsigned long start, unsigned long end, int behavior)
28814 static long madvise_behavior(struct vm_area_struct * vma,
28815 struct vm_area_struct **prev,
28816 unsigned long start, unsigned long end, int behavior)
28819 struct mm_struct * mm = vma->vm_mm;
28821 diff -urNp linux-2.6.20.3/mm/memory.c linux-2.6.20.3/mm/memory.c
28822 --- linux-2.6.20.3/mm/memory.c 2007-03-13 14:27:08.000000000 -0400
28823 +++ linux-2.6.20.3/mm/memory.c 2007-03-23 08:11:31.000000000 -0400
28825 #include <linux/delayacct.h>
28826 #include <linux/init.h>
28827 #include <linux/writeback.h>
28828 +#include <linux/grsecurity.h>
28830 #include <asm/pgalloc.h>
28831 #include <asm/uaccess.h>
28832 @@ -322,6 +323,11 @@ int __pte_alloc(struct mm_struct *mm, pm
28834 int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
28837 +#ifdef CONFIG_PAX_KERNEXEC
28838 + unsigned long cr0;
28841 pte_t *new = pte_alloc_one_kernel(&init_mm, address);
28844 @@ -329,8 +335,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
28845 spin_lock(&init_mm.page_table_lock);
28846 if (pmd_present(*pmd)) /* Another has populated it */
28847 pte_free_kernel(new);
28851 +#ifdef CONFIG_PAX_KERNEXEC
28852 + pax_open_kernel(cr0);
28855 pmd_populate_kernel(&init_mm, pmd, new);
28857 +#ifdef CONFIG_PAX_KERNEXEC
28858 + pax_close_kernel(cr0);
28862 spin_unlock(&init_mm.page_table_lock);
28865 @@ -995,7 +1012,7 @@ int get_user_pages(struct task_struct *t
28866 struct vm_area_struct *vma;
28867 unsigned int foll_flags;
28869 - vma = find_extend_vma(mm, start);
28870 + vma = find_vma(mm, start);
28871 if (!vma && in_gate_area(tsk, start)) {
28872 unsigned long pg = start & PAGE_MASK;
28873 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
28874 @@ -1035,7 +1052,7 @@ int get_user_pages(struct task_struct *t
28878 - if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
28879 + if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
28880 || !(vm_flags & vma->vm_flags))
28881 return i ? : -EFAULT;
28883 @@ -1469,6 +1486,88 @@ static inline void cow_user_page(struct
28884 copy_user_highpage(dst, src, va, vma);
28887 +#ifdef CONFIG_PAX_SEGMEXEC
28888 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
28890 + * the ptl of the lower mapped page is held on entry and is not released on exit
28891 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
28893 +static void pax_mirror_fault(struct vm_area_struct *vma, unsigned long address, pte_t *pte)
28895 + struct mm_struct *mm = vma->vm_mm;
28896 + unsigned long address_m, pfn_m;
28897 + struct vm_area_struct * vma_m = NULL;
28898 + pte_t * pte_m, entry_m;
28899 + struct page * page_m = NULL;
28901 + address_m = vma->vm_start + vma->vm_mirror;
28902 + vma_m = find_vma(mm, address_m);
28903 + BUG_ON(!vma_m || vma_m->vm_start != address_m);
28905 + address_m = address + vma->vm_mirror;
28906 + pte_m = pte_offset_map_nested(pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m), address_m);
28908 + if (pte_same(*pte, *pte_m)) {
28909 + pte_unmap_nested(pte_m);
28913 + pfn_m = pte_pfn(*pte);
28914 + if (pte_present(*pte_m)) {
28915 + page_m = vm_normal_page(vma_m, address_m, *pte_m);
28917 + flush_cache_page(vma_m, address_m, pfn_m);
28918 + flush_icache_page(vma_m, page_m);
28922 + if (pte_present(*pte_m))
28923 + entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
28925 + entry_m = ptep_get_and_clear(mm, address_m, pte_m);
28927 + if (pte_none(entry_m)) {
28928 + } else if (pte_present(entry_m)) {
28930 + page_remove_rmap(page_m, vma_m);
28931 + if (PageAnon(page_m))
28932 + dec_mm_counter(mm, anon_rss);
28934 + dec_mm_counter(mm, file_rss);
28935 + page_cache_release(page_m);
28937 + } else if (!pte_file(entry_m)) {
28938 + free_swap_and_cache(pte_to_swp_entry(entry_m));
28940 + printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
28941 + address, vma->vm_start, address_m, vma_m->vm_start);
28944 + page_m = vm_normal_page(vma, address, *pte);
28945 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
28946 + if (pte_write(*pte))
28947 + entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
28949 + page_cache_get(page_m);
28951 + * we can test PAGE_MAPPING_ANON without holding page_map_lock because
28952 + * we hold the page table lock and have a reference to page_m
28954 + if (PageAnon(page_m)) {
28955 + page_add_anon_rmap(page_m, vma_m, address_m);
28956 + inc_mm_counter(mm, anon_rss);
28958 + page_add_file_rmap(page_m);
28959 + inc_mm_counter(mm, file_rss);
28962 + set_pte_at(mm, address_m, pte_m, entry_m);
28963 + update_mmu_cache(vma_m, address_m, entry_m);
28964 + lazy_mmu_prot_update(entry_m);
28965 + pte_unmap_nested(pte_m);
28970 * This routine handles present pages, when users try to write
28971 * to a shared page. It is done by copying the page to a new address
28972 @@ -1612,6 +1711,12 @@ gotten:
28973 /* Free the old page.. */
28974 new_page = old_page;
28975 ret |= VM_FAULT_WRITE;
28977 +#ifdef CONFIG_PAX_SEGMEXEC
28978 + if (vma->vm_flags & VM_MIRROR)
28979 + pax_mirror_fault(vma, address, page_table);
28984 page_cache_release(new_page);
28985 @@ -1871,6 +1976,7 @@ int vmtruncate(struct inode * inode, lof
28988 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
28989 + gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
28990 if (limit != RLIM_INFINITY && offset > limit)
28992 if (offset > inode->i_sb->s_maxbytes)
28993 @@ -2064,6 +2170,12 @@ static int do_swap_page(struct mm_struct
28994 /* No need to invalidate - it was non-present before */
28995 update_mmu_cache(vma, address, pte);
28996 lazy_mmu_prot_update(pte);
28998 +#ifdef CONFIG_PAX_SEGMEXEC
28999 + if (vma->vm_flags & VM_MIRROR)
29000 + pax_mirror_fault(vma, address, page_table);
29004 pte_unmap_unlock(page_table, ptl);
29006 @@ -2126,6 +2238,12 @@ static int do_anonymous_page(struct mm_s
29007 /* No need to invalidate - it was non-present before */
29008 update_mmu_cache(vma, address, entry);
29009 lazy_mmu_prot_update(entry);
29011 +#ifdef CONFIG_PAX_SEGMEXEC
29012 + if (vma->vm_flags & VM_MIRROR)
29013 + pax_mirror_fault(vma, address, page_table);
29017 pte_unmap_unlock(page_table, ptl);
29018 return VM_FAULT_MINOR;
29019 @@ -2271,6 +2389,12 @@ retry:
29020 /* no need to invalidate: a not-present page shouldn't be cached */
29021 update_mmu_cache(vma, address, entry);
29022 lazy_mmu_prot_update(entry);
29024 +#ifdef CONFIG_PAX_SEGMEXEC
29025 + if (vma->vm_flags & VM_MIRROR)
29026 + pax_mirror_fault(vma, address, page_table);
29030 pte_unmap_unlock(page_table, ptl);
29032 @@ -2464,6 +2588,12 @@ static inline int handle_pte_fault(struc
29033 flush_tlb_page(vma, address);
29037 +#ifdef CONFIG_PAX_SEGMEXEC
29038 + if (vma->vm_flags & VM_MIRROR)
29039 + pax_mirror_fault(vma, address, pte);
29042 pte_unmap_unlock(pte, ptl);
29043 ret = VM_FAULT_MINOR;
29045 @@ -2460,6 +2590,49 @@ int __handle_mm_fault(struct mm_struct *
29046 if (unlikely(is_vm_hugetlb_page(vma)))
29047 return hugetlb_fault(mm, vma, address, write_access);
29049 +#ifdef CONFIG_PAX_SEGMEXEC
29050 + if (vma->vm_flags & VM_MIRROR) {
29051 + unsigned long address_m;
29052 + struct vm_area_struct * vma_m;
29057 + address_m = vma->vm_start + vma->vm_mirror;
29058 + vma_m = find_vma(mm, address_m);
29060 + /* PaX: sanity checks */
29062 + printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
29063 + address, vma, address_m, vma_m);
29064 + return VM_FAULT_SIGBUS;
29065 + } else if (!(vma_m->vm_flags & VM_MIRROR) ||
29066 + vma_m->vm_start != address_m ||
29067 + vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
29069 + printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
29070 + address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
29071 + return VM_FAULT_SIGBUS;
29074 + if (address_m < address) {
29075 + address += vma->vm_mirror;
29079 + address_m = address + vma->vm_mirror;
29080 + pgd_m = pgd_offset(mm, address_m);
29081 + pud_m = pud_alloc(mm, pgd_m, address_m);
29083 + return VM_FAULT_OOM;
29084 + pmd_m = pmd_alloc(mm, pud_m, address_m);
29086 + return VM_FAULT_OOM;
29087 + if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
29088 + return VM_FAULT_OOM;
29092 pgd = pgd_offset(mm, address);
29093 pud = pud_alloc(mm, pgd, address);
29095 diff -urNp linux-2.6.20.3/mm/mempolicy.c linux-2.6.20.3/mm/mempolicy.c
29096 --- linux-2.6.20.3/mm/mempolicy.c 2007-03-13 14:27:08.000000000 -0400
29097 +++ linux-2.6.20.3/mm/mempolicy.c 2007-03-23 08:10:06.000000000 -0400
29098 @@ -355,6 +355,12 @@ check_range(struct mm_struct *mm, unsign
29099 if (prev && prev->vm_end < vma->vm_start)
29100 return ERR_PTR(-EFAULT);
29103 +#ifdef CONFIG_PAX_SEGMEXEC
29104 + if (vma->vm_flags & VM_MIRROR)
29105 + return ERR_PTR(-EFAULT);
29108 if (!is_vm_hugetlb_page(vma) &&
29109 ((flags & MPOL_MF_STRICT) ||
29110 ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
29111 diff -urNp linux-2.6.20.3/mm/mlock.c linux-2.6.20.3/mm/mlock.c
29112 --- linux-2.6.20.3/mm/mlock.c 2007-03-13 14:27:08.000000000 -0400
29113 +++ linux-2.6.20.3/mm/mlock.c 2007-03-23 08:11:31.000000000 -0400
29114 @@ -11,44 +11,46 @@
29115 #include <linux/mempolicy.h>
29116 #include <linux/syscalls.h>
29117 #include <linux/vs_memory.h>
29118 +#include <linux/grsecurity.h>
29120 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
29121 + unsigned long start, unsigned long end, unsigned int newflags);
29123 static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
29124 unsigned long start, unsigned long end, unsigned int newflags)
29126 struct mm_struct * mm = vma->vm_mm;
29131 - if (newflags == vma->vm_flags) {
29136 - pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
29137 - *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
29138 - vma->vm_file, pgoff, vma_policy(vma));
29146 +#ifdef CONFIG_PAX_SEGMEXEC
29147 + struct vm_area_struct * vma_m = NULL, *prev_m;
29148 + unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
29150 + if (vma->vm_flags & VM_MIRROR) {
29151 + start_m = vma->vm_start + vma->vm_mirror;
29152 + vma_m = find_vma_prev(mm, start_m, &prev_m);
29153 + if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
29154 + printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
29158 - if (start != vma->vm_start) {
29159 - ret = split_vma(mm, vma, start, 1);
29160 + start_m = start + vma->vm_mirror;
29161 + end_m = end + vma->vm_mirror;
29162 + if (newflags & VM_LOCKED)
29163 + newflags_m = vma_m->vm_flags | VM_LOCKED;
29165 + newflags_m = vma_m->vm_flags & ~VM_LOCKED;
29166 + ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
29173 - if (end != vma->vm_end) {
29174 - ret = split_vma(mm, vma, end, 0);
29178 + ret = __mlock_fixup(vma, prev, start, end, newflags);
29184 * vm_flags is protected by the mmap_sem held in write mode.
29185 * It's okay if try_to_unmap_one unmaps a page just after we
29186 @@ -56,6 +58,11 @@ success:
29188 vma->vm_flags = newflags;
29190 +#ifdef CONFIG_PAX_SEGMEXEC
29191 + if (vma->vm_flags & VM_MIRROR)
29192 + vma_m->vm_flags = newflags_m;
29196 * Keep track of amount of locked VM.
29198 @@ -66,6 +73,48 @@ success:
29201 vx_vmlocked_sub(mm, pages);
29203 +#ifdef CONFIG_PAX_SEGMEXEC
29204 + if (vma->vm_flags & VM_MIRROR)
29205 + mm->locked_vm -= pages;
29208 + if (ret == -ENOMEM)
29213 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
29214 + unsigned long start, unsigned long end, unsigned int newflags)
29216 + struct mm_struct * mm = vma->vm_mm;
29220 + if (newflags == vma->vm_flags) {
29225 + pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
29226 + *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
29227 + vma->vm_file, pgoff, vma_policy(vma));
29235 + if (start != vma->vm_start) {
29236 + ret = split_vma(mm, vma, start, 1);
29241 + if (end != vma->vm_end)
29242 + ret = split_vma(mm, vma, end, 0);
29245 if (ret == -ENOMEM)
29247 @@ -85,6 +134,17 @@ static int do_mlock(unsigned long start,
29252 +#ifdef CONFIG_PAX_SEGMEXEC
29253 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
29254 + if (end > SEGMEXEC_TASK_SIZE)
29259 + if (end > TASK_SIZE)
29262 vma = find_vma_prev(current->mm, start, &prev);
29263 if (!vma || vma->vm_start > start)
29265 @@ -141,6 +201,7 @@ asmlinkage long sys_mlock(unsigned long
29266 lock_limit >>= PAGE_SHIFT;
29268 /* check against resource limits */
29269 + gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
29270 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
29271 error = do_mlock(start, len, 1);
29273 @@ -173,6 +234,16 @@ static int do_mlockall(int flags)
29274 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
29275 unsigned int newflags;
29277 +#ifdef CONFIG_PAX_SEGMEXEC
29278 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
29279 + if (vma->vm_end > SEGMEXEC_TASK_SIZE)
29284 + if (vma->vm_end > TASK_SIZE)
29287 newflags = vma->vm_flags | VM_LOCKED;
29288 if (!(flags & MCL_CURRENT))
29289 newflags &= ~VM_LOCKED;
29290 @@ -202,6 +273,7 @@ asmlinkage long sys_mlockall(int flags)
29291 lock_limit >>= PAGE_SHIFT;
29294 + gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
29295 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
29297 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
29298 diff -urNp linux-2.6.20.3/mm/mmap.c linux-2.6.20.3/mm/mmap.c
29299 --- linux-2.6.20.3/mm/mmap.c 2007-03-13 14:27:08.000000000 -0400
29300 +++ linux-2.6.20.3/mm/mmap.c 2007-03-23 08:11:31.000000000 -0400
29302 #include <linux/mount.h>
29303 #include <linux/mempolicy.h>
29304 #include <linux/rmap.h>
29305 +#include <linux/grsecurity.h>
29307 #include <asm/uaccess.h>
29308 #include <asm/cacheflush.h>
29309 @@ -251,6 +252,7 @@ asmlinkage unsigned long sys_brk(unsigne
29310 * not page aligned -Ram Gupta
29312 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
29313 + gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
29314 if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
29317 @@ -639,11 +641,17 @@ again: remove_next = 1 + (end > next->
29318 * If the vma has a ->close operation then the driver probably needs to release
29319 * per-vma resources, so we don't attempt to merge those.
29321 +#ifdef CONFIG_PAX_SEGMEXEC
29322 +#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
29324 #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
29327 static inline int is_mergeable_vma(struct vm_area_struct *vma,
29328 struct file *file, unsigned long vm_flags)
29330 + if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
29332 if (vma->vm_flags != vm_flags)
29334 if (vma->vm_file != file)
29335 @@ -868,14 +876,11 @@ none:
29336 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
29337 struct file *file, long pages)
29339 - const unsigned long stack_flags
29340 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
29343 mm->shared_vm += pages;
29344 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
29345 mm->exec_vm += pages;
29346 - } else if (flags & stack_flags)
29347 + } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
29348 mm->stack_vm += pages;
29349 if (flags & (VM_RESERVED|VM_IO))
29350 mm->reserved_vm += pages;
29351 @@ -886,10 +891,55 @@ void vm_stat_account(struct mm_struct *m
29352 * The caller must hold down_write(current->mm->mmap_sem).
29355 +#ifdef CONFIG_PAX_SEGMEXEC
29356 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
29357 + unsigned long len, unsigned long prot,
29358 + unsigned long flags, unsigned long pgoff);
29360 unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
29361 unsigned long len, unsigned long prot,
29362 unsigned long flags, unsigned long pgoff)
29364 + unsigned long ret = -EINVAL;
29366 + if (flags & MAP_MIRROR)
29369 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
29370 + (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
29373 + ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
29375 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
29377 +#ifdef CONFIG_PAX_MPROTECT
29378 + && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
29383 + unsigned long ret_m;
29384 + prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
29385 + ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
29386 + if (ret_m >= TASK_SIZE) {
29387 + do_munmap(current->mm, ret, len);
29395 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
29396 + unsigned long len, unsigned long prot,
29397 + unsigned long flags, unsigned long pgoff)
29399 +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
29400 + unsigned long len, unsigned long prot,
29401 + unsigned long flags, unsigned long pgoff)
29404 struct mm_struct * mm = current->mm;
29405 struct vm_area_struct * vma, * prev;
29406 struct inode *inode;
29407 @@ -900,13 +950,35 @@ unsigned long do_mmap_pgoff(struct file
29408 int accountable = 1;
29409 unsigned long charged = 0, reqprot = prot;
29411 +#ifdef CONFIG_PAX_SEGMEXEC
29412 + struct vm_area_struct * vma_m = NULL;
29414 + if (flags & MAP_MIRROR) {
29415 + /* PaX: sanity checks, to be removed when proved to be stable */
29416 + if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
29419 + vma_m = find_vma(mm, pgoff);
29421 + if (!vma_m || is_vm_hugetlb_page(vma_m) ||
29422 + vma_m->vm_start != pgoff ||
29423 + (vma_m->vm_flags & VM_SPECIAL) ||
29424 + (prot & PROT_WRITE))
29427 + file = vma_m->vm_file;
29428 + pgoff = vma_m->vm_pgoff;
29429 + len = vma_m->vm_end - vma_m->vm_start;
29434 * Does the application expect PROT_READ to imply PROT_EXEC?
29436 * (the exception is when the underlying filesystem is noexec
29437 * mounted, in which case we dont add PROT_EXEC.)
29439 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
29440 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
29441 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
29444 @@ -933,7 +1005,7 @@ unsigned long do_mmap_pgoff(struct file
29445 /* Obtain the address to map to. we verify (or select) it and ensure
29446 * that it represents a valid section of the address space.
29448 - addr = get_unmapped_area(file, addr, len, pgoff, flags);
29449 + addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
29450 if (addr & ~PAGE_MASK)
29453 @@ -944,6 +1016,21 @@ unsigned long do_mmap_pgoff(struct file
29454 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
29455 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
29457 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
29458 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29460 +#ifdef CONFIG_PAX_MPROTECT
29461 + if (mm->pax_flags & MF_PAX_MPROTECT) {
29462 + if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
29463 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
29465 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
29472 if (flags & MAP_LOCKED) {
29473 if (!can_do_mlock())
29475 @@ -956,6 +1043,7 @@ unsigned long do_mmap_pgoff(struct file
29476 locked += mm->locked_vm;
29477 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
29478 lock_limit >>= PAGE_SHIFT;
29479 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
29480 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
29483 @@ -1013,6 +1101,11 @@ unsigned long do_mmap_pgoff(struct file
29485 * Set pgoff according to addr for anon_vma.
29488 +#ifdef CONFIG_PAX_SEGMEXEC
29489 + if (!(flags & MAP_MIRROR))
29492 pgoff = addr >> PAGE_SHIFT;
29495 @@ -1024,14 +1117,17 @@ unsigned long do_mmap_pgoff(struct file
29499 + if (!gr_acl_handle_mmap(file, prot))
29502 /* Clear old maps */
29505 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
29506 if (vma && vma->vm_start < addr + len) {
29507 if (do_munmap(mm, addr, len))
29509 - goto munmap_back;
29510 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
29511 + BUG_ON(vma && vma->vm_start < addr + len);
29514 /* Check against address space limit. */
29515 @@ -1079,6 +1175,13 @@ munmap_back:
29516 vma->vm_start = addr;
29517 vma->vm_end = addr + len;
29518 vma->vm_flags = vm_flags;
29520 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
29521 + if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
29522 + vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29526 vma->vm_page_prot = protection_map[vm_flags &
29527 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29528 vma->vm_pgoff = pgoff;
29529 @@ -1104,6 +1207,14 @@ munmap_back:
29533 +#ifdef CONFIG_PAX_SEGMEXEC
29534 + if (flags & MAP_MIRROR) {
29535 + vma_m->vm_flags |= VM_MIRROR;
29536 + vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
29537 + vma->vm_mirror = vma_m->vm_start - vma->vm_start;
29541 /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
29542 * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
29543 * that memory reservation must be checked; but that reservation
29544 @@ -1121,9 +1232,17 @@ munmap_back:
29545 pgoff = vma->vm_pgoff;
29546 vm_flags = vma->vm_flags;
29548 - if (vma_wants_writenotify(vma))
29549 + if (vma_wants_writenotify(vma)) {
29551 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
29552 + if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
29553 + vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
29557 vma->vm_page_prot =
29558 protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
29561 if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
29562 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
29563 @@ -1143,6 +1262,7 @@ munmap_back:
29565 vx_vmpages_add(mm, len >> PAGE_SHIFT);
29566 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
29567 + track_exec_limit(mm, addr, addr + len, vm_flags);
29568 if (vm_flags & VM_LOCKED) {
29569 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
29570 make_pages_present(addr, addr + len);
29571 @@ -1197,6 +1317,10 @@ arch_get_unmapped_area(struct file *filp
29572 if (len > TASK_SIZE)
29575 +#ifdef CONFIG_PAX_RANDMMAP
29576 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
29580 addr = PAGE_ALIGN(addr);
29581 vma = find_vma(mm, addr);
29582 @@ -1207,7 +1331,7 @@ arch_get_unmapped_area(struct file *filp
29583 if (len > mm->cached_hole_size) {
29584 start_addr = addr = mm->free_area_cache;
29586 - start_addr = addr = TASK_UNMAPPED_BASE;
29587 + start_addr = addr = mm->mmap_base;
29588 mm->cached_hole_size = 0;
29591 @@ -1219,9 +1343,8 @@ full_search:
29592 * Start a new search - just in case we missed
29595 - if (start_addr != TASK_UNMAPPED_BASE) {
29596 - addr = TASK_UNMAPPED_BASE;
29597 - start_addr = addr;
29598 + if (start_addr != mm->mmap_base) {
29599 + start_addr = addr = mm->mmap_base;
29600 mm->cached_hole_size = 0;
29603 @@ -1246,7 +1369,7 @@ void arch_unmap_area(struct mm_struct *m
29605 * Is this a new hole at the lowest possible address?
29607 - if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
29608 + if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
29609 mm->free_area_cache = addr;
29610 mm->cached_hole_size = ~0UL;
29612 @@ -1264,12 +1387,16 @@ arch_get_unmapped_area_topdown(struct fi
29614 struct vm_area_struct *vma;
29615 struct mm_struct *mm = current->mm;
29616 - unsigned long addr = addr0;
29617 + unsigned long base = mm->mmap_base, addr = addr0;
29619 /* requested length too big for entire address space */
29620 if (len > TASK_SIZE)
29623 +#ifdef CONFIG_PAX_RANDMMAP
29624 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
29627 /* requesting a specific address */
29629 addr = PAGE_ALIGN(addr);
29630 @@ -1327,13 +1454,21 @@ bottomup:
29631 * can happen with large stack limits and large mmap()
29634 + mm->mmap_base = TASK_UNMAPPED_BASE;
29636 +#ifdef CONFIG_PAX_RANDMMAP
29637 + if (mm->pax_flags & MF_PAX_RANDMMAP)
29638 + mm->mmap_base += mm->delta_mmap;
29641 + mm->free_area_cache = mm->mmap_base;
29642 mm->cached_hole_size = ~0UL;
29643 - mm->free_area_cache = TASK_UNMAPPED_BASE;
29644 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
29646 * Restore the topdown base:
29648 - mm->free_area_cache = mm->mmap_base;
29649 + mm->mmap_base = base;
29650 + mm->free_area_cache = base;
29651 mm->cached_hole_size = ~0UL;
29654 @@ -1349,8 +1484,10 @@ void arch_unmap_area_topdown(struct mm_s
29655 mm->free_area_cache = addr;
29657 /* dont allow allocations above current base */
29658 - if (mm->free_area_cache > mm->mmap_base)
29659 + if (mm->free_area_cache > mm->mmap_base) {
29660 mm->free_area_cache = mm->mmap_base;
29661 + mm->cached_hole_size = ~0UL;
29666 @@ -1484,6 +1621,7 @@ static int acct_stack_growth(struct vm_a
29669 /* Stack limit test */
29670 + gr_learn_resource(current, RLIMIT_STACK, size, 1);
29671 if (size > rlim[RLIMIT_STACK].rlim_cur)
29674 @@ -1493,6 +1631,7 @@ static int acct_stack_growth(struct vm_a
29675 unsigned long limit;
29676 locked = mm->locked_vm + grow;
29677 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
29678 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
29679 if (locked > limit && !capable(CAP_IPC_LOCK))
29682 @@ -1571,23 +1710,6 @@ int expand_stack(struct vm_area_struct *
29684 return expand_upwards(vma, address);
29687 -struct vm_area_struct *
29688 -find_extend_vma(struct mm_struct *mm, unsigned long addr)
29690 - struct vm_area_struct *vma, *prev;
29692 - addr &= PAGE_MASK;
29693 - vma = find_vma_prev(mm, addr, &prev);
29694 - if (vma && (vma->vm_start <= addr))
29696 - if (!prev || expand_stack(prev, addr))
29698 - if (prev->vm_flags & VM_LOCKED) {
29699 - make_pages_present(addr, prev->vm_end);
29705 * vma is the first one with address < vma->vm_start. Have to extend vma.
29706 @@ -1616,41 +1738,54 @@ int expand_stack(struct vm_area_struct *
29707 if (address < vma->vm_start) {
29708 unsigned long size, grow;
29710 +#ifdef CONFIG_PAX_SEGMEXEC
29711 + struct vm_area_struct *vma_m = NULL;
29712 + unsigned long address_m = 0UL;
29714 + if (vma->vm_flags & VM_MIRROR) {
29715 + address_m = vma->vm_start + vma->vm_mirror;
29716 + vma_m = find_vma(vma->vm_mm, address_m);
29717 + if (!vma_m || vma_m->vm_start != address_m ||
29718 + !(vma_m->vm_flags & VM_MIRROR) ||
29719 + vma->vm_end - vma->vm_start !=
29720 + vma_m->vm_end - vma_m->vm_start ||
29721 + vma->anon_vma != vma_m->anon_vma) {
29722 + printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
29723 + address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
29724 + anon_vma_unlock(vma);
29727 + address_m = address + vma->vm_mirror;
29731 size = vma->vm_end - address;
29732 grow = (vma->vm_start - address) >> PAGE_SHIFT;
29734 +#ifdef CONFIG_PAX_SEGMEXEC
29736 + error = acct_stack_growth(vma, size, 2*grow);
29740 error = acct_stack_growth(vma, size, grow);
29742 vma->vm_start = address;
29743 vma->vm_pgoff -= grow;
29744 + track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
29746 +#ifdef CONFIG_PAX_SEGMEXEC
29748 + vma_m->vm_start = address_m;
29749 + vma_m->vm_pgoff -= grow;
29755 anon_vma_unlock(vma);
29759 -struct vm_area_struct *
29760 -find_extend_vma(struct mm_struct * mm, unsigned long addr)
29762 - struct vm_area_struct * vma;
29763 - unsigned long start;
29765 - addr &= PAGE_MASK;
29766 - vma = find_vma(mm,addr);
29769 - if (vma->vm_start <= addr)
29771 - if (!(vma->vm_flags & VM_GROWSDOWN))
29773 - start = vma->vm_start;
29774 - if (expand_stack(vma, addr))
29776 - if (vma->vm_flags & VM_LOCKED) {
29777 - make_pages_present(addr, start);
29784 @@ -1784,8 +1919,25 @@ int split_vma(struct mm_struct * mm, str
29785 * work. This now handles partial unmappings.
29786 * Jeremy Fitzhardinge <jeremy@goop.org>
29788 +#ifdef CONFIG_PAX_SEGMEXEC
29789 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
29791 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
29793 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
29794 + int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
29799 + return __do_munmap(mm, start, len);
29802 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
29804 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
29808 struct vm_area_struct *vma, *prev, *last;
29810 @@ -1838,6 +1990,8 @@ int do_munmap(struct mm_struct *mm, unsi
29811 /* Fix up all other VM information */
29812 remove_vma_list(mm, vma);
29814 + track_exec_limit(mm, start, end, 0UL);
29819 @@ -1850,6 +2004,12 @@ asmlinkage long sys_munmap(unsigned long
29821 profile_munmap(addr);
29823 +#ifdef CONFIG_PAX_SEGMEXEC
29824 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
29825 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
29829 down_write(&mm->mmap_sem);
29830 ret = do_munmap(mm, addr, len);
29831 up_write(&mm->mmap_sem);
29832 @@ -1871,11 +2031,35 @@ static inline void verify_mm_writelocked
29833 * anonymous maps. eventually we may be able to do some
29834 * brk-specific accounting here.
29836 +#ifdef CONFIG_PAX_SEGMEXEC
29837 +static unsigned long __do_brk(unsigned long addr, unsigned long len);
29839 +unsigned long do_brk(unsigned long addr, unsigned long len)
29841 + unsigned long ret;
29843 + ret = __do_brk(addr, len);
29844 + if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
29845 + unsigned long ret_m;
29847 + ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
29848 + if (ret_m > TASK_SIZE) {
29849 + do_munmap(current->mm, addr, len);
29857 +static unsigned long __do_brk(unsigned long addr, unsigned long len)
29859 unsigned long do_brk(unsigned long addr, unsigned long len)
29862 struct mm_struct * mm = current->mm;
29863 struct vm_area_struct * vma, * prev;
29864 - unsigned long flags;
29865 + unsigned long flags, task_size = TASK_SIZE;
29866 struct rb_node ** rb_link, * rb_parent;
29867 pgoff_t pgoff = addr >> PAGE_SHIFT;
29869 @@ -1884,7 +2068,12 @@ unsigned long do_brk(unsigned long addr,
29873 - if ((addr + len) > TASK_SIZE || (addr + len) < addr)
29874 +#ifdef CONFIG_PAX_SEGMEXEC
29875 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
29876 + task_size = SEGMEXEC_TASK_SIZE;
29879 + if ((addr + len) > task_size || (addr + len) < addr)
29882 if (is_hugepage_only_range(mm, addr, len))
29883 @@ -1892,6 +2081,18 @@ unsigned long do_brk(unsigned long addr,
29885 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
29887 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
29888 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29889 + flags &= ~VM_EXEC;
29891 +#ifdef CONFIG_PAX_MPROTECT
29892 + if (mm->pax_flags & MF_PAX_MPROTECT)
29893 + flags &= ~VM_MAYEXEC;
29899 error = arch_mmap_check(addr, len, flags);
29902 @@ -1905,6 +2106,7 @@ unsigned long do_brk(unsigned long addr,
29903 locked += mm->locked_vm;
29904 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
29905 lock_limit >>= PAGE_SHIFT;
29906 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
29907 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
29909 if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
29910 @@ -1920,12 +2122,12 @@ unsigned long do_brk(unsigned long addr,
29912 * Clear old maps. this also does some error checking for us
29915 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
29916 if (vma && vma->vm_start < addr + len) {
29917 if (do_munmap(mm, addr, len))
29919 - goto munmap_back;
29920 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
29921 + BUG_ON(vma && vma->vm_start < addr + len);
29924 /* Check against address space limits *after* clearing old maps... */
29925 @@ -1958,6 +2160,13 @@ unsigned long do_brk(unsigned long addr,
29926 vma->vm_end = addr + len;
29927 vma->vm_pgoff = pgoff;
29928 vma->vm_flags = flags;
29930 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
29931 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
29932 + vma->vm_page_prot = protection_map[(flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29936 vma->vm_page_prot = protection_map[flags &
29937 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29938 vma_link(mm, vma, prev, rb_link, rb_parent);
29939 @@ -1967,6 +2176,7 @@ out:
29940 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
29941 make_pages_present(addr, addr + len);
29943 + track_exec_limit(mm, addr, addr + len, flags);
29947 @@ -2105,7 +2315,7 @@ int may_expand_vm(struct mm_struct *mm,
29950 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
29952 + gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
29953 if (cur + npages > lim)
29955 if (!vx_vmpages_avail(mm, npages))
29956 diff -urNp linux-2.6.20.3/mm/mprotect.c linux-2.6.20.3/mm/mprotect.c
29957 --- linux-2.6.20.3/mm/mprotect.c 2007-03-13 14:27:08.000000000 -0400
29958 +++ linux-2.6.20.3/mm/mprotect.c 2007-03-23 08:27:30.000000000 -0400
29959 @@ -21,10 +21,17 @@
29960 #include <linux/syscalls.h>
29961 #include <linux/swap.h>
29962 #include <linux/swapops.h>
29963 +#include <linux/grsecurity.h>
29965 +#ifdef CONFIG_PAX_MPROTECT
29966 +#include <linux/elf.h>
29969 #include <asm/uaccess.h>
29970 #include <asm/pgtable.h>
29971 #include <asm/cacheflush.h>
29972 #include <asm/tlbflush.h>
29973 +#include <asm/mmu_context.h>
29975 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
29976 unsigned long addr, unsigned long end, pgprot_t newprot,
29977 @@ -128,6 +135,94 @@ static void change_protection(struct vm_
29978 flush_tlb_range(vma, start, end);
29981 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
29982 +/* called while holding the mmap semaphor for writing */
29983 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
29985 + struct vm_area_struct *vma = find_vma(mm, start);
29987 + for (; vma && vma->vm_start < end; vma = vma->vm_next)
29988 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
29992 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
29994 + unsigned long oldlimit, newlimit = 0UL;
29996 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
29999 + spin_lock(&mm->page_table_lock);
30000 + oldlimit = mm->context.user_cs_limit;
30001 + if ((prot & VM_EXEC) && oldlimit < end)
30002 + /* USER_CS limit moved up */
30004 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
30005 + /* USER_CS limit moved down */
30006 + newlimit = start;
30009 + mm->context.user_cs_limit = newlimit;
30013 + cpus_clear(mm->context.cpu_user_cs_mask);
30014 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
30017 + set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
30019 + spin_unlock(&mm->page_table_lock);
30020 + if (newlimit == end)
30021 + establish_user_cs_limit(mm, oldlimit, end);
30025 +#ifdef CONFIG_PAX_SEGMEXEC
30026 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
30027 + unsigned long start, unsigned long end, unsigned int newflags);
30029 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
30030 + unsigned long start, unsigned long end, unsigned int newflags)
30032 + if (vma->vm_flags & VM_MIRROR) {
30033 + struct vm_area_struct * vma_m, * prev_m;
30034 + unsigned long start_m, end_m;
30037 + start_m = vma->vm_start + vma->vm_mirror;
30038 + vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
30039 + if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
30040 + start_m = start + vma->vm_mirror;
30041 + end_m = end + vma->vm_mirror;
30043 + if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
30044 + error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
30046 + error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
30050 + printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
30055 + return __mprotect_fixup(vma, pprev, start, end, newflags);
30058 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
30059 + unsigned long start, unsigned long end, unsigned int newflags)
30061 + struct mm_struct * mm = vma->vm_mm;
30062 + unsigned long oldflags = vma->vm_flags;
30063 + long nrpages = (end - start) >> PAGE_SHIFT;
30064 + unsigned long charged = 0;
30067 + int dirty_accountable = 0;
30070 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
30071 unsigned long start, unsigned long end, unsigned long newflags)
30072 @@ -144,6 +239,7 @@ mprotect_fixup(struct vm_area_struct *vm
30079 * If we make a private mapping writable we increase our commit;
30080 @@ -193,12 +289,29 @@ success:
30081 * held in write mode.
30083 vma->vm_flags = newflags;
30084 - vma->vm_page_prot = protection_map[newflags &
30085 - (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
30086 if (vma_wants_writenotify(vma)) {
30088 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
30089 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
30090 + vma->vm_page_prot = protection_map[(newflags | VM_EXEC) &
30091 + (VM_READ|VM_WRITE|VM_EXEC)];
30095 vma->vm_page_prot = protection_map[newflags &
30096 (VM_READ|VM_WRITE|VM_EXEC)];
30097 dirty_accountable = 1;
30100 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
30101 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
30102 + vma->vm_page_prot = protection_map[(newflags | VM_EXEC) &
30103 + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
30107 + vma->vm_page_prot = protection_map[newflags &
30108 + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
30111 if (is_vm_hugetlb_page(vma))
30112 @@ -214,6 +327,69 @@ fail:
30116 +#ifdef CONFIG_PAX_MPROTECT
30117 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
30118 + * therefore we'll grant them VM_MAYWRITE once during their life.
30120 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
30121 + * basis because we want to allow the common case and not the special ones.
30123 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
30125 + struct elfhdr elf_h;
30126 + struct elf_phdr elf_p, p_dyn;
30128 + unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
30130 +#ifndef CONFIG_PAX_NOELFRELOCS
30131 + if ((vma->vm_start != start) ||
30133 + !(vma->vm_flags & VM_MAYEXEC) ||
30134 + (vma->vm_flags & VM_MAYNOTWRITE))
30139 + if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
30140 + memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
30142 +#ifdef CONFIG_PAX_ETEXECRELOCS
30143 + (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
30145 + elf_h.e_type != ET_DYN ||
30148 + !elf_check_arch(&elf_h) ||
30149 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
30150 + elf_h.e_phnum > j)
30153 + for (i = 0UL; i < elf_h.e_phnum; i++) {
30154 + if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
30156 + if (elf_p.p_type == PT_DYNAMIC) {
30161 + if (elf_h.e_phnum <= j)
30166 + if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
30168 + if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
30169 + vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
30170 + gr_log_textrel(vma);
30174 + } while (dyn.d_tag != DT_NULL);
30180 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
30182 @@ -233,6 +409,17 @@ sys_mprotect(unsigned long start, size_t
30187 +#ifdef CONFIG_PAX_SEGMEXEC
30188 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
30189 + if (end > SEGMEXEC_TASK_SIZE)
30194 + if (end > TASK_SIZE)
30197 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
30200 @@ -240,7 +427,7 @@ sys_mprotect(unsigned long start, size_t
30202 * Does the application expect PROT_READ to imply PROT_EXEC:
30204 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
30205 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
30208 vm_flags = calc_vm_prot_bits(prot);
30209 @@ -272,6 +459,16 @@ sys_mprotect(unsigned long start, size_t
30210 if (start > vma->vm_start)
30213 +#ifdef CONFIG_PAX_MPROTECT
30214 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
30215 + pax_handle_maywrite(vma, start);
30218 + if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
30223 for (nstart = start ; ; ) {
30224 unsigned long newflags;
30226 @@ -285,6 +482,12 @@ sys_mprotect(unsigned long start, size_t
30230 +#ifdef CONFIG_PAX_MPROTECT
30231 + /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
30232 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
30233 + newflags &= ~VM_MAYWRITE;
30236 error = security_file_mprotect(vma, reqprot, prot);
30239 @@ -308,6 +511,9 @@ sys_mprotect(unsigned long start, size_t
30244 + track_exec_limit(current->mm, start, end, vm_flags);
30247 up_write(¤t->mm->mmap_sem);
30249 diff -urNp linux-2.6.20.3/mm/mremap.c linux-2.6.20.3/mm/mremap.c
30250 --- linux-2.6.20.3/mm/mremap.c 2007-03-13 14:27:08.000000000 -0400
30251 +++ linux-2.6.20.3/mm/mremap.c 2007-03-23 08:10:06.000000000 -0400
30252 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
30254 pte = ptep_clear_flush(vma, old_addr, old_pte);
30255 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
30257 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
30258 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
30259 + pte_exprotect(pte);
30262 set_pte_at(mm, new_addr, new_pte, pte);
30265 @@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
30266 struct vm_area_struct *vma;
30267 unsigned long ret = -EINVAL;
30268 unsigned long charged = 0;
30269 + unsigned long task_size = TASK_SIZE;
30271 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
30273 @@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
30277 +#ifdef CONFIG_PAX_SEGMEXEC
30278 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
30279 + task_size = SEGMEXEC_TASK_SIZE;
30282 + if (new_len > task_size || addr > task_size-new_len ||
30283 + old_len > task_size || addr > task_size-old_len)
30286 /* new_addr is only valid if MREMAP_FIXED is specified */
30287 if (flags & MREMAP_FIXED) {
30288 if (new_addr & ~PAGE_MASK)
30289 @@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
30290 if (!(flags & MREMAP_MAYMOVE))
30293 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
30294 + if (new_addr > task_size - new_len)
30297 /* Check if the location we're moving into overlaps the
30298 * old location at all, and fail if it does.
30300 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
30303 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
30304 + if (addr + old_len > new_addr && new_addr + new_len > addr)
30307 ret = do_munmap(mm, new_addr, new_len);
30308 @@ -322,6 +335,14 @@ unsigned long do_mremap(unsigned long ad
30313 +#ifdef CONFIG_PAX_SEGMEXEC
30314 + if (vma->vm_flags & VM_MIRROR) {
30320 /* We can't remap across vm area boundaries */
30321 if (old_len > vma->vm_end - addr)
30323 @@ -355,7 +376,7 @@ unsigned long do_mremap(unsigned long ad
30324 if (old_len == vma->vm_end - addr &&
30325 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
30326 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
30327 - unsigned long max_addr = TASK_SIZE;
30328 + unsigned long max_addr = task_size;
30330 max_addr = vma->vm_next->vm_start;
30331 /* can we just expand the current mapping? */
30332 @@ -373,6 +394,7 @@ unsigned long do_mremap(unsigned long ad
30336 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
30340 @@ -383,8 +405,8 @@ unsigned long do_mremap(unsigned long ad
30343 if (flags & MREMAP_MAYMOVE) {
30344 + unsigned long map_flags = 0;
30345 if (!(flags & MREMAP_FIXED)) {
30346 - unsigned long map_flags = 0;
30347 if (vma->vm_flags & VM_MAYSHARE)
30348 map_flags |= MAP_SHARED;
30350 @@ -394,7 +416,12 @@ unsigned long do_mremap(unsigned long ad
30351 if (new_addr & ~PAGE_MASK)
30354 + map_flags = vma->vm_flags;
30355 ret = move_vma(vma, addr, old_len, new_len, new_addr);
30356 + if (!(ret & ~PAGE_MASK)) {
30357 + track_exec_limit(current->mm, addr, addr + old_len, 0UL);
30358 + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
30362 if (ret & ~PAGE_MASK)
30363 diff -urNp linux-2.6.20.3/mm/nommu.c linux-2.6.20.3/mm/nommu.c
30364 --- linux-2.6.20.3/mm/nommu.c 2007-03-13 14:27:08.000000000 -0400
30365 +++ linux-2.6.20.3/mm/nommu.c 2007-03-23 08:10:06.000000000 -0400
30366 @@ -350,15 +350,6 @@ struct vm_area_struct *find_vma(struct m
30367 EXPORT_SYMBOL(find_vma);
30371 - * - we don't extend stack VMAs under NOMMU conditions
30373 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
30375 - return find_vma(mm, addr);
30379 * look up the first VMA exactly that exactly matches addr
30380 * - should be called with mm->mmap_sem at least held readlocked
30382 diff -urNp linux-2.6.20.3/mm/page_alloc.c linux-2.6.20.3/mm/page_alloc.c
30383 --- linux-2.6.20.3/mm/page_alloc.c 2007-03-13 14:27:08.000000000 -0400
30384 +++ linux-2.6.20.3/mm/page_alloc.c 2007-03-23 08:10:06.000000000 -0400
30385 @@ -384,7 +384,7 @@ static inline int page_is_buddy(struct p
30386 static inline void __free_one_page(struct page *page,
30387 struct zone *zone, unsigned int order)
30389 - unsigned long page_idx;
30390 + unsigned long page_idx, index;
30391 int order_size = 1 << order;
30393 if (unlikely(PageCompound(page)))
30394 @@ -395,6 +395,11 @@ static inline void __free_one_page(struc
30395 VM_BUG_ON(page_idx & (order_size - 1));
30396 VM_BUG_ON(bad_range(zone, page));
30398 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
30399 + for (index = order_size; index; --index)
30400 + sanitize_highpage(page + index - 1);
30403 zone->free_pages += order_size;
30404 while (order < MAX_ORDER-1) {
30405 unsigned long combined_idx;
30406 diff -urNp linux-2.6.20.3/mm/rmap.c linux-2.6.20.3/mm/rmap.c
30407 --- linux-2.6.20.3/mm/rmap.c 2007-03-13 14:27:08.000000000 -0400
30408 +++ linux-2.6.20.3/mm/rmap.c 2007-03-23 08:10:06.000000000 -0400
30409 @@ -100,6 +100,19 @@ int anon_vma_prepare(struct vm_area_stru
30410 vma->anon_vma = anon_vma;
30411 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
30414 +#ifdef CONFIG_PAX_SEGMEXEC
30415 + if (vma->vm_flags & VM_MIRROR) {
30416 + struct vm_area_struct *vma_m;
30418 + vma_m = find_vma(mm, vma->vm_start + vma->vm_mirror);
30419 + BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
30420 + BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
30421 + vma_m->anon_vma = anon_vma;
30422 + __anon_vma_link(vma_m);
30427 spin_unlock(&mm->page_table_lock);
30429 diff -urNp linux-2.6.20.3/mm/shmem.c linux-2.6.20.3/mm/shmem.c
30430 --- linux-2.6.20.3/mm/shmem.c 2007-03-13 14:27:08.000000000 -0400
30431 +++ linux-2.6.20.3/mm/shmem.c 2007-03-23 08:11:31.000000000 -0400
30432 @@ -2416,7 +2416,7 @@ static struct file_system_type tmpfs_fs_
30433 .get_sb = shmem_get_sb,
30434 .kill_sb = kill_litter_super,
30436 -static struct vfsmount *shm_mnt;
30437 +struct vfsmount *shm_mnt;
30439 static int __init init_tmpfs(void)
30441 diff -urNp linux-2.6.20.3/mm/slab.c linux-2.6.20.3/mm/slab.c
30442 --- linux-2.6.20.3/mm/slab.c 2007-03-13 14:27:08.000000000 -0400
30443 +++ linux-2.6.20.3/mm/slab.c 2007-03-23 08:10:06.000000000 -0400
30444 @@ -305,7 +305,7 @@ struct kmem_list3 {
30445 * Need this for bootstrapping a per node allocator.
30447 #define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
30448 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
30449 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
30450 #define CACHE_CACHE 0
30452 #define SIZE_L3 (1 + MAX_NUMNODES)
30453 @@ -662,14 +662,14 @@ struct cache_names {
30454 static struct cache_names __initdata cache_names[] = {
30455 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
30456 #include <linux/kmalloc_sizes.h>
30462 static struct arraycache_init initarray_cache __initdata =
30463 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
30464 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
30465 static struct arraycache_init initarray_generic =
30466 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
30467 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
30469 /* internal cache of cache description objs */
30470 static struct kmem_cache cache_cache = {
30471 @@ -1694,6 +1694,11 @@ static void store_stackinfo(struct kmem_
30473 while (!kstack_end(sptr)) {
30476 +#ifdef CONFIG_PAX_KERNEXEC
30477 + svalue += __KERNEL_TEXT_OFFSET;
30480 if (kernel_text_address(svalue)) {
30482 size -= sizeof(unsigned long);
30483 diff -urNp linux-2.6.20.3/mm/swap.c linux-2.6.20.3/mm/swap.c
30484 --- linux-2.6.20.3/mm/swap.c 2007-03-13 14:27:08.000000000 -0400
30485 +++ linux-2.6.20.3/mm/swap.c 2007-03-23 08:10:06.000000000 -0400
30486 @@ -174,8 +174,8 @@ EXPORT_SYMBOL(mark_page_accessed);
30487 * lru_cache_add: add a page to the page lists
30488 * @page: the page to add
30490 -static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
30491 -static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
30492 +static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} };
30493 +static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} };
30495 void fastcall lru_cache_add(struct page *page)
30497 diff -urNp linux-2.6.20.3/mm/thrash.c linux-2.6.20.3/mm/thrash.c
30498 --- linux-2.6.20.3/mm/thrash.c 2007-03-13 14:27:08.000000000 -0400
30499 +++ linux-2.6.20.3/mm/thrash.c 2007-03-23 08:10:06.000000000 -0400
30500 @@ -48,9 +48,8 @@ void grab_swap_token(void)
30501 if (current_interval < current->mm->last_interval)
30502 current->mm->token_priority++;
30504 - current->mm->token_priority--;
30505 - if (unlikely(current->mm->token_priority < 0))
30506 - current->mm->token_priority = 0;
30507 + if (likely(current->mm->token_priority > 0))
30508 + current->mm->token_priority--;
30510 /* Check if we deserve the token */
30511 if (current->mm->token_priority >
30512 diff -urNp linux-2.6.20.3/mm/tiny-shmem.c linux-2.6.20.3/mm/tiny-shmem.c
30513 --- linux-2.6.20.3/mm/tiny-shmem.c 2007-03-13 14:27:08.000000000 -0400
30514 +++ linux-2.6.20.3/mm/tiny-shmem.c 2007-03-23 08:11:31.000000000 -0400
30515 @@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
30516 .kill_sb = kill_litter_super,
30519 -static struct vfsmount *shm_mnt;
30520 +struct vfsmount *shm_mnt;
30522 static int __init init_tmpfs(void)
30524 diff -urNp linux-2.6.20.3/mm/vmalloc.c linux-2.6.20.3/mm/vmalloc.c
30525 --- linux-2.6.20.3/mm/vmalloc.c 2007-03-13 14:27:08.000000000 -0400
30526 +++ linux-2.6.20.3/mm/vmalloc.c 2007-03-23 08:10:06.000000000 -0400
30527 @@ -195,6 +195,8 @@ static struct vm_struct *__get_vm_area_n
30529 write_lock(&vmlist_lock);
30530 for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
30531 + if (addr > end - size)
30533 if ((unsigned long)tmp->addr < addr) {
30534 if((unsigned long)tmp->addr + tmp->size >= addr)
30535 addr = ALIGN(tmp->size +
30536 @@ -206,8 +208,6 @@ static struct vm_struct *__get_vm_area_n
30537 if (size + addr <= (unsigned long)tmp->addr)
30539 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
30540 - if (addr > end - size)
30545 diff -urNp linux-2.6.20.3/net/core/flow.c linux-2.6.20.3/net/core/flow.c
30546 --- linux-2.6.20.3/net/core/flow.c 2007-03-13 14:27:08.000000000 -0400
30547 +++ linux-2.6.20.3/net/core/flow.c 2007-03-23 08:10:06.000000000 -0400
30548 @@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
30550 static u32 flow_hash_shift;
30551 #define flow_hash_size (1 << flow_hash_shift)
30552 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
30553 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
30555 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
30557 @@ -53,7 +53,7 @@ struct flow_percpu_info {
30560 } ____cacheline_aligned;
30561 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
30562 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
30564 #define flow_hash_rnd_recalc(cpu) \
30565 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
30566 @@ -70,7 +70,7 @@ struct flow_flush_info {
30568 struct completion completion;
30570 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
30571 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
30573 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
30575 diff -urNp linux-2.6.20.3/net/core/sock.c linux-2.6.20.3/net/core/sock.c
30576 --- linux-2.6.20.3/net/core/sock.c 2007-03-13 14:27:08.000000000 -0400
30577 +++ linux-2.6.20.3/net/core/sock.c 2007-03-23 08:10:06.000000000 -0400
30578 @@ -808,7 +808,7 @@ lenout:
30580 * (We also register the sk_lock with the lock validator.)
30582 -static void inline sock_lock_init(struct sock *sk)
30583 +static inline void sock_lock_init(struct sock *sk)
30585 sock_lock_init_class_and_name(sk,
30586 af_family_slock_key_strings[sk->sk_family],
30587 diff -urNp linux-2.6.20.3/net/dccp/ccids/ccid3.c linux-2.6.20.3/net/dccp/ccids/ccid3.c
30588 --- linux-2.6.20.3/net/dccp/ccids/ccid3.c 2007-03-13 14:27:08.000000000 -0400
30589 +++ linux-2.6.20.3/net/dccp/ccids/ccid3.c 2007-03-23 08:10:06.000000000 -0400
30591 static int ccid3_debug;
30592 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
30594 -#define ccid3_pr_debug(format, a...)
30595 +#define ccid3_pr_debug(format, a...) do {} while (0)
30598 static struct dccp_tx_hist *ccid3_tx_hist;
30599 @@ -784,7 +784,7 @@ static u32 ccid3_hc_rx_calc_first_li(str
30600 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
30602 suseconds_t rtt, delta;
30603 - struct timeval tstamp = { 0, };
30604 + struct timeval tstamp = { 0, 0 };
30608 diff -urNp linux-2.6.20.3/net/dccp/dccp.h linux-2.6.20.3/net/dccp/dccp.h
30609 --- linux-2.6.20.3/net/dccp/dccp.h 2007-03-13 14:27:08.000000000 -0400
30610 +++ linux-2.6.20.3/net/dccp/dccp.h 2007-03-23 08:10:06.000000000 -0400
30611 @@ -46,8 +46,8 @@ extern int dccp_debug;
30612 #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
30613 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
30615 -#define dccp_pr_debug(format, a...)
30616 -#define dccp_pr_debug_cat(format, a...)
30617 +#define dccp_pr_debug(format, a...) do {} while (0)
30618 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
30621 extern struct inet_hashinfo dccp_hashinfo;
30622 diff -urNp linux-2.6.20.3/net/ipv4/inet_connection_sock.c linux-2.6.20.3/net/ipv4/inet_connection_sock.c
30623 --- linux-2.6.20.3/net/ipv4/inet_connection_sock.c 2007-03-13 14:27:08.000000000 -0400
30624 +++ linux-2.6.20.3/net/ipv4/inet_connection_sock.c 2007-03-23 08:11:31.000000000 -0400
30627 #include <linux/module.h>
30628 #include <linux/jhash.h>
30629 +#include <linux/grsecurity.h>
30631 #include <net/inet_connection_sock.h>
30632 #include <net/inet_hashtables.h>
30633 diff -urNp linux-2.6.20.3/net/ipv4/inet_hashtables.c linux-2.6.20.3/net/ipv4/inet_hashtables.c
30634 --- linux-2.6.20.3/net/ipv4/inet_hashtables.c 2007-03-13 14:27:08.000000000 -0400
30635 +++ linux-2.6.20.3/net/ipv4/inet_hashtables.c 2007-03-23 08:11:31.000000000 -0400
30636 @@ -18,11 +18,14 @@
30637 #include <linux/sched.h>
30638 #include <linux/slab.h>
30639 #include <linux/wait.h>
30640 +#include <linux/grsecurity.h>
30642 #include <net/inet_connection_sock.h>
30643 #include <net/inet_hashtables.h>
30644 #include <net/ip.h>
30646 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
30649 * Allocate and initialize a new local port bind bucket.
30650 * The bindhash mutex for snum's hash chain must be held here.
30651 @@ -338,6 +341,8 @@ ok:
30653 spin_unlock(&head->lock);
30655 + gr_update_task_in_ip_table(current, inet_sk(sk));
30658 inet_twsk_deschedule(tw, death_row);
30660 diff -urNp linux-2.6.20.3/net/ipv4/netfilter/ipt_stealth.c linux-2.6.20.3/net/ipv4/netfilter/ipt_stealth.c
30661 --- linux-2.6.20.3/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
30662 +++ linux-2.6.20.3/net/ipv4/netfilter/ipt_stealth.c 2007-03-23 08:11:31.000000000 -0400
30664 +/* Kernel module to add stealth support.
30666 + * Copyright (C) 2002-2006 Brad Spengler <spender@grsecurity.net>
30670 +#include <linux/kernel.h>
30671 +#include <linux/module.h>
30672 +#include <linux/skbuff.h>
30673 +#include <linux/net.h>
30674 +#include <linux/sched.h>
30675 +#include <linux/inet.h>
30676 +#include <linux/stddef.h>
30678 +#include <net/ip.h>
30679 +#include <net/sock.h>
30680 +#include <net/tcp.h>
30681 +#include <net/udp.h>
30682 +#include <net/route.h>
30683 +#include <net/inet_common.h>
30685 +#include <linux/netfilter_ipv4/ip_tables.h>
30687 +MODULE_LICENSE("GPL");
30689 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
30692 +match(const struct sk_buff *skb,
30693 + const struct net_device *in,
30694 + const struct net_device *out,
30695 + const struct xt_match *match,
30696 + const void *matchinfo,
30698 + unsigned int protoff,
30701 + struct iphdr *ip = skb->nh.iph;
30702 + struct tcphdr th;
30703 + struct udphdr uh;
30704 + struct sock *sk = NULL;
30706 + if (!ip || offset) return 0;
30708 + switch(ip->protocol) {
30709 + case IPPROTO_TCP:
30710 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
30714 + if (!(th.syn && !th.ack)) return 0;
30715 + sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);
30717 + case IPPROTO_UDP:
30718 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
30722 + sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
30728 + if(!sk) // port is being listened on, match this
30736 +/* Called when user tries to insert an entry of this type. */
30738 +checkentry(const char *tablename,
30740 + const struct xt_match *match,
30742 + unsigned int hook_mask)
30744 + const struct ipt_ip *ip = (const struct ipt_ip *)nip;
30746 + if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
30747 + ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
30748 + && (hook_mask & (1 << NF_IP_LOCAL_IN)))
30751 + printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
30757 +static struct ipt_match stealth_match = {
30758 + .name = "stealth",
30760 + .checkentry = checkentry,
30762 + .me = THIS_MODULE
30765 +static int __init init(void)
30767 + return ipt_register_match(&stealth_match);
30770 +static void __exit fini(void)
30772 + ipt_unregister_match(&stealth_match);
30775 +module_init(init);
30776 +module_exit(fini);
30777 diff -urNp linux-2.6.20.3/net/ipv4/netfilter/Kconfig linux-2.6.20.3/net/ipv4/netfilter/Kconfig
30778 --- linux-2.6.20.3/net/ipv4/netfilter/Kconfig 2007-03-13 14:27:08.000000000 -0400
30779 +++ linux-2.6.20.3/net/ipv4/netfilter/Kconfig 2007-03-23 08:11:31.000000000 -0400
30780 @@ -330,6 +330,21 @@ config IP_NF_MATCH_ADDRTYPE
30781 If you want to compile it as a module, say M here and read
30782 <file:Documentation/modules.txt>. If unsure, say `N'.
30784 +config IP_NF_MATCH_STEALTH
30785 + tristate "stealth match support"
30786 + depends on IP_NF_IPTABLES
30788 + Enabling this option will drop all syn packets coming to unserved tcp
30789 + ports as well as all packets coming to unserved udp ports. If you
30790 + are using your system to route any type of packets (ie. via NAT)
30791 + you should put this module at the end of your ruleset, since it will
30792 + drop packets that aren't going to ports that are listening on your
30793 + machine itself, it doesn't take into account that the packet might be
30794 + destined for someone on your internal network if you're using NAT for
30797 + To compile it as a module, choose M here. If unsure, say N.
30799 # `filter', generic and specific targets
30800 config IP_NF_FILTER
30801 tristate "Packet filtering"
30802 diff -urNp linux-2.6.20.3/net/ipv4/netfilter/Makefile linux-2.6.20.3/net/ipv4/netfilter/Makefile
30803 --- linux-2.6.20.3/net/ipv4/netfilter/Makefile 2007-03-13 14:27:08.000000000 -0400
30804 +++ linux-2.6.20.3/net/ipv4/netfilter/Makefile 2007-03-23 08:11:31.000000000 -0400
30805 @@ -104,6 +104,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn
30806 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
30807 obj-$(CONFIG_IP_NF_MATCH_SET) += ipt_set.o
30808 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
30809 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
30811 obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o
30813 diff -urNp linux-2.6.20.3/net/ipv4/tcp_ipv4.c linux-2.6.20.3/net/ipv4/tcp_ipv4.c
30814 --- linux-2.6.20.3/net/ipv4/tcp_ipv4.c 2007-03-13 14:27:08.000000000 -0400
30815 +++ linux-2.6.20.3/net/ipv4/tcp_ipv4.c 2007-03-23 08:11:31.000000000 -0400
30817 #include <linux/jhash.h>
30818 #include <linux/init.h>
30819 #include <linux/times.h>
30820 +#include <linux/grsecurity.h>
30822 #include <net/icmp.h>
30823 #include <net/inet_hashtables.h>
30824 diff -urNp linux-2.6.20.3/net/ipv4/udp.c linux-2.6.20.3/net/ipv4/udp.c
30825 --- linux-2.6.20.3/net/ipv4/udp.c 2007-03-13 14:27:08.000000000 -0400
30826 +++ linux-2.6.20.3/net/ipv4/udp.c 2007-03-23 08:11:31.000000000 -0400
30827 @@ -97,12 +97,19 @@
30828 #include <linux/skbuff.h>
30829 #include <linux/proc_fs.h>
30830 #include <linux/seq_file.h>
30831 +#include <linux/grsecurity.h>
30832 #include <net/icmp.h>
30833 #include <net/route.h>
30834 #include <net/checksum.h>
30835 #include <net/xfrm.h>
30836 #include "udp_impl.h"
30838 +extern int gr_search_udp_recvmsg(const struct sock *sk,
30839 + const struct sk_buff *skb);
30840 +extern int gr_search_udp_sendmsg(const struct sock *sk,
30841 + const struct sockaddr_in *addr);
30845 * Snmp MIB for the UDP layer
30847 @@ -284,6 +291,13 @@ static struct sock *__udp4_lib_lookup(__
30851 +struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
30852 + __be32 daddr, __be16 dport, int dif)
30854 + return __udp4_lib_lookup(saddr, sport, daddr, dport, dif, udp_hash);
30858 static inline struct sock *udp_v4_mcast_next(struct sock *sk,
30859 __be16 loc_port, __be32 loc_addr,
30860 __be16 rmt_port, __be32 rmt_addr,
30861 @@ -566,9 +580,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
30862 dport = usin->sin_port;
30866 + if (!gr_search_udp_sendmsg(sk, usin))
30869 if (sk->sk_state != TCP_ESTABLISHED)
30870 return -EDESTADDRREQ;
30872 + if (!gr_search_udp_sendmsg(sk, NULL))
30875 daddr = inet->daddr;
30876 dport = inet->dport;
30877 /* Open fast path for connected socket.
30878 @@ -825,6 +846,11 @@ try_again:
30882 + if (!gr_search_udp_recvmsg(sk, skb)) {
30887 copied = skb->len - sizeof(struct udphdr);
30888 if (copied > len) {
30890 diff -urNp linux-2.6.20.3/net/ipv6/addrconf.c linux-2.6.20.3/net/ipv6/addrconf.c
30891 --- linux-2.6.20.3/net/ipv6/addrconf.c 2007-03-13 14:27:08.000000000 -0400
30892 +++ linux-2.6.20.3/net/ipv6/addrconf.c 2007-03-23 08:10:06.000000000 -0400
30893 @@ -877,7 +877,7 @@ struct ipv6_saddr_score {
30894 #define IPV6_SADDR_SCORE_LABEL 0x0020
30895 #define IPV6_SADDR_SCORE_PRIVACY 0x0040
30897 -static int inline ipv6_saddr_preferred(int type)
30898 +static inline int ipv6_saddr_preferred(int type)
30900 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
30901 IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
30902 @@ -886,7 +886,7 @@ static int inline ipv6_saddr_preferred(i
30905 /* static matching label */
30906 -static int inline ipv6_saddr_label(const struct in6_addr *addr, int type)
30907 +static inline int ipv6_saddr_label(const struct in6_addr *addr, int type)
30910 * prefix (longest match) label
30911 @@ -3365,7 +3365,7 @@ errout:
30912 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
30915 -static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
30916 +static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
30917 __s32 *array, int bytes)
30919 BUG_ON(bytes < (DEVCONF_MAX * 4));
30920 diff -urNp linux-2.6.20.3/net/ipv6/exthdrs.c linux-2.6.20.3/net/ipv6/exthdrs.c
30921 --- linux-2.6.20.3/net/ipv6/exthdrs.c 2007-03-13 14:27:08.000000000 -0400
30922 +++ linux-2.6.20.3/net/ipv6/exthdrs.c 2007-03-23 08:10:06.000000000 -0400
30923 @@ -691,7 +691,7 @@ static struct tlvtype_proc tlvprochopopt
30924 .type = IPV6_TLV_JUMBO,
30925 .func = ipv6_hop_jumbo,
30931 int ipv6_parse_hopopts(struct sk_buff **skbp)
30932 diff -urNp linux-2.6.20.3/net/ipv6/raw.c linux-2.6.20.3/net/ipv6/raw.c
30933 --- linux-2.6.20.3/net/ipv6/raw.c 2007-03-13 14:27:08.000000000 -0400
30934 +++ linux-2.6.20.3/net/ipv6/raw.c 2007-03-23 08:10:06.000000000 -0400
30935 @@ -548,7 +548,7 @@ out:
30939 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
30940 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
30941 struct flowi *fl, struct rt6_info *rt,
30942 unsigned int flags)
30944 diff -urNp linux-2.6.20.3/net/ipv6/route.c linux-2.6.20.3/net/ipv6/route.c
30945 --- linux-2.6.20.3/net/ipv6/route.c 2007-03-13 14:27:08.000000000 -0400
30946 +++ linux-2.6.20.3/net/ipv6/route.c 2007-03-23 08:10:06.000000000 -0400
30947 @@ -308,7 +308,7 @@ static inline void rt6_probe(struct rt6_
30949 * Default Router Selection (RFC 2461 6.3.6)
30951 -static int inline rt6_check_dev(struct rt6_info *rt, int oif)
30952 +static inline int rt6_check_dev(struct rt6_info *rt, int oif)
30954 struct net_device *dev = rt->rt6i_dev;
30955 if (!oif || dev->ifindex == oif)
30956 @@ -319,7 +319,7 @@ static int inline rt6_check_dev(struct r
30960 -static int inline rt6_check_neigh(struct rt6_info *rt)
30961 +static inline int rt6_check_neigh(struct rt6_info *rt)
30963 struct neighbour *neigh = rt->rt6i_nexthop;
30965 diff -urNp linux-2.6.20.3/net/ipv6/xfrm6_tunnel.c linux-2.6.20.3/net/ipv6/xfrm6_tunnel.c
30966 --- linux-2.6.20.3/net/ipv6/xfrm6_tunnel.c 2007-03-13 14:27:08.000000000 -0400
30967 +++ linux-2.6.20.3/net/ipv6/xfrm6_tunnel.c 2007-03-23 08:10:06.000000000 -0400
30968 @@ -58,7 +58,7 @@ static struct kmem_cache *xfrm6_tunnel_s
30969 static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
30970 static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
30972 -static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
30973 +static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
30977 @@ -70,7 +70,7 @@ static unsigned inline xfrm6_tunnel_spi_
30981 -static unsigned inline xfrm6_tunnel_spi_hash_byspi(u32 spi)
30982 +static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
30984 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
30986 diff -urNp linux-2.6.20.3/net/sctp/sm_statetable.c linux-2.6.20.3/net/sctp/sm_statetable.c
30987 --- linux-2.6.20.3/net/sctp/sm_statetable.c 2007-03-13 14:27:08.000000000 -0400
30988 +++ linux-2.6.20.3/net/sctp/sm_statetable.c 2007-03-23 08:10:06.000000000 -0400
30989 @@ -960,7 +960,7 @@ static const sctp_sm_table_entry_t *sctp
30990 if (state > SCTP_STATE_MAX)
30993 - if (cid >= 0 && cid <= SCTP_CID_BASE_MAX)
30994 + if (cid <= SCTP_CID_BASE_MAX)
30995 return &chunk_event_table[cid][state];
30997 if (sctp_prsctp_enable) {
30998 diff -urNp linux-2.6.20.3/net/sctp/socket.c linux-2.6.20.3/net/sctp/socket.c
30999 --- linux-2.6.20.3/net/sctp/socket.c 2007-03-13 14:27:08.000000000 -0400
31000 +++ linux-2.6.20.3/net/sctp/socket.c 2007-03-23 08:10:06.000000000 -0400
31001 @@ -1358,11 +1358,11 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
31002 struct sctp_chunk *chunk;
31003 union sctp_addr to;
31004 struct sockaddr *msg_name = NULL;
31005 - struct sctp_sndrcvinfo default_sinfo = { 0 };
31006 + struct sctp_sndrcvinfo default_sinfo;
31007 struct sctp_sndrcvinfo *sinfo;
31008 struct sctp_initmsg *sinit;
31009 sctp_assoc_t associd = 0;
31010 - sctp_cmsgs_t cmsgs = { NULL };
31011 + sctp_cmsgs_t cmsgs = { NULL, NULL };
31013 sctp_scope_t scope;
31015 diff -urNp linux-2.6.20.3/net/socket.c linux-2.6.20.3/net/socket.c
31016 --- linux-2.6.20.3/net/socket.c 2007-03-13 14:27:08.000000000 -0400
31017 +++ linux-2.6.20.3/net/socket.c 2007-03-23 08:11:31.000000000 -0400
31019 #include <linux/kmod.h>
31020 #include <linux/audit.h>
31021 #include <linux/wireless.h>
31022 +#include <linux/in.h>
31024 #include <asm/uaccess.h>
31025 #include <asm/unistd.h>
31027 #include <linux/vs_base.h>
31028 #include <linux/vs_socket.h>
31030 +extern void gr_attach_curr_ip(const struct sock *sk);
31031 +extern int gr_handle_sock_all(const int family, const int type,
31032 + const int protocol);
31033 +extern int gr_handle_sock_server(const struct sockaddr *sck);
31034 +extern int gr_handle_sock_server_other(const struct socket *sck);
31035 +extern int gr_handle_sock_client(const struct sockaddr *sck);
31036 +extern int gr_search_connect(const struct socket * sock,
31037 + const struct sockaddr_in * addr);
31038 +extern int gr_search_bind(const struct socket * sock,
31039 + const struct sockaddr_in * addr);
31040 +extern int gr_search_listen(const struct socket * sock);
31041 +extern int gr_search_accept(const struct socket * sock);
31042 +extern int gr_search_socket(const int domain, const int type,
31043 + const int protocol);
31045 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
31046 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
31047 unsigned long nr_segs, loff_t pos);
31048 @@ -297,7 +313,7 @@ static int sockfs_get_sb(struct file_sys
31052 -static struct vfsmount *sock_mnt __read_mostly;
31053 +struct vfsmount *sock_mnt __read_mostly;
31055 static struct file_system_type sock_fs_type = {
31057 @@ -1181,6 +1197,16 @@ asmlinkage long sys_socket(int family, i
31059 struct socket *sock;
31061 + if(!gr_search_socket(family, type, protocol)) {
31062 + retval = -EACCES;
31066 + if (gr_handle_sock_all(family, type, protocol)) {
31067 + retval = -EACCES;
31071 retval = sock_create(family, type, protocol, &sock);
31074 @@ -1276,12 +1302,20 @@ asmlinkage long sys_bind(int fd, struct
31076 struct socket *sock;
31077 char address[MAX_SOCK_ADDR];
31078 + struct sockaddr *sck;
31079 int err, fput_needed;
31081 sock = sockfd_lookup_light(fd, &err, &fput_needed);
31083 err = move_addr_to_kernel(umyaddr, addrlen, address);
31085 + sck = (struct sockaddr *)address;
31086 + if (!gr_search_bind(sock, (struct sockaddr_in *)sck) ||
31087 + gr_handle_sock_server(sck)) {
31092 err = security_socket_bind(sock,
31093 (struct sockaddr *)address,
31095 @@ -1290,6 +1324,7 @@ asmlinkage long sys_bind(int fd, struct
31096 (struct sockaddr *)
31100 fput_light(sock->file, fput_needed);
31103 @@ -1313,10 +1348,17 @@ asmlinkage long sys_listen(int fd, int b
31104 if ((unsigned)backlog > sysctl_somaxconn)
31105 backlog = sysctl_somaxconn;
31107 + if (gr_handle_sock_server_other(sock) ||
31108 + !gr_search_listen(sock)) {
31113 err = security_socket_listen(sock, backlog);
31115 err = sock->ops->listen(sock, backlog);
31118 fput_light(sock->file, fput_needed);
31121 @@ -1353,6 +1395,13 @@ asmlinkage long sys_accept(int fd, struc
31122 newsock->type = sock->type;
31123 newsock->ops = sock->ops;
31125 + if (gr_handle_sock_server_other(sock) ||
31126 + !gr_search_accept(sock)) {
31128 + sock_release(newsock);
31133 * We don't need try_module_get here, as the listening socket (sock)
31134 * has the protocol module (sock->ops->owner) held.
31135 @@ -1396,6 +1445,7 @@ asmlinkage long sys_accept(int fd, struc
31138 security_socket_post_accept(sock, newsock);
31139 + gr_attach_curr_ip(newsock->sk);
31142 fput_light(sock->file, fput_needed);
31143 @@ -1424,6 +1474,7 @@ asmlinkage long sys_connect(int fd, stru
31145 struct socket *sock;
31146 char address[MAX_SOCK_ADDR];
31147 + struct sockaddr *sck;
31148 int err, fput_needed;
31150 sock = sockfd_lookup_light(fd, &err, &fput_needed);
31151 @@ -1433,6 +1484,13 @@ asmlinkage long sys_connect(int fd, stru
31155 + sck = (struct sockaddr *)address;
31156 + if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
31157 + gr_handle_sock_client(sck)) {
31163 security_socket_connect(sock, (struct sockaddr *)address, addrlen);
31165 @@ -1706,6 +1764,7 @@ asmlinkage long sys_shutdown(int fd, int
31166 err = sock->ops->shutdown(sock, how);
31167 fput_light(sock->file, fput_needed);
31173 diff -urNp linux-2.6.20.3/net/unix/af_unix.c linux-2.6.20.3/net/unix/af_unix.c
31174 --- linux-2.6.20.3/net/unix/af_unix.c 2007-03-13 14:27:08.000000000 -0400
31175 +++ linux-2.6.20.3/net/unix/af_unix.c 2007-03-23 08:11:31.000000000 -0400
31176 @@ -118,6 +118,7 @@
31177 #include <linux/security.h>
31178 #include <linux/vs_context.h>
31179 #include <linux/vs_limit.h>
31180 +#include <linux/grsecurity.h>
31182 int sysctl_unix_max_dgram_qlen __read_mostly = 10;
31184 @@ -711,6 +712,11 @@ static struct sock *unix_find_other(stru
31188 + if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
31193 err = -ECONNREFUSED;
31194 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
31196 @@ -734,6 +740,13 @@ static struct sock *unix_find_other(stru
31198 struct dentry *dentry;
31199 dentry = unix_sk(u)->dentry;
31201 + if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
31208 touch_atime(unix_sk(u)->mnt, dentry);
31210 @@ -808,9 +821,18 @@ static int unix_bind(struct socket *sock
31213 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
31215 + if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
31217 + goto out_mknod_dput;
31220 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
31222 goto out_mknod_dput;
31224 + gr_handle_create(dentry, nd.mnt);
31226 mutex_unlock(&nd.dentry->d_inode->i_mutex);
31228 nd.dentry = dentry;
31229 @@ -828,6 +850,10 @@ static int unix_bind(struct socket *sock
31233 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
31234 + sk->sk_peercred.pid = current->pid;
31237 list = &unix_socket_table[addr->hash];
31239 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
31240 diff -urNp linux-2.6.20.3/net/xfrm/xfrm_user.c linux-2.6.20.3/net/xfrm/xfrm_user.c
31241 --- linux-2.6.20.3/net/xfrm/xfrm_user.c 2007-03-13 14:27:08.000000000 -0400
31242 +++ linux-2.6.20.3/net/xfrm/xfrm_user.c 2007-03-23 08:10:06.000000000 -0400
31243 @@ -1855,7 +1855,7 @@ nlmsg_failure:
31247 -static int inline xfrm_sa_len(struct xfrm_state *x)
31248 +static inline int xfrm_sa_len(struct xfrm_state *x)
31252 diff -urNp linux-2.6.20.3/scripts/pnmtologo.c linux-2.6.20.3/scripts/pnmtologo.c
31253 --- linux-2.6.20.3/scripts/pnmtologo.c 2007-03-13 14:27:08.000000000 -0400
31254 +++ linux-2.6.20.3/scripts/pnmtologo.c 2007-03-23 08:10:06.000000000 -0400
31255 @@ -237,14 +237,14 @@ static void write_header(void)
31256 fprintf(out, " * Linux logo %s\n", logoname);
31257 fputs(" */\n\n", out);
31258 fputs("#include <linux/linux_logo.h>\n\n", out);
31259 - fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
31260 + fprintf(out, "static unsigned char %s_data[] = {\n",
31264 static void write_footer(void)
31266 fputs("\n};\n\n", out);
31267 - fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
31268 + fprintf(out, "struct linux_logo %s = {\n", logoname);
31269 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
31270 fprintf(out, " .width\t= %d,\n", logo_width);
31271 fprintf(out, " .height\t= %d,\n", logo_height);
31272 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
31273 fputs("\n};\n\n", out);
31275 /* write logo clut */
31276 - fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
31277 + fprintf(out, "static unsigned char %s_clut[] = {\n",
31280 for (i = 0; i < logo_clutsize; i++) {
31281 diff -urNp linux-2.6.20.3/security/commoncap.c linux-2.6.20.3/security/commoncap.c
31282 --- linux-2.6.20.3/security/commoncap.c 2007-03-13 14:27:08.000000000 -0400
31283 +++ linux-2.6.20.3/security/commoncap.c 2007-03-23 08:11:31.000000000 -0400
31284 @@ -24,10 +24,11 @@
31285 #include <linux/xattr.h>
31286 #include <linux/hugetlb.h>
31287 #include <linux/vs_context.h>
31288 +#include <linux/grsecurity.h>
31290 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
31292 - cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
31293 + cap_t(NETLINK_CB(skb).eff_cap) = gr_cap_rtnetlink();
31297 @@ -44,7 +45,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
31298 int cap_capable (struct task_struct *tsk, int cap)
31300 /* Derived from include/linux/sched.h:capable. */
31301 - if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
31302 + if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
31307 +int cap_capable_nolog (struct task_struct *tsk, int cap)
31309 + /* tsk = current for all callers */
31310 + if ((vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap)) && gr_is_capable_nolog(cap))
31314 @@ -163,8 +172,11 @@ void cap_bprm_apply_creds (struct linux_
31318 - current->suid = current->euid = current->fsuid = bprm->e_uid;
31319 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
31320 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
31321 + current->suid = current->euid = current->fsuid = bprm->e_uid;
31323 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
31324 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
31326 /* For init, we want to retain the capabilities set
31327 * in the init_task struct. Thus we skip the usual
31328 @@ -175,6 +187,8 @@ void cap_bprm_apply_creds (struct linux_
31329 cap_intersect (new_permitted, bprm->cap_effective);
31332 + gr_handle_chroot_caps(current);
31334 /* AUD: Audit candidate if current->cap_effective is set */
31336 current->keep_capabilities = 0;
31337 @@ -320,12 +334,13 @@ int cap_vm_enough_memory(long pages)
31339 int cap_sys_admin = 0;
31341 - if (cap_capable(current, CAP_SYS_ADMIN) == 0)
31342 + if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
31344 return __vm_enough_memory(pages, cap_sys_admin);
31347 EXPORT_SYMBOL(cap_capable);
31348 +EXPORT_SYMBOL(cap_capable_nolog);
31349 EXPORT_SYMBOL(cap_settime);
31350 EXPORT_SYMBOL(cap_ptrace);
31351 EXPORT_SYMBOL(cap_capget);
31352 diff -urNp linux-2.6.20.3/security/dummy.c linux-2.6.20.3/security/dummy.c
31353 --- linux-2.6.20.3/security/dummy.c 2007-03-13 14:27:08.000000000 -0400
31354 +++ linux-2.6.20.3/security/dummy.c 2007-03-23 08:11:31.000000000 -0400
31356 #include <linux/ptrace.h>
31357 #include <linux/file.h>
31358 #include <linux/vs_context.h>
31359 +#include <linux/grsecurity.h>
31361 static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
31363 @@ -139,8 +140,11 @@ static void dummy_bprm_apply_creds (stru
31367 - current->suid = current->euid = current->fsuid = bprm->e_uid;
31368 - current->sgid = current->egid = current->fsgid = bprm->e_gid;
31369 + if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
31370 + current->suid = current->euid = current->fsuid = bprm->e_uid;
31372 + if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
31373 + current->sgid = current->egid = current->fsgid = bprm->e_gid;
31375 dummy_capget(current, ¤t->cap_effective, ¤t->cap_inheritable, ¤t->cap_permitted);
31377 diff -urNp linux-2.6.20.3/security/Kconfig linux-2.6.20.3/security/Kconfig
31378 --- linux-2.6.20.3/security/Kconfig 2007-03-13 14:27:08.000000000 -0400
31379 +++ linux-2.6.20.3/security/Kconfig 2007-03-23 09:03:54.000000000 -0400
31382 menu "Security options"
31387 + bool "Enable various PaX features"
31388 + depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
31390 + This allows you to enable various PaX features. PaX adds
31391 + intrusion prevention mechanisms to the kernel that reduce
31392 + the risks posed by exploitable memory corruption bugs.
31394 +menu "PaX Control"
31397 +config PAX_SOFTMODE
31398 + bool 'Support soft mode'
31400 + Enabling this option will allow you to run PaX in soft mode, that
31401 + is, PaX features will not be enforced by default, only on executables
31402 + marked explicitly. You must also enable PT_PAX_FLAGS support as it
31403 + is the only way to mark executables for soft mode use.
31405 + Soft mode can be activated by using the "pax_softmode=1" kernel command
31406 + line option on boot. Furthermore you can control various PaX features
31407 + at runtime via the entries in /proc/sys/kernel/pax.
31410 + bool 'Use legacy ELF header marking'
31412 + Enabling this option will allow you to control PaX features on
31413 + a per executable basis via the 'chpax' utility available at
31414 + http://pax.grsecurity.net/. The control flags will be read from
31415 + an otherwise reserved part of the ELF header. This marking has
31416 + numerous drawbacks (no support for soft-mode, toolchain does not
31417 + know about the non-standard use of the ELF header) therefore it
31418 + has been deprecated in favour of PT_PAX_FLAGS support.
31420 + If you have applications not marked by the PT_PAX_FLAGS ELF
31421 + program header then you MUST enable this option otherwise they
31422 + will not get any protection.
31424 + Note that if you enable PT_PAX_FLAGS marking support as well,
31425 + the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
31427 +config PAX_PT_PAX_FLAGS
31428 + bool 'Use ELF program header marking'
31430 + Enabling this option will allow you to control PaX features on
31431 + a per executable basis via the 'paxctl' utility available at
31432 + http://pax.grsecurity.net/. The control flags will be read from
31433 + a PaX specific ELF program header (PT_PAX_FLAGS). This marking
31434 + has the benefits of supporting both soft mode and being fully
31435 + integrated into the toolchain (the binutils patch is available
31436 + from http://pax.grsecurity.net).
31438 + If you have applications not marked by the PT_PAX_FLAGS ELF
31439 + program header then you MUST enable the EI_PAX marking support
31440 + otherwise they will not get any protection.
31442 + Note that if you enable the legacy EI_PAX marking support as well,
31443 + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
31446 + prompt 'MAC system integration'
31447 + default PAX_NO_ACL_FLAGS
31449 + Mandatory Access Control systems have the option of controlling
31450 + PaX flags on a per executable basis, choose the method supported
31451 + by your particular system.
31453 + - "none": if your MAC system does not interact with PaX,
31454 + - "direct": if your MAC system defines pax_set_flags() itself,
31455 + - "hook": if your MAC system uses the pax_set_flags_func callback.
31457 + NOTE: this option is for developers/integrators only.
31459 +config PAX_NO_ACL_FLAGS
31462 +config PAX_HAVE_ACL_FLAGS
31465 +config PAX_HOOK_ACL_FLAGS
31471 +menu "Non-executable pages"
31475 + bool "Enforce non-executable pages"
31476 + depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
31478 + By design some architectures do not allow for protecting memory
31479 + pages against execution or even if they do, Linux does not make
31480 + use of this feature. In practice this means that if a page is
31481 + readable (such as the stack or heap) it is also executable.
31483 + There is a well known exploit technique that makes use of this
31484 + fact and a common programming mistake where an attacker can
31485 + introduce code of his choice somewhere in the attacked program's
31486 + memory (typically the stack or the heap) and then execute it.
31488 + If the attacked program was running with different (typically
31489 + higher) privileges than that of the attacker, then he can elevate
31490 + his own privilege level (e.g. get a root shell, write to files for
31491 + which he does not have write access to, etc).
31493 + Enabling this option will let you choose from various features
31494 + that prevent the injection and execution of 'foreign' code in
31497 + This will also break programs that rely on the old behaviour and
31498 + expect that dynamically allocated memory via the malloc() family
31499 + of functions is executable (which it is not). Notable examples
31500 + are the XFree86 4.x server, the java runtime and wine.
31502 +config PAX_PAGEEXEC
31503 + bool "Paging based non-executable pages"
31504 + depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
31506 + This implementation is based on the paging feature of the CPU.
31507 + On i386 and ppc there is a variable but usually low performance
31508 + impact on applications. On alpha, ia64, parisc, sparc, sparc64
31509 + and x86_64 there is no performance impact.
31511 +config PAX_SEGMEXEC
31512 + bool "Segmentation based non-executable pages"
31513 + depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
31515 + This implementation is based on the segmentation feature of the
31516 + CPU and has little performance impact, however applications will
31517 + be limited to a 1.5 GB address space instead of the normal 3 GB.
31520 + prompt "Default non-executable page method"
31521 + depends on PAX_PAGEEXEC && PAX_SEGMEXEC
31522 + default PAX_DEFAULT_SEGMEXEC
31524 + Select the default non-executable page method applied to applications
31525 + that do not select one themselves.
31527 +config PAX_DEFAULT_PAGEEXEC
31530 +config PAX_DEFAULT_SEGMEXEC
31534 +config PAX_EMUTRAMP
31535 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
31536 + default y if PARISC || PPC32
31538 + There are some programs and libraries that for one reason or
31539 + another attempt to execute special small code snippets from
31540 + non-executable memory pages. Most notable examples are the
31541 + signal handler return code generated by the kernel itself and
31542 + the GCC trampolines.
31544 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
31545 + such programs will no longer work under your kernel.
31547 + As a remedy you can say Y here and use the 'chpax' or 'paxctl'
31548 + utilities to enable trampoline emulation for the affected programs
31549 + yet still have the protection provided by the non-executable pages.
31551 + On parisc and ppc you MUST enable this option and EMUSIGRT as
31552 + well, otherwise your system will not even boot.
31554 + Alternatively you can say N here and use the 'chpax' or 'paxctl'
31555 + utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
31556 + for the affected files.
31558 + NOTE: enabling this feature *may* open up a loophole in the
31559 + protection provided by non-executable pages that an attacker
31560 + could abuse. Therefore the best solution is to not have any
31561 + files on your system that would require this option. This can
31562 + be achieved by not using libc5 (which relies on the kernel
31563 + signal handler return code) and not using or rewriting programs
31564 + that make use of the nested function implementation of GCC.
31565 + Skilled users can just fix GCC itself so that it implements
31566 + nested function calls in a way that does not interfere with PaX.
31568 +config PAX_EMUSIGRT
31569 + bool "Automatically emulate sigreturn trampolines"
31570 + depends on PAX_EMUTRAMP && (PARISC || PPC32)
31573 + Enabling this option will have the kernel automatically detect
31574 + and emulate signal return trampolines executing on the stack
31575 + that would otherwise lead to task termination.
31577 + This solution is intended as a temporary one for users with
31578 + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
31579 + Modula-3 runtime, etc) or executables linked to such, basically
31580 + everything that does not specify its own SA_RESTORER function in
31581 + normal executable memory like glibc 2.1+ does.
31583 + On parisc and ppc you MUST enable this option, otherwise your
31584 + system will not even boot.
31586 + NOTE: this feature cannot be disabled on a per executable basis
31587 + and since it *does* open up a loophole in the protection provided
31588 + by non-executable pages, the best solution is to not have any
31589 + files on your system that would require this option.
31591 +config PAX_MPROTECT
31592 + bool "Restrict mprotect()"
31593 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
31595 + Enabling this option will prevent programs from
31596 + - changing the executable status of memory pages that were
31597 + not originally created as executable,
31598 + - making read-only executable pages writable again,
31599 + - creating executable pages from anonymous memory.
31601 + You should say Y here to complete the protection provided by
31602 + the enforcement of non-executable pages.
31604 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
31605 + this feature on a per file basis.
31607 +config PAX_NOELFRELOCS
31608 + bool "Disallow ELF text relocations"
31609 + depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
31611 + Non-executable pages and mprotect() restrictions are effective
31612 + in preventing the introduction of new executable code into an
31613 + attacked task's address space. There remain only two venues
31614 + for this kind of attack: if the attacker can execute already
31615 + existing code in the attacked task then he can either have it
31616 + create and mmap() a file containing his code or have it mmap()
31617 + an already existing ELF library that does not have position
31618 + independent code in it and use mprotect() on it to make it
31619 + writable and copy his code there. While protecting against
31620 + the former approach is beyond PaX, the latter can be prevented
31621 + by having only PIC ELF libraries on one's system (which do not
31622 + need to relocate their code). If you are sure this is your case,
31623 + then enable this option otherwise be careful as you may not even
31624 + be able to boot or log on your system (for example, some PAM
31625 + modules are erroneously compiled as non-PIC by default).
31627 + NOTE: if you are using dynamic ELF executables (as suggested
31628 + when using ASLR) then you must have made sure that you linked
31629 + your files using the PIC version of crt1 (the et_dyn.tar.gz package
31630 + referenced there has already been updated to support this).
31632 +config PAX_ETEXECRELOCS
31633 + bool "Allow ELF ET_EXEC text relocations"
31634 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
31637 + On some architectures there are incorrectly created applications
31638 + that require text relocations and would not work without enabling
31639 + this option. If you are an alpha, ia64 or parisc user, you should
31640 + enable this option and disable it once you have made sure that
31641 + none of your applications need it.
31644 + bool "Automatically emulate ELF PLT"
31645 + depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
31648 + Enabling this option will have the kernel automatically detect
31649 + and emulate the Procedure Linkage Table entries in ELF files.
31650 + On some architectures such entries are in writable memory, and
31651 + become non-executable leading to task termination. Therefore
31652 + it is mandatory that you enable this option on alpha, parisc, ppc,
31653 + sparc and sparc64, otherwise your system would not even boot.
31655 + NOTE: this feature *does* open up a loophole in the protection
31656 + provided by the non-executable pages, therefore the proper
31657 + solution is to modify the toolchain to produce a PLT that does
31658 + not need to be writable.
31660 +config PAX_DLRESOLVE
31662 + depends on PAX_EMUPLT && (SPARC32 || SPARC64)
31665 +config PAX_SYSCALL
31667 + depends on PAX_PAGEEXEC && PPC32
31670 +config PAX_KERNEXEC
31671 + bool "Enforce non-executable kernel pages"
31672 + depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !COMPAT_VDSO && X86_WP_WORKS_OK
31674 + This is the kernel land equivalent of PAGEEXEC and MPROTECT,
31675 + that is, enabling this option will make it harder to inject
31676 + and execute 'foreign' code in kernel memory itself.
31680 +menu "Address Space Layout Randomization"
31684 + bool "Address Space Layout Randomization"
31685 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
31687 + Many if not most exploit techniques rely on the knowledge of
31688 + certain addresses in the attacked program. The following options
31689 + will allow the kernel to apply a certain amount of randomization
31690 + to specific parts of the program thereby forcing an attacker to
31691 + guess them in most cases. Any failed guess will most likely crash
31692 + the attacked program which allows the kernel to detect such attempts
31693 + and react on them. PaX itself provides no reaction mechanisms,
31694 + instead it is strongly encouraged that you make use of Nergal's
31695 + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
31696 + (http://www.grsecurity.net/) built-in crash detection features or
31697 + develop one yourself.
31699 + By saying Y here you can choose to randomize the following areas:
31700 + - top of the task's kernel stack
31701 + - top of the task's userland stack
31702 + - base address for mmap() requests that do not specify one
31703 + (this includes all libraries)
31704 + - base address of the main executable
31706 + It is strongly recommended to say Y here as address space layout
31707 + randomization has negligible impact on performance yet it provides
31708 + a very effective protection.
31710 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
31711 + this feature on a per file basis.
31713 +config PAX_RANDKSTACK
31714 + bool "Randomize kernel stack base"
31715 + depends on PAX_ASLR && X86_TSC && X86_32
31717 + By saying Y here the kernel will randomize every task's kernel
31718 + stack on every system call. This will not only force an attacker
31719 + to guess it but also prevent him from making use of possible
31720 + leaked information about it.
31722 + Since the kernel stack is a rather scarce resource, randomization
31723 + may cause unexpected stack overflows, therefore you should very
31724 + carefully test your system. Note that once enabled in the kernel
31725 + configuration, this feature cannot be disabled on a per file basis.
31727 +config PAX_RANDUSTACK
31728 + bool "Randomize user stack base"
31729 + depends on PAX_ASLR
31731 + By saying Y here the kernel will randomize every task's userland
31732 + stack. The randomization is done in two steps where the second
31733 + one may apply a big amount of shift to the top of the stack and
31734 + cause problems for programs that want to use lots of memory (more
31735 + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
31736 + For this reason the second step can be controlled by 'chpax' or
31737 + 'paxctl' on a per file basis.
31739 +config PAX_RANDMMAP
31740 + bool "Randomize mmap() base"
31741 + depends on PAX_ASLR
31743 + By saying Y here the kernel will use a randomized base address for
31744 + mmap() requests that do not specify one themselves. As a result
31745 + all dynamically loaded libraries will appear at random addresses
31746 + and therefore be harder to exploit by a technique where an attacker
31747 + attempts to execute library code for his purposes (e.g. spawn a
31748 + shell from an exploited program that is running at an elevated
31749 + privilege level).
31751 + Furthermore, if a program is relinked as a dynamic ELF file, its
31752 + base address will be randomized as well, completing the full
31753 + randomization of the address space layout. Attacking such programs
31754 + becomes a guess game. You can find an example of doing this at
31755 + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
31756 + http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
31758 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
31759 + feature on a per file basis.
31763 +menu "Miscellaneous hardening features"
31765 +config PAX_MEMORY_SANITIZE
31766 + bool "Sanitize all freed memory"
31768 + By saying Y here the kernel will erase memory pages as soon as they
31769 + are freed. This in turn reduces the lifetime of data stored in the
31770 + pages, making it less likely that sensitive information such as
31771 + passwords, cryptographic secrets, etc stay in memory for too long.
31773 + This is especially useful for programs whose runtime is short, long
31774 + lived processes and the kernel itself benefit from this as long as
31775 + they operate on whole memory pages and ensure timely freeing of pages
31776 + that may hold sensitive information.
31778 + The tradeoff is performance impact, on a single CPU system kernel
31779 + compilation sees a 3% slowdown, other systems and workloads may vary
31780 + and you are advised to test this feature on your expected workload
31781 + before deploying it.
31783 + Note that this feature does not protect data stored in live pages,
31784 + e.g., process memory swapped to disk may stay there for a long time.
31786 +config PAX_MEMORY_UDEREF
31787 + bool "Prevent invalid userland pointer dereference"
31788 + depends on X86_32 && !COMPAT_VDSO
31790 + By saying Y here the kernel will be prevented from dereferencing
31791 + userland pointers in contexts where the kernel expects only kernel
31792 + pointers. This is both a useful runtime debugging feature and a
31793 + security measure that prevents exploiting a class of kernel bugs.
31795 + The tradeoff is that some virtualization solutions may experience
31796 + a huge slowdown and therefore you should not enable this feature
31797 + for kernels meant to run in such environments. Whether a given VM
31798 + solution is affected or not is best determined by simply trying it
31799 + out, the performance impact will be obvious right on boot as this
31800 + mechanism engages from very early on. A good rule of thumb is that
31801 + VMs running on CPUs without hardware virtualization support (i.e.,
31802 + the majority of IA-32 CPUs) will likely experience the slowdown.
31808 +source grsecurity/Kconfig
31811 bool "Enable access key retention support"
31812 depends on !VSERVER_SECURITY
31813 diff -urNp linux-2.6.20.3/sound/core/oss/pcm_oss.c linux-2.6.20.3/sound/core/oss/pcm_oss.c
31814 --- linux-2.6.20.3/sound/core/oss/pcm_oss.c 2007-03-13 14:27:08.000000000 -0400
31815 +++ linux-2.6.20.3/sound/core/oss/pcm_oss.c 2007-03-23 08:10:06.000000000 -0400
31816 @@ -2881,8 +2881,8 @@ static void snd_pcm_oss_proc_done(struct
31819 #else /* !CONFIG_SND_VERBOSE_PROCFS */
31820 -#define snd_pcm_oss_proc_init(pcm)
31821 -#define snd_pcm_oss_proc_done(pcm)
31822 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
31823 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
31824 #endif /* CONFIG_SND_VERBOSE_PROCFS */
31827 diff -urNp linux-2.6.20.3/sound/core/seq/seq_lock.h linux-2.6.20.3/sound/core/seq/seq_lock.h
31828 --- linux-2.6.20.3/sound/core/seq/seq_lock.h 2007-03-13 14:27:08.000000000 -0400
31829 +++ linux-2.6.20.3/sound/core/seq/seq_lock.h 2007-03-23 08:10:06.000000000 -0400
31830 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
31831 #else /* SMP || CONFIG_SND_DEBUG */
31833 typedef spinlock_t snd_use_lock_t; /* dummy */
31834 -#define snd_use_lock_init(lockp) /**/
31835 -#define snd_use_lock_use(lockp) /**/
31836 -#define snd_use_lock_free(lockp) /**/
31837 -#define snd_use_lock_sync(lockp) /**/
31838 +#define snd_use_lock_init(lockp) do {} while (0)
31839 +#define snd_use_lock_use(lockp) do {} while (0)
31840 +#define snd_use_lock_free(lockp) do {} while (0)
31841 +#define snd_use_lock_sync(lockp) do {} while (0)
31843 #endif /* SMP || CONFIG_SND_DEBUG */
31845 diff -urNp linux-2.6.20.3/sound/pci/ac97/ac97_codec.c linux-2.6.20.3/sound/pci/ac97/ac97_codec.c
31846 --- linux-2.6.20.3/sound/pci/ac97/ac97_codec.c 2007-03-13 14:27:08.000000000 -0400
31847 +++ linux-2.6.20.3/sound/pci/ac97/ac97_codec.c 2007-03-23 08:10:06.000000000 -0400
31848 @@ -67,129 +67,129 @@ struct ac97_codec_id {
31851 static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
31852 -{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
31853 -{ 0x41445300, 0xffffff00, "Analog Devices", NULL, NULL },
31854 -{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL },
31855 -{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL },
31856 -{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
31857 -{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL, NULL },
31858 -{ 0x43585400, 0xffffff00, "Conexant", NULL, NULL },
31859 -{ 0x44543000, 0xffffff00, "Diamond Technology", NULL, NULL },
31860 -{ 0x454d4300, 0xffffff00, "eMicro", NULL, NULL },
31861 -{ 0x45838300, 0xffffff00, "ESS Technology", NULL, NULL },
31862 -{ 0x48525300, 0xffffff00, "Intersil", NULL, NULL },
31863 -{ 0x49434500, 0xffffff00, "ICEnsemble", NULL, NULL },
31864 -{ 0x49544500, 0xffffff00, "ITE Tech.Inc", NULL, NULL },
31865 -{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL },
31866 -{ 0x50534300, 0xffffff00, "Philips", NULL, NULL },
31867 -{ 0x53494c00, 0xffffff00, "Silicon Laboratory", NULL, NULL },
31868 -{ 0x54524100, 0xffffff00, "TriTech", NULL, NULL },
31869 -{ 0x54584e00, 0xffffff00, "Texas Instruments", NULL, NULL },
31870 -{ 0x56494100, 0xffffff00, "VIA Technologies", NULL, NULL },
31871 -{ 0x57454300, 0xffffff00, "Winbond", NULL, NULL },
31872 -{ 0x574d4c00, 0xffffff00, "Wolfson", NULL, NULL },
31873 -{ 0x594d4800, 0xffffff00, "Yamaha", NULL, NULL },
31874 -{ 0x83847600, 0xffffff00, "SigmaTel", NULL, NULL },
31875 -{ 0, 0, NULL, NULL, NULL }
31876 +{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL, 0 },
31877 +{ 0x41445300, 0xffffff00, "Analog Devices", NULL, NULL, 0 },
31878 +{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL, 0 },
31879 +{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL, 0 },
31880 +{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL, 0 },
31881 +{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL, NULL, 0 },
31882 +{ 0x43585400, 0xffffff00, "Conexant", NULL, NULL, 0 },
31883 +{ 0x44543000, 0xffffff00, "Diamond Technology", NULL, NULL, 0 },
31884 +{ 0x454d4300, 0xffffff00, "eMicro", NULL, NULL, 0 },
31885 +{ 0x45838300, 0xffffff00, "ESS Technology", NULL, NULL, 0 },
31886 +{ 0x48525300, 0xffffff00, "Intersil", NULL, NULL, 0 },
31887 +{ 0x49434500, 0xffffff00, "ICEnsemble", NULL, NULL, 0 },
31888 +{ 0x49544500, 0xffffff00, "ITE Tech.Inc", NULL, NULL, 0 },
31889 +{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL, 0 },
31890 +{ 0x50534300, 0xffffff00, "Philips", NULL, NULL, 0 },
31891 +{ 0x53494c00, 0xffffff00, "Silicon Laboratory", NULL, NULL, 0 },
31892 +{ 0x54524100, 0xffffff00, "TriTech", NULL, NULL, 0 },
31893 +{ 0x54584e00, 0xffffff00, "Texas Instruments", NULL, NULL, 0 },
31894 +{ 0x56494100, 0xffffff00, "VIA Technologies", NULL, NULL, 0 },
31895 +{ 0x57454300, 0xffffff00, "Winbond", NULL, NULL, 0 },
31896 +{ 0x574d4c00, 0xffffff00, "Wolfson", NULL, NULL, 0 },
31897 +{ 0x594d4800, 0xffffff00, "Yamaha", NULL, NULL, 0 },
31898 +{ 0x83847600, 0xffffff00, "SigmaTel", NULL, NULL, 0 },
31899 +{ 0, 0, NULL, NULL, NULL, 0 }
31902 static const struct ac97_codec_id snd_ac97_codec_ids[] = {
31903 -{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL },
31904 -{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL },
31905 -{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL },
31906 -{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL },
31907 -{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL },
31908 -{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819, NULL },
31909 -{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881, NULL },
31910 -{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881, NULL },
31911 -{ 0x41445360, 0xffffffff, "AD1885", patch_ad1885, NULL },
31912 -{ 0x41445361, 0xffffffff, "AD1886", patch_ad1886, NULL },
31913 -{ 0x41445362, 0xffffffff, "AD1887", patch_ad1881, NULL },
31914 -{ 0x41445363, 0xffffffff, "AD1886A", patch_ad1881, NULL },
31915 -{ 0x41445368, 0xffffffff, "AD1888", patch_ad1888, NULL },
31916 -{ 0x41445370, 0xffffffff, "AD1980", patch_ad1980, NULL },
31917 -{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL },
31918 -{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL },
31919 -{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL },
31920 -{ 0x41445378, 0xffffffff, "AD1986", patch_ad1985, NULL },
31921 -{ 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL },
31922 -{ 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL },
31923 -{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */
31924 -{ 0x414c4722, 0xffffffff, "ALC650E", NULL, NULL }, /* already patched */
31925 -{ 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */
31926 -{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL },
31927 -{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL },
31928 -{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */
31929 -{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL },
31930 -{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL },
31931 -{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL },
31932 -{ 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL },
31933 -{ 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL },
31934 -{ 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL },
31935 -{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
31936 -{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
31937 -{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL },
31938 -{ 0x434d4978, 0xffffffff, "CMI9761A", patch_cm9761, NULL },
31939 -{ 0x434d4982, 0xffffffff, "CMI9761B", patch_cm9761, NULL },
31940 -{ 0x434d4983, 0xffffffff, "CMI9761A+", patch_cm9761, NULL },
31941 -{ 0x43525900, 0xfffffff8, "CS4297", NULL, NULL },
31942 -{ 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif, NULL },
31943 -{ 0x43525920, 0xfffffff8, "CS4298", patch_cirrus_spdif, NULL },
31944 -{ 0x43525928, 0xfffffff8, "CS4294", NULL, NULL },
31945 -{ 0x43525930, 0xfffffff8, "CS4299", patch_cirrus_cs4299, NULL },
31946 -{ 0x43525948, 0xfffffff8, "CS4201", NULL, NULL },
31947 -{ 0x43525958, 0xfffffff8, "CS4205", patch_cirrus_spdif, NULL },
31948 -{ 0x43525960, 0xfffffff8, "CS4291", NULL, NULL },
31949 -{ 0x43525970, 0xfffffff8, "CS4202", NULL, NULL },
31950 -{ 0x43585421, 0xffffffff, "HSD11246", NULL, NULL }, // SmartMC II
31951 -{ 0x43585428, 0xfffffff8, "Cx20468", patch_conexant, NULL }, // SmartAMC fixme: the mask might be different
31952 -{ 0x44543031, 0xfffffff0, "DT0398", NULL, NULL },
31953 -{ 0x454d4328, 0xffffffff, "EM28028", NULL, NULL }, // same as TR28028?
31954 -{ 0x45838308, 0xffffffff, "ESS1988", NULL, NULL },
31955 -{ 0x48525300, 0xffffff00, "HMP9701", NULL, NULL },
31956 -{ 0x49434501, 0xffffffff, "ICE1230", NULL, NULL },
31957 -{ 0x49434511, 0xffffffff, "ICE1232", NULL, NULL }, // alias VIA VT1611A?
31958 -{ 0x49434514, 0xffffffff, "ICE1232A", NULL, NULL },
31959 -{ 0x49434551, 0xffffffff, "VT1616", patch_vt1616, NULL },
31960 -{ 0x49434552, 0xffffffff, "VT1616i", patch_vt1616, NULL }, // VT1616 compatible (chipset integrated)
31961 -{ 0x49544520, 0xffffffff, "IT2226E", NULL, NULL },
31962 -{ 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL },
31963 -{ 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk
31964 -{ 0x4e534331, 0xffffffff, "LM4549", NULL, NULL },
31965 -{ 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix
31966 -{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL },
31967 +{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL, 0 },
31968 +{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL, 0 },
31969 +{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL, 0 },
31970 +{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL, 0 },
31971 +{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL, 0 },
31972 +{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819, NULL, 0 },
31973 +{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881, NULL, 0 },
31974 +{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881, NULL, 0 },
31975 +{ 0x41445360, 0xffffffff, "AD1885", patch_ad1885, NULL, 0 },
31976 +{ 0x41445361, 0xffffffff, "AD1886", patch_ad1886, NULL, 0 },
31977 +{ 0x41445362, 0xffffffff, "AD1887", patch_ad1881, NULL, 0 },
31978 +{ 0x41445363, 0xffffffff, "AD1886A", patch_ad1881, NULL, 0 },
31979 +{ 0x41445368, 0xffffffff, "AD1888", patch_ad1888, NULL, 0 },
31980 +{ 0x41445370, 0xffffffff, "AD1980", patch_ad1980, NULL, 0 },
31981 +{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL, 0 },
31982 +{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL, 0 },
31983 +{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL, 0 },
31984 +{ 0x41445378, 0xffffffff, "AD1986", patch_ad1985, NULL, 0 },
31985 +{ 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL, 0 },
31986 +{ 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL, 0 },
31987 +{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL, 0 }, /* already patched */
31988 +{ 0x414c4722, 0xffffffff, "ALC650E", NULL, NULL, 0 }, /* already patched */
31989 +{ 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL, 0 }, /* already patched */
31990 +{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL, 0 },
31991 +{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL, 0 },
31992 +{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL, 0 }, /* already patched */
31993 +{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL, 0 },
31994 +{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL, 0 },
31995 +{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL, 0 },
31996 +{ 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL, 0 },
31997 +{ 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL, 0 },
31998 +{ 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL, 0 },
31999 +{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL, 0 },
32000 +{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL, 0 },
32001 +{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL, 0 },
32002 +{ 0x434d4978, 0xffffffff, "CMI9761A", patch_cm9761, NULL, 0 },
32003 +{ 0x434d4982, 0xffffffff, "CMI9761B", patch_cm9761, NULL, 0 },
32004 +{ 0x434d4983, 0xffffffff, "CMI9761A+", patch_cm9761, NULL, 0 },
32005 +{ 0x43525900, 0xfffffff8, "CS4297", NULL, NULL, 0 },
32006 +{ 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif, NULL, 0 },
32007 +{ 0x43525920, 0xfffffff8, "CS4298", patch_cirrus_spdif, NULL, 0 },
32008 +{ 0x43525928, 0xfffffff8, "CS4294", NULL, NULL, 0 },
32009 +{ 0x43525930, 0xfffffff8, "CS4299", patch_cirrus_cs4299, NULL, 0 },
32010 +{ 0x43525948, 0xfffffff8, "CS4201", NULL, NULL, 0 },
32011 +{ 0x43525958, 0xfffffff8, "CS4205", patch_cirrus_spdif, NULL, 0 },
32012 +{ 0x43525960, 0xfffffff8, "CS4291", NULL, NULL, 0 },
32013 +{ 0x43525970, 0xfffffff8, "CS4202", NULL, NULL, 0 },
32014 +{ 0x43585421, 0xffffffff, "HSD11246", NULL, NULL, 0 }, // SmartMC II
32015 +{ 0x43585428, 0xfffffff8, "Cx20468", patch_conexant, NULL, 0 }, // SmartAMC fixme: the mask might be different
32016 +{ 0x44543031, 0xfffffff0, "DT0398", NULL, NULL, 0 },
32017 +{ 0x454d4328, 0xffffffff, "EM28028", NULL, NULL, 0 }, // same as TR28028?
32018 +{ 0x45838308, 0xffffffff, "ESS1988", NULL, NULL, 0 },
32019 +{ 0x48525300, 0xffffff00, "HMP9701", NULL, NULL, 0 },
32020 +{ 0x49434501, 0xffffffff, "ICE1230", NULL, NULL, 0 },
32021 +{ 0x49434511, 0xffffffff, "ICE1232", NULL, NULL, 0 }, // alias VIA VT1611A?
32022 +{ 0x49434514, 0xffffffff, "ICE1232A", NULL, NULL, 0 },
32023 +{ 0x49434551, 0xffffffff, "VT1616", patch_vt1616, NULL, 0 },
32024 +{ 0x49434552, 0xffffffff, "VT1616i", patch_vt1616, NULL, 0 }, // VT1616 compatible (chipset integrated)
32025 +{ 0x49544520, 0xffffffff, "IT2226E", NULL, NULL, 0 },
32026 +{ 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL, 0 },
32027 +{ 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL, 0 }, // only guess --jk
32028 +{ 0x4e534331, 0xffffffff, "LM4549", NULL, NULL, 0 },
32029 +{ 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL, 0 }, // volume wrap fix
32030 +{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL, 0 },
32031 { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH },
32032 -{ 0x54524102, 0xffffffff, "TR28022", NULL, NULL },
32033 -{ 0x54524106, 0xffffffff, "TR28026", NULL, NULL },
32034 -{ 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL }, // added by xin jin [07/09/99]
32035 -{ 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
32036 -{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL },
32037 -{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF
32038 -{ 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF
32039 -{ 0x56494182, 0xffffffff, "VIA1618", NULL, NULL },
32040 -{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL },
32041 -{ 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL },
32042 -{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL},
32043 -{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL},
32044 -{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL},
32045 -{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL},
32046 -{ 0x574d4C12, 0xffffffff, "WM9711,WM9712", patch_wolfson11, NULL},
32047 +{ 0x54524102, 0xffffffff, "TR28022", NULL, NULL, 0 },
32048 +{ 0x54524106, 0xffffffff, "TR28026", NULL, NULL, 0 },
32049 +{ 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL, 0 }, // added by xin jin [07/09/99]
32050 +{ 0x54524123, 0xffffffff, "TR28602", NULL, NULL, 0 }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
32051 +{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL, 0 },
32052 +{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL, 0 }, // modified ICE1232 with S/PDIF
32053 +{ 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL, 0 }, // modified VT1616 with S/PDIF
32054 +{ 0x56494182, 0xffffffff, "VIA1618", NULL, NULL, 0 },
32055 +{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL, 0 },
32056 +{ 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL, 0 },
32057 +{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL, 0},
32058 +{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL, 0},
32059 +{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL, 0},
32060 +{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL, 0},
32061 +{ 0x574d4C12, 0xffffffff, "WM9711,WM9712", patch_wolfson11, NULL, 0},
32062 { 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
32063 -{ 0x594d4800, 0xffffffff, "YMF743", NULL, NULL },
32064 -{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL },
32065 -{ 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753, NULL },
32066 -{ 0x83847600, 0xffffffff, "STAC9700,83,84", patch_sigmatel_stac9700, NULL },
32067 -{ 0x83847604, 0xffffffff, "STAC9701,3,4,5", NULL, NULL },
32068 -{ 0x83847605, 0xffffffff, "STAC9704", NULL, NULL },
32069 -{ 0x83847608, 0xffffffff, "STAC9708,11", patch_sigmatel_stac9708, NULL },
32070 -{ 0x83847609, 0xffffffff, "STAC9721,23", patch_sigmatel_stac9721, NULL },
32071 -{ 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744, NULL },
32072 -{ 0x83847650, 0xffffffff, "STAC9750,51", NULL, NULL }, // patch?
32073 -{ 0x83847652, 0xffffffff, "STAC9752,53", NULL, NULL }, // patch?
32074 -{ 0x83847656, 0xffffffff, "STAC9756,57", patch_sigmatel_stac9756, NULL },
32075 -{ 0x83847658, 0xffffffff, "STAC9758,59", patch_sigmatel_stac9758, NULL },
32076 -{ 0x83847666, 0xffffffff, "STAC9766,67", NULL, NULL }, // patch?
32077 -{ 0, 0, NULL, NULL, NULL }
32078 +{ 0x594d4800, 0xffffffff, "YMF743", NULL, NULL, 0 },
32079 +{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL, 0 },
32080 +{ 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753, NULL, 0 },
32081 +{ 0x83847600, 0xffffffff, "STAC9700,83,84", patch_sigmatel_stac9700, NULL, 0 },
32082 +{ 0x83847604, 0xffffffff, "STAC9701,3,4,5", NULL, NULL, 0 },
32083 +{ 0x83847605, 0xffffffff, "STAC9704", NULL, NULL, 0 },
32084 +{ 0x83847608, 0xffffffff, "STAC9708,11", patch_sigmatel_stac9708, NULL, 0 },
32085 +{ 0x83847609, 0xffffffff, "STAC9721,23", patch_sigmatel_stac9721, NULL, 0 },
32086 +{ 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744, NULL, 0 },
32087 +{ 0x83847650, 0xffffffff, "STAC9750,51", NULL, NULL, 0 }, // patch?
32088 +{ 0x83847652, 0xffffffff, "STAC9752,53", NULL, NULL, 0 }, // patch?
32089 +{ 0x83847656, 0xffffffff, "STAC9756,57", patch_sigmatel_stac9756, NULL, 0 },
32090 +{ 0x83847658, 0xffffffff, "STAC9758,59", patch_sigmatel_stac9758, NULL, 0 },
32091 +{ 0x83847666, 0xffffffff, "STAC9766,67", NULL, NULL, 0 }, // patch?
32092 +{ 0, 0, NULL, NULL, NULL, 0 }
32096 diff -urNp linux-2.6.20.3/sound/pci/ac97/ac97_patch.c linux-2.6.20.3/sound/pci/ac97/ac97_patch.c
32097 --- linux-2.6.20.3/sound/pci/ac97/ac97_patch.c 2007-03-13 14:27:08.000000000 -0400
32098 +++ linux-2.6.20.3/sound/pci/ac97/ac97_patch.c 2007-03-23 08:10:06.000000000 -0400
32099 @@ -1404,7 +1404,7 @@ static const struct snd_ac97_res_table a
32100 { AC97_VIDEO, 0x9f1f },
32101 { AC97_AUX, 0x9f1f },
32102 { AC97_PCM, 0x9f1f },
32103 - { } /* terminator */
32104 + { 0, 0} /* terminator */
32107 int patch_ad1819(struct snd_ac97 * ac97)
32108 @@ -2924,7 +2924,7 @@ static struct snd_ac97_res_table lm4550_
32109 { AC97_AUX, 0x1f1f },
32110 { AC97_PCM, 0x1f1f },
32111 { AC97_REC_GAIN, 0x0f0f },
32112 - { } /* terminator */
32113 + { 0, 0 } /* terminator */
32116 int patch_lm4550(struct snd_ac97 *ac97)
32117 diff -urNp linux-2.6.20.3/sound/pci/ens1370.c linux-2.6.20.3/sound/pci/ens1370.c
32118 --- linux-2.6.20.3/sound/pci/ens1370.c 2007-03-13 14:27:08.000000000 -0400
32119 +++ linux-2.6.20.3/sound/pci/ens1370.c 2007-03-23 08:10:06.000000000 -0400
32120 @@ -455,7 +455,7 @@ static struct pci_device_id snd_audiopci
32121 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
32122 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
32125 + { 0, 0, 0, 0, 0, 0, 0 }
32128 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
32129 diff -urNp linux-2.6.20.3/sound/pci/intel8x0.c linux-2.6.20.3/sound/pci/intel8x0.c
32130 --- linux-2.6.20.3/sound/pci/intel8x0.c 2007-03-13 14:27:08.000000000 -0400
32131 +++ linux-2.6.20.3/sound/pci/intel8x0.c 2007-03-23 08:10:06.000000000 -0400
32132 @@ -437,7 +437,7 @@ static struct pci_device_id snd_intel8x0
32133 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
32134 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
32135 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
32137 + { 0, 0, 0, 0, 0, 0, 0 }
32140 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
32141 @@ -2046,7 +2046,7 @@ static struct ac97_quirk ac97_quirks[] _
32142 .type = AC97_TUNE_HP_ONLY
32145 - { } /* terminator */
32146 + { 0, 0, 0, 0, NULL, 0 } /* terminator */
32149 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
32150 diff -urNp linux-2.6.20.3/sound/pci/intel8x0m.c linux-2.6.20.3/sound/pci/intel8x0m.c
32151 --- linux-2.6.20.3/sound/pci/intel8x0m.c 2007-03-13 14:27:08.000000000 -0400
32152 +++ linux-2.6.20.3/sound/pci/intel8x0m.c 2007-03-23 08:10:06.000000000 -0400
32153 @@ -244,7 +244,7 @@ static struct pci_device_id snd_intel8x0
32154 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
32155 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
32158 + { 0, 0, 0, 0, 0, 0, 0 }
32161 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
32162 @@ -1297,7 +1297,7 @@ static struct shortname_table {
32163 { 0x5455, "ALi M5455" },
32164 { 0x746d, "AMD AMD8111" },
32170 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,